1 /* NetHack 3.6 cmd.c $NHDT-Date: 1575245052 2019/12/02 00:04:12 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.350 $ */
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-2020 */
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))
31 #define unctrl(c) ((c) <= C('z') ? (0x60 | (c)) : (c))
32 #define unmeta(c) (0x7f & (c))
35 STATIC_VAR boolean alt_esc = FALSE;
38 struct cmd Cmd = { 0 }; /* flag.h */
40 extern const char *hu_stat[]; /* hunger status from eat.c */
41 extern const char *enc_stat[]; /* encumbrance status from botl.c */
45 * Some systems may have getchar() return EOF for various reasons, and
46 * we should not quit before seeing at least NR_OF_EOFS consecutive EOFs.
48 #if defined(SYSV) || defined(DGUX) || defined(HPUX)
53 #define CMD_TRAVEL (char) 0x90
54 #define CMD_CLICKLOOK (char) 0x8F
57 extern int NDECL(wiz_debug_cmd_bury);
60 #ifdef DUMB /* stuff commented out in extern.h, but needed here */
61 extern int NDECL(doapply); /**/
62 extern int NDECL(dorub); /**/
63 extern int NDECL(dojump); /**/
64 extern int NDECL(doextlist); /**/
65 extern int NDECL(enter_explore_mode); /**/
66 extern int NDECL(dodrop); /**/
67 extern int NDECL(doddrop); /**/
68 extern int NDECL(dodown); /**/
69 extern int NDECL(doup); /**/
70 extern int NDECL(donull); /**/
71 extern int NDECL(dowipe); /**/
72 extern int NDECL(docallcnd); /**/
73 extern int NDECL(dotakeoff); /**/
74 extern int NDECL(doremring); /**/
75 extern int NDECL(dowear); /**/
76 extern int NDECL(doputon); /**/
77 extern int NDECL(doddoremarm); /**/
78 extern int NDECL(dokick); /**/
79 extern int NDECL(dofire); /**/
80 extern int NDECL(dothrow); /**/
81 extern int NDECL(doeat); /**/
82 extern int NDECL(done2); /**/
83 extern int NDECL(vanquished); /**/
84 extern int NDECL(doengrave); /**/
85 extern int NDECL(dopickup); /**/
86 extern int NDECL(ddoinv); /**/
87 extern int NDECL(dotypeinv); /**/
88 extern int NDECL(dolook); /**/
89 extern int NDECL(doprgold); /**/
90 extern int NDECL(doprwep); /**/
91 extern int NDECL(doprarm); /**/
92 extern int NDECL(doprring); /**/
93 extern int NDECL(dopramulet); /**/
94 extern int NDECL(doprtool); /**/
95 extern int NDECL(dosuspend); /**/
96 extern int NDECL(doforce); /**/
97 extern int NDECL(doopen); /**/
98 extern int NDECL(doclose); /**/
99 extern int NDECL(dosh); /**/
100 extern int NDECL(dodiscovered); /**/
101 extern int NDECL(doclassdisco); /**/
102 extern int NDECL(doset); /**/
103 extern int NDECL(dotogglepickup); /**/
104 extern int NDECL(dowhatis); /**/
105 extern int NDECL(doquickwhatis); /**/
106 extern int NDECL(dowhatdoes); /**/
107 extern int NDECL(dohelp); /**/
108 extern int NDECL(dohistory); /**/
109 extern int NDECL(doloot); /**/
110 extern int NDECL(dodrink); /**/
111 extern int NDECL(dodip); /**/
112 extern int NDECL(dosacrifice); /**/
113 extern int NDECL(dopray); /**/
114 extern int NDECL(dotip); /**/
115 extern int NDECL(doturn); /**/
116 extern int NDECL(doredraw); /**/
117 extern int NDECL(doread); /**/
118 extern int NDECL(dosave); /**/
119 extern int NDECL(dosearch); /**/
120 extern int NDECL(doidtrap); /**/
121 extern int NDECL(dopay); /**/
122 extern int NDECL(dosit); /**/
123 extern int NDECL(dotalk); /**/
124 extern int NDECL(docast); /**/
125 extern int NDECL(dovspell); /**/
126 extern int NDECL(dotelecmd); /**/
127 extern int NDECL(dountrap); /**/
128 extern int NDECL(doversion); /**/
129 extern int NDECL(doextversion); /**/
130 extern int NDECL(doswapweapon); /**/
131 extern int NDECL(dowield); /**/
132 extern int NDECL(dowieldquiver); /**/
133 extern int NDECL(dozap); /**/
134 extern int NDECL(doorganize); /**/
137 static int NDECL((*timed_occ_fn));
139 STATIC_PTR int NDECL(dosuspend_core);
140 STATIC_PTR int NDECL(dosh_core);
141 STATIC_PTR int NDECL(doherecmdmenu);
142 STATIC_PTR int NDECL(dotherecmdmenu);
143 STATIC_PTR int NDECL(doprev_message);
144 STATIC_PTR int NDECL(timed_occupation);
145 STATIC_PTR int NDECL(doextcmd);
146 STATIC_PTR int NDECL(dotravel);
147 STATIC_PTR int NDECL(doterrain);
148 STATIC_PTR int NDECL(wiz_wish);
149 STATIC_PTR int NDECL(wiz_identify);
150 STATIC_PTR int NDECL(wiz_intrinsic);
151 STATIC_PTR int NDECL(wiz_map);
152 STATIC_PTR int NDECL(wiz_makemap);
153 STATIC_PTR int NDECL(wiz_genesis);
154 STATIC_PTR int NDECL(wiz_where);
155 STATIC_PTR int NDECL(wiz_detect);
156 STATIC_PTR int NDECL(wiz_panic);
157 STATIC_PTR int NDECL(wiz_polyself);
158 STATIC_PTR int NDECL(wiz_level_tele);
159 STATIC_PTR int NDECL(wiz_level_change);
160 STATIC_PTR int NDECL(wiz_show_seenv);
161 STATIC_PTR int NDECL(wiz_show_vision);
162 STATIC_PTR int NDECL(wiz_smell);
163 STATIC_PTR int NDECL(wiz_show_wmodes);
164 STATIC_DCL void NDECL(wiz_map_levltyp);
165 STATIC_DCL void NDECL(wiz_levltyp_legend);
166 #if defined(__BORLANDC__) && !defined(_WIN32)
167 extern void FDECL(show_borlandc_stats, (winid));
169 #ifdef DEBUG_MIGRATING_MONS
170 STATIC_PTR int NDECL(wiz_migrate_mons);
172 STATIC_DCL int FDECL(size_monst, (struct monst *, BOOLEAN_P));
173 STATIC_DCL int FDECL(size_obj, (struct obj *));
174 STATIC_DCL void FDECL(count_obj, (struct obj *, long *, long *,
175 BOOLEAN_P, BOOLEAN_P));
176 STATIC_DCL void FDECL(obj_chain, (winid, const char *, struct obj *,
177 BOOLEAN_P, long *, long *));
178 STATIC_DCL void FDECL(mon_invent_chain, (winid, const char *, struct monst *,
180 STATIC_DCL void FDECL(mon_chain, (winid, const char *, struct monst *,
181 BOOLEAN_P, long *, long *));
182 STATIC_DCL void FDECL(contained_stats, (winid, const char *, long *, long *));
183 STATIC_DCL void FDECL(misc_stats, (winid, long *, long *));
184 STATIC_PTR int NDECL(wiz_show_stats);
185 STATIC_DCL boolean FDECL(accept_menu_prefix, (int NDECL((*))));
186 STATIC_PTR int NDECL(wiz_rumor_check);
187 STATIC_PTR int NDECL(doattributes);
189 STATIC_DCL void FDECL(enlght_out, (const char *));
190 STATIC_DCL void FDECL(enlght_line, (const char *, const char *, const char *,
192 STATIC_DCL char *FDECL(enlght_combatinc, (const char *, int, int, char *));
193 STATIC_DCL void FDECL(enlght_halfdmg, (int, int));
194 STATIC_DCL boolean NDECL(walking_on_water);
195 STATIC_DCL boolean FDECL(cause_known, (int));
196 STATIC_DCL char *FDECL(attrval, (int, int, char *));
197 STATIC_DCL void FDECL(background_enlightenment, (int, int));
198 STATIC_DCL void FDECL(basics_enlightenment, (int, int));
199 STATIC_DCL void FDECL(characteristics_enlightenment, (int, int));
200 STATIC_DCL void FDECL(one_characteristic, (int, int, int));
201 STATIC_DCL void FDECL(status_enlightenment, (int, int));
202 STATIC_DCL void FDECL(attributes_enlightenment, (int, int));
204 STATIC_DCL void FDECL(add_herecmd_menuitem, (winid, int NDECL((*)),
206 STATIC_DCL char FDECL(here_cmd_menu, (BOOLEAN_P));
207 STATIC_DCL char FDECL(there_cmd_menu, (BOOLEAN_P, int, int));
208 STATIC_DCL char *NDECL(parse);
209 STATIC_DCL void FDECL(show_direction_keys, (winid, CHAR_P, BOOLEAN_P));
210 STATIC_DCL boolean FDECL(help_dir, (CHAR_P, int, const char *));
212 static const char *readchar_queue = "";
213 static coord clicklook_cc;
214 /* for rejecting attempts to use wizard mode commands */
216 static const char unavailcmd[] = "Unavailable command '%s'.";
218 static const char unavailcmd[] = "'%s'
\83R
\83}
\83\93\83h
\82Í
\8eg
\82¦
\82È
\82¢
\81D";
219 /* for rejecting #if !SHELL, !SUSPEND */
221 static const char cmdnotavail[] = "'%s' command not available.";
223 static const char cmdnotavail[] = "'%s'
\83R
\83}
\83\93\83h
\82Í
\97\98\97p
\82Å
\82«
\82Ü
\82¹
\82ñ
\81D";
226 doprev_message(VOID_ARGS)
228 return nh_doprev_message();
231 /* Count down by decrementing multi */
233 timed_occupation(VOID_ARGS)
241 /* If you have moved since initially setting some occupations, they
242 * now shouldn't be able to restart.
244 * The basic rule is that if you are carrying it, you can continue
245 * since it is with you. If you are acting on something at a distance,
246 * your orientation to it must have changed when you moved.
248 * The exception to this is taking off items, since they can be taken
249 * off in a number of ways in the intervening time, screwing up ordering.
251 * Currently: Take off all armor.
252 * Picking Locks / Forcing Chests.
263 /* If a time is given, use it to timeout this function, otherwise the
264 * function times out by its own means.
267 set_occupation(fn, txt, xtime)
273 occupation = timed_occupation;
282 STATIC_DCL char NDECL(popch);
284 /* Provide a means to redo the last command. The flag `in_doagain' is set
285 * to true while redoing the command. This flag is tested in commands that
286 * require additional input (like `throw' which requires a thing and a
287 * direction), and the input prompt is not shown. Also, while in_doagain is
288 * TRUE, no keystrokes can be saved into the saveq.
291 static char pushq[BSIZE], saveq[BSIZE];
292 static NEARDATA int phead, ptail, shead, stail;
297 /* If occupied, return '\0', letting tgetch know a character should
298 * be read from the keyboard. If the character read is not the
299 * ABORT character (as checked in pcmain.c), that character will be
300 * pushed back on the pushq.
305 return (char) ((shead != stail) ? saveq[stail++] : '\0');
307 return (char) ((phead != ptail) ? pushq[ptail++] : '\0');
311 pgetchar() /* courtesy of aeb@cwi.nl */
315 if (iflags.debug_fuzzer)
322 /* A ch == 0 resets the pushq */
334 /* A ch == 0 resets the saveq. Only save keystrokes when not
335 * replaying a previous command.
343 phead = ptail = shead = stail = 0;
344 else if (shead < BSIZE)
350 /* here after # - now read a full-word command */
357 /* keep repeating until we don't run help or quit */
363 func = extcmdlist[idx].ef_funct;
364 if (!wizard && (extcmdlist[idx].flags & WIZMODECMD)) {
366 You("can't do that.");
368 pline("
\82»
\82ê
\82Í
\82Å
\82«
\82Ü
\82¹
\82ñ
\81D");
371 if (iflags.menu_requested && !accept_menu_prefix(func)) {
373 pline("'%s' prefix has no effect for the %s command.",
374 visctrl(Cmd.spkeys[NHKF_REQMENU]),
375 extcmdlist[idx].ef_txt);
377 pline("'%s'
\90Ú
\93ª
\8e«
\82Í%s
\83R
\83}
\83\93\83h
\82É
\82Í
\96³
\8cø
\81D",
378 visctrl(Cmd.spkeys[NHKF_REQMENU]),
379 extcmdlist[idx].ef_txt);
381 iflags.menu_requested = FALSE;
384 } while (func == doextlist);
389 /* here after #? - now list all full-word commands and provid
390 some navigation capability through the long list */
394 register const struct ext_func_tab *efp;
395 char buf[BUFSZ], searchbuf[BUFSZ], promptbuf[QBUFSZ];
400 int menumode = 0, menushown[2], onelist = 0;
401 boolean redisplay = TRUE, search = FALSE;
403 static const char *headings[] = { "Extended commands",
404 "Debugging Extended Commands" };
406 static const char *headings[] = { "
\8ag
\92£
\83R
\83}
\83\93\83h",
407 "
\83f
\83o
\83b
\83O
\8ag
\92£
\83R
\83}
\83\93\83h" };
411 menuwin = create_nhwindow(NHW_MENU);
418 add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
419 "Extended Commands List", MENU_UNSELECTED);
421 add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
422 "
\8ag
\92£
\83R
\83}
\83\93\83h
\88ê
\97\97", MENU_UNSELECTED);
424 add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
425 "", MENU_UNSELECTED);
428 Strcpy(buf, menumode ? "Show" : "Hide");
429 Strcat(buf, " commands that don't autocomplete");
431 Strcat(buf, " (those not marked with [A])");
433 Strcpy(buf, "
\8e©
\93®
\95â
\8a®
\82³
\82ê
\82È
\82¢
\83R
\83}
\83\93\83h
\82ð");
434 Strcat(buf, menumode ? "
\95\
\8e¦
\82·
\82é" : "
\95\
\8e¦
\82µ
\82È
\82¢ (
\82±
\82ê
\82ç
\82Í[A]
\83}
\81[
\83N
\82ª
\82Â
\82©
\82È
\82¢)");
437 add_menu(menuwin, NO_GLYPH, &any, 'a', 0, ATR_NONE, buf,
442 /* was 's', but then using ':' handling within the interface
443 would only examine the two or three meta entries, not the
444 actual list of extended commands shown via separator lines;
445 having ':' as an explicit selector overrides the default
446 menu behavior for it; we retain 's' as a group accelerator */
448 add_menu(menuwin, NO_GLYPH, &any, ':', 's', ATR_NONE,
449 "Search extended commands", MENU_UNSELECTED);
451 add_menu(menuwin, NO_GLYPH, &any, ':', 's', ATR_NONE,
452 "
\8ag
\92£
\83R
\83}
\83\93\83h
\82ð
\8c\9f\8dõ
\82·
\82é", MENU_UNSELECTED);
456 Strcpy(buf, "Show all, clear search");
458 Strcpy(buf, "
\91S
\82Ä
\95\
\8e¦;
\8c\9f\8dõ
\82ð
\83N
\83\8a\83A");
460 if (strlen(buf) + strlen(searchbuf) + strlen(" (\"\")") < QBUFSZ)
461 Sprintf(eos(buf), " (\"%s\")", searchbuf);
463 /* specifying ':' as a group accelerator here is mostly a
464 statement of intent (we'd like to accept it as a synonym but
465 also want to hide it from general menu use) because it won't
466 work for interfaces which support ':' to search; use as a
467 general menu command takes precedence over group accelerator */
468 add_menu(menuwin, NO_GLYPH, &any, 's', ':', ATR_NONE,
469 buf, MENU_UNSELECTED);
474 add_menu(menuwin, NO_GLYPH, &any, 'z', 0, ATR_NONE,
475 onelist ? "Show debugging commands in separate section"
476 : "Show all alphabetically, including debugging commands",
479 add_menu(menuwin, NO_GLYPH, &any, 'z', 0, ATR_NONE,
480 onelist ? "
\83f
\83o
\83b
\83O
\83R
\83}
\83\93\83h
\82Í
\95Ê
\82Ì
\90ß
\82É
\95\
\8e¦
\82·
\82é"
481 : "
\83f
\83o
\83b
\83O
\83R
\83}
\83\93\83h
\82ð
\8aÜ
\82Þ
\91S
\82Ä
\82Ì
\83R
\83}
\83\93\83h
\82ð
\83A
\83\8b\83t
\83@
\83x
\83b
\83g
\8f\87\82É
\95\
\8e¦
\82·
\82é",
486 add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
487 "", MENU_UNSELECTED);
488 menushown[0] = menushown[1] = 0;
490 for (pass = 0; pass <= 1; ++pass) {
491 /* skip second pass if not in wizard mode or wizard mode
492 commands are being integrated into a single list */
493 if (pass == 1 && (onelist || !wizard))
495 for (efp = extcmdlist; efp->ef_txt; efp++) {
498 if ((efp->flags & CMD_NOT_AVAILABLE) != 0)
500 /* if hiding non-autocomplete commands, skip such */
501 if (menumode == 1 && (efp->flags & AUTOCOMPLETE) == 0)
503 /* if searching, skip this command if it doesn't match */
505 /* first try case-insensitive substring match */
506 && !strstri(efp->ef_txt, searchbuf)
507 && !strstri(efp->ef_desc, searchbuf)
508 /* wildcard support; most interfaces use case-insensitve
509 pmatch rather than regexp for menu searching */
510 && !pmatchi(searchbuf, efp->ef_txt)
511 && !pmatchi(searchbuf, efp->ef_desc))
513 /* skip wizard mode commands if not in wizard mode;
514 when showing two sections, skip wizard mode commands
515 in pass==0 and skip other commands in pass==1 */
516 wizc = (efp->flags & WIZMODECMD) != 0;
519 if (!onelist && pass != wizc)
522 /* We're about to show an item, have we shown the menu yet?
523 Doing menu in inner loop like this on demand avoids a
524 heading with no subordinate entries on the search
526 if (!menushown[pass]) {
527 Strcpy(buf, headings[pass]);
528 add_menu(menuwin, NO_GLYPH, &any, 0, 0,
529 iflags.menu_headings, buf, MENU_UNSELECTED);
532 Sprintf(buf, " %-14s %-3s %s",
534 (efp->flags & AUTOCOMPLETE) ? "[A]" : " ",
536 add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
537 buf, MENU_UNSELECTED);
541 add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
542 "", MENU_UNSELECTED);
544 if (*searchbuf && !n)
546 add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
547 "no matches", MENU_UNSELECTED);
549 add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
550 "
\88ê
\92v
\82È
\82µ", MENU_UNSELECTED);
553 end_menu(menuwin, (char *) 0);
554 n = select_menu(menuwin, PICK_ONE, &selected);
556 switch (selected[0].item.a_int) {
557 case 1: /* 'a': toggle show/hide non-autocomplete */
558 menumode = 1 - menumode; /* toggle 0 -> 1, 1 -> 0 */
561 case 2: /* ':' when not searching yet: enable search */
564 case 3: /* 's' when already searching: disable search */
569 case 4: /* 'z': toggle showing wizard mode commands separately */
572 onelist = 1 - onelist; /* toggle 0 -> 1, 1 -> 0 */
576 free((genericptr_t) selected);
583 Strcpy(promptbuf, "Extended command list search phrase");
584 Strcat(promptbuf, "?");
586 Strcpy(promptbuf, "
\8ag
\92£
\83R
\83}
\83\93\83h
\82Ì
\8c\9f\8dõ
\95¶
\8e\9a\97ñ
\82Í?");
588 getlin(promptbuf, searchbuf);
589 (void) mungspaces(searchbuf);
590 if (searchbuf[0] == '\033')
597 destroy_nhwindow(menuwin);
601 #if defined(TTY_GRAPHICS) || defined(CURSES_GRAPHICS)
602 #define MAX_EXT_CMD 200 /* Change if we ever have more ext cmds */
605 * This is currently used only by the tty interface and is
606 * controlled via runtime option 'extmenu'. (Most other interfaces
607 * already use a menu all the time for extended commands.)
609 * ``# ?'' is counted towards the limit of the number of commands,
610 * so we actually support MAX_EXT_CMD-1 "real" extended commands.
612 * Here after # - now show pick-list of possible commands.
617 const struct ext_func_tab *efp;
618 menu_item *pick_list = (menu_item *) 0;
621 const struct ext_func_tab *choices[MAX_EXT_CMD + 1];
623 char cbuf[QBUFSZ], prompt[QBUFSZ], fmtstr[20];
624 int i, n, nchoices, acount;
625 int ret, len, biggest;
626 int accelerator, prevaccelerator;
628 boolean wastoolong, one_per_line;
636 /* populate choices */
637 for (efp = extcmdlist; efp->ef_txt; efp++) {
638 if ((efp->flags & CMD_NOT_AVAILABLE)
639 || !(efp->flags & AUTOCOMPLETE)
640 || (!wizard && (efp->flags & WIZMODECMD)))
642 if (!matchlevel || !strncmp(efp->ef_txt, cbuf, matchlevel)) {
644 if ((len = (int) strlen(efp->ef_desc)) > biggest)
646 if (++i > MAX_EXT_CMD) {
647 #if (NH_DEVEL_STATUS != NH_STATUS_RELEASED)
649 "Exceeded %d extended commands in doextcmd() menu; 'extmenu' disabled.",
651 #endif /* NH_DEVEL_STATUS != NH_STATUS_RELEASED */
657 choices[i] = (struct ext_func_tab *) 0;
659 /* if we're down to one, we have our selection so get out of here */
661 ret = (nchoices == 1) ? (int) (choices[0] - extcmdlist) : -1;
666 win = create_nhwindow(NHW_MENU);
668 Sprintf(fmtstr, "%%-%ds", biggest + 15);
670 wastoolong = FALSE; /* True => had to wrap due to line width
671 * ('w' in wizard mode) */
672 /* -3: two line menu header, 1 line menu footer (for prompt) */
673 one_per_line = (nchoices < ROWNO - 3);
674 accelerator = prevaccelerator = 0;
676 for (i = 0; choices[i]; ++i) {
677 accelerator = choices[i]->ef_txt[matchlevel];
678 if (accelerator != prevaccelerator || one_per_line)
680 if (accelerator != prevaccelerator || one_per_line
682 /* +4: + sizeof " or " - sizeof "" */
683 && (strlen(prompt) + 4 + strlen(choices[i]->ef_txt)
684 /* -6: enough room for 1 space left margin
685 * + "%c - " menu selector + 1 space right margin */
686 >= min(sizeof prompt, COLNO - 6)))) {
688 /* flush extended cmds for that letter already in buf */
689 Sprintf(buf, fmtstr, prompt);
690 any.a_char = prevaccelerator;
691 add_menu(win, NO_GLYPH, &any, any.a_char, 0, ATR_NONE,
694 if (!(accelerator != prevaccelerator || one_per_line))
698 prevaccelerator = accelerator;
699 if (!acount || one_per_line) {
701 Sprintf(prompt, "%s%s [%s]", wastoolong ? "or " : "",
702 choices[i]->ef_txt, choices[i]->ef_desc);
704 Sprintf(prompt, "%s%s [%s]", wastoolong ? "
\82Ü
\82½
\82Í" : "",
705 choices[i]->ef_txt, choices[i]->ef_desc);
707 } else if (acount == 1) {
709 Sprintf(prompt, "%s%s or %s", wastoolong ? "or " : "",
710 choices[i - 1]->ef_txt, choices[i]->ef_txt);
712 Sprintf(prompt, "%s%s
\82Ü
\82½
\82Í%s", wastoolong ? "
\82Ü
\82½
\82Í" : "",
713 choices[i - 1]->ef_txt, choices[i]->ef_txt);
717 Strcat(prompt, " or ");
719 Strcat(prompt,"
\82Ü
\82½
\82Í ");
720 Strcat(prompt, choices[i]->ef_txt);
726 Sprintf(buf, fmtstr, prompt);
727 any.a_char = prevaccelerator;
728 add_menu(win, NO_GLYPH, &any, any.a_char, 0, ATR_NONE, buf,
732 Sprintf(prompt, "Extended Command: %s", cbuf);
734 Sprintf(prompt, "
\8ag
\92£
\83R
\83}
\83\93\83h: %s", cbuf);
735 end_menu(win, prompt);
736 n = select_menu(win, PICK_ONE, &pick_list);
737 destroy_nhwindow(win);
739 if (matchlevel > (QBUFSZ - 2)) {
740 free((genericptr_t) pick_list);
741 #if (NH_DEVEL_STATUS != NH_STATUS_RELEASED)
742 impossible("Too many chars (%d) entered in extcmd_via_menu()",
747 cbuf[matchlevel++] = pick_list[0].item.a_char;
748 cbuf[matchlevel] = '\0';
749 free((genericptr_t) pick_list);
761 #endif /* TTY_GRAPHICS */
763 /* #monster command - use special monster ability while polymorphed */
765 domonability(VOID_ARGS)
767 if (can_breathe(youmonst.data))
769 else if (attacktype(youmonst.data, AT_SPIT))
771 else if (youmonst.data->mlet == S_NYMPH)
773 else if (attacktype(youmonst.data, AT_GAZE))
775 else if (is_were(youmonst.data))
777 else if (webmaker(youmonst.data))
779 else if (is_hider(youmonst.data))
781 else if (is_mind_flayer(youmonst.data))
782 return domindblast();
783 else if (u.umonnum == PM_GREMLIN) {
784 if (IS_FOUNTAIN(levl[u.ux][u.uy].typ)) {
785 if (split_mon(&youmonst, (struct monst *) 0))
786 dryup(u.ux, u.uy, TRUE);
789 There("is no fountain here.");
791 pline("
\82±
\82±
\82É
\82Í
\90ò
\82Í
\82È
\82¢
\81D");
792 } else if (is_unicorn(youmonst.data)) {
793 use_unicorn_horn((struct obj *) 0);
795 } else if (youmonst.data->msound == MS_SHRIEK) {
799 You("
\8bà
\90Ø
\82è
\90º
\82ð
\82 \82°
\82½
\81D");
802 pline("Unfortunately sound does not carry well through rock.");
804 pline("
\8ec
\94O
\82È
\82ª
\82ç
\89¹
\82Í
\8aâ
\82ð
\82¤
\82Ü
\82
\93`
\82í
\82ç
\82È
\82¢
\81D");
807 } else if (youmonst.data->mlet == S_VAMPIRE)
811 pline("Any special ability you may have is purely reflexive.");
813 pline("
\82 \82È
\82½
\82Ì
\8e\9d\82Á
\82Ä
\82¢
\82é
\93Á
\8eê
\94\
\97Í
\82Í
\82Ç
\82ê
\82à
\8eó
\93®
\93I
\82¾
\81D");
816 You("don't have a special ability in your normal form!");
818 You("
\95\81\92i
\82Ì
\8ep
\82Å
\82Ì
\93Á
\8eê
\94\
\97Í
\82ð
\8e\9d\82Á
\82Ä
\82¢
\82È
\82¢
\81I");
823 enter_explore_mode(VOID_ARGS)
827 You("are in debug mode.");
829 You("
\82·
\82Å
\82É
\83f
\83o
\83b
\83O
\83\82\81[
\83h
\82¾
\81D");
830 } else if (discover) {
832 You("are already in explore mode.");
834 You("
\82·
\82Å
\82É
\92T
\8c\9f\83\82\81[
\83h
\82¾
\81D");
838 if (!sysopt.explorers || !sysopt.explorers[0]
839 || !check_user_string(sysopt.explorers)) {
841 You("cannot access explore mode.");
843 You("
\92T
\8c\9f\83\82\81[
\83h
\82É
\83A
\83N
\83Z
\83X
\82Å
\82«
\82È
\82¢
\81D");
850 "Beware! From explore mode there will be no return to normal game.");
852 "
\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");
853 if (paranoid_query(ParanoidQuit,
855 "Do you want to enter explore mode?")) {
857 "
\94
\8c©
\83\82\81[
\83h
\82É
\88Ú
\82è
\82Ü
\82·
\82©
\81H")) {
858 clear_nhwindow(WIN_MESSAGE);
860 You("are now in non-scoring explore mode.");
862 You("
\83X
\83R
\83A
\82ª
\82Ì
\82ç
\82È
\82¢
\94
\8c©
\83\82\81[
\83h
\82É
\88Ú
\8ds
\82µ
\82½
\81D");
865 clear_nhwindow(WIN_MESSAGE);
867 pline("Resuming normal game.");
869 pline("
\92Ê
\8fí
\83\82\81[
\83h
\82ð
\91±
\82¯
\82é
\81D");
875 /* ^W command - wish for something */
877 wiz_wish(VOID_ARGS) /* Unlimited wishes for debug mode by Paul Polderman */
880 boolean save_verbose = flags.verbose;
882 flags.verbose = FALSE;
884 flags.verbose = save_verbose;
885 (void) encumber_msg();
887 pline(unavailcmd, visctrl((int) cmd_from_func(wiz_wish)));
891 /* ^I command - reveal and optionally identify hero's inventory */
893 wiz_identify(VOID_ARGS)
896 iflags.override_ID = (int) cmd_from_func(wiz_identify);
897 /* command remapping might leave #wizidentify as the only way
898 to invoke us, in which case cmd_from_func() will yield NUL;
899 it won't matter to display_inventory()/display_pickinv()
900 if ^I invokes some other command--what matters is that
901 display_pickinv() and xname() see override_ID as nonzero */
902 if (!iflags.override_ID)
903 iflags.override_ID = C('I');
904 (void) display_inventory((char *) 0, FALSE);
905 iflags.override_ID = 0;
907 pline(unavailcmd, visctrl((int) cmd_from_func(wiz_identify)));
911 /* #wizmakemap - discard current dungeon level and replace with a new one */
913 wiz_makemap(VOID_ARGS)
917 boolean was_in_W_tower = In_W_tower(u.ux, u.uy, &u.uz);
919 rm_mapseen(ledger_no(&u.uz));
920 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
921 if (mtmp->isgd) { /* vault is going away; get rid of guard */
925 if (DEADMONSTER(mtmp))
930 * Reduce 'born' tally for each monster about to be discarded
931 * by savelev(), otherwise replacing heavily populated levels
932 * tends to make their inhabitants become extinct.
939 /* reset lock picking unless it's for a carried container */
940 maybe_reset_pick((struct obj *) 0);
941 /* reset interrupted digging if it was taking place on this level */
942 if (on_level(&context.digging.level, &u.uz))
943 (void) memset((genericptr_t) &context.digging, 0,
944 sizeof (struct dig_info));
945 /* reset cached targets */
946 iflags.travelcc.x = iflags.travelcc.y = 0; /* travel destination */
947 context.polearm.hitmon = (struct monst *) 0; /* polearm target */
948 /* escape from trap */
950 check_special_room(TRUE); /* room exit */
951 u.ustuck = (struct monst *) 0;
954 u.uundetected = 0; /* not hidden, even if means are available */
955 dmonsfree(); /* purge dead monsters from 'fmon' */
956 /* keep steed and other adjacent pets after releasing them
957 from traps, stopping eating, &c as if hero were ascending */
958 keepdogs(TRUE); /* (pets-only; normally we'd be using 'FALSE' here) */
960 /* discard current level; "saving" is used to release dynamic data */
961 savelev(-1, ledger_no(&u.uz), FREE_SAVE);
962 /* create a new level; various things like bestowing a guardian
963 angel on Astral or setting off alarm on Ft.Ludios are handled
964 by goto_level(do.c) so won't occur for replacement levels */
968 vision_full_recalc = 1;
970 /* was using safe_teleds() but that doesn't honor arrival region
971 on levels which have such; we don't force stairs, just area */
972 u_on_rndspot((u.uhave.amulet ? 1 : 0) /* 'going up' flag */
973 | (was_in_W_tower ? 2 : 0));
975 kill_genocided_monsters();
976 /* u_on_rndspot() might pick a spot that has a monster, or losedogs()
977 might pick the hero's spot (only if there isn't already a monster
978 there), so we might have to move hero or the co-located monster */
979 if ((mtmp = m_at(u.ux, u.uy)) != 0)
988 deliver_splev_message(); /* level entry */
989 check_special_room(FALSE); /* room entry */
994 pline(unavailcmd, "#wizmakemap");
999 /* ^F command - reveal the level map and any traps on it */
1005 long save_Hconf = HConfusion, save_Hhallu = HHallucination;
1007 HConfusion = HHallucination = 0L;
1008 for (t = ftrap; t != 0; t = t->ntrap) {
1013 HConfusion = save_Hconf;
1014 HHallucination = save_Hhallu;
1016 pline(unavailcmd, visctrl((int) cmd_from_func(wiz_map)));
1020 /* ^G command - generate monster(s); a count prefix will be honored */
1022 wiz_genesis(VOID_ARGS)
1025 (void) create_particular();
1027 pline(unavailcmd, visctrl((int) cmd_from_func(wiz_genesis)));
1031 /* ^O command - display dungeon layout */
1033 wiz_where(VOID_ARGS)
1036 (void) print_dungeon(FALSE, (schar *) 0, (xchar *) 0);
1038 pline(unavailcmd, visctrl((int) cmd_from_func(wiz_where)));
1042 /* ^E command - detect unseen (secret doors, traps, hidden monsters) */
1044 wiz_detect(VOID_ARGS)
1049 pline(unavailcmd, visctrl((int) cmd_from_func(wiz_detect)));
1053 /* ^V command - level teleport */
1055 wiz_level_tele(VOID_ARGS)
1060 pline(unavailcmd, visctrl((int) cmd_from_func(wiz_level_tele)));
1064 /* #levelchange command - adjust hero's experience level */
1066 wiz_level_change(VOID_ARGS)
1068 char buf[BUFSZ] = DUMMY;
1073 getlin("To what experience level do you want to be set?", buf);
1075 getlin("
\8co
\8c±
\83\8c\83x
\83\8b\82ð
\82¢
\82
\82Â
\82É
\90Ý
\92è
\82µ
\82Ü
\82·
\82©
\81H", buf);
1076 (void) mungspaces(buf);
1077 if (buf[0] == '\033' || buf[0] == '\0')
1080 ret = sscanf(buf, "%d", &newlevel);
1086 if (newlevel == u.ulevel) {
1088 You("are already that experienced.");
1090 You("
\82·
\82Å
\82É
\82»
\82Ì
\8co
\8c±
\83\8c\83x
\83\8b\82¾
\81D");
1091 } else if (newlevel < u.ulevel) {
1092 if (u.ulevel == 1) {
1094 You("are already as inexperienced as you can get.");
1096 You("
\82·
\82Å
\82É
\89Â
\94\
\82È
\8cÀ
\82è
\82Ì
\8dÅ
\92á
\82Ì
\8co
\8c±
\83\8c\83x
\83\8b\82¾
\81D");
1101 while (u.ulevel > newlevel)
1103 losexp("#levelchange");
1105 losexp("#levelchange
\83R
\83}
\83\93\83h
\82Å");
1107 if (u.ulevel >= MAXULEV) {
1109 You("are already as experienced as you can get.");
1111 You("
\82·
\82Å
\82É
\89Â
\94\
\82È
\8cÀ
\82è
\82Ì
\8dÅ
\91å
\82Ì
\8co
\8c±
\83\8c\83x
\83\8b\82¾
\81D");
1114 if (newlevel > MAXULEV)
1116 while (u.ulevel < newlevel)
1119 u.ulevelmax = u.ulevel;
1123 /* #panic command - test program's panic handling */
1125 wiz_panic(VOID_ARGS)
1127 if (iflags.debug_fuzzer) {
1128 u.uhp = u.uhpmax = 1000;
1129 u.uen = u.uenmax = 1000;
1133 if (paranoid_query(ParanoidQuit,
1134 "Do you want to call panic() and end your game?"))
1136 if (paranoid_query(ParanoidQuit,
1137 "panic()
\8aÖ
\90\94\82ð
\8cÄ
\82Ñ
\8fo
\82µ
\82Ä
\83Q
\81[
\83\80\82ð
\8fI
\97¹
\82³
\82¹
\82Ü
\82·
\82©
\81H"))
1139 panic("Crash test.");
1143 /* #polyself command - change hero's form */
1145 wiz_polyself(VOID_ARGS)
1151 /* #seenv command */
1153 wiz_show_seenv(VOID_ARGS)
1156 int x, y, v, startx, stopx, curx;
1157 char row[COLNO + 1];
1159 win = create_nhwindow(NHW_TEXT);
1161 * Each seenv description takes up 2 characters, so center
1162 * the seenv display around the hero.
1164 startx = max(1, u.ux - (COLNO / 4));
1165 stopx = min(startx + (COLNO / 2), COLNO);
1166 /* can't have a line exactly 80 chars long */
1167 if (stopx - startx == COLNO / 2)
1170 for (y = 0; y < ROWNO; y++) {
1171 for (x = startx, curx = 0; x < stopx; x++, curx += 2) {
1172 if (x == u.ux && y == u.uy) {
1173 row[curx] = row[curx + 1] = '@';
1175 v = levl[x][y].seenv & 0xff;
1177 row[curx] = row[curx + 1] = ' ';
1179 Sprintf(&row[curx], "%02x", v);
1182 /* remove trailing spaces */
1183 for (x = curx - 1; x >= 0; x--)
1188 putstr(win, 0, row);
1190 display_nhwindow(win, TRUE);
1191 destroy_nhwindow(win);
1195 /* #vision command */
1197 wiz_show_vision(VOID_ARGS)
1201 char row[COLNO + 1];
1203 win = create_nhwindow(NHW_TEXT);
1204 Sprintf(row, "Flags: 0x%x could see, 0x%x in sight, 0x%x temp lit",
1205 COULD_SEE, IN_SIGHT, TEMP_LIT);
1206 putstr(win, 0, row);
1208 for (y = 0; y < ROWNO; y++) {
1209 for (x = 1; x < COLNO; x++) {
1210 if (x == u.ux && y == u.uy)
1213 v = viz_array[y][x]; /* data access should be hidden */
1217 row[x] = '0' + viz_array[y][x];
1220 /* remove trailing spaces */
1221 for (x = COLNO - 1; x >= 1; x--)
1226 putstr(win, 0, &row[1]);
1228 display_nhwindow(win, TRUE);
1229 destroy_nhwindow(win);
1233 /* #wmode command */
1235 wiz_show_wmodes(VOID_ARGS)
1239 char row[COLNO + 1];
1241 boolean istty = WINDOWPORT("tty");
1243 win = create_nhwindow(NHW_TEXT);
1245 putstr(win, 0, ""); /* tty only: blank top line */
1246 for (y = 0; y < ROWNO; y++) {
1247 for (x = 0; x < COLNO; x++) {
1249 if (x == u.ux && y == u.uy)
1251 else if (IS_WALL(lev->typ) || lev->typ == SDOOR)
1252 row[x] = '0' + (lev->wall_info & WM_MASK);
1253 else if (lev->typ == CORR)
1255 else if (IS_ROOM(lev->typ) || IS_DOOR(lev->typ))
1261 /* map column 0, levl[0][], is off the left edge of the screen */
1262 putstr(win, 0, &row[1]);
1264 display_nhwindow(win, TRUE);
1265 destroy_nhwindow(win);
1269 /* wizard mode variant of #terrain; internal levl[][].typ values in base-36 */
1271 wiz_map_levltyp(VOID_ARGS)
1275 char row[COLNO + 1];
1276 boolean istty = !strcmp(windowprocs.name, "tty");
1278 win = create_nhwindow(NHW_TEXT);
1279 /* map row 0, levl[][0], is drawn on the second line of tty screen */
1281 putstr(win, 0, ""); /* tty only: blank top line */
1282 for (y = 0; y < ROWNO; y++) {
1283 /* map column 0, levl[0][], is off the left edge of the screen;
1284 it should always have terrain type "undiggable stone" */
1285 for (x = 1; x < COLNO; x++) {
1286 terrain = levl[x][y].typ;
1287 /* assumes there aren't more than 10+26+26 terrain types */
1288 row[x - 1] = (char) ((terrain == STONE && !may_dig(x, y))
1293 ? 'a' + terrain - 10
1294 : 'A' + terrain - 36);
1297 if (levl[0][y].typ != STONE || may_dig(0, y))
1300 putstr(win, 0, row);
1305 s_level *slev = Is_special(&u.uz);
1307 Sprintf(dsc, "D:%d,L:%d", u.uz.dnum, u.uz.dlevel);
1308 /* [dungeon branch features currently omitted] */
1309 /* special level features */
1311 Sprintf(eos(dsc), " \"%s\"", slev->proto);
1312 /* special level flags (note: dungeon.def doesn't set `maze'
1313 or `hell' for any specific levels so those never show up) */
1314 if (slev->flags.maze_like)
1315 Strcat(dsc, " mazelike");
1316 if (slev->flags.hellish)
1317 Strcat(dsc, " hellish");
1318 if (slev->flags.town)
1319 Strcat(dsc, " town");
1320 if (slev->flags.rogue_like)
1321 Strcat(dsc, " roguelike");
1322 /* alignment currently omitted to save space */
1324 /* level features */
1325 if (level.flags.nfountains)
1326 Sprintf(eos(dsc), " %c:%d", defsyms[S_fountain].sym,
1327 (int) level.flags.nfountains);
1328 if (level.flags.nsinks)
1329 Sprintf(eos(dsc), " %c:%d", defsyms[S_sink].sym,
1330 (int) level.flags.nsinks);
1331 if (level.flags.has_vault)
1332 Strcat(dsc, " vault");
1333 if (level.flags.has_shop)
1334 Strcat(dsc, " shop");
1335 if (level.flags.has_temple)
1336 Strcat(dsc, " temple");
1337 if (level.flags.has_court)
1338 Strcat(dsc, " throne");
1339 if (level.flags.has_zoo)
1340 Strcat(dsc, " zoo");
1341 if (level.flags.has_morgue)
1342 Strcat(dsc, " morgue");
1343 if (level.flags.has_barracks)
1344 Strcat(dsc, " barracks");
1345 if (level.flags.has_beehive)
1346 Strcat(dsc, " hive");
1347 if (level.flags.has_swamp)
1348 Strcat(dsc, " swamp");
1350 if (level.flags.noteleport)
1351 Strcat(dsc, " noTport");
1352 if (level.flags.hardfloor)
1353 Strcat(dsc, " noDig");
1354 if (level.flags.nommap)
1355 Strcat(dsc, " noMMap");
1356 if (!level.flags.hero_memory)
1357 Strcat(dsc, " noMem");
1358 if (level.flags.shortsighted)
1359 Strcat(dsc, " shortsight");
1360 if (level.flags.graveyard)
1361 Strcat(dsc, " graveyard");
1362 if (level.flags.is_maze_lev)
1363 Strcat(dsc, " maze");
1364 if (level.flags.is_cavernous_lev)
1365 Strcat(dsc, " cave");
1366 if (level.flags.arboreal)
1367 Strcat(dsc, " tree");
1369 Strcat(dsc, " sokoban-rules");
1370 /* non-flag info; probably should include dungeon branching
1371 checks (extra stairs and magic portals) here */
1372 if (Invocation_lev(&u.uz))
1373 Strcat(dsc, " invoke");
1374 if (On_W_tower_level(&u.uz))
1375 Strcat(dsc, " tower");
1376 /* append a branch identifier for completeness' sake */
1378 Strcat(dsc, " dungeon");
1379 else if (u.uz.dnum == mines_dnum)
1380 Strcat(dsc, " mines");
1381 else if (In_sokoban(&u.uz))
1382 Strcat(dsc, " sokoban");
1383 else if (u.uz.dnum == quest_dnum)
1384 Strcat(dsc, " quest");
1385 else if (Is_knox(&u.uz))
1386 Strcat(dsc, " ludios");
1387 else if (u.uz.dnum == 1)
1388 Strcat(dsc, " gehennom");
1389 else if (u.uz.dnum == tower_dnum)
1390 Strcat(dsc, " vlad");
1391 else if (In_endgame(&u.uz))
1392 Strcat(dsc, " endgame");
1394 /* somebody's added a dungeon branch we're not expecting */
1395 const char *brname = dungeons[u.uz.dnum].dname;
1397 if (!brname || !*brname)
1399 if (!strncmpi(brname, "the ", 4))
1401 Sprintf(eos(dsc), " %s", brname);
1403 /* limit the line length to map width */
1404 if (strlen(dsc) >= COLNO)
1405 dsc[COLNO - 1] = '\0'; /* truncate */
1406 putstr(win, 0, dsc);
1409 display_nhwindow(win, TRUE);
1410 destroy_nhwindow(win);
1414 /* temporary? hack, since level type codes aren't the same as screen
1415 symbols and only the latter have easily accessible descriptions */
1416 static const char *levltyp[] = {
1417 "stone", "vertical wall", "horizontal wall", "top-left corner wall",
1418 "top-right corner wall", "bottom-left corner wall",
1419 "bottom-right corner wall", "cross wall", "tee-up wall", "tee-down wall",
1420 "tee-left wall", "tee-right wall", "drawbridge wall", "tree",
1421 "secret door", "secret corridor", "pool", "moat", "water",
1422 "drawbridge up", "lava pool", "iron bars", "door", "corridor", "room",
1423 "stairs", "ladder", "fountain", "throne", "sink", "grave", "altar", "ice",
1424 "drawbridge down", "air", "cloud",
1425 /* not a real terrain type, but used for undiggable stone
1426 by wiz_map_levltyp() */
1427 "unreachable/undiggable",
1428 /* padding in case the number of entries above is odd */
1432 /* explanation of base-36 output from wiz_map_levltyp() */
1434 wiz_levltyp_legend(VOID_ARGS)
1438 const char *dsc, *fmt;
1441 win = create_nhwindow(NHW_TEXT);
1442 putstr(win, 0, "#terrain encodings:");
1444 fmt = " %c - %-28s"; /* TODO: include tab-separated variant for win32 */
1446 /* output in pairs, left hand column holds [0],[1],...,[N/2-1]
1447 and right hand column holds [N/2],[N/2+1],...,[N-1];
1448 N ('last') will always be even, and may or may not include
1449 the empty string entry to pad out the final pair, depending
1450 upon how many other entries are present in levltyp[] */
1451 last = SIZE(levltyp) & ~1;
1452 for (i = 0; i < last / 2; ++i)
1453 for (j = i; j < last; j += last / 2) {
1456 : !strncmp(dsc, "unreachable", 11) ? '*'
1457 /* same int-to-char conversion as wiz_map_levltyp() */
1458 : (j < 10) ? '0' + j
1459 : (j < 36) ? 'a' + j - 10
1461 Sprintf(eos(buf), fmt, c, dsc);
1463 putstr(win, 0, buf);
1467 display_nhwindow(win, TRUE);
1468 destroy_nhwindow(win);
1472 /* #wizsmell command - test usmellmon(). */
1474 wiz_smell(VOID_ARGS)
1477 int mndx; /* monster index */
1478 coord cc; /* screen pos of unknown glyph */
1479 int glyph; /* glyph at selected position */
1483 mndx = 0; /* gcc -Wall lint */
1484 if (!olfaction(youmonst.data)) {
1485 You("are incapable of detecting odors in your present form.");
1489 pline("You can move the cursor to a monster that you want to smell.");
1491 pline("Pick a monster to smell.");
1492 ans = getpos(&cc, TRUE, "a monster");
1493 if (ans < 0 || cc.x < 0) {
1494 return 0; /* done */
1496 /* Convert the glyph at the selected position to a mndxbol. */
1497 glyph = glyph_at(cc.x, cc.y);
1498 if (glyph_is_monster(glyph))
1499 mndx = glyph_to_mon(glyph);
1502 /* Is it a monster? */
1504 if (!usmellmon(&mons[mndx]))
1505 pline("That monster seems to give off no smell.");
1507 pline("That is not a monster.");
1512 /* #wizinstrinsic command to set some intrinsics for testing */
1514 wiz_intrinsic(VOID_ARGS)
1517 extern const struct propname {
1519 const char *prop_name;
1520 } propertynames[]; /* timeout.c */
1521 static const char wizintrinsic[] = "#wizintrinsic";
1522 static const char fmt[] = "You are%s %s.";
1526 int i, j, n, p, amt, typ;
1527 long oldtimeout, newtimeout;
1528 const char *propname;
1529 menu_item *pick_list = (menu_item *) 0;
1532 win = create_nhwindow(NHW_MENU);
1534 for (i = 0; (propname = propertynames[i].prop_name) != 0; ++i) {
1535 p = propertynames[i].prop_num;
1536 if (p == HALLUC_RES) {
1537 /* Grayswandir vs hallucination; ought to be redone to
1538 use u.uprops[HALLUC].blocked instead of being treated
1539 as a separate property; letting in be manually toggled
1540 even only in wizard mode would be asking for trouble... */
1543 if (p == FIRE_RES) {
1545 add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, "--", FALSE);
1547 any.a_int = i + 1; /* +1: avoid 0 */
1548 oldtimeout = u.uprops[p].intrinsic & TIMEOUT;
1550 Sprintf(buf, "%-27s [%li]", propname, oldtimeout);
1552 Sprintf(buf, "%s", propname);
1553 add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
1555 end_menu(win, "Which intrinsics?");
1556 n = select_menu(win, PICK_ANY, &pick_list);
1557 destroy_nhwindow(win);
1559 amt = 30; /* TODO: prompt for duration */
1560 for (j = 0; j < n; ++j) {
1561 i = pick_list[j].item.a_int - 1; /* -1: reverse +1 above */
1562 p = propertynames[i].prop_num;
1563 oldtimeout = u.uprops[p].intrinsic & TIMEOUT;
1564 newtimeout = oldtimeout + (long) amt;
1569 if (oldtimeout > 0L && newtimeout > oldtimeout)
1570 newtimeout = oldtimeout;
1576 make_blinded(newtimeout, TRUE);
1578 #if 0 /* make_confused() only gives feedback when confusion is
1579 * ending so use the 'default' case for it instead */
1581 make_confused(newtimeout, TRUE);
1585 make_deaf(newtimeout, TRUE);
1588 make_hallucinated(newtimeout, TRUE, 0L);
1591 typ = !rn2(2) ? SICK_VOMITABLE : SICK_NONVOMITABLE;
1592 make_sick(newtimeout, wizintrinsic, TRUE, typ);
1596 !Slimed ? "" : " still", "turning into slime");
1597 make_slimed(newtimeout, buf);
1601 !Stoned ? "" : " still", "turning into stone");
1602 make_stoned(newtimeout, buf, KILLED_BY, wizintrinsic);
1605 make_stunned(newtimeout, TRUE);
1608 Sprintf(buf, fmt, !Vomiting ? "" : " still", "vomiting");
1609 make_vomiting(newtimeout, FALSE);
1614 context.warntype.speciesidx = PM_GRID_BUG;
1615 context.warntype.species
1616 = &mons[context.warntype.speciesidx];
1620 /* slippery fingers applies to gloves if worn at the time
1621 so persistent inventory might need updating */
1622 make_glib((int) newtimeout);
1630 pline("Timeout for %s %s %d.", propertynames[i].prop_name,
1631 oldtimeout ? "increased by" : "set to", amt);
1633 incr_itimeout(&u.uprops[p].intrinsic, amt);
1636 context.botl = 1; /* probably not necessary... */
1639 free((genericptr_t) pick_list);
1642 pline(unavailcmd, visctrl((int) cmd_from_func(wiz_intrinsic)));
1646 /* #wizrumorcheck command - verify each rumor access */
1648 wiz_rumor_check(VOID_ARGS)
1654 /* #terrain command -- show known map, inspired by crawl's '|' command */
1656 doterrain(VOID_ARGS)
1665 * normal play: choose between known map without mons, obj, and traps
1666 * (to see underlying terrain only), or
1667 * known map without mons and objs (to see traps under mons and objs), or
1668 * known map without mons (to see objects under monsters);
1669 * explore mode: normal choices plus full map (w/o mons, objs, traps);
1670 * wizard mode: normal and explore choices plus
1671 * a dump of the internal levl[][].typ codes w/ level flags, or
1672 * a legend for the levl[][].typ codes dump
1674 men = create_nhwindow(NHW_MENU);
1678 add_menu(men, NO_GLYPH, &any, 0, 0, ATR_NONE,
1680 "known map without monsters, objects, and traps",
1682 "
\89ö
\95¨
\81C
\95¨
\81Cã©
\82È
\82µ
\82Ì
\92n
\90}",
1685 add_menu(men, NO_GLYPH, &any, 0, 0, ATR_NONE,
1687 "known map without monsters and objects",
1689 "
\89ö
\95¨
\81C
\95¨
\82È
\82µ
\82Ì
\92n
\90}",
1692 add_menu(men, NO_GLYPH, &any, 0, 0, ATR_NONE,
1694 "known map without monsters",
1696 "
\89ö
\95¨
\82È
\82µ
\82Ì
\92n
\90}",
1698 if (discover || wizard) {
1700 add_menu(men, NO_GLYPH, &any, 0, 0, ATR_NONE,
1702 "full map without monsters, objects, and traps",
1704 "
\89ö
\95¨
\81C
\95¨
\81Cã©
\82È
\82µ
\82Ì
\8a®
\91S
\82È
\92n
\90}",
1708 add_menu(men, NO_GLYPH, &any, 0, 0, ATR_NONE,
1709 "internal levl[][].typ codes in base-36",
1712 add_menu(men, NO_GLYPH, &any, 0, 0, ATR_NONE,
1713 "legend of base-36 levl[][].typ codes",
1718 end_menu(men, "View which?");
1720 end_menu(men, "
\82Ç
\82ê
\82ð
\8c©
\82é
\81H");
1722 n = select_menu(men, PICK_ONE, &sel);
1723 destroy_nhwindow(men);
1725 * n < 0: player used ESC to cancel;
1726 * n == 0: preselected entry was explicitly chosen and got toggled off;
1727 * n == 1: preselected entry was implicitly chosen via <space>|<enter>;
1728 * n == 2: another entry was explicitly chosen, so skip preselected one.
1730 which = (n < 0) ? -1 : (n == 0) ? 1 : sel[0].item.a_int;
1731 if (n > 1 && which == 1)
1732 which = sel[1].item.a_int;
1734 free((genericptr_t) sel);
1737 case 1: /* known map */
1738 reveal_terrain(0, TER_MAP);
1740 case 2: /* known map with known traps */
1741 reveal_terrain(0, TER_MAP | TER_TRP);
1743 case 3: /* known map with known traps and objects */
1744 reveal_terrain(0, TER_MAP | TER_TRP | TER_OBJ);
1746 case 4: /* full map */
1747 reveal_terrain(1, TER_MAP);
1749 case 5: /* map internals */
1752 case 6: /* internal details */
1753 wiz_levltyp_legend();
1758 return 0; /* no time elapses */
1761 /* -enlightenment and conduct- */
1762 static winid en_win = WIN_ERR;
1763 static boolean en_via_menu = FALSE;
1765 static const char You_[] = "You ", are[] = "are ", were[] = "were ",
1766 have[] = "have ", had[] = "had ", can[] = "can ",
1769 static const char You_[] = "
\82 \82È
\82½
\82Í",
1770 are[] = "
\82Å
\82 \82é", were[] = "
\82Å
\82 \82Á
\82½",
1771 have[] = "
\82ð
\82à
\82Á
\82Ä
\82¢
\82é", had[] = "
\82ð
\82à
\82Á
\82Ä
\82¢
\82½",
1772 can[] = "
\82Å
\82«
\82é", could[] = "
\82Å
\82«
\82½",
1773 iru[] = "
\82¢
\82é", ita[] = "
\82¢
\82½";
1775 #if 0 /*JP*//* not used */
1776 static const char have_been[] = "have been ", have_never[] = "have never ",
1781 #define enl_msg(prefix, present, past, suffix, ps) \
1782 enlght_line(prefix, final ? past : present, suffix, ps)
1784 #define enl_msg(prefix, present, past, suffix, ps) \
1785 enlght_line(prefix, ps, suffix, final ? past : present)
1787 #define you_are(attr, ps) enl_msg(You_, are, were, attr, ps)
1788 #define you_have(attr, ps) enl_msg(You_, have, had, attr, ps)
1789 #define you_can(attr, ps) enl_msg(You_, can, could, attr, ps)
1791 #define you_have_been(goodthing) enl_msg(You_, have_been, were, goodthing, "")
1793 #define you_have_been(goodthing) enl_msg(You_, are, were, goodthing, "")
1795 #define you_have_never(badthing) \
1796 enl_msg(You_, have_never, never, badthing, "")
1798 #define you_have_never(badthing) \
1799 enl_msg(badthing, "
\82Ä
\82¢
\82È
\82¢", "
\82È
\82©
\82Á
\82½", "", "")
1802 #define you_have_X(something) \
1803 enl_msg(You_, have, (const char *) "", something, "")
1805 #define you_have_X(something) \
1806 enl_msg(something, "
\82Ä
\82¢
\82é", "
\82½", "", "")
1809 #define you_are_ing(goodthing, ps) enl_msg(You_, iru, ita, goodthing, ps)
1820 add_menu(en_win, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
1822 putstr(en_win, 0, buf);
1826 enlght_line(start, middle, end, ps)
1827 const char *start, *middle, *end, *ps;
1832 Sprintf(buf, " %s%s%s%s.", start, middle, end, ps);
1834 Sprintf(buf, "%s%s%s%s
\81D", start, middle, end, ps);
1838 /* format increased chance to hit or damage or defense (Protection) */
1840 enlght_combatinc(inctyp, incamt, final, outbuf)
1845 const char *modif, *bonus;
1851 absamt = abs(incamt);
1852 /* Protection amount is typically larger than damage or to-hit;
1853 reduce magnitude by a third in order to stretch modifier ranges
1854 (small:1..5, moderate:6..10, large:11..19, huge:20+) */
1856 if (!strcmp(inctyp, "defense"))
1858 if (!strcmp(inctyp, "
\96h
\8cä"))
1860 absamt = (absamt * 2) / 3;
1866 modif = "
\8bÍ
\82©
\82È";
1867 else if (absamt <= 6)
1871 modif = "
\92\86\92ö
\93x
\82Ì";
1872 else if (absamt <= 12)
1876 modif = "
\91å
\82«
\82È";
1881 modif = "
\8b
\91å
\82È";
1884 modif = !incamt ? "no" : an(modif); /* ("no" case shouldn't happen) */
1887 bonus = (incamt >= 0) ? "bonus" : "penalty";
1889 bonus = (incamt > 0) ? "
\83{
\81[
\83i
\83X" : "
\83y
\83i
\83\8b\83e
\83B";
1890 /* "bonus <foo>" (to hit) vs "<bar> bonus" (damage, defense) */
1892 invrt = strcmp(inctyp, "to hit") ? TRUE : FALSE;
1896 Sprintf(outbuf, "%s %s %s", modif, invrt ? inctyp : bonus,
1897 invrt ? bonus : inctyp);
1899 Sprintf(outbuf, "%s
\82É%s%s", inctyp, modif, bonus);
1901 if (final || wizard)
1902 Sprintf(eos(outbuf), " (%s%d)", (incamt > 0) ? "+" : "", incamt);
1907 /* report half physical or half spell damage */
1909 enlght_halfdmg(category, final)
1913 const char *category_name;
1919 category_name = "physical";
1921 category_name = "
\95¨
\97\9d";
1925 category_name = "spell";
1927 category_name = "
\8eô
\95¶";
1931 category_name = "unknown";
1933 category_name = "
\95s
\96¾";
1937 Sprintf(buf, " %s %s damage", (final || wizard) ? "half" : "reduced",
1939 enl_msg(You_, "take", "took", buf, from_what(category));
1941 Sprintf(buf, " %s
\83_
\83\81\81[
\83W
\82ð%s", (final || wizard) ? "
\94¼
\8c¸" : "
\8c¸
\8f",
1943 enl_msg(You_, "
\82µ
\82Ä
\82¢
\82é", "
\82µ
\82Ä
\82¢
\82½", buf, from_what(category));
1947 /* is hero actively using water walking capability on water (or lava)? */
1951 if (u.uinwater || Levitation || Flying)
1953 return (boolean) (Wwalking
1954 && (is_pool(u.ux, u.uy) || is_lava(u.ux, u.uy)));
1957 /* check whether hero is wearing something that player definitely knows
1958 confers the target property; item must have been seen and its type
1959 discovered but it doesn't necessarily have to be fully identified */
1961 cause_known(propindx)
1962 int propindx; /* index of a property which can be conveyed by worn item */
1964 register struct obj *o;
1965 long mask = W_ARMOR | W_AMUL | W_RING | W_TOOL;
1967 /* simpler than from_what()/what_gives(); we don't attempt to
1968 handle artifacts and we deliberately ignore wielded items */
1969 for (o = invent; o; o = o->nobj) {
1970 if (!(o->owornmask & mask))
1972 if ((int) objects[o->otyp].oc_oprop == propindx
1973 && objects[o->otyp].oc_name_known && o->dknown)
1979 /* format a characteristic value, accommodating Strength's strangeness */
1981 attrval(attrindx, attrvalue, resultbuf)
1982 int attrindx, attrvalue;
1983 char resultbuf[]; /* should be at least [7] to hold "18/100\0" */
1985 if (attrindx != A_STR || attrvalue <= 18)
1986 Sprintf(resultbuf, "%d", attrvalue);
1987 else if (attrvalue > STR18(100)) /* 19 to 25 */
1988 Sprintf(resultbuf, "%d", attrvalue - 100);
1989 else /* simplify "18/ **" to be "18/100" */
1990 Sprintf(resultbuf, "18/%02d", attrvalue - 18);
1995 enlightenment(mode, final)
1996 int mode; /* BASICENLIGHTENMENT | MAGICENLIGHTENMENT (| both) */
1997 int final; /* ENL_GAMEINPROGRESS:0, ENL_GAMEOVERALIVE, ENL_GAMEOVERDEAD */
1999 char buf[BUFSZ], tmpbuf[BUFSZ];
2001 en_win = create_nhwindow(NHW_MENU);
2002 en_via_menu = !final;
2006 Strcpy(tmpbuf, plname);
2007 *tmpbuf = highc(*tmpbuf); /* same adjustment as bottom line */
2008 /* as in background_enlightenment, when poly'd we need to use the saved
2009 gender in u.mfemale rather than the current you-as-monster gender */
2011 Sprintf(buf, "%s the %s's attributes:", tmpbuf,
2012 ((Upolyd ? u.mfemale : flags.female) && urole.name.f)
2016 Sprintf(buf, "%s
\82Ì%s
\82Ì
\91®
\90«:",
2017 ((Upolyd ? u.mfemale : flags.female) && urole.name.f)
2024 enlght_out(buf); /* "Conan the Archeologist's attributes:" */
2025 /* background and characteristics; ^X or end-of-game disclosure */
2026 if (mode & BASICENLIGHTENMENT) {
2027 /* role, race, alignment, deities, dungeon level, time, experience */
2028 background_enlightenment(mode, final);
2029 /* hit points, energy points, armor class, gold */
2030 basics_enlightenment(mode, final);
2031 /* strength, dexterity, &c */
2032 characteristics_enlightenment(mode, final);
2034 /* expanded status line information, including things which aren't
2035 included there due to space considerations--such as obvious
2036 alternative movement indicators (riding, levitation, &c), and
2037 various troubles (turning to stone, trapped, confusion, &c);
2038 shown for both basic and magic enlightenment */
2039 status_enlightenment(mode, final);
2040 /* remaining attributes; shown for potion,&c or wizard mode and
2041 explore mode ^X or end of game disclosure */
2042 if (mode & MAGICENLIGHTENMENT) {
2043 /* intrinsics and other traditional enlightenment feedback */
2044 attributes_enlightenment(mode, final);
2048 display_nhwindow(en_win, TRUE);
2050 menu_item *selected = 0;
2052 end_menu(en_win, (char *) 0);
2053 if (select_menu(en_win, PICK_NONE, &selected) > 0)
2054 free((genericptr_t) selected);
2055 en_via_menu = FALSE;
2057 destroy_nhwindow(en_win);
2062 /* display role, race, alignment and such to en_win */
2064 background_enlightenment(unused_mode, final)
2065 int unused_mode UNUSED;
2068 const char *role_titl, *rank_titl;
2069 int innategend, difgend, difalgn;
2070 char buf[BUFSZ], tmpbuf[BUFSZ];
2072 /* note that if poly'd, we need to use u.mfemale instead of flags.female
2073 to access hero's saved gender-as-human/elf/&c rather than current one */
2074 innategend = (Upolyd ? u.mfemale : flags.female) ? 1 : 0;
2075 role_titl = (innategend && urole.name.f) ? urole.name.f : urole.name.m;
2076 rank_titl = rank_of(u.ulevel, Role_switch, innategend);
2078 enlght_out(""); /* separator after title */
2080 enlght_out("Background:");
2082 enlght_out("
\94w
\8ci
\8fî
\95ñ:");
2084 /* if polymorphed, report current shape before underlying role;
2085 will be repeated as first status: "you are transformed" and also
2086 among various attributes: "you are in beast form" (after being
2087 told about lycanthropy) or "you are polymorphed into <a foo>"
2088 (with countdown timer appended for wizard mode); we really want
2089 the player to know he's not a samurai at the moment... */
2091 struct permonst *uasmon = youmonst.data;
2094 /* here we always use current gender, not saved role gender */
2095 if (!is_male(uasmon) && !is_female(uasmon) && !is_neuter(uasmon))
2097 Sprintf(tmpbuf, "%s ", genders[flags.female ? 1 : 0].adj);
2099 Sprintf(tmpbuf, "%s
\82Ì", genders[flags.female ? 1 : 0].adj);
2101 Sprintf(buf, "%sin %s%s form", !final ? "currently " : "", tmpbuf,
2104 Sprintf(buf, "%s%s%s
\82Ì
\8ep", !final ? "
\8d¡
\82Ì
\82Æ
\82±
\82ë" : "", tmpbuf,
2110 you_are_ing(buf, "");
2113 /* report role; omit gender if it's redundant (eg, "female priestess") */
2116 && ((urole.allow & ROLE_GENDMASK) == (ROLE_MALE | ROLE_FEMALE)
2117 || innategend != flags.initgend))
2119 Sprintf(tmpbuf, "%s ", genders[innategend].adj);
2121 Sprintf(tmpbuf, "%s", genders[innategend].adj);
2125 Strcpy(buf, "actually "); /* "You are actually a ..." */
2127 Strcpy(buf, "
\8eÀ
\8dÛ
\82É
\82Í"); /* "
\82 \82È
\82½
\82Í
\8eÀ
\8dÛ
\82É
\82Í..." */
2129 if (!strcmpi(rank_titl, role_titl)) {
2130 /* omit role when rank title matches it */
2132 Sprintf(eos(buf), "%s, level %d %s%s", an(rank_titl), u.ulevel,
2133 tmpbuf, urace.noun);
2135 Sprintf(eos(buf), "
\83\8c\83x
\83\8b%d
\82Ì%s
\82Ì%s%s", u.ulevel,
2136 tmpbuf, urace.adj, role_titl);
2140 Sprintf(eos(buf), "%s, a level %d %s%s %s", an(rank_titl), u.ulevel,
2141 tmpbuf, urace.adj, role_titl);
2143 Sprintf(eos(buf), "
\83\8c\83x
\83\8b%d
\82Ì%s
\82Ì%s%s
\82Ì%s", u.ulevel,
2144 tmpbuf, urace.adj, role_titl, rank_titl);
2149 /* report alignment (bypass you_are() in order to omit ending period);
2150 adverb is used to distinguish between temporary change (helm of opp.
2151 alignment), permanent change (one-time conversion), and original */
2153 Sprintf(buf, " %s%s%s, %son a mission for %s",
2154 You_, !final ? are : were,
2155 align_str(u.ualign.type),
2156 /* helm of opposite alignment (might hide conversion) */
2157 (u.ualign.type != u.ualignbase[A_CURRENT])
2158 /* what's the past tense of "currently"? if we used "formerly"
2159 it would sound like a reference to the original alignment */
2160 ? (!final ? "currently " : "temporarily ")
2161 /* permanent conversion */
2162 : (u.ualign.type != u.ualignbase[A_ORIGINAL])
2163 /* and what's the past tense of "now"? certainly not "then"
2164 in a context like this...; "belatedly" == weren't that
2165 way sooner (in other words, didn't start that way) */
2166 ? (!final ? "now " : "belatedly ")
2167 /* atheist (ignored in very early game) */
2168 : (!u.uconduct.gnostic && moves > 1000L)
2170 /* lastly, normal case */
2174 Sprintf(buf, "
\82 \82È
\82½
\82Í%s
\82Å, %s%s
\82Ì
\82½
\82ß
\82Ì
\94C
\96±
\82ð
\8ds
\82Á
\82Ä%s
\81D",
2175 align_str(u.ualign.type),
2176 /* helm of opposite alignment (might hide conversion) */
2177 (u.ualign.type != u.ualignbase[A_CURRENT]) ? "
\88ê
\8e\9e\93I
\82É"
2178 /* permanent conversion */
2179 : (u.ualign.type != u.ualignbase[A_ORIGINAL]) ? "
\8c»
\8dÝ"
2180 /* atheist (ignored in very early game) */
2181 : (!u.uconduct.gnostic && moves > 1000L) ? "
\96¼
\8b`
\8fã"
2182 /* lastly, normal case */
2184 u_gname(), !final ? iru : ita);
2187 /* show the rest of this game's pantheon (finishes previous sentence)
2188 [appending "also Moloch" at the end would allow for straightforward
2189 trailing "and" on all three aligned entries but looks too verbose] */
2191 Sprintf(buf, " who %s opposed by", !final ? "is" : "was");
2193 Strcpy(buf, "
\82 \82È
\82½
\82Í");
2195 if (u.ualign.type != A_LAWFUL)
2197 Sprintf(eos(buf), " %s (%s) and", align_gname(A_LAWFUL),
2198 align_str(A_LAWFUL));
2200 Sprintf(eos(buf), "%s(%s)
\82¨
\82æ
\82Ñ", align_gname(A_LAWFUL),
2201 align_str(A_LAWFUL));
2203 if (u.ualign.type != A_NEUTRAL)
2205 Sprintf(eos(buf), " %s (%s)%s", align_gname(A_NEUTRAL),
2206 align_str(A_NEUTRAL),
2207 (u.ualign.type != A_CHAOTIC) ? " and" : "");
2209 Sprintf(eos(buf), "%s(%s)%s", align_gname(A_NEUTRAL),
2210 align_str(A_NEUTRAL),
2211 (u.ualign.type != A_CHAOTIC) ? "
\82¨
\82æ
\82Ñ" : "");
2213 if (u.ualign.type != A_CHAOTIC)
2215 Sprintf(eos(buf), " %s (%s)", align_gname(A_CHAOTIC),
2216 align_str(A_CHAOTIC));
2218 if (u.ualign.type != A_CHAOTIC)
2219 Sprintf(eos(buf), "%s(%s)", align_gname(A_CHAOTIC),
2220 align_str(A_CHAOTIC));
2223 Strcat(buf, "."); /* terminate sentence */
2225 Sprintf(eos(buf), "
\82Æ
\91Î
\97§
\82µ
\82Ä%s
\81D", !final ? iru : ita);
2229 /* show original alignment,gender,race,role if any have been changed;
2230 giving separate message for temporary alignment change bypasses need
2231 for tricky phrasing otherwise necessitated by possibility of having
2232 helm of opposite alignment mask a permanent alignment conversion */
2233 difgend = (innategend != flags.initgend);
2234 difalgn = (((u.ualign.type != u.ualignbase[A_CURRENT]) ? 1 : 0)
2235 + ((u.ualignbase[A_CURRENT] != u.ualignbase[A_ORIGINAL])
2237 if (difalgn & 1) { /* have temporary alignment so report permanent one */
2239 Sprintf(buf, "actually %s", align_str(u.ualignbase[A_CURRENT]));
2241 Sprintf(buf, "
\8eÀ
\8dÛ
\82É
\82Í%s", align_str(u.ualignbase[A_CURRENT]));
2245 enl_msg(buf, "
\82Ä
\82¢
\82é", "
\82Ä
\82¢
\82½", "", "");
2247 difalgn &= ~1; /* suppress helm from "started out <foo>" message */
2249 if (difgend || difalgn) { /* sex change or perm align change or both */
2251 Sprintf(buf, " You started out %s%s%s.",
2252 difgend ? genders[flags.initgend].adj : "",
2253 (difgend && difalgn) ? " and " : "",
2254 difalgn ? align_str(u.ualignbase[A_ORIGINAL]) : "");
2256 Sprintf(buf, "
\82 \82È
\82½
\82Í%s%s%s
\82Å
\8aJ
\8en
\82µ
\82½
\81D",
2257 difgend ? genders[flags.initgend].adj : "",
2258 (difgend && difalgn) ? "
\82©
\82Â" : "",
2259 difalgn ? align_str(u.ualignbase[A_ORIGINAL]) : "");
2264 /* As of 3.6.2: dungeon level, so that ^X really has all status info as
2265 claimed by the comment below; this reveals more information than
2266 the basic status display, but that's one of the purposes of ^X;
2267 similar information is revealed by #overview; the "You died in
2268 <location>" given by really_done() is more rudimentary than this */
2269 *buf = *tmpbuf = '\0';
2270 if (In_endgame(&u.uz)) {
2271 int egdepth = observable_depth(&u.uz);
2273 (void) endgamelevelname(tmpbuf, egdepth);
2275 Sprintf(buf, "in the endgame, on the %s%s",
2276 !strncmp(tmpbuf, "Plane", 5) ? "Elemental " : "", tmpbuf);
2278 Sprintf(buf, "
\8dÅ
\8fI
\8e\8e\97û
\82Ì%s", tmpbuf);
2280 } else if (Is_knox(&u.uz)) {
2281 /* this gives away the fact that the knox branch is only 1 level */
2283 Sprintf(buf, "on the %s level", dungeons[u.uz.dnum].dname);
2285 Sprintf(buf, "%s", dungeons[u.uz.dnum].dname);
2286 /* TODO? maybe phrase it differently when actually inside the fort,
2287 if we're able to determine that (not trivial) */
2289 char dgnbuf[QBUFSZ];
2291 Strcpy(dgnbuf, dungeons[u.uz.dnum].dname);
2293 if (!strncmpi(dgnbuf, "The ", 4))
2294 *dgnbuf = lowc(*dgnbuf);
2297 Sprintf(tmpbuf, "level %d",
2298 In_quest(&u.uz) ? dunlev(&u.uz) : depth(&u.uz));
2300 if (In_quest(&u.uz)) {
2301 Sprintf(tmpbuf, "
\91æ%d
\8aK
\91w", dunlev(&u.uz));
2303 Sprintf(tmpbuf, "
\92n
\89º%d
\8aK", depth(&u.uz));
2306 /* TODO? maybe extend this bit to include various other automatic
2307 annotations from the dungeon overview code */
2308 if (Is_rogue_level(&u.uz))
2310 Strcat(tmpbuf, ", a primitive area");
2312 Strcat(tmpbuf, ",
\92P
\8f\83\82È
\90¢
\8aE");
2313 else if (Is_bigroom(&u.uz) && !Blind)
2315 Strcat(tmpbuf, ", a very big room");
2317 Strcat(tmpbuf, ",
\82Æ
\82Ä
\82à
\91å
\82«
\82È
\95\94\89®");
2319 Sprintf(buf, "in %s, on %s", dgnbuf, tmpbuf);
2321 Sprintf(buf, "%s
\82Ì%s", dgnbuf, tmpbuf);
2326 /* this is shown even if the 'time' option is off */
2329 you_have("just started your adventure", "");
2331 enlght_line(You_, "", "
\96`
\8c¯
\82ð
\8aJ
\8en
\82µ
\82½
\82Æ
\82±
\82ë
\82¾", "");
2334 /* 'turns' grates on the nerves in this context... */
2336 Sprintf(buf, "the dungeon %ld turn%s ago", moves, plur(moves));
2338 Sprintf(buf, "%ld
\83^
\81[
\83\93\91O
\82É
\96À
\8b{
\82É
\93ü
\82Á
\82½", moves);
2339 /* same phrasing for current and final: "entered" is unconditional */
2341 enlght_line(You_, "entered ", buf, "");
2343 enlght_line(You_, "", buf, "");
2347 /* for gameover, these have been obtained in really_done() so that they
2348 won't vary if user leaves a disclosure prompt or --More-- unanswered
2349 long enough for the dynamic value to change between then and now */
2350 if (final ? iflags.at_midnight : midnight()) {
2352 enl_msg("It ", "is ", "was ", "the midnight hour", "");
2354 enl_msg("
\8e\9e\8aÔ
\91Ñ
\82Í
\90[
\96é", "
\82¾", "
\82¾
\82Á
\82½", "", "");
2356 } else if (final ? iflags.at_night : night()) {
2358 enl_msg("It ", "is ", "was ", "nighttime", "");
2360 enl_msg("
\8e\9e\8aÔ
\91Ñ
\82Í
\96é", "
\82¾", "
\82¾
\82Á
\82½", "", "");
2363 /* other environmental factors */
2364 if (flags.moonphase == FULL_MOON || flags.moonphase == NEW_MOON) {
2365 /* [This had "tonight" but has been changed to "in effect".
2366 There is a similar issue to Friday the 13th--it's the value
2367 at the start of the current session but that session might
2368 have dragged on for an arbitrary amount of time. We want to
2369 report the values that currently affect play--or affected
2370 play when game ended--rather than actual outside situation.] */
2372 Sprintf(buf, "a %s moon in effect%s",
2373 (flags.moonphase == FULL_MOON) ? "full"
2374 : (flags.moonphase == NEW_MOON) ? "new"
2375 /* showing these would probably just lead to confusion
2376 since they have no effect on game play... */
2377 : (flags.moonphase < FULL_MOON) ? "first quarter"
2379 /* we don't have access to 'how' here--aside from survived
2380 vs died--so settle for general platitude */
2381 final ? " when your adventure ended" : "");
2382 enl_msg("There ", "is ", "was ", buf, "");
2384 Sprintf(buf, "%s%s
\8c\8e",
2385 /* we don't have access to 'how' here--aside from survived
2386 vs died--so settle for general platitude */
2387 final ? "
\96`
\8c¯
\82ð
\8fI
\82¦
\82½
\82Æ
\82«
\81C" : "",
2388 (flags.moonphase == FULL_MOON) ? "
\96\9e"
2389 : (flags.moonphase == NEW_MOON) ? "
\90V"
2390 /* showing these would probably just lead to confusion
2391 since they have no effect on game play... */
2392 : (flags.moonphase < FULL_MOON) ? "
\8fã
\8c·
\82Ì"
2394 enl_msg("", "
\82¾", "
\82¾
\82Á
\82½", buf, "");
2397 if (flags.friday13) {
2398 /* let player know that friday13 penalty is/was in effect;
2399 we don't say "it is/was Friday the 13th" because that was at
2400 the start of the session and it might be past midnight (or
2401 days later if the game has been paused without save/restore),
2402 so phrase this similar to the start up message */
2404 Sprintf(buf, " Bad things %s on Friday the 13th.",
2405 !final ? "can happen"
2406 : (final == ENL_GAMEOVERALIVE) ? "could have happened"
2407 /* there's no may to tell whether -1 Luck made a
2408 difference but hero has died... */
2411 Sprintf(buf, "
\82P
\82R
\93ú
\82Ì
\8bà
\97j
\93ú
\82É
\82Í
\82æ
\82
\82È
\82¢
\82±
\82Æ
\82ª%s
\81D",
2413 : (final == ENL_GAMEOVERALIVE) ? "
\82 \82Á
\82½
\82©
\82à
\82µ
\82ê
\82È
\82¢"
2414 /* there's no may to tell whether -1 Luck made a
2415 difference but hero has died... */
2422 int ulvl = (int) u.ulevel;
2423 /* [flags.showexp currently does not matter; should it?] */
2425 /* experience level is already shown above */
2427 Sprintf(buf, "%-1ld experience point%s", u.uexp, plur(u.uexp));
2429 Sprintf(buf, "
\8co
\8c±
\92l%-1ld
\83|
\83C
\83\93\83g", u.uexp);
2432 * Remove wizard-mode restriction since patient players can
2433 * determine the numbers needed without resorting to spoilers
2434 * (even before this started being disclosed for 'final';
2435 * just enable 'showexp' and look at normal status lines
2436 * after drinking gain level potions or eating wraith corpses
2437 * or being level-drained by vampires).
2439 if (ulvl < 30 && (final || wizard)) {
2440 long nxtlvl = newuexp(ulvl), delta = nxtlvl - u.uexp;
2443 Sprintf(eos(buf), ", %ld %s%sneeded %s level %d",
2444 delta, (u.uexp > 0) ? "more " : "",
2445 /* present tense=="needed", past tense=="were needed" */
2446 !final ? "" : (delta == 1L) ? "was " : "were ",
2447 /* "for": grammatically iffy but less likely to wrap */
2448 (ulvl < 18) ? "to attain" : "for", (ulvl + 1));
2450 Sprintf(eos(buf), "(
\83\8c\83x
\83\8b%d
\82Ü
\82Å%ld
\83|
\83C
\83\93\83g)",
2456 #ifdef SCORE_ON_BOTL
2457 if (flags.showscore) {
2458 /* describes what's shown on status line, which is an approximation;
2459 only show it here if player has the 'showscore' option enabled */
2461 Sprintf(buf, "%ld%s", botl_score(),
2462 !final ? "" : " before end-of-game adjustments");
2463 enl_msg("Your score ", "is ", "was ", buf, "");
2465 Sprintf(buf, "%s%ld", botl_score(),
2466 !final ? "" : "
\83Q
\81[
\83\80\8fI
\97¹
\8e\9e\82Ì
\92²
\90®
\91O
\82Í");
2467 enl_msg("
\82 \82È
\82½
\82Ì
\83X
\83R
\83A
\82Í", "
\82Å
\82 \82é", "
\82Å
\82 \82Á
\82½", buf, "");
2473 /* hit points, energy points, armor class -- essential information which
2474 doesn't fit very well in other categories */
2477 basics_enlightenment(mode, final)
2481 #if 0 /*JP*//*unused*/
2482 static char Power[] = "energy points (spell power)";
2485 int pw = u.uen, hp = (Upolyd ? u.mh : u.uhp),
2486 pwmax = u.uenmax, hpmax = (Upolyd ? u.mhmax : u.uhpmax);
2488 enlght_out(""); /* separator after background */
2490 enlght_out("Basics:");
2492 enlght_out("
\8aî
\96{:");
2496 /* "1 out of 1" rather than "all" if max is only 1; should never happen */
2498 if (hp == hpmax && hpmax > 1)
2499 Sprintf(buf, "all %d hit points", hpmax);
2501 Sprintf(buf, "%d out of %d hit point%s", hp, hpmax, plur(hpmax));
2503 Sprintf(buf, "%d
\83q
\83b
\83g
\83|
\83C
\83\93\83g(
\8dÅ
\91å:%d)", hp, hpmax);
2507 /* low max energy is feasible, so handle couple of extra special cases */
2509 if (pwmax == 0 || (pw == pwmax && pwmax == 2)) /* both: "all 2" is silly */
2510 Sprintf(buf, "%s %s", !pwmax ? "no" : "both", Power);
2511 else if (pw == pwmax && pwmax > 2)
2512 Sprintf(buf, "all %d %s", pwmax, Power);
2514 Sprintf(buf, "%d out of %d %s", pw, pwmax, Power);
2516 Sprintf(buf, "%d
\96\82\97Í
\83|
\83C
\83\93\83g(
\8dÅ
\91å:%d)", pw, pwmax);
2521 switch (mons[u.umonnum].mlevel) {
2523 /* status line currently being explained shows "HD:0" */
2525 Strcpy(buf, "0 hit dice (actually 1/2)");
2527 Strcpy(buf, "HD0(
\8eÀ
\8dÛ
\82É
\82Í1/2)");
2531 Strcpy(buf, "1 hit die");
2537 Sprintf(buf, "%d hit dice", mons[u.umonnum].mlevel);
2539 Sprintf(buf, "HD%d", mons[u.umonnum].mlevel);
2545 Sprintf(buf, "%d", u.uac);
2547 enl_msg("Your armor class ", "is ", "was ", buf, "");
2549 enl_msg("
\82 \82È
\82½
\82Ì
\96h
\8cä
\92l
\82Í", "
\82Å
\82 \82é", "
\82Å
\82 \82Á
\82½", buf, "");
2551 /* gold; similar to doprgold(#seegold) but without shop billing info;
2552 same amount as shown on status line which ignores container contents */
2555 static const char Your_wallet[] = "Your wallet ";
2557 static const char Your_wallet[] = "
\82 \82È
\82½
\82Ì
\8dà
\95z";
2558 long umoney = money_cnt(invent);
2562 enl_msg(Your_wallet, "is ", "was ", "empty", "");
2564 enl_msg(Your_wallet, "
\82Å
\82 \82é", "
\82¾
\82Á
\82½", "
\82Í
\8bó", "");
2567 Sprintf(buf, "%ld %s", umoney, currency(umoney));
2568 enl_msg(Your_wallet, "contains ", "contained ", buf, "");
2570 Sprintf(buf, "
\82É
\82Í%ld%s", umoney, currency(umoney));
2571 enl_msg(Your_wallet, "
\93ü
\82Á
\82Ä
\82¢
\82é", "
\93ü
\82Á
\82Ä
\82¢
\82½", buf, "");
2577 char ocl[MAXOCLASSES + 1];
2579 #if 0 /*JP*//*
\8cã
\82É
\89ñ
\82·*/
2582 oc_to_str(flags.pickup_types, ocl);
2584 Sprintf(eos(buf), " for %s%s%s",
2585 *ocl ? "'" : "", *ocl ? ocl : "all types", *ocl ? "'" : "");
2587 Sprintf(buf, "%s%s%s",
2588 *ocl ? "'" : "", *ocl ? ocl : "
\91S
\82Ä
\82Ì
\8eí
\97Þ", *ocl ? "'" : "");
2590 if (flags.pickup_thrown && *ocl) /* *ocl: don't show if 'all types' */
2592 Strcat(buf, " plus thrown");
2594 Strcat(buf, "
\82É
\89Á
\82¦
\82Ä
\93\8a\82°
\82é
\82à
\82Ì");
2597 Strcat(buf, ", with exceptions");
2599 Strcat(buf, "(
\97á
\8aO
\82 \82è)");
2601 Strcpy(buf, "
\82É
\91Î
\82µ
\82Ä
\83I
\83\93");
2607 Strcpy(buf, "
\83I
\83t");
2609 enl_msg("Autopickup ", "is ", "was ", buf, "");
2611 enl_msg("
\8e©
\93®
\8fE
\82¢
\90Ý
\92è
\82Í", "
\82Å
\82 \82é", "
\82Å
\82 \82Á
\82½", buf, "");
2614 /* characteristics: expanded version of bottom line strength, dexterity, &c */
2616 characteristics_enlightenment(mode, final)
2624 Sprintf(buf, "%s Characteristics:", !final ? "Current" : "Final");
2626 Sprintf(buf, "%s
\93Á
\90«
\81F", !final ? "
\8c»
\8dÝ
\82Ì" : "
\8dÅ
\8fI");
2629 /* bottom line order */
2630 one_characteristic(mode, final, A_STR); /* strength */
2631 one_characteristic(mode, final, A_DEX); /* dexterity */
2632 one_characteristic(mode, final, A_CON); /* constitution */
2633 one_characteristic(mode, final, A_INT); /* intelligence */
2634 one_characteristic(mode, final, A_WIS); /* wisdom */
2635 one_characteristic(mode, final, A_CHA); /* charisma */
2638 /* display one attribute value for characteristics_enlightenment() */
2640 one_characteristic(mode, final, attrindx)
2641 int mode, final, attrindx;
2643 extern const char *const attrname[]; /* attrib.c */
2644 boolean hide_innate_value = FALSE, interesting_alimit;
2645 int acurrent, abase, apeak, alimit;
2646 const char *paren_pfx;
2647 char subjbuf[BUFSZ], valubuf[BUFSZ], valstring[32];
2649 /* being polymorphed or wearing certain cursed items prevents
2650 hero from reliably tracking changes to characteristics so
2651 we don't show base & peak values then; when the items aren't
2652 cursed, hero could take them off to check underlying values
2653 and we show those in such case so that player doesn't need
2654 to actually resort to doing that */
2656 hide_innate_value = TRUE;
2657 } else if (Fixed_abil) {
2658 if (stuck_ring(uleft, RIN_SUSTAIN_ABILITY)
2659 || stuck_ring(uright, RIN_SUSTAIN_ABILITY))
2660 hide_innate_value = TRUE;
2664 if (uarmg && uarmg->otyp == GAUNTLETS_OF_POWER && uarmg->cursed)
2665 hide_innate_value = TRUE;
2670 if (uwep && uwep->oartifact == ART_OGRESMASHER && uwep->cursed)
2671 hide_innate_value = TRUE;
2674 if (uarmh && uarmh->otyp == DUNCE_CAP && uarmh->cursed)
2675 hide_innate_value = TRUE;
2678 if (uarmh && uarmh->otyp == DUNCE_CAP && uarmh->cursed)
2679 hide_innate_value = TRUE;
2684 return; /* impossible */
2686 /* note: final disclosure includes MAGICENLIGHTENTMENT */
2687 if ((mode & MAGICENLIGHTENMENT) && !Upolyd)
2688 hide_innate_value = FALSE;
2690 acurrent = ACURR(attrindx);
2691 (void) attrval(attrindx, acurrent, valubuf); /* Sprintf(valubuf,"%d",) */
2693 Sprintf(subjbuf, "Your %s ", attrname[attrindx]);
2695 Sprintf(subjbuf, "
\82 \82È
\82½
\82Ì%s
\82Í", attrname[attrindx]);
2697 if (!hide_innate_value) {
2698 /* show abase, amax, and/or attrmax if acurr doesn't match abase
2699 (a magic bonus or penalty is in effect) or abase doesn't match
2700 amax (some points have been lost to poison or exercise abuse
2701 and are restorable) or attrmax is different from normal human
2702 (while game is in progress; trying to reduce dependency on
2703 spoilers to keep track of such stuff) or attrmax was different
2704 from abase (at end of game; this attribute wasn't maxed out) */
2705 abase = ABASE(attrindx);
2706 apeak = AMAX(attrindx);
2707 alimit = ATTRMAX(attrindx);
2708 /* criterium for whether the limit is interesting varies */
2709 interesting_alimit =
2710 final ? TRUE /* was originally `(abase != alimit)' */
2711 : (alimit != (attrindx != A_STR ? 18 : STR18(100)));
2713 paren_pfx = final ? " (" : " (current; ";
2715 paren_pfx = final ? " (" : " (
\8c»
\8dÝ; ";
2716 if (acurrent != abase) {
2718 Sprintf(eos(valubuf), "%sbase:%s", paren_pfx,
2719 attrval(attrindx, abase, valstring));
2721 Sprintf(eos(valubuf), "%s
\8aî
\96{:%s", paren_pfx,
2722 attrval(attrindx, abase, valstring));
2726 if (abase != apeak) {
2728 Sprintf(eos(valubuf), "%speak:%s", paren_pfx,
2729 attrval(attrindx, apeak, valstring));
2731 Sprintf(eos(valubuf), "%s
\8dÅ
\91å:%s", paren_pfx,
2732 attrval(attrindx, apeak, valstring));
2736 if (interesting_alimit) {
2738 Sprintf(eos(valubuf), "%s%slimit:%s", paren_pfx,
2739 /* more verbose if exceeding 'limit' due to magic bonus */
2740 (acurrent > alimit) ? "innate " : "",
2741 attrval(attrindx, alimit, valstring));
2743 Sprintf(eos(valubuf), "%s%s
\8fã
\8cÀ:%s", paren_pfx,
2744 /* more verbose if exceeding 'limit' due to magic bonus */
2745 (acurrent > alimit) ? "
\96{
\97\88\82Ì" : "",
2746 attrval(attrindx, alimit, valstring));
2748 /* paren_pfx = ", "; */
2750 if (acurrent != abase || abase != apeak || interesting_alimit)
2751 Strcat(valubuf, ")");
2754 enl_msg(subjbuf, "is ", "was ", valubuf, "");
2756 enl_msg(subjbuf, "
\82¾", "
\82¾
\82Á
\82½", valubuf, "");
2759 /* status: selected obvious capabilities, assorted troubles */
2761 status_enlightenment(mode, final)
2765 boolean magic = (mode & MAGICENLIGHTENMENT) ? TRUE : FALSE;
2767 char buf[BUFSZ], youtoo[BUFSZ];
2768 boolean Riding = (u.usteed
2769 /* if hero dies while dismounting, u.usteed will still
2770 be set; we want to ignore steed in that situation */
2771 && !(final == ENL_GAMEOVERDEAD
2773 && !strcmp(killer.name, "riding accident")));
2775 && !strcmp(killer.name, "
\8bR
\8fæ
\8e\96\8cÌ
\82Å")));
2776 const char *steedname = (!Riding ? (char *) 0
2777 : x_monnam(u.usteed,
2778 u.usteed->mtame ? ARTICLE_YOUR : ARTICLE_THE,
2780 (SUPPRESS_SADDLE | SUPPRESS_HALLUCINATION),
2784 * Status (many are abbreviated on bottom line; others are or
2785 * should be discernible to the hero hence to the player)
2787 enlght_out(""); /* separator after title or characteristics */
2789 enlght_out(final ? "Final Status:" : "Current Status:");
2791 enlght_out(final ? "
\8dÅ
\8fI
\8fó
\91Ô:" : "
\8c»
\8dÝ
\82Ì
\8fó
\91Ô:");
2793 Strcpy(youtoo, You_);
2794 /* not a traditional status but inherently obvious to player; more
2795 detail given below (attributes section) for magic enlightenment */
2798 Strcpy(buf, "transformed");
2800 Sprintf(eos(buf), " and %s %s inside",
2801 final ? "felt" : "feel", udeadinside());
2803 #else /*JP:TODO:
\95Ï
\89»+
\8bs
\8eE
\83p
\83^
\81[
\83\93*/
2804 you_are_ing("
\95Ï
\89»
\82µ
\82Ä", "");
2807 /* not a trouble, but we want to display riding status before maybe
2808 reporting steed as trapped or hero stuck to cursed saddle */
2811 Sprintf(buf, "riding %s", steedname);
2814 Sprintf(buf, "%s
\82É
\8fæ
\82Á
\82Ä", steedname);
2815 you_are_ing(buf, "");
2818 Sprintf(eos(youtoo), "and %s ", steedname);
2820 Sprintf(youtoo, "
\82 \82È
\82½
\82Æ%s
\82Í", steedname);
2822 /* other movement situations that hero should always know */
2824 if (Lev_at_will && magic)
2826 you_are("levitating, at will", "");
2828 you_are_ing("
\8e©
\95ª
\82Ì
\88Ó
\8eu
\82Å
\95\82\97V
\82µ
\82Ä", "");
2831 enl_msg(youtoo, are, were, "levitating", from_what(LEVITATION));
2833 enl_msg(youtoo, "
\82¢
\82é", "
\82¢
\82½", "
\95\82\97V
\82µ
\82Ä", from_what(LEVITATION));
2834 } else if (Flying) { /* can only fly when not levitating */
2836 enl_msg(youtoo, are, were, "flying", from_what(FLYING));
2838 enl_msg(youtoo, "
\82¢
\82é", "
\82¢
\82½", "
\94ò
\82ñ
\82Å", from_what(FLYING));
2842 you_are("underwater", "");
2844 enl_msg(You_, "
\82¢
\82é", "
\82¢
\82½", "
\90\85\96Ê
\89º
\82É", "");
2845 } else if (u.uinwater) {
2847 you_are(Swimming ? "swimming" : "in water", from_what(SWIMMING));
2849 enl_msg(You_, Swimming ? "
\89j
\82¢
\82Å" : "
\90\85\92\86\82É", "
\82¢
\82é", "
\82¢
\82½", from_what(SWIMMING));
2850 } else if (walking_on_water()) {
2851 /* show active Wwalking here, potential Wwalking elsewhere */
2853 Sprintf(buf, "walking on %s",
2854 is_pool(u.ux, u.uy) ? "water"
2855 : is_lava(u.ux, u.uy) ? "lava"
2856 : surface(u.ux, u.uy)); /* catchall; shouldn't happen */
2857 you_are(buf, from_what(WWALKING));
2859 Sprintf(buf, "%s
\82Ì
\8fã
\82ð
\95à
\82¢
\82Ä",
2860 is_pool(u.ux, u.uy) ? "
\90\85"
2861 : is_lava(u.ux, u.uy) ? "
\97n
\8aâ"
2862 : surface(u.ux, u.uy)); /* catchall; shouldn't happen */
2863 you_are_ing(buf, from_what(WWALKING));
2866 if (Upolyd && (u.uundetected || U_AP_TYPE != M_AP_NOTHING))
2867 youhiding(TRUE, final);
2869 /* internal troubles, mostly in the order that prayer ranks them */
2871 if (final && (Stoned & I_SPECIAL))
2873 enlght_out(" You turned into stone.");
2875 enlght_out("
\82 \82È
\82½
\82Í
\90Î
\82É
\82È
\82Á
\82½
\81D");
2878 you_are("turning to stone", "");
2880 enl_msg("
\82 \82È
\82½
\82Í", "
\82È
\82è
\82Â
\82Â
\82 \82é", "
\82È
\82Á
\82½", "
\90Î
\82É", "");
2883 if (final && (Slimed & I_SPECIAL))
2885 enlght_out(" You turned into slime.");
2887 enlght_out("
\82 \82È
\82½
\82Í
\83X
\83\89\83C
\83\80\82É
\82È
\82Á
\82½
\81D");
2890 you_are("turning into slime", "");
2892 enl_msg("
\82 \82È
\82½
\82Í", "
\82È
\82è
\82Â
\82Â
\82 \82é", "
\82È
\82Á
\82½", "
\83X
\83\89\83C
\83\80\82É", "");
2897 you_are("buried", "");
2899 you_are_ing("
\92\82\91§
\82µ
\82Ä", "");
2901 if (final && (Strangled & I_SPECIAL)) {
2903 enlght_out(" You died from strangulation.");
2905 enlght_out("
\82 \82È
\82½
\82Í
\92\82\91§
\8e\80\82µ
\82½
\81D");
2908 Strcpy(buf, "being strangled");
2910 Strcpy(buf, "
\8eñ
\82ð
\8di
\82ß
\82ç
\82ê
\82Ä");
2912 Sprintf(eos(buf), " (%ld)", (Strangled & TIMEOUT));
2914 you_are(buf, from_what(STRANGLED));
2916 enl_msg("
\82 \82È
\82½
\82Í", "
\82¢
\82é", "
\82¢
\82½", buf, from_what(STRANGLED));
2921 /* the two types of sickness are lumped together; hero can be
2922 afflicted by both but there is only one timeout; botl status
2923 puts TermIll before FoodPois and death due to timeout reports
2924 terminal illness if both are in effect, so do the same here */
2925 if (final && (Sick & I_SPECIAL)) {
2927 Sprintf(buf, " %sdied from %s.", You_, /* has trailing space */
2928 (u.usick_type & SICK_NONVOMITABLE)
2929 ? "terminal illness" : "food poisoning");
2931 Sprintf(buf, " %s%s
\82Å
\8e\80\82ñ
\82¾
\81D", You_, /* has trailing space */
2932 (u.usick_type & SICK_NONVOMITABLE)
2933 ? "
\95a
\8bC" : "
\90H
\92\86\93Å");
2937 /* unlike death due to sickness, report the two cases separately
2938 because it is possible to cure one without curing the other */
2939 if (u.usick_type & SICK_NONVOMITABLE)
2941 you_are("terminally sick from illness", "");
2943 enl_msg("
\82 \82È
\82½
\82Í
\95a
\8bC
\82Å
\92v
\96½
\93I
\82É
\8bC
\95ª
\82ª
\88«", "
\82¢", "
\82©
\82Á
\82½", "", "");
2944 if (u.usick_type & SICK_VOMITABLE)
2946 you_are("terminally sick from food poisoning", "");
2948 enl_msg("
\82 \82È
\82½
\82Í
\90H
\92\86\93Å
\82Å
\92v
\96½
\93I
\82É
\8bC
\95ª
\82ª
\88«", "
\82¢", "
\82©
\82Á
\82½", "", "");
2953 you_are("nauseated", "");
2955 enl_msg(You_, "
\93f
\82«
\8bC
\82ª", "
\82 \82é", "
\82 \82Á
\82½", "");
2958 you_are("stunned", "");
2960 you_are("
\82
\82ç
\82
\82ç
\8fó
\91Ô", "");
2963 you_are("confused", "");
2965 you_are("
\8d¬
\97\90\8fó
\91Ô", "");
2968 you_are("hallucinating", "");
2970 you_are("
\8c¶
\8ao
\8fó
\91Ô", "");
2972 /* from_what() (currently wizard-mode only) checks !haseyes()
2973 before u.uroleplay.blind, so we should too */
2975 Sprintf(buf, "%s blind",
2976 !haseyes(youmonst.data) ? "innately"
2977 : u.uroleplay.blind ? "permanently"
2978 /* better phrasing desperately wanted... */
2979 : Blindfolded_only ? "deliberately"
2982 Sprintf(buf, "%s
\96Ó
\96Ú",
2983 !haseyes(youmonst.data) ? "
\90¶
\82Ü
\82ê
\82È
\82ª
\82ç
\82É"
2984 : u.uroleplay.blind ? "
\8dP
\8bv
\93I
\82É"
2985 /* better phrasing desperately wanted... */
2986 : Blindfolded_only ? "
\8cÌ
\88Ó
\82É"
2987 : "
\88ê
\8e\9e\93I
\82É");
2989 if (wizard && (Blinded & TIMEOUT) != 0L
2990 && !u.uroleplay.blind && haseyes(youmonst.data))
2991 Sprintf(eos(buf), " (%ld)", (Blinded & TIMEOUT));
2992 /* !haseyes: avoid "you are innately blind innately" */
2993 you_are(buf, !haseyes(youmonst.data) ? "" : from_what(BLINDED));
2997 you_are("deaf", from_what(DEAF));
2999 you_are("
\8e¨
\82ª
\95·
\82±
\82¦
\82È
\82¢
\8fó
\91Ô", from_what(DEAF));
3001 /* external troubles, more or less */
3005 Sprintf(buf, "chained to %s", ansimpleoname(uball));
3007 Sprintf(buf, "%s
\82É
\82Â
\82È
\82ª
\82ê
\82Ä", ansimpleoname(uball));
3009 impossible("Punished without uball?");
3011 Strcpy(buf, "punished");
3013 Strcpy(buf, "
\94±
\82ð
\8eó
\82¯
\82Ä");
3018 char predicament[BUFSZ];
3020 boolean anchored = (u.utraptype == TT_BURIEDBALL);
3024 Strcpy(predicament, "tethered to something buried");
3026 Strcpy(predicament, "
\89½
\82©
\96\84\82Ü
\82Á
\82Ä
\82¢
\82é
\82à
\82Ì
\82É
\82Â
\82È
\82ª
\82ê
\82Ä");
3027 } else if (u.utraptype == TT_INFLOOR || u.utraptype == TT_LAVA) {
3029 Sprintf(predicament, "stuck in %s", the(surface(u.ux, u.uy)));
3031 Sprintf(predicament, "%s
\82É
\96\84\82Ü
\82Á
\82Ä", surface(u.ux, u.uy));
3034 Strcpy(predicament, "trapped");
3035 if ((t = t_at(u.ux, u.uy)) != 0)
3036 Sprintf(eos(predicament), " in %s",
3037 an(defsyms[trap_to_defsym(t->ttyp)].explanation));
3039 predicament[0] = '\0';
3040 if ((t = t_at(u.ux, u.uy)) != 0)
3041 Sprintf(predicament, "%s
\82É",
3042 defsyms[trap_to_defsym(t->ttyp)].explanation);
3043 Strcat(predicament, "
\82Ð
\82Á
\82©
\82©
\82Á
\82Ä");
3046 if (u.usteed) { /* not `Riding' here */
3048 Sprintf(buf, "%s%s ", anchored ? "you and " : "", steedname);
3050 enl_msg(buf, (anchored ? "are " : "is "),
3051 (anchored ? "were " : "was "), predicament, "");
3053 Sprintf(buf, "%s%s
\82Í", anchored ? "
\82 \82È
\82½
\82Æ" : "", steedname);
3054 enl_msg(buf, "
\82¢
\82é", "
\82¢
\82½" , predicament, "");
3057 you_are(predicament, "");
3061 Sprintf(buf, "swallowed by %s", a_monnam(u.ustuck));
3063 Sprintf(buf, "%s
\82É
\88ù
\82Ý
\8d\9e\82Ü
\82ê
\82Ä", a_monnam(u.ustuck));
3065 Sprintf(eos(buf), " (%u)", u.uswldtim);
3067 } else if (u.ustuck) {
3069 Sprintf(buf, "%s %s",
3070 (Upolyd && sticks(youmonst.data)) ? "holding" : "held by",
3071 a_monnam(u.ustuck));
3074 Sprintf(buf, "%s%s",
3076 (Upolyd && sticks(youmonst.data)) ? "
\82ð
\95ß
\82Ü
\82¦
\82Ä" : "
\82É
\95ß
\82Ü
\82Á
\82Ä");
3077 you_are_ing(buf, "");
3081 struct obj *saddle = which_armor(u.usteed, W_SADDLE);
3083 if (saddle && saddle->cursed) {
3085 Sprintf(buf, "stuck to %s %s", s_suffix(steedname),
3086 simpleonames(saddle));
3089 Sprintf(buf, "%s
\82Ì%s
\82É
\82Â
\82©
\82Ü
\82Á
\82Ä", steedname,
3090 simpleonames(saddle));
3091 you_are_ing(buf, "");
3096 /* when mounted, Wounded_legs applies to steed rather than to
3097 hero; we only report steed's wounded legs in wizard mode */
3098 if (u.usteed) { /* not `Riding' here */
3099 if (wizard && steedname) {
3101 Strcpy(buf, steedname);
3103 enl_msg(buf, " has", " had", " wounded legs", "");
3105 enl_msg(buf, iru, ita, "
\82Í
\8e\88\82ð
\89ö
\89ä
\82µ
\82Ä", "");
3110 Sprintf(buf, "wounded %s", makeplural(body_part(LEG)));
3113 Sprintf(buf, "%s
\82ð
\89ö
\89ä
\82µ
\82Ä", makeplural(body_part(LEG)));
3114 you_are_ing(buf, "");
3120 Sprintf(buf, "slippery %s", fingers_or_gloves(TRUE));
3122 Sprintf(eos(buf), " (%ld)", (Glib & TIMEOUT));
3125 Sprintf(buf, "%s
\82ª
\82Ê
\82é
\82Ê
\82é
\82µ
\82Ä", body_part(FINGER));
3127 Sprintf(eos(buf), " (%ld)", (Glib & TIMEOUT));
3128 enl_msg(buf, iru, ita, "", "");
3132 if (magic || cause_known(FUMBLING))
3134 enl_msg(You_, "fumble", "fumbled", "", from_what(FUMBLING));
3136 you_are_ing("
\95s
\8aí
\97p
\82É
\82È
\82Á
\82Ä", from_what(FUMBLING));
3139 if (magic || cause_known(SLEEPY)) {
3140 Strcpy(buf, from_what(SLEEPY));
3142 Sprintf(eos(buf), " (%ld)", (HSleepy & TIMEOUT));
3144 enl_msg("You ", "fall", "fell", " asleep uncontrollably", buf);
3146 you_are_ing("
\96°
\82Á
\82Ä", buf);
3149 /* hunger/nutrition */
3151 if (magic || cause_known(HUNGER))
3153 enl_msg(You_, "hunger", "hungered", " rapidly",
3156 enl_msg("
\82 \82È
\82½
\82Í
\82·
\82®
\82É
\95 \82ª
\8c¸
\82é
\8fó
\91Ô", "
\82Å
\82 \82é", "
\82¾
\82Á
\82½", "", "");
3159 Strcpy(buf, hu_stat[u.uhs]); /* hunger status; omitted if "normal" */
3160 mungspaces(buf); /* strip trailing spaces */
3163 *buf = lowc(*buf); /* override capitalization */
3164 if (!strcmp(buf, "weak"))
3165 Strcat(buf, " from severe hunger");
3166 else if (!strncmp(buf, "faint", 5)) /* fainting, fainted */
3167 Strcat(buf, " due to starvation");
3170 Strcat(buf, "
\8fó
\91Ô");
3175 if ((cap = near_capacity()) > UNENCUMBERED) {
3177 const char *adj = "?_?"; /* (should always get overridden) */
3179 Strcpy(buf, enc_stat[cap]);
3184 break; /* burdened */
3187 break; /* stressed */
3190 break; /* strained */
3193 break; /* overtaxed */
3195 adj = "not possible";
3198 Sprintf(eos(buf), "; movement %s %s%s", !final ? "is" : "was", adj,
3199 (cap < OVERLOADED) ? " slowed" : "");
3202 Sprintf(buf, "
\89×
\95¨
\82É
\82æ
\82Á
\82Ä%s
\8fó
\91Ô", enc_stat[cap]);
3206 /* last resort entry, guarantees Status section is non-empty
3207 (no longer needed for that purpose since weapon status added;
3208 still useful though) */
3210 you_are("unencumbered", "");
3212 you_are("
\89×
\95¨
\82Í
\8e×
\96\82\82É
\82È
\82ç
\82È
\82¢
\8fó
\91Ô", "");
3215 /* report being weaponless; distinguish whether gloves are worn */
3218 you_are(uarmg ? "empty handed" /* gloves imply hands */
3219 : humanoid(youmonst.data)
3220 /* hands but no weapon and no gloves */
3222 /* alternate phrasing for paws or lack of hands */
3223 : "not wielding anything",
3226 enl_msg(You_, "
\82¢", "
\82©
\82Á
\82½", "
\95\90\8aí
\82ð
\91\95\94õ
\82µ
\82Ä
\82¢
\82È", "");
3228 /* two-weaponing implies hands (can't be polymorphed) and
3229 a weapon or wep-tool (not other odd stuff) in each hand */
3230 } else if (u.twoweap) {
3232 you_are("wielding two weapons at once", "");
3234 you_are("
\93ñ
\93\81\97¬", "");
3235 /* report most weapons by their skill class (so a katana will be
3236 described as a long sword, for instance; mattock and hook are
3237 exceptions), or wielded non-weapon item by its object class */
3239 const char *what = weapon_descr(uwep);
3242 if (!strcmpi(what, "armor") || !strcmpi(what, "food")
3243 || !strcmpi(what, "venom"))
3244 Sprintf(buf, "wielding some %s", what);
3246 Sprintf(buf, "wielding %s",
3247 (uwep->quan == 1L) ? an(what) : makeplural(what));
3250 Sprintf(buf, "%s
\82ð
\91\95\94õ
\82µ
\82Ä", what);
3251 enl_msg(You_, "
\82¢
\82é", "
\82¢
\82½", buf, "");
3255 * Skill with current weapon. Might help players who've never
3256 * noticed #enhance or decided that it was pointless.
3258 * TODO? Maybe merge wielding line and skill line into one sentence.
3260 if ((wtype = uwep_skill_type()) != P_NONE) {
3262 int sklvl = P_SKILL(wtype);
3263 boolean hav = (sklvl != P_UNSKILLED && sklvl != P_SKILLED);
3265 if (sklvl == P_ISRESTRICTED)
3267 Strcpy(sklvlbuf, "no");
3269 Strcpy(sklvlbuf, "
\90§
\8cÀ");
3271 (void) lcase(skill_level_name(wtype, sklvlbuf));
3272 /* "you have no/basic/expert/master/grand-master skill with <skill>"
3273 or "you are unskilled/skilled in <skill>" */
3275 Sprintf(buf, "%s %s %s", sklvlbuf,
3276 hav ? "skill with" : "in", skill_name(wtype));
3278 Sprintf(buf, "%s
\82Ì%s
\83X
\83L
\83\8b", skill_name(wtype), sklvlbuf);
3280 if (can_advance(wtype, FALSE))
3282 Sprintf(eos(buf), " and %s that",
3283 !final ? "can enhance" : "could have enhanced");
3285 Sprintf(eos(buf), "(
\8d\82\82ß
\82é
\82±
\82Æ
\82ª
\82Å
\82«%s)",
3286 !final ? "
\82é" : "
\82½");
3293 /* report 'nudity' */
3294 if (!uarm && !uarmu && !uarmc && !uarms && !uarmg && !uarmf && !uarmh) {
3295 if (u.uroleplay.nudist)
3297 enl_msg(You_, "do", "did", " not wear any armor", "");
3299 enl_msg(You_, "
\82¢", "
\82©
\82Á
\82½", "
\89½
\82Ì
\8aZ
\82à
\91\95\94õ
\82µ
\82È", "");
3303 you_are("not wearing any armor", "");
3305 enl_msg(You_, "
\82¢", "
\82©
\82Á
\82½", "
\89½
\82Ì
\8aZ
\82à
\91\95\94õ
\82µ
\82Ä
\82¢
\82È", "");
3310 /* attributes: intrinsics and the like, other non-obvious capabilities */
3312 attributes_enlightenment(unused_mode, final)
3313 int unused_mode UNUSED;
3317 static NEARDATA const char if_surroundings_permitted[] =
3318 " if surroundings permitted";
3328 enlght_out(final ? "Final Attributes:" : "Current Attributes:");
3330 enlght_out(final ? "
\8dÅ
\8fI
\91®
\90«:" : "
\8c»
\8dÝ
\82Ì
\91®
\90«:");
3332 if (u.uevent.uhand_of_elbereth) {
3334 static const char *const hofe_titles[3] = { "the Hand of Elbereth",
3335 "the Envoy of Balance",
3336 "the Glory of Arioch" };
3338 static const char *const hofe_titles[3] = { "
\83G
\83\8b\83x
\83\8c\83X
\82Ì
\8cä
\8eè",
3339 "
\92²
\98a
\82Ì
\8eg
\8eÒ",
3340 "
\83A
\83\8a\83I
\83b
\83`
\82Ì
\96¼
\97_" };
3342 you_are(hofe_titles[u.uevent.uhand_of_elbereth - 1], "");
3346 Sprintf(buf, "%s", piousness(TRUE, "aligned"));
3348 Sprintf(buf, "%s", piousness(TRUE, "
\90M
\8bÂ
\90S"));
3349 if (u.ualign.record >= 0)
3356 Sprintf(buf, " %d", u.ualign.record);
3357 enl_msg("Your alignment ", "is", "was", buf, "");
3359 Sprintf(buf, "
\82 \82È
\82½
\82Ì
\91®
\90«
\92l
\82Í%d", u.ualign.record);
3360 enl_msg(buf, "
\82Å
\82 \82é", "
\82¾
\82Á
\82½", "", "");
3364 /*** Resistances to troubles ***/
3367 you_are("invulnerable", from_what(INVULNERABLE));
3369 you_are("
\95s
\8e\80\90g", from_what(INVULNERABLE));
3372 you_are("magic-protected", from_what(ANTIMAGIC));
3374 you_have("
\96\82\96@
\96h
\8cä
\94\
\97Í", from_what(ANTIMAGIC));
3375 if (Fire_resistance)
3377 you_are("fire resistant", from_what(FIRE_RES));
3379 you_have("
\89Î
\82Ö
\82Ì
\91Ï
\90«", from_what(FIRE_RES));
3380 if (Cold_resistance)
3382 you_are("cold resistant", from_what(COLD_RES));
3384 you_have("
\8a¦
\82³
\82Ö
\82Ì
\91Ï
\90«", from_what(COLD_RES));
3385 if (Sleep_resistance)
3387 you_are("sleep resistant", from_what(SLEEP_RES));
3389 you_have("
\96°
\82è
\82Ö
\82Ì
\91Ï
\90«", from_what(SLEEP_RES));
3390 if (Disint_resistance)
3392 you_are("disintegration-resistant", from_what(DISINT_RES));
3394 you_have("
\95²
\8dÓ
\82Ö
\82Ì
\91Ï
\90«", from_what(DISINT_RES));
3395 if (Shock_resistance)
3397 you_are("shock resistant", from_what(SHOCK_RES));
3399 you_have("
\93d
\8c\82\82Ö
\82Ì
\91Ï
\90«", from_what(SHOCK_RES));
3400 if (Poison_resistance)
3402 you_are("poison resistant", from_what(POISON_RES));
3404 you_have("
\93Å
\82Ö
\82Ì
\91Ï
\90«", from_what(POISON_RES));
3405 if (Acid_resistance)
3407 you_are("acid resistant", from_what(ACID_RES));
3409 you_have("
\8e_
\82Ö
\82Ì
\91Ï
\90«", from_what(ACID_RES));
3410 if (Drain_resistance)
3412 you_are("level-drain resistant", from_what(DRAIN_RES));
3414 you_have("
\83\8c\83x
\83\8b\83_
\83E
\83\93\82Ö
\82Ì
\91Ï
\90«", from_what(DRAIN_RES));
3415 if (Sick_resistance)
3417 you_are("immune to sickness", from_what(SICK_RES));
3419 you_have("
\95a
\8bC
\82É
\91Î
\82·
\82é
\96Æ
\89u", from_what(SICK_RES));
3420 if (Stone_resistance)
3422 you_are("petrification resistant", from_what(STONE_RES));
3424 you_have("
\90Î
\89»
\82Ö
\82Ì
\91Ï
\90«", from_what(STONE_RES));
3425 if (Halluc_resistance)
3427 enl_msg(You_, "resist", "resisted", " hallucinations",
3428 from_what(HALLUC_RES));
3430 you_have("
\8c¶
\8ao
\82Ö
\82Ì
\91Ï
\90«", from_what(HALLUC_RES));
3434 you_can("recognize detrimental food", "");
3436 you_can("
\97L
\8aQ
\82È
\90H
\97¿
\82ð
\8e¯
\95Ê", "");
3438 /*** Vision and senses ***/
3439 if (!Blind && (Blinded || !haseyes(youmonst.data)))
3441 you_can("see", from_what(-BLINDED)); /* Eyes of the Overworld */
3442 #else /*
\81u
\92´
\90¢
\8aE
\82Ì
\96Ú
\82É
\82æ
\82Á
\82Ä
\8c©
\82é
\82±
\82Æ
\82ª
\82Å
\82«
\82é
\81v*/
3443 you_can("
\8c©
\82é
\82±
\82Æ
\82ª", from_what(-BLINDED)); /* Eyes of the Overworld */
3445 if (See_invisible) {
3448 enl_msg(You_, "see", "saw", " invisible", from_what(SEE_INVIS));
3450 enl_msg("
\82 \82È
\82½
\82Í
\93§
\96¾
\82È
\82à
\82Ì
\82ð
\8c©
\82ç
\82ê", "
\82é", "
\82½", "", from_what(SEE_INVIS));
3453 enl_msg(You_, "will see", "would have seen",
3454 " invisible when not blind", from_what(SEE_INVIS));
3456 enl_msg(You_, "
\82é", "
\82½",
3457 "
\96Ó
\96Ú
\82Å
\82È
\82¢
\82Æ
\82«
\82É
\82Í
\93§
\96¾
\82È
\82à
\82Ì
\82ð
\8c©
\82ç
\82ê", from_what(SEE_INVIS));
3462 you_are("telepathic", from_what(TELEPAT));
3464 you_have("
\83e
\83\8c\83p
\83V
\81[", from_what(TELEPAT));
3467 you_are("warned", from_what(WARNING));
3469 you_have("
\8cx
\89ú
\94\
\97Í", from_what(WARNING));
3470 if (Warn_of_mon && context.warntype.obj) {
3472 Sprintf(buf, "aware of the presence of %s",
3473 (context.warntype.obj & M2_ORC) ? "orcs"
3474 : (context.warntype.obj & M2_ELF) ? "elves"
3475 : (context.warntype.obj & M2_DEMON) ? "demons" : something);
3476 you_are(buf, from_what(WARN_OF_MON));
3478 Sprintf(buf, "%s
\82Ì
\91¶
\8dÝ
\82ð
\8a´
\82¶
\82é
\94\
\97Í",
3479 (context.warntype.obj & M2_ORC) ? "
\83I
\81[
\83N"
3480 : (context.warntype.obj & M2_ELF) ? "
\83G
\83\8b\83t"
3481 : (context.warntype.obj & M2_DEMON) ? "
\88«
\96\82" : something);
3485 if (Warn_of_mon && context.warntype.polyd) {
3487 Sprintf(buf, "aware of the presence of %s",
3488 ((context.warntype.polyd & (M2_HUMAN | M2_ELF))
3489 == (M2_HUMAN | M2_ELF))
3490 ? "humans and elves"
3491 : (context.warntype.polyd & M2_HUMAN)
3493 : (context.warntype.polyd & M2_ELF)
3495 : (context.warntype.polyd & M2_ORC)
3497 : (context.warntype.polyd & M2_DEMON)
3499 : "certain monsters");
3502 Sprintf(buf, "%s
\82Ì
\91¶
\8dÝ
\82ð
\8a´
\82¶
\82é
\94\
\97Í",
3503 ((context.warntype.polyd & (M2_HUMAN | M2_ELF))
3504 == (M2_HUMAN | M2_ELF))
3505 ? "
\90l
\8aÔ
\82Æ
\83G
\83\8b\83t"
3506 : (context.warntype.polyd & M2_HUMAN)
3508 : (context.warntype.polyd & M2_ELF)
3510 : (context.warntype.polyd & M2_ORC)
3512 : (context.warntype.polyd & M2_DEMON)
3514 : "
\82 \82é
\8eí
\82Ì
\89ö
\95¨");
3518 if (Warn_of_mon && context.warntype.speciesidx >= LOW_PM) {
3520 Sprintf(buf, "aware of the presence of %s",
3521 makeplural(mons[context.warntype.speciesidx].mname));
3522 you_are(buf, from_what(WARN_OF_MON));
3524 Sprintf(buf, "%s
\82Ì
\91¶
\8dÝ
\82ð
\8a´
\82¶
\82é
\94\
\97Í",
3525 mons[context.warntype.speciesidx].mname);
3526 you_have(buf, from_what(WARN_OF_MON));
3531 you_are("warned of undead", from_what(WARN_UNDEAD));
3533 you_have("
\95s
\8e\80\82Ì
\90¶
\95¨
\82Ö
\82Ì
\8cx
\89ú
\94\
\97Í", from_what(WARN_UNDEAD));
3536 you_have("automatic searching", from_what(SEARCHING));
3538 you_have("
\92T
\8d¸
\94\
\97Í", from_what(SEARCHING));
3541 you_are("clairvoyant", from_what(CLAIRVOYANT));
3543 you_have("
\90ç
\97¢
\8aá
\94\
\97Í", from_what(CLAIRVOYANT));
3544 else if ((HClairvoyant || EClairvoyant) && BClairvoyant) {
3545 Strcpy(buf, from_what(-CLAIRVOYANT));
3547 if (!strncmp(buf, " because of ", 12))
3548 /* overwrite substring; strncpy doesn't add terminator */
3549 (void) strncpy(buf, " if not for ", 12);
3550 enl_msg(You_, "could be", "could have been", " clairvoyant", buf);
3552 /*JP:
\81u
\81c
\82É
\82æ
\82Á
\82Ä
\81v*/
3553 if (!strncmp(buf, "
\82É
\82æ
\82Á
\82Ä", 8))
3554 /*JP:
\81u
\81c
\82ª
\82È
\82¯
\82ê
\82Î
\81v
\82É
\8f\91\82«
\8a·
\82¦
\82é*/
3555 strcpy(eos(buf) - 8, "
\82ª
\82È
\82¯
\82ê
\82Î");
3556 you_have("
\90ç
\97¢
\8aá
\94\
\97Í", buf);
3561 you_have("infravision", from_what(INFRAVISION));
3563 you_have("
\90Ô
\8aO
\90ü
\82ª
\8c©
\82¦
\82é
\8e\8b\8ao", from_what(INFRAVISION));
3564 if (Detect_monsters)
3566 you_are("sensing the presence of monsters", "");
3568 you_have("
\89ö
\95¨
\82ð
\92T
\82·
\94\
\97Í", "");
3571 you_are("going to confuse monsters", "");
3573 you_have("
\89ö
\95¨
\82ð
\8d¬
\97\90\82³
\82¹
\82é
\94\
\97Í", "");
3575 /*** Appearance and behavior ***/
3579 if (uleft && uleft->otyp == RIN_ADORNMENT)
3580 adorn += uleft->spe;
3581 if (uright && uright->otyp == RIN_ADORNMENT)
3582 adorn += uright->spe;
3583 /* the sum might be 0 (+0 ring or two which negate each other);
3584 that yields "you are charismatic" (which isn't pointless
3585 because it potentially impacts seduction attacks) */
3587 Sprintf(buf, "%scharismatic",
3588 (adorn > 0) ? "more " : (adorn < 0) ? "less " : "");
3589 you_are(buf, from_what(ADORNED));
3591 Sprintf(buf, "
\96£
\97Í%s
\82Ä",
3592 (adorn > 0) ? "
\82ª
\91\9d\89Á
\82µ" : (adorn < 0) ? "
\82ª
\8c¸
\8f
\82µ" : "
\93I
\82É
\82È
\82Á");
3593 enl_msg(You_, "
\82Ä
\82¢
\82é", "
\82½", buf, "");
3598 you_are("invisible", from_what(INVIS));
3600 you_are("
\93§
\96¾", from_what(INVIS));
3603 you_are("invisible to others", from_what(INVIS));
3605 you_are("
\91¼
\90l
\82É
\91Î
\82µ
\82Ä
\93§
\96¾", from_what(INVIS));
3606 /* ordinarily "visible" is redundant; this is a special case for
3607 the situation when invisibility would be an expected attribute */
3608 else if ((HInvis || EInvis) && BInvis)
3610 you_are("visible", from_what(-INVIS));
3612 you_are("
\95s
\93§
\96¾", from_what(-INVIS));
3615 you_are("displaced", from_what(DISPLACED));
3617 you_have("
\8c¶
\89e
\94\
\97Í", from_what(DISPLACED));
3620 you_are("stealthy", from_what(STEALTH));
3622 you_have("
\90l
\96Ú
\82ð
\93\90\82Þ
\94\
\97Í", from_what(STEALTH));
3623 if (Aggravate_monster)
3625 enl_msg("You aggravate", "", "d", " monsters",
3626 from_what(AGGRAVATE_MONSTER));
3628 you_are_ing("
\94½
\8a´
\82ð
\82©
\82Á
\82Ä", from_what(AGGRAVATE_MONSTER));
3632 enl_msg("You cause", "", "d", " conflict", from_what(CONFLICT));
3634 you_are_ing("
\93¬
\91\88\82ð
\88ø
\82«
\8bN
\82±
\82µ
\82Ä", from_what(CONFLICT));
3636 /*** Transportation ***/
3639 you_can("jump", from_what(JUMPING));
3641 you_can("
\92µ
\96ô
\82·
\82é
\82±
\82Æ
\82ª", from_what(JUMPING));
3644 you_can("teleport", from_what(TELEPORT));
3646 you_can("
\8fu
\8aÔ
\88Ú
\93®
\82ª", from_what(TELEPORT));
3647 if (Teleport_control)
3649 you_have("teleport control", from_what(TELEPORT_CONTROL));
3651 you_have("
\8fu
\8aÔ
\88Ú
\93®
\82Ì
\90§
\8cä
\94\
\97Í", from_what(TELEPORT_CONTROL));
3652 /* actively levitating handled earlier as a status condition */
3653 if (BLevitation) { /* levitation is blocked */
3654 long save_BLev = BLevitation;
3658 /* either trapped in the floor or inside solid rock
3659 (or both if chained to buried iron ball and have
3660 moved one step into solid rock somehow) */
3662 boolean trapped = (save_BLev & I_SPECIAL) != 0L,
3663 terrain = (save_BLev & FROMOUTSIDE) != 0L;
3665 Sprintf(buf, "%s%s%s",
3666 trapped ? " if not trapped" : "",
3667 (trapped && terrain) ? " and" : "",
3668 terrain ? if_surroundings_permitted : "");
3669 enl_msg(You_, "would levitate", "would have levitated", buf, "");
3671 you_are("
\8fó
\8bµ
\82ª
\8b\96\82¹
\82Î
\95\82\97V
\82·
\82é
\8fó
\91Ô", "");
3674 BLevitation = save_BLev;
3676 /* actively flying handled earlier as a status condition */
3677 if (BFlying) { /* flight is blocked */
3678 long save_BFly = BFlying;
3683 enl_msg(You_, "would fly", "would have flown",
3684 /* wording quibble: for past tense, "hadn't been"
3685 would sound better than "weren't" (and
3686 "had permitted" better than "permitted"), but
3687 "weren't" and "permitted" are adequate so the
3688 extra complexity to handle that isn't worth it */
3690 ? " if you weren't levitating"
3691 : (save_BFly == I_SPECIAL)
3692 /* this is an oversimpliction; being trapped
3693 might also be blocking levitation so flight
3694 would still be blocked after escaping trap */
3695 ? " if you weren't trapped"
3696 : (save_BFly == FROMOUTSIDE)
3697 ? if_surroundings_permitted
3698 /* two or more of levitation, surroundings,
3699 and being trapped in the floor */
3700 : " if circumstances permitted",
3703 enl_msg(You_, "
\94ò
\82Ô
\82±
\82Æ
\82ª
\82Å
\82«
\82é", "
\94ò
\82Ô
\82±
\82Æ
\82ª
\82Å
\82«
\82½",
3704 /* wording quibble: for past tense, "hadn't been"
3705 would sound better than "weren't" (and
3706 "had permitted" better than "permitted"), but
3707 "weren't" and "permitted" are adequate so the
3708 extra complexity to handle that isn't worth it */
3710 ? "
\95\82\97V
\82µ
\82Ä
\82¢
\82È
\82¯
\82ê
\82Î"
3711 : (save_BFly == I_SPECIAL)
3712 /* this is an oversimpliction; being trapped
3713 might also be blocking levitation so flight
3714 would still be blocked after escaping trap */
3715 ? "
\95ß
\82Ü
\82Á
\82Ä
\82¢
\82È
\82¯
\82ê
\82Î"
3716 : (save_BFly == FROMOUTSIDE)
3717 ? "
\8fó
\8bµ
\82ª
\8b\96\82¹
\82Î"
3718 /* two or more of levitation, surroundings,
3719 and being trapped in the floor */
3720 : "
\8e\96\8fî
\82ª
\8b\96\82¹
\82Î",
3724 BFlying = save_BFly;
3726 /* actively walking on water handled earlier as a status condition */
3727 if (Wwalking && !walking_on_water())
3729 you_can("walk on water", from_what(WWALKING));
3731 you_can("
\90\85\82Ì
\8fã
\82ð
\95à
\82
\82±
\82Æ
\82ª", from_what(WWALKING));
3732 /* actively swimming (in water but not under it) handled earlier */
3733 if (Swimming && (Underwater || !u.uinwater))
3735 you_can("swim", from_what(SWIMMING));
3737 you_can("
\89j
\82®
\82±
\82Æ
\82ª", from_what(SWIMMING));
3740 you_can("survive without air", from_what(MAGICAL_BREATHING));
3742 you_can("
\8bó
\8bC
\82È
\82µ
\82Å
\90¶
\82«
\89\84\82Ñ
\82é
\82±
\82Æ
\82ª", from_what(MAGICAL_BREATHING));
3743 else if (Amphibious)
3745 you_can("breathe water", from_what(MAGICAL_BREATHING));
3747 you_can("
\90\85\92\86\82Å
\8cÄ
\8bz
\82ª", from_what(MAGICAL_BREATHING));
3750 you_can("walk through walls", from_what(PASSES_WALLS));
3752 you_can("
\95Ç
\82ð
\92Ê
\82è
\94²
\82¯
\82é
\82±
\82Æ
\82ª", from_what(PASSES_WALLS));
3754 /*** Physical attributes ***/
3757 enl_msg("You regenerate", "", "d", "", from_what(REGENERATION));
3759 you_have("
\8dÄ
\90¶
\94\
\97Í", from_what(REGENERATION));
3762 you_have("slower digestion", from_what(SLOW_DIGESTION));
3764 enl_msg("
\90H
\95¨
\82Ì
\8fÁ
\89»
\82ª
\92x", "
\82¢", "
\82©
\82Á
\82½", "", from_what(SLOW_DIGESTION));
3767 you_have(enlght_combatinc("to hit", u.uhitinc, final, buf), "");
3769 you_have(enlght_combatinc("
\96½
\92\86\97¦", u.uhitinc, final, buf), "");
3772 you_have(enlght_combatinc("damage", u.udaminc, final, buf), "");
3774 you_have(enlght_combatinc("
\83_
\83\81\81[
\83W", u.udaminc, final, buf), "");
3775 if (u.uspellprot || Protection) {
3778 if (uleft && uleft->otyp == RIN_PROTECTION)
3780 if (uright && uright->otyp == RIN_PROTECTION)
3781 prot += uright->spe;
3782 if (HProtection & INTRINSIC)
3784 prot += u.uspellprot;
3787 you_have(enlght_combatinc("defense", prot, final, buf), "");
3789 you_have(enlght_combatinc("
\96h
\8cä", prot, final, buf), "");
3791 if ((armpro = magic_negation(&youmonst)) > 0) {
3792 /* magic cancellation factor, conferred by worn armor */
3793 static const char *const mc_types[] = {
3795 "" /*ordinary*/, "warded", "guarded", "protected",
3797 "" /*ordinary*/, "
\89q
\82ç
\82ê
\82Ä", "
\8cì
\82ç
\82ê
\82Ä", "
\8eç
\82ç
\82ê
\82Ä",
3801 if (armpro >= SIZE(mc_types))
3802 armpro = SIZE(mc_types) - 1;
3804 you_are(mc_types[armpro], "");
3806 you_are_ing(mc_types[armpro], "");
3808 if (Half_physical_damage)
3809 enlght_halfdmg(HALF_PHDAM, final);
3810 if (Half_spell_damage)
3811 enlght_halfdmg(HALF_SPDAM, final);
3812 /* polymorph and other shape change */
3813 if (Protection_from_shape_changers)
3815 you_are("protected from shape changers",
3816 from_what(PROT_FROM_SHAPE_CHANGERS));
3818 you_have("
\95Ï
\89»
\89ö
\95¨
\82Ö
\82Ì
\91Ï
\90«", from_what(PROT_FROM_SHAPE_CHANGERS));
3821 const char *what = 0;
3823 if (!Upolyd) /* Upolyd handled below after current form */
3825 you_can("not change from your current form",
3827 you_are("
\8c»
\8dÝ
\82Ì
\8ep
\82©
\82ç
\95Ï
\89»
\82Å
\82«
\82È
\82¢
\8fó
\91Ô",
3828 from_what(UNCHANGING));
3829 /* blocked shape changes */
3832 what = !final ? "polymorph" : "have polymorphed";
3834 what = "
\95Ï
\89»
\82µ
\82Ä";
3835 else if (u.ulycn >= LOW_PM)
3837 what = !final ? "change shape" : "have changed shape";
3839 what = "
\8ep
\82ð
\95Ï
\82¦
\82Ä";
3842 Sprintf(buf, "would %s periodically", what);
3843 /* omit from_what(UNCHANGING); too verbose */
3844 enl_msg(You_, buf, buf, " if not locked into your current form",
3847 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);
3848 you_are_ing(buf, "");
3851 } else if (Polymorph) {
3853 you_are("polymorphing periodically", from_what(POLYMORPH));
3855 you_are("
\92è
\8aú
\93I
\82É
\95Ï
\89»
\82µ
\82Ä", from_what(POLYMORPH));
3857 if (Polymorph_control)
3859 you_have("polymorph control", from_what(POLYMORPH_CONTROL));
3861 you_have("
\95Ï
\89»
\82Ì
\90§
\8cä
\94\
\97Í", from_what(POLYMORPH_CONTROL));
3862 if (Upolyd && u.umonnum != u.ulycn
3863 /* if we've died from turning into slime, we're polymorphed
3864 right now but don't want to list it as a temporary attribute
3865 [we need a more reliable way to detect this situation] */
3866 && !(final == ENL_GAMEOVERDEAD
3867 && u.umonnum == PM_GREEN_SLIME && !Unchanging)) {
3868 /* foreign shape (except were-form which is handled below) */
3870 Sprintf(buf, "polymorphed into %s", an(youmonst.data->mname));
3872 Sprintf(buf, "%s
\82É
\95Ï
\89»
\82µ
\82Ä", youmonst.data->mname);
3874 Sprintf(eos(buf), " (%d)", u.mtimedone);
3877 if (lays_eggs(youmonst.data) && flags.female) /* Upolyd */
3879 you_can("lay eggs", "");
3881 you_can("
\97\91\82ð
\8eY
\82Þ
\82±
\82Æ
\82ª", "");
3882 if (u.ulycn >= LOW_PM) {
3884 /* "you are a werecreature [in beast form]" */
3885 Strcpy(buf, an(mons[u.ulycn].mname));
3886 if (u.umonnum == u.ulycn) {
3887 Strcat(buf, " in beast form");
3889 Sprintf(eos(buf), " (%d)", u.mtimedone);
3892 /*JP:
\81u
\82 \82È
\82½
\82Í[
\8fb
\82Ì
\8ep
\82Ì]
\81\9b\81\9b\90l
\8aÔ
\82Å
\82 \82é
\81v*/
3894 if (u.umonnum == u.ulycn) {
3895 Strcpy(buf, "
\8fb
\82Ì
\8ep
\82Ì");
3897 Sprintf(eos(buf), " (%d)", u.mtimedone);
3899 Strcat(buf, mons[u.ulycn].mname);
3903 if (Unchanging && Upolyd) /* !Upolyd handled above */
3905 you_can("not change from your current form", from_what(UNCHANGING));
3907 enl_msg("
\8d¡
\82Ì
\8ep
\82©
\82ç
\95Ï
\89»
\82·
\82é
\82±
\82Æ
\82ª
\82Å
\82«
\82È", "
\82¢", "
\82©
\82Á
\82½", "", from_what(UNCHANGING));
3910 you_are("harmed by silver", "");
3912 enl_msg("
\82 \82È
\82½
\82Í
\8bâ
\82É
\8eã", "
\82¢", "
\82©
\82Á
\82½", "", "");
3913 /* movement and non-armor-based protection */
3916 you_are(Very_fast ? "very fast" : "fast", from_what(FAST));
3918 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));
3921 you_have("reflection", from_what(REFLECTING));
3923 you_have("
\94½
\8eË
\94\
\97Í", from_what(REFLECTING));
3926 you_have("free action", from_what(FREE_ACTION));
3928 you_have("
\8dS
\91©
\82³
\82ê
\82È
\82¢
\94\
\97Í", from_what(FREE_ACTION));
3931 you_have("fixed abilities", from_what(FIXED_ABIL));
3933 enl_msg("
\94\
\97Í
\82ª
\95Ï
\89»
\82µ
\82È", "
\82¢", "
\82©
\82Á
\82½", "", from_what(FIXED_ABIL));
3936 enl_msg("Your life ", "will be", "would have been", " saved", "");
3938 enl_msg("
\82 \82È
\82½
\82Ì
\90¶
\96½
\82Í
\95Û
\91¶
\82³
\82ê
\82Ä", iru, ita, "", "");
3940 /*** Miscellany ***/
3942 ltmp = abs((int) Luck);
3944 Sprintf(buf, "%s%slucky",
3945 ltmp >= 10 ? "extremely " : ltmp >= 5 ? "very " : "",
3946 Luck < 0 ? "un" : "");
3948 Sprintf(buf, "%s%s",
3949 ltmp >= 10 ? "
\96Ò
\97ó
\82É" : ltmp >= 5 ? "
\82Æ
\82Ä
\82à" : "",
3950 Luck < 0 ? "
\95s
\8dK" : "
\8dK
\95\9f");
3953 Sprintf(eos(buf), " (%d)", Luck);
3957 enl_msg("Your luck ", "is", "was", " zero", "");
3959 enl_msg("
\82 \82È
\82½
\82Ì
\89^
\82Í
\83[
\83\8d", "
\82Å
\82 \82é", "
\82¾
\82Á
\82½", "", "");
3962 you_have("extra luck", "");
3964 you_have("
\82³
\82ç
\82È
\82é
\8dK
\89^", "");
3965 else if (u.moreluck < 0)
3967 you_have("reduced luck", "");
3969 you_have("
\82³
\82ç
\82È
\82é
\95s
\89^", "");
3970 if (carrying(LUCKSTONE) || stone_luck(TRUE)) {
3971 ltmp = stone_luck(FALSE);
3974 enl_msg("Bad luck ", "does", "did", " not time out for you", "");
3976 enl_msg("
\95s
\89^
\82Í
\8e\9e\8aÔ
\90Ø
\82ê
\82É
\82È
\82ç
\82È", "
\82¢", "
\82©
\82Á
\82½", "", "");
3979 enl_msg("Good luck ", "does", "did", " not time out for you", "");
3981 enl_msg("
\8dK
\89^
\82Í
\8e\9e\8aÔ
\90Ø
\82ê
\82É
\82È
\82ç
\82È", "
\82¢", "
\82©
\82Á
\82½", "", "");
3986 Sprintf(buf, " %sangry with you",
3987 u.ugangr > 6 ? "extremely " : u.ugangr > 3 ? "very " : "");
3989 Sprintf(buf, "%s
\82Í%s
\93{
\82Á
\82Ä%s", u_gname(),
3990 u.ugangr > 6 ? "
\96Ò
\97ó
\82É" : u.ugangr > 3 ? "
\82Æ
\82Ä
\82à" : "", final ? ita : iru);
3993 Sprintf(eos(buf), " (%d)", u.ugangr);
3995 enl_msg(u_gname(), " is", " was", buf, "");
3997 enl_msg(buf, "", "", "", "");
4001 * We need to suppress this when the game is over, because death
4002 * can change the value calculated by can_pray(), potentially
4003 * resulting in a false claim that you could have prayed safely.
4008 /* "can [not] safely pray" vs "could [not] have safely prayed" */
4009 Sprintf(buf, "%s%ssafely pray%s", can_pray(FALSE) ? "" : "not ",
4010 final ? "have " : "", final ? "ed" : "");
4012 Sprintf(buf, "%ssafely pray", can_pray(FALSE) ? "" : "not ");
4015 Sprintf(eos(buf), " (%d)", u.ublesscnt);
4018 Sprintf(buf, "
\82 \82È
\82½
\82Í
\88À
\91S
\82É
\8bF
\82é
\82±
\82Æ
\82ª");
4019 Strcat(buf, can_pray(FALSE) ? can : "
\82Å
\82«
\82È
\82¢");
4021 Sprintf(eos(buf), " (%d)", u.ublesscnt);
4022 enl_msg(buf, "", "", "", "");
4028 /* named fruit debugging (doesn't really belong here...); to enable,
4029 include 'fruit' in DEBUGFILES list (even though it isn't a file...) */
4030 if (wizard && explicitdebug("fruit")) {
4033 reorder_fruit(TRUE); /* sort by fruit index, from low to high;
4034 * this modifies the ffruit chain, so could
4035 * possibly mask or even introduce a problem,
4036 * but it does useful sanity checking */
4037 for (f = ffruit; f; f = f->nextf) {
4039 Sprintf(buf, "Fruit #%d ", f->fid);
4041 Sprintf(buf, "fruit $%d
\82Í", f->fid);
4043 enl_msg(buf, "is ", "was ", f->fname, "");
4045 enl_msg(buf, "
\82¾", "
\82¾
\82Á
\82½", f->fname, "");
4048 enl_msg("The current fruit ", "is ", "was ", pl_fruit, "");
4050 enl_msg("
\8c»
\8dÝ
\82Ì fruit
\82Í", "
\82¾", "
\82¾
\82Á
\82½", pl_fruit, "");
4051 Sprintf(buf, "%d", flags.made_fruit);
4053 enl_msg("The made fruit flag ", "is ", "was ", buf, "");
4055 enl_msg("made fruit flag
\82Í", "
\82¾", "
\82¾
\82Á
\82½", buf, "");
4063 if (final < 2) { /* still in progress, or quit/escaped/ascended */
4065 p = "survived after being killed ";
4067 p = "
\8e\80\82ñ
\82¾
\8cã
\95\9c\8a\88\82µ
\82Ä
\82¢
\82½";
4068 switch (u.umortality) {
4071 p = !final ? (char *) 0 : "survived";
4073 p = !final ? (char *)0 : "
\90¶
\82«
\89\84\82Ñ
\82½";
4077 Strcpy(buf, "once");
4079 Strcpy(buf, "
\88ê
\93x");
4083 Strcpy(buf, "twice");
4085 Strcpy(buf, "
\93ñ
\93x");
4089 Strcpy(buf, "thrice");
4091 Strcpy(buf, "
\8eO
\93x");
4095 Sprintf(buf, "%d times", u.umortality);
4097 Sprintf(buf, "%d
\89ñ", u.umortality);
4100 } else { /* game ended in character's death */
4104 p = "
\8e\80\82ñ
\82Å
\82¢
\82é";
4105 switch (u.umortality) {
4107 impossible("dead without dying?");
4109 break; /* just "are dead" */
4112 Sprintf(buf, " (%d%s time!)", u.umortality,
4113 ordin(u.umortality));
4115 Sprintf(buf, "(%d
\89ñ
\81I)", u.umortality);
4122 enl_msg(You_, "have been killed ", p, buf, "");
4124 enl_msg(You_, "
\8e\80\82ñ
\82Å
\82¢
\82é", p, buf, "");
4128 #if 0 /* no longer used */
4129 STATIC_DCL boolean NDECL(minimal_enlightenment);
4132 * Courtesy function for non-debug, non-explorer mode players
4133 * to help refresh them about who/what they are.
4134 * Returns FALSE if menu cancelled (dismissed with ESC), TRUE otherwise.
4137 minimal_enlightenment()
4140 menu_item *selected;
4143 char buf[BUFSZ], buf2[BUFSZ];
4144 static const char untabbed_fmtstr[] = "%-15s: %-12s";
4145 static const char untabbed_deity_fmtstr[] = "%-17s%s";
4146 static const char tabbed_fmtstr[] = "%s:\t%-12s";
4147 static const char tabbed_deity_fmtstr[] = "%s\t%s";
4148 static const char *fmtstr;
4149 static const char *deity_fmtstr;
4151 fmtstr = iflags.menu_tab_sep ? tabbed_fmtstr : untabbed_fmtstr;
4152 deity_fmtstr = iflags.menu_tab_sep ? tabbed_deity_fmtstr
4153 : untabbed_deity_fmtstr;
4155 buf[0] = buf2[0] = '\0';
4156 tmpwin = create_nhwindow(NHW_MENU);
4158 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
4164 /* Starting name, race, role, gender */
4166 Sprintf(buf, fmtstr, "name", plname);
4168 Sprintf(buf, fmtstr, "
\96¼
\91O", plname);
4169 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4171 Sprintf(buf, fmtstr, "race", urace.noun);
4173 Sprintf(buf, fmtstr, "
\8eí
\91°", urace.noun);
4174 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4176 Sprintf(buf, fmtstr, "role",
4178 Sprintf(buf, fmtstr, "
\90E
\8bÆ",
4179 (flags.initgend && urole.name.f) ? urole.name.f : urole.name.m);
4180 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4182 Sprintf(buf, fmtstr, "gender", genders[flags.initgend].adj);
4184 Sprintf(buf, fmtstr, "
\90«
\95Ê", genders[flags.initgend].adj);
4185 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4187 /* Starting alignment */
4189 Sprintf(buf, fmtstr, "alignment", align_str(u.ualignbase[A_ORIGINAL]));
4191 Sprintf(buf, fmtstr, "
\91®
\90«", align_str(u.ualignbase[A_ORIGINAL]));
4192 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4194 /* Current name, race, role, gender */
4195 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, "", FALSE);
4196 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
4202 Sprintf(buf, fmtstr, "race", Upolyd ? youmonst.data->mname : urace.noun);
4204 Sprintf(buf, fmtstr, "
\8eí
\91°", Upolyd ? youmonst.data->mname : urace.noun);
4205 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4208 Sprintf(buf, fmtstr, "role (base)",
4210 Sprintf(buf, fmtstr, "
\90E
\8bÆ(
\8aî
\96{)",
4211 (u.mfemale && urole.name.f) ? urole.name.f
4213 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4216 Sprintf(buf, fmtstr, "role",
4218 Sprintf(buf, fmtstr, "
\90E
\8bÆ",
4219 (flags.female && urole.name.f) ? urole.name.f
4221 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4223 /* don't want poly_gender() here; it forces `2' for non-humanoids */
4224 genidx = is_neuter(youmonst.data) ? 2 : flags.female;
4226 Sprintf(buf, fmtstr, "gender", genders[genidx].adj);
4228 Sprintf(buf, fmtstr, "
\90«
\95Ê", genders[genidx].adj);
4229 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4230 if (Upolyd && (int) u.mfemale != genidx) {
4232 Sprintf(buf, fmtstr, "gender (base)", genders[u.mfemale].adj);
4234 Sprintf(buf, fmtstr, "
\90«
\95Ê(
\8aî
\96{)", genders[u.mfemale].adj);
4235 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4238 /* Current alignment */
4240 Sprintf(buf, fmtstr, "alignment", align_str(u.ualign.type));
4242 Sprintf(buf, fmtstr, "
\91®
\90«", align_str(u.ualign.type));
4243 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4246 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, "", FALSE);
4247 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
4253 Sprintf(buf2, deity_fmtstr, align_gname(A_CHAOTIC),
4254 (u.ualignbase[A_ORIGINAL] == u.ualign.type
4255 && u.ualign.type == A_CHAOTIC) ? " (s,c)"
4256 : (u.ualignbase[A_ORIGINAL] == A_CHAOTIC) ? " (s)"
4257 : (u.ualign.type == A_CHAOTIC) ? " (c)" : "");
4259 Sprintf(buf2, deity_fmtstr, align_gname(A_CHAOTIC),
4260 (u.ualignbase[A_ORIGINAL] == u.ualign.type
4261 && u.ualign.type == A_CHAOTIC) ? " (
\8f\89\81C
\8c»)"
4262 : (u.ualignbase[A_ORIGINAL] == A_CHAOTIC) ? " (
\8f\89)"
4263 : (u.ualign.type == A_CHAOTIC) ? " (
\8c»)" : "");
4266 Sprintf(buf, fmtstr, "Chaotic", buf2);
4268 Sprintf(buf, fmtstr, "
\8d¬
\93×", buf2);
4269 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4272 Sprintf(buf2, deity_fmtstr, align_gname(A_NEUTRAL),
4273 (u.ualignbase[A_ORIGINAL] == u.ualign.type
4274 && u.ualign.type == A_NEUTRAL) ? " (s,c)"
4275 : (u.ualignbase[A_ORIGINAL] == A_NEUTRAL) ? " (s)"
4276 : (u.ualign.type == A_NEUTRAL) ? " (c)" : "");
4278 Sprintf(buf2, deity_fmtstr, align_gname(A_NEUTRAL),
4279 (u.ualignbase[A_ORIGINAL] == u.ualign.type
4280 && u.ualign.type == A_NEUTRAL) ? " (
\8f\89\81C
\8c»)"
4281 : (u.ualignbase[A_ORIGINAL] == A_NEUTRAL) ? " (
\8f\89)"
4282 : (u.ualign.type == A_NEUTRAL) ? " (
\8c»)" : "");
4285 Sprintf(buf, fmtstr, "Neutral", buf2);
4287 Sprintf(buf, fmtstr, "
\92\86\97§", buf2);
4288 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4291 Sprintf(buf2, deity_fmtstr, align_gname(A_LAWFUL),
4292 (u.ualignbase[A_ORIGINAL] == u.ualign.type
4293 && u.ualign.type == A_LAWFUL) ? " (s,c)"
4294 : (u.ualignbase[A_ORIGINAL] == A_LAWFUL) ? " (s)"
4295 : (u.ualign.type == A_LAWFUL) ? " (c)" : "");
4297 Sprintf(buf2, deity_fmtstr, align_gname(A_LAWFUL),
4298 (u.ualignbase[A_ORIGINAL] == u.ualign.type
4299 && u.ualign.type == A_LAWFUL) ? " (
\8f\89\81C
\8c»)"
4300 : (u.ualignbase[A_ORIGINAL] == A_LAWFUL) ? " (
\8f\89)"
4301 : (u.ualign.type == A_LAWFUL) ? " (
\8c»)" : "");
4304 Sprintf(buf, fmtstr, "Lawful", buf2);
4306 Sprintf(buf, fmtstr, "
\92\81\8f\98", buf2);
4307 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4310 end_menu(tmpwin, "Base Attributes");
4312 end_menu(tmpwin, "
\8aî
\96{
\91®
\90«");
4313 n = select_menu(tmpwin, PICK_NONE, &selected);
4314 destroy_nhwindow(tmpwin);
4315 return (boolean) (n != -1);
4321 doattributes(VOID_ARGS)
4323 int mode = BASICENLIGHTENMENT;
4325 /* show more--as if final disclosure--for wizard and explore modes */
4326 if (wizard || discover)
4327 mode |= MAGICENLIGHTENMENT;
4329 enlightenment(mode, ENL_GAMEINPROGRESS);
4334 youhiding(via_enlghtmt, msgflag)
4335 boolean via_enlghtmt; /* englightment line vs topl message */
4336 int msgflag; /* for variant message phrasing */
4338 char *bp, buf[BUFSZ];
4341 Strcpy(buf, "hiding");
4343 Strcpy(buf, "
\89B
\82ê");
4344 if (U_AP_TYPE != M_AP_NOTHING) {
4345 /* mimic; hero is only able to mimic a strange object or gold
4346 or hallucinatory alternative to gold, so we skip the details
4347 for the hypothetical furniture and monster cases */
4348 #if 0 /*JP*//*
\8cã
\82ë
\82É
\89ñ
\82·*//* not used */
4349 bp = eos(strcpy(buf, "mimicking"));
4351 if (U_AP_TYPE == M_AP_OBJECT) {
4353 Sprintf(bp, " %s", an(simple_typename(youmonst.mappearance)));
4355 Strcpy(buf, simple_typename(youmonst.mappearance));
4356 } else if (U_AP_TYPE == M_AP_FURNITURE) {
4358 Strcpy(bp, " something");
4360 Strcpy(buf, "
\89½
\82©");
4361 } else if (U_AP_TYPE == M_AP_MONSTER) {
4363 Strcpy(bp, " someone");
4365 Strcpy(buf, "
\89½
\8eÒ
\82©");
4367 ; /* something unexpected; leave 'buf' as-is */
4369 #if 1 /*JP*//*
\82±
\82±
\82Å
\92Ç
\89Á*/
4370 Strcat(buf, "
\82Ì
\82Ó
\82è
\82ð
\82µ");
4372 } else if (u.uundetected) {
4373 bp = eos(buf); /* points past "hiding" */
4374 if (youmonst.data->mlet == S_EEL) {
4375 if (is_pool(u.ux, u.uy))
4377 Sprintf(bp, " in the %s", waterbody_name(u.ux, u.uy));
4379 Sprintf(bp, "%s
\82Ì
\92\86\82É", waterbody_name(u.ux, u.uy));
4380 } else if (hides_under(youmonst.data)) {
4381 struct obj *o = level.objects[u.ux][u.uy];
4385 Sprintf(bp, " underneath %s", ansimpleoname(o));
4387 Sprintf(bp, "%s
\82Ì
\89º
\82É", ansimpleoname(o));
4388 } else if (is_clinger(youmonst.data) || Flying) {
4389 /* Flying: 'lurker above' hides on ceiling but doesn't cling */
4391 Sprintf(bp, " on the %s", ceiling(u.ux, u.uy));
4393 Sprintf(bp, "%s
\82É", ceiling(u.ux, u.uy));
4395 /* on floor; is_hider() but otherwise not special: 'trapper' */
4396 if (u.utrap && u.utraptype == TT_PIT) {
4397 struct trap *t = t_at(u.ux, u.uy);
4400 Sprintf(bp, " in a %spit",
4401 (t && t->ttyp == SPIKED_PIT) ? "spiked " : "");
4403 Sprintf(bp, "%s
\97\8e\82µ
\8c\8a\82Ì
\92\86\82É",
4404 (t && t->ttyp == SPIKED_PIT) ? "
\83g
\83Q
\82¾
\82ç
\82¯
\82Ì" : "");
4408 Sprintf(bp, " on the %s", surface(u.ux, u.uy));
4410 Sprintf(bp, "%s
\82É", surface(u.ux, u.uy));
4412 #if 1 /*JP*//*
\82±
\82±
\82Å
\92Ç
\89Á*/
4413 Strcat(buf, "
\89B
\82ê");
4416 ; /* shouldn't happen; will result in generic "you are hiding" */
4420 int final = msgflag; /* 'final' is used by you_are() macro */
4424 /* for dohide(), when player uses '#monster' command */
4426 You("are %s %s.", msgflag ? "already" : "now", buf);
4429 You("
\82·
\82Å
\82É%s
\82Ä
\82¢
\82é
\81D", buf);
4431 You("%s
\82½
\81D", buf);
4438 * (shares enlightenment's tense handling)
4441 doconduct(VOID_ARGS)
4454 /* Create the conduct window */
4455 en_win = create_nhwindow(NHW_MENU);
4457 putstr(en_win, 0, "Voluntary challenges:");
4459 putstr(en_win, 0, "
\8e©
\94
\93I
\92§
\90í:");
4461 if (u.uroleplay.blind)
4463 you_have_been("blind from birth");
4465 you_have_been("
\90¶
\82Ü
\82ê
\82È
\82ª
\82ç
\82É
\96Ó
\96Ú");
4466 if (u.uroleplay.nudist)
4468 you_have_been("faithfully nudist");
4470 you_have_been("
\92\89\8eÀ
\82È
\97\87\91°");
4472 if (!u.uconduct.food)
4474 enl_msg(You_, "have gone", "went", " without food", "");
4476 enl_msg("
\82 \82È
\82½
\82Í
\90H
\8e\96\82ð
\82µ", "
\82Ä
\82¢
\82È
\82¢", "
\82È
\82©
\82Á
\82½", "", "");
4477 /* but beverages are okay */
4478 else if (!u.uconduct.unvegan)
4480 you_have_X("followed a strict vegan diet");
4482 you_have_been("
\8cµ
\8ai
\82È
\8dØ
\90H
\8eå
\8b`
\8eÒ");
4483 else if (!u.uconduct.unvegetarian)
4485 you_have_been("vegetarian");
4487 you_have_been("
\8dØ
\90H
\8eå
\8b`
\8eÒ");
4489 if (!u.uconduct.gnostic)
4491 you_have_been("an atheist");
4493 you_have_been("
\96³
\90_
\98_
\8eÒ");
4495 if (!u.uconduct.weaphit) {
4497 you_have_never("hit with a wielded weapon");
4499 you_have_never("
\82 \82È
\82½
\82Í
\91\95\94õ
\82µ
\82Ä
\82¢
\82é
\95\90\8aí
\82Å
\8dU
\8c\82\82µ");
4500 } else if (wizard) {
4502 Sprintf(buf, "used a wielded weapon %ld time%s", u.uconduct.weaphit,
4503 plur(u.uconduct.weaphit));
4506 Sprintf(buf, "
\82 \82È
\82½
\82Í%ld
\89ñ
\91\95\94õ
\82µ
\82½
\95\90\8aí
\82ð
\8eg
\97p
\82µ", u.uconduct.weaphit);
4510 if (!u.uconduct.killer)
4512 you_have_been("a pacifist");
4514 you_have_been("
\95½
\98a
\8eå
\8b`
\8eÒ");
4516 if (!u.uconduct.literate) {
4518 you_have_been("illiterate");
4520 you_have_never("
\82 \82È
\82½
\82Í
\93Ç
\82Ý
\8f\91\82«
\82µ");
4521 } else if (wizard) {
4523 Sprintf(buf, "read items or engraved %ld time%s", u.uconduct.literate,
4524 plur(u.uconduct.literate));
4527 Sprintf(buf, "%ld
\89ñ
\93Ç
\82ñ
\82¾
\82è
\8f\91\82¢
\82½
\82è
\82µ", u.uconduct.literate);
4532 ngenocided = num_genocides();
4533 if (ngenocided == 0) {
4535 you_have_never("genocided any monsters");
4537 you_have_never("
\82 \82È
\82½
\82Í
\89ö
\95¨
\82ð
\8bs
\8eE
\82µ");
4540 Sprintf(buf, "genocided %d type%s of monster%s", ngenocided,
4541 plur(ngenocided), plur(ngenocided));
4544 Sprintf(buf, "%d
\8eí
\82Ì
\89ö
\95¨
\82ð
\8bs
\8eE
\82µ", ngenocided);
4549 if (!u.uconduct.polypiles) {
4551 you_have_never("polymorphed an object");
4553 you_have_never("
\82 \82È
\82½
\82Í
\95¨
\91Ì
\82ð
\95Ï
\89»
\82³
\82¹");
4554 } else if (wizard) {
4556 Sprintf(buf, "polymorphed %ld item%s", u.uconduct.polypiles,
4557 plur(u.uconduct.polypiles));
4560 Sprintf(buf, "%ld
\8cÂ
\82Ì
\95¨
\82ð
\95Ï
\89»
\82³
\82¹", u.uconduct.polypiles);
4565 if (!u.uconduct.polyselfs) {
4567 you_have_never("changed form");
4569 you_have_never("
\82 \82È
\82½
\82Í
\95Ï
\89»
\82µ");
4570 } else if (wizard) {
4572 Sprintf(buf, "changed form %ld time%s", u.uconduct.polyselfs,
4573 plur(u.uconduct.polyselfs));
4576 Sprintf(buf, "%ld
\89ñ
\8ep
\82ð
\95Ï
\82¦", u.uconduct.polyselfs);
4581 if (!u.uconduct.wishes) {
4583 you_have_X("used no wishes");
4585 you_have_never("
\82 \82È
\82½
\82Í
\8aè
\82¢
\8e\96\82ð
\82µ");
4588 Sprintf(buf, "used %ld wish%s", u.uconduct.wishes,
4589 (u.uconduct.wishes > 1L) ? "es" : "");
4591 Sprintf(buf, "%ld
\89ñ
\8aè
\82¢
\8e\96\82ð
\82µ", u.uconduct.wishes);
4593 if (u.uconduct.wisharti) {
4594 /* if wisharti == wishes
4595 * 1 wish (for an artifact)
4596 * 2 wishes (both for artifacts)
4597 * N wishes (all for artifacts)
4598 * else (N is at least 2 in order to get here; M < N)
4599 * N wishes (1 for an artifact)
4600 * N wishes (M for artifacts)
4603 if (u.uconduct.wisharti == u.uconduct.wishes)
4604 Sprintf(eos(buf), " (%s",
4605 (u.uconduct.wisharti > 2L) ? "all "
4606 : (u.uconduct.wisharti == 2L) ? "both " : "");
4608 Sprintf(eos(buf), " (%ld ", u.uconduct.wisharti);
4610 Sprintf(eos(buf), "for %s)",
4611 (u.uconduct.wisharti == 1L) ? "an artifact"
4614 Sprintf(eos(buf), " (
\90¹
\8aí
\82Í%ld
\89ñ)", u.uconduct.wisharti);
4619 if (!u.uconduct.wisharti)
4621 enl_msg(You_, "have not wished", "did not wish",
4622 " for any artifacts", "");
4624 enl_msg("
\82 \82È
\82½
\82Í
\90¹
\8aí
\82ð
\8aè", "
\82Á
\82Ä
\82¢
\82È
\82¢", "
\82í
\82È
\82©
\82Á
\82½", "", "");
4628 /* Pop up the window and wait for a key */
4629 display_nhwindow(en_win, TRUE);
4630 destroy_nhwindow(en_win);
4634 /* ordered by command name */
4635 struct ext_func_tab extcmdlist[] = {
4636 { '#', "#", "perform an extended command",
4637 doextcmd, IFBURIED | GENERALCMD },
4639 { M('?'), "?", "list all extended commands",
4641 { M('?'), "?", "
\82±
\82Ì
\8ag
\92£
\83R
\83}
\83\93\83h
\88ê
\97\97\82ð
\95\
\8e¦
\82·
\82é",
4643 doextlist, IFBURIED | AUTOCOMPLETE | GENERALCMD },
4645 { M('a'), "adjust", "adjust inventory letters",
4647 { M('a'), "adjust", "
\8e\9d\82¿
\95¨
\88ê
\97\97\82Ì
\92²
\90®",
4649 doorganize, IFBURIED | AUTOCOMPLETE },
4651 { M('A'), "annotate", "name current level",
4653 { M('A'), "annotate", "
\8c»
\8dÝ
\82Ì
\8aK
\82É
\96¼
\91O
\82ð
\82Â
\82¯
\82é",
4655 donamelevel, IFBURIED | AUTOCOMPLETE },
4657 { 'a', "apply", "apply (use) a tool (pick-axe, key, lamp...)",
4659 { 'a', "apply", "
\93¹
\8bï
\82ð
\8eg
\82¤
\81D(
\82Â
\82é
\82Í
\82µ,
\8c®,
\83\89\83\93\83v
\81c)",
4662 { C('x'), "attributes", "show your attributes",
4663 doattributes, IFBURIED },
4665 { '@', "autopickup", "toggle the pickup option on/off",
4667 { '@', "autopickup", "
\8e©
\93®
\8fE
\82¢
\83I
\83v
\83V
\83\87\83\93\82ð
\90Ø
\82è
\91Ö
\82¦
\82é",
4669 dotogglepickup, IFBURIED },
4671 { 'C', "call", "call (name) something", docallcmd, IFBURIED },
4673 { 'C', "call", "
\96¼
\91O
\82ð
\82Â
\82¯
\82é", docallcmd, IFBURIED },
4676 { 'Z', "cast", "zap (cast) a spell", docast, IFBURIED },
4678 { 'Z', "cast", "
\8eô
\95¶
\82ð
\8f¥
\82¦
\82é", docast, IFBURIED },
4681 { M('c'), "chat", "talk to someone", dotalk, IFBURIED | AUTOCOMPLETE },
4683 { M('c'), "chat", "
\92N
\82©
\82Æ
\98b
\82·", dotalk, IFBURIED | AUTOCOMPLETE },
4686 { 'c', "close", "close a door", doclose },
4688 { 'c', "close", "
\83h
\83A
\82ð
\95Â
\82ß
\82é", doclose },
4691 { M('C'), "conduct", "list voluntary challenges you have maintained",
4693 { M('C'), "conduct", "
\82Ç
\82¤
\82¢
\82¤
\8ds
\93®
\82ð
\82Æ
\82Á
\82½
\82©
\8c©
\82é",
4695 doconduct, IFBURIED | AUTOCOMPLETE },
4697 { M('d'), "dip", "dip an object into something", dodip, AUTOCOMPLETE },
4699 { M('d'), "dip", "
\89½
\82©
\82É
\95¨
\82ð
\90Z
\82·", dodip, AUTOCOMPLETE },
4701 { '>', "down", "go down a staircase", dodown },
4702 { 'd', "drop", "drop an item", dodrop },
4703 { 'D', "droptype", "drop specific item types", doddrop },
4704 { 'e', "eat", "eat something", doeat },
4705 { 'E', "engrave", "engrave writing on the floor", doengrave },
4707 { M('e'), "enhance", "advance or check weapon and spell skills",
4709 { M('e'), "enhance", "
\95\90\8aí
\8fn
\97û
\93x
\82ð
\8d\82\82ß
\82é",
4711 enhance_weapon_skill, IFBURIED | AUTOCOMPLETE },
4713 { '\0', "exploremode", "enter explore (discovery) mode",
4715 { '\0', "exploremode", "
\92T
\8c\9f(
\94
\8c©)
\83\82\81[
\83h
\82É
\93ü
\82é",
4717 enter_explore_mode, IFBURIED },
4718 { 'f', "fire", "fire ammunition from quiver", dofire },
4720 { M('f'), "force", "force a lock", doforce, AUTOCOMPLETE },
4722 { M('f'), "force", "
\8c®
\82ð
\82±
\82¶
\82 \82¯
\82é", doforce, AUTOCOMPLETE },
4724 { ';', "glance", "show what type of thing a map symbol corresponds to",
4725 doquickwhatis, IFBURIED | GENERALCMD },
4726 { '?', "help", "give a help message", dohelp, IFBURIED | GENERALCMD },
4727 { '\0', "herecmdmenu", "show menu of commands you can do here",
4728 doherecmdmenu, IFBURIED },
4729 { 'V', "history", "show long version and game history",
4730 dohistory, IFBURIED | GENERALCMD },
4731 { 'i', "inventory", "show your inventory", ddoinv, IFBURIED },
4732 { 'I', "inventtype", "inventory specific item types",
4733 dotypeinv, IFBURIED },
4735 { M('i'), "invoke", "invoke an object's special powers",
4737 { M('i'), "invoke", "
\95¨
\82Ì
\93Á
\95Ê
\82È
\97Í
\82ð
\8eg
\82¤",
4739 doinvoke, IFBURIED | AUTOCOMPLETE },
4741 { M('j'), "jump", "jump to another location", dojump, AUTOCOMPLETE },
4743 { M('j'), "jump", "
\91¼
\82Ì
\88Ê
\92u
\82É
\94ò
\82Ñ
\82¤
\82Â
\82é", dojump, AUTOCOMPLETE },
4745 { C('d'), "kick", "kick something", dokick },
4746 { '\\', "known", "show what object types have been discovered",
4747 dodiscovered, IFBURIED | GENERALCMD },
4748 { '`', "knownclass", "show discovered types for one class of objects",
4749 doclassdisco, IFBURIED | GENERALCMD },
4751 { '\0', "levelchange", "change experience level",
4753 { '\0', "levelchange", "
\8co
\8c±
\83\8c\83x
\83\8b\82ð
\95Ï
\82¦
\82é",
4755 wiz_level_change, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4757 { '\0', "lightsources", "show mobile light sources",
4759 { '\0', "lightsources", "
\88Ú
\93®
\8cõ
\8c¹
\82ð
\8c©
\82é",
4761 wiz_light_sources, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4762 { ':', "look", "look at what is here", dolook, IFBURIED },
4764 { M('l'), "loot", "loot a box on the floor", doloot, AUTOCOMPLETE },
4766 { M('l'), "loot", "
\8f°
\82Ì
\8fã
\82Ì
\94 \82ð
\8aJ
\82¯
\82é", doloot, AUTOCOMPLETE },
4768 #ifdef DEBUG_MIGRATING_MONS
4770 { '\0', "migratemons", "migrate N random monsters",
4772 { '\0', "migratemons", "
\83\89\83\93\83_
\83\80\82È
\89ö
\95¨
\82ð
\89½
\91Ì
\82©
\88Ú
\8fZ
\82³
\82¹
\82é",
4774 wiz_migrate_mons, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4777 { M('m'), "monster", "use monster's special ability",
4779 { M('m'), "monster", "
\89ö
\95¨
\82Ì
\93Á
\95Ê
\94\
\97Í
\82ð
\8eg
\82¤",
4781 domonability, IFBURIED | AUTOCOMPLETE },
4783 { 'N', "name", "name a monster or an object",
4785 { 'N', "name", "
\83A
\83C
\83e
\83\80\82â
\95¨
\82É
\96¼
\91O
\82ð
\82Â
\82¯
\82é",
4787 docallcmd, IFBURIED | AUTOCOMPLETE },
4789 { M('o'), "offer", "offer a sacrifice to the gods",
4791 { M('o'), "offer", "
\90_
\82É
\8b\9f\95¨
\82ð
\95ù
\82°
\82é",
4793 dosacrifice, AUTOCOMPLETE },
4794 { 'o', "open", "open a door", doopen },
4795 { 'O', "options", "show option settings, possibly change them",
4796 doset, IFBURIED | GENERALCMD },
4798 { C('o'), "overview", "show a summary of the explored dungeon",
4800 { C('o'), "overview", "
\92T
\8dõ
\82µ
\82½
\96À
\8b{
\82Ì
\8aT
\97v
\82ð
\95\
\8e¦
\82·
\82é",
4802 dooverview, IFBURIED | AUTOCOMPLETE },
4804 { '\0', "panic", "test panic routine (fatal to game)",
4806 { '\0', "panic", "
\83p
\83j
\83b
\83N
\83\8b\81[
\83`
\83\93\82ð
\83e
\83X
\83g
\82·
\82é(
\92v
\96½
\93I)",
4808 wiz_panic, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4809 { 'p', "pay", "pay your shopping bill", dopay },
4810 { ',', "pickup", "pick up things at the current location", dopickup },
4812 { '\0', "polyself", "polymorph self",
4814 { '\0', "polyself", "
\95Ï
\89»
\82·
\82é",
4816 wiz_polyself, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4818 { M('p'), "pray", "pray to the gods for help",
4820 { M('p'), "pray", "
\90_
\82É
\8bF
\82é",
4822 dopray, IFBURIED | AUTOCOMPLETE },
4823 { C('p'), "prevmsg", "view recent game messages",
4824 doprev_message, IFBURIED | GENERALCMD },
4825 { 'P', "puton", "put on an accessory (ring, amulet, etc)", doputon },
4826 { 'q', "quaff", "quaff (drink) something", dodrink },
4828 { M('q'), "quit", "exit without saving current game",
4830 { M('q'), "quit", "
\83Z
\81[
\83u
\82µ
\82È
\82¢
\82Å
\8fI
\97¹",
4832 done2, IFBURIED | AUTOCOMPLETE | GENERALCMD },
4833 { 'Q', "quiver", "select ammunition for quiver", dowieldquiver },
4834 { 'r', "read", "read a scroll or spellbook", doread },
4835 { C('r'), "redraw", "redraw screen", doredraw, IFBURIED | GENERALCMD },
4836 { 'R', "remove", "remove an accessory (ring, amulet, etc)", doremring },
4838 { M('R'), "ride", "mount or dismount a saddled steed",
4840 { M('R'), "ride", "
\89ö
\95¨
\82É
\8fæ
\82é(
\82Ü
\82½
\82Í
\8d~
\82è
\82é)",
4842 doride, AUTOCOMPLETE },
4844 { M('r'), "rub", "rub a lamp or a stone", dorub, AUTOCOMPLETE },
4846 { M('r'), "rub", "
\83\89\83\93\83v
\82ð
\82±
\82·
\82é", dorub, AUTOCOMPLETE },
4848 { 'S', "save", "save the game and exit", dosave, IFBURIED | GENERALCMD },
4850 { 's', "search", "search for traps and secret doors",
4851 dosearch, IFBURIED, "searching" },
4853 { 's', "search", "ã©
\82â
\89B
\82µ
\94à
\82ð
\92T
\82·",
4854 dosearch, IFBURIED, "
\92T
\82·" },
4856 { '*', "seeall", "show all equipment in use", doprinuse, IFBURIED },
4857 { AMULET_SYM, "seeamulet", "show the amulet currently worn",
4858 dopramulet, IFBURIED },
4859 { ARMOR_SYM, "seearmor", "show the armor currently worn",
4860 doprarm, IFBURIED },
4861 { GOLD_SYM, "seegold", "count your gold", doprgold, IFBURIED },
4863 { '\0', "seenv", "show seen vectors",
4865 { '\0', "seenv", "
\8e\8b\90ü
\83x
\83N
\83g
\83\8b\82ð
\8c©
\82é",
4867 wiz_show_seenv, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4868 { RING_SYM, "seerings", "show the ring(s) currently worn",
4869 doprring, IFBURIED },
4870 { SPBOOK_SYM, "seespells", "list and reorder known spells",
4871 dovspell, IFBURIED },
4872 { TOOL_SYM, "seetools", "show the tools currently in use",
4873 doprtool, IFBURIED },
4874 { '^', "seetrap", "show the type of adjacent trap", doidtrap, IFBURIED },
4875 { WEAPON_SYM, "seeweapon", "show the weapon currently wielded",
4876 doprwep, IFBURIED },
4877 { '!', "shell", "do a shell escape",
4878 dosh_core, IFBURIED | GENERALCMD
4884 { M('s'), "sit", "sit down", dosit, AUTOCOMPLETE },
4886 { M('s'), "sit", "
\8dÀ
\82é", dosit, AUTOCOMPLETE },
4889 { '\0', "stats", "show memory statistics",
4891 { '\0', "stats", "
\83\81\83\82\83\8a\8fó
\91Ô
\82ð
\8c©
\82é",
4893 wiz_show_stats, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4894 { C('z'), "suspend", "suspend the game",
4895 dosuspend_core, IFBURIED | GENERALCMD
4898 #endif /* SUSPEND */
4900 { 'x', "swap", "swap wielded and secondary weapons", doswapweapon },
4901 { 'T', "takeoff", "take off one piece of armor", dotakeoff },
4902 { 'A', "takeoffall", "remove all armor", doddoremarm },
4903 { C('t'), "teleport", "teleport around the level", dotelecmd, IFBURIED },
4905 { '\0', "terrain", "show map without obstructions",
4907 { '\0', "terrain", "
\8e×
\96\82\82³
\82ê
\82¸
\82É
\92n
\90}
\82ð
\8c©
\82é",
4909 doterrain, IFBURIED | AUTOCOMPLETE },
4910 { '\0', "therecmdmenu",
4911 "menu of commands you can do from here to adjacent spot",
4913 { 't', "throw", "throw something", dothrow },
4915 { '\0', "timeout", "look at timeout queue and hero's timed intrinsics",
4917 { '\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é",
4919 wiz_timeout_queue, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4921 { M('T'), "tip", "empty a container", dotip, AUTOCOMPLETE },
4923 { M('T'), "tip", "
\93ü
\82ê
\95¨
\82ð
\8bó
\82É
\82·
\82é", dotip, AUTOCOMPLETE },
4925 { '_', "travel", "travel to a specific location on the map", dotravel },
4927 { M('t'), "turn", "turn undead away", doturn, IFBURIED | AUTOCOMPLETE },
4929 { M('t'), "turn", "
\83A
\83\93\83f
\83b
\83g
\82ð
\93y
\82É
\95Ô
\82·", doturn, IFBURIED | AUTOCOMPLETE },
4932 { 'X', "twoweapon", "toggle two-weapon combat",
4934 { 'X', "twoweapon", "
\97¼
\8eè
\8e\9d\82¿
\82Ì
\90Ø
\82è
\91Ö
\82¦",
4936 dotwoweapon, AUTOCOMPLETE },
4938 { M('u'), "untrap", "untrap something", dountrap, AUTOCOMPLETE },
4940 { M('u'), "untrap", "ã©
\82ð
\82Í
\82¸
\82·", dountrap, AUTOCOMPLETE },
4942 { '<', "up", "go up a staircase", doup },
4944 { '\0', "vanquished", "list vanquished monsters",
4946 { '\0', "vanquished", "
\93|
\82µ
\82½
\89ö
\95¨
\82Ì
\88ê
\97\97\82ð
\8c©
\82é",
4948 dovanquished, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4949 { M('v'), "version",
4951 "list compile time options for this version of NetHack",
4953 "
\83R
\83\93\83p
\83C
\83\8b\8e\9e\82Ì
\83I
\83v
\83V
\83\87\83\93\82ð
\95\
\8e¦
\82·
\82é",
4955 doextversion, IFBURIED | AUTOCOMPLETE | GENERALCMD },
4956 { 'v', "versionshort", "show version", doversion, IFBURIED | GENERALCMD },
4958 { '\0', "vision", "show vision array",
4960 { '\0', "vision", "
\8e\8b\8aE
\94z
\97ñ
\82ð
\8c©
\82é",
4962 wiz_show_vision, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4964 { '.', "wait", "rest one move while doing nothing",
4965 donull, IFBURIED, "waiting" },
4967 { '.', "wait", "
\88ê
\95à
\95ª
\89½
\82à
\82µ
\82È
\82¢",
4968 donull, IFBURIED, "
\8bx
\8ce
\82·
\82é" },
4970 { 'W', "wear", "wear a piece of armor", dowear },
4971 { '&', "whatdoes", "tell what a command does", dowhatdoes, IFBURIED },
4972 { '/', "whatis", "show what type of thing a symbol corresponds to",
4973 dowhatis, IFBURIED | GENERALCMD },
4974 { 'w', "wield", "wield (put in use) a weapon", dowield },
4976 { M('w'), "wipe", "wipe off your face", dowipe, AUTOCOMPLETE },
4978 { M('w'), "wipe", "
\8aç
\82ð
\90@
\82¤", dowipe, AUTOCOMPLETE },
4982 { '\0', "wizbury", "bury objs under and around you",
4984 { '\0', "wizbury", "
\95¨
\82ð
\82 \82È
\82½
\82Ì
\8eü
\82è
\82É
\96\84\82ß
\82é",
4986 wiz_debug_cmd_bury, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4988 { C('e'), "wizdetect", "reveal hidden things within a small radius",
4989 wiz_detect, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4990 { C('g'), "wizgenesis", "create a monster",
4991 wiz_genesis, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4992 { C('i'), "wizidentify", "identify all items in inventory",
4993 wiz_identify, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4994 { '\0', "wizintrinsic", "set an intrinsic",
4995 wiz_intrinsic, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4996 { C('v'), "wizlevelport", "teleport to another level",
4997 wiz_level_tele, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4998 { '\0', "wizmakemap", "recreate the current level",
4999 wiz_makemap, IFBURIED | WIZMODECMD },
5000 { C('f'), "wizmap", "map the level",
5001 wiz_map, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
5003 { '\0', "wizrumorcheck", "verify rumor boundaries",
5005 { '\0', "wizrumorcheck", "
\89\
\82Ì
\8b«
\8aE
\82ð
\8c\9f\8fØ
\82·
\82é",
5007 wiz_rumor_check, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
5009 { '\0', "wizsmell", "smell monster",
5011 { '\0', "wizsmell", "
\89ö
\95¨
\82Ì
\93õ
\82¢
\82ð
\9ak
\82®",
5013 wiz_smell, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
5014 { '\0', "wizwhere", "show locations of special levels",
5015 wiz_where, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
5016 { C('w'), "wizwish", "wish for something",
5017 wiz_wish, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
5019 { '\0', "wmode", "show wall modes",
5021 { '\0', "wmode", "
\95Ç
\83\82\81[
\83h
\82ð
\8c©
\82é",
5023 wiz_show_wmodes, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
5024 { 'z', "zap", "zap a wand", dozap },
5025 { '\0', (char *) 0, (char *) 0, donull, 0, (char *) 0 } /* sentinel */
5028 /* for key2extcmddesc() to support dowhatdoes() */
5030 uchar k1, k2, k3, k4; /* 'normal', 'qwertz', 'numpad', 'phone' */
5031 const char *txt, *alt; /* compass direction, screen direction */
5033 static const struct movcmd movtab[] = {
5034 { 'h', 'h', '4', '4', "west", "left" },
5035 { 'j', 'j', '2', '8', "south", "down" },
5036 { 'k', 'k', '8', '2', "north", "up" },
5037 { 'l', 'l', '6', '6', "east", "right" },
5038 { 'b', 'b', '1', '7', "southwest", "lower left" },
5039 { 'n', 'n', '3', '9', "southeast", "lower right" },
5040 { 'u', 'u', '9', '3', "northeast", "upper right" },
5041 { 'y', 'z', '7', '1', "northwest", "upper left" },
5042 { 0, 0, 0, 0, (char *) 0, (char *) 0 }
5045 int extcmdlist_length = SIZE(extcmdlist) - 1;
5051 static char key2cmdbuf[48];
5052 const struct movcmd *mov;
5054 uchar M_5 = (uchar) M('5'), M_0 = (uchar) M('0');
5056 /* need to check for movement commands before checking the extended
5057 commands table because it contains entries for number_pad commands
5058 that match !number_pad movement (like 'j' for "jump") */
5059 key2cmdbuf[0] = '\0';
5060 if (movecmd(k = key))
5061 Strcpy(key2cmdbuf, "move"); /* "move or attack"? */
5062 else if (movecmd(k = unctrl(key)))
5063 Strcpy(key2cmdbuf, "rush");
5064 else if (movecmd(k = (Cmd.num_pad ? unmeta(key) : lowc(key))))
5065 Strcpy(key2cmdbuf, "run");
5067 for (mov = &movtab[0]; mov->k1; ++mov) {
5068 c = !Cmd.num_pad ? (!Cmd.swap_yz ? mov->k1 : mov->k2)
5069 : (!Cmd.phone_layout ? mov->k3 : mov->k4);
5071 Sprintf(eos(key2cmdbuf), " %s (screen %s)",
5072 mov->txt, mov->alt);
5076 } else if (digit(key) || (Cmd.num_pad && digit(unmeta(key)))) {
5077 key2cmdbuf[0] = '\0';
5079 Strcpy(key2cmdbuf, "start of, or continuation of, a count");
5080 else if (key == '5' || key == M_5)
5081 Sprintf(key2cmdbuf, "%s prefix",
5082 (!!Cmd.pcHack_compat ^ (key == M_5)) ? "run" : "rush");
5083 else if (key == '0' || (Cmd.pcHack_compat && key == M_0))
5084 Strcpy(key2cmdbuf, "synonym for 'i'");
5088 if (Cmd.commands[key]) {
5089 if (Cmd.commands[key]->ef_txt)
5090 return Cmd.commands[key]->ef_desc;
5097 bind_key(key, command)
5099 const char *command;
5101 struct ext_func_tab *extcmd;
5103 /* special case: "nothing" is reserved for unbinding */
5104 if (!strcmp(command, "nothing")) {
5105 Cmd.commands[key] = (struct ext_func_tab *) 0;
5109 for (extcmd = extcmdlist; extcmd->ef_txt; extcmd++) {
5110 if (strcmp(command, extcmd->ef_txt))
5112 Cmd.commands[key] = extcmd;
5113 #if 0 /* silently accept key binding for unavailable command (!SHELL,&c) */
5114 if ((extcmd->flags & CMD_NOT_AVAILABLE) != 0) {
5117 Sprintf(buf, cmdnotavail, extcmd->ef_txt);
5118 config_error_add("%s", buf);
5127 /* initialize all keyboard commands */
5131 struct ext_func_tab *extcmd;
5133 for (extcmd = extcmdlist; extcmd->ef_txt; extcmd++)
5135 Cmd.commands[extcmd->key] = extcmd;
5137 (void) bind_key(C('l'), "redraw"); /* if number_pad is set */
5138 /* 'b', 'B' : go sw */
5139 /* 'F' : fight (one time) */
5140 /* 'g', 'G' : multiple go */
5141 /* 'h', 'H' : go west */
5142 (void) bind_key('h', "help"); /* if number_pad is set */
5143 (void) bind_key('j', "jump"); /* if number_pad is on */
5144 /* 'j', 'J', 'k', 'K', 'l', 'L', 'm', 'M', 'n', 'N' move commands */
5145 (void) bind_key('k', "kick"); /* if number_pad is on */
5146 (void) bind_key('l', "loot"); /* if number_pad is on */
5147 (void) bind_key(C('n'), "annotate"); /* if number_pad is on */
5148 (void) bind_key(M('n'), "name");
5149 (void) bind_key(M('N'), "name");
5150 (void) bind_key('u', "untrap"); /* if number_pad is on */
5153 (void) bind_key(M('O'), "overview");
5154 (void) bind_key(M('2'), "twoweapon");
5157 (void) bind_key(' ', "wait");
5161 dokeylist_putcmds(datawin, docount, cmdflags, exflags, keys_used)
5164 int cmdflags, exflags;
5165 boolean *keys_used; /* boolean keys_used[256] */
5172 for (i = 0; i < 256; i++) {
5173 const struct ext_func_tab *extcmd;
5174 uchar key = (uchar) i;
5178 if (key == ' ' && !flags.rest_on_space)
5180 if ((extcmd = Cmd.commands[i]) != (struct ext_func_tab *) 0) {
5181 if ((cmdflags && !(extcmd->flags & cmdflags))
5182 || (exflags && (extcmd->flags & exflags)))
5188 Sprintf(buf, "%-8s %-12s %s", key2txt(key, buf2),
5191 putstr(datawin, 0, buf);
5192 keys_used[i] = TRUE;
5198 /* list all keys and their bindings, like dat/hh but dynamic */
5200 dokeylist(VOID_ARGS)
5202 char buf[BUFSZ], buf2[BUFSZ];
5204 boolean keys_used[256] = {0};
5208 run_desc[] = "Prefix: run until something very interesting is seen",
5210 "Prefix: force fight even if you don't see a monster";
5211 static const struct {
5216 { NHKF_ESC, "escape from the current query/action", FALSE },
5218 "Prefix: rush until something interesting is seen", FALSE },
5219 { NHKF_RUN, run_desc, FALSE },
5220 { NHKF_RUN2, run_desc, TRUE },
5221 { NHKF_FIGHT, forcefight_desc, FALSE },
5222 { NHKF_FIGHT2, forcefight_desc, TRUE } ,
5224 "Prefix: move without picking up objects/fighting", FALSE },
5225 { NHKF_RUN_NOPICKUP,
5226 "Prefix: run without picking up objects/fighting", FALSE },
5227 { NHKF_DOINV, "view inventory", TRUE },
5228 { NHKF_REQMENU, "Prefix: request a menu", FALSE },
5230 { NHKF_DOAGAIN , "re-do: perform the previous command again", FALSE },
5232 { 0, (const char *) 0, FALSE }
5235 datawin = create_nhwindow(NHW_TEXT);
5236 putstr(datawin, 0, "");
5237 putstr(datawin, 0, " Full Current Key Bindings List");
5239 /* directional keys */
5240 putstr(datawin, 0, "");
5241 putstr(datawin, 0, "Directional keys:");
5242 show_direction_keys(datawin, '.', FALSE); /* '.'==self in direction grid */
5244 keys_used[(uchar) Cmd.move_NW] = keys_used[(uchar) Cmd.move_N]
5245 = keys_used[(uchar) Cmd.move_NE] = keys_used[(uchar) Cmd.move_W]
5246 = keys_used[(uchar) Cmd.move_E] = keys_used[(uchar) Cmd.move_SW]
5247 = keys_used[(uchar) Cmd.move_S] = keys_used[(uchar) Cmd.move_SE]
5250 if (!iflags.num_pad) {
5251 keys_used[(uchar) highc(Cmd.move_NW)]
5252 = keys_used[(uchar) highc(Cmd.move_N)]
5253 = keys_used[(uchar) highc(Cmd.move_NE)]
5254 = keys_used[(uchar) highc(Cmd.move_W)]
5255 = keys_used[(uchar) highc(Cmd.move_E)]
5256 = keys_used[(uchar) highc(Cmd.move_SW)]
5257 = keys_used[(uchar) highc(Cmd.move_S)]
5258 = keys_used[(uchar) highc(Cmd.move_SE)] = TRUE;
5259 keys_used[(uchar) C(Cmd.move_NW)]
5260 = keys_used[(uchar) C(Cmd.move_N)]
5261 = keys_used[(uchar) C(Cmd.move_NE)]
5262 = keys_used[(uchar) C(Cmd.move_W)]
5263 = keys_used[(uchar) C(Cmd.move_E)]
5264 = keys_used[(uchar) C(Cmd.move_SW)]
5265 = keys_used[(uchar) C(Cmd.move_S)]
5266 = keys_used[(uchar) C(Cmd.move_SE)] = TRUE;
5267 putstr(datawin, 0, "");
5269 "Shift-<direction> will move in specified direction until you hit");
5270 putstr(datawin, 0, " a wall or run into something.");
5272 "Ctrl-<direction> will run in specified direction until something");
5273 putstr(datawin, 0, " very interesting is seen.");
5276 putstr(datawin, 0, "");
5277 putstr(datawin, 0, "Miscellaneous keys:");
5278 for (i = 0; misc_keys[i].desc; i++) {
5279 key = Cmd.spkeys[misc_keys[i].nhkf];
5280 if (key && ((misc_keys[i].numpad && iflags.num_pad)
5281 || !misc_keys[i].numpad)) {
5282 keys_used[(uchar) key] = TRUE;
5283 Sprintf(buf, "%-8s %s", key2txt(key, buf2), misc_keys[i].desc);
5284 putstr(datawin, 0, buf);
5288 putstr(datawin, 0, "^c break out of NetHack (SIGINT)");
5289 keys_used[(uchar) C('c')] = TRUE;
5292 putstr(datawin, 0, "");
5293 show_menu_controls(datawin, TRUE);
5295 if (dokeylist_putcmds(datawin, TRUE, GENERALCMD, WIZMODECMD, keys_used)) {
5296 putstr(datawin, 0, "");
5297 putstr(datawin, 0, "General commands:");
5298 (void) dokeylist_putcmds(datawin, FALSE, GENERALCMD, WIZMODECMD,
5302 if (dokeylist_putcmds(datawin, TRUE, 0, WIZMODECMD, keys_used)) {
5303 putstr(datawin, 0, "");
5304 putstr(datawin, 0, "Game commands:");
5305 (void) dokeylist_putcmds(datawin, FALSE, 0, WIZMODECMD, keys_used);
5309 && dokeylist_putcmds(datawin, TRUE, WIZMODECMD, 0, keys_used)) {
5310 putstr(datawin, 0, "");
5311 putstr(datawin, 0, "Wizard-mode commands:");
5312 (void) dokeylist_putcmds(datawin, FALSE, WIZMODECMD, 0, keys_used);
5315 display_nhwindow(datawin, FALSE);
5316 destroy_nhwindow(datawin);
5325 for (i = 0; i < 256; ++i)
5326 if (Cmd.commands[i] && Cmd.commands[i]->ef_funct == fn)
5332 * wizard mode sanity_check code
5335 static const char template[] = "%-27s %4ld %6ld";
5336 static const char stats_hdr[] = " count bytes";
5337 static const char stats_sep[] = "--------------------------- ----- -------";
5343 int sz = (int) sizeof (struct obj);
5346 sz += (int) sizeof (struct oextra);
5348 sz += (int) strlen(ONAME(otmp)) + 1;
5350 sz += size_monst(OMONST(otmp), FALSE);
5352 sz += (int) sizeof (unsigned);
5354 sz += (int) sizeof (long);
5356 sz += (int) strlen(OMAILCMD(otmp)) + 1;
5362 count_obj(chain, total_count, total_size, top, recurse)
5372 for (count = size = 0, obj = chain; obj; obj = obj->nobj) {
5375 size += size_obj(obj);
5377 if (recurse && obj->cobj)
5378 count_obj(obj->cobj, total_count, total_size, TRUE, TRUE);
5380 *total_count += count;
5381 *total_size += size;
5385 obj_chain(win, src, chain, force, total_count, total_size)
5394 long count = 0L, size = 0L;
5396 count_obj(chain, &count, &size, TRUE, FALSE);
5398 if (count || size || force) {
5399 *total_count += count;
5400 *total_size += size;
5401 Sprintf(buf, template, src, count, size);
5402 putstr(win, 0, buf);
5407 mon_invent_chain(win, src, chain, total_count, total_size)
5410 struct monst *chain;
5415 long count = 0, size = 0;
5418 for (mon = chain; mon; mon = mon->nmon)
5419 count_obj(mon->minvent, &count, &size, TRUE, FALSE);
5421 if (count || size) {
5422 *total_count += count;
5423 *total_size += size;
5424 Sprintf(buf, template, src, count, size);
5425 putstr(win, 0, buf);
5430 contained_stats(win, src, total_count, total_size)
5437 long count = 0, size = 0;
5440 count_obj(invent, &count, &size, FALSE, TRUE);
5441 count_obj(fobj, &count, &size, FALSE, TRUE);
5442 count_obj(level.buriedobjlist, &count, &size, FALSE, TRUE);
5443 count_obj(migrating_objs, &count, &size, FALSE, TRUE);
5444 /* DEADMONSTER check not required in this loop since they have no
5446 for (mon = fmon; mon; mon = mon->nmon)
5447 count_obj(mon->minvent, &count, &size, FALSE, TRUE);
5448 for (mon = migrating_mons; mon; mon = mon->nmon)
5449 count_obj(mon->minvent, &count, &size, FALSE, TRUE);
5451 if (count || size) {
5452 *total_count += count;
5453 *total_size += size;
5454 Sprintf(buf, template, src, count, size);
5455 putstr(win, 0, buf);
5460 size_monst(mtmp, incl_wsegs)
5464 int sz = (int) sizeof (struct monst);
5466 if (mtmp->wormno && incl_wsegs)
5467 sz += size_wseg(mtmp);
5470 sz += (int) sizeof (struct mextra);
5472 sz += (int) strlen(MNAME(mtmp)) + 1;
5474 sz += (int) sizeof (struct egd);
5476 sz += (int) sizeof (struct epri);
5478 sz += (int) sizeof (struct eshk);
5480 sz += (int) sizeof (struct emin);
5482 sz += (int) sizeof (struct edog);
5483 /* mextra->mcorpsenm doesn't point to more memory */
5489 mon_chain(win, src, chain, force, total_count, total_size)
5492 struct monst *chain;
5500 /* mon->wormno means something different for migrating_mons and mydogs */
5501 boolean incl_wsegs = !strcmpi(src, "fmon");
5504 for (mon = chain; mon; mon = mon->nmon) {
5506 size += size_monst(mon, incl_wsegs);
5508 if (count || size || force) {
5509 *total_count += count;
5510 *total_size += size;
5511 Sprintf(buf, template, src, count, size);
5512 putstr(win, 0, buf);
5517 misc_stats(win, total_count, total_size)
5522 char buf[BUFSZ], hdrbuf[QBUFSZ];
5526 struct damage *sd; /* shop damage */
5527 struct kinfo *k; /* delayed killer */
5528 struct cemetery *bi; /* bones info */
5530 /* traps and engravings are output unconditionally;
5531 * others only if nonzero
5534 for (tt = ftrap; tt; tt = tt->ntrap) {
5536 size += (long) sizeof *tt;
5538 *total_count += count;
5539 *total_size += size;
5540 Sprintf(hdrbuf, "traps, size %ld", (long) sizeof (struct trap));
5541 Sprintf(buf, template, hdrbuf, count, size);
5542 putstr(win, 0, buf);
5545 engr_stats("engravings, size %ld+text", hdrbuf, &count, &size);
5546 *total_count += count;
5547 *total_size += size;
5548 Sprintf(buf, template, hdrbuf, count, size);
5549 putstr(win, 0, buf);
5552 light_stats("light sources, size %ld", hdrbuf, &count, &size);
5553 if (count || size) {
5554 *total_count += count;
5555 *total_size += size;
5556 Sprintf(buf, template, hdrbuf, count, size);
5557 putstr(win, 0, buf);
5561 timer_stats("timers, size %ld", hdrbuf, &count, &size);
5562 if (count || size) {
5563 *total_count += count;
5564 *total_size += size;
5565 Sprintf(buf, template, hdrbuf, count, size);
5566 putstr(win, 0, buf);
5570 for (sd = level.damagelist; sd; sd = sd->next) {
5572 size += (long) sizeof *sd;
5574 if (count || size) {
5575 *total_count += count;
5576 *total_size += size;
5577 Sprintf(hdrbuf, "shop damage, size %ld",
5578 (long) sizeof (struct damage));
5579 Sprintf(buf, template, hdrbuf, count, size);
5580 putstr(win, 0, buf);
5584 region_stats("regions, size %ld+%ld*rect+N", hdrbuf, &count, &size);
5585 if (count || size) {
5586 *total_count += count;
5587 *total_size += size;
5588 Sprintf(buf, template, hdrbuf, count, size);
5589 putstr(win, 0, buf);
5593 for (k = killer.next; k; k = k->next) {
5595 size += (long) sizeof *k;
5597 if (count || size) {
5598 *total_count += count;
5599 *total_size += size;
5600 Sprintf(hdrbuf, "delayed killer%s, size %ld",
5601 plur(count), (long) sizeof (struct kinfo));
5602 Sprintf(buf, template, hdrbuf, count, size);
5603 putstr(win, 0, buf);
5607 for (bi = level.bonesinfo; bi; bi = bi->next) {
5609 size += (long) sizeof *bi;
5611 if (count || size) {
5612 *total_count += count;
5613 *total_size += size;
5614 Sprintf(hdrbuf, "bones history, size %ld",
5615 (long) sizeof (struct cemetery));
5616 Sprintf(buf, template, hdrbuf, count, size);
5617 putstr(win, 0, buf);
5621 for (idx = 0; idx < NUM_OBJECTS; ++idx)
5622 if (objects[idx].oc_uname) {
5624 size += (long) (strlen(objects[idx].oc_uname) + 1);
5626 if (count || size) {
5627 *total_count += count;
5628 *total_size += size;
5629 Strcpy(hdrbuf, "object type names, text");
5630 Sprintf(buf, template, hdrbuf, count, size);
5631 putstr(win, 0, buf);
5636 * Display memory usage of all monsters and objects on the level.
5643 long total_obj_size, total_obj_count,
5644 total_mon_size, total_mon_count,
5645 total_ovr_size, total_ovr_count,
5646 total_misc_size, total_misc_count;
5648 win = create_nhwindow(NHW_TEXT);
5649 putstr(win, 0, "Current memory statistics:");
5651 total_obj_count = total_obj_size = 0L;
5652 putstr(win, 0, stats_hdr);
5653 Sprintf(buf, " Objects, base size %ld", (long) sizeof (struct obj));
5654 putstr(win, 0, buf);
5655 obj_chain(win, "invent", invent, TRUE, &total_obj_count, &total_obj_size);
5656 obj_chain(win, "fobj", fobj, TRUE, &total_obj_count, &total_obj_size);
5657 obj_chain(win, "buried", level.buriedobjlist, FALSE,
5658 &total_obj_count, &total_obj_size);
5659 obj_chain(win, "migrating obj", migrating_objs, FALSE,
5660 &total_obj_count, &total_obj_size);
5661 obj_chain(win, "billobjs", billobjs, FALSE,
5662 &total_obj_count, &total_obj_size);
5663 mon_invent_chain(win, "minvent", fmon, &total_obj_count, &total_obj_size);
5664 mon_invent_chain(win, "migrating minvent", migrating_mons,
5665 &total_obj_count, &total_obj_size);
5666 contained_stats(win, "contained", &total_obj_count, &total_obj_size);
5667 putstr(win, 0, stats_sep);
5668 Sprintf(buf, template, " Obj total", total_obj_count, total_obj_size);
5669 putstr(win, 0, buf);
5671 total_mon_count = total_mon_size = 0L;
5673 Sprintf(buf, " Monsters, base size %ld", (long) sizeof (struct monst));
5674 putstr(win, 0, buf);
5675 mon_chain(win, "fmon", fmon, TRUE, &total_mon_count, &total_mon_size);
5676 mon_chain(win, "migrating", migrating_mons, FALSE,
5677 &total_mon_count, &total_mon_size);
5678 /* 'mydogs' is only valid during level change or end of game disclosure,
5679 but conceivably we've been called from within debugger at such time */
5680 if (mydogs) /* monsters accompanying hero */
5681 mon_chain(win, "mydogs", mydogs, FALSE,
5682 &total_mon_count, &total_mon_size);
5683 putstr(win, 0, stats_sep);
5684 Sprintf(buf, template, " Mon total", total_mon_count, total_mon_size);
5685 putstr(win, 0, buf);
5687 total_ovr_count = total_ovr_size = 0L;
5689 putstr(win, 0, " Overview");
5690 overview_stats(win, template, &total_ovr_count, &total_ovr_size);
5691 putstr(win, 0, stats_sep);
5692 Sprintf(buf, template, " Over total", total_ovr_count, total_ovr_size);
5693 putstr(win, 0, buf);
5695 total_misc_count = total_misc_size = 0L;
5697 putstr(win, 0, " Miscellaneous");
5698 misc_stats(win, &total_misc_count, &total_misc_size);
5699 putstr(win, 0, stats_sep);
5700 Sprintf(buf, template, " Misc total", total_misc_count, total_misc_size);
5701 putstr(win, 0, buf);
5704 putstr(win, 0, stats_sep);
5705 Sprintf(buf, template, " Grand total",
5706 (total_obj_count + total_mon_count
5707 + total_ovr_count + total_misc_count),
5708 (total_obj_size + total_mon_size
5709 + total_ovr_size + total_misc_size));
5710 putstr(win, 0, buf);
5712 #if defined(__BORLANDC__) && !defined(_WIN32)
5713 show_borlandc_stats(win);
5716 display_nhwindow(win, FALSE);
5717 destroy_nhwindow(win);
5725 timer_sanity_check();
5727 light_sources_sanity_check();
5731 #ifdef DEBUG_MIGRATING_MONS
5736 char inbuf[BUFSZ] = DUMMY;
5737 struct permonst *ptr;
5741 getlin("How many random monsters to migrate? [0]", inbuf);
5742 if (*inbuf == '\033')
5744 mcount = atoi(inbuf);
5745 if (mcount < 0 || mcount > (COLNO * ROWNO) || Is_botlevel(&u.uz))
5747 while (mcount > 0) {
5748 if (Is_stronghold(&u.uz))
5749 assign_level(&tolevel, &valley_level);
5751 get_level(&tolevel, depth(&u.uz) + 1);
5753 mtmp = makemon(ptr, 0, 0, NO_MM_FLAGS);
5755 migrate_to_level(mtmp, ledger_no(&tolevel), MIGR_RANDOM,
5767 } const spkeys_binds[] = {
5768 { NHKF_ESC, '\033', (char *) 0 }, /* no binding */
5769 { NHKF_DOAGAIN, DOAGAIN, "repeat" },
5770 { NHKF_REQMENU, 'm', "reqmenu" },
5771 { NHKF_RUN, 'G', "run" },
5772 { NHKF_RUN2, '5', "run.numpad" },
5773 { NHKF_RUSH, 'g', "rush" },
5774 { NHKF_FIGHT, 'F', "fight" },
5775 { NHKF_FIGHT2, '-', "fight.numpad" },
5776 { NHKF_NOPICKUP, 'm', "nopickup" },
5777 { NHKF_RUN_NOPICKUP, 'M', "run.nopickup" },
5778 { NHKF_DOINV, '0', "doinv" },
5779 { NHKF_TRAVEL, CMD_TRAVEL, (char *) 0 }, /* no binding */
5780 { NHKF_CLICKLOOK, CMD_CLICKLOOK, (char *) 0 }, /* no binding */
5781 { NHKF_REDRAW, C('r'), "redraw" },
5782 { NHKF_REDRAW2, C('l'), "redraw.numpad" },
5783 { NHKF_GETDIR_SELF, '.', "getdir.self" },
5784 { NHKF_GETDIR_SELF2, 's', "getdir.self2" },
5785 { NHKF_GETDIR_HELP, '?', "getdir.help" },
5786 { NHKF_COUNT, 'n', "count" },
5787 { NHKF_GETPOS_SELF, '@', "getpos.self" },
5788 { NHKF_GETPOS_PICK, '.', "getpos.pick" },
5789 { NHKF_GETPOS_PICK_Q, ',', "getpos.pick.quick" },
5790 { NHKF_GETPOS_PICK_O, ';', "getpos.pick.once" },
5791 { NHKF_GETPOS_PICK_V, ':', "getpos.pick.verbose" },
5792 { NHKF_GETPOS_SHOWVALID, '$', "getpos.valid" },
5793 { NHKF_GETPOS_AUTODESC, '#', "getpos.autodescribe" },
5794 { NHKF_GETPOS_MON_NEXT, 'm', "getpos.mon.next" },
5795 { NHKF_GETPOS_MON_PREV, 'M', "getpos.mon.prev" },
5796 { NHKF_GETPOS_OBJ_NEXT, 'o', "getpos.obj.next" },
5797 { NHKF_GETPOS_OBJ_PREV, 'O', "getpos.obj.prev" },
5798 { NHKF_GETPOS_DOOR_NEXT, 'd', "getpos.door.next" },
5799 { NHKF_GETPOS_DOOR_PREV, 'D', "getpos.door.prev" },
5800 { NHKF_GETPOS_UNEX_NEXT, 'x', "getpos.unexplored.next" },
5801 { NHKF_GETPOS_UNEX_PREV, 'X', "getpos.unexplored.prev" },
5802 { NHKF_GETPOS_VALID_NEXT, 'z', "getpos.valid.next" },
5803 { NHKF_GETPOS_VALID_PREV, 'Z', "getpos.valid.prev" },
5804 { NHKF_GETPOS_INTERESTING_NEXT, 'a', "getpos.all.next" },
5805 { NHKF_GETPOS_INTERESTING_PREV, 'A', "getpos.all.prev" },
5806 { NHKF_GETPOS_HELP, '?', "getpos.help" },
5807 { NHKF_GETPOS_LIMITVIEW, '"', "getpos.filter" },
5808 { NHKF_GETPOS_MOVESKIP, '*', "getpos.moveskip" },
5809 { NHKF_GETPOS_MENU, '!', "getpos.menu" }
5813 bind_specialkey(key, command)
5815 const char *command;
5818 for (i = 0; i < SIZE(spkeys_binds); i++) {
5819 if (!spkeys_binds[i].name || strcmp(command, spkeys_binds[i].name))
5821 Cmd.spkeys[spkeys_binds[i].nhkf] = key;
5827 /* returns a one-byte character from the text (it may massacre the txt
5833 txt = trimspaces(txt);
5837 /* simple character */
5841 /* a few special entries */
5842 if (!strcmp(txt, "<enter>"))
5844 if (!strcmp(txt, "<space>"))
5846 if (!strcmp(txt, "<esc>"))
5849 /* control and meta keys */
5851 case 'm': /* can be mx, Mx, m-x, M-x */
5854 if (*txt == '-' && txt[1])
5859 case 'c': /* can be cx, Cx, ^x, c-x, C-x, ^-x */
5863 if (*txt == '-' && txt[1])
5870 /* ascii codes: must be three-digit decimal */
5871 if (*txt >= '0' && *txt <= '9') {
5875 for (i = 0; i < 3; i++) {
5876 if (txt[i] < '0' || txt[i] > '9')
5878 key = 10 * key + txt[i] - '0';
5886 /* returns the text for a one-byte encoding;
5887 * must be shorter than a tab for proper formatting */
5891 char *txt; /* sufficiently long buffer */
5893 /* should probably switch to "SPC", "ESC", "RET"
5894 since nethack's documentation uses ESC for <escape> */
5896 Sprintf(txt, "<space>");
5897 else if (c == '\033')
5898 Sprintf(txt, "<esc>");
5900 Sprintf(txt, "<enter>");
5901 else if (c == '\177')
5902 Sprintf(txt, "<del>"); /* "<delete>" won't fit */
5904 Strcpy(txt, visctrl((char) c));
5910 parseautocomplete(autocomplete, condition)
5914 struct ext_func_tab *efp;
5915 register char *autoc;
5917 /* break off first autocomplete from the rest; parse the rest */
5918 if ((autoc = index(autocomplete, ',')) != 0
5919 || (autoc = index(autocomplete, ':')) != 0) {
5921 parseautocomplete(autoc, condition);
5924 /* strip leading and trailing white space */
5925 autocomplete = trimspaces(autocomplete);
5930 /* take off negation */
5931 if (*autocomplete == '!') {
5932 /* unlike most options, a leading "no" might actually be a part of
5933 * the extended command. Thus you have to use ! */
5935 autocomplete = trimspaces(autocomplete);
5936 condition = !condition;
5939 /* find and modify the extended command */
5940 for (efp = extcmdlist; efp->ef_txt; efp++) {
5941 if (!strcmp(autocomplete, efp->ef_txt)) {
5943 efp->flags |= AUTOCOMPLETE;
5945 efp->flags &= ~AUTOCOMPLETE;
5950 /* not a real extended command */
5951 raw_printf("Bad autocomplete: invalid extended command '%s'.",
5956 /* called at startup and after number_pad is twiddled */
5958 reset_commands(initial)
5961 static const char sdir[] = "hykulnjb><",
5962 sdir_swap_yz[] = "hzkulnjb><",
5963 ndir[] = "47896321><",
5964 ndir_phone_layout[] = "41236987><";
5965 static const int ylist[] = {
5966 'y', 'Y', C('y'), M('y'), M('Y'), M(C('y'))
5968 static struct ext_func_tab *back_dir_cmd[8];
5969 const struct ext_func_tab *cmdtmp;
5971 int c, i, updated = 0;
5972 static boolean backed_dir_cmd = FALSE;
5976 Cmd.num_pad = FALSE;
5977 Cmd.pcHack_compat = Cmd.phone_layout = Cmd.swap_yz = FALSE;
5978 for (i = 0; i < SIZE(spkeys_binds); i++)
5979 Cmd.spkeys[spkeys_binds[i].nhkf] = spkeys_binds[i].key;
5983 if (backed_dir_cmd) {
5984 for (i = 0; i < 8; i++) {
5985 Cmd.commands[(uchar) Cmd.dirchars[i]] = back_dir_cmd[i];
5990 flagtemp = iflags.num_pad;
5991 if (flagtemp != Cmd.num_pad) {
5992 Cmd.num_pad = flagtemp;
5995 /* swap_yz mode (only applicable for !num_pad); intended for
5996 QWERTZ keyboard used in Central Europe, particularly Germany */
5997 flagtemp = (iflags.num_pad_mode & 1) ? !Cmd.num_pad : FALSE;
5998 if (flagtemp != Cmd.swap_yz) {
5999 Cmd.swap_yz = flagtemp;
6001 /* Cmd.swap_yz has been toggled;
6002 perform the swap (or reverse previous one) */
6003 for (i = 0; i < SIZE(ylist); i++) {
6004 c = ylist[i] & 0xff;
6005 cmdtmp = Cmd.commands[c]; /* tmp = [y] */
6006 Cmd.commands[c] = Cmd.commands[c + 1]; /* [y] = [z] */
6007 Cmd.commands[c + 1] = cmdtmp; /* [z] = tmp */
6010 /* MSDOS compatibility mode (only applicable for num_pad) */
6011 flagtemp = (iflags.num_pad_mode & 1) ? Cmd.num_pad : FALSE;
6012 if (flagtemp != Cmd.pcHack_compat) {
6013 Cmd.pcHack_compat = flagtemp;
6015 /* pcHack_compat has been toggled */
6017 cmdtmp = Cmd.commands['5'];
6018 Cmd.commands['5'] = Cmd.commands[c];
6019 Cmd.commands[c] = cmdtmp;
6021 Cmd.commands[c] = Cmd.pcHack_compat ? Cmd.commands['I'] : 0;
6023 /* phone keypad layout (only applicable for num_pad) */
6024 flagtemp = (iflags.num_pad_mode & 2) ? Cmd.num_pad : FALSE;
6025 if (flagtemp != Cmd.phone_layout) {
6026 Cmd.phone_layout = flagtemp;
6028 /* phone_layout has been toggled */
6029 for (i = 0; i < 3; i++) {
6030 c = '1' + i; /* 1,2,3 <-> 7,8,9 */
6031 cmdtmp = Cmd.commands[c]; /* tmp = [1] */
6032 Cmd.commands[c] = Cmd.commands[c + 6]; /* [1] = [7] */
6033 Cmd.commands[c + 6] = cmdtmp; /* [7] = tmp */
6034 c = (M('1') & 0xff) + i; /* M-1,M-2,M-3 <-> M-7,M-8,M-9 */
6035 cmdtmp = Cmd.commands[c]; /* tmp = [M-1] */
6036 Cmd.commands[c] = Cmd.commands[c + 6]; /* [M-1] = [M-7] */
6037 Cmd.commands[c + 6] = cmdtmp; /* [M-7] = tmp */
6044 Cmd.dirchars = !Cmd.num_pad
6045 ? (!Cmd.swap_yz ? sdir : sdir_swap_yz)
6046 : (!Cmd.phone_layout ? ndir : ndir_phone_layout);
6047 Cmd.alphadirchars = !Cmd.num_pad ? Cmd.dirchars : sdir;
6049 Cmd.move_W = Cmd.dirchars[0];
6050 Cmd.move_NW = Cmd.dirchars[1];
6051 Cmd.move_N = Cmd.dirchars[2];
6052 Cmd.move_NE = Cmd.dirchars[3];
6053 Cmd.move_E = Cmd.dirchars[4];
6054 Cmd.move_SE = Cmd.dirchars[5];
6055 Cmd.move_S = Cmd.dirchars[6];
6056 Cmd.move_SW = Cmd.dirchars[7];
6059 for (i = 0; i < 8; i++) {
6061 (struct ext_func_tab *) Cmd.commands[(uchar) Cmd.dirchars[i]];
6062 Cmd.commands[(uchar) Cmd.dirchars[i]] = (struct ext_func_tab *) 0;
6064 backed_dir_cmd = TRUE;
6065 for (i = 0; i < 8; i++)
6066 (void) bind_key(Cmd.dirchars[i], "nothing");
6070 /* non-movement commands which accept 'm' prefix to request menu operation */
6072 accept_menu_prefix(cmd_func)
6073 int NDECL((*cmd_func));
6075 if (cmd_func == dopickup || cmd_func == dotip
6076 /* eat, #offer, and apply tinning-kit all use floorfood() to pick
6077 an item on floor or in invent; 'm' skips picking from floor
6078 (ie, inventory only) rather than request use of menu operation */
6079 || cmd_func == doeat || cmd_func == dosacrifice || cmd_func == doapply
6080 /* 'm' for removing saddle from adjacent monster without checking
6081 for containers at <u.ux,u.uy> */
6082 || cmd_func == doloot
6083 /* travel: pop up a menu of interesting targets in view */
6084 || cmd_func == dotravel
6085 /* wizard mode ^V and ^T */
6086 || cmd_func == wiz_level_tele || cmd_func == dotelecmd
6087 /* 'm' prefix allowed for some extended commands */
6088 || cmd_func == doextcmd || cmd_func == doextlist)
6096 static unsigned i = 0;
6110 c = (char) rn1('~' - ' ' + 1, ' ');
6113 c = (char) (rn2(2) ? '\t' : ' ');
6116 c = (char) rn1('z' - 'a' + 1, 'a');
6119 c = (char) rn1('Z' - 'A' + 1, 'A');
6122 c = extcmdlist[i++ % SIZE(extcmdlist)].key;
6130 c = Cmd.dirchars[rn2(8)];
6132 c = !Cmd.num_pad ? (!rn2(3) ? C(c) : (c + 'A' - 'a')) : M(c);
6135 c = (char) rn1('9' - '0' + 1, '0');
6138 /* any char, but avoid '\0' because it's used for mouse click */
6139 c = (char) rnd(iflags.wc_eight_bit_input ? 255 : 127);
6147 random_response(buf, sz)
6169 rnd_extcmd_idx(VOID_ARGS)
6171 return rn2(extcmdlist_length + 1) - 1;
6175 ch2spkeys(c, start, end)
6181 for (i = start; i <= end; i++)
6182 if (Cmd.spkeys[i] == c)
6192 boolean prefix_seen, bad_command,
6193 firsttime = (cmd == 0);
6195 iflags.menu_requested = FALSE;
6197 if (program_state.done_hup)
6204 if (*cmd == Cmd.spkeys[NHKF_ESC]) {
6205 context.move = FALSE;
6208 if (*cmd == DOAGAIN && !in_doagain && saveq[0]) {
6211 rhack((char *) 0); /* read and execute command */
6215 /* Special case of *cmd == ' ' handled better below */
6216 if (!*cmd || *cmd == (char) 0377) {
6218 context.move = FALSE;
6219 return; /* probably we just had an interrupt */
6222 /* handle most movement commands */
6223 prefix_seen = FALSE;
6224 context.travel = context.travel1 = 0;
6225 spkey = ch2spkeys(*cmd, NHKF_RUN, NHKF_CLICKLOOK);
6229 if (movecmd(cmd[1])) {
6231 domove_attempting |= DOMOVE_RUSH;
6240 if (movecmd(lowc(cmd[1]))) {
6242 domove_attempting |= DOMOVE_RUSH;
6250 /* Effects of movement commands and invisible monsters:
6251 * m: always move onto space (even if 'I' remembered)
6252 * F: always attack space (even if 'I' not remembered)
6253 * normal movement: attack if 'I', move otherwise.
6256 if (movecmd(cmd[1])) {
6257 context.forcefight = 1;
6258 domove_attempting |= DOMOVE_WALK;
6263 if (movecmd(cmd[1]) || u.dz) {
6267 domove_attempting |= DOMOVE_WALK;
6269 cmd[0] = cmd[1]; /* "m<" or "m>" */
6273 case NHKF_RUN_NOPICKUP:
6274 if (movecmd(lowc(cmd[1]))) {
6277 domove_attempting |= DOMOVE_RUSH;
6284 (void) ddoinv(); /* a convenience borrowed from the PC */
6285 context.move = FALSE;
6288 case NHKF_CLICKLOOK:
6289 if (iflags.clicklook) {
6290 context.move = FALSE;
6291 do_look(2, &clicklook_cc);
6295 if (flags.travelcmd) {
6297 context.travel1 = 1;
6300 domove_attempting |= DOMOVE_RUSH;
6305 if (movecmd(*cmd)) { /* ordinary movement */
6306 context.run = 0; /* only matters here if it was 8 */
6307 domove_attempting |= DOMOVE_WALK;
6308 } else if (movecmd(Cmd.num_pad ? unmeta(*cmd) : lowc(*cmd))) {
6310 domove_attempting |= DOMOVE_RUSH;
6311 } else if (movecmd(unctrl(*cmd))) {
6313 domove_attempting |= DOMOVE_RUSH;
6318 /* some special prefix handling */
6319 /* overload 'm' prefix to mean "request a menu" */
6320 if (prefix_seen && cmd[0] == Cmd.spkeys[NHKF_REQMENU]) {
6321 /* (for func_tab cast, see below) */
6322 const struct ext_func_tab *ft = Cmd.commands[cmd[1] & 0xff];
6323 int NDECL((*func)) = ft ? ((struct ext_func_tab *) ft)->ef_funct : 0;
6325 if (func && accept_menu_prefix(func)) {
6326 iflags.menu_requested = TRUE;
6331 if (((domove_attempting & (DOMOVE_RUSH | DOMOVE_WALK)) != 0L)
6332 && !context.travel && !dxdy_moveok()) {
6333 /* trying to move diagonally as a grid bug;
6334 this used to be treated by movecmd() as not being
6335 a movement attempt, but that didn't provide for any
6336 feedback and led to strangeness if the key pressed
6337 ('u' in particular) was overloaded for num_pad use */
6339 You_cant("get there from here...");
6341 You_cant("
\82±
\82±
\82©
\82ç
\82»
\82±
\82Ö
\82Í
\8ds
\82¯
\82Ü
\82¹
\82ñ
\81D
\81D
\81D");
6343 context.nopick = context.forcefight = FALSE;
6344 context.move = context.mv = FALSE;
6349 if ((domove_attempting & DOMOVE_WALK) != 0L) {
6353 context.forcefight = 0;
6355 } else if ((domove_attempting & DOMOVE_RUSH) != 0L) {
6358 multi = max(COLNO, ROWNO);
6359 u.last_str_turn = 0;
6364 } else if (prefix_seen && cmd[1] == Cmd.spkeys[NHKF_ESC]) {
6365 /* <prefix><escape> */
6366 /* don't report "unknown command" for change of heart... */
6367 bad_command = FALSE;
6368 } else if (*cmd == ' ' && !flags.rest_on_space) {
6369 bad_command = TRUE; /* skip cmdlist[] loop */
6371 /* handle all other commands */
6373 register const struct ext_func_tab *tlist;
6374 int res, NDECL((*func));
6376 /* current - use *cmd to directly index cmdlist array */
6377 if ((tlist = Cmd.commands[*cmd & 0xff]) != 0) {
6378 if (!wizard && (tlist->flags & WIZMODECMD)) {
6380 You_cant("do that!");
6382 pline("
\82»
\82ê
\82Í
\82Å
\82«
\82Ü
\82¹
\82ñ
\81I");
6384 } else if (u.uburied && !(tlist->flags & IFBURIED)) {
6386 You_cant("do that while you are buried!");
6388 You("
\96\84\82Ü
\82Á
\82Ä
\82¢
\82é
\8e\9e\82É
\82»
\82ñ
\82È
\82±
\82Æ
\82Í
\82Å
\82«
\82È
\82¢
\81I");
6391 /* we discard 'const' because some compilers seem to have
6392 trouble with the pointer passed to set_occupation() */
6393 func = ((struct ext_func_tab *) tlist)->ef_funct;
6394 if (tlist->f_text && !occupation && multi)
6395 set_occupation(func, tlist->f_text, multi);
6396 res = (*func)(); /* perform the command */
6399 context.move = FALSE;
6404 /* if we reach here, cmd wasn't found in cmdlist[] */
6409 char expcmd[20]; /* we expect 'cmd' to point to 1 or 2 chars */
6410 char c, c1 = cmd[1];
6413 while ((c = *cmd++) != '\0')
6414 Strcat(expcmd, visctrl(c)); /* add 1..4 chars plus terminator */
6417 if (!prefix_seen || !help_dir(c1, spkey, "Invalid direction key!"))
6419 if (!prefix_seen || !help_dir(c1, spkey, "
\96³
\8cø
\82È
\95û
\8cü
\8ew
\92è
\82Å
\82·
\81I"))
6421 Norep("Unknown command '%s'.", expcmd);
6423 Norep("'%s'
\83R
\83}
\83\93\83h
\81H", expcmd);
6426 context.move = FALSE;
6431 /* convert an x,y pair into a direction code */
6438 for (dd = 0; dd < 8; dd++)
6439 if (x == xdir[dd] && y == ydir[dd])
6444 /* convert a direction code into an x,y pair */
6455 /* also sets u.dz, but returns false for <> */
6460 register const char *dp = index(Cmd.dirchars, sym);
6465 u.dx = xdir[dp - Cmd.dirchars];
6466 u.dy = ydir[dp - Cmd.dirchars];
6467 u.dz = zdir[dp - Cmd.dirchars];
6468 #if 0 /* now handled elsewhere */
6469 if (u.dx && u.dy && NODIAG(u.umonnum)) {
6477 /* grid bug handling which used to be in movecmd() */
6481 if (u.dx && u.dy && NODIAG(u.umonnum))
6483 return u.dx || u.dy;
6486 /* decide whether a character (user input keystroke) requests screen repaint */
6491 return (boolean) (c == Cmd.spkeys[NHKF_REDRAW]
6492 || (Cmd.num_pad && c == Cmd.spkeys[NHKF_REDRAW2]));
6499 return (c == Cmd.spkeys[NHKF_RUSH]
6500 || c == Cmd.spkeys[NHKF_RUN]
6501 || c == Cmd.spkeys[NHKF_NOPICKUP]
6502 || c == Cmd.spkeys[NHKF_RUN_NOPICKUP]
6503 || c == Cmd.spkeys[NHKF_FIGHT]
6504 || (Cmd.num_pad && (c == Cmd.spkeys[NHKF_RUN2]
6505 || c == Cmd.spkeys[NHKF_FIGHT2])));
6509 * uses getdir() but unlike getdir() it specifically
6510 * produces coordinates using the direction from getdir()
6511 * and verifies that those coordinates are ok.
6513 * If the call to getdir() returns 0, Never_mind is displayed.
6514 * If the resulting coordinates are not okay, emsg is displayed.
6516 * Returns non-zero if coordinates in cc are valid.
6519 get_adjacent_loc(prompt, emsg, x, y, cc)
6520 const char *prompt, *emsg;
6525 if (!getdir(prompt)) {
6531 if (cc && isok(new_x, new_y)) {
6550 if (in_doagain || *readchar_queue)
6551 dirsym = readchar();
6554 dirsym = yn_function((s && *s != '^') ? s : "In what direction?",
6556 dirsym = yn_function((s && *s != '^') ? s : "
\82Ç
\82Ì
\95û
\8cü
\81H",
6558 /* remove the prompt string so caller won't have to */
6559 clear_nhwindow(WIN_MESSAGE);
6561 if (redraw_cmd(dirsym)) { /* ^R */
6562 docrt(); /* redraw */
6567 if (dirsym == Cmd.spkeys[NHKF_GETDIR_SELF]
6568 || dirsym == Cmd.spkeys[NHKF_GETDIR_SELF2]) {
6569 u.dx = u.dy = u.dz = 0;
6570 } else if (!(is_mov = movecmd(dirsym)) && !u.dz) {
6571 boolean did_help = FALSE, help_requested;
6573 if (!index(quitchars, dirsym)) {
6574 help_requested = (dirsym == Cmd.spkeys[NHKF_GETDIR_HELP]);
6575 if (help_requested || iflags.cmdassist) {
6576 did_help = help_dir((s && *s == '^') ? dirsym : '\0',
6578 help_requested ? (const char *) 0
6580 : "Invalid direction key!");
6582 : "
\96³
\8cø
\82È
\95û
\8cü
\8ew
\92è
\82Å
\82·
\81I");
6588 pline("What a strange direction!");
6590 pline("
\82¸
\82¢
\82Ô
\82ñ
\82Æ
\8aï
\96
\82È
\95û
\8cü
\82¾
\81I");
6593 } else if (is_mov && !dxdy_moveok()) {
6595 You_cant("orient yourself that direction.");
6597 You_cant("
\8cü
\82«
\82É
\8e©
\95ª
\8e©
\90g
\82ð
\8ew
\92è
\82Å
\82«
\82È
\82¢
\81D");
6600 if (!u.dz && (Stunned || (Confusion && !rn2(5))))
6606 show_direction_keys(win, centerchar, nodiag)
6607 winid win; /* should specify a window which is using a fixed-width font... */
6608 char centerchar; /* '.' or '@' or ' ' */
6617 Sprintf(buf, " %c ", Cmd.move_N);
6618 putstr(win, 0, buf);
6619 putstr(win, 0, " | ");
6620 Sprintf(buf, " %c- %c -%c",
6621 Cmd.move_W, centerchar, Cmd.move_E);
6622 putstr(win, 0, buf);
6623 putstr(win, 0, " | ");
6624 Sprintf(buf, " %c ", Cmd.move_S);
6625 putstr(win, 0, buf);
6627 Sprintf(buf, " %c %c %c",
6628 Cmd.move_NW, Cmd.move_N, Cmd.move_NE);
6629 putstr(win, 0, buf);
6630 putstr(win, 0, " \\ | / ");
6631 Sprintf(buf, " %c- %c -%c",
6632 Cmd.move_W, centerchar, Cmd.move_E);
6633 putstr(win, 0, buf);
6634 putstr(win, 0, " / | \\ ");
6635 Sprintf(buf, " %c %c %c",
6636 Cmd.move_SW, Cmd.move_S, Cmd.move_SE);
6637 putstr(win, 0, buf);
6641 /* explain choices if player has asked for getdir() help or has given
6642 an invalid direction after a prefix key ('F', 'g', 'm', &c), which
6643 might be bogus but could be up, down, or self when not applicable */
6645 help_dir(sym, spkey, msg)
6647 int spkey; /* NHKF_ code for prefix key, if one was used, or for ESC */
6650 static const char wiz_only_list[] = "EFGIVW";
6653 char buf[BUFSZ], buf2[BUFSZ], *explain;
6654 const char *dothat, *how;
6655 boolean prefixhandling, viawindow;
6657 /* NHKF_ESC indicates that player asked for help at getdir prompt */
6658 viawindow = (spkey == NHKF_ESC || iflags.cmdassist);
6659 prefixhandling = (spkey != NHKF_ESC);
6661 * Handling for prefix keys that don't want special directions.
6662 * Delivered via pline if 'cmdassist' is off, or instead of the
6663 * general message if it's on.
6666 how = " at"; /* for "<action> at yourself"; not used for up/down */
6679 case NHKF_RUN_NOPICKUP:
6688 how = ""; /* avoid "fight at yourself" */
6691 prefixhandling = FALSE;
6696 /* for movement prefix followed by '.' or (numpad && 's') to mean 'self';
6697 note: '-' for hands (inventory form of 'self') is not handled here */
6699 && (sym == Cmd.spkeys[NHKF_GETDIR_SELF]
6700 || (Cmd.num_pad && sym == Cmd.spkeys[NHKF_GETDIR_SELF2]))) {
6701 Sprintf(buf, "You can't %s%s yourself.", dothat, how);
6702 /* for movement prefix followed by up or down */
6703 } else if (prefixhandling && (sym == '<' || sym == '>')) {
6704 Sprintf(buf, "You can't %s %s.", dothat,
6705 /* was "upwards" and "downwards", but they're considered
6706 to be variants of canonical "upward" and "downward" */
6707 (sym == '<') ? "upward" : "downward");
6710 /* if '!cmdassist', display via pline() and we're done (note: asking
6711 for help at getdir() prompt forces cmdassist for this operation) */
6713 if (prefixhandling) {
6715 Sprintf(buf, "Invalid direction for '%s' prefix.",
6716 visctrl(Cmd.spkeys[spkey]));
6720 /* when 'cmdassist' is off and caller doesn't insist, do nothing */
6724 win = create_nhwindow(NHW_TEXT);
6729 /* show bad-prefix message instead of general invalid-direction one */
6730 putstr(win, 0, buf);
6733 Sprintf(buf, "cmdassist: %s", msg);
6734 putstr(win, 0, buf);
6738 if (!prefixhandling && (letter(sym) || sym == '[')) {
6739 /* '[': old 'cmdhelp' showed ESC as ^[ */
6740 sym = highc(sym); /* @A-Z[ (note: letter() accepts '@') */
6741 ctrl = (sym - 'A') + 1; /* 0-27 (note: 28-31 aren't applicable) */
6742 if ((explain = dowhatdoes_core(ctrl, buf2)) != 0
6743 && (!index(wiz_only_list, sym) || wizard)) {
6744 Sprintf(buf, "Are you trying to use ^%c%s?", sym,
6745 index(wiz_only_list, sym) ? ""
6746 : " as specified in the Guidebook");
6747 putstr(win, 0, buf);
6749 putstr(win, 0, explain);
6752 "To use that command, hold down the <Ctrl> key as a shift");
6753 Sprintf(buf, "and press the <%c> key.", sym);
6754 putstr(win, 0, buf);
6760 Sprintf(buf, "Valid direction keys%s%s%s are:",
6761 prefixhandling ? " to " : "", prefixhandling ? dothat : "",
6762 NODIAG(u.umonnum) ? " in your current form" : "");
6764 Sprintf(buf, "%s%s%s
\97L
\8cø
\82È
\95û
\8cü
\8ew
\92è
\82Í:",
6765 prefixhandling ? dothat : "", prefixhandling ? "
\82½
\82ß
\82Ì" : "",
6766 NODIAG(u.umonnum) ? "
\8c»
\8dÝ
\82Ì
\8ep
\82Å
\82Ì" : "");
6768 putstr(win, 0, buf);
6769 show_direction_keys(win, !prefixhandling ? '.' : ' ', NODIAG(u.umonnum));
6771 if (!prefixhandling || spkey == NHKF_NOPICKUP) {
6772 /* NOPICKUP: unlike the other prefix keys, 'm' allows up/down for
6773 stair traversal; we won't get here when "m<" or "m>" has been
6774 given but we include up and down for 'm'+invalid_direction;
6775 self is excluded as a viable direction for every prefix */
6777 putstr(win, 0, " < up");
6778 putstr(win, 0, " > down");
6779 if (!prefixhandling) {
6780 int selfi = Cmd.num_pad ? NHKF_GETDIR_SELF2 : NHKF_GETDIR_SELF;
6782 Sprintf(buf, " %4s direct at yourself",
6783 visctrl(Cmd.spkeys[selfi]));
6784 putstr(win, 0, buf);
6789 /* non-null msg means that this wasn't an explicit user request */
6793 "(Suppress this message with !cmdassist in config file.)");
6795 "(
\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)");
6797 display_nhwindow(win, FALSE);
6798 destroy_nhwindow(win);
6805 register int x = NODIAG(u.umonnum) ? 2 * rn2(4) : rn2(8);
6816 static NEARDATA const char *const dirnames[] = {
6817 "west", "northwest", "north", "northeast", "east",
6818 "southeast", "south", "southwest", "down", "up",
6821 if (dir < 0 || dir >= SIZE(dirnames))
6823 return dirnames[dir];
6830 /* x corresponds to curx, so x==1 is the first column. Ach. %% */
6831 return x >= 1 && x <= COLNO - 1 && y >= 0 && y <= ROWNO - 1;
6834 /* #herecmdmenu command */
6836 doherecmdmenu(VOID_ARGS)
6838 char ch = here_cmd_menu(TRUE);
6843 /* #therecmdmenu command, a way to test there_cmd_menu without mouse */
6845 dotherecmdmenu(VOID_ARGS)
6849 if (!getdir((const char *) 0) || !isok(u.ux + u.dx, u.uy + u.dy))
6853 ch = there_cmd_menu(TRUE, u.ux + u.dx, u.uy + u.dy);
6855 ch = here_cmd_menu(TRUE);
6861 add_herecmd_menuitem(win, func, text)
6869 if ((ch = cmd_from_func(func)) != '\0') {
6872 add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, text, MENU_UNSELECTED);
6877 there_cmd_menu(doit, x, y)
6884 schar typ = levl[x][y].typ;
6886 menu_item *picks = (menu_item *) 0;
6890 win = create_nhwindow(NHW_MENU);
6894 boolean key_or_pick, card;
6895 int dm = levl[x][y].doormask;
6897 if ((dm & (D_CLOSED | D_LOCKED))) {
6898 add_herecmd_menuitem(win, doopen, "Open the door"), ++K;
6899 /* unfortunately there's no lknown flag for doors to
6900 remember the locked/unlocked state */
6901 key_or_pick = (carrying(SKELETON_KEY) || carrying(LOCK_PICK));
6902 card = (carrying(CREDIT_CARD) != 0);
6903 if (key_or_pick || card) {
6904 Sprintf(buf, "%sunlock the door",
6905 key_or_pick ? "lock or " : "");
6906 add_herecmd_menuitem(win, doapply, upstart(buf)), ++K;
6908 /* unfortunately there's no tknown flag for doors (or chests)
6909 to remember whether a trap had been found */
6910 add_herecmd_menuitem(win, dountrap,
6911 "Search the door for a trap"), ++K;
6912 /* [what about #force?] */
6913 add_herecmd_menuitem(win, dokick, "Kick the door"), ++K;
6914 } else if ((dm & D_ISOPEN)) {
6915 add_herecmd_menuitem(win, doclose, "Close the door"), ++K;
6920 add_herecmd_menuitem(win, dosearch, "Search for secret doors"), ++K;
6922 if ((ttmp = t_at(x, y)) != 0 && ttmp->tseen) {
6923 add_herecmd_menuitem(win, doidtrap, "Examine trap"), ++K;
6924 if (ttmp->ttyp != VIBRATING_SQUARE)
6925 add_herecmd_menuitem(win, dountrap, "Attempt to disarm trap"), ++K;
6929 if (mtmp && !canspotmon(mtmp))
6931 if (mtmp && which_armor(mtmp, W_SADDLE)) {
6932 char *mnam = x_monnam(mtmp, ARTICLE_THE, (char *) 0,
6933 SUPPRESS_SADDLE, FALSE);
6936 Sprintf(buf, "Ride %s", mnam);
6937 add_herecmd_menuitem(win, doride, buf), ++K;
6939 Sprintf(buf, "Remove saddle from %s", mnam);
6940 add_herecmd_menuitem(win, doloot, buf), ++K;
6942 if (mtmp && can_saddle(mtmp) && !which_armor(mtmp, W_SADDLE)
6943 && carrying(SADDLE)) {
6944 Sprintf(buf, "Put saddle on %s", mon_nam(mtmp)), ++K;
6945 add_herecmd_menuitem(win, doapply, buf);
6948 if (mtmp || glyph_is_invisible(glyph_at(x, y))) {
6949 /* "Attack %s", mtmp ? mon_nam(mtmp) : "unseen creature" */
6951 /* "Move %s", direction */
6956 end_menu(win, "What do you want to do?");
6957 npick = select_menu(win, PICK_ONE, &picks);
6959 pline("No applicable actions.");
6962 destroy_nhwindow(win);
6965 int NDECL((*func)) = picks->item.a_nfunc;
6966 free((genericptr_t) picks);
6969 int ret = (*func)();
6973 ch = cmd_from_func(func);
6986 schar typ = levl[u.ux][u.uy].typ;
6988 menu_item *picks = (menu_item *) 0;
6990 win = create_nhwindow(NHW_MENU);
6993 if (IS_FOUNTAIN(typ) || IS_SINK(typ)) {
6994 Sprintf(buf, "Drink from the %s",
6995 defsyms[IS_FOUNTAIN(typ) ? S_fountain : S_sink].explanation);
6996 add_herecmd_menuitem(win, dodrink, buf);
6998 if (IS_FOUNTAIN(typ))
6999 add_herecmd_menuitem(win, dodip,
7000 "Dip something into the fountain");
7002 add_herecmd_menuitem(win, dosit,
7003 "Sit on the throne");
7005 if ((u.ux == xupstair && u.uy == yupstair)
7006 || (u.ux == sstairs.sx && u.uy == sstairs.sy && sstairs.up)
7007 || (u.ux == xupladder && u.uy == yupladder)) {
7008 Sprintf(buf, "Go up the %s",
7009 (u.ux == xupladder && u.uy == yupladder)
7010 ? "ladder" : "stairs");
7011 add_herecmd_menuitem(win, doup, buf);
7013 if ((u.ux == xdnstair && u.uy == ydnstair)
7014 || (u.ux == sstairs.sx && u.uy == sstairs.sy && !sstairs.up)
7015 || (u.ux == xdnladder && u.uy == ydnladder)) {
7016 Sprintf(buf, "Go down the %s",
7017 (u.ux == xupladder && u.uy == yupladder)
7018 ? "ladder" : "stairs");
7019 add_herecmd_menuitem(win, dodown, buf);
7021 if (u.usteed) { /* another movement choice */
7022 Sprintf(buf, "Dismount %s",
7023 x_monnam(u.usteed, ARTICLE_THE, (char *) 0,
7024 SUPPRESS_SADDLE, FALSE));
7025 add_herecmd_menuitem(win, doride, buf);
7029 if (Upolyd) { /* before objects */
7030 Sprintf(buf, "Use %s special ability",
7031 s_suffix(mons[u.umonnum].mname));
7032 add_herecmd_menuitem(win, domonability, buf);
7036 if (OBJ_AT(u.ux, u.uy)) {
7037 struct obj *otmp = level.objects[u.ux][u.uy];
7039 Sprintf(buf, "Pick up %s", otmp->nexthere ? "items" : doname(otmp));
7040 add_herecmd_menuitem(win, dopickup, buf);
7042 if (Is_container(otmp)) {
7043 Sprintf(buf, "Loot %s", doname(otmp));
7044 add_herecmd_menuitem(win, doloot, buf);
7046 if (otmp->oclass == FOOD_CLASS) {
7047 Sprintf(buf, "Eat %s", doname(otmp));
7048 add_herecmd_menuitem(win, doeat, buf);
7053 add_herecmd_menuitem(win, dodrop, "Drop items");
7055 add_herecmd_menuitem(win, donull, "Rest one turn");
7056 add_herecmd_menuitem(win, dosearch, "Search around you");
7057 add_herecmd_menuitem(win, dolook, "Look at what is here");
7059 end_menu(win, "What do you want to do?");
7060 npick = select_menu(win, PICK_ONE, &picks);
7061 destroy_nhwindow(win);
7064 int NDECL((*func)) = picks->item.a_nfunc;
7065 free((genericptr_t) picks);
7068 int ret = (*func)();
7072 ch = cmd_from_func(func);
7079 static NEARDATA int last_multi;
7082 * convert a MAP window position into a movecmd
7085 click_to_cmd(x, y, mod)
7092 if (iflags.clicklook && mod == CLICK_2) {
7095 cmd[0] = Cmd.spkeys[NHKF_CLICKLOOK];
7102 if (flags.travelcmd) {
7103 if (abs(x) <= 1 && abs(y) <= 1) {
7104 x = sgn(x), y = sgn(y);
7108 cmd[0] = Cmd.spkeys[NHKF_TRAVEL];
7112 if (x == 0 && y == 0) {
7113 if (iflags.herecmd_menu) {
7114 cmd[0] = here_cmd_menu(FALSE);
7119 if (IS_FOUNTAIN(levl[u.ux][u.uy].typ)
7120 || IS_SINK(levl[u.ux][u.uy].typ)) {
7121 cmd[0] = cmd_from_func(mod == CLICK_1 ? dodrink : dodip);
7123 } else if (IS_THRONE(levl[u.ux][u.uy].typ)) {
7124 cmd[0] = cmd_from_func(dosit);
7126 } else if ((u.ux == xupstair && u.uy == yupstair)
7127 || (u.ux == sstairs.sx && u.uy == sstairs.sy
7129 || (u.ux == xupladder && u.uy == yupladder)) {
7130 cmd[0] = cmd_from_func(doup);
7132 } else if ((u.ux == xdnstair && u.uy == ydnstair)
7133 || (u.ux == sstairs.sx && u.uy == sstairs.sy
7135 || (u.ux == xdnladder && u.uy == ydnladder)) {
7136 cmd[0] = cmd_from_func(dodown);
7138 } else if (OBJ_AT(u.ux, u.uy)) {
7139 cmd[0] = cmd_from_func(Is_container(level.objects[u.ux][u.uy])
7140 ? doloot : dopickup);
7143 cmd[0] = cmd_from_func(donull); /* just rest */
7148 /* directional commands */
7152 if (!m_at(u.ux + x, u.uy + y)
7153 && !test_move(u.ux, u.uy, x, y, TEST_MOVE)) {
7154 cmd[1] = Cmd.dirchars[dir];
7156 if (iflags.herecmd_menu) {
7157 cmd[0] = there_cmd_menu(FALSE, u.ux + x, u.uy + y);
7163 if (IS_DOOR(levl[u.ux + x][u.uy + y].typ)) {
7164 /* slight assistance to the player: choose kick/open for them
7166 if (levl[u.ux + x][u.uy + y].doormask & D_LOCKED) {
7167 cmd[0] = cmd_from_func(dokick);
7170 if (levl[u.ux + x][u.uy + y].doormask & D_CLOSED) {
7171 cmd[0] = cmd_from_func(doopen);
7175 if (levl[u.ux + x][u.uy + y].typ <= SCORR) {
7176 cmd[0] = cmd_from_func(dosearch);
7182 /* convert without using floating point, allowing sloppy clicking */
7185 else if (y > 2 * abs(x))
7187 else if (x < -2 * abs(y))
7189 else if (y < -2 * abs(x))
7192 x = sgn(x), y = sgn(y);
7194 if (x == 0 && y == 0) {
7195 /* map click on player to "rest" command */
7196 cmd[0] = cmd_from_func(donull);
7202 /* move, attack, etc. */
7204 if (mod == CLICK_1) {
7205 cmd[0] = Cmd.dirchars[dir];
7207 cmd[0] = (Cmd.num_pad
7208 ? M(Cmd.dirchars[dir])
7209 : (Cmd.dirchars[dir] - 'a' + 'A')); /* run command */
7216 get_count(allowchars, inkey, maxcount, count, historical)
7221 boolean historical; /* whether to include in message history: True => yes */
7226 boolean backspaced = FALSE;
7227 /* this should be done in port code so that we have erase_char
7228 and kill_char available; we can at least fake erase_char */
7229 #define STANDBY_erase_char '\177'
7239 cnt = 10L * cnt + (long) (key - '0');
7242 else if (maxcount > 0 && cnt > maxcount)
7244 } else if (cnt && (key == '\b' || key == STANDBY_erase_char)) {
7247 } else if (key == Cmd.spkeys[NHKF_ESC]) {
7249 } else if (!allowchars || index(allowchars, key)) {
7254 if (cnt > 9 || backspaced) {
7255 clear_nhwindow(WIN_MESSAGE);
7256 if (backspaced && !cnt) {
7258 Sprintf(qbuf, "Count: ");
7260 Sprintf(qbuf, "
\90\94: ");
7263 Sprintf(qbuf, "Count: %ld", cnt);
7265 Sprintf(qbuf, "
\90\94: %ld", cnt);
7268 custompline(SUPPRESS_HISTORY, "%s", qbuf);
7275 Sprintf(qbuf, "Count: %ld ", *count);
7277 Sprintf(qbuf, "
\90\94: %ld ", *count);
7278 (void) key2txt((uchar) key, eos(qbuf));
7279 putmsghistory(qbuf, FALSE);
7289 #ifdef LINT /* static char in_line[COLNO]; */
7290 char in_line[COLNO];
7292 static char in_line[COLNO];
7296 iflags.in_parse = TRUE;
7299 flush_screen(1); /* Flush screen buffer. Put the cursor on the hero. */
7302 alt_esc = iflags.altmeta; /* readchar() hack */
7304 if (!Cmd.num_pad || (foo = readchar()) == Cmd.spkeys[NHKF_COUNT]) {
7305 long tmpmulti = multi;
7307 foo = get_count((char *) 0, '\0', LARGEST_INT, &tmpmulti, FALSE);
7308 last_multi = multi = tmpmulti;
7311 alt_esc = FALSE; /* readchar() reset */
7314 if (iflags.debug_fuzzer /* if fuzzing, override '!' and ^Z */
7315 && (Cmd.commands[foo & 0x0ff]
7316 && (Cmd.commands[foo & 0x0ff]->ef_funct == dosuspend_core
7317 || Cmd.commands[foo & 0x0ff]->ef_funct == dosh_core)))
7318 foo = Cmd.spkeys[NHKF_ESC];
7320 if (foo == Cmd.spkeys[NHKF_ESC]) { /* esc cancels count (TH) */
7321 clear_nhwindow(WIN_MESSAGE);
7322 multi = last_multi = 0;
7323 } else if (foo == Cmd.spkeys[NHKF_DOAGAIN] || in_doagain) {
7327 savech(0); /* reset input queue */
7335 save_cm = (char *) 0;
7337 /* in 3.4.3 this was in rhack(), where it was too late to handle M-5 */
7338 if (Cmd.pcHack_compat) {
7339 /* This handles very old inconsistent DOS/Windows behaviour
7340 in a different way: earlier, the keyboard handler mapped
7341 these, which caused counts to be strange when entered
7342 from the number pad. Now do not map them until here. */
7345 foo = Cmd.spkeys[NHKF_RUSH];
7348 foo = Cmd.spkeys[NHKF_RUN];
7351 foo = Cmd.spkeys[NHKF_DOINV];
7360 if (prefix_cmd(foo)) {
7366 clear_nhwindow(WIN_MESSAGE);
7368 iflags.in_parse = FALSE;
7372 #ifdef HANGUPHANDLING
7373 /* some very old systems, or descendents of such systems, expect signal
7374 handlers to have return type `int', but they don't actually inspect
7375 the return value so we should be safe using `void' unconditionally */
7378 hangup(sig_unused) /* called as signal() handler, so sent at least one arg */
7379 int sig_unused UNUSED;
7381 if (program_state.exiting)
7382 program_state.in_moveloop = 0;
7385 /* When using SAFERHANGUP, the done_hup flag it tested in rhack
7386 and a couple of other places; actual hangup handling occurs then.
7387 This is 'safer' because it disallows certain cheats and also
7388 protects against losing objects in the process of being thrown,
7389 but also potentially riskier because the disconnected program
7390 must continue running longer before attempting a hangup save. */
7391 program_state.done_hup++;
7392 /* defer hangup iff game appears to be in progress */
7393 if (program_state.in_moveloop && program_state.something_worth_saving)
7395 #endif /* SAFERHANGUP */
7402 #ifdef NOSAVEONHANGUP
7404 if (flags.ins_chkpt && program_state.something_worth_saving)
7405 program_state.preserve_locks = 1; /* keep files for recovery */
7407 program_state.something_worth_saving = 0; /* don't save */
7411 if (!program_state.done_hup++)
7413 if (program_state.something_worth_saving)
7415 if (iflags.window_inited)
7416 exit_nhwindows((char *) 0);
7418 nh_terminate(EXIT_SUCCESS);
7419 /*NOTREACHED*/ /* not necessarily true for vms... */
7422 #endif /* HANGUPHANDLING */
7428 int x = u.ux, y = u.uy, mod = 0;
7430 if (iflags.debug_fuzzer)
7432 if (*readchar_queue)
7433 sym = *readchar_queue++;
7435 sym = in_doagain ? pgetchar() : nh_poskey(&x, &y, &mod);
7439 register int cnt = NR_OF_EOFS;
7441 * Some SYSV systems seem to return EOFs for various reasons
7442 * (?like when one hits break or for interrupted systemcalls?),
7443 * and we must see several before we quit.
7446 clearerr(stdin); /* omit if clearerr is undefined */
7448 } while (--cnt && sym == EOF);
7450 #endif /* NR_OF_EOFS */
7453 #ifdef HANGUPHANDLING
7454 hangup(0); /* call end_of_input() or set program_state.done_hup */
7458 } else if (sym == '\033' && alt_esc) {
7459 /* iflags.altmeta: treat two character ``ESC c'' as single `M-c' */
7460 sym = *readchar_queue ? *readchar_queue++ : pgetchar();
7461 if (sym == EOF || sym == 0)
7463 else if (sym != '\033')
7464 sym |= 0200; /* force 8th bit on */
7466 } else if (sym == 0) {
7468 readchar_queue = click_to_cmd(x, y, mod);
7469 sym = *readchar_queue++;
7474 /* '_' command, #travel, via keyboard rather than mouse click */
7481 /* [FIXME? Supporting the ability to disable traveling via mouse
7482 click makes some sense, depending upon overall mouse usage.
7483 Disabling '_' on a user by user basis makes no sense at all since
7484 even if it is typed by accident, aborting when picking a target
7485 destination is trivial. Travel via mouse predates travel via '_',
7486 and this use of OPTION=!travel is probably just a mistake....] */
7487 if (!flags.travelcmd)
7491 cc.x = iflags.travelcc.x;
7492 cc.y = iflags.travelcc.y;
7493 if (cc.x == 0 && cc.y == 0) {
7494 /* No cached destination, start attempt from current position */
7498 iflags.getloc_travelmode = TRUE;
7499 if (iflags.menu_requested) {
7500 int gf = iflags.getloc_filter;
7501 iflags.getloc_filter = GFILTER_VIEW;
7502 if (!getpos_menu(&cc, GLOC_INTERESTING)) {
7503 iflags.getloc_filter = gf;
7504 iflags.getloc_travelmode = FALSE;
7507 iflags.getloc_filter = gf;
7510 pline("Where do you want to travel to?");
7512 pline("
\82Ç
\82±
\82É
\88Ú
\93®
\82·
\82é
\81H");
7514 if (getpos(&cc, TRUE, "the desired destination") < 0) {
7516 if (getpos(&cc, TRUE, "
\88Ú
\93®
\90æ") < 0) {
7517 /* user pressed ESC */
7518 iflags.getloc_travelmode = FALSE;
7522 iflags.getloc_travelmode = FALSE;
7523 iflags.travelcc.x = u.tx = cc.x;
7524 iflags.travelcc.y = u.ty = cc.y;
7525 cmd[0] = Cmd.spkeys[NHKF_TRAVEL];
7526 readchar_queue = cmd;
7531 * Parameter validator for generic yes/no function to prevent
7532 * the core from sending too long a prompt string to the
7533 * window port causing a buffer overflow there.
7536 yn_function(query, resp, def)
7537 const char *query, *resp;
7540 char res, qbuf[QBUFSZ];
7542 extern unsigned saved_pline_index; /* pline.c */
7543 unsigned idx = saved_pline_index;
7544 /* buffer to hold query+space+formatted_single_char_response */
7545 char dumplog_buf[QBUFSZ + 1 + 15]; /* [QBUFSZ+1+7] should suffice */
7548 iflags.last_msg = PLNMSG_UNKNOWN; /* most recent pline is clobbered */
7550 /* maximum acceptable length is QBUFSZ-1 */
7551 if (strlen(query) >= QBUFSZ) {
7552 /* caller shouldn't have passed anything this long */
7553 paniclog("Query truncated: ", query);
7554 (void) strncpy(qbuf, query, QBUFSZ - 1 - 3);
7555 Strcpy(&qbuf[QBUFSZ - 1 - 3], "...");
7558 res = (*windowprocs.win_yn_function)(query, resp, def);
7560 if (idx == saved_pline_index) {
7561 /* when idx is still the same as saved_pline_index, the interface
7562 didn't put the prompt into saved_plines[]; we put a simplified
7563 version in there now (without response choices or default) */
7564 Sprintf(dumplog_buf, "%s ", query);
7565 (void) key2txt((uchar) res, eos(dumplog_buf));
7566 dumplogmsg(dumplog_buf);
7572 /* for paranoid_confirm:quit,die,attack prompting */
7574 paranoid_query(be_paranoid, prompt)
7575 boolean be_paranoid;
7578 boolean confirmed_ok;
7580 /* when paranoid, player must respond with "yes" rather than just 'y'
7581 to give the go-ahead for this query; default is "no" unless the
7582 ParanoidConfirm flag is set in which case there's no default */
7584 char pbuf[BUFSZ], qbuf[QBUFSZ], ans[BUFSZ];
7585 const char *promptprefix = "",
7586 *responsetype = ParanoidConfirm ? "(yes|no)" : "(yes) [no]";
7587 int k, trylimit = 6; /* 1 normal, 5 more with "Yes or No:" prefix */
7589 copynchars(pbuf, prompt, BUFSZ - 1);
7590 /* in addition to being paranoid about this particular
7591 query, we might be even more paranoid about all paranoia
7592 responses (ie, ParanoidConfirm is set) in which case we
7593 require "no" to reject in addition to "yes" to confirm
7594 (except we won't loop if response is ESC; it means no) */
7596 /* make sure we won't overflow a QBUFSZ sized buffer */
7597 k = (int) (strlen(promptprefix) + 1 + strlen(responsetype));
7598 if ((int) strlen(pbuf) + k > QBUFSZ - 1) {
7599 /* chop off some at the end */
7600 Strcpy(pbuf + (QBUFSZ - 1) - k - 4, "...?"); /* -4: "...?" */
7603 Sprintf(qbuf, "%s%s %s", promptprefix, pbuf, responsetype);
7606 (void) mungspaces(ans);
7607 confirmed_ok = !strcmpi(ans, "yes");
7608 if (confirmed_ok || *ans == '\033')
7610 promptprefix = "\"Yes\" or \"No\": ";
7611 } while (ParanoidConfirm && strcmpi(ans, "no") && --trylimit);
7613 confirmed_ok = (yn(prompt) == 'y');
7615 return confirmed_ok;
7618 /* ^Z command, #suspend */
7620 dosuspend_core(VOID_ARGS)
7623 /* Does current window system support suspend? */
7624 if ((*windowprocs.win_can_suspend)()) {
7625 /* NB: SYSCF SHELLERS handled in port code. */
7629 Norep(cmdnotavail, "#suspend");
7633 /* '!' command, #shell */
7635 dosh_core(VOID_ARGS)
7638 /* access restrictions, if any, are handled in port code */
7641 Norep(cmdnotavail, "#shell");