1 /* NetHack 3.6 cmd.c $NHDT-Date: 1557088405 2019/05/05 20:33:25 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.333 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /*-Copyright (c) Robert Patrick Rankin, 2013. */
4 /* NetHack may be freely redistributed. See license for details. */
6 /* JNetHack Copyright */
7 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000 */
8 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2019 */
9 /* JNetHack may be freely redistributed. See license for details. */
15 /* Macros for meta and ctrl modifiers:
16 * M and C return the meta/ctrl code for the given character;
17 * e.g., (C('c') is ctrl-c
21 #define M(c) (0x80 | (c))
23 #define M(c) ((c) - 128)
28 #define C(c) (0x1f & (c))
32 STATIC_VAR boolean alt_esc = FALSE;
35 struct cmd Cmd = { 0 }; /* flag.h */
37 extern const char *hu_stat[]; /* hunger status from eat.c */
38 extern const char *enc_stat[]; /* encumbrance status from botl.c */
42 * Some systems may have getchar() return EOF for various reasons, and
43 * we should not quit before seeing at least NR_OF_EOFS consecutive EOFs.
45 #if defined(SYSV) || defined(DGUX) || defined(HPUX)
50 #define CMD_TRAVEL (char) 0x90
51 #define CMD_CLICKLOOK (char) 0x8F
54 extern int NDECL(wiz_debug_cmd_bury);
57 #ifdef DUMB /* stuff commented out in extern.h, but needed here */
58 extern int NDECL(doapply); /**/
59 extern int NDECL(dorub); /**/
60 extern int NDECL(dojump); /**/
61 extern int NDECL(doextlist); /**/
62 extern int NDECL(enter_explore_mode); /**/
63 extern int NDECL(dodrop); /**/
64 extern int NDECL(doddrop); /**/
65 extern int NDECL(dodown); /**/
66 extern int NDECL(doup); /**/
67 extern int NDECL(donull); /**/
68 extern int NDECL(dowipe); /**/
69 extern int NDECL(docallcnd); /**/
70 extern int NDECL(dotakeoff); /**/
71 extern int NDECL(doremring); /**/
72 extern int NDECL(dowear); /**/
73 extern int NDECL(doputon); /**/
74 extern int NDECL(doddoremarm); /**/
75 extern int NDECL(dokick); /**/
76 extern int NDECL(dofire); /**/
77 extern int NDECL(dothrow); /**/
78 extern int NDECL(doeat); /**/
79 extern int NDECL(done2); /**/
80 extern int NDECL(vanquished); /**/
81 extern int NDECL(doengrave); /**/
82 extern int NDECL(dopickup); /**/
83 extern int NDECL(ddoinv); /**/
84 extern int NDECL(dotypeinv); /**/
85 extern int NDECL(dolook); /**/
86 extern int NDECL(doprgold); /**/
87 extern int NDECL(doprwep); /**/
88 extern int NDECL(doprarm); /**/
89 extern int NDECL(doprring); /**/
90 extern int NDECL(dopramulet); /**/
91 extern int NDECL(doprtool); /**/
92 extern int NDECL(dosuspend); /**/
93 extern int NDECL(doforce); /**/
94 extern int NDECL(doopen); /**/
95 extern int NDECL(doclose); /**/
96 extern int NDECL(dosh); /**/
97 extern int NDECL(dodiscovered); /**/
98 extern int NDECL(doclassdisco); /**/
99 extern int NDECL(doset); /**/
100 extern int NDECL(dotogglepickup); /**/
101 extern int NDECL(dowhatis); /**/
102 extern int NDECL(doquickwhatis); /**/
103 extern int NDECL(dowhatdoes); /**/
104 extern int NDECL(dohelp); /**/
105 extern int NDECL(dohistory); /**/
106 extern int NDECL(doloot); /**/
107 extern int NDECL(dodrink); /**/
108 extern int NDECL(dodip); /**/
109 extern int NDECL(dosacrifice); /**/
110 extern int NDECL(dopray); /**/
111 extern int NDECL(dotip); /**/
112 extern int NDECL(doturn); /**/
113 extern int NDECL(doredraw); /**/
114 extern int NDECL(doread); /**/
115 extern int NDECL(dosave); /**/
116 extern int NDECL(dosearch); /**/
117 extern int NDECL(doidtrap); /**/
118 extern int NDECL(dopay); /**/
119 extern int NDECL(dosit); /**/
120 extern int NDECL(dotalk); /**/
121 extern int NDECL(docast); /**/
122 extern int NDECL(dovspell); /**/
123 extern int NDECL(dotelecmd); /**/
124 extern int NDECL(dountrap); /**/
125 extern int NDECL(doversion); /**/
126 extern int NDECL(doextversion); /**/
127 extern int NDECL(doswapweapon); /**/
128 extern int NDECL(dowield); /**/
129 extern int NDECL(dowieldquiver); /**/
130 extern int NDECL(dozap); /**/
131 extern int NDECL(doorganize); /**/
134 static int NDECL((*timed_occ_fn));
136 STATIC_PTR int NDECL(dosuspend_core);
137 STATIC_PTR int NDECL(dosh_core);
138 STATIC_PTR int NDECL(doherecmdmenu);
139 STATIC_PTR int NDECL(dotherecmdmenu);
140 STATIC_PTR int NDECL(doprev_message);
141 STATIC_PTR int NDECL(timed_occupation);
142 STATIC_PTR int NDECL(doextcmd);
143 STATIC_PTR int NDECL(dotravel);
144 STATIC_PTR int NDECL(doterrain);
145 STATIC_PTR int NDECL(wiz_wish);
146 STATIC_PTR int NDECL(wiz_identify);
147 STATIC_PTR int NDECL(wiz_intrinsic);
148 STATIC_PTR int NDECL(wiz_map);
149 STATIC_PTR int NDECL(wiz_makemap);
150 STATIC_PTR int NDECL(wiz_genesis);
151 STATIC_PTR int NDECL(wiz_where);
152 STATIC_PTR int NDECL(wiz_detect);
153 STATIC_PTR int NDECL(wiz_panic);
154 STATIC_PTR int NDECL(wiz_polyself);
155 STATIC_PTR int NDECL(wiz_level_tele);
156 STATIC_PTR int NDECL(wiz_level_change);
157 STATIC_PTR int NDECL(wiz_show_seenv);
158 STATIC_PTR int NDECL(wiz_show_vision);
159 STATIC_PTR int NDECL(wiz_smell);
160 STATIC_PTR int NDECL(wiz_intrinsic);
161 STATIC_PTR int NDECL(wiz_show_wmodes);
162 STATIC_DCL void NDECL(wiz_map_levltyp);
163 STATIC_DCL void NDECL(wiz_levltyp_legend);
164 #if defined(__BORLANDC__) && !defined(_WIN32)
165 extern void FDECL(show_borlandc_stats, (winid));
167 #ifdef DEBUG_MIGRATING_MONS
168 STATIC_PTR int NDECL(wiz_migrate_mons);
170 STATIC_DCL int FDECL(size_monst, (struct monst *, BOOLEAN_P));
171 STATIC_DCL int FDECL(size_obj, (struct obj *));
172 STATIC_DCL void FDECL(count_obj, (struct obj *, long *, long *,
173 BOOLEAN_P, BOOLEAN_P));
174 STATIC_DCL void FDECL(obj_chain, (winid, const char *, struct obj *,
175 BOOLEAN_P, long *, long *));
176 STATIC_DCL void FDECL(mon_invent_chain, (winid, const char *, struct monst *,
178 STATIC_DCL void FDECL(mon_chain, (winid, const char *, struct monst *,
179 BOOLEAN_P, long *, long *));
180 STATIC_DCL void FDECL(contained_stats, (winid, const char *, long *, long *));
181 STATIC_DCL void FDECL(misc_stats, (winid, long *, long *));
182 STATIC_PTR int NDECL(wiz_show_stats);
183 STATIC_DCL boolean FDECL(accept_menu_prefix, (int NDECL((*))));
184 STATIC_PTR int NDECL(wiz_rumor_check);
185 STATIC_PTR int NDECL(doattributes);
187 STATIC_DCL void FDECL(enlght_out, (const char *));
188 STATIC_DCL void FDECL(enlght_line, (const char *, const char *, const char *,
190 STATIC_DCL char *FDECL(enlght_combatinc, (const char *, int, int, char *));
191 STATIC_DCL void FDECL(enlght_halfdmg, (int, int));
192 STATIC_DCL boolean NDECL(walking_on_water);
193 STATIC_DCL boolean FDECL(cause_known, (int));
194 STATIC_DCL char *FDECL(attrval, (int, int, char *));
195 STATIC_DCL void FDECL(background_enlightenment, (int, int));
196 STATIC_DCL void FDECL(basics_enlightenment, (int, int));
197 STATIC_DCL void FDECL(characteristics_enlightenment, (int, int));
198 STATIC_DCL void FDECL(one_characteristic, (int, int, int));
199 STATIC_DCL void FDECL(status_enlightenment, (int, int));
200 STATIC_DCL void FDECL(attributes_enlightenment, (int, int));
202 STATIC_DCL void FDECL(add_herecmd_menuitem, (winid, int NDECL((*)),
204 STATIC_DCL char FDECL(here_cmd_menu, (BOOLEAN_P));
205 STATIC_DCL char FDECL(there_cmd_menu, (BOOLEAN_P, int, int));
206 STATIC_DCL char *NDECL(parse);
207 STATIC_DCL void FDECL(show_direction_keys, (winid, CHAR_P, BOOLEAN_P));
208 STATIC_DCL boolean FDECL(help_dir, (CHAR_P, int, const char *));
210 static const char *readchar_queue = "";
211 static coord clicklook_cc;
212 /* for rejecting attempts to use wizard mode commands */
214 static const char unavailcmd[] = "Unavailable command '%s'.";
216 static const char unavailcmd[] = "'%s'
\83R
\83}
\83\93\83h
\82Í
\8eg
\82¦
\82È
\82¢
\81D";
217 /* for rejecting #if !SHELL, !SUSPEND */
219 static const char cmdnotavail[] = "'%s' command not available.";
221 static const char cmdnotavail[] = "'%s'
\83R
\83}
\83\93\83h
\82Í
\97\98\97p
\82Å
\82«
\82Ü
\82¹
\82ñ
\81D";
224 doprev_message(VOID_ARGS)
226 return nh_doprev_message();
229 /* Count down by decrementing multi */
231 timed_occupation(VOID_ARGS)
239 /* If you have moved since initially setting some occupations, they
240 * now shouldn't be able to restart.
242 * The basic rule is that if you are carrying it, you can continue
243 * since it is with you. If you are acting on something at a distance,
244 * your orientation to it must have changed when you moved.
246 * The exception to this is taking off items, since they can be taken
247 * off in a number of ways in the intervening time, screwing up ordering.
249 * Currently: Take off all armor.
250 * Picking Locks / Forcing Chests.
261 /* If a time is given, use it to timeout this function, otherwise the
262 * function times out by its own means.
265 set_occupation(fn, txt, xtime)
271 occupation = timed_occupation;
280 STATIC_DCL char NDECL(popch);
282 /* Provide a means to redo the last command. The flag `in_doagain' is set
283 * to true while redoing the command. This flag is tested in commands that
284 * require additional input (like `throw' which requires a thing and a
285 * direction), and the input prompt is not shown. Also, while in_doagain is
286 * TRUE, no keystrokes can be saved into the saveq.
289 static char pushq[BSIZE], saveq[BSIZE];
290 static NEARDATA int phead, ptail, shead, stail;
295 /* If occupied, return '\0', letting tgetch know a character should
296 * be read from the keyboard. If the character read is not the
297 * ABORT character (as checked in pcmain.c), that character will be
298 * pushed back on the pushq.
303 return (char) ((shead != stail) ? saveq[stail++] : '\0');
305 return (char) ((phead != ptail) ? pushq[ptail++] : '\0');
309 pgetchar() /* courtesy of aeb@cwi.nl */
313 if (iflags.debug_fuzzer)
320 /* A ch == 0 resets the pushq */
332 /* A ch == 0 resets the saveq. Only save keystrokes when not
333 * replaying a previous command.
341 phead = ptail = shead = stail = 0;
342 else if (shead < BSIZE)
348 /* here after # - now read a full-word command */
355 /* keep repeating until we don't run help or quit */
361 func = extcmdlist[idx].ef_funct;
362 if (!wizard && (extcmdlist[idx].flags & WIZMODECMD)) {
364 You("can't do that.");
366 pline("
\82»
\82ê
\82Í
\82Å
\82«
\82Ü
\82¹
\82ñ
\81D");
369 if (iflags.menu_requested && !accept_menu_prefix(func)) {
371 pline("'%s' prefix has no effect for the %s command.",
372 visctrl(Cmd.spkeys[NHKF_REQMENU]),
373 extcmdlist[idx].ef_txt);
375 pline("'%s'
\90Ú
\93ª
\8e«
\82Í%s
\83R
\83}
\83\93\83h
\82É
\82Í
\96³
\8cø
\81D",
376 visctrl(Cmd.spkeys[NHKF_REQMENU]),
377 extcmdlist[idx].ef_txt);
379 iflags.menu_requested = FALSE;
382 } while (func == doextlist);
387 /* here after #? - now list all full-word commands and provid
388 some navigation capability through the long list */
392 register const struct ext_func_tab *efp;
393 char buf[BUFSZ], searchbuf[BUFSZ], promptbuf[QBUFSZ];
398 int menumode = 0, menushown[2], onelist = 0;
399 boolean redisplay = TRUE, search = FALSE;
401 static const char *headings[] = { "Extended commands",
402 "Debugging Extended Commands" };
404 static const char *headings[] = { "
\8ag
\92£
\83R
\83}
\83\93\83h",
405 "
\83f
\83o
\83b
\83O
\8ag
\92£
\83R
\83}
\83\93\83h" };
409 menuwin = create_nhwindow(NHW_MENU);
416 add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
417 "Extended Commands List", MENU_UNSELECTED);
419 add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
420 "
\8ag
\92£
\83R
\83}
\83\93\83h
\88ê
\97\97", MENU_UNSELECTED);
422 add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
423 "", MENU_UNSELECTED);
425 Strcpy(buf, menumode ? "Show" : "Hide");
426 Strcat(buf, " commands that don't autocomplete");
428 Strcat(buf, " (those not marked with [A])");
430 add_menu(menuwin, NO_GLYPH, &any, 'a', 0, ATR_NONE, buf,
435 /* was 's', but then using ':' handling within the interface
436 would only examine the two or three meta entries, not the
437 actual list of extended commands shown via separator lines;
438 having ':' as an explicit selector overrides the default
439 menu behavior for it; we retain 's' as a group accelerator */
440 add_menu(menuwin, NO_GLYPH, &any, ':', 's', ATR_NONE,
441 "Search extended commands", MENU_UNSELECTED);
443 Strcpy(buf, "Show all, clear search");
444 if (strlen(buf) + strlen(searchbuf) + strlen(" (\"\")") < QBUFSZ)
445 Sprintf(eos(buf), " (\"%s\")", searchbuf);
447 /* specifying ':' as a group accelerator here is mostly a
448 statement of intent (we'd like to accept it as a synonym but
449 also want to hide it from general menu use) because it won't
450 work for interfaces which support ':' to search; use as a
451 general menu command takes precedence over group accelerator */
452 add_menu(menuwin, NO_GLYPH, &any, 's', ':', ATR_NONE,
453 buf, MENU_UNSELECTED);
457 add_menu(menuwin, NO_GLYPH, &any, 'z', 0, ATR_NONE,
458 onelist ? "Show debugging commands in separate section"
459 : "Show all alphabetically, including debugging commands",
463 add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
464 "", MENU_UNSELECTED);
465 menushown[0] = menushown[1] = 0;
467 for (pass = 0; pass <= 1; ++pass) {
468 /* skip second pass if not in wizard mode or wizard mode
469 commands are being integrated into a single list */
470 if (pass == 1 && (onelist || !wizard))
472 for (efp = extcmdlist; efp->ef_txt; efp++) {
475 if ((efp->flags & CMD_NOT_AVAILABLE) != 0)
477 /* if hiding non-autocomplete commands, skip such */
478 if (menumode == 1 && (efp->flags & AUTOCOMPLETE) == 0)
480 /* if searching, skip this command if it doesn't match */
482 /* first try case-insensitive substring match */
483 && !strstri(efp->ef_txt, searchbuf)
484 && !strstri(efp->ef_desc, searchbuf)
485 /* wildcard support; most interfaces use case-insensitve
486 pmatch rather than regexp for menu searching */
487 && !pmatchi(searchbuf, efp->ef_txt)
488 && !pmatchi(searchbuf, efp->ef_desc))
490 /* skip wizard mode commands if not in wizard mode;
491 when showing two sections, skip wizard mode commands
492 in pass==0 and skip other commands in pass==1 */
493 wizc = (efp->flags & WIZMODECMD) != 0;
496 if (!onelist && pass != wizc)
499 /* We're about to show an item, have we shown the menu yet?
500 Doing menu in inner loop like this on demand avoids a
501 heading with no subordinate entries on the search
503 if (!menushown[pass]) {
504 Strcpy(buf, headings[pass]);
505 add_menu(menuwin, NO_GLYPH, &any, 0, 0,
506 iflags.menu_headings, buf, MENU_UNSELECTED);
509 Sprintf(buf, " %-14s %-3s %s",
511 (efp->flags & AUTOCOMPLETE) ? "[A]" : " ",
513 add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
514 buf, MENU_UNSELECTED);
518 add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
519 "", MENU_UNSELECTED);
521 if (*searchbuf && !n)
522 add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
523 "no matches", MENU_UNSELECTED);
525 end_menu(menuwin, (char *) 0);
526 n = select_menu(menuwin, PICK_ONE, &selected);
528 switch (selected[0].item.a_int) {
529 case 1: /* 'a': toggle show/hide non-autocomplete */
530 menumode = 1 - menumode; /* toggle 0 -> 1, 1 -> 0 */
533 case 2: /* ':' when not searching yet: enable search */
536 case 3: /* 's' when already searching: disable search */
541 case 4: /* 'z': toggle showing wizard mode commands separately */
544 onelist = 1 - onelist; /* toggle 0 -> 1, 1 -> 0 */
548 free((genericptr_t) selected);
554 Strcpy(promptbuf, "Extended command list search phrase");
555 Strcat(promptbuf, "?");
556 getlin(promptbuf, searchbuf);
557 (void) mungspaces(searchbuf);
558 if (searchbuf[0] == '\033')
565 destroy_nhwindow(menuwin);
569 #if defined(TTY_GRAPHICS) || defined(CURSES_GRAPHICS)
570 #define MAX_EXT_CMD 200 /* Change if we ever have more ext cmds */
573 * This is currently used only by the tty interface and is
574 * controlled via runtime option 'extmenu'. (Most other interfaces
575 * already use a menu all the time for extended commands.)
577 * ``# ?'' is counted towards the limit of the number of commands,
578 * so we actually support MAX_EXT_CMD-1 "real" extended commands.
580 * Here after # - now show pick-list of possible commands.
585 const struct ext_func_tab *efp;
586 menu_item *pick_list = (menu_item *) 0;
589 const struct ext_func_tab *choices[MAX_EXT_CMD + 1];
591 char cbuf[QBUFSZ], prompt[QBUFSZ], fmtstr[20];
592 int i, n, nchoices, acount;
593 int ret, len, biggest;
594 int accelerator, prevaccelerator;
596 boolean wastoolong, one_per_line;
604 /* populate choices */
605 for (efp = extcmdlist; efp->ef_txt; efp++) {
606 if ((efp->flags & CMD_NOT_AVAILABLE)
607 || !(efp->flags & AUTOCOMPLETE)
608 || (!wizard && (efp->flags & WIZMODECMD)))
610 if (!matchlevel || !strncmp(efp->ef_txt, cbuf, matchlevel)) {
612 if ((len = (int) strlen(efp->ef_desc)) > biggest)
614 if (++i > MAX_EXT_CMD) {
617 "Exceeded %d extended commands in doextcmd() menu; 'extmenu' disabled.",
625 choices[i] = (struct ext_func_tab *) 0;
627 /* if we're down to one, we have our selection so get out of here */
629 ret = (nchoices == 1) ? (int) (choices[0] - extcmdlist) : -1;
634 win = create_nhwindow(NHW_MENU);
636 Sprintf(fmtstr, "%%-%ds", biggest + 15);
638 wastoolong = FALSE; /* True => had to wrap due to line width
639 * ('w' in wizard mode) */
640 /* -3: two line menu header, 1 line menu footer (for prompt) */
641 one_per_line = (nchoices < ROWNO - 3);
642 accelerator = prevaccelerator = 0;
644 for (i = 0; choices[i]; ++i) {
645 accelerator = choices[i]->ef_txt[matchlevel];
646 if (accelerator != prevaccelerator || one_per_line)
648 if (accelerator != prevaccelerator || one_per_line
650 /* +4: + sizeof " or " - sizeof "" */
651 && (strlen(prompt) + 4 + strlen(choices[i]->ef_txt)
652 /* -6: enough room for 1 space left margin
653 * + "%c - " menu selector + 1 space right margin */
654 >= min(sizeof prompt, COLNO - 6)))) {
656 /* flush extended cmds for that letter already in buf */
657 Sprintf(buf, fmtstr, prompt);
658 any.a_char = prevaccelerator;
659 add_menu(win, NO_GLYPH, &any, any.a_char, 0, ATR_NONE,
662 if (!(accelerator != prevaccelerator || one_per_line))
666 prevaccelerator = accelerator;
667 if (!acount || one_per_line) {
669 Sprintf(prompt, "%s%s [%s]", wastoolong ? "or " : "",
670 choices[i]->ef_txt, choices[i]->ef_desc);
672 Sprintf(prompt, "%s%s [%s]", wastoolong ? "
\82Ü
\82½
\82Í" : "",
673 choices[i]->ef_txt, choices[i]->ef_desc);
675 } else if (acount == 1) {
677 Sprintf(prompt, "%s%s or %s", wastoolong ? "or " : "",
678 choices[i - 1]->ef_txt, choices[i]->ef_txt);
680 Sprintf(prompt, "%s%s
\82Ü
\82½
\82Í%s", wastoolong ? "
\82Ü
\82½
\82Í" : "",
681 choices[i - 1]->ef_txt, choices[i]->ef_txt);
685 Strcat(prompt, " or ");
687 Strcat(prompt,"
\82Ü
\82½
\82Í ");
688 Strcat(prompt, choices[i]->ef_txt);
694 Sprintf(buf, fmtstr, prompt);
695 any.a_char = prevaccelerator;
696 add_menu(win, NO_GLYPH, &any, any.a_char, 0, ATR_NONE, buf,
700 Sprintf(prompt, "Extended Command: %s", cbuf);
702 Sprintf(prompt, "
\8ag
\92£
\83R
\83}
\83\93\83h: %s", cbuf);
703 end_menu(win, prompt);
704 n = select_menu(win, PICK_ONE, &pick_list);
705 destroy_nhwindow(win);
707 if (matchlevel > (QBUFSZ - 2)) {
708 free((genericptr_t) pick_list);
710 impossible("Too many chars (%d) entered in extcmd_via_menu()",
715 cbuf[matchlevel++] = pick_list[0].item.a_char;
716 cbuf[matchlevel] = '\0';
717 free((genericptr_t) pick_list);
729 #endif /* TTY_GRAPHICS */
731 /* #monster command - use special monster ability while polymorphed */
733 domonability(VOID_ARGS)
735 if (can_breathe(youmonst.data))
737 else if (attacktype(youmonst.data, AT_SPIT))
739 else if (youmonst.data->mlet == S_NYMPH)
741 else if (attacktype(youmonst.data, AT_GAZE))
743 else if (is_were(youmonst.data))
745 else if (webmaker(youmonst.data))
747 else if (is_hider(youmonst.data))
749 else if (is_mind_flayer(youmonst.data))
750 return domindblast();
751 else if (u.umonnum == PM_GREMLIN) {
752 if (IS_FOUNTAIN(levl[u.ux][u.uy].typ)) {
753 if (split_mon(&youmonst, (struct monst *) 0))
754 dryup(u.ux, u.uy, TRUE);
757 There("is no fountain here.");
759 pline("
\82±
\82±
\82É
\82Í
\90ò
\82Í
\82È
\82¢
\81D");
760 } else if (is_unicorn(youmonst.data)) {
761 use_unicorn_horn((struct obj *) 0);
763 } else if (youmonst.data->msound == MS_SHRIEK) {
767 You("
\8bà
\90Ø
\82è
\90º
\82ð
\82 \82°
\82½
\81D");
770 pline("Unfortunately sound does not carry well through rock.");
772 pline("
\8ec
\94O
\82È
\82ª
\82ç
\89¹
\82Í
\8aâ
\82ð
\82¤
\82Ü
\82
\93`
\82í
\82ç
\82È
\82¢
\81D");
775 } else if (youmonst.data->mlet == S_VAMPIRE)
779 pline("Any special ability you may have is purely reflexive.");
781 pline("
\82 \82È
\82½
\82Ì
\8e\9d\82Á
\82Ä
\82¢
\82é
\93Á
\8eê
\94\
\97Í
\82Í
\82Ç
\82ê
\82à
\8eó
\93®
\93I
\82¾
\81D");
784 You("don't have a special ability in your normal form!");
786 You("
\95\81\92i
\82Ì
\8ep
\82Å
\82Ì
\93Á
\8eê
\94\
\97Í
\82ð
\8e\9d\82Á
\82Ä
\82¢
\82È
\82¢
\81I");
791 enter_explore_mode(VOID_ARGS)
795 You("are in debug mode.");
797 You("
\82·
\82Å
\82É
\83f
\83o
\83b
\83O
\83\82\81[
\83h
\82¾
\81D");
798 } else if (discover) {
800 You("are already in explore mode.");
802 You("
\82·
\82Å
\82É
\92T
\8c\9f\83\82\81[
\83h
\82¾
\81D");
806 if (!sysopt.explorers || !sysopt.explorers[0]
807 || !check_user_string(sysopt.explorers)) {
809 You("cannot access explore mode.");
811 You("
\92T
\8c\9f\83\82\81[
\83h
\82É
\83A
\83N
\83Z
\83X
\82Å
\82«
\82È
\82¢
\81D");
818 "Beware! From explore mode there will be no return to normal game.");
820 "
\8cx
\8d\90\81I
\94
\8c©
\83\82\81[
\83h
\82É
\93ü
\82Á
\82½
\82ç
\92Ê
\8fí
\83\82\81[
\83h
\82É
\82Í
\96ß
\82ê
\82È
\82¢
\81D");
821 if (paranoid_query(ParanoidQuit,
823 "Do you want to enter explore mode?")) {
825 "
\94
\8c©
\83\82\81[
\83h
\82É
\88Ú
\82è
\82Ü
\82·
\82©
\81H")) {
826 clear_nhwindow(WIN_MESSAGE);
828 You("are now in non-scoring explore mode.");
830 You("
\83X
\83R
\83A
\82ª
\82Ì
\82ç
\82È
\82¢
\94
\8c©
\83\82\81[
\83h
\82É
\88Ú
\8ds
\82µ
\82½
\81D");
833 clear_nhwindow(WIN_MESSAGE);
835 pline("Resuming normal game.");
837 pline("
\92Ê
\8fí
\83\82\81[
\83h
\82ð
\91±
\82¯
\82é
\81D");
843 /* ^W command - wish for something */
845 wiz_wish(VOID_ARGS) /* Unlimited wishes for debug mode by Paul Polderman */
848 boolean save_verbose = flags.verbose;
850 flags.verbose = FALSE;
852 flags.verbose = save_verbose;
853 (void) encumber_msg();
855 pline(unavailcmd, visctrl((int) cmd_from_func(wiz_wish)));
859 /* ^I command - reveal and optionally identify hero's inventory */
861 wiz_identify(VOID_ARGS)
864 iflags.override_ID = (int) cmd_from_func(wiz_identify);
865 /* command remapping might leave #wizidentify as the only way
866 to invoke us, in which case cmd_from_func() will yield NUL;
867 it won't matter to display_inventory()/display_pickinv()
868 if ^I invokes some other command--what matters is that
869 display_pickinv() and xname() see override_ID as nonzero */
870 if (!iflags.override_ID)
871 iflags.override_ID = C('I');
872 (void) display_inventory((char *) 0, FALSE);
873 iflags.override_ID = 0;
875 pline(unavailcmd, visctrl((int) cmd_from_func(wiz_identify)));
879 /* #wizmakemap - discard current dungeon level and replace with a new one */
881 wiz_makemap(VOID_ARGS)
885 boolean was_in_W_tower = In_W_tower(u.ux, u.uy, &u.uz);
887 rm_mapseen(ledger_no(&u.uz));
888 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
889 if (mtmp->isgd) { /* vault is going away; get rid of guard */
893 if (DEADMONSTER(mtmp))
898 * Reduce 'born' tally for each monster about to be discarded
899 * by savelev(), otherwise replacing heavily populated levels
900 * tends to make their inhabitants become extinct.
907 /* reset lock picking unless it's for a carried container */
908 maybe_reset_pick((struct obj *) 0);
909 /* reset interrupted digging if it was taking place on this level */
910 if (on_level(&context.digging.level, &u.uz))
911 (void) memset((genericptr_t) &context.digging, 0,
912 sizeof (struct dig_info));
913 /* reset cached targets */
914 iflags.travelcc.x = iflags.travelcc.y = 0; /* travel destination */
915 context.polearm.hitmon = (struct monst *) 0; /* polearm target */
916 /* escape from trap */
918 check_special_room(TRUE); /* room exit */
919 u.ustuck = (struct monst *) 0;
922 u.uundetected = 0; /* not hidden, even if means are available */
923 dmonsfree(); /* purge dead monsters from 'fmon' */
924 /* keep steed and other adjacent pets after releasing them
925 from traps, stopping eating, &c as if hero were ascending */
926 keepdogs(TRUE); /* (pets-only; normally we'd be using 'FALSE' here) */
928 /* discard current level; "saving" is used to release dynamic data */
929 savelev(-1, ledger_no(&u.uz), FREE_SAVE);
930 /* create a new level; various things like bestowing a guardian
931 angel on Astral or setting off alarm on Ft.Ludios are handled
932 by goto_level(do.c) so won't occur for replacement levels */
936 vision_full_recalc = 1;
938 /* was using safe_teleds() but that doesn't honor arrival region
939 on levels which have such; we don't force stairs, just area */
940 u_on_rndspot((u.uhave.amulet ? 1 : 0) /* 'going up' flag */
941 | (was_in_W_tower ? 2 : 0));
943 /* u_on_rndspot() might pick a spot that has a monster, or losedogs()
944 might pick the hero's spot (only if there isn't already a monster
945 there), so we might have to move hero or the co-located monster */
946 if ((mtmp = m_at(u.ux, u.uy)) != 0)
955 deliver_splev_message(); /* level entry */
956 check_special_room(FALSE); /* room entry */
961 pline(unavailcmd, "#wizmakemap");
966 /* ^F command - reveal the level map and any traps on it */
972 long save_Hconf = HConfusion, save_Hhallu = HHallucination;
974 HConfusion = HHallucination = 0L;
975 for (t = ftrap; t != 0; t = t->ntrap) {
980 HConfusion = save_Hconf;
981 HHallucination = save_Hhallu;
983 pline(unavailcmd, visctrl((int) cmd_from_func(wiz_map)));
987 /* ^G command - generate monster(s); a count prefix will be honored */
989 wiz_genesis(VOID_ARGS)
992 (void) create_particular();
994 pline(unavailcmd, visctrl((int) cmd_from_func(wiz_genesis)));
998 /* ^O command - display dungeon layout */
1000 wiz_where(VOID_ARGS)
1003 (void) print_dungeon(FALSE, (schar *) 0, (xchar *) 0);
1005 pline(unavailcmd, visctrl((int) cmd_from_func(wiz_where)));
1009 /* ^E command - detect unseen (secret doors, traps, hidden monsters) */
1011 wiz_detect(VOID_ARGS)
1016 pline(unavailcmd, visctrl((int) cmd_from_func(wiz_detect)));
1020 /* ^V command - level teleport */
1022 wiz_level_tele(VOID_ARGS)
1027 pline(unavailcmd, visctrl((int) cmd_from_func(wiz_level_tele)));
1031 /* #levelchange command - adjust hero's experience level */
1033 wiz_level_change(VOID_ARGS)
1035 char buf[BUFSZ] = DUMMY;
1040 getlin("To what experience level do you want to be set?", buf);
1042 getlin("
\8co
\8c±
\83\8c\83x
\83\8b\82ð
\82¢
\82
\82Â
\82É
\90Ý
\92è
\82µ
\82Ü
\82·
\82©
\81H", buf);
1043 (void) mungspaces(buf);
1044 if (buf[0] == '\033' || buf[0] == '\0')
1047 ret = sscanf(buf, "%d", &newlevel);
1053 if (newlevel == u.ulevel) {
1055 You("are already that experienced.");
1057 You("
\82·
\82Å
\82É
\82»
\82Ì
\8co
\8c±
\83\8c\83x
\83\8b\82¾
\81D");
1058 } else if (newlevel < u.ulevel) {
1059 if (u.ulevel == 1) {
1061 You("are already as inexperienced as you can get.");
1063 You("
\82·
\82Å
\82É
\89Â
\94\
\82È
\8cÀ
\82è
\82Ì
\8dÅ
\92á
\82Ì
\8co
\8c±
\83\8c\83x
\83\8b\82¾
\81D");
1068 while (u.ulevel > newlevel)
1070 losexp("#levelchange");
1072 losexp("#levelchange
\83R
\83}
\83\93\83h
\82Å");
1074 if (u.ulevel >= MAXULEV) {
1076 You("are already as experienced as you can get.");
1078 You("
\82·
\82Å
\82É
\89Â
\94\
\82È
\8cÀ
\82è
\82Ì
\8dÅ
\91å
\82Ì
\8co
\8c±
\83\8c\83x
\83\8b\82¾
\81D");
1081 if (newlevel > MAXULEV)
1083 while (u.ulevel < newlevel)
1086 u.ulevelmax = u.ulevel;
1090 /* #panic command - test program's panic handling */
1092 wiz_panic(VOID_ARGS)
1094 if (iflags.debug_fuzzer) {
1095 u.uhp = u.uhpmax = 1000;
1096 u.uen = u.uenmax = 1000;
1100 if (yn("Do you want to call panic() and end your game?") == 'y')
1102 if (yn("panic()
\8aÖ
\90\94\82ð
\8cÄ
\82Ñ
\8fo
\82µ
\82Ä
\83Q
\81[
\83\80\82ð
\8fI
\97¹
\82³
\82¹
\82Ü
\82·
\82©
\81H") == 'y')
1103 panic("Crash test.");
1107 /* #polyself command - change hero's form */
1109 wiz_polyself(VOID_ARGS)
1115 /* #seenv command */
1117 wiz_show_seenv(VOID_ARGS)
1120 int x, y, v, startx, stopx, curx;
1121 char row[COLNO + 1];
1123 win = create_nhwindow(NHW_TEXT);
1125 * Each seenv description takes up 2 characters, so center
1126 * the seenv display around the hero.
1128 startx = max(1, u.ux - (COLNO / 4));
1129 stopx = min(startx + (COLNO / 2), COLNO);
1130 /* can't have a line exactly 80 chars long */
1131 if (stopx - startx == COLNO / 2)
1134 for (y = 0; y < ROWNO; y++) {
1135 for (x = startx, curx = 0; x < stopx; x++, curx += 2) {
1136 if (x == u.ux && y == u.uy) {
1137 row[curx] = row[curx + 1] = '@';
1139 v = levl[x][y].seenv & 0xff;
1141 row[curx] = row[curx + 1] = ' ';
1143 Sprintf(&row[curx], "%02x", v);
1146 /* remove trailing spaces */
1147 for (x = curx - 1; x >= 0; x--)
1152 putstr(win, 0, row);
1154 display_nhwindow(win, TRUE);
1155 destroy_nhwindow(win);
1159 /* #vision command */
1161 wiz_show_vision(VOID_ARGS)
1165 char row[COLNO + 1];
1167 win = create_nhwindow(NHW_TEXT);
1168 Sprintf(row, "Flags: 0x%x could see, 0x%x in sight, 0x%x temp lit",
1169 COULD_SEE, IN_SIGHT, TEMP_LIT);
1170 putstr(win, 0, row);
1172 for (y = 0; y < ROWNO; y++) {
1173 for (x = 1; x < COLNO; x++) {
1174 if (x == u.ux && y == u.uy)
1177 v = viz_array[y][x]; /* data access should be hidden */
1181 row[x] = '0' + viz_array[y][x];
1184 /* remove trailing spaces */
1185 for (x = COLNO - 1; x >= 1; x--)
1190 putstr(win, 0, &row[1]);
1192 display_nhwindow(win, TRUE);
1193 destroy_nhwindow(win);
1197 /* #wmode command */
1199 wiz_show_wmodes(VOID_ARGS)
1203 char row[COLNO + 1];
1205 boolean istty = WINDOWPORT("tty");
1207 win = create_nhwindow(NHW_TEXT);
1209 putstr(win, 0, ""); /* tty only: blank top line */
1210 for (y = 0; y < ROWNO; y++) {
1211 for (x = 0; x < COLNO; x++) {
1213 if (x == u.ux && y == u.uy)
1215 else if (IS_WALL(lev->typ) || lev->typ == SDOOR)
1216 row[x] = '0' + (lev->wall_info & WM_MASK);
1217 else if (lev->typ == CORR)
1219 else if (IS_ROOM(lev->typ) || IS_DOOR(lev->typ))
1225 /* map column 0, levl[0][], is off the left edge of the screen */
1226 putstr(win, 0, &row[1]);
1228 display_nhwindow(win, TRUE);
1229 destroy_nhwindow(win);
1233 /* wizard mode variant of #terrain; internal levl[][].typ values in base-36 */
1235 wiz_map_levltyp(VOID_ARGS)
1239 char row[COLNO + 1];
1240 boolean istty = !strcmp(windowprocs.name, "tty");
1242 win = create_nhwindow(NHW_TEXT);
1243 /* map row 0, levl[][0], is drawn on the second line of tty screen */
1245 putstr(win, 0, ""); /* tty only: blank top line */
1246 for (y = 0; y < ROWNO; y++) {
1247 /* map column 0, levl[0][], is off the left edge of the screen;
1248 it should always have terrain type "undiggable stone" */
1249 for (x = 1; x < COLNO; x++) {
1250 terrain = levl[x][y].typ;
1251 /* assumes there aren't more than 10+26+26 terrain types */
1252 row[x - 1] = (char) ((terrain == STONE && !may_dig(x, y))
1257 ? 'a' + terrain - 10
1258 : 'A' + terrain - 36);
1261 if (levl[0][y].typ != STONE || may_dig(0, y))
1264 putstr(win, 0, row);
1269 s_level *slev = Is_special(&u.uz);
1271 Sprintf(dsc, "D:%d,L:%d", u.uz.dnum, u.uz.dlevel);
1272 /* [dungeon branch features currently omitted] */
1273 /* special level features */
1275 Sprintf(eos(dsc), " \"%s\"", slev->proto);
1276 /* special level flags (note: dungeon.def doesn't set `maze'
1277 or `hell' for any specific levels so those never show up) */
1278 if (slev->flags.maze_like)
1279 Strcat(dsc, " mazelike");
1280 if (slev->flags.hellish)
1281 Strcat(dsc, " hellish");
1282 if (slev->flags.town)
1283 Strcat(dsc, " town");
1284 if (slev->flags.rogue_like)
1285 Strcat(dsc, " roguelike");
1286 /* alignment currently omitted to save space */
1288 /* level features */
1289 if (level.flags.nfountains)
1290 Sprintf(eos(dsc), " %c:%d", defsyms[S_fountain].sym,
1291 (int) level.flags.nfountains);
1292 if (level.flags.nsinks)
1293 Sprintf(eos(dsc), " %c:%d", defsyms[S_sink].sym,
1294 (int) level.flags.nsinks);
1295 if (level.flags.has_vault)
1296 Strcat(dsc, " vault");
1297 if (level.flags.has_shop)
1298 Strcat(dsc, " shop");
1299 if (level.flags.has_temple)
1300 Strcat(dsc, " temple");
1301 if (level.flags.has_court)
1302 Strcat(dsc, " throne");
1303 if (level.flags.has_zoo)
1304 Strcat(dsc, " zoo");
1305 if (level.flags.has_morgue)
1306 Strcat(dsc, " morgue");
1307 if (level.flags.has_barracks)
1308 Strcat(dsc, " barracks");
1309 if (level.flags.has_beehive)
1310 Strcat(dsc, " hive");
1311 if (level.flags.has_swamp)
1312 Strcat(dsc, " swamp");
1314 if (level.flags.noteleport)
1315 Strcat(dsc, " noTport");
1316 if (level.flags.hardfloor)
1317 Strcat(dsc, " noDig");
1318 if (level.flags.nommap)
1319 Strcat(dsc, " noMMap");
1320 if (!level.flags.hero_memory)
1321 Strcat(dsc, " noMem");
1322 if (level.flags.shortsighted)
1323 Strcat(dsc, " shortsight");
1324 if (level.flags.graveyard)
1325 Strcat(dsc, " graveyard");
1326 if (level.flags.is_maze_lev)
1327 Strcat(dsc, " maze");
1328 if (level.flags.is_cavernous_lev)
1329 Strcat(dsc, " cave");
1330 if (level.flags.arboreal)
1331 Strcat(dsc, " tree");
1333 Strcat(dsc, " sokoban-rules");
1334 /* non-flag info; probably should include dungeon branching
1335 checks (extra stairs and magic portals) here */
1336 if (Invocation_lev(&u.uz))
1337 Strcat(dsc, " invoke");
1338 if (On_W_tower_level(&u.uz))
1339 Strcat(dsc, " tower");
1340 /* append a branch identifier for completeness' sake */
1342 Strcat(dsc, " dungeon");
1343 else if (u.uz.dnum == mines_dnum)
1344 Strcat(dsc, " mines");
1345 else if (In_sokoban(&u.uz))
1346 Strcat(dsc, " sokoban");
1347 else if (u.uz.dnum == quest_dnum)
1348 Strcat(dsc, " quest");
1349 else if (Is_knox(&u.uz))
1350 Strcat(dsc, " ludios");
1351 else if (u.uz.dnum == 1)
1352 Strcat(dsc, " gehennom");
1353 else if (u.uz.dnum == tower_dnum)
1354 Strcat(dsc, " vlad");
1355 else if (In_endgame(&u.uz))
1356 Strcat(dsc, " endgame");
1358 /* somebody's added a dungeon branch we're not expecting */
1359 const char *brname = dungeons[u.uz.dnum].dname;
1361 if (!brname || !*brname)
1363 if (!strncmpi(brname, "the ", 4))
1365 Sprintf(eos(dsc), " %s", brname);
1367 /* limit the line length to map width */
1368 if (strlen(dsc) >= COLNO)
1369 dsc[COLNO - 1] = '\0'; /* truncate */
1370 putstr(win, 0, dsc);
1373 display_nhwindow(win, TRUE);
1374 destroy_nhwindow(win);
1378 /* temporary? hack, since level type codes aren't the same as screen
1379 symbols and only the latter have easily accessible descriptions */
1380 static const char *levltyp[] = {
1381 "stone", "vertical wall", "horizontal wall", "top-left corner wall",
1382 "top-right corner wall", "bottom-left corner wall",
1383 "bottom-right corner wall", "cross wall", "tee-up wall", "tee-down wall",
1384 "tee-left wall", "tee-right wall", "drawbridge wall", "tree",
1385 "secret door", "secret corridor", "pool", "moat", "water",
1386 "drawbridge up", "lava pool", "iron bars", "door", "corridor", "room",
1387 "stairs", "ladder", "fountain", "throne", "sink", "grave", "altar", "ice",
1388 "drawbridge down", "air", "cloud",
1389 /* not a real terrain type, but used for undiggable stone
1390 by wiz_map_levltyp() */
1391 "unreachable/undiggable",
1392 /* padding in case the number of entries above is odd */
1396 /* explanation of base-36 output from wiz_map_levltyp() */
1398 wiz_levltyp_legend(VOID_ARGS)
1402 const char *dsc, *fmt;
1405 win = create_nhwindow(NHW_TEXT);
1406 putstr(win, 0, "#terrain encodings:");
1408 fmt = " %c - %-28s"; /* TODO: include tab-separated variant for win32 */
1410 /* output in pairs, left hand column holds [0],[1],...,[N/2-1]
1411 and right hand column holds [N/2],[N/2+1],...,[N-1];
1412 N ('last') will always be even, and may or may not include
1413 the empty string entry to pad out the final pair, depending
1414 upon how many other entries are present in levltyp[] */
1415 last = SIZE(levltyp) & ~1;
1416 for (i = 0; i < last / 2; ++i)
1417 for (j = i; j < last; j += last / 2) {
1420 : !strncmp(dsc, "unreachable", 11) ? '*'
1421 /* same int-to-char conversion as wiz_map_levltyp() */
1422 : (j < 10) ? '0' + j
1423 : (j < 36) ? 'a' + j - 10
1425 Sprintf(eos(buf), fmt, c, dsc);
1427 putstr(win, 0, buf);
1431 display_nhwindow(win, TRUE);
1432 destroy_nhwindow(win);
1436 /* #wizsmell command - test usmellmon(). */
1438 wiz_smell(VOID_ARGS)
1441 int mndx; /* monster index */
1442 coord cc; /* screen pos of unknown glyph */
1443 int glyph; /* glyph at selected position */
1447 mndx = 0; /* gcc -Wall lint */
1448 if (!olfaction(youmonst.data)) {
1449 You("are incapable of detecting odors in your present form.");
1453 pline("You can move the cursor to a monster that you want to smell.");
1455 pline("Pick a monster to smell.");
1456 ans = getpos(&cc, TRUE, "a monster");
1457 if (ans < 0 || cc.x < 0) {
1458 return 0; /* done */
1460 /* Convert the glyph at the selected position to a mndxbol. */
1461 glyph = glyph_at(cc.x, cc.y);
1462 if (glyph_is_monster(glyph))
1463 mndx = glyph_to_mon(glyph);
1466 /* Is it a monster? */
1468 if (!usmellmon(&mons[mndx]))
1469 pline("That monster seems to give off no smell.");
1471 pline("That is not a monster.");
1476 /* #wizinstrinsic command to set some intrinsics for testing */
1478 wiz_intrinsic(VOID_ARGS)
1481 extern const struct propname {
1483 const char *prop_name;
1484 } propertynames[]; /* timeout.c */
1485 static const char wizintrinsic[] = "#wizintrinsic";
1486 static const char fmt[] = "You are%s %s.";
1490 int i, j, n, p, amt, typ;
1491 long oldtimeout, newtimeout;
1492 const char *propname;
1493 menu_item *pick_list = (menu_item *) 0;
1496 win = create_nhwindow(NHW_MENU);
1498 for (i = 0; (propname = propertynames[i].prop_name) != 0; ++i) {
1499 p = propertynames[i].prop_num;
1500 if (p == HALLUC_RES) {
1501 /* Grayswandir vs hallucination; ought to be redone to
1502 use u.uprops[HALLUC].blocked instead of being treated
1503 as a separate property; letting in be manually toggled
1504 even only in wizard mode would be asking for trouble... */
1507 if (p == FIRE_RES) {
1509 add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, "--", FALSE);
1511 any.a_int = i + 1; /* +1: avoid 0 */
1512 oldtimeout = u.uprops[p].intrinsic & TIMEOUT;
1514 Sprintf(buf, "%-27s [%li]", propname, oldtimeout);
1516 Sprintf(buf, "%s", propname);
1517 add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
1519 end_menu(win, "Which intrinsics?");
1520 n = select_menu(win, PICK_ANY, &pick_list);
1521 destroy_nhwindow(win);
1523 amt = 30; /* TODO: prompt for duration */
1524 for (j = 0; j < n; ++j) {
1525 i = pick_list[j].item.a_int - 1; /* -1: reverse +1 above */
1526 p = propertynames[i].prop_num;
1527 oldtimeout = u.uprops[p].intrinsic & TIMEOUT;
1528 newtimeout = oldtimeout + (long) amt;
1533 if (oldtimeout > 0L && newtimeout > oldtimeout)
1534 newtimeout = oldtimeout;
1540 make_blinded(newtimeout, TRUE);
1542 #if 0 /* make_confused() only gives feedback when confusion is
1543 * ending so use the 'default' case for it instead */
1545 make_confused(newtimeout, TRUE);
1549 make_deaf(newtimeout, TRUE);
1552 make_hallucinated(newtimeout, TRUE, 0L);
1555 typ = !rn2(2) ? SICK_VOMITABLE : SICK_NONVOMITABLE;
1556 make_sick(newtimeout, wizintrinsic, TRUE, typ);
1560 !Slimed ? "" : " still", "turning into slime");
1561 make_slimed(newtimeout, buf);
1565 !Stoned ? "" : " still", "turning into stone");
1566 make_stoned(newtimeout, buf, KILLED_BY, wizintrinsic);
1569 make_stunned(newtimeout, TRUE);
1572 Sprintf(buf, fmt, !Vomiting ? "" : " still", "vomiting");
1573 make_vomiting(newtimeout, FALSE);
1578 context.warntype.speciesidx = PM_GRID_BUG;
1579 context.warntype.species
1580 = &mons[context.warntype.speciesidx];
1589 pline("Timeout for %s %s %d.", propertynames[i].prop_name,
1590 oldtimeout ? "increased by" : "set to", amt);
1591 incr_itimeout(&u.uprops[p].intrinsic, amt);
1594 context.botl = 1; /* probably not necessary... */
1597 free((genericptr_t) pick_list);
1600 pline(unavailcmd, visctrl((int) cmd_from_func(wiz_intrinsic)));
1604 /* #wizrumorcheck command - verify each rumor access */
1606 wiz_rumor_check(VOID_ARGS)
1612 /* #terrain command -- show known map, inspired by crawl's '|' command */
1614 doterrain(VOID_ARGS)
1623 * normal play: choose between known map without mons, obj, and traps
1624 * (to see underlying terrain only), or
1625 * known map without mons and objs (to see traps under mons and objs), or
1626 * known map without mons (to see objects under monsters);
1627 * explore mode: normal choices plus full map (w/o mons, objs, traps);
1628 * wizard mode: normal and explore choices plus
1629 * a dump of the internal levl[][].typ codes w/ level flags, or
1630 * a legend for the levl[][].typ codes dump
1632 men = create_nhwindow(NHW_MENU);
1636 add_menu(men, NO_GLYPH, &any, 0, 0, ATR_NONE,
1638 "known map without monsters, objects, and traps",
1640 "
\89ö
\95¨
\81C
\95¨
\81Cã©
\82È
\82µ
\82Ì
\92n
\90}",
1643 add_menu(men, NO_GLYPH, &any, 0, 0, ATR_NONE,
1645 "known map without monsters and objects",
1647 "
\89ö
\95¨
\81C
\95¨
\82È
\82µ
\82Ì
\92n
\90}",
1650 add_menu(men, NO_GLYPH, &any, 0, 0, ATR_NONE,
1652 "known map without monsters",
1654 "
\89ö
\95¨
\82È
\82µ
\82Ì
\92n
\90}",
1656 if (discover || wizard) {
1658 add_menu(men, NO_GLYPH, &any, 0, 0, ATR_NONE,
1660 "full map without monsters, objects, and traps",
1662 "
\89ö
\95¨
\81C
\95¨
\81Cã©
\82È
\82µ
\82Ì
\8a®
\91S
\82È
\92n
\90}",
1666 add_menu(men, NO_GLYPH, &any, 0, 0, ATR_NONE,
1667 "internal levl[][].typ codes in base-36",
1670 add_menu(men, NO_GLYPH, &any, 0, 0, ATR_NONE,
1671 "legend of base-36 levl[][].typ codes",
1676 end_menu(men, "View which?");
1678 end_menu(men, "
\82Ç
\82ê
\82ð
\8c©
\82é
\81H");
1680 n = select_menu(men, PICK_ONE, &sel);
1681 destroy_nhwindow(men);
1683 * n < 0: player used ESC to cancel;
1684 * n == 0: preselected entry was explicitly chosen and got toggled off;
1685 * n == 1: preselected entry was implicitly chosen via <space>|<enter>;
1686 * n == 2: another entry was explicitly chosen, so skip preselected one.
1688 which = (n < 0) ? -1 : (n == 0) ? 1 : sel[0].item.a_int;
1689 if (n > 1 && which == 1)
1690 which = sel[1].item.a_int;
1692 free((genericptr_t) sel);
1695 case 1: /* known map */
1696 reveal_terrain(0, TER_MAP);
1698 case 2: /* known map with known traps */
1699 reveal_terrain(0, TER_MAP | TER_TRP);
1701 case 3: /* known map with known traps and objects */
1702 reveal_terrain(0, TER_MAP | TER_TRP | TER_OBJ);
1704 case 4: /* full map */
1705 reveal_terrain(1, TER_MAP);
1707 case 5: /* map internals */
1710 case 6: /* internal details */
1711 wiz_levltyp_legend();
1716 return 0; /* no time elapses */
1719 /* -enlightenment and conduct- */
1720 static winid en_win = WIN_ERR;
1721 static boolean en_via_menu = FALSE;
1723 static const char You_[] = "You ", are[] = "are ", were[] = "were ",
1724 have[] = "have ", had[] = "had ", can[] = "can ",
1727 static const char You_[] = "
\82 \82È
\82½
\82Í",
1728 are[] = "
\82Å
\82 \82é", were[] = "
\82Å
\82 \82Á
\82½",
1729 have[] = "
\82ð
\82à
\82Á
\82Ä
\82¢
\82é", had[] = "
\82ð
\82à
\82Á
\82Ä
\82¢
\82½",
1730 can[] = "
\82Å
\82«
\82é", could[] = "
\82Å
\82«
\82½",
1731 iru[] = "
\82¢
\82é", ita[] = "
\82¢
\82½";
1733 #if 0 /*JP*//* not used */
1734 static const char have_been[] = "have been ", have_never[] = "have never ",
1739 #define enl_msg(prefix, present, past, suffix, ps) \
1740 enlght_line(prefix, final ? past : present, suffix, ps)
1742 #define enl_msg(prefix, present, past, suffix, ps) \
1743 enlght_line(prefix, ps, suffix, final ? past : present)
1745 #define you_are(attr, ps) enl_msg(You_, are, were, attr, ps)
1746 #define you_have(attr, ps) enl_msg(You_, have, had, attr, ps)
1747 #define you_can(attr, ps) enl_msg(You_, can, could, attr, ps)
1749 #define you_have_been(goodthing) enl_msg(You_, have_been, were, goodthing, "")
1751 #define you_have_been(goodthing) enl_msg(You_, are, were, goodthing, "")
1753 #define you_have_never(badthing) \
1754 enl_msg(You_, have_never, never, badthing, "")
1756 #define you_have_never(badthing) \
1757 enl_msg(badthing, "
\82Ä
\82¢
\82È
\82¢", "
\82È
\82©
\82Á
\82½", "", "")
1760 #define you_have_X(something) \
1761 enl_msg(You_, have, (const char *) "", something, "")
1763 #define you_have_X(something) \
1764 enl_msg(something, "
\82Ä
\82¢
\82é", "
\82½", "", "")
1767 #define you_are_ing(goodthing, ps) enl_msg(You_, iru, ita, goodthing, ps)
1778 add_menu(en_win, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
1780 putstr(en_win, 0, buf);
1784 enlght_line(start, middle, end, ps)
1785 const char *start, *middle, *end, *ps;
1790 Sprintf(buf, " %s%s%s%s.", start, middle, end, ps);
1792 Sprintf(buf, "%s%s%s%s
\81D", start, middle, end, ps);
1796 /* format increased chance to hit or damage or defense (Protection) */
1798 enlght_combatinc(inctyp, incamt, final, outbuf)
1803 const char *modif, *bonus;
1809 absamt = abs(incamt);
1810 /* Protection amount is typically larger than damage or to-hit;
1811 reduce magnitude by a third in order to stretch modifier ranges
1812 (small:1..5, moderate:6..10, large:11..19, huge:20+) */
1814 if (!strcmp(inctyp, "defense"))
1816 if (!strcmp(inctyp, "
\96h
\8cä"))
1818 absamt = (absamt * 2) / 3;
1824 modif = "
\8bÍ
\82©
\82È";
1825 else if (absamt <= 6)
1829 modif = "
\92\86\92ö
\93x
\82Ì";
1830 else if (absamt <= 12)
1834 modif = "
\91å
\82«
\82È";
1839 modif = "
\8b
\91å
\82È";
1842 modif = !incamt ? "no" : an(modif); /* ("no" case shouldn't happen) */
1845 bonus = (incamt >= 0) ? "bonus" : "penalty";
1847 bonus = (incamt > 0) ? "
\83{
\81[
\83i
\83X" : "
\83y
\83i
\83\8b\83e
\83B";
1848 /* "bonus <foo>" (to hit) vs "<bar> bonus" (damage, defense) */
1850 invrt = strcmp(inctyp, "to hit") ? TRUE : FALSE;
1854 Sprintf(outbuf, "%s %s %s", modif, invrt ? inctyp : bonus,
1855 invrt ? bonus : inctyp);
1857 Sprintf(outbuf, "%s
\82É%s%s", inctyp, modif, bonus);
1859 if (final || wizard)
1860 Sprintf(eos(outbuf), " (%s%d)", (incamt > 0) ? "+" : "", incamt);
1865 /* report half physical or half spell damage */
1867 enlght_halfdmg(category, final)
1871 const char *category_name;
1877 category_name = "physical";
1879 category_name = "
\95¨
\97\9d";
1883 category_name = "spell";
1885 category_name = "
\8eô
\95¶";
1889 category_name = "unknown";
1891 category_name = "
\95s
\96¾";
1895 Sprintf(buf, " %s %s damage", (final || wizard) ? "half" : "reduced",
1897 enl_msg(You_, "take", "took", buf, from_what(category));
1899 Sprintf(buf, " %s
\83_
\83\81\81[
\83W
\82ð%s", (final || wizard) ? "
\94¼
\8c¸" : "
\8c¸
\8f",
1901 enl_msg(You_, "
\82µ
\82Ä
\82¢
\82é", "
\82µ
\82Ä
\82¢
\82½", buf, from_what(category));
1905 /* is hero actively using water walking capability on water (or lava)? */
1909 if (u.uinwater || Levitation || Flying)
1911 return (boolean) (Wwalking
1912 && (is_pool(u.ux, u.uy) || is_lava(u.ux, u.uy)));
1915 /* check whether hero is wearing something that player definitely knows
1916 confers the target property; item must have been seen and its type
1917 discovered but it doesn't necessarily have to be fully identified */
1919 cause_known(propindx)
1920 int propindx; /* index of a property which can be conveyed by worn item */
1922 register struct obj *o;
1923 long mask = W_ARMOR | W_AMUL | W_RING | W_TOOL;
1925 /* simpler than from_what()/what_gives(); we don't attempt to
1926 handle artifacts and we deliberately ignore wielded items */
1927 for (o = invent; o; o = o->nobj) {
1928 if (!(o->owornmask & mask))
1930 if ((int) objects[o->otyp].oc_oprop == propindx
1931 && objects[o->otyp].oc_name_known && o->dknown)
1937 /* format a characteristic value, accommodating Strength's strangeness */
1939 attrval(attrindx, attrvalue, resultbuf)
1940 int attrindx, attrvalue;
1941 char resultbuf[]; /* should be at least [7] to hold "18/100\0" */
1943 if (attrindx != A_STR || attrvalue <= 18)
1944 Sprintf(resultbuf, "%d", attrvalue);
1945 else if (attrvalue > STR18(100)) /* 19 to 25 */
1946 Sprintf(resultbuf, "%d", attrvalue - 100);
1947 else /* simplify "18/ **" to be "18/100" */
1948 Sprintf(resultbuf, "18/%02d", attrvalue - 18);
1953 enlightenment(mode, final)
1954 int mode; /* BASICENLIGHTENMENT | MAGICENLIGHTENMENT (| both) */
1955 int final; /* ENL_GAMEINPROGRESS:0, ENL_GAMEOVERALIVE, ENL_GAMEOVERDEAD */
1957 char buf[BUFSZ], tmpbuf[BUFSZ];
1959 en_win = create_nhwindow(NHW_MENU);
1960 en_via_menu = !final;
1964 Strcpy(tmpbuf, plname);
1965 *tmpbuf = highc(*tmpbuf); /* same adjustment as bottom line */
1966 /* as in background_enlightenment, when poly'd we need to use the saved
1967 gender in u.mfemale rather than the current you-as-monster gender */
1969 Sprintf(buf, "%s the %s's attributes:", tmpbuf,
1970 ((Upolyd ? u.mfemale : flags.female) && urole.name.f)
1974 Sprintf(buf, "%s
\82Ì%s
\82Ì
\91®
\90«:",
1975 ((Upolyd ? u.mfemale : flags.female) && urole.name.f)
1982 enlght_out(buf); /* "Conan the Archeologist's attributes:" */
1983 /* background and characteristics; ^X or end-of-game disclosure */
1984 if (mode & BASICENLIGHTENMENT) {
1985 /* role, race, alignment, deities, dungeon level, time, experience */
1986 background_enlightenment(mode, final);
1987 /* hit points, energy points, armor class, gold */
1988 basics_enlightenment(mode, final);
1989 /* strength, dexterity, &c */
1990 characteristics_enlightenment(mode, final);
1992 /* expanded status line information, including things which aren't
1993 included there due to space considerations--such as obvious
1994 alternative movement indicators (riding, levitation, &c), and
1995 various troubles (turning to stone, trapped, confusion, &c);
1996 shown for both basic and magic enlightenment */
1997 status_enlightenment(mode, final);
1998 /* remaining attributes; shown for potion,&c or wizard mode and
1999 explore mode ^X or end of game disclosure */
2000 if (mode & MAGICENLIGHTENMENT) {
2001 /* intrinsics and other traditional enlightenment feedback */
2002 attributes_enlightenment(mode, final);
2006 display_nhwindow(en_win, TRUE);
2008 menu_item *selected = 0;
2010 end_menu(en_win, (char *) 0);
2011 if (select_menu(en_win, PICK_NONE, &selected) > 0)
2012 free((genericptr_t) selected);
2013 en_via_menu = FALSE;
2015 destroy_nhwindow(en_win);
2020 /* display role, race, alignment and such to en_win */
2022 background_enlightenment(unused_mode, final)
2023 int unused_mode UNUSED;
2026 const char *role_titl, *rank_titl;
2027 int innategend, difgend, difalgn;
2028 char buf[BUFSZ], tmpbuf[BUFSZ];
2030 /* note that if poly'd, we need to use u.mfemale instead of flags.female
2031 to access hero's saved gender-as-human/elf/&c rather than current one */
2032 innategend = (Upolyd ? u.mfemale : flags.female) ? 1 : 0;
2033 role_titl = (innategend && urole.name.f) ? urole.name.f : urole.name.m;
2034 rank_titl = rank_of(u.ulevel, Role_switch, innategend);
2036 enlght_out(""); /* separator after title */
2038 enlght_out("Background:");
2040 enlght_out("
\94w
\8ci
\8fî
\95ñ:");
2042 /* if polymorphed, report current shape before underlying role;
2043 will be repeated as first status: "you are transformed" and also
2044 among various attributes: "you are in beast form" (after being
2045 told about lycanthropy) or "you are polymorphed into <a foo>"
2046 (with countdown timer appended for wizard mode); we really want
2047 the player to know he's not a samurai at the moment... */
2049 struct permonst *uasmon = youmonst.data;
2052 /* here we always use current gender, not saved role gender */
2053 if (!is_male(uasmon) && !is_female(uasmon) && !is_neuter(uasmon))
2055 Sprintf(tmpbuf, "%s ", genders[flags.female ? 1 : 0].adj);
2057 Sprintf(tmpbuf, "%s
\82Ì", genders[flags.female ? 1 : 0].adj);
2059 Sprintf(buf, "%sin %s%s form", !final ? "currently " : "", tmpbuf,
2062 Sprintf(buf, "%s%s%s
\82Ì
\8ep", !final ? "
\8d¡
\82Ì
\82Æ
\82±
\82ë" : "", tmpbuf,
2068 you_are_ing(buf, "");
2071 /* report role; omit gender if it's redundant (eg, "female priestess") */
2074 && ((urole.allow & ROLE_GENDMASK) == (ROLE_MALE | ROLE_FEMALE)
2075 || innategend != flags.initgend))
2077 Sprintf(tmpbuf, "%s ", genders[innategend].adj);
2079 Sprintf(tmpbuf, "%s", genders[innategend].adj);
2083 Strcpy(buf, "actually "); /* "You are actually a ..." */
2085 Strcpy(buf, "
\8eÀ
\8dÛ
\82É
\82Í"); /* "
\82 \82È
\82½
\82Í
\8eÀ
\8dÛ
\82É
\82Í..." */
2087 if (!strcmpi(rank_titl, role_titl)) {
2088 /* omit role when rank title matches it */
2090 Sprintf(eos(buf), "%s, level %d %s%s", an(rank_titl), u.ulevel,
2091 tmpbuf, urace.noun);
2093 Sprintf(eos(buf), "
\83\8c\83x
\83\8b%d
\82Ì%s
\82Ì%s%s", u.ulevel,
2094 tmpbuf, urace.adj, role_titl);
2098 Sprintf(eos(buf), "%s, a level %d %s%s %s", an(rank_titl), u.ulevel,
2099 tmpbuf, urace.adj, role_titl);
2101 Sprintf(eos(buf), "
\83\8c\83x
\83\8b%d
\82Ì%s
\82Ì%s%s
\82Ì%s", u.ulevel,
2102 tmpbuf, urace.adj, role_titl, rank_titl);
2107 /* report alignment (bypass you_are() in order to omit ending period);
2108 adverb is used to distinguish between temporary change (helm of opp.
2109 alignment), permanent change (one-time conversion), and original */
2111 Sprintf(buf, " %s%s%s, %son a mission for %s",
2112 You_, !final ? are : were,
2113 align_str(u.ualign.type),
2114 /* helm of opposite alignment (might hide conversion) */
2115 (u.ualign.type != u.ualignbase[A_CURRENT])
2116 /* what's the past tense of "currently"? if we used "formerly"
2117 it would sound like a reference to the original alignment */
2118 ? (!final ? "currently " : "temporarily ")
2119 /* permanent conversion */
2120 : (u.ualign.type != u.ualignbase[A_ORIGINAL])
2121 /* and what's the past tense of "now"? certainly not "then"
2122 in a context like this...; "belatedly" == weren't that
2123 way sooner (in other words, didn't start that way) */
2124 ? (!final ? "now " : "belatedly ")
2125 /* atheist (ignored in very early game) */
2126 : (!u.uconduct.gnostic && moves > 1000L)
2128 /* lastly, normal case */
2132 Sprintf(buf, "
\82 \82È
\82½
\82Í%s
\82Å, %s%s
\82Ì
\82½
\82ß
\82Ì
\94C
\96±
\82ð
\8ds
\82Á
\82Ä%s
\81D",
2133 align_str(u.ualign.type),
2134 /* helm of opposite alignment (might hide conversion) */
2135 (u.ualign.type != u.ualignbase[A_CURRENT]) ? "
\88ê
\8e\9e\93I
\82É"
2136 /* permanent conversion */
2137 : (u.ualign.type != u.ualignbase[A_ORIGINAL]) ? "
\8c»
\8dÝ"
2138 /* atheist (ignored in very early game) */
2139 : (!u.uconduct.gnostic && moves > 1000L) ? "
\96¼
\8b`
\8fã"
2140 /* lastly, normal case */
2142 u_gname(), !final ? iru : ita);
2145 /* show the rest of this game's pantheon (finishes previous sentence)
2146 [appending "also Moloch" at the end would allow for straightforward
2147 trailing "and" on all three aligned entries but looks too verbose] */
2149 Sprintf(buf, " who %s opposed by", !final ? "is" : "was");
2151 Strcpy(buf, "
\82 \82È
\82½
\82Í");
2153 if (u.ualign.type != A_LAWFUL)
2155 Sprintf(eos(buf), " %s (%s) and", align_gname(A_LAWFUL),
2156 align_str(A_LAWFUL));
2158 Sprintf(eos(buf), "%s(%s)
\82¨
\82æ
\82Ñ", align_gname(A_LAWFUL),
2159 align_str(A_LAWFUL));
2161 if (u.ualign.type != A_NEUTRAL)
2163 Sprintf(eos(buf), " %s (%s)%s", align_gname(A_NEUTRAL),
2164 align_str(A_NEUTRAL),
2165 (u.ualign.type != A_CHAOTIC) ? " and" : "");
2167 Sprintf(eos(buf), "%s(%s)%s", align_gname(A_NEUTRAL),
2168 align_str(A_NEUTRAL),
2169 (u.ualign.type != A_CHAOTIC) ? "
\82¨
\82æ
\82Ñ" : "");
2171 if (u.ualign.type != A_CHAOTIC)
2173 Sprintf(eos(buf), " %s (%s)", align_gname(A_CHAOTIC),
2174 align_str(A_CHAOTIC));
2176 if (u.ualign.type != A_CHAOTIC)
2177 Sprintf(eos(buf), "%s(%s)", align_gname(A_CHAOTIC),
2178 align_str(A_CHAOTIC));
2181 Strcat(buf, "."); /* terminate sentence */
2183 Sprintf(eos(buf), "
\82Æ
\91Î
\97§
\82µ
\82Ä%s
\81D", !final ? iru : ita);
2187 /* show original alignment,gender,race,role if any have been changed;
2188 giving separate message for temporary alignment change bypasses need
2189 for tricky phrasing otherwise necessitated by possibility of having
2190 helm of opposite alignment mask a permanent alignment conversion */
2191 difgend = (innategend != flags.initgend);
2192 difalgn = (((u.ualign.type != u.ualignbase[A_CURRENT]) ? 1 : 0)
2193 + ((u.ualignbase[A_CURRENT] != u.ualignbase[A_ORIGINAL])
2195 if (difalgn & 1) { /* have temporary alignment so report permanent one */
2197 Sprintf(buf, "actually %s", align_str(u.ualignbase[A_CURRENT]));
2199 Sprintf(buf, "
\8eÀ
\8dÛ
\82É
\82Í%s", align_str(u.ualignbase[A_CURRENT]));
2203 enl_msg(buf, "
\82Ä
\82¢
\82é", "
\82Ä
\82¢
\82½", "", "");
2205 difalgn &= ~1; /* suppress helm from "started out <foo>" message */
2207 if (difgend || difalgn) { /* sex change or perm align change or both */
2209 Sprintf(buf, " You started out %s%s%s.",
2210 difgend ? genders[flags.initgend].adj : "",
2211 (difgend && difalgn) ? " and " : "",
2212 difalgn ? align_str(u.ualignbase[A_ORIGINAL]) : "");
2214 Sprintf(buf, "
\82 \82È
\82½
\82Í%s%s%s
\82Å
\8aJ
\8en
\82µ
\82½
\81D",
2215 difgend ? genders[flags.initgend].adj : "",
2216 (difgend && difalgn) ? "
\82©
\82Â" : "",
2217 difalgn ? align_str(u.ualignbase[A_ORIGINAL]) : "");
2222 /* 3.6.2: dungeon level, so that ^X really has all status info as
2223 claimed by the comment below; this reveals more information than
2224 the basic status display, but that's one of the purposes of ^X;
2225 similar information is revealed by #overview; the "You died in
2226 <location>" given by really_done() is more rudimentary than this */
2227 *buf = *tmpbuf = '\0';
2228 if (In_endgame(&u.uz)) {
2229 int egdepth = observable_depth(&u.uz);
2231 (void) endgamelevelname(tmpbuf, egdepth);
2232 Sprintf(buf, "in the endgame, on the %s%s",
2233 !strncmp(tmpbuf, "Plane", 5) ? "Elemental " : "", tmpbuf);
2234 } else if (Is_knox(&u.uz)) {
2235 /* this gives away the fact that the knox branch is only 1 level */
2237 Sprintf(buf, "on the %s level", dungeons[u.uz.dnum].dname);
2239 Sprintf(buf, "%s", dungeons[u.uz.dnum].dname);
2240 /* TODO? maybe phrase it differently when actually inside the fort,
2241 if we're able to determine that (not trivial) */
2243 char dgnbuf[QBUFSZ];
2245 Strcpy(dgnbuf, dungeons[u.uz.dnum].dname);
2247 if (!strncmpi(dgnbuf, "The ", 4))
2248 *dgnbuf = lowc(*dgnbuf);
2251 Sprintf(tmpbuf, "level %d",
2252 In_quest(&u.uz) ? dunlev(&u.uz) : depth(&u.uz));
2254 if (In_quest(&u.uz)) {
2255 Sprintf(tmpbuf, "
\91æ%d
\8aK
\91w", dunlev(&u.uz));
2257 Sprintf(tmpbuf, "
\92n
\89º%d
\8aK", depth(&u.uz));
2260 /* TODO? maybe extend this bit to include various other automatic
2261 annotations from the dungeon overview code */
2262 if (Is_rogue_level(&u.uz))
2263 Strcat(tmpbuf, ", a primitive area");
2264 else if (Is_bigroom(&u.uz) && !Blind)
2265 Strcat(tmpbuf, ", a very big room");
2267 Sprintf(buf, "in %s, on %s", dgnbuf, tmpbuf);
2269 Sprintf(buf, "%s
\82Ì%s", dgnbuf, tmpbuf);
2274 /* this is shown even if the 'time' option is off */
2277 you_have("just started your adventure", "");
2279 enlght_line(You_, "", "
\96`
\8c¯
\82ð
\8aJ
\8en
\82µ
\82½
\82Æ
\82±
\82ë
\82¾", "");
2282 /* 'turns' grates on the nerves in this context... */
2284 Sprintf(buf, "the dungeon %ld turn%s ago", moves, plur(moves));
2286 Sprintf(buf, "%ld
\83^
\81[
\83\93\91O
\82É
\96À
\8b{
\82É
\93ü
\82Á
\82½", moves);
2287 /* same phrasing for current and final: "entered" is unconditional */
2289 enlght_line(You_, "entered ", buf, "");
2291 enlght_line(You_, "", buf, "");
2295 /* flags.showexp does not matter */
2296 /* experience level is already shown above */
2298 Sprintf(buf, "%-1ld experience point%s", u.uexp, plur(u.uexp));
2300 Sprintf(buf, "
\8co
\8c±
\92l%-1ld
\83|
\83C
\83\93\83g", u.uexp);
2303 if (u.ulevel < 30) {
2304 int ulvl = (int) u.ulevel;
2305 long nxtlvl = newuexp(ulvl);
2306 /* long oldlvl = (ulvl > 1) ? newuexp(ulvl - 1) : 0; */
2308 Sprintf(eos(buf), ", %ld %s%sneeded to attain level %d",
2309 (nxtlvl - u.uexp), (u.uexp > 0) ? "more " : "",
2310 !final ? "" : "were ", (ulvl + 1));
2315 #ifdef SCORE_ON_BOTL
2316 if (flags.showscore) {
2317 /* describes what's shown on status line, which is an approximation;
2318 only show it here if player has the 'showscore' option enabled */
2320 Sprintf(buf, "%ld%s", botl_score(),
2321 !final ? "" : " before end-of-game adjustments");
2322 enl_msg("Your score ", "is ", "was ", buf, "");
2324 Sprintf(buf, "%s%ld", botl_score(),
2325 !final ? "" : "
\83Q
\81[
\83\80\8fI
\97¹
\8e\9e\82Ì
\92²
\90®
\91O
\82Í");
2326 enl_msg("
\82 \82È
\82½
\82Ì
\83X
\83R
\83A
\82Í", "
\82Å
\82 \82é", "
\82Å
\82 \82Á
\82½", buf, "");
2332 /* hit points, energy points, armor class -- essential information which
2333 doesn't fit very well in other categories */
2336 basics_enlightenment(mode, final)
2340 static char Power[] = "energy points (spell power)";
2342 int pw = u.uen, hp = (Upolyd ? u.mh : u.uhp),
2343 pwmax = u.uenmax, hpmax = (Upolyd ? u.mhmax : u.uhpmax);
2345 enlght_out(""); /* separator after background */
2347 enlght_out("Basics:");
2349 enlght_out("
\8aî
\96{:");
2353 /* "1 out of 1" rather than "all" if max is only 1; should never happen */
2355 if (hp == hpmax && hpmax > 1)
2356 Sprintf(buf, "all %d hit points", hpmax);
2358 Sprintf(buf, "%d out of %d hit point%s", hp, hpmax, plur(hpmax));
2360 Sprintf(buf, "%d
\83q
\83b
\83g
\83|
\83C
\83\93\83g(
\8dÅ
\91å:%d)", hp, hpmax);
2364 /* low max energy is feasible, so handle couple of extra special cases */
2366 if (pwmax == 0 || (pw == pwmax && pwmax == 2)) /* both: "all 2" is silly */
2367 Sprintf(buf, "%s %s", !pwmax ? "no" : "both", Power);
2368 else if (pw == pwmax && pwmax > 2)
2369 Sprintf(buf, "all %d %s", pwmax, Power);
2371 Sprintf(buf, "%d out of %d %s", pw, pwmax, Power);
2373 Sprintf(buf, "%d
\96\82\97Í
\83|
\83C
\83\93\83g(
\8dÅ
\91å:%d)", pw, pwmax);
2378 switch (mons[u.umonnum].mlevel) {
2380 /* status line currently being explained shows "HD:0" */
2382 Strcpy(buf, "0 hit dice (actually 1/2)");
2384 Strcpy(buf, "HD0(
\8eÀ
\8dÛ
\82É
\82Í1/2)");
2388 Strcpy(buf, "1 hit die");
2394 Sprintf(buf, "%d hit dice", mons[u.umonnum].mlevel);
2396 Sprintf(buf, "HD%d", mons[u.umonnum].mlevel);
2402 Sprintf(buf, "%d", u.uac);
2404 enl_msg("Your armor class ", "is ", "was ", buf, "");
2406 enl_msg("
\82 \82È
\82½
\82Ì
\96h
\8cä
\92l
\82Í", "
\82Å
\82 \82é", "
\82Å
\82 \82Á
\82½", buf, "");
2408 /* gold; similar to doprgold(#seegold) but without shop billing info;
2409 same amount as shown on status line which ignores container contents */
2412 static const char Your_wallet[] = "Your wallet ";
2414 static const char Your_wallet[] = "
\82 \82È
\82½
\82Ì
\8dà
\95z";
2415 long umoney = money_cnt(invent);
2419 enl_msg(Your_wallet, "is ", "was ", "empty", "");
2421 enl_msg(Your_wallet, "
\82Å
\82 \82é", "
\82Å
\82¾
\82Á
\82½", "
\82Í
\8bó", "");
2424 Sprintf(buf, "%ld %s", umoney, currency(umoney));
2425 enl_msg(Your_wallet, "contains ", "contained ", buf, "");
2427 Sprintf(buf, "
\82É
\82Í%ld%s", umoney, currency(umoney));
2428 enl_msg(Your_wallet, "
\93ü
\82Á
\82Ä
\82¢
\82é", "
\93ü
\82Á
\82Ä
\82¢
\82½", buf, "");
2434 char ocl[MAXOCLASSES + 1];
2437 oc_to_str(flags.pickup_types, ocl);
2438 Sprintf(eos(buf), " for %s%s%s",
2439 *ocl ? "'" : "", *ocl ? ocl : "all types", *ocl ? "'" : "");
2440 if (flags.pickup_thrown && *ocl) /* *ocl: don't show if 'all types' */
2441 Strcat(buf, " plus thrown");
2442 if (iflags.autopickup_exceptions[AP_GRAB]
2443 || iflags.autopickup_exceptions[AP_LEAVE])
2444 Strcat(buf, ", with exceptions");
2449 Strcpy(buf, "
\83I
\83t");
2451 enl_msg("Autopickup ", "is ", "was ", buf, "");
2453 enl_msg("
\8e©
\93®
\8fE
\82¢
\90Ý
\92è
\82Í", "
\82Å
\82 \82é", "
\82Å
\82 \82Á
\82½", buf, "");
2456 /* characteristics: expanded version of bottom line strength, dexterity, &c */
2458 characteristics_enlightenment(mode, final)
2466 Sprintf(buf, "%s Characteristics:", !final ? "Current" : "Final");
2468 Sprintf(buf, "%s
\91®
\90«
\81F", !final ? "
\8c»
\8dÝ
\82Ì" : "
\8dÅ
\8fI");
2471 /* bottom line order */
2472 one_characteristic(mode, final, A_STR); /* strength */
2473 one_characteristic(mode, final, A_DEX); /* dexterity */
2474 one_characteristic(mode, final, A_CON); /* constitution */
2475 one_characteristic(mode, final, A_INT); /* intelligence */
2476 one_characteristic(mode, final, A_WIS); /* wisdom */
2477 one_characteristic(mode, final, A_CHA); /* charisma */
2480 /* display one attribute value for characteristics_enlightenment() */
2482 one_characteristic(mode, final, attrindx)
2483 int mode, final, attrindx;
2485 extern const char *const attrname[]; /* attrib.c */
2486 boolean hide_innate_value = FALSE, interesting_alimit;
2487 int acurrent, abase, apeak, alimit;
2488 const char *paren_pfx;
2489 char subjbuf[BUFSZ], valubuf[BUFSZ], valstring[32];
2491 /* being polymorphed or wearing certain cursed items prevents
2492 hero from reliably tracking changes to characteristics so
2493 we don't show base & peak values then; when the items aren't
2494 cursed, hero could take them off to check underlying values
2495 and we show those in such case so that player doesn't need
2496 to actually resort to doing that */
2498 hide_innate_value = TRUE;
2499 } else if (Fixed_abil) {
2500 if (stuck_ring(uleft, RIN_SUSTAIN_ABILITY)
2501 || stuck_ring(uright, RIN_SUSTAIN_ABILITY))
2502 hide_innate_value = TRUE;
2506 if (uarmg && uarmg->otyp == GAUNTLETS_OF_POWER && uarmg->cursed)
2507 hide_innate_value = TRUE;
2512 if (uwep && uwep->oartifact == ART_OGRESMASHER && uwep->cursed)
2513 hide_innate_value = TRUE;
2516 if (uarmh && uarmh->otyp == DUNCE_CAP && uarmh->cursed)
2517 hide_innate_value = TRUE;
2520 if (uarmh && uarmh->otyp == DUNCE_CAP && uarmh->cursed)
2521 hide_innate_value = TRUE;
2526 return; /* impossible */
2528 /* note: final disclosure includes MAGICENLIGHTENTMENT */
2529 if ((mode & MAGICENLIGHTENMENT) && !Upolyd)
2530 hide_innate_value = FALSE;
2532 acurrent = ACURR(attrindx);
2533 (void) attrval(attrindx, acurrent, valubuf); /* Sprintf(valubuf,"%d",) */
2535 Sprintf(subjbuf, "Your %s ", attrname[attrindx]);
2537 Sprintf(subjbuf, "
\82 \82È
\82½
\82Ì%s
\82Í", attrname[attrindx]);
2539 if (!hide_innate_value) {
2540 /* show abase, amax, and/or attrmax if acurr doesn't match abase
2541 (a magic bonus or penalty is in effect) or abase doesn't match
2542 amax (some points have been lost to poison or exercise abuse
2543 and are restorable) or attrmax is different from normal human
2544 (while game is in progress; trying to reduce dependency on
2545 spoilers to keep track of such stuff) or attrmax was different
2546 from abase (at end of game; this attribute wasn't maxed out) */
2547 abase = ABASE(attrindx);
2548 apeak = AMAX(attrindx);
2549 alimit = ATTRMAX(attrindx);
2550 /* criterium for whether the limit is interesting varies */
2551 interesting_alimit =
2552 final ? TRUE /* was originally `(abase != alimit)' */
2553 : (alimit != (attrindx != A_STR ? 18 : STR18(100)));
2555 paren_pfx = final ? " (" : " (current; ";
2557 paren_pfx = final ? " (" : " (
\8c»
\8dÝ; ";
2558 if (acurrent != abase) {
2560 Sprintf(eos(valubuf), "%sbase:%s", paren_pfx,
2561 attrval(attrindx, abase, valstring));
2563 Sprintf(eos(valubuf), "%s
\8aî
\96{:%s", paren_pfx,
2564 attrval(attrindx, abase, valstring));
2568 if (abase != apeak) {
2570 Sprintf(eos(valubuf), "%speak:%s", paren_pfx,
2571 attrval(attrindx, apeak, valstring));
2573 Sprintf(eos(valubuf), "%s
\8dÅ
\91å:%s", paren_pfx,
2574 attrval(attrindx, apeak, valstring));
2578 if (interesting_alimit) {
2580 Sprintf(eos(valubuf), "%s%slimit:%s", paren_pfx,
2581 /* more verbose if exceeding 'limit' due to magic bonus */
2582 (acurrent > alimit) ? "innate " : "",
2583 attrval(attrindx, alimit, valstring));
2585 Sprintf(eos(valubuf), "%s%s
\8fã
\8cÀ:%s", paren_pfx,
2586 /* more verbose if exceeding 'limit' due to magic bonus */
2587 (acurrent > alimit) ? "
\96{
\97\88\82Ì" : "",
2588 attrval(attrindx, alimit, valstring));
2590 /* paren_pfx = ", "; */
2592 if (acurrent != abase || abase != apeak || interesting_alimit)
2593 Strcat(valubuf, ")");
2596 enl_msg(subjbuf, "is ", "was ", valubuf, "");
2598 enl_msg(subjbuf, "
\82¾", "
\82¾
\82Á
\82½", valubuf, "");
2601 /* status: selected obvious capabilities, assorted troubles */
2603 status_enlightenment(mode, final)
2607 boolean magic = (mode & MAGICENLIGHTENMENT) ? TRUE : FALSE;
2609 char buf[BUFSZ], youtoo[BUFSZ];
2610 boolean Riding = (u.usteed
2611 /* if hero dies while dismounting, u.usteed will still
2612 be set; we want to ignore steed in that situation */
2613 && !(final == ENL_GAMEOVERDEAD
2615 && !strcmp(killer.name, "riding accident")));
2617 && !strcmp(killer.name, "
\8bR
\8fæ
\8e\96\8cÌ
\82Å")));
2618 const char *steedname = (!Riding ? (char *) 0
2619 : x_monnam(u.usteed,
2620 u.usteed->mtame ? ARTICLE_YOUR : ARTICLE_THE,
2622 (SUPPRESS_SADDLE | SUPPRESS_HALLUCINATION),
2626 * Status (many are abbreviated on bottom line; others are or
2627 * should be discernible to the hero hence to the player)
2629 enlght_out(""); /* separator after title or characteristics */
2631 enlght_out(final ? "Final Status:" : "Current Status:");
2633 enlght_out(final ? "
\8dÅ
\8fI
\8fó
\91Ô:" : "
\8c»
\8dÝ
\82Ì
\8fó
\91Ô:");
2635 Strcpy(youtoo, You_);
2636 /* not a traditional status but inherently obvious to player; more
2637 detail given below (attributes section) for magic enlightenment */
2640 Strcpy(buf, "transformed");
2642 Sprintf(eos(buf), " and %s %s inside",
2643 final ? "felt" : "feel", udeadinside());
2645 #else /*JP:TODO:
\95Ï
\89»+
\8bs
\8eE
\83p
\83^
\81[
\83\93*/
2646 you_are_ing("
\95Ï
\89»
\82µ
\82Ä", "");
2649 /* not a trouble, but we want to display riding status before maybe
2650 reporting steed as trapped or hero stuck to cursed saddle */
2653 Sprintf(buf, "riding %s", steedname);
2656 Sprintf(buf, "%s
\82É
\8fæ
\82Á
\82Ä", steedname);
2657 you_are_ing(buf, "");
2660 Sprintf(eos(youtoo), "and %s ", steedname);
2662 Sprintf(youtoo, "
\82 \82È
\82½
\82Æ%s
\82Í", steedname);
2664 /* other movement situations that hero should always know */
2666 if (Lev_at_will && magic)
2668 you_are("levitating, at will", "");
2670 you_are_ing("
\8e©
\95ª
\82Ì
\88Ó
\8eu
\82Å
\95\82\97V
\82µ
\82Ä", "");
2673 enl_msg(youtoo, are, were, "levitating", from_what(LEVITATION));
2675 enl_msg(youtoo, "
\82¢
\82é", "
\82¢
\82½", "
\95\82\97V
\82µ
\82Ä", from_what(LEVITATION));
2676 } else if (Flying) { /* can only fly when not levitating */
2678 enl_msg(youtoo, are, were, "flying", from_what(FLYING));
2680 enl_msg(youtoo, "
\82¢
\82é", "
\82¢
\82½", "
\94ò
\82ñ
\82Å", from_what(FLYING));
2684 you_are("underwater", "");
2686 enl_msg(You_, "
\82¢
\82é", "
\82¢
\82½", "
\90\85\96Ê
\89º
\82É", "");
2687 } else if (u.uinwater) {
2689 you_are(Swimming ? "swimming" : "in water", from_what(SWIMMING));
2691 enl_msg(You_, Swimming ? "
\89j
\82¢
\82Å" : "
\90\85\92\86\82É", "
\82¢
\82é", "
\82¢
\82½", from_what(SWIMMING));
2692 } else if (walking_on_water()) {
2693 /* show active Wwalking here, potential Wwalking elsewhere */
2695 Sprintf(buf, "walking on %s",
2696 is_pool(u.ux, u.uy) ? "water"
2697 : is_lava(u.ux, u.uy) ? "lava"
2698 : surface(u.ux, u.uy)); /* catchall; shouldn't happen */
2699 you_are(buf, from_what(WWALKING));
2701 Sprintf(buf, "%s
\82Ì
\8fã
\82ð
\95à
\82¢
\82Ä",
2702 is_pool(u.ux, u.uy) ? "
\90\85"
2703 : is_lava(u.ux, u.uy) ? "
\97n
\8aâ"
2704 : surface(u.ux, u.uy)); /* catchall; shouldn't happen */
2705 you_are_ing(buf, from_what(WWALKING));
2708 if (Upolyd && (u.uundetected || U_AP_TYPE != M_AP_NOTHING))
2709 youhiding(TRUE, final);
2711 /* internal troubles, mostly in the order that prayer ranks them */
2714 you_are("turning to stone", "");
2716 enl_msg("
\82 \82È
\82½
\82Í", "
\82È
\82è
\82Â
\82Â
\82 \82é", "
\82È
\82Á
\82½", "
\90Î
\82É", "");
2719 you_are("turning into slime", "");
2721 enl_msg("
\82 \82È
\82½
\82Í", "
\82È
\82è
\82Â
\82Â
\82 \82é", "
\82È
\82Á
\82½", "
\83X
\83\89\83C
\83\80\82É", "");
2725 you_are("buried", "");
2727 you_are_ing("
\92\82\91§
\82µ
\82Ä", "");
2730 Strcpy(buf, "being strangled");
2732 Strcpy(buf, "
\8eñ
\82ð
\8di
\82ß
\82ç
\82ê
\82Ä");
2734 Sprintf(eos(buf), " (%ld)", (Strangled & TIMEOUT));
2736 you_are(buf, from_what(STRANGLED));
2738 enl_msg("
\82 \82È
\82½
\82Í", "
\82¢
\82é", "
\82¢
\82½", buf, from_what(STRANGLED));
2742 /* prayer lumps these together; botl puts Ill before FoodPois */
2743 if (u.usick_type & SICK_NONVOMITABLE)
2745 you_are("terminally sick from illness", "");
2747 enl_msg("
\82 \82È
\82½
\82Í
\95a
\8bC
\82Å
\92v
\96½
\93I
\82É
\8bC
\95ª
\82ª
\88«", "
\82¢", "
\82©
\82Á
\82½", "", "");
2748 if (u.usick_type & SICK_VOMITABLE)
2750 you_are("terminally sick from food poisoning", "");
2752 enl_msg("
\82 \82È
\82½
\82Í
\90H
\92\86\93Å
\82Å
\92v
\96½
\93I
\82É
\8bC
\95ª
\82ª
\88«", "
\82¢", "
\82©
\82Á
\82½", "", "");
2756 you_are("nauseated", "");
2758 enl_msg(You_, "
\93f
\82«
\8bC
\82ª", "
\82 \82é", "
\82 \82Á
\82½", "");
2761 you_are("stunned", "");
2763 you_are("
\82
\82ç
\82
\82ç
\8fó
\91Ô", "");
2766 you_are("confused", "");
2768 you_are("
\8d¬
\97\90\8fó
\91Ô", "");
2771 you_are("hallucinating", "");
2773 you_are("
\8c¶
\8ao
\8fó
\91Ô", "");
2775 /* from_what() (currently wizard-mode only) checks !haseyes()
2776 before u.uroleplay.blind, so we should too */
2778 Sprintf(buf, "%s blind",
2779 !haseyes(youmonst.data) ? "innately"
2780 : u.uroleplay.blind ? "permanently"
2781 /* better phrasing desperately wanted... */
2782 : Blindfolded_only ? "deliberately"
2785 Sprintf(buf, "%s
\96Ó
\96Ú",
2786 !haseyes(youmonst.data) ? "
\90¶
\82Ü
\82ê
\82È
\82ª
\82ç
\82É"
2787 : u.uroleplay.blind ? "
\8dP
\8bv
\93I
\82É"
2788 /* better phrasing desperately wanted... */
2789 : Blindfolded_only ? "
\8cÌ
\88Ó
\82É"
2790 : "
\88ê
\8e\9e\93I
\82É");
2792 if (wizard && (Blinded & TIMEOUT) != 0L
2793 && !u.uroleplay.blind && haseyes(youmonst.data))
2794 Sprintf(eos(buf), " (%ld)", (Blinded & TIMEOUT));
2795 /* !haseyes: avoid "you are innately blind innately" */
2796 you_are(buf, !haseyes(youmonst.data) ? "" : from_what(BLINDED));
2800 you_are("deaf", from_what(DEAF));
2802 you_are("
\8e¨
\82ª
\95·
\82±
\82¦
\82È
\82¢
\8fó
\91Ô", from_what(DEAF));
2804 /* external troubles, more or less */
2808 Sprintf(buf, "chained to %s", ansimpleoname(uball));
2810 Sprintf(buf, "%s
\82É
\82Â
\82È
\82ª
\82ê
\82Ä", ansimpleoname(uball));
2812 impossible("Punished without uball?");
2814 Strcpy(buf, "punished");
2816 Strcpy(buf, "
\94±
\82ð
\8eó
\82¯
\82Ä");
2821 char predicament[BUFSZ];
2823 boolean anchored = (u.utraptype == TT_BURIEDBALL);
2827 Strcpy(predicament, "tethered to something buried");
2829 Strcpy(predicament, "
\89½
\82©
\96\84\82Ü
\82Á
\82Ä
\82¢
\82é
\82à
\82Ì
\82É
\82Â
\82È
\82ª
\82ê
\82Ä");
2830 } else if (u.utraptype == TT_INFLOOR || u.utraptype == TT_LAVA) {
2832 Sprintf(predicament, "stuck in %s", the(surface(u.ux, u.uy)));
2834 Sprintf(predicament, "%s
\82É
\96\84\82Ü
\82Á
\82Ä", surface(u.ux, u.uy));
2837 Strcpy(predicament, "trapped");
2838 if ((t = t_at(u.ux, u.uy)) != 0)
2839 Sprintf(eos(predicament), " in %s",
2840 an(defsyms[trap_to_defsym(t->ttyp)].explanation));
2842 predicament[0] = '\0';
2843 if ((t = t_at(u.ux, u.uy)) != 0)
2844 Sprintf(predicament, "%s
\82É",
2845 defsyms[trap_to_defsym(t->ttyp)].explanation);
2846 Strcat(predicament, "
\82Ð
\82Á
\82©
\82©
\82Á
\82Ä");
2849 if (u.usteed) { /* not `Riding' here */
2851 Sprintf(buf, "%s%s ", anchored ? "you and " : "", steedname);
2853 enl_msg(buf, (anchored ? "are " : "is "),
2854 (anchored ? "were " : "was "), predicament, "");
2856 Sprintf(buf, "%s%s
\82Í", anchored ? "
\82 \82È
\82½
\82Æ" : "", steedname);
2857 enl_msg(buf, "
\82¢
\82é", "
\82¢
\82½" , predicament, "");
2860 you_are(predicament, "");
2864 Sprintf(buf, "swallowed by %s", a_monnam(u.ustuck));
2866 Sprintf(buf, "%s
\82É
\88ù
\82Ý
\8d\9e\82Ü
\82ê
\82Ä", a_monnam(u.ustuck));
2868 Sprintf(eos(buf), " (%u)", u.uswldtim);
2870 } else if (u.ustuck) {
2872 Sprintf(buf, "%s %s",
2873 (Upolyd && sticks(youmonst.data)) ? "holding" : "held by",
2874 a_monnam(u.ustuck));
2877 Sprintf(buf, "%s%s",
2879 (Upolyd && sticks(youmonst.data)) ? "
\82ð
\95ß
\82Ü
\82¦
\82Ä" : "
\82É
\95ß
\82Ü
\82Á
\82Ä");
2880 you_are_ing(buf, "");
2884 struct obj *saddle = which_armor(u.usteed, W_SADDLE);
2886 if (saddle && saddle->cursed) {
2888 Sprintf(buf, "stuck to %s %s", s_suffix(steedname),
2889 simpleonames(saddle));
2892 Sprintf(buf, "%s
\82Ì%s
\82É
\82Â
\82©
\82Ü
\82Á
\82Ä", steedname,
2893 simpleonames(saddle));
2894 you_are_ing(buf, "");
2899 /* when mounted, Wounded_legs applies to steed rather than to
2900 hero; we only report steed's wounded legs in wizard mode */
2901 if (u.usteed) { /* not `Riding' here */
2902 if (wizard && steedname) {
2904 Strcpy(buf, steedname);
2906 enl_msg(buf, " has", " had", " wounded legs", "");
2908 enl_msg(buf, iru, ita, "
\82Í
\8e\88\82ð
\89ö
\89ä
\82µ
\82Ä", "");
2913 Sprintf(buf, "wounded %s", makeplural(body_part(LEG)));
2916 Sprintf(buf, "%s
\82ð
\89ö
\89ä
\82µ
\82Ä", makeplural(body_part(LEG)));
2917 you_are_ing(buf, "");
2923 Sprintf(buf, "slippery %s", makeplural(body_part(FINGER)));
2926 Sprintf(buf, "%s
\82ª
\82Ê
\82é
\82Ê
\82é
\82µ
\82Ä", body_part(FINGER));
2927 enl_msg(buf, iru, ita, "", "");
2931 if (magic || cause_known(FUMBLING))
2933 enl_msg(You_, "fumble", "fumbled", "", from_what(FUMBLING));
2935 you_are_ing("
\95s
\8aí
\97p
\82É
\82È
\82Á
\82Ä", from_what(FUMBLING));
2938 if (magic || cause_known(SLEEPY)) {
2939 Strcpy(buf, from_what(SLEEPY));
2941 Sprintf(eos(buf), " (%ld)", (HSleepy & TIMEOUT));
2943 enl_msg("You ", "fall", "fell", " asleep uncontrollably", buf);
2945 you_are_ing("
\96°
\82Á
\82Ä", buf);
2948 /* hunger/nutrition */
2950 if (magic || cause_known(HUNGER))
2952 enl_msg(You_, "hunger", "hungered", " rapidly",
2955 enl_msg("
\82 \82È
\82½
\82Í
\82·
\82®
\82É
\95 \82ª
\8c¸
\82é
\8fó
\91Ô", "
\82Å
\82 \82é", "
\82¾
\82Á
\82½", "", "");
2958 Strcpy(buf, hu_stat[u.uhs]); /* hunger status; omitted if "normal" */
2959 mungspaces(buf); /* strip trailing spaces */
2962 *buf = lowc(*buf); /* override capitalization */
2963 if (!strcmp(buf, "weak"))
2964 Strcat(buf, " from severe hunger");
2965 else if (!strncmp(buf, "faint", 5)) /* fainting, fainted */
2966 Strcat(buf, " due to starvation");
2969 Strcat(buf, "
\8fó
\91Ô");
2974 if ((cap = near_capacity()) > UNENCUMBERED) {
2976 const char *adj = "?_?"; /* (should always get overridden) */
2978 Strcpy(buf, enc_stat[cap]);
2983 break; /* burdened */
2986 break; /* stressed */
2989 break; /* strained */
2992 break; /* overtaxed */
2994 adj = "not possible";
2997 Sprintf(eos(buf), "; movement %s %s%s", !final ? "is" : "was", adj,
2998 (cap < OVERLOADED) ? " slowed" : "");
3001 Sprintf(buf, "
\89×
\95¨
\82É
\82æ
\82Á
\82Ä%s
\8fó
\91Ô", enc_stat[cap]);
3005 /* last resort entry, guarantees Status section is non-empty
3006 (no longer needed for that purpose since weapon status added;
3007 still useful though) */
3009 you_are("unencumbered", "");
3011 you_are("
\89×
\95¨
\82Í
\8e×
\96\82\82É
\82È
\82ç
\82È
\82¢
\8fó
\91Ô", "");
3014 /* report being weaponless; distinguish whether gloves are worn */
3017 you_are(uarmg ? "empty handed" /* gloves imply hands */
3018 : humanoid(youmonst.data)
3019 /* hands but no weapon and no gloves */
3021 /* alternate phrasing for paws or lack of hands */
3022 : "not wielding anything",
3025 enl_msg(You_, "
\82¢", "
\82©
\82Á
\82½", "
\95\90\8aí
\82ð
\91\95\94õ
\82µ
\82Ä
\82¢
\82È", "");
3027 /* two-weaponing implies hands (can't be polymorphed) and
3028 a weapon or wep-tool (not other odd stuff) in each hand */
3029 } else if (u.twoweap) {
3031 you_are("wielding two weapons at once", "");
3033 you_are("
\93ñ
\93\81\97¬", "");
3034 /* report most weapons by their skill class (so a katana will be
3035 described as a long sword, for instance; mattock and hook are
3036 exceptions), or wielded non-weapon item by its object class */
3038 const char *what = weapon_descr(uwep);
3041 if (!strcmpi(what, "armor") || !strcmpi(what, "food")
3042 || !strcmpi(what, "venom"))
3043 Sprintf(buf, "wielding some %s", what);
3045 Sprintf(buf, "wielding %s",
3046 (uwep->quan == 1L) ? an(what) : makeplural(what));
3049 Sprintf(buf, "%s
\82ð
\91\95\94õ
\82µ
\82Ä", what);
3050 enl_msg(You_, "
\82¢
\82é", "
\82¢
\82½", buf, "");
3054 * Skill with current weapon. Might help players who've never
3055 * noticed #enhance or decided that it was pointless.
3057 * TODO? Maybe merge wielding line and skill line into one sentence.
3059 if ((wtype = uwep_skill_type()) != P_NONE) {
3061 int sklvl = P_SKILL(wtype);
3062 boolean hav = (sklvl != P_UNSKILLED && sklvl != P_SKILLED);
3064 if (sklvl == P_ISRESTRICTED)
3065 Strcpy(sklvlbuf, "no");
3067 (void) lcase(skill_level_name(wtype, sklvlbuf));
3068 /* "you have no/basic/expert/master/grand-master skill with <skill>"
3069 or "you are unskilled/skilled in <skill>" */
3071 Sprintf(buf, "%s %s %s", sklvlbuf,
3072 hav ? "skill with" : "in", skill_name(wtype));
3074 Sprintf(buf, "%s
\82Ì%s
\83X
\83L
\83\8b", skill_name(wtype), sklvlbuf);
3076 if (can_advance(wtype, FALSE))
3077 Sprintf(eos(buf), " and %s that",
3078 !final ? "can enhance" : "could have enhanced");
3084 /* report 'nudity' */
3085 if (!uarm && !uarmu && !uarmc && !uarms && !uarmg && !uarmf && !uarmh) {
3086 if (u.uroleplay.nudist)
3088 enl_msg(You_, "do", "did", " not wear any armor", "");
3090 enl_msg(You_, "
\82¢", "
\82©
\82Á
\82½", "
\89½
\82Ì
\8aZ
\82à
\91\95\94õ
\82µ
\82È", "");
3094 you_are("not wearing any armor", "");
3096 enl_msg(You_, "
\82¢", "
\82©
\82Á
\82½", "
\89½
\82Ì
\8aZ
\82à
\91\95\94õ
\82µ
\82Ä
\82¢
\82È", "");
3101 /* attributes: intrinsics and the like, other non-obvious capabilities */
3103 attributes_enlightenment(unused_mode, final)
3104 int unused_mode UNUSED;
3108 static NEARDATA const char if_surroundings_permitted[] =
3109 " if surroundings permitted";
3119 enlght_out(final ? "Final Attributes:" : "Current Attributes:");
3121 enlght_out(final ? "
\8dÅ
\8fI
\91®
\90«:" : "
\8c»
\8dÝ
\82Ì
\91®
\90«:");
3123 if (u.uevent.uhand_of_elbereth) {
3125 static const char *const hofe_titles[3] = { "the Hand of Elbereth",
3126 "the Envoy of Balance",
3127 "the Glory of Arioch" };
3129 static const char *const hofe_titles[3] = { "
\83G
\83\8b\83x
\83\8c\83X
\82Ì
\8cä
\8eè",
3130 "
\92²
\98a
\82Ì
\8eg
\8eÒ",
3131 "
\83A
\83\8a\83I
\83b
\83`
\82Ì
\96¼
\97_" };
3133 you_are(hofe_titles[u.uevent.uhand_of_elbereth - 1], "");
3137 Sprintf(buf, "%s", piousness(TRUE, "aligned"));
3139 Sprintf(buf, "%s", piousness(TRUE, "
\90M
\8bÂ
\90S"));
3140 if (u.ualign.record >= 0)
3147 Sprintf(buf, " %d", u.ualign.record);
3148 enl_msg("Your alignment ", "is", "was", buf, "");
3150 Sprintf(buf, "
\82 \82È
\82½
\82Ì
\91®
\90«
\92l
\82Í%d", u.ualign.record);
3151 enl_msg(buf, "
\82Å
\82 \82é", "
\82¾
\82Á
\82½", "", "");
3155 /*** Resistances to troubles ***/
3158 you_are("invulnerable", from_what(INVULNERABLE));
3160 you_are("
\95s
\8e\80\90g", from_what(INVULNERABLE));
3163 you_are("magic-protected", from_what(ANTIMAGIC));
3165 you_have("
\96\82\96@
\96h
\8cä
\94\
\97Í", from_what(ANTIMAGIC));
3166 if (Fire_resistance)
3168 you_are("fire resistant", from_what(FIRE_RES));
3170 you_have("
\89Î
\82Ö
\82Ì
\91Ï
\90«", from_what(FIRE_RES));
3171 if (Cold_resistance)
3173 you_are("cold resistant", from_what(COLD_RES));
3175 you_have("
\8a¦
\82³
\82Ö
\82Ì
\91Ï
\90«", from_what(COLD_RES));
3176 if (Sleep_resistance)
3178 you_are("sleep resistant", from_what(SLEEP_RES));
3180 you_have("
\96°
\82è
\82Ö
\82Ì
\91Ï
\90«", from_what(SLEEP_RES));
3181 if (Disint_resistance)
3183 you_are("disintegration-resistant", from_what(DISINT_RES));
3185 you_have("
\95²
\8dÓ
\82Ö
\82Ì
\91Ï
\90«", from_what(DISINT_RES));
3186 if (Shock_resistance)
3188 you_are("shock resistant", from_what(SHOCK_RES));
3190 you_have("
\93d
\8c\82\82Ö
\82Ì
\91Ï
\90«", from_what(SHOCK_RES));
3191 if (Poison_resistance)
3193 you_are("poison resistant", from_what(POISON_RES));
3195 you_have("
\93Å
\82Ö
\82Ì
\91Ï
\90«", from_what(POISON_RES));
3196 if (Acid_resistance)
3198 you_are("acid resistant", from_what(ACID_RES));
3200 you_have("
\8e_
\82Ö
\82Ì
\91Ï
\90«", from_what(ACID_RES));
3201 if (Drain_resistance)
3203 you_are("level-drain resistant", from_what(DRAIN_RES));
3205 you_have("
\83\8c\83x
\83\8b\83_
\83E
\83\93\82Ö
\82Ì
\91Ï
\90«", from_what(DRAIN_RES));
3206 if (Sick_resistance)
3208 you_are("immune to sickness", from_what(SICK_RES));
3210 you_have("
\95a
\8bC
\82É
\91Î
\82·
\82é
\96Æ
\89u", from_what(SICK_RES));
3211 if (Stone_resistance)
3213 you_are("petrification resistant", from_what(STONE_RES));
3215 you_have("
\90Î
\89»
\82Ö
\82Ì
\91Ï
\90«", from_what(STONE_RES));
3216 if (Halluc_resistance)
3218 enl_msg(You_, "resist", "resisted", " hallucinations",
3219 from_what(HALLUC_RES));
3221 you_have("
\8c¶
\8ao
\82Ö
\82Ì
\91Ï
\90«", from_what(HALLUC_RES));
3225 you_can("recognize detrimental food", "");
3227 you_can("
\97L
\8aQ
\82È
\90H
\97¿
\82ð
\8e¯
\95Ê", "");
3229 /*** Vision and senses ***/
3230 if (!Blind && (Blinded || !haseyes(youmonst.data)))
3231 you_can("see", from_what(-BLINDED)); /* Eyes of the Overworld */
3232 if (See_invisible) {
3235 enl_msg(You_, "see", "saw", " invisible", from_what(SEE_INVIS));
3237 enl_msg("
\82 \82È
\82½
\82Í
\93§
\96¾
\82È
\82à
\82Ì
\82ð
\8c©
\82ç
\82ê", "
\82é", "
\82½", "", from_what(SEE_INVIS));
3240 enl_msg(You_, "will see", "would have seen",
3241 " invisible when not blind", from_what(SEE_INVIS));
3243 enl_msg(You_, "
\82é", "
\82½",
3244 "
\96Ó
\96Ú
\82Å
\82È
\82¢
\82Æ
\82«
\82É
\82Í
\93§
\96¾
\82È
\82à
\82Ì
\82ð
\8c©
\82ç
\82ê", from_what(SEE_INVIS));
3249 you_are("telepathic", from_what(TELEPAT));
3251 you_have("
\83e
\83\8c\83p
\83V
\81[", from_what(TELEPAT));
3254 you_are("warned", from_what(WARNING));
3256 you_have("
\8cx
\89ú
\94\
\97Í", from_what(WARNING));
3257 if (Warn_of_mon && context.warntype.obj) {
3259 Sprintf(buf, "aware of the presence of %s",
3260 (context.warntype.obj & M2_ORC) ? "orcs"
3261 : (context.warntype.obj & M2_ELF) ? "elves"
3262 : (context.warntype.obj & M2_DEMON) ? "demons" : something);
3263 you_are(buf, from_what(WARN_OF_MON));
3265 Sprintf(buf, "%s
\82Ì
\91¶
\8dÝ
\82ð
\8a´
\82¶
\82é
\94\
\97Í",
3266 (context.warntype.obj & M2_ORC) ? "
\83I
\81[
\83N"
3267 : (context.warntype.obj & M2_ELF) ? "
\83G
\83\8b\83t"
3268 : (context.warntype.obj & M2_DEMON) ? "
\88«
\96\82" : something);
3272 if (Warn_of_mon && context.warntype.polyd) {
3274 Sprintf(buf, "aware of the presence of %s",
3275 ((context.warntype.polyd & (M2_HUMAN | M2_ELF))
3276 == (M2_HUMAN | M2_ELF))
3277 ? "humans and elves"
3278 : (context.warntype.polyd & M2_HUMAN)
3280 : (context.warntype.polyd & M2_ELF)
3282 : (context.warntype.polyd & M2_ORC)
3284 : (context.warntype.polyd & M2_DEMON)
3286 : "certain monsters");
3289 Sprintf(buf, "%s
\82Ì
\91¶
\8dÝ
\82ð
\8a´
\82¶
\82é
\94\
\97Í",
3290 ((context.warntype.polyd & (M2_HUMAN | M2_ELF))
3291 == (M2_HUMAN | M2_ELF))
3292 ? "
\90l
\8aÔ
\82Æ
\83G
\83\8b\83t"
3293 : (context.warntype.polyd & M2_HUMAN)
3295 : (context.warntype.polyd & M2_ELF)
3297 : (context.warntype.polyd & M2_ORC)
3299 : (context.warntype.polyd & M2_DEMON)
3301 : "
\82 \82é
\8eí
\82Ì
\89ö
\95¨");
3305 if (Warn_of_mon && context.warntype.speciesidx >= LOW_PM) {
3307 Sprintf(buf, "aware of the presence of %s",
3308 makeplural(mons[context.warntype.speciesidx].mname));
3309 you_are(buf, from_what(WARN_OF_MON));
3311 Sprintf(buf, "%s
\82Ì
\91¶
\8dÝ
\82ð
\8a´
\82¶
\82é
\94\
\97Í",
3312 mons[context.warntype.speciesidx].mname);
3313 you_have(buf, from_what(WARN_OF_MON));
3318 you_are("warned of undead", from_what(WARN_UNDEAD));
3320 you_have("
\95s
\8e\80\82Ì
\90¶
\95¨
\82Ö
\82Ì
\8cx
\89ú
\94\
\97Í", from_what(WARN_UNDEAD));
3323 you_have("automatic searching", from_what(SEARCHING));
3325 you_have("
\92T
\8d¸
\94\
\97Í", from_what(SEARCHING));
3328 you_are("clairvoyant", from_what(CLAIRVOYANT));
3330 you_have("
\90ç
\97¢
\8aá
\94\
\97Í", from_what(CLAIRVOYANT));
3331 else if ((HClairvoyant || EClairvoyant) && BClairvoyant) {
3332 Strcpy(buf, from_what(-CLAIRVOYANT));
3334 if (!strncmp(buf, " because of ", 12))
3335 /* overwrite substring; strncpy doesn't add terminator */
3336 (void) strncpy(buf, " if not for ", 12);
3337 enl_msg(You_, "could be", "could have been", " clairvoyant", buf);
3339 /*JP:
\81u
\81c
\82É
\82æ
\82Á
\82Ä
\81v*/
3340 if (!strncmp(buf, "
\82É
\82æ
\82Á
\82Ä", 8))
3341 /*JP:
\81u
\81c
\82ª
\82È
\82¯
\82ê
\82Î
\81v
\82É
\8f\91\82«
\8a·
\82¦
\82é*/
3342 strcpy(eos(buf) - 8, "
\82ª
\82È
\82¯
\82ê
\82Î");
3343 you_have("
\90ç
\97¢
\8aá
\94\
\97Í", buf);
3348 you_have("infravision", from_what(INFRAVISION));
3350 you_have("
\90Ô
\8aO
\90ü
\82ª
\8c©
\82¦
\82é
\8e\8b\8ao", from_what(INFRAVISION));
3351 if (Detect_monsters)
3353 you_are("sensing the presence of monsters", "");
3355 you_have("
\89ö
\95¨
\82ð
\92T
\82·
\94\
\97Í", "");
3358 you_are("going to confuse monsters", "");
3360 you_have("
\89ö
\95¨
\82ð
\8d¬
\97\90\82³
\82¹
\82é
\94\
\97Í", "");
3362 /*** Appearance and behavior ***/
3366 if (uleft && uleft->otyp == RIN_ADORNMENT)
3367 adorn += uleft->spe;
3368 if (uright && uright->otyp == RIN_ADORNMENT)
3369 adorn += uright->spe;
3370 /* the sum might be 0 (+0 ring or two which negate each other);
3371 that yields "you are charismatic" (which isn't pointless
3372 because it potentially impacts seduction attacks) */
3374 Sprintf(buf, "%scharismatic",
3375 (adorn > 0) ? "more " : (adorn < 0) ? "less " : "");
3376 you_are(buf, from_what(ADORNED));
3378 Sprintf(buf, "
\96£
\97Í%s
\82Ä",
3379 (adorn > 0) ? "
\82ª
\91\9d\89Á
\82µ" : (adorn < 0) ? "
\82ª
\8c¸
\8f
\82µ" : "
\93I
\82É
\82È
\82Á");
3380 enl_msg(You_, "
\82Ä
\82¢
\82é", "
\82½", buf, "");
3385 you_are("invisible", from_what(INVIS));
3387 you_are("
\93§
\96¾", from_what(INVIS));
3390 you_are("invisible to others", from_what(INVIS));
3392 you_are("
\91¼
\90l
\82É
\91Î
\82µ
\82Ä
\93§
\96¾", from_what(INVIS));
3393 /* ordinarily "visible" is redundant; this is a special case for
3394 the situation when invisibility would be an expected attribute */
3395 else if ((HInvis || EInvis) && BInvis)
3397 you_are("visible", from_what(-INVIS));
3399 you_are("
\95s
\93§
\96¾", from_what(-INVIS));
3402 you_are("displaced", from_what(DISPLACED));
3404 you_have("
\8c¶
\89e
\94\
\97Í", from_what(DISPLACED));
3407 you_are("stealthy", from_what(STEALTH));
3409 you_have("
\90l
\96Ú
\82ð
\93\90\82Þ
\94\
\97Í", from_what(STEALTH));
3410 if (Aggravate_monster)
3412 enl_msg("You aggravate", "", "d", " monsters",
3413 from_what(AGGRAVATE_MONSTER));
3415 you_are_ing("
\94½
\8a´
\82ð
\82©
\82Á
\82Ä", from_what(AGGRAVATE_MONSTER));
3419 enl_msg("You cause", "", "d", " conflict", from_what(CONFLICT));
3421 you_are_ing("
\93¬
\91\88\82ð
\88ø
\82«
\8bN
\82±
\82µ
\82Ä", from_what(CONFLICT));
3423 /*** Transportation ***/
3426 you_can("jump", from_what(JUMPING));
3428 you_can("
\92µ
\96ô
\82·
\82é
\82±
\82Æ
\82ª", from_what(JUMPING));
3431 you_can("teleport", from_what(TELEPORT));
3433 you_can("
\8fu
\8aÔ
\88Ú
\93®
\82ª", from_what(TELEPORT));
3434 if (Teleport_control)
3436 you_have("teleport control", from_what(TELEPORT_CONTROL));
3438 you_have("
\8fu
\8aÔ
\88Ú
\93®
\82Ì
\90§
\8cä
\94\
\97Í", from_what(TELEPORT_CONTROL));
3439 /* actively levitating handled earlier as a status condition */
3440 if (BLevitation) { /* levitation is blocked */
3441 long save_BLev = BLevitation;
3445 /* either trapped in the floor or inside solid rock
3446 (or both if chained to buried iron ball and have
3447 moved one step into solid rock somehow) */
3448 boolean trapped = (save_BLev & I_SPECIAL) != 0L,
3449 terrain = (save_BLev & FROMOUTSIDE) != 0L;
3452 Sprintf(buf, "%s%s%s",
3453 trapped ? " if not trapped" : "",
3454 (trapped && terrain) ? " and" : "",
3455 terrain ? if_surroundings_permitted : "");
3456 enl_msg(You_, "would levitate", "would have levitated", buf, "");
3458 you_are("
\8fó
\8bµ
\82ª
\8b\96\82¹
\82Î
\95\82\97V
\82·
\82é
\8fó
\91Ô", "");
3461 BLevitation = save_BLev;
3463 /* actively flying handled earlier as a status condition */
3464 if (BFlying) { /* flight is blocked */
3465 long save_BFly = BFlying;
3470 enl_msg(You_, "would fly", "would have flown",
3471 /* wording quibble: for past tense, "hadn't been"
3472 would sound better than "weren't" (and
3473 "had permitted" better than "permitted"), but
3474 "weren't" and "permitted" are adequate so the
3475 extra complexity to handle that isn't worth it */
3477 ? " if you weren't levitating"
3478 : (save_BFly == I_SPECIAL)
3479 /* this is an oversimpliction; being trapped
3480 might also be blocking levitation so flight
3481 would still be blocked after escaping trap */
3482 ? " if you weren't trapped"
3483 : (save_BFly == FROMOUTSIDE)
3484 ? if_surroundings_permitted
3485 /* two or more of levitation, surroundings,
3486 and being trapped in the floor */
3487 : " if circumstances permitted",
3490 enl_msg(You_, "
\94ò
\82Ô
\82±
\82Æ
\82ª
\82Å
\82«
\82é", "
\94ò
\82Ô
\82±
\82Æ
\82ª
\82Å
\82«
\82½",
3491 /* wording quibble: for past tense, "hadn't been"
3492 would sound better than "weren't" (and
3493 "had permitted" better than "permitted"), but
3494 "weren't" and "permitted" are adequate so the
3495 extra complexity to handle that isn't worth it */
3497 ? "
\95\82\97V
\82µ
\82Ä
\82¢
\82È
\82¯
\82ê
\82Î"
3498 : (save_BFly == I_SPECIAL)
3499 /* this is an oversimpliction; being trapped
3500 might also be blocking levitation so flight
3501 would still be blocked after escaping trap */
3502 ? "
\95ß
\82Ü
\82Á
\82Ä
\82¢
\82È
\82¯
\82ê
\82Î"
3503 : (save_BFly == FROMOUTSIDE)
3504 ? "
\8fó
\8bµ
\82ª
\8b\96\82¹
\82Î"
3505 /* two or more of levitation, surroundings,
3506 and being trapped in the floor */
3507 : "
\8e\96\8fî
\82ª
\8b\96\82¹
\82Î",
3511 BFlying = save_BFly;
3513 /* actively walking on water handled earlier as a status condition */
3514 if (Wwalking && !walking_on_water())
3516 you_can("walk on water", from_what(WWALKING));
3518 you_can("
\90\85\82Ì
\8fã
\82ð
\95à
\82
\82±
\82Æ
\82ª", from_what(WWALKING));
3519 /* actively swimming (in water but not under it) handled earlier */
3520 if (Swimming && (Underwater || !u.uinwater))
3522 you_can("swim", from_what(SWIMMING));
3524 you_can("
\89j
\82®
\82±
\82Æ
\82ª", from_what(SWIMMING));
3527 you_can("survive without air", from_what(MAGICAL_BREATHING));
3529 you_can("
\8bó
\8bC
\82È
\82µ
\82Å
\90¶
\82«
\89\84\82Ñ
\82é
\82±
\82Æ
\82ª", from_what(MAGICAL_BREATHING));
3530 else if (Amphibious)
3532 you_can("breathe water", from_what(MAGICAL_BREATHING));
3534 you_can("
\90\85\92\86\82Å
\8cÄ
\8bz
\82ª", from_what(MAGICAL_BREATHING));
3537 you_can("walk through walls", from_what(PASSES_WALLS));
3539 you_can("
\95Ç
\82ð
\92Ê
\82è
\94²
\82¯
\82é
\82±
\82Æ
\82ª", from_what(PASSES_WALLS));
3541 /*** Physical attributes ***/
3544 enl_msg("You regenerate", "", "d", "", from_what(REGENERATION));
3546 you_have("
\8dÄ
\90¶
\94\
\97Í", from_what(REGENERATION));
3549 you_have("slower digestion", from_what(SLOW_DIGESTION));
3551 enl_msg("
\90H
\95¨
\82Ì
\8fÁ
\89»
\82ª
\92x", "
\82¢", "
\82©
\82Á
\82½", "", from_what(SLOW_DIGESTION));
3554 you_have(enlght_combatinc("to hit", u.uhitinc, final, buf), "");
3556 you_have(enlght_combatinc("
\96½
\92\86\97¦", u.uhitinc, final, buf), "");
3559 you_have(enlght_combatinc("damage", u.udaminc, final, buf), "");
3561 you_have(enlght_combatinc("
\83_
\83\81\81[
\83W", u.udaminc, final, buf), "");
3562 if (u.uspellprot || Protection) {
3565 if (uleft && uleft->otyp == RIN_PROTECTION)
3567 if (uright && uright->otyp == RIN_PROTECTION)
3568 prot += uright->spe;
3569 if (HProtection & INTRINSIC)
3571 prot += u.uspellprot;
3574 you_have(enlght_combatinc("defense", prot, final, buf), "");
3576 you_have(enlght_combatinc("
\96h
\8cä", prot, final, buf), "");
3578 if ((armpro = magic_negation(&youmonst)) > 0) {
3579 /* magic cancellation factor, conferred by worn armor */
3580 static const char *const mc_types[] = {
3582 "" /*ordinary*/, "warded", "guarded", "protected",
3584 "" /*ordinary*/, "
\89q
\82ç
\82ê
\82Ä", "
\8cì
\82ç
\82ê
\82Ä", "
\8eç
\82ç
\82ê
\82Ä",
3588 if (armpro >= SIZE(mc_types))
3589 armpro = SIZE(mc_types) - 1;
3591 you_are(mc_types[armpro], "");
3593 you_are_ing(mc_types[armpro], "");
3595 if (Half_physical_damage)
3596 enlght_halfdmg(HALF_PHDAM, final);
3597 if (Half_spell_damage)
3598 enlght_halfdmg(HALF_SPDAM, final);
3599 /* polymorph and other shape change */
3600 if (Protection_from_shape_changers)
3602 you_are("protected from shape changers",
3603 from_what(PROT_FROM_SHAPE_CHANGERS));
3605 you_have("
\95Ï
\89»
\89ö
\95¨
\82Ö
\82Ì
\91Ï
\90«", from_what(PROT_FROM_SHAPE_CHANGERS));
3608 const char *what = 0;
3610 if (!Upolyd) /* Upolyd handled below after current form */
3612 you_can("not change from your current form",
3614 you_are("
\8c»
\8dÝ
\82Ì
\8ep
\82©
\82ç
\95Ï
\89»
\82Å
\82«
\82È
\82¢
\8fó
\91Ô",
3615 from_what(UNCHANGING));
3616 /* blocked shape changes */
3619 what = !final ? "polymorph" : "have polymorphed";
3621 what = "
\95Ï
\89»
\82µ
\82Ä";
3622 else if (u.ulycn >= LOW_PM)
3624 what = !final ? "change shape" : "have changed shape";
3626 what = "
\8ep
\82ð
\95Ï
\82¦
\82Ä";
3629 Sprintf(buf, "would %s periodically", what);
3630 /* omit from_what(UNCHANGING); too verbose */
3631 enl_msg(You_, buf, buf, " if not locked into your current form",
3634 Sprintf(buf, "
\82à
\82µ
\8c»
\8dÝ
\82Ì
\8ep
\82É
\8cÅ
\92è
\82³
\82ê
\82Ä
\82¢
\82È
\82¯
\82ê
\82Î
\92è
\8aú
\93I
\82É%s", what);
3635 you_are_ing(buf, "");
3638 } else if (Polymorph) {
3640 you_are("polymorphing periodically", from_what(POLYMORPH));
3642 you_are("
\92è
\8aú
\93I
\82É
\95Ï
\89»
\82µ
\82Ä", from_what(POLYMORPH));
3644 if (Polymorph_control)
3646 you_have("polymorph control", from_what(POLYMORPH_CONTROL));
3648 you_have("
\95Ï
\89»
\82Ì
\90§
\8cä
\94\
\97Í", from_what(POLYMORPH_CONTROL));
3649 if (Upolyd && u.umonnum != u.ulycn
3650 /* if we've died from turning into slime, we're polymorphed
3651 right now but don't want to list it as a temporary attribute
3652 [we need a more reliable way to detect this situation] */
3653 && !(final == ENL_GAMEOVERDEAD
3654 && u.umonnum == PM_GREEN_SLIME && !Unchanging)) {
3655 /* foreign shape (except were-form which is handled below) */
3657 Sprintf(buf, "polymorphed into %s", an(youmonst.data->mname));
3659 Sprintf(buf, "%s
\82É
\95Ï
\89»
\82µ
\82Ä", youmonst.data->mname);
3661 Sprintf(eos(buf), " (%d)", u.mtimedone);
3664 if (lays_eggs(youmonst.data) && flags.female) /* Upolyd */
3666 you_can("lay eggs", "");
3668 you_can("
\97\91\82ð
\8eY
\82Þ
\82±
\82Æ
\82ª", "");
3669 if (u.ulycn >= LOW_PM) {
3671 /* "you are a werecreature [in beast form]" */
3672 Strcpy(buf, an(mons[u.ulycn].mname));
3673 if (u.umonnum == u.ulycn) {
3674 Strcat(buf, " in beast form");
3676 Sprintf(eos(buf), " (%d)", u.mtimedone);
3679 /*JP:
\81u
\82 \82È
\82½
\82Í[
\8fb
\82Ì
\8ep
\82Ì]
\81\9b\81\9b\90l
\8aÔ
\82Å
\82 \82é
\81v*/
3681 if (u.umonnum == u.ulycn) {
3682 Strcpy(buf, "
\8fb
\82Ì
\8ep
\82Ì");
3684 Sprintf(eos(buf), " (%d)", u.mtimedone);
3686 Strcat(buf, mons[u.ulycn].mname);
3690 if (Unchanging && Upolyd) /* !Upolyd handled above */
3692 you_can("not change from your current form", from_what(UNCHANGING));
3694 enl_msg("
\8d¡
\82Ì
\8ep
\82©
\82ç
\95Ï
\89»
\82·
\82é
\82±
\82Æ
\82ª
\82Å
\82«
\82È", "
\82¢", "
\82©
\82Á
\82½", "", from_what(UNCHANGING));
3697 you_are("harmed by silver", "");
3699 enl_msg("
\82 \82È
\82½
\82Í
\8bâ
\82É
\8eã", "
\82¢", "
\82©
\82Á
\82½", "", "");
3700 /* movement and non-armor-based protection */
3703 you_are(Very_fast ? "very fast" : "fast", from_what(FAST));
3705 you_have(Very_fast ? "
\82Æ
\82Ä
\82à
\91f
\91\81\82
\8ds
\93®
\82·
\82é
\94\
\97Í" : "
\91f
\91\81\82
\8ds
\93®
\82·
\82é
\94\
\97Í", from_what(FAST));
3708 you_have("reflection", from_what(REFLECTING));
3710 you_have("
\94½
\8eË
\94\
\97Í", from_what(REFLECTING));
3713 you_have("free action", from_what(FREE_ACTION));
3715 you_have("
\8dS
\91©
\82³
\82ê
\82È
\82¢
\94\
\97Í", from_what(FREE_ACTION));
3718 you_have("fixed abilities", from_what(FIXED_ABIL));
3720 enl_msg("
\94\
\97Í
\82ª
\95Ï
\89»
\82µ
\82È", "
\82¢", "
\82©
\82Á
\82½", "", from_what(FIXED_ABIL));
3723 enl_msg("Your life ", "will be", "would have been", " saved", "");
3725 enl_msg("
\82 \82È
\82½
\82Ì
\90¶
\96½
\82Í
\95Û
\91¶
\82³
\82ê
\82Ä", iru, ita, "", "");
3727 /*** Miscellany ***/
3729 ltmp = abs((int) Luck);
3731 Sprintf(buf, "%s%slucky",
3732 ltmp >= 10 ? "extremely " : ltmp >= 5 ? "very " : "",
3733 Luck < 0 ? "un" : "");
3735 Sprintf(buf, "%s%s",
3736 ltmp >= 10 ? "
\96Ò
\97ó
\82É" : ltmp >= 5 ? "
\82Æ
\82Ä
\82à" : "",
3737 Luck < 0 ? "
\95s
\8dK" : "
\8dK
\95\9f");
3740 Sprintf(eos(buf), " (%d)", Luck);
3744 enl_msg("Your luck ", "is", "was", " zero", "");
3746 enl_msg("
\82 \82È
\82½
\82Ì
\89^
\82Í
\83[
\83\8d", "
\82Å
\82 \82é", "
\82¾
\82Á
\82½", "", "");
3749 you_have("extra luck", "");
3751 you_have("
\82³
\82ç
\82È
\82é
\8dK
\89^", "");
3752 else if (u.moreluck < 0)
3754 you_have("reduced luck", "");
3756 you_have("
\82³
\82ç
\82È
\82é
\95s
\89^", "");
3757 if (carrying(LUCKSTONE) || stone_luck(TRUE)) {
3758 ltmp = stone_luck(FALSE);
3761 enl_msg("Bad luck ", "does", "did", " not time out for you", "");
3763 enl_msg("
\95s
\89^
\82Í
\8e\9e\8aÔ
\90Ø
\82ê
\82É
\82È
\82ç
\82È", "
\82¢", "
\82©
\82Á
\82½", "", "");
3766 enl_msg("Good luck ", "does", "did", " not time out for you", "");
3768 enl_msg("
\8dK
\89^
\82Í
\8e\9e\8aÔ
\90Ø
\82ê
\82É
\82È
\82ç
\82È", "
\82¢", "
\82©
\82Á
\82½", "", "");
3773 Sprintf(buf, " %sangry with you",
3774 u.ugangr > 6 ? "extremely " : u.ugangr > 3 ? "very " : "");
3776 Sprintf(buf, "%s
\82Í%s
\93{
\82Á
\82Ä%s", u_gname(),
3777 u.ugangr > 6 ? "
\96Ò
\97ó
\82É" : u.ugangr > 3 ? "
\82Æ
\82Ä
\82à" : "", final ? ita : iru);
3780 Sprintf(eos(buf), " (%d)", u.ugangr);
3782 enl_msg(u_gname(), " is", " was", buf, "");
3784 enl_msg(buf, "", "", "", "");
3788 * We need to suppress this when the game is over, because death
3789 * can change the value calculated by can_pray(), potentially
3790 * resulting in a false claim that you could have prayed safely.
3795 /* "can [not] safely pray" vs "could [not] have safely prayed" */
3796 Sprintf(buf, "%s%ssafely pray%s", can_pray(FALSE) ? "" : "not ",
3797 final ? "have " : "", final ? "ed" : "");
3799 Sprintf(buf, "%ssafely pray", can_pray(FALSE) ? "" : "not ");
3802 Sprintf(eos(buf), " (%d)", u.ublesscnt);
3805 Sprintf(buf, "
\82 \82È
\82½
\82Í
\88À
\91S
\82É
\8bF
\82é
\82±
\82Æ
\82ª");
3806 Strcat(buf, can_pray(FALSE) ? can : "
\82Å
\82«
\82È
\82¢");
3808 Sprintf(eos(buf), " (%d)", u.ublesscnt);
3809 enl_msg(buf, "", "", "", "");
3815 /* named fruit debugging (doesn't really belong here...); to enable,
3816 include 'fruit' in DEBUGFILES list (even though it isn't a file...) */
3817 if (wizard && explicitdebug("fruit")) {
3820 reorder_fruit(TRUE); /* sort by fruit index, from low to high;
3821 * this modifies the ffruit chain, so could
3822 * possibly mask or even introduce a problem,
3823 * but it does useful sanity checking */
3824 for (f = ffruit; f; f = f->nextf) {
3826 Sprintf(buf, "Fruit #%d ", f->fid);
3828 Sprintf(buf, "fruit $%d
\82Í", f->fid);
3830 enl_msg(buf, "is ", "was ", f->fname, "");
3832 enl_msg(buf, "
\82¾", "
\82¾
\82Á
\82½", f->fname, "");
3835 enl_msg("The current fruit ", "is ", "was ", pl_fruit, "");
3837 enl_msg("
\8c»
\8dÝ
\82Ì fruit
\82Í", "
\82¾", "
\82¾
\82Á
\82½", pl_fruit, "");
3838 Sprintf(buf, "%d", flags.made_fruit);
3840 enl_msg("The made fruit flag ", "is ", "was ", buf, "");
3842 enl_msg("made fruit flag
\82Í", "
\82¾", "
\82¾
\82Á
\82½", buf, "");
3850 if (final < 2) { /* still in progress, or quit/escaped/ascended */
3852 p = "survived after being killed ";
3854 p = "
\8e\80\82ñ
\82¾
\8cã
\95\9c\8a\88\82µ
\82Ä
\82¢
\82½";
3855 switch (u.umortality) {
3858 p = !final ? (char *) 0 : "survived";
3860 p = !final ? (char *)0 : "
\90¶
\82«
\89\84\82Ñ
\82½";
3864 Strcpy(buf, "once");
3866 Strcpy(buf, "
\88ê
\93x");
3870 Strcpy(buf, "twice");
3872 Strcpy(buf, "
\93ñ
\93x");
3876 Strcpy(buf, "thrice");
3878 Strcpy(buf, "
\8eO
\93x");
3882 Sprintf(buf, "%d times", u.umortality);
3884 Sprintf(buf, "%d
\89ñ", u.umortality);
3887 } else { /* game ended in character's death */
3891 p = "
\8e\80\82ñ
\82Å
\82¢
\82é";
3892 switch (u.umortality) {
3894 impossible("dead without dying?");
3896 break; /* just "are dead" */
3899 Sprintf(buf, " (%d%s time!)", u.umortality,
3900 ordin(u.umortality));
3902 Sprintf(buf, "(%d
\89ñ
\81I)", u.umortality);
3909 enl_msg(You_, "have been killed ", p, buf, "");
3911 enl_msg(You_, "
\8e\80\82ñ
\82Å
\82¢
\82é", p, buf, "");
3915 #if 0 /* no longer used */
3916 STATIC_DCL boolean NDECL(minimal_enlightenment);
3919 * Courtesy function for non-debug, non-explorer mode players
3920 * to help refresh them about who/what they are.
3921 * Returns FALSE if menu cancelled (dismissed with ESC), TRUE otherwise.
3924 minimal_enlightenment()
3927 menu_item *selected;
3930 char buf[BUFSZ], buf2[BUFSZ];
3931 static const char untabbed_fmtstr[] = "%-15s: %-12s";
3932 static const char untabbed_deity_fmtstr[] = "%-17s%s";
3933 static const char tabbed_fmtstr[] = "%s:\t%-12s";
3934 static const char tabbed_deity_fmtstr[] = "%s\t%s";
3935 static const char *fmtstr;
3936 static const char *deity_fmtstr;
3938 fmtstr = iflags.menu_tab_sep ? tabbed_fmtstr : untabbed_fmtstr;
3939 deity_fmtstr = iflags.menu_tab_sep ? tabbed_deity_fmtstr
3940 : untabbed_deity_fmtstr;
3942 buf[0] = buf2[0] = '\0';
3943 tmpwin = create_nhwindow(NHW_MENU);
3945 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
3951 /* Starting name, race, role, gender */
3953 Sprintf(buf, fmtstr, "name", plname);
3955 Sprintf(buf, fmtstr, "
\96¼
\91O", plname);
3956 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
3958 Sprintf(buf, fmtstr, "race", urace.noun);
3960 Sprintf(buf, fmtstr, "
\8eí
\91°", urace.noun);
3961 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
3963 Sprintf(buf, fmtstr, "role",
3965 Sprintf(buf, fmtstr, "
\90E
\8bÆ",
3966 (flags.initgend && urole.name.f) ? urole.name.f : urole.name.m);
3967 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
3969 Sprintf(buf, fmtstr, "gender", genders[flags.initgend].adj);
3971 Sprintf(buf, fmtstr, "
\90«
\95Ê", genders[flags.initgend].adj);
3972 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
3974 /* Starting alignment */
3976 Sprintf(buf, fmtstr, "alignment", align_str(u.ualignbase[A_ORIGINAL]));
3978 Sprintf(buf, fmtstr, "
\91®
\90«", align_str(u.ualignbase[A_ORIGINAL]));
3979 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
3981 /* Current name, race, role, gender */
3982 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, "", FALSE);
3983 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
3989 Sprintf(buf, fmtstr, "race", Upolyd ? youmonst.data->mname : urace.noun);
3991 Sprintf(buf, fmtstr, "
\8eí
\91°", Upolyd ? youmonst.data->mname : urace.noun);
3992 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
3995 Sprintf(buf, fmtstr, "role (base)",
3997 Sprintf(buf, fmtstr, "
\90E
\8bÆ(
\8aî
\96{)",
3998 (u.mfemale && urole.name.f) ? urole.name.f
4000 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4003 Sprintf(buf, fmtstr, "role",
4005 Sprintf(buf, fmtstr, "
\90E
\8bÆ",
4006 (flags.female && urole.name.f) ? urole.name.f
4008 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4010 /* don't want poly_gender() here; it forces `2' for non-humanoids */
4011 genidx = is_neuter(youmonst.data) ? 2 : flags.female;
4013 Sprintf(buf, fmtstr, "gender", genders[genidx].adj);
4015 Sprintf(buf, fmtstr, "
\90«
\95Ê", genders[genidx].adj);
4016 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4017 if (Upolyd && (int) u.mfemale != genidx) {
4019 Sprintf(buf, fmtstr, "gender (base)", genders[u.mfemale].adj);
4021 Sprintf(buf, fmtstr, "
\90«
\95Ê(
\8aî
\96{)", genders[u.mfemale].adj);
4022 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4025 /* Current alignment */
4027 Sprintf(buf, fmtstr, "alignment", align_str(u.ualign.type));
4029 Sprintf(buf, fmtstr, "
\91®
\90«", align_str(u.ualign.type));
4030 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4033 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, "", FALSE);
4034 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
4040 Sprintf(buf2, deity_fmtstr, align_gname(A_CHAOTIC),
4041 (u.ualignbase[A_ORIGINAL] == u.ualign.type
4042 && u.ualign.type == A_CHAOTIC) ? " (s,c)"
4043 : (u.ualignbase[A_ORIGINAL] == A_CHAOTIC) ? " (s)"
4044 : (u.ualign.type == A_CHAOTIC) ? " (c)" : "");
4046 Sprintf(buf2, deity_fmtstr, align_gname(A_CHAOTIC),
4047 (u.ualignbase[A_ORIGINAL] == u.ualign.type
4048 && u.ualign.type == A_CHAOTIC) ? " (
\8f\89\81C
\8c»)"
4049 : (u.ualignbase[A_ORIGINAL] == A_CHAOTIC) ? " (
\8f\89)"
4050 : (u.ualign.type == A_CHAOTIC) ? " (
\8c»)" : "");
4053 Sprintf(buf, fmtstr, "Chaotic", buf2);
4055 Sprintf(buf, fmtstr, "
\8d¬
\93×", buf2);
4056 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4059 Sprintf(buf2, deity_fmtstr, align_gname(A_NEUTRAL),
4060 (u.ualignbase[A_ORIGINAL] == u.ualign.type
4061 && u.ualign.type == A_NEUTRAL) ? " (s,c)"
4062 : (u.ualignbase[A_ORIGINAL] == A_NEUTRAL) ? " (s)"
4063 : (u.ualign.type == A_NEUTRAL) ? " (c)" : "");
4065 Sprintf(buf2, deity_fmtstr, align_gname(A_NEUTRAL),
4066 (u.ualignbase[A_ORIGINAL] == u.ualign.type
4067 && u.ualign.type == A_NEUTRAL) ? " (
\8f\89\81C
\8c»)"
4068 : (u.ualignbase[A_ORIGINAL] == A_NEUTRAL) ? " (
\8f\89)"
4069 : (u.ualign.type == A_NEUTRAL) ? " (
\8c»)" : "");
4072 Sprintf(buf, fmtstr, "Neutral", buf2);
4074 Sprintf(buf, fmtstr, "
\92\86\97§", buf2);
4075 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4078 Sprintf(buf2, deity_fmtstr, align_gname(A_LAWFUL),
4079 (u.ualignbase[A_ORIGINAL] == u.ualign.type
4080 && u.ualign.type == A_LAWFUL) ? " (s,c)"
4081 : (u.ualignbase[A_ORIGINAL] == A_LAWFUL) ? " (s)"
4082 : (u.ualign.type == A_LAWFUL) ? " (c)" : "");
4084 Sprintf(buf2, deity_fmtstr, align_gname(A_LAWFUL),
4085 (u.ualignbase[A_ORIGINAL] == u.ualign.type
4086 && u.ualign.type == A_LAWFUL) ? " (
\8f\89\81C
\8c»)"
4087 : (u.ualignbase[A_ORIGINAL] == A_LAWFUL) ? " (
\8f\89)"
4088 : (u.ualign.type == A_LAWFUL) ? " (
\8c»)" : "");
4091 Sprintf(buf, fmtstr, "Lawful", buf2);
4093 Sprintf(buf, fmtstr, "
\92\81\8f\98", buf2);
4094 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4097 end_menu(tmpwin, "Base Attributes");
4099 end_menu(tmpwin, "
\8aî
\96{
\91®
\90«");
4100 n = select_menu(tmpwin, PICK_NONE, &selected);
4101 destroy_nhwindow(tmpwin);
4102 return (boolean) (n != -1);
4108 doattributes(VOID_ARGS)
4110 int mode = BASICENLIGHTENMENT;
4112 /* show more--as if final disclosure--for wizard and explore modes */
4113 if (wizard || discover)
4114 mode |= MAGICENLIGHTENMENT;
4116 enlightenment(mode, ENL_GAMEINPROGRESS);
4121 youhiding(via_enlghtmt, msgflag)
4122 boolean via_enlghtmt; /* englightment line vs topl message */
4123 int msgflag; /* for variant message phrasing */
4125 char *bp, buf[BUFSZ];
4128 Strcpy(buf, "hiding");
4130 Strcpy(buf, "
\89B
\82ê");
4131 if (U_AP_TYPE != M_AP_NOTHING) {
4132 /* mimic; hero is only able to mimic a strange object or gold
4133 or hallucinatory alternative to gold, so we skip the details
4134 for the hypothetical furniture and monster cases */
4135 #if 0 /*JP*//*
\8cã
\82ë
\82É
\89ñ
\82·*//* not used */
4136 bp = eos(strcpy(buf, "mimicking"));
4138 if (U_AP_TYPE == M_AP_OBJECT) {
4140 Sprintf(bp, " %s", an(simple_typename(youmonst.mappearance)));
4142 Strcpy(buf, simple_typename(youmonst.mappearance));
4143 } else if (U_AP_TYPE == M_AP_FURNITURE) {
4145 Strcpy(bp, " something");
4147 Strcpy(buf, "
\89½
\82©");
4148 } else if (U_AP_TYPE == M_AP_MONSTER) {
4150 Strcpy(bp, " someone");
4152 Strcpy(buf, "
\89½
\8eÒ
\82©");
4154 ; /* something unexpected; leave 'buf' as-is */
4156 #if 1 /*JP*//*
\82±
\82±
\82Å
\92Ç
\89Á*/
4157 Strcat(buf, "
\82Ì
\82Ó
\82è
\82ð
\82µ");
4159 } else if (u.uundetected) {
4160 bp = eos(buf); /* points past "hiding" */
4161 if (youmonst.data->mlet == S_EEL) {
4162 if (is_pool(u.ux, u.uy))
4164 Sprintf(bp, " in the %s", waterbody_name(u.ux, u.uy));
4166 Sprintf(bp, "%s
\82Ì
\92\86\82É", waterbody_name(u.ux, u.uy));
4167 } else if (hides_under(youmonst.data)) {
4168 struct obj *o = level.objects[u.ux][u.uy];
4172 Sprintf(bp, " underneath %s", ansimpleoname(o));
4174 Sprintf(bp, "%s
\82Ì
\89º
\82É", ansimpleoname(o));
4175 } else if (is_clinger(youmonst.data) || Flying) {
4176 /* Flying: 'lurker above' hides on ceiling but doesn't cling */
4178 Sprintf(bp, " on the %s", ceiling(u.ux, u.uy));
4180 Sprintf(bp, "%s
\82É", ceiling(u.ux, u.uy));
4182 /* on floor; is_hider() but otherwise not special: 'trapper' */
4183 if (u.utrap && u.utraptype == TT_PIT) {
4184 struct trap *t = t_at(u.ux, u.uy);
4187 Sprintf(bp, " in a %spit",
4188 (t && t->ttyp == SPIKED_PIT) ? "spiked " : "");
4190 Sprintf(bp, "%s
\97\8e\82µ
\8c\8a\82Ì
\92\86\82É",
4191 (t && t->ttyp == SPIKED_PIT) ? "
\83g
\83Q
\82¾
\82ç
\82¯
\82Ì" : "");
4195 Sprintf(bp, " on the %s", surface(u.ux, u.uy));
4197 Sprintf(bp, "%s
\82É", surface(u.ux, u.uy));
4199 #if 1 /*JP*//*
\82±
\82±
\82Å
\92Ç
\89Á*/
4200 Strcat(buf, "
\89B
\82ê");
4203 ; /* shouldn't happen; will result in generic "you are hiding" */
4207 int final = msgflag; /* 'final' is used by you_are() macro */
4211 /* for dohide(), when player uses '#monster' command */
4213 You("are %s %s.", msgflag ? "already" : "now", buf);
4216 You("
\82·
\82Å
\82É%s
\82Ä
\82¢
\82é
\81D", buf);
4218 You("%s
\82½
\81D", buf);
4225 * (shares enlightenment's tense handling)
4228 doconduct(VOID_ARGS)
4241 /* Create the conduct window */
4242 en_win = create_nhwindow(NHW_MENU);
4244 putstr(en_win, 0, "Voluntary challenges:");
4246 putstr(en_win, 0, "
\8e©
\94
\93I
\92§
\90í:");
4248 if (u.uroleplay.blind)
4250 you_have_been("blind from birth");
4252 you_have_been("
\90¶
\82Ü
\82ê
\82È
\82ª
\82ç
\82É
\96Ó
\96Ú");
4253 if (u.uroleplay.nudist)
4255 you_have_been("faithfully nudist");
4257 you_have_been("
\92\89\8eÀ
\82È
\97\87\91°");
4259 if (!u.uconduct.food)
4261 enl_msg(You_, "have gone", "went", " without food", "");
4263 enl_msg("
\82 \82È
\82½
\82Í
\90H
\8e\96\82ð
\82µ", "
\82Ä
\82¢
\82È
\82¢", "
\82È
\82©
\82Á
\82½", "", "");
4264 /* but beverages are okay */
4265 else if (!u.uconduct.unvegan)
4267 you_have_X("followed a strict vegan diet");
4269 you_have_been("
\8cµ
\8ai
\82È
\8dØ
\90H
\8eå
\8b`
\8eÒ");
4270 else if (!u.uconduct.unvegetarian)
4272 you_have_been("vegetarian");
4274 you_have_been("
\8dØ
\90H
\8eå
\8b`
\8eÒ");
4276 if (!u.uconduct.gnostic)
4278 you_have_been("an atheist");
4280 you_have_been("
\96³
\90_
\98_
\8eÒ");
4282 if (!u.uconduct.weaphit) {
4284 you_have_never("hit with a wielded weapon");
4286 you_have_never("
\82 \82È
\82½
\82Í
\91\95\94õ
\82µ
\82Ä
\82¢
\82é
\95\90\8aí
\82Å
\8dU
\8c\82\82µ");
4287 } else if (wizard) {
4289 Sprintf(buf, "used a wielded weapon %ld time%s", u.uconduct.weaphit,
4290 plur(u.uconduct.weaphit));
4293 Sprintf(buf, "
\82 \82È
\82½
\82Í%ld
\89ñ
\91\95\94õ
\82µ
\82½
\95\90\8aí
\82ð
\8eg
\97p
\82µ", u.uconduct.weaphit);
4297 if (!u.uconduct.killer)
4299 you_have_been("a pacifist");
4301 you_have_been("
\95½
\98a
\8eå
\8b`
\8eÒ");
4303 if (!u.uconduct.literate) {
4305 you_have_been("illiterate");
4307 you_have_never("
\82 \82È
\82½
\82Í
\93Ç
\82Ý
\8f\91\82«
\82µ");
4308 } else if (wizard) {
4310 Sprintf(buf, "read items or engraved %ld time%s", u.uconduct.literate,
4311 plur(u.uconduct.literate));
4314 Sprintf(buf, "%ld
\89ñ
\93Ç
\82ñ
\82¾
\82è
\8f\91\82¢
\82½
\82è
\82µ", u.uconduct.literate);
4319 ngenocided = num_genocides();
4320 if (ngenocided == 0) {
4322 you_have_never("genocided any monsters");
4324 you_have_never("
\82 \82È
\82½
\82Í
\89ö
\95¨
\82ð
\8bs
\8eE
\82µ");
4327 Sprintf(buf, "genocided %d type%s of monster%s", ngenocided,
4328 plur(ngenocided), plur(ngenocided));
4331 Sprintf(buf, "%d
\8eí
\82Ì
\89ö
\95¨
\82ð
\8bs
\8eE
\82µ", ngenocided);
4336 if (!u.uconduct.polypiles) {
4338 you_have_never("polymorphed an object");
4340 you_have_never("
\82 \82È
\82½
\82Í
\95¨
\91Ì
\82ð
\95Ï
\89»
\82³
\82¹");
4341 } else if (wizard) {
4343 Sprintf(buf, "polymorphed %ld item%s", u.uconduct.polypiles,
4344 plur(u.uconduct.polypiles));
4347 Sprintf(buf, "%ld
\8cÂ
\82Ì
\95¨
\82ð
\95Ï
\89»
\82³
\82¹", u.uconduct.polypiles);
4352 if (!u.uconduct.polyselfs) {
4354 you_have_never("changed form");
4356 you_have_never("
\82 \82È
\82½
\82Í
\95Ï
\89»
\82µ");
4357 } else if (wizard) {
4359 Sprintf(buf, "changed form %ld time%s", u.uconduct.polyselfs,
4360 plur(u.uconduct.polyselfs));
4363 Sprintf(buf, "%ld
\89ñ
\8ep
\82ð
\95Ï
\82¦", u.uconduct.polyselfs);
4368 if (!u.uconduct.wishes) {
4370 you_have_X("used no wishes");
4372 you_have_never("
\82 \82È
\82½
\82Í
\8aè
\82¢
\8e\96\82ð
\82µ");
4375 Sprintf(buf, "used %ld wish%s", u.uconduct.wishes,
4376 (u.uconduct.wishes > 1L) ? "es" : "");
4378 Sprintf(buf, "%ld
\89ñ
\8aè
\82¢
\8e\96\82ð
\82µ", u.uconduct.wishes);
4380 if (u.uconduct.wisharti) {
4381 /* if wisharti == wishes
4382 * 1 wish (for an artifact)
4383 * 2 wishes (both for artifacts)
4384 * N wishes (all for artifacts)
4385 * else (N is at least 2 in order to get here; M < N)
4386 * N wishes (1 for an artifact)
4387 * N wishes (M for artifacts)
4389 if (u.uconduct.wisharti == u.uconduct.wishes)
4390 Sprintf(eos(buf), " (%s",
4391 (u.uconduct.wisharti > 2L) ? "all "
4392 : (u.uconduct.wisharti == 2L) ? "both " : "");
4394 Sprintf(eos(buf), " (%ld ", u.uconduct.wisharti);
4396 Sprintf(eos(buf), "for %s)",
4397 (u.uconduct.wisharti == 1L) ? "an artifact"
4402 if (!u.uconduct.wisharti)
4404 enl_msg(You_, "have not wished", "did not wish",
4405 " for any artifacts", "");
4407 enl_msg("
\82 \82È
\82½
\82Í
\90¹
\8aí
\82ð
\8aè", "
\82Á
\82Ä
\82¢
\82È
\82¢", "
\82í
\82È
\82©
\82Á
\82½", "", "");
4411 /* Pop up the window and wait for a key */
4412 display_nhwindow(en_win, TRUE);
4413 destroy_nhwindow(en_win);
4417 /* ordered by command name */
4418 struct ext_func_tab extcmdlist[] = {
4419 { '#', "#", "perform an extended command",
4420 doextcmd, IFBURIED | GENERALCMD },
4422 { M('?'), "?", "list all extended commands",
4424 { M('?'), "?", "
\82±
\82Ì
\8ag
\92£
\83R
\83}
\83\93\83h
\88ê
\97\97\82ð
\95\
\8e¦
\82·
\82é",
4426 doextlist, IFBURIED | AUTOCOMPLETE | GENERALCMD },
4428 { M('a'), "adjust", "adjust inventory letters",
4430 { M('a'), "adjust", "
\8e\9d\82¿
\95¨
\88ê
\97\97\82Ì
\92²
\90®",
4432 doorganize, IFBURIED | AUTOCOMPLETE },
4434 { M('A'), "annotate", "name current level",
4436 { M('A'), "annotate", "
\8c»
\8dÝ
\82Ì
\8aK
\82É
\96¼
\91O
\82ð
\82Â
\82¯
\82é",
4438 donamelevel, IFBURIED | AUTOCOMPLETE },
4439 { 'a', "apply", "apply (use) a tool (pick-axe, key, lamp...)",
4441 { C('x'), "attributes", "show your attributes",
4442 doattributes, IFBURIED },
4443 { '@', "autopickup", "toggle the pickup option on/off",
4444 dotogglepickup, IFBURIED },
4445 { 'C', "call", "call (name) something", docallcmd, IFBURIED },
4446 { 'Z', "cast", "zap (cast) a spell", docast, IFBURIED },
4448 { M('c'), "chat", "talk to someone", dotalk, IFBURIED | AUTOCOMPLETE },
4450 { M('c'), "chat", "
\92N
\82©
\82Æ
\98b
\82·", dotalk, IFBURIED | AUTOCOMPLETE },
4452 { 'c', "close", "close a door", doclose },
4454 { M('C'), "conduct", "list voluntary challenges you have maintained",
4456 { M('C'), "conduct", "
\82Ç
\82¤
\82¢
\82¤
\8ds
\93®
\82ð
\82Æ
\82Á
\82½
\82©
\8c©
\82é",
4458 doconduct, IFBURIED | AUTOCOMPLETE },
4460 { M('d'), "dip", "dip an object into something", dodip, AUTOCOMPLETE },
4462 { M('d'), "dip", "
\89½
\82©
\82É
\95¨
\82ð
\90Z
\82·", dodip, AUTOCOMPLETE },
4464 { '>', "down", "go down a staircase", dodown },
4465 { 'd', "drop", "drop an item", dodrop },
4466 { 'D', "droptype", "drop specific item types", doddrop },
4467 { 'e', "eat", "eat something", doeat },
4468 { 'E', "engrave", "engrave writing on the floor", doengrave },
4470 { M('e'), "enhance", "advance or check weapon and spell skills",
4472 { M('e'), "enhance", "
\95\90\8aí
\8fn
\97û
\93x
\82ð
\8d\82\82ß
\82é",
4474 enhance_weapon_skill, IFBURIED | AUTOCOMPLETE },
4476 { '\0', "exploremode", "enter explore (discovery) mode",
4478 { '\0', "exploremode", "
\92T
\8c\9f(
\94
\8c©)
\83\82\81[
\83h
\82É
\93ü
\82é",
4480 enter_explore_mode, IFBURIED },
4481 { 'f', "fire", "fire ammunition from quiver", dofire },
4483 { M('f'), "force", "force a lock", doforce, AUTOCOMPLETE },
4485 { M('f'), "force", "
\8c®
\82ð
\82±
\82¶
\82 \82¯
\82é", doforce, AUTOCOMPLETE },
4487 { ';', "glance", "show what type of thing a map symbol corresponds to",
4488 doquickwhatis, IFBURIED | GENERALCMD },
4489 { '?', "help", "give a help message", dohelp, IFBURIED | GENERALCMD },
4490 { '\0', "herecmdmenu", "show menu of commands you can do here",
4491 doherecmdmenu, IFBURIED },
4492 { 'V', "history", "show long version and game history",
4493 dohistory, IFBURIED | GENERALCMD },
4494 { 'i', "inventory", "show your inventory", ddoinv, IFBURIED },
4495 { 'I', "inventtype", "inventory specific item types",
4496 dotypeinv, IFBURIED },
4498 { M('i'), "invoke", "invoke an object's special powers",
4500 { M('i'), "invoke", "
\95¨
\82Ì
\93Á
\95Ê
\82È
\97Í
\82ð
\8eg
\82¤",
4502 doinvoke, IFBURIED | AUTOCOMPLETE },
4504 { M('j'), "jump", "jump to another location", dojump, AUTOCOMPLETE },
4506 { M('j'), "jump", "
\91¼
\82Ì
\88Ê
\92u
\82É
\94ò
\82Ñ
\82¤
\82Â
\82é", dojump, AUTOCOMPLETE },
4508 { C('d'), "kick", "kick something", dokick },
4509 { '\\', "known", "show what object types have been discovered",
4510 dodiscovered, IFBURIED | GENERALCMD },
4511 { '`', "knownclass", "show discovered types for one class of objects",
4512 doclassdisco, IFBURIED | GENERALCMD },
4514 { '\0', "levelchange", "change experience level",
4516 { '\0', "levelchange", "
\8co
\8c±
\83\8c\83x
\83\8b\82ð
\95Ï
\82¦
\82é",
4518 wiz_level_change, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4520 { '\0', "lightsources", "show mobile light sources",
4522 { '\0', "lightsources", "
\88Ú
\93®
\8cõ
\8c¹
\82ð
\8c©
\82é",
4524 wiz_light_sources, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4525 { ':', "look", "look at what is here", dolook, IFBURIED },
4527 { M('l'), "loot", "loot a box on the floor", doloot, AUTOCOMPLETE },
4529 { M('l'), "loot", "
\8f°
\82Ì
\8fã
\82Ì
\94 \82ð
\8aJ
\82¯
\82é", doloot, AUTOCOMPLETE },
4531 #ifdef DEBUG_MIGRATING_MONS
4533 { '\0', "migratemons", "migrate N random monsters",
4535 { '\0', "migratemons", "
\83\89\83\93\83_
\83\80\82È
\89ö
\95¨
\82ð
\89½
\91Ì
\82©
\88Ú
\8fZ
\82³
\82¹
\82é",
4537 wiz_migrate_mons, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4540 { M('m'), "monster", "use monster's special ability",
4542 { M('m'), "monster", "
\89ö
\95¨
\82Ì
\93Á
\95Ê
\94\
\97Í
\82ð
\8eg
\82¤",
4544 domonability, IFBURIED | AUTOCOMPLETE },
4546 { 'N', "name", "name a monster or an object",
4548 { 'N', "name", "
\83A
\83C
\83e
\83\80\82â
\95¨
\82É
\96¼
\91O
\82ð
\82Â
\82¯
\82é",
4550 docallcmd, IFBURIED | AUTOCOMPLETE },
4552 { M('o'), "offer", "offer a sacrifice to the gods",
4554 { M('o'), "offer", "
\90_
\82É
\8b\9f\95¨
\82ð
\95ù
\82°
\82é",
4556 dosacrifice, AUTOCOMPLETE },
4557 { 'o', "open", "open a door", doopen },
4558 { 'O', "options", "show option settings, possibly change them",
4559 doset, IFBURIED | GENERALCMD },
4561 { C('o'), "overview", "show a summary of the explored dungeon",
4563 { C('o'), "overview", "
\92T
\8dõ
\82µ
\82½
\96À
\8b{
\82Ì
\8aT
\97v
\82ð
\95\
\8e¦
\82·
\82é",
4565 dooverview, IFBURIED | AUTOCOMPLETE },
4567 { '\0', "panic", "test panic routine (fatal to game)",
4569 { '\0', "panic", "
\83p
\83j
\83b
\83N
\83\8b\81[
\83`
\83\93\82ð
\83e
\83X
\83g
\82·
\82é(
\92v
\96½
\93I)",
4571 wiz_panic, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4572 { 'p', "pay", "pay your shopping bill", dopay },
4573 { ',', "pickup", "pick up things at the current location", dopickup },
4575 { '\0', "polyself", "polymorph self",
4577 { '\0', "polyself", "
\95Ï
\89»
\82·
\82é",
4579 wiz_polyself, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4581 { M('p'), "pray", "pray to the gods for help",
4583 { M('p'), "pray", "
\90_
\82É
\8bF
\82é",
4585 dopray, IFBURIED | AUTOCOMPLETE },
4586 { C('p'), "prevmsg", "view recent game messages",
4587 doprev_message, IFBURIED | GENERALCMD },
4588 { 'P', "puton", "put on an accessory (ring, amulet, etc)", doputon },
4589 { 'q', "quaff", "quaff (drink) something", dodrink },
4591 { M('q'), "quit", "exit without saving current game",
4593 { M('q'), "quit", "
\83Z
\81[
\83u
\82µ
\82È
\82¢
\82Å
\8fI
\97¹",
4595 done2, IFBURIED | AUTOCOMPLETE | GENERALCMD },
4596 { 'Q', "quiver", "select ammunition for quiver", dowieldquiver },
4597 { 'r', "read", "read a scroll or spellbook", doread },
4598 { C('r'), "redraw", "redraw screen", doredraw, IFBURIED | GENERALCMD },
4599 { 'R', "remove", "remove an accessory (ring, amulet, etc)", doremring },
4601 { M('R'), "ride", "mount or dismount a saddled steed",
4603 { M('R'), "ride", "
\89ö
\95¨
\82É
\8fæ
\82é(
\82Ü
\82½
\82Í
\8d~
\82è
\82é)",
4605 doride, AUTOCOMPLETE },
4607 { M('r'), "rub", "rub a lamp or a stone", dorub, AUTOCOMPLETE },
4609 { M('r'), "rub", "
\83\89\83\93\83v
\82ð
\82±
\82·
\82é", dorub, AUTOCOMPLETE },
4611 { 'S', "save", "save the game and exit", dosave, IFBURIED | GENERALCMD },
4613 { 's', "search", "search for traps and secret doors",
4614 dosearch, IFBURIED, "searching" },
4616 { 's', "search", "ã©
\82â
\89B
\82µ
\94à
\82ð
\92T
\82·",
4617 dosearch, IFBURIED, "
\92T
\82·" },
4619 { '*', "seeall", "show all equipment in use", doprinuse, IFBURIED },
4620 { AMULET_SYM, "seeamulet", "show the amulet currently worn",
4621 dopramulet, IFBURIED },
4622 { ARMOR_SYM, "seearmor", "show the armor currently worn",
4623 doprarm, IFBURIED },
4624 { GOLD_SYM, "seegold", "count your gold", doprgold, IFBURIED },
4626 { '\0', "seenv", "show seen vectors",
4628 { '\0', "seenv", "
\8e\8b\90ü
\83x
\83N
\83g
\83\8b\82ð
\8c©
\82é",
4630 wiz_show_seenv, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4631 { RING_SYM, "seerings", "show the ring(s) currently worn",
4632 doprring, IFBURIED },
4633 { SPBOOK_SYM, "seespells", "list and reorder known spells",
4634 dovspell, IFBURIED },
4635 { TOOL_SYM, "seetools", "show the tools currently in use",
4636 doprtool, IFBURIED },
4637 { '^', "seetrap", "show the type of adjacent trap", doidtrap, IFBURIED },
4638 { WEAPON_SYM, "seeweapon", "show the weapon currently wielded",
4639 doprwep, IFBURIED },
4640 { '!', "shell", "do a shell escape",
4641 dosh_core, IFBURIED | GENERALCMD
4647 { M('s'), "sit", "sit down", dosit, AUTOCOMPLETE },
4649 { M('s'), "sit", "
\8dÀ
\82é", dosit, AUTOCOMPLETE },
4652 { '\0', "stats", "show memory statistics",
4654 { '\0', "stats", "
\83\81\83\82\83\8a\8fó
\91Ô
\82ð
\8c©
\82é",
4656 wiz_show_stats, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4657 { C('z'), "suspend", "suspend the game",
4658 dosuspend_core, IFBURIED | GENERALCMD
4661 #endif /* SUSPEND */
4663 { 'x', "swap", "swap wielded and secondary weapons", doswapweapon },
4664 { 'T', "takeoff", "take off one piece of armor", dotakeoff },
4665 { 'A', "takeoffall", "remove all armor", doddoremarm },
4666 { C('t'), "teleport", "teleport around the level", dotelecmd, IFBURIED },
4668 { '\0', "terrain", "show map without obstructions",
4670 { '\0', "terrain", "
\8e×
\96\82\82³
\82ê
\82¸
\82É
\92n
\90}
\82ð
\8c©
\82é",
4672 doterrain, IFBURIED | AUTOCOMPLETE },
4673 { '\0', "therecmdmenu",
4674 "menu of commands you can do from here to adjacent spot",
4676 { 't', "throw", "throw something", dothrow },
4678 { '\0', "timeout", "look at timeout queue and hero's timed intrinsics",
4680 { '\0', "timeout", "
\8e\9e\8aÔ
\90Ø
\82ê
\83L
\83\85\81[
\82Æ
\83v
\83\8c\83C
\83\84\81[
\82Ì
\8e\9e\8aÔ
\8co
\89ß
\82ð
\8c©
\82é",
4682 wiz_timeout_queue, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4684 { M('T'), "tip", "empty a container", dotip, AUTOCOMPLETE },
4686 { M('T'), "tip", "
\93ü
\82ê
\95¨
\82ð
\8bó
\82É
\82·
\82é", dotip, AUTOCOMPLETE },
4688 { '_', "travel", "travel to a specific location on the map", dotravel },
4690 { M('t'), "turn", "turn undead away", doturn, IFBURIED | AUTOCOMPLETE },
4692 { M('t'), "turn", "
\83A
\83\93\83f
\83b
\83g
\82ð
\93y
\82É
\95Ô
\82·", doturn, IFBURIED | AUTOCOMPLETE },
4695 { 'X', "twoweapon", "toggle two-weapon combat",
4697 { 'X', "twoweapon", "
\97¼
\8eè
\8e\9d\82¿
\82Ì
\90Ø
\82è
\91Ö
\82¦",
4699 dotwoweapon, AUTOCOMPLETE },
4701 { M('u'), "untrap", "untrap something", dountrap, AUTOCOMPLETE },
4703 { M('u'), "untrap", "ã©
\82ð
\82Í
\82¸
\82·", dountrap, AUTOCOMPLETE },
4705 { '<', "up", "go up a staircase", doup },
4707 { '\0', "vanquished", "list vanquished monsters",
4709 { '\0', "vanquished", "
\93|
\82µ
\82½
\89ö
\95¨
\82Ì
\88ê
\97\97\82ð
\8c©
\82é",
4711 dovanquished, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4712 { M('v'), "version",
4714 "list compile time options for this version of NetHack",
4716 "
\83R
\83\93\83p
\83C
\83\8b\8e\9e\82Ì
\83I
\83v
\83V
\83\87\83\93\82ð
\95\
\8e¦
\82·
\82é",
4718 doextversion, IFBURIED | AUTOCOMPLETE | GENERALCMD },
4719 { 'v', "versionshort", "show version", doversion, IFBURIED | GENERALCMD },
4721 { '\0', "vision", "show vision array",
4723 { '\0', "vision", "
\8e\8b\8aE
\94z
\97ñ
\82ð
\8c©
\82é",
4725 wiz_show_vision, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4727 { '.', "wait", "rest one move while doing nothing",
4728 donull, IFBURIED, "waiting" },
4730 { '.', "wait", "
\88ê
\95à
\95ª
\89½
\82à
\82µ
\82È
\82¢",
4731 donull, IFBURIED, "
\8bx
\8ce
\82·
\82é" },
4733 { 'W', "wear", "wear a piece of armor", dowear },
4734 { '&', "whatdoes", "tell what a command does", dowhatdoes, IFBURIED },
4735 { '/', "whatis", "show what type of thing a symbol corresponds to",
4736 dowhatis, IFBURIED | GENERALCMD },
4737 { 'w', "wield", "wield (put in use) a weapon", dowield },
4739 { M('w'), "wipe", "wipe off your face", dowipe, AUTOCOMPLETE },
4741 { M('w'), "wipe", "
\8aç
\82ð
\90@
\82¤", dowipe, AUTOCOMPLETE },
4745 { '\0', "wizbury", "bury objs under and around you",
4747 { '\0', "wizbury", "
\95¨
\82ð
\82 \82È
\82½
\82Ì
\8eü
\82è
\82É
\96\84\82ß
\82é",
4749 wiz_debug_cmd_bury, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4751 { C('e'), "wizdetect", "reveal hidden things within a small radius",
4752 wiz_detect, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4753 { C('g'), "wizgenesis", "create a monster",
4754 wiz_genesis, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4755 { C('i'), "wizidentify", "identify all items in inventory",
4756 wiz_identify, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4757 { '\0', "wizintrinsic", "set an intrinsic",
4758 wiz_intrinsic, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4759 { C('v'), "wizlevelport", "teleport to another level",
4760 wiz_level_tele, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4761 { '\0', "wizmakemap", "recreate the current level",
4762 wiz_makemap, IFBURIED | WIZMODECMD },
4763 { C('f'), "wizmap", "map the level",
4764 wiz_map, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4766 { '\0', "wizrumorcheck", "verify rumor boundaries",
4768 { '\0', "wizrumorcheck", "
\89\
\82Ì
\8b«
\8aE
\82ð
\8c\9f\8fØ
\82·
\82é",
4770 wiz_rumor_check, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4772 { '\0', "wizsmell", "smell monster",
4774 { '\0', "wizsmell", "
\89ö
\95¨
\82Ì
\93õ
\82¢
\82ð
\9ak
\82®",
4776 wiz_smell, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4777 { '\0', "wizwhere", "show locations of special levels",
4778 wiz_where, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4779 { C('w'), "wizwish", "wish for something",
4780 wiz_wish, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4782 { '\0', "wmode", "show wall modes",
4784 { '\0', "wmode", "
\95Ç
\83\82\81[
\83h
\82ð
\8c©
\82é",
4786 wiz_show_wmodes, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4787 { 'z', "zap", "zap a wand", dozap },
4788 { '\0', (char *) 0, (char *) 0, donull, 0, (char *) 0 } /* sentinel */
4791 int extcmdlist_length = SIZE(extcmdlist) - 1;
4797 if (Cmd.commands[key] && Cmd.commands[key]->ef_txt)
4798 return Cmd.commands[key]->ef_desc;
4803 bind_key(key, command)
4805 const char *command;
4807 struct ext_func_tab *extcmd;
4809 /* special case: "nothing" is reserved for unbinding */
4810 if (!strcmp(command, "nothing")) {
4811 Cmd.commands[key] = (struct ext_func_tab *) 0;
4815 for (extcmd = extcmdlist; extcmd->ef_txt; extcmd++) {
4816 if (strcmp(command, extcmd->ef_txt))
4818 Cmd.commands[key] = extcmd;
4819 #if 0 /* silently accept key binding for unavailable command (!SHELL,&c) */
4820 if ((extcmd->flags & CMD_NOT_AVAILABLE) != 0) {
4823 Sprintf(buf, cmdnotavail, extcmd->ef_txt);
4824 config_error_add("%s", buf);
4833 /* initialize all keyboard commands */
4837 struct ext_func_tab *extcmd;
4839 for (extcmd = extcmdlist; extcmd->ef_txt; extcmd++)
4841 Cmd.commands[extcmd->key] = extcmd;
4843 (void) bind_key(C('l'), "redraw"); /* if number_pad is set */
4844 /* 'b', 'B' : go sw */
4845 /* 'F' : fight (one time) */
4846 /* 'g', 'G' : multiple go */
4847 /* 'h', 'H' : go west */
4848 (void) bind_key('h', "help"); /* if number_pad is set */
4849 (void) bind_key('j', "jump"); /* if number_pad is on */
4850 /* 'j', 'J', 'k', 'K', 'l', 'L', 'm', 'M', 'n', 'N' move commands */
4851 (void) bind_key('k', "kick"); /* if number_pad is on */
4852 (void) bind_key('l', "loot"); /* if number_pad is on */
4853 (void) bind_key(C('n'), "annotate"); /* if number_pad is on */
4854 (void) bind_key(M('n'), "name");
4855 (void) bind_key(M('N'), "name");
4856 (void) bind_key('u', "untrap"); /* if number_pad is on */
4859 (void) bind_key(M('O'), "overview");
4860 (void) bind_key(M('2'), "twoweapon");
4863 (void) bind_key(' ', "wait");
4867 dokeylist_putcmds(datawin, docount, cmdflags, exflags, keys_used)
4870 int cmdflags, exflags;
4871 boolean *keys_used; /* boolean keys_used[256] */
4878 for (i = 0; i < 256; i++) {
4879 const struct ext_func_tab *extcmd;
4880 uchar key = (uchar) i;
4884 if (key == ' ' && !flags.rest_on_space)
4886 if ((extcmd = Cmd.commands[i]) != (struct ext_func_tab *) 0) {
4887 if ((cmdflags && !(extcmd->flags & cmdflags))
4888 || (exflags && (extcmd->flags & exflags)))
4894 Sprintf(buf, "%-8s %-12s %s", key2txt(key, buf2),
4897 putstr(datawin, 0, buf);
4898 keys_used[i] = TRUE;
4904 /* list all keys and their bindings, like dat/hh but dynamic */
4906 dokeylist(VOID_ARGS)
4908 char buf[BUFSZ], buf2[BUFSZ];
4910 boolean keys_used[256] = {0};
4914 run_desc[] = "Prefix: run until something very interesting is seen",
4916 "Prefix: force fight even if you don't see a monster";
4917 static const struct {
4922 { NHKF_ESC, "escape from the current query/action", FALSE },
4924 "Prefix: rush until something interesting is seen", FALSE },
4925 { NHKF_RUN, run_desc, FALSE },
4926 { NHKF_RUN2, run_desc, TRUE },
4927 { NHKF_FIGHT, forcefight_desc, FALSE },
4928 { NHKF_FIGHT2, forcefight_desc, TRUE } ,
4930 "Prefix: move without picking up objects/fighting", FALSE },
4931 { NHKF_RUN_NOPICKUP,
4932 "Prefix: run without picking up objects/fighting", FALSE },
4933 { NHKF_DOINV, "view inventory", TRUE },
4934 { NHKF_REQMENU, "Prefix: request a menu", FALSE },
4936 { NHKF_DOAGAIN , "re-do: perform the previous command again", FALSE },
4938 { 0, (const char *) 0, FALSE }
4941 datawin = create_nhwindow(NHW_TEXT);
4942 putstr(datawin, 0, "");
4943 putstr(datawin, 0, " Full Current Key Bindings List");
4945 /* directional keys */
4946 putstr(datawin, 0, "");
4947 putstr(datawin, 0, "Directional keys:");
4948 show_direction_keys(datawin, '.', FALSE); /* '.'==self in direction grid */
4950 keys_used[(uchar) Cmd.move_NW] = keys_used[(uchar) Cmd.move_N]
4951 = keys_used[(uchar) Cmd.move_NE] = keys_used[(uchar) Cmd.move_W]
4952 = keys_used[(uchar) Cmd.move_E] = keys_used[(uchar) Cmd.move_SW]
4953 = keys_used[(uchar) Cmd.move_S] = keys_used[(uchar) Cmd.move_SE]
4956 if (!iflags.num_pad) {
4957 keys_used[(uchar) highc(Cmd.move_NW)]
4958 = keys_used[(uchar) highc(Cmd.move_N)]
4959 = keys_used[(uchar) highc(Cmd.move_NE)]
4960 = keys_used[(uchar) highc(Cmd.move_W)]
4961 = keys_used[(uchar) highc(Cmd.move_E)]
4962 = keys_used[(uchar) highc(Cmd.move_SW)]
4963 = keys_used[(uchar) highc(Cmd.move_S)]
4964 = keys_used[(uchar) highc(Cmd.move_SE)] = TRUE;
4965 keys_used[(uchar) C(Cmd.move_NW)]
4966 = keys_used[(uchar) C(Cmd.move_N)]
4967 = keys_used[(uchar) C(Cmd.move_NE)]
4968 = keys_used[(uchar) C(Cmd.move_W)]
4969 = keys_used[(uchar) C(Cmd.move_E)]
4970 = keys_used[(uchar) C(Cmd.move_SW)]
4971 = keys_used[(uchar) C(Cmd.move_S)]
4972 = keys_used[(uchar) C(Cmd.move_SE)] = TRUE;
4973 putstr(datawin, 0, "");
4975 "Shift-<direction> will move in specified direction until you hit");
4976 putstr(datawin, 0, " a wall or run into something.");
4978 "Ctrl-<direction> will run in specified direction until something");
4979 putstr(datawin, 0, " very interesting is seen.");
4982 putstr(datawin, 0, "");
4983 putstr(datawin, 0, "Miscellaneous keys:");
4984 for (i = 0; misc_keys[i].desc; i++) {
4985 key = Cmd.spkeys[misc_keys[i].nhkf];
4986 if (key && ((misc_keys[i].numpad && iflags.num_pad)
4987 || !misc_keys[i].numpad)) {
4988 keys_used[(uchar) key] = TRUE;
4989 Sprintf(buf, "%-8s %s", key2txt(key, buf2), misc_keys[i].desc);
4990 putstr(datawin, 0, buf);
4994 putstr(datawin, 0, "^c break out of NetHack (SIGINT)");
4995 keys_used[(uchar) C('c')] = TRUE;
4998 putstr(datawin, 0, "");
4999 show_menu_controls(datawin, TRUE);
5001 if (dokeylist_putcmds(datawin, TRUE, GENERALCMD, WIZMODECMD, keys_used)) {
5002 putstr(datawin, 0, "");
5003 putstr(datawin, 0, "General commands:");
5004 (void) dokeylist_putcmds(datawin, FALSE, GENERALCMD, WIZMODECMD,
5008 if (dokeylist_putcmds(datawin, TRUE, 0, WIZMODECMD, keys_used)) {
5009 putstr(datawin, 0, "");
5010 putstr(datawin, 0, "Game commands:");
5011 (void) dokeylist_putcmds(datawin, FALSE, 0, WIZMODECMD, keys_used);
5015 && dokeylist_putcmds(datawin, TRUE, WIZMODECMD, 0, keys_used)) {
5016 putstr(datawin, 0, "");
5017 putstr(datawin, 0, "Wizard-mode commands:");
5018 (void) dokeylist_putcmds(datawin, FALSE, WIZMODECMD, 0, keys_used);
5021 display_nhwindow(datawin, FALSE);
5022 destroy_nhwindow(datawin);
5031 for (i = 0; i < 256; ++i)
5032 if (Cmd.commands[i] && Cmd.commands[i]->ef_funct == fn)
5038 * wizard mode sanity_check code
5041 static const char template[] = "%-27s %4ld %6ld";
5042 static const char stats_hdr[] = " count bytes";
5043 static const char stats_sep[] = "--------------------------- ----- -------";
5049 int sz = (int) sizeof (struct obj);
5052 sz += (int) sizeof (struct oextra);
5054 sz += (int) strlen(ONAME(otmp)) + 1;
5056 sz += size_monst(OMONST(otmp), FALSE);
5058 sz += (int) sizeof (unsigned);
5060 sz += (int) sizeof (long);
5062 sz += (int) strlen(OMAILCMD(otmp)) + 1;
5068 count_obj(chain, total_count, total_size, top, recurse)
5078 for (count = size = 0, obj = chain; obj; obj = obj->nobj) {
5081 size += size_obj(obj);
5083 if (recurse && obj->cobj)
5084 count_obj(obj->cobj, total_count, total_size, TRUE, TRUE);
5086 *total_count += count;
5087 *total_size += size;
5091 obj_chain(win, src, chain, force, total_count, total_size)
5100 long count = 0L, size = 0L;
5102 count_obj(chain, &count, &size, TRUE, FALSE);
5104 if (count || size || force) {
5105 *total_count += count;
5106 *total_size += size;
5107 Sprintf(buf, template, src, count, size);
5108 putstr(win, 0, buf);
5113 mon_invent_chain(win, src, chain, total_count, total_size)
5116 struct monst *chain;
5121 long count = 0, size = 0;
5124 for (mon = chain; mon; mon = mon->nmon)
5125 count_obj(mon->minvent, &count, &size, TRUE, FALSE);
5127 if (count || size) {
5128 *total_count += count;
5129 *total_size += size;
5130 Sprintf(buf, template, src, count, size);
5131 putstr(win, 0, buf);
5136 contained_stats(win, src, total_count, total_size)
5143 long count = 0, size = 0;
5146 count_obj(invent, &count, &size, FALSE, TRUE);
5147 count_obj(fobj, &count, &size, FALSE, TRUE);
5148 count_obj(level.buriedobjlist, &count, &size, FALSE, TRUE);
5149 count_obj(migrating_objs, &count, &size, FALSE, TRUE);
5150 /* DEADMONSTER check not required in this loop since they have no
5152 for (mon = fmon; mon; mon = mon->nmon)
5153 count_obj(mon->minvent, &count, &size, FALSE, TRUE);
5154 for (mon = migrating_mons; mon; mon = mon->nmon)
5155 count_obj(mon->minvent, &count, &size, FALSE, TRUE);
5157 if (count || size) {
5158 *total_count += count;
5159 *total_size += size;
5160 Sprintf(buf, template, src, count, size);
5161 putstr(win, 0, buf);
5166 size_monst(mtmp, incl_wsegs)
5170 int sz = (int) sizeof (struct monst);
5172 if (mtmp->wormno && incl_wsegs)
5173 sz += size_wseg(mtmp);
5176 sz += (int) sizeof (struct mextra);
5178 sz += (int) strlen(MNAME(mtmp)) + 1;
5180 sz += (int) sizeof (struct egd);
5182 sz += (int) sizeof (struct epri);
5184 sz += (int) sizeof (struct eshk);
5186 sz += (int) sizeof (struct emin);
5188 sz += (int) sizeof (struct edog);
5189 /* mextra->mcorpsenm doesn't point to more memory */
5195 mon_chain(win, src, chain, force, total_count, total_size)
5198 struct monst *chain;
5206 /* mon->wormno means something different for migrating_mons and mydogs */
5207 boolean incl_wsegs = !strcmpi(src, "fmon");
5210 for (mon = chain; mon; mon = mon->nmon) {
5212 size += size_monst(mon, incl_wsegs);
5214 if (count || size || force) {
5215 *total_count += count;
5216 *total_size += size;
5217 Sprintf(buf, template, src, count, size);
5218 putstr(win, 0, buf);
5223 misc_stats(win, total_count, total_size)
5228 char buf[BUFSZ], hdrbuf[QBUFSZ];
5232 struct damage *sd; /* shop damage */
5233 struct kinfo *k; /* delayed killer */
5234 struct cemetery *bi; /* bones info */
5236 /* traps and engravings are output unconditionally;
5237 * others only if nonzero
5240 for (tt = ftrap; tt; tt = tt->ntrap) {
5242 size += (long) sizeof *tt;
5244 *total_count += count;
5245 *total_size += size;
5246 Sprintf(hdrbuf, "traps, size %ld", (long) sizeof (struct trap));
5247 Sprintf(buf, template, hdrbuf, count, size);
5248 putstr(win, 0, buf);
5251 engr_stats("engravings, size %ld+text", hdrbuf, &count, &size);
5252 *total_count += count;
5253 *total_size += size;
5254 Sprintf(buf, template, hdrbuf, count, size);
5255 putstr(win, 0, buf);
5258 light_stats("light sources, size %ld", hdrbuf, &count, &size);
5259 if (count || size) {
5260 *total_count += count;
5261 *total_size += size;
5262 Sprintf(buf, template, hdrbuf, count, size);
5263 putstr(win, 0, buf);
5267 timer_stats("timers, size %ld", hdrbuf, &count, &size);
5268 if (count || size) {
5269 *total_count += count;
5270 *total_size += size;
5271 Sprintf(buf, template, hdrbuf, count, size);
5272 putstr(win, 0, buf);
5276 for (sd = level.damagelist; sd; sd = sd->next) {
5278 size += (long) sizeof *sd;
5280 if (count || size) {
5281 *total_count += count;
5282 *total_size += size;
5283 Sprintf(hdrbuf, "shop damage, size %ld",
5284 (long) sizeof (struct damage));
5285 Sprintf(buf, template, hdrbuf, count, size);
5286 putstr(win, 0, buf);
5290 region_stats("regions, size %ld+%ld*rect+N", hdrbuf, &count, &size);
5291 if (count || size) {
5292 *total_count += count;
5293 *total_size += size;
5294 Sprintf(buf, template, hdrbuf, count, size);
5295 putstr(win, 0, buf);
5299 for (k = killer.next; k; k = k->next) {
5301 size += (long) sizeof *k;
5303 if (count || size) {
5304 *total_count += count;
5305 *total_size += size;
5306 Sprintf(hdrbuf, "delayed killer%s, size %ld",
5307 plur(count), (long) sizeof (struct kinfo));
5308 Sprintf(buf, template, hdrbuf, count, size);
5309 putstr(win, 0, buf);
5313 for (bi = level.bonesinfo; bi; bi = bi->next) {
5315 size += (long) sizeof *bi;
5317 if (count || size) {
5318 *total_count += count;
5319 *total_size += size;
5320 Sprintf(hdrbuf, "bones history, size %ld",
5321 (long) sizeof (struct cemetery));
5322 Sprintf(buf, template, hdrbuf, count, size);
5323 putstr(win, 0, buf);
5327 for (idx = 0; idx < NUM_OBJECTS; ++idx)
5328 if (objects[idx].oc_uname) {
5330 size += (long) (strlen(objects[idx].oc_uname) + 1);
5332 if (count || size) {
5333 *total_count += count;
5334 *total_size += size;
5335 Strcpy(hdrbuf, "object type names, text");
5336 Sprintf(buf, template, hdrbuf, count, size);
5337 putstr(win, 0, buf);
5342 * Display memory usage of all monsters and objects on the level.
5349 long total_obj_size, total_obj_count,
5350 total_mon_size, total_mon_count,
5351 total_ovr_size, total_ovr_count,
5352 total_misc_size, total_misc_count;
5354 win = create_nhwindow(NHW_TEXT);
5355 putstr(win, 0, "Current memory statistics:");
5357 total_obj_count = total_obj_size = 0L;
5358 putstr(win, 0, stats_hdr);
5359 Sprintf(buf, " Objects, base size %ld", (long) sizeof (struct obj));
5360 putstr(win, 0, buf);
5361 obj_chain(win, "invent", invent, TRUE, &total_obj_count, &total_obj_size);
5362 obj_chain(win, "fobj", fobj, TRUE, &total_obj_count, &total_obj_size);
5363 obj_chain(win, "buried", level.buriedobjlist, FALSE,
5364 &total_obj_count, &total_obj_size);
5365 obj_chain(win, "migrating obj", migrating_objs, FALSE,
5366 &total_obj_count, &total_obj_size);
5367 obj_chain(win, "billobjs", billobjs, FALSE,
5368 &total_obj_count, &total_obj_size);
5369 mon_invent_chain(win, "minvent", fmon, &total_obj_count, &total_obj_size);
5370 mon_invent_chain(win, "migrating minvent", migrating_mons,
5371 &total_obj_count, &total_obj_size);
5372 contained_stats(win, "contained", &total_obj_count, &total_obj_size);
5373 putstr(win, 0, stats_sep);
5374 Sprintf(buf, template, " Obj total", total_obj_count, total_obj_size);
5375 putstr(win, 0, buf);
5377 total_mon_count = total_mon_size = 0L;
5379 Sprintf(buf, " Monsters, base size %ld", (long) sizeof (struct monst));
5380 putstr(win, 0, buf);
5381 mon_chain(win, "fmon", fmon, TRUE, &total_mon_count, &total_mon_size);
5382 mon_chain(win, "migrating", migrating_mons, FALSE,
5383 &total_mon_count, &total_mon_size);
5384 /* 'mydogs' is only valid during level change or end of game disclosure,
5385 but conceivably we've been called from within debugger at such time */
5386 if (mydogs) /* monsters accompanying hero */
5387 mon_chain(win, "mydogs", mydogs, FALSE,
5388 &total_mon_count, &total_mon_size);
5389 putstr(win, 0, stats_sep);
5390 Sprintf(buf, template, " Mon total", total_mon_count, total_mon_size);
5391 putstr(win, 0, buf);
5393 total_ovr_count = total_ovr_size = 0L;
5395 putstr(win, 0, " Overview");
5396 overview_stats(win, template, &total_ovr_count, &total_ovr_size);
5397 putstr(win, 0, stats_sep);
5398 Sprintf(buf, template, " Over total", total_ovr_count, total_ovr_size);
5399 putstr(win, 0, buf);
5401 total_misc_count = total_misc_size = 0L;
5403 putstr(win, 0, " Miscellaneous");
5404 misc_stats(win, &total_misc_count, &total_misc_size);
5405 putstr(win, 0, stats_sep);
5406 Sprintf(buf, template, " Misc total", total_misc_count, total_misc_size);
5407 putstr(win, 0, buf);
5410 putstr(win, 0, stats_sep);
5411 Sprintf(buf, template, " Grand total",
5412 (total_obj_count + total_mon_count
5413 + total_ovr_count + total_misc_count),
5414 (total_obj_size + total_mon_size
5415 + total_ovr_size + total_misc_size));
5416 putstr(win, 0, buf);
5418 #if defined(__BORLANDC__) && !defined(_WIN32)
5419 show_borlandc_stats(win);
5422 display_nhwindow(win, FALSE);
5423 destroy_nhwindow(win);
5431 timer_sanity_check();
5433 light_sources_sanity_check();
5437 #ifdef DEBUG_MIGRATING_MONS
5442 char inbuf[BUFSZ] = DUMMY;
5443 struct permonst *ptr;
5447 getlin("How many random monsters to migrate? [0]", inbuf);
5448 if (*inbuf == '\033')
5450 mcount = atoi(inbuf);
5451 if (mcount < 0 || mcount > (COLNO * ROWNO) || Is_botlevel(&u.uz))
5453 while (mcount > 0) {
5454 if (Is_stronghold(&u.uz))
5455 assign_level(&tolevel, &valley_level);
5457 get_level(&tolevel, depth(&u.uz) + 1);
5459 mtmp = makemon(ptr, 0, 0, NO_MM_FLAGS);
5461 migrate_to_level(mtmp, ledger_no(&tolevel), MIGR_RANDOM,
5469 #define unctrl(c) ((c) <= C('z') ? (0x60 | (c)) : (c))
5470 #define unmeta(c) (0x7f & (c))
5476 } const spkeys_binds[] = {
5477 { NHKF_ESC, '\033', (char *) 0 }, /* no binding */
5478 { NHKF_DOAGAIN, DOAGAIN, "repeat" },
5479 { NHKF_REQMENU, 'm', "reqmenu" },
5480 { NHKF_RUN, 'G', "run" },
5481 { NHKF_RUN2, '5', "run.numpad" },
5482 { NHKF_RUSH, 'g', "rush" },
5483 { NHKF_FIGHT, 'F', "fight" },
5484 { NHKF_FIGHT2, '-', "fight.numpad" },
5485 { NHKF_NOPICKUP, 'm', "nopickup" },
5486 { NHKF_RUN_NOPICKUP, 'M', "run.nopickup" },
5487 { NHKF_DOINV, '0', "doinv" },
5488 { NHKF_TRAVEL, CMD_TRAVEL, (char *) 0 }, /* no binding */
5489 { NHKF_CLICKLOOK, CMD_CLICKLOOK, (char *) 0 }, /* no binding */
5490 { NHKF_REDRAW, C('r'), "redraw" },
5491 { NHKF_REDRAW2, C('l'), "redraw.numpad" },
5492 { NHKF_GETDIR_SELF, '.', "getdir.self" },
5493 { NHKF_GETDIR_SELF2, 's', "getdir.self2" },
5494 { NHKF_GETDIR_HELP, '?', "getdir.help" },
5495 { NHKF_COUNT, 'n', "count" },
5496 { NHKF_GETPOS_SELF, '@', "getpos.self" },
5497 { NHKF_GETPOS_PICK, '.', "getpos.pick" },
5498 { NHKF_GETPOS_PICK_Q, ',', "getpos.pick.quick" },
5499 { NHKF_GETPOS_PICK_O, ';', "getpos.pick.once" },
5500 { NHKF_GETPOS_PICK_V, ':', "getpos.pick.verbose" },
5501 { NHKF_GETPOS_SHOWVALID, '$', "getpos.valid" },
5502 { NHKF_GETPOS_AUTODESC, '#', "getpos.autodescribe" },
5503 { NHKF_GETPOS_MON_NEXT, 'm', "getpos.mon.next" },
5504 { NHKF_GETPOS_MON_PREV, 'M', "getpos.mon.prev" },
5505 { NHKF_GETPOS_OBJ_NEXT, 'o', "getpos.obj.next" },
5506 { NHKF_GETPOS_OBJ_PREV, 'O', "getpos.obj.prev" },
5507 { NHKF_GETPOS_DOOR_NEXT, 'd', "getpos.door.next" },
5508 { NHKF_GETPOS_DOOR_PREV, 'D', "getpos.door.prev" },
5509 { NHKF_GETPOS_UNEX_NEXT, 'x', "getpos.unexplored.next" },
5510 { NHKF_GETPOS_UNEX_PREV, 'X', "getpos.unexplored.prev" },
5511 { NHKF_GETPOS_VALID_NEXT, 'z', "getpos.valid.next" },
5512 { NHKF_GETPOS_VALID_PREV, 'Z', "getpos.valid.prev" },
5513 { NHKF_GETPOS_INTERESTING_NEXT, 'a', "getpos.all.next" },
5514 { NHKF_GETPOS_INTERESTING_PREV, 'A', "getpos.all.prev" },
5515 { NHKF_GETPOS_HELP, '?', "getpos.help" },
5516 { NHKF_GETPOS_LIMITVIEW, '"', "getpos.filter" },
5517 { NHKF_GETPOS_MOVESKIP, '*', "getpos.moveskip" },
5518 { NHKF_GETPOS_MENU, '!', "getpos.menu" }
5522 bind_specialkey(key, command)
5524 const char *command;
5527 for (i = 0; i < SIZE(spkeys_binds); i++) {
5528 if (!spkeys_binds[i].name || strcmp(command, spkeys_binds[i].name))
5530 Cmd.spkeys[spkeys_binds[i].nhkf] = key;
5536 /* returns a one-byte character from the text (it may massacre the txt
5542 txt = trimspaces(txt);
5546 /* simple character */
5550 /* a few special entries */
5551 if (!strcmp(txt, "<enter>"))
5553 if (!strcmp(txt, "<space>"))
5555 if (!strcmp(txt, "<esc>"))
5558 /* control and meta keys */
5560 case 'm': /* can be mx, Mx, m-x, M-x */
5563 if (*txt == '-' && txt[1])
5568 case 'c': /* can be cx, Cx, ^x, c-x, C-x, ^-x */
5572 if (*txt == '-' && txt[1])
5579 /* ascii codes: must be three-digit decimal */
5580 if (*txt >= '0' && *txt <= '9') {
5584 for (i = 0; i < 3; i++) {
5585 if (txt[i] < '0' || txt[i] > '9')
5587 key = 10 * key + txt[i] - '0';
5595 /* returns the text for a one-byte encoding;
5596 * must be shorter than a tab for proper formatting */
5600 char *txt; /* sufficiently long buffer */
5602 /* should probably switch to "SPC", "ESC", "RET"
5603 since nethack's documentation uses ESC for <escape> */
5605 Sprintf(txt, "<space>");
5606 else if (c == '\033')
5607 Sprintf(txt, "<esc>");
5609 Sprintf(txt, "<enter>");
5610 else if (c == '\177')
5611 Sprintf(txt, "<del>"); /* "<delete>" won't fit */
5613 Strcpy(txt, visctrl((char) c));
5619 parseautocomplete(autocomplete, condition)
5623 struct ext_func_tab *efp;
5624 register char *autoc;
5626 /* break off first autocomplete from the rest; parse the rest */
5627 if ((autoc = index(autocomplete, ',')) != 0
5628 || (autoc = index(autocomplete, ':')) != 0) {
5630 parseautocomplete(autoc, condition);
5633 /* strip leading and trailing white space */
5634 autocomplete = trimspaces(autocomplete);
5639 /* take off negation */
5640 if (*autocomplete == '!') {
5641 /* unlike most options, a leading "no" might actually be a part of
5642 * the extended command. Thus you have to use ! */
5644 autocomplete = trimspaces(autocomplete);
5645 condition = !condition;
5648 /* find and modify the extended command */
5649 for (efp = extcmdlist; efp->ef_txt; efp++) {
5650 if (!strcmp(autocomplete, efp->ef_txt)) {
5652 efp->flags |= AUTOCOMPLETE;
5654 efp->flags &= ~AUTOCOMPLETE;
5659 /* not a real extended command */
5660 raw_printf("Bad autocomplete: invalid extended command '%s'.",
5665 /* called at startup and after number_pad is twiddled */
5667 reset_commands(initial)
5670 static const char sdir[] = "hykulnjb><",
5671 sdir_swap_yz[] = "hzkulnjb><",
5672 ndir[] = "47896321><",
5673 ndir_phone_layout[] = "41236987><";
5674 static const int ylist[] = {
5675 'y', 'Y', C('y'), M('y'), M('Y'), M(C('y'))
5677 static struct ext_func_tab *back_dir_cmd[8];
5678 const struct ext_func_tab *cmdtmp;
5680 int c, i, updated = 0;
5681 static boolean backed_dir_cmd = FALSE;
5685 Cmd.num_pad = FALSE;
5686 Cmd.pcHack_compat = Cmd.phone_layout = Cmd.swap_yz = FALSE;
5687 for (i = 0; i < SIZE(spkeys_binds); i++)
5688 Cmd.spkeys[spkeys_binds[i].nhkf] = spkeys_binds[i].key;
5692 if (backed_dir_cmd) {
5693 for (i = 0; i < 8; i++) {
5694 Cmd.commands[(uchar) Cmd.dirchars[i]] = back_dir_cmd[i];
5699 flagtemp = iflags.num_pad;
5700 if (flagtemp != Cmd.num_pad) {
5701 Cmd.num_pad = flagtemp;
5704 /* swap_yz mode (only applicable for !num_pad); intended for
5705 QWERTZ keyboard used in Central Europe, particularly Germany */
5706 flagtemp = (iflags.num_pad_mode & 1) ? !Cmd.num_pad : FALSE;
5707 if (flagtemp != Cmd.swap_yz) {
5708 Cmd.swap_yz = flagtemp;
5710 /* Cmd.swap_yz has been toggled;
5711 perform the swap (or reverse previous one) */
5712 for (i = 0; i < SIZE(ylist); i++) {
5713 c = ylist[i] & 0xff;
5714 cmdtmp = Cmd.commands[c]; /* tmp = [y] */
5715 Cmd.commands[c] = Cmd.commands[c + 1]; /* [y] = [z] */
5716 Cmd.commands[c + 1] = cmdtmp; /* [z] = tmp */
5719 /* MSDOS compatibility mode (only applicable for num_pad) */
5720 flagtemp = (iflags.num_pad_mode & 1) ? Cmd.num_pad : FALSE;
5721 if (flagtemp != Cmd.pcHack_compat) {
5722 Cmd.pcHack_compat = flagtemp;
5724 /* pcHack_compat has been toggled */
5726 cmdtmp = Cmd.commands['5'];
5727 Cmd.commands['5'] = Cmd.commands[c];
5728 Cmd.commands[c] = cmdtmp;
5730 Cmd.commands[c] = Cmd.pcHack_compat ? Cmd.commands['I'] : 0;
5732 /* phone keypad layout (only applicable for num_pad) */
5733 flagtemp = (iflags.num_pad_mode & 2) ? Cmd.num_pad : FALSE;
5734 if (flagtemp != Cmd.phone_layout) {
5735 Cmd.phone_layout = flagtemp;
5737 /* phone_layout has been toggled */
5738 for (i = 0; i < 3; i++) {
5739 c = '1' + i; /* 1,2,3 <-> 7,8,9 */
5740 cmdtmp = Cmd.commands[c]; /* tmp = [1] */
5741 Cmd.commands[c] = Cmd.commands[c + 6]; /* [1] = [7] */
5742 Cmd.commands[c + 6] = cmdtmp; /* [7] = tmp */
5743 c = (M('1') & 0xff) + i; /* M-1,M-2,M-3 <-> M-7,M-8,M-9 */
5744 cmdtmp = Cmd.commands[c]; /* tmp = [M-1] */
5745 Cmd.commands[c] = Cmd.commands[c + 6]; /* [M-1] = [M-7] */
5746 Cmd.commands[c + 6] = cmdtmp; /* [M-7] = tmp */
5753 Cmd.dirchars = !Cmd.num_pad
5754 ? (!Cmd.swap_yz ? sdir : sdir_swap_yz)
5755 : (!Cmd.phone_layout ? ndir : ndir_phone_layout);
5756 Cmd.alphadirchars = !Cmd.num_pad ? Cmd.dirchars : sdir;
5758 Cmd.move_W = Cmd.dirchars[0];
5759 Cmd.move_NW = Cmd.dirchars[1];
5760 Cmd.move_N = Cmd.dirchars[2];
5761 Cmd.move_NE = Cmd.dirchars[3];
5762 Cmd.move_E = Cmd.dirchars[4];
5763 Cmd.move_SE = Cmd.dirchars[5];
5764 Cmd.move_S = Cmd.dirchars[6];
5765 Cmd.move_SW = Cmd.dirchars[7];
5768 for (i = 0; i < 8; i++) {
5770 (struct ext_func_tab *) Cmd.commands[(uchar) Cmd.dirchars[i]];
5771 Cmd.commands[(uchar) Cmd.dirchars[i]] = (struct ext_func_tab *) 0;
5773 backed_dir_cmd = TRUE;
5774 for (i = 0; i < 8; i++)
5775 (void) bind_key(Cmd.dirchars[i], "nothing");
5779 /* non-movement commands which accept 'm' prefix to request menu operation */
5781 accept_menu_prefix(cmd_func)
5782 int NDECL((*cmd_func));
5784 if (cmd_func == dopickup || cmd_func == dotip
5785 /* eat, #offer, and apply tinning-kit all use floorfood() to pick
5786 an item on floor or in invent; 'm' skips picking from floor
5787 (ie, inventory only) rather than request use of menu operation */
5788 || cmd_func == doeat || cmd_func == dosacrifice || cmd_func == doapply
5789 /* 'm' for removing saddle from adjacent monster without checking
5790 for containers at <u.ux,u.uy> */
5791 || cmd_func == doloot
5792 /* travel: pop up a menu of interesting targets in view */
5793 || cmd_func == dotravel
5794 /* wizard mode ^V and ^T */
5795 || cmd_func == wiz_level_tele || cmd_func == dotelecmd
5796 /* 'm' prefix allowed for some extended commands */
5797 || cmd_func == doextcmd || cmd_func == doextlist)
5809 default: c = '\033'; break;
5810 case 0: c = '\n'; break;
5814 case 4: c = (char)(' ' + rn2((int)('~' - ' '))); break;
5815 case 5: c = '\t'; break;
5816 case 6: c = (char)('a' + rn2((int)('z' - 'a'))); break;
5817 case 7: c = (char)('A' + rn2((int)('Z' - 'A'))); break;
5818 case 8: c = extcmdlist[(i++) % SIZE(extcmdlist)].key; break;
5819 case 9: c = '#'; break;
5826 random_response(buf, sz)
5848 rnd_extcmd_idx(VOID_ARGS)
5850 return rn2(extcmdlist_length + 1) - 1;
5854 ch2spkeys(c, start, end)
5860 for (i = start; i <= end; i++)
5861 if (Cmd.spkeys[i] == c)
5871 boolean prefix_seen, bad_command,
5872 firsttime = (cmd == 0);
5874 iflags.menu_requested = FALSE;
5876 if (program_state.done_hup)
5883 if (*cmd == Cmd.spkeys[NHKF_ESC]) {
5884 context.move = FALSE;
5887 if (*cmd == DOAGAIN && !in_doagain && saveq[0]) {
5890 rhack((char *) 0); /* read and execute command */
5894 /* Special case of *cmd == ' ' handled better below */
5895 if (!*cmd || *cmd == (char) 0377) {
5897 context.move = FALSE;
5898 return; /* probably we just had an interrupt */
5901 /* handle most movement commands */
5902 prefix_seen = FALSE;
5903 context.travel = context.travel1 = 0;
5904 spkey = ch2spkeys(*cmd, NHKF_RUN, NHKF_CLICKLOOK);
5908 if (movecmd(cmd[1])) {
5910 domove_attempting |= DOMOVE_RUSH;
5919 if (movecmd(lowc(cmd[1]))) {
5921 domove_attempting |= DOMOVE_RUSH;
5929 /* Effects of movement commands and invisible monsters:
5930 * m: always move onto space (even if 'I' remembered)
5931 * F: always attack space (even if 'I' not remembered)
5932 * normal movement: attack if 'I', move otherwise.
5935 if (movecmd(cmd[1])) {
5936 context.forcefight = 1;
5937 domove_attempting |= DOMOVE_WALK;
5942 if (movecmd(cmd[1]) || u.dz) {
5946 domove_attempting |= DOMOVE_WALK;
5948 cmd[0] = cmd[1]; /* "m<" or "m>" */
5952 case NHKF_RUN_NOPICKUP:
5953 if (movecmd(lowc(cmd[1]))) {
5956 domove_attempting |= DOMOVE_RUSH;
5963 (void) ddoinv(); /* a convenience borrowed from the PC */
5964 context.move = FALSE;
5967 case NHKF_CLICKLOOK:
5968 if (iflags.clicklook) {
5969 context.move = FALSE;
5970 do_look(2, &clicklook_cc);
5974 if (flags.travelcmd) {
5976 context.travel1 = 1;
5979 domove_attempting |= DOMOVE_RUSH;
5984 if (movecmd(*cmd)) { /* ordinary movement */
5985 context.run = 0; /* only matters here if it was 8 */
5986 domove_attempting |= DOMOVE_WALK;
5987 } else if (movecmd(Cmd.num_pad ? unmeta(*cmd) : lowc(*cmd))) {
5989 domove_attempting |= DOMOVE_RUSH;
5990 } else if (movecmd(unctrl(*cmd))) {
5992 domove_attempting |= DOMOVE_RUSH;
5997 /* some special prefix handling */
5998 /* overload 'm' prefix to mean "request a menu" */
5999 if (prefix_seen && cmd[0] == Cmd.spkeys[NHKF_REQMENU]) {
6000 /* (for func_tab cast, see below) */
6001 const struct ext_func_tab *ft = Cmd.commands[cmd[1] & 0xff];
6002 int NDECL((*func)) = ft ? ((struct ext_func_tab *) ft)->ef_funct : 0;
6004 if (func && accept_menu_prefix(func)) {
6005 iflags.menu_requested = TRUE;
6010 if (((domove_attempting & (DOMOVE_RUSH | DOMOVE_WALK)) != 0L)
6011 && !context.travel && !dxdy_moveok()) {
6012 /* trying to move diagonally as a grid bug;
6013 this used to be treated by movecmd() as not being
6014 a movement attempt, but that didn't provide for any
6015 feedback and led to strangeness if the key pressed
6016 ('u' in particular) was overloaded for num_pad use */
6018 You_cant("get there from here...");
6020 You_cant("
\82±
\82±
\82©
\82ç
\82»
\82±
\82Ö
\82Í
\8ds
\82¯
\82Ü
\82¹
\82ñ
\81D
\81D
\81D");
6022 context.nopick = context.forcefight = FALSE;
6023 context.move = context.mv = FALSE;
6028 if ((domove_attempting & DOMOVE_WALK) != 0L) {
6032 context.forcefight = 0;
6034 } else if ((domove_attempting & DOMOVE_RUSH) != 0L) {
6037 multi = max(COLNO, ROWNO);
6038 u.last_str_turn = 0;
6043 } else if (prefix_seen && cmd[1] == Cmd.spkeys[NHKF_ESC]) {
6044 /* <prefix><escape> */
6045 /* don't report "unknown command" for change of heart... */
6046 bad_command = FALSE;
6047 } else if (*cmd == ' ' && !flags.rest_on_space) {
6048 bad_command = TRUE; /* skip cmdlist[] loop */
6050 /* handle all other commands */
6052 register const struct ext_func_tab *tlist;
6053 int res, NDECL((*func));
6055 /* current - use *cmd to directly index cmdlist array */
6056 if ((tlist = Cmd.commands[*cmd & 0xff]) != 0) {
6057 if (!wizard && (tlist->flags & WIZMODECMD)) {
6059 You_cant("do that!");
6061 pline("
\82»
\82ê
\82Í
\82Å
\82«
\82Ü
\82¹
\82ñ
\81I");
6063 } else if (u.uburied && !(tlist->flags & IFBURIED)) {
6065 You_cant("do that while you are buried!");
6067 You("
\96\84\82Ü
\82Á
\82Ä
\82¢
\82é
\8e\9e\82É
\82»
\82ñ
\82È
\82±
\82Æ
\82Í
\82Å
\82«
\82È
\82¢
\81I");
6070 /* we discard 'const' because some compilers seem to have
6071 trouble with the pointer passed to set_occupation() */
6072 func = ((struct ext_func_tab *) tlist)->ef_funct;
6073 if (tlist->f_text && !occupation && multi)
6074 set_occupation(func, tlist->f_text, multi);
6075 res = (*func)(); /* perform the command */
6078 context.move = FALSE;
6083 /* if we reach here, cmd wasn't found in cmdlist[] */
6088 char expcmd[20]; /* we expect 'cmd' to point to 1 or 2 chars */
6089 char c, c1 = cmd[1];
6092 while ((c = *cmd++) != '\0')
6093 Strcat(expcmd, visctrl(c)); /* add 1..4 chars plus terminator */
6096 if (!prefix_seen || !help_dir(c1, spkey, "Invalid direction key!"))
6098 if (!prefix_seen || !help_dir(c1, spkey, "
\96³
\8cø
\82È
\95û
\8cü
\8ew
\92è
\82Å
\82·
\81I"))
6100 Norep("Unknown command '%s'.", expcmd);
6102 Norep("'%s'
\83R
\83}
\83\93\83h
\81H", expcmd);
6105 context.move = FALSE;
6110 /* convert an x,y pair into a direction code */
6117 for (dd = 0; dd < 8; dd++)
6118 if (x == xdir[dd] && y == ydir[dd])
6123 /* convert a direction code into an x,y pair */
6134 /* also sets u.dz, but returns false for <> */
6139 register const char *dp = index(Cmd.dirchars, sym);
6144 u.dx = xdir[dp - Cmd.dirchars];
6145 u.dy = ydir[dp - Cmd.dirchars];
6146 u.dz = zdir[dp - Cmd.dirchars];
6147 #if 0 /* now handled elsewhere */
6148 if (u.dx && u.dy && NODIAG(u.umonnum)) {
6156 /* grid bug handling which used to be in movecmd() */
6160 if (u.dx && u.dy && NODIAG(u.umonnum))
6162 return u.dx || u.dy;
6165 /* decide whether a character (user input keystroke) requests screen repaint */
6170 return (boolean) (c == Cmd.spkeys[NHKF_REDRAW]
6171 || (Cmd.num_pad && c == Cmd.spkeys[NHKF_REDRAW2]));
6178 return (c == Cmd.spkeys[NHKF_RUSH]
6179 || c == Cmd.spkeys[NHKF_RUN]
6180 || c == Cmd.spkeys[NHKF_NOPICKUP]
6181 || c == Cmd.spkeys[NHKF_RUN_NOPICKUP]
6182 || c == Cmd.spkeys[NHKF_FIGHT]
6183 || (Cmd.num_pad && (c == Cmd.spkeys[NHKF_RUN2]
6184 || c == Cmd.spkeys[NHKF_FIGHT2])));
6188 * uses getdir() but unlike getdir() it specifically
6189 * produces coordinates using the direction from getdir()
6190 * and verifies that those coordinates are ok.
6192 * If the call to getdir() returns 0, Never_mind is displayed.
6193 * If the resulting coordinates are not okay, emsg is displayed.
6195 * Returns non-zero if coordinates in cc are valid.
6198 get_adjacent_loc(prompt, emsg, x, y, cc)
6199 const char *prompt, *emsg;
6204 if (!getdir(prompt)) {
6210 if (cc && isok(new_x, new_y)) {
6229 if (in_doagain || *readchar_queue)
6230 dirsym = readchar();
6233 dirsym = yn_function((s && *s != '^') ? s : "In what direction?",
6235 dirsym = yn_function((s && *s != '^') ? s : "
\82Ç
\82Ì
\95û
\8cü
\81H",
6237 /* remove the prompt string so caller won't have to */
6238 clear_nhwindow(WIN_MESSAGE);
6240 if (redraw_cmd(dirsym)) { /* ^R */
6241 docrt(); /* redraw */
6246 if (dirsym == Cmd.spkeys[NHKF_GETDIR_SELF]
6247 || dirsym == Cmd.spkeys[NHKF_GETDIR_SELF2]) {
6248 u.dx = u.dy = u.dz = 0;
6249 } else if (!(is_mov = movecmd(dirsym)) && !u.dz) {
6250 boolean did_help = FALSE, help_requested;
6252 if (!index(quitchars, dirsym)) {
6253 help_requested = (dirsym == Cmd.spkeys[NHKF_GETDIR_HELP]);
6254 if (help_requested || iflags.cmdassist) {
6255 did_help = help_dir((s && *s == '^') ? dirsym : '\0',
6257 help_requested ? (const char *) 0
6259 : "Invalid direction key!");
6261 : "
\96³
\8cø
\82È
\95û
\8cü
\8ew
\92è
\82Å
\82·
\81I");
6267 pline("What a strange direction!");
6269 pline("
\82¸
\82¢
\82Ô
\82ñ
\82Æ
\8aï
\96
\82È
\95û
\8cü
\82¾
\81I");
6272 } else if (is_mov && !dxdy_moveok()) {
6274 You_cant("orient yourself that direction.");
6276 You_cant("
\8cü
\82«
\82É
\8e©
\95ª
\8e©
\90g
\82ð
\8ew
\92è
\82Å
\82«
\82È
\82¢
\81D");
6279 if (!u.dz && (Stunned || (Confusion && !rn2(5))))
6285 show_direction_keys(win, centerchar, nodiag)
6286 winid win; /* should specify a window which is using a fixed-width font... */
6287 char centerchar; /* '.' or '@' or ' ' */
6296 Sprintf(buf, " %c ", Cmd.move_N);
6297 putstr(win, 0, buf);
6298 putstr(win, 0, " | ");
6299 Sprintf(buf, " %c- %c -%c",
6300 Cmd.move_W, centerchar, Cmd.move_E);
6301 putstr(win, 0, buf);
6302 putstr(win, 0, " | ");
6303 Sprintf(buf, " %c ", Cmd.move_S);
6304 putstr(win, 0, buf);
6306 Sprintf(buf, " %c %c %c",
6307 Cmd.move_NW, Cmd.move_N, Cmd.move_NE);
6308 putstr(win, 0, buf);
6309 putstr(win, 0, " \\ | / ");
6310 Sprintf(buf, " %c- %c -%c",
6311 Cmd.move_W, centerchar, Cmd.move_E);
6312 putstr(win, 0, buf);
6313 putstr(win, 0, " / | \\ ");
6314 Sprintf(buf, " %c %c %c",
6315 Cmd.move_SW, Cmd.move_S, Cmd.move_SE);
6316 putstr(win, 0, buf);
6320 /* explain choices if player has asked for getdir() help or has given
6321 an invalid direction after a prefix key ('F', 'g', 'm', &c), which
6322 might be bogus but could be up, down, or self when not applicable */
6324 help_dir(sym, spkey, msg)
6326 int spkey; /* NHKF_ code for prefix key, if one was used, or for ESC */
6329 static const char wiz_only_list[] = "EFGIVW";
6332 char buf[BUFSZ], buf2[BUFSZ], *explain;
6333 const char *dothat, *how;
6334 boolean prefixhandling, viawindow;
6336 /* NHKF_ESC indicates that player asked for help at getdir prompt */
6337 viawindow = (spkey == NHKF_ESC || iflags.cmdassist);
6338 prefixhandling = (spkey != NHKF_ESC);
6340 * Handling for prefix keys that don't want special directions.
6341 * Delivered via pline if 'cmdassist' is off, or instead of the
6342 * general message if it's on.
6345 how = " at"; /* for "<action> at yourself"; not used for up/down */
6358 case NHKF_RUN_NOPICKUP:
6367 how = ""; /* avoid "fight at yourself" */
6370 prefixhandling = FALSE;
6375 /* for movement prefix followed by '.' or (numpad && 's') to mean 'self';
6376 note: '-' for hands (inventory form of 'self') is not handled here */
6378 && (sym == Cmd.spkeys[NHKF_GETDIR_SELF]
6379 || (Cmd.num_pad && sym == Cmd.spkeys[NHKF_GETDIR_SELF2]))) {
6380 Sprintf(buf, "You can't %s%s yourself.", dothat, how);
6381 /* for movement prefix followed by up or down */
6382 } else if (prefixhandling && (sym == '<' || sym == '>')) {
6383 Sprintf(buf, "You can't %s %s.", dothat,
6384 /* was "upwards" and "downwards", but they're considered
6385 to be variants of canonical "upward" and "downward" */
6386 (sym == '<') ? "upward" : "downward");
6389 /* if '!cmdassist', display via pline() and we're done (note: asking
6390 for help at getdir() prompt forces cmdassist for this operation) */
6392 if (prefixhandling) {
6394 Sprintf(buf, "Invalid direction for '%s' prefix.",
6395 visctrl(Cmd.spkeys[spkey]));
6399 /* when 'cmdassist' is off and caller doesn't insist, do nothing */
6403 win = create_nhwindow(NHW_TEXT);
6408 /* show bad-prefix message instead of general invalid-direction one */
6409 putstr(win, 0, buf);
6412 Sprintf(buf, "cmdassist: %s", msg);
6413 putstr(win, 0, buf);
6417 if (!prefixhandling && (letter(sym) || sym == '[')) {
6418 /* '[': old 'cmdhelp' showed ESC as ^[ */
6419 sym = highc(sym); /* @A-Z[ (note: letter() accepts '@') */
6420 ctrl = (sym - 'A') + 1; /* 0-27 (note: 28-31 aren't applicable) */
6421 if ((explain = dowhatdoes_core(ctrl, buf2)) != 0
6422 && (!index(wiz_only_list, sym) || wizard)) {
6423 Sprintf(buf, "Are you trying to use ^%c%s?", sym,
6424 index(wiz_only_list, sym) ? ""
6425 : " as specified in the Guidebook");
6426 putstr(win, 0, buf);
6428 putstr(win, 0, explain);
6431 "To use that command, hold down the <Ctrl> key as a shift");
6432 Sprintf(buf, "and press the <%c> key.", sym);
6433 putstr(win, 0, buf);
6438 Sprintf(buf, "Valid direction keys%s%s%s are:",
6439 prefixhandling ? " to " : "", prefixhandling ? dothat : "",
6440 NODIAG(u.umonnum) ? " in your current form" : "");
6441 putstr(win, 0, buf);
6442 show_direction_keys(win, !prefixhandling ? '.' : ' ', NODIAG(u.umonnum));
6444 if (!prefixhandling || spkey == NHKF_NOPICKUP) {
6445 /* NOPICKUP: unlike the other prefix keys, 'm' allows up/down for
6446 stair traversal; we won't get here when "m<" or "m>" has been
6447 given but we include up and down for 'm'+invalid_direction;
6448 self is excluded as a viable direction for every prefix */
6450 putstr(win, 0, " < up");
6451 putstr(win, 0, " > down");
6452 if (!prefixhandling) {
6453 int selfi = Cmd.num_pad ? NHKF_GETDIR_SELF2 : NHKF_GETDIR_SELF;
6455 Sprintf(buf, " %4s direct at yourself",
6456 visctrl(Cmd.spkeys[selfi]));
6457 putstr(win, 0, buf);
6462 /* non-null msg means that this wasn't an explicit user request */
6466 "(Suppress this message with !cmdassist in config file.)");
6468 "(
\82±
\82Ì
\83\81\83b
\83Z
\81[
\83W
\82ð
\95\
\8e¦
\82µ
\82½
\82
\82È
\82¢
\8fê
\8d\87\82Í
\90Ý
\92è
\83t
\83@
\83C
\83\8b\82É !cmdassist
\82ð
\90Ý
\92è
\82µ
\82Ä
\82
\82¾
\82³
\82¢
\81D)");
6470 display_nhwindow(win, FALSE);
6471 destroy_nhwindow(win);
6478 register int x = NODIAG(u.umonnum) ? 2 * rn2(4) : rn2(8);
6489 static NEARDATA const char *const dirnames[] = {
6490 "west", "northwest", "north", "northeast", "east",
6491 "southeast", "south", "southwest", "down", "up",
6494 if (dir < 0 || dir >= SIZE(dirnames))
6496 return dirnames[dir];
6503 /* x corresponds to curx, so x==1 is the first column. Ach. %% */
6504 return x >= 1 && x <= COLNO - 1 && y >= 0 && y <= ROWNO - 1;
6507 /* #herecmdmenu command */
6509 doherecmdmenu(VOID_ARGS)
6511 char ch = here_cmd_menu(TRUE);
6516 /* #therecmdmenu command, a way to test there_cmd_menu without mouse */
6518 dotherecmdmenu(VOID_ARGS)
6522 if (!getdir((const char *) 0) || !isok(u.ux + u.dx, u.uy + u.dy))
6526 ch = there_cmd_menu(TRUE, u.ux + u.dx, u.uy + u.dy);
6528 ch = here_cmd_menu(TRUE);
6534 add_herecmd_menuitem(win, func, text)
6542 if ((ch = cmd_from_func(func)) != '\0') {
6545 add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, text, MENU_UNSELECTED);
6550 there_cmd_menu(doit, x, y)
6557 schar typ = levl[x][y].typ;
6559 menu_item *picks = (menu_item *) 0;
6563 win = create_nhwindow(NHW_MENU);
6567 boolean key_or_pick, card;
6568 int dm = levl[x][y].doormask;
6570 if ((dm & (D_CLOSED | D_LOCKED))) {
6571 add_herecmd_menuitem(win, doopen, "Open the door"), ++K;
6572 /* unfortunately there's no lknown flag for doors to
6573 remember the locked/unlocked state */
6574 key_or_pick = (carrying(SKELETON_KEY) || carrying(LOCK_PICK));
6575 card = (carrying(CREDIT_CARD) != 0);
6576 if (key_or_pick || card) {
6577 Sprintf(buf, "%sunlock the door",
6578 key_or_pick ? "lock or " : "");
6579 add_herecmd_menuitem(win, doapply, upstart(buf)), ++K;
6581 /* unfortunately there's no tknown flag for doors (or chests)
6582 to remember whether a trap had been found */
6583 add_herecmd_menuitem(win, dountrap,
6584 "Search the door for a trap"), ++K;
6585 /* [what about #force?] */
6586 add_herecmd_menuitem(win, dokick, "Kick the door"), ++K;
6587 } else if ((dm & D_ISOPEN)) {
6588 add_herecmd_menuitem(win, doclose, "Close the door"), ++K;
6593 add_herecmd_menuitem(win, dosearch, "Search for secret doors"), ++K;
6595 if ((ttmp = t_at(x, y)) != 0 && ttmp->tseen) {
6596 add_herecmd_menuitem(win, doidtrap, "Examine trap"), ++K;
6597 if (ttmp->ttyp != VIBRATING_SQUARE)
6598 add_herecmd_menuitem(win, dountrap, "Attempt to disarm trap"), ++K;
6602 if (mtmp && !canspotmon(mtmp))
6604 if (mtmp && which_armor(mtmp, W_SADDLE)) {
6605 char *mnam = x_monnam(mtmp, ARTICLE_THE, (char *) 0,
6606 SUPPRESS_SADDLE, FALSE);
6609 Sprintf(buf, "Ride %s", mnam);
6610 add_herecmd_menuitem(win, doride, buf), ++K;
6612 Sprintf(buf, "Remove saddle from %s", mnam);
6613 add_herecmd_menuitem(win, doloot, buf), ++K;
6615 if (mtmp && can_saddle(mtmp) && !which_armor(mtmp, W_SADDLE)
6616 && carrying(SADDLE)) {
6617 Sprintf(buf, "Put saddle on %s", mon_nam(mtmp)), ++K;
6618 add_herecmd_menuitem(win, doapply, buf);
6621 if (mtmp || glyph_is_invisible(glyph_at(x, y))) {
6622 /* "Attack %s", mtmp ? mon_nam(mtmp) : "unseen creature" */
6624 /* "Move %s", direction */
6629 end_menu(win, "What do you want to do?");
6630 npick = select_menu(win, PICK_ONE, &picks);
6632 pline("No applicable actions.");
6635 destroy_nhwindow(win);
6638 int NDECL((*func)) = picks->item.a_nfunc;
6639 free((genericptr_t) picks);
6642 int ret = (*func)();
6646 ch = cmd_from_func(func);
6659 schar typ = levl[u.ux][u.uy].typ;
6661 menu_item *picks = (menu_item *) 0;
6663 win = create_nhwindow(NHW_MENU);
6666 if (IS_FOUNTAIN(typ) || IS_SINK(typ)) {
6667 Sprintf(buf, "Drink from the %s",
6668 defsyms[IS_FOUNTAIN(typ) ? S_fountain : S_sink].explanation);
6669 add_herecmd_menuitem(win, dodrink, buf);
6671 if (IS_FOUNTAIN(typ))
6672 add_herecmd_menuitem(win, dodip,
6673 "Dip something into the fountain");
6675 add_herecmd_menuitem(win, dosit,
6676 "Sit on the throne");
6678 if ((u.ux == xupstair && u.uy == yupstair)
6679 || (u.ux == sstairs.sx && u.uy == sstairs.sy && sstairs.up)
6680 || (u.ux == xupladder && u.uy == yupladder)) {
6681 Sprintf(buf, "Go up the %s",
6682 (u.ux == xupladder && u.uy == yupladder)
6683 ? "ladder" : "stairs");
6684 add_herecmd_menuitem(win, doup, buf);
6686 if ((u.ux == xdnstair && u.uy == ydnstair)
6687 || (u.ux == sstairs.sx && u.uy == sstairs.sy && !sstairs.up)
6688 || (u.ux == xdnladder && u.uy == ydnladder)) {
6689 Sprintf(buf, "Go down the %s",
6690 (u.ux == xupladder && u.uy == yupladder)
6691 ? "ladder" : "stairs");
6692 add_herecmd_menuitem(win, dodown, buf);
6694 if (u.usteed) { /* another movement choice */
6695 Sprintf(buf, "Dismount %s",
6696 x_monnam(u.usteed, ARTICLE_THE, (char *) 0,
6697 SUPPRESS_SADDLE, FALSE));
6698 add_herecmd_menuitem(win, doride, buf);
6702 if (Upolyd) { /* before objects */
6703 Sprintf(buf, "Use %s special ability",
6704 s_suffix(mons[u.umonnum].mname));
6705 add_herecmd_menuitem(win, domonability, buf);
6709 if (OBJ_AT(u.ux, u.uy)) {
6710 struct obj *otmp = level.objects[u.ux][u.uy];
6712 Sprintf(buf, "Pick up %s", otmp->nexthere ? "items" : doname(otmp));
6713 add_herecmd_menuitem(win, dopickup, buf);
6715 if (Is_container(otmp)) {
6716 Sprintf(buf, "Loot %s", doname(otmp));
6717 add_herecmd_menuitem(win, doloot, buf);
6719 if (otmp->oclass == FOOD_CLASS) {
6720 Sprintf(buf, "Eat %s", doname(otmp));
6721 add_herecmd_menuitem(win, doeat, buf);
6726 add_herecmd_menuitem(win, dodrop, "Drop items");
6728 add_herecmd_menuitem(win, donull, "Rest one turn");
6729 add_herecmd_menuitem(win, dosearch, "Search around you");
6730 add_herecmd_menuitem(win, dolook, "Look at what is here");
6732 end_menu(win, "What do you want to do?");
6733 npick = select_menu(win, PICK_ONE, &picks);
6734 destroy_nhwindow(win);
6737 int NDECL((*func)) = picks->item.a_nfunc;
6738 free((genericptr_t) picks);
6741 int ret = (*func)();
6745 ch = cmd_from_func(func);
6752 static NEARDATA int last_multi;
6755 * convert a MAP window position into a movecmd
6758 click_to_cmd(x, y, mod)
6765 if (iflags.clicklook && mod == CLICK_2) {
6768 cmd[0] = Cmd.spkeys[NHKF_CLICKLOOK];
6775 if (flags.travelcmd) {
6776 if (abs(x) <= 1 && abs(y) <= 1) {
6777 x = sgn(x), y = sgn(y);
6781 cmd[0] = Cmd.spkeys[NHKF_TRAVEL];
6785 if (x == 0 && y == 0) {
6786 if (iflags.herecmd_menu) {
6787 cmd[0] = here_cmd_menu(FALSE);
6792 if (IS_FOUNTAIN(levl[u.ux][u.uy].typ)
6793 || IS_SINK(levl[u.ux][u.uy].typ)) {
6794 cmd[0] = cmd_from_func(mod == CLICK_1 ? dodrink : dodip);
6796 } else if (IS_THRONE(levl[u.ux][u.uy].typ)) {
6797 cmd[0] = cmd_from_func(dosit);
6799 } else if ((u.ux == xupstair && u.uy == yupstair)
6800 || (u.ux == sstairs.sx && u.uy == sstairs.sy
6802 || (u.ux == xupladder && u.uy == yupladder)) {
6803 cmd[0] = cmd_from_func(doup);
6805 } else if ((u.ux == xdnstair && u.uy == ydnstair)
6806 || (u.ux == sstairs.sx && u.uy == sstairs.sy
6808 || (u.ux == xdnladder && u.uy == ydnladder)) {
6809 cmd[0] = cmd_from_func(dodown);
6811 } else if (OBJ_AT(u.ux, u.uy)) {
6812 cmd[0] = cmd_from_func(Is_container(level.objects[u.ux][u.uy])
6813 ? doloot : dopickup);
6816 cmd[0] = cmd_from_func(donull); /* just rest */
6821 /* directional commands */
6825 if (!m_at(u.ux + x, u.uy + y)
6826 && !test_move(u.ux, u.uy, x, y, TEST_MOVE)) {
6827 cmd[1] = Cmd.dirchars[dir];
6829 if (iflags.herecmd_menu) {
6830 cmd[0] = there_cmd_menu(FALSE, u.ux + x, u.uy + y);
6836 if (IS_DOOR(levl[u.ux + x][u.uy + y].typ)) {
6837 /* slight assistance to the player: choose kick/open for them
6839 if (levl[u.ux + x][u.uy + y].doormask & D_LOCKED) {
6840 cmd[0] = cmd_from_func(dokick);
6843 if (levl[u.ux + x][u.uy + y].doormask & D_CLOSED) {
6844 cmd[0] = cmd_from_func(doopen);
6848 if (levl[u.ux + x][u.uy + y].typ <= SCORR) {
6849 cmd[0] = cmd_from_func(dosearch);
6855 /* convert without using floating point, allowing sloppy clicking */
6858 else if (y > 2 * abs(x))
6860 else if (x < -2 * abs(y))
6862 else if (y < -2 * abs(x))
6865 x = sgn(x), y = sgn(y);
6867 if (x == 0 && y == 0) {
6868 /* map click on player to "rest" command */
6869 cmd[0] = cmd_from_func(donull);
6875 /* move, attack, etc. */
6877 if (mod == CLICK_1) {
6878 cmd[0] = Cmd.dirchars[dir];
6880 cmd[0] = (Cmd.num_pad
6881 ? M(Cmd.dirchars[dir])
6882 : (Cmd.dirchars[dir] - 'a' + 'A')); /* run command */
6889 get_count(allowchars, inkey, maxcount, count, historical)
6894 boolean historical; /* whether to include in message history: True => yes */
6899 boolean backspaced = FALSE;
6900 /* this should be done in port code so that we have erase_char
6901 and kill_char available; we can at least fake erase_char */
6902 #define STANDBY_erase_char '\177'
6912 cnt = 10L * cnt + (long) (key - '0');
6915 else if (maxcount > 0 && cnt > maxcount)
6917 } else if (cnt && (key == '\b' || key == STANDBY_erase_char)) {
6920 } else if (key == Cmd.spkeys[NHKF_ESC]) {
6922 } else if (!allowchars || index(allowchars, key)) {
6927 if (cnt > 9 || backspaced) {
6928 clear_nhwindow(WIN_MESSAGE);
6929 if (backspaced && !cnt) {
6931 Sprintf(qbuf, "Count: ");
6933 Sprintf(qbuf, "
\90\94: ");
6936 Sprintf(qbuf, "Count: %ld", cnt);
6938 Sprintf(qbuf, "
\90\94: %ld", cnt);
6941 custompline(SUPPRESS_HISTORY, "%s", qbuf);
6948 Sprintf(qbuf, "Count: %ld ", *count);
6950 Sprintf(qbuf, "
\90\94: %ld ", *count);
6951 (void) key2txt((uchar) key, eos(qbuf));
6952 putmsghistory(qbuf, FALSE);
6962 #ifdef LINT /* static char in_line[COLNO]; */
6963 char in_line[COLNO];
6965 static char in_line[COLNO];
6969 iflags.in_parse = TRUE;
6972 flush_screen(1); /* Flush screen buffer. Put the cursor on the hero. */
6975 alt_esc = iflags.altmeta; /* readchar() hack */
6977 if (!Cmd.num_pad || (foo = readchar()) == Cmd.spkeys[NHKF_COUNT]) {
6978 long tmpmulti = multi;
6980 foo = get_count((char *) 0, '\0', LARGEST_INT, &tmpmulti, FALSE);
6981 last_multi = multi = tmpmulti;
6984 alt_esc = FALSE; /* readchar() reset */
6987 if (iflags.debug_fuzzer /* if fuzzing, override '!' and ^Z */
6988 && (Cmd.commands[foo & 0x0ff]
6989 && (Cmd.commands[foo & 0x0ff]->ef_funct == dosuspend_core
6990 || Cmd.commands[foo & 0x0ff]->ef_funct == dosh_core)))
6991 foo = Cmd.spkeys[NHKF_ESC];
6993 if (foo == Cmd.spkeys[NHKF_ESC]) { /* esc cancels count (TH) */
6994 clear_nhwindow(WIN_MESSAGE);
6995 multi = last_multi = 0;
6996 } else if (foo == Cmd.spkeys[NHKF_DOAGAIN] || in_doagain) {
7000 savech(0); /* reset input queue */
7008 save_cm = (char *) 0;
7010 /* in 3.4.3 this was in rhack(), where it was too late to handle M-5 */
7011 if (Cmd.pcHack_compat) {
7012 /* This handles very old inconsistent DOS/Windows behaviour
7013 in a different way: earlier, the keyboard handler mapped
7014 these, which caused counts to be strange when entered
7015 from the number pad. Now do not map them until here. */
7018 foo = Cmd.spkeys[NHKF_RUSH];
7021 foo = Cmd.spkeys[NHKF_RUN];
7024 foo = Cmd.spkeys[NHKF_DOINV];
7033 if (prefix_cmd(foo)) {
7039 clear_nhwindow(WIN_MESSAGE);
7041 iflags.in_parse = FALSE;
7045 #ifdef HANGUPHANDLING
7046 /* some very old systems, or descendents of such systems, expect signal
7047 handlers to have return type `int', but they don't actually inspect
7048 the return value so we should be safe using `void' unconditionally */
7051 hangup(sig_unused) /* called as signal() handler, so sent at least one arg */
7052 int sig_unused UNUSED;
7054 if (program_state.exiting)
7055 program_state.in_moveloop = 0;
7058 /* When using SAFERHANGUP, the done_hup flag it tested in rhack
7059 and a couple of other places; actual hangup handling occurs then.
7060 This is 'safer' because it disallows certain cheats and also
7061 protects against losing objects in the process of being thrown,
7062 but also potentially riskier because the disconnected program
7063 must continue running longer before attempting a hangup save. */
7064 program_state.done_hup++;
7065 /* defer hangup iff game appears to be in progress */
7066 if (program_state.in_moveloop && program_state.something_worth_saving)
7068 #endif /* SAFERHANGUP */
7075 #ifdef NOSAVEONHANGUP
7077 if (flags.ins_chkpt && program_state.something_worth_saving)
7078 program_statue.preserve_locks = 1; /* keep files for recovery */
7080 program_state.something_worth_saving = 0; /* don't save */
7084 if (!program_state.done_hup++)
7086 if (program_state.something_worth_saving)
7088 if (iflags.window_inited)
7089 exit_nhwindows((char *) 0);
7091 nh_terminate(EXIT_SUCCESS);
7092 /*NOTREACHED*/ /* not necessarily true for vms... */
7095 #endif /* HANGUPHANDLING */
7101 int x = u.ux, y = u.uy, mod = 0;
7103 if (iflags.debug_fuzzer)
7105 if (*readchar_queue)
7106 sym = *readchar_queue++;
7108 sym = in_doagain ? pgetchar() : nh_poskey(&x, &y, &mod);
7112 register int cnt = NR_OF_EOFS;
7114 * Some SYSV systems seem to return EOFs for various reasons
7115 * (?like when one hits break or for interrupted systemcalls?),
7116 * and we must see several before we quit.
7119 clearerr(stdin); /* omit if clearerr is undefined */
7121 } while (--cnt && sym == EOF);
7123 #endif /* NR_OF_EOFS */
7126 #ifdef HANGUPHANDLING
7127 hangup(0); /* call end_of_input() or set program_state.done_hup */
7131 } else if (sym == '\033' && alt_esc) {
7132 /* iflags.altmeta: treat two character ``ESC c'' as single `M-c' */
7133 sym = *readchar_queue ? *readchar_queue++ : pgetchar();
7134 if (sym == EOF || sym == 0)
7136 else if (sym != '\033')
7137 sym |= 0200; /* force 8th bit on */
7139 } else if (sym == 0) {
7141 readchar_queue = click_to_cmd(x, y, mod);
7142 sym = *readchar_queue++;
7147 /* '_' command, #travel, via keyboard rather than mouse click */
7154 /* [FIXME? Supporting the ability to disable traveling via mouse
7155 click makes some sense, depending upon overall mouse usage.
7156 Disabling '_' on a user by user basis makes no sense at all since
7157 even if it is typed by accident, aborting when picking a target
7158 destination is trivial. Travel via mouse predates travel via '_',
7159 and this use of OPTION=!travel is probably just a mistake....] */
7160 if (!flags.travelcmd)
7164 cc.x = iflags.travelcc.x;
7165 cc.y = iflags.travelcc.y;
7166 if (cc.x == 0 && cc.y == 0) {
7167 /* No cached destination, start attempt from current position */
7171 iflags.getloc_travelmode = TRUE;
7172 if (iflags.menu_requested) {
7173 int gf = iflags.getloc_filter;
7174 iflags.getloc_filter = GFILTER_VIEW;
7175 if (!getpos_menu(&cc, GLOC_INTERESTING)) {
7176 iflags.getloc_filter = gf;
7177 iflags.getloc_travelmode = FALSE;
7180 iflags.getloc_filter = gf;
7183 pline("Where do you want to travel to?");
7185 pline("
\82Ç
\82±
\82É
\88Ú
\93®
\82·
\82é
\81H");
7187 if (getpos(&cc, TRUE, "the desired destination") < 0) {
7189 if (getpos(&cc, TRUE, "
\88Ú
\93®
\90æ") < 0) {
7190 /* user pressed ESC */
7191 iflags.getloc_travelmode = FALSE;
7195 iflags.getloc_travelmode = FALSE;
7196 iflags.travelcc.x = u.tx = cc.x;
7197 iflags.travelcc.y = u.ty = cc.y;
7198 cmd[0] = Cmd.spkeys[NHKF_TRAVEL];
7199 readchar_queue = cmd;
7204 * Parameter validator for generic yes/no function to prevent
7205 * the core from sending too long a prompt string to the
7206 * window port causing a buffer overflow there.
7209 yn_function(query, resp, def)
7210 const char *query, *resp;
7213 char res, qbuf[QBUFSZ];
7215 extern unsigned saved_pline_index; /* pline.c */
7216 unsigned idx = saved_pline_index;
7217 /* buffer to hold query+space+formatted_single_char_response */
7218 char dumplog_buf[QBUFSZ + 1 + 15]; /* [QBUFSZ+1+7] should suffice */
7221 iflags.last_msg = PLNMSG_UNKNOWN; /* most recent pline is clobbered */
7223 /* maximum acceptable length is QBUFSZ-1 */
7224 if (strlen(query) >= QBUFSZ) {
7225 /* caller shouldn't have passed anything this long */
7226 paniclog("Query truncated: ", query);
7227 (void) strncpy(qbuf, query, QBUFSZ - 1 - 3);
7228 Strcpy(&qbuf[QBUFSZ - 1 - 3], "...");
7231 res = (*windowprocs.win_yn_function)(query, resp, def);
7233 if (idx == saved_pline_index) {
7234 /* when idx is still the same as saved_pline_index, the interface
7235 didn't put the prompt into saved_plines[]; we put a simplified
7236 version in there now (without response choices or default) */
7237 Sprintf(dumplog_buf, "%s ", query);
7238 (void) key2txt((uchar) res, eos(dumplog_buf));
7239 dumplogmsg(dumplog_buf);
7245 /* for paranoid_confirm:quit,die,attack prompting */
7247 paranoid_query(be_paranoid, prompt)
7248 boolean be_paranoid;
7251 boolean confirmed_ok;
7253 /* when paranoid, player must respond with "yes" rather than just 'y'
7254 to give the go-ahead for this query; default is "no" unless the
7255 ParanoidConfirm flag is set in which case there's no default */
7257 char qbuf[QBUFSZ], ans[BUFSZ] = DUMMY;
7258 const char *promptprefix = "", *responsetype = ParanoidConfirm
7261 int trylimit = 6; /* 1 normal, 5 more with "Yes or No:" prefix */
7263 /* in addition to being paranoid about this particular
7264 query, we might be even more paranoid about all paranoia
7265 responses (ie, ParanoidConfirm is set) in which case we
7266 require "no" to reject in addition to "yes" to confirm
7267 (except we won't loop if response is ESC; it means no) */
7269 Sprintf(qbuf, "%s%s %s", promptprefix, prompt, responsetype);
7271 (void) mungspaces(ans);
7272 confirmed_ok = !strcmpi(ans, "yes");
7273 if (confirmed_ok || *ans == '\033')
7275 promptprefix = "\"Yes\" or \"No\": ";
7276 } while (ParanoidConfirm && strcmpi(ans, "no") && --trylimit);
7278 confirmed_ok = (yn(prompt) == 'y');
7280 return confirmed_ok;
7283 /* ^Z command, #suspend */
7285 dosuspend_core(VOID_ARGS)
7288 /* Does current window system support suspend? */
7289 if ((*windowprocs.win_can_suspend)()) {
7290 /* NB: SYSCF SHELLERS handled in port code. */
7294 Norep(cmdnotavail, "#suspend");
7298 /* '!' command, #shell */
7300 dosh_core(VOID_ARGS)
7303 /* access restrictions, if any, are handled in port code */
7306 Norep(cmdnotavail, "#shell");