1 /* NetHack 3.6 cmd.c $NHDT-Date: 1557088405 2019/05/05 20:33:25 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.333 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /*-Copyright (c) Robert Patrick Rankin, 2013. */
4 /* NetHack may be freely redistributed. See license for details. */
6 /* JNetHack Copyright */
7 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000 */
8 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2019 */
9 /* JNetHack may be freely redistributed. See license for details. */
15 /* Macros for meta and ctrl modifiers:
16 * M and C return the meta/ctrl code for the given character;
17 * e.g., (C('c') is ctrl-c
21 #define M(c) (0x80 | (c))
23 #define M(c) ((c) - 128)
28 #define C(c) (0x1f & (c))
32 STATIC_VAR boolean alt_esc = FALSE;
35 struct cmd Cmd = { 0 }; /* flag.h */
37 extern const char *hu_stat[]; /* hunger status from eat.c */
38 extern const char *enc_stat[]; /* encumbrance status from botl.c */
42 * Some systems may have getchar() return EOF for various reasons, and
43 * we should not quit before seeing at least NR_OF_EOFS consecutive EOFs.
45 #if defined(SYSV) || defined(DGUX) || defined(HPUX)
50 #define CMD_TRAVEL (char) 0x90
51 #define CMD_CLICKLOOK (char) 0x8F
54 extern int NDECL(wiz_debug_cmd_bury);
57 #ifdef DUMB /* stuff commented out in extern.h, but needed here */
58 extern int NDECL(doapply); /**/
59 extern int NDECL(dorub); /**/
60 extern int NDECL(dojump); /**/
61 extern int NDECL(doextlist); /**/
62 extern int NDECL(enter_explore_mode); /**/
63 extern int NDECL(dodrop); /**/
64 extern int NDECL(doddrop); /**/
65 extern int NDECL(dodown); /**/
66 extern int NDECL(doup); /**/
67 extern int NDECL(donull); /**/
68 extern int NDECL(dowipe); /**/
69 extern int NDECL(docallcnd); /**/
70 extern int NDECL(dotakeoff); /**/
71 extern int NDECL(doremring); /**/
72 extern int NDECL(dowear); /**/
73 extern int NDECL(doputon); /**/
74 extern int NDECL(doddoremarm); /**/
75 extern int NDECL(dokick); /**/
76 extern int NDECL(dofire); /**/
77 extern int NDECL(dothrow); /**/
78 extern int NDECL(doeat); /**/
79 extern int NDECL(done2); /**/
80 extern int NDECL(vanquished); /**/
81 extern int NDECL(doengrave); /**/
82 extern int NDECL(dopickup); /**/
83 extern int NDECL(ddoinv); /**/
84 extern int NDECL(dotypeinv); /**/
85 extern int NDECL(dolook); /**/
86 extern int NDECL(doprgold); /**/
87 extern int NDECL(doprwep); /**/
88 extern int NDECL(doprarm); /**/
89 extern int NDECL(doprring); /**/
90 extern int NDECL(dopramulet); /**/
91 extern int NDECL(doprtool); /**/
92 extern int NDECL(dosuspend); /**/
93 extern int NDECL(doforce); /**/
94 extern int NDECL(doopen); /**/
95 extern int NDECL(doclose); /**/
96 extern int NDECL(dosh); /**/
97 extern int NDECL(dodiscovered); /**/
98 extern int NDECL(doclassdisco); /**/
99 extern int NDECL(doset); /**/
100 extern int NDECL(dotogglepickup); /**/
101 extern int NDECL(dowhatis); /**/
102 extern int NDECL(doquickwhatis); /**/
103 extern int NDECL(dowhatdoes); /**/
104 extern int NDECL(dohelp); /**/
105 extern int NDECL(dohistory); /**/
106 extern int NDECL(doloot); /**/
107 extern int NDECL(dodrink); /**/
108 extern int NDECL(dodip); /**/
109 extern int NDECL(dosacrifice); /**/
110 extern int NDECL(dopray); /**/
111 extern int NDECL(dotip); /**/
112 extern int NDECL(doturn); /**/
113 extern int NDECL(doredraw); /**/
114 extern int NDECL(doread); /**/
115 extern int NDECL(dosave); /**/
116 extern int NDECL(dosearch); /**/
117 extern int NDECL(doidtrap); /**/
118 extern int NDECL(dopay); /**/
119 extern int NDECL(dosit); /**/
120 extern int NDECL(dotalk); /**/
121 extern int NDECL(docast); /**/
122 extern int NDECL(dovspell); /**/
123 extern int NDECL(dotelecmd); /**/
124 extern int NDECL(dountrap); /**/
125 extern int NDECL(doversion); /**/
126 extern int NDECL(doextversion); /**/
127 extern int NDECL(doswapweapon); /**/
128 extern int NDECL(dowield); /**/
129 extern int NDECL(dowieldquiver); /**/
130 extern int NDECL(dozap); /**/
131 extern int NDECL(doorganize); /**/
134 static int NDECL((*timed_occ_fn));
136 STATIC_PTR int NDECL(dosuspend_core);
137 STATIC_PTR int NDECL(dosh_core);
138 STATIC_PTR int NDECL(doherecmdmenu);
139 STATIC_PTR int NDECL(dotherecmdmenu);
140 STATIC_PTR int NDECL(doprev_message);
141 STATIC_PTR int NDECL(timed_occupation);
142 STATIC_PTR int NDECL(doextcmd);
143 STATIC_PTR int NDECL(dotravel);
144 STATIC_PTR int NDECL(doterrain);
145 STATIC_PTR int NDECL(wiz_wish);
146 STATIC_PTR int NDECL(wiz_identify);
147 STATIC_PTR int NDECL(wiz_intrinsic);
148 STATIC_PTR int NDECL(wiz_map);
149 STATIC_PTR int NDECL(wiz_makemap);
150 STATIC_PTR int NDECL(wiz_genesis);
151 STATIC_PTR int NDECL(wiz_where);
152 STATIC_PTR int NDECL(wiz_detect);
153 STATIC_PTR int NDECL(wiz_panic);
154 STATIC_PTR int NDECL(wiz_polyself);
155 STATIC_PTR int NDECL(wiz_level_tele);
156 STATIC_PTR int NDECL(wiz_level_change);
157 STATIC_PTR int NDECL(wiz_show_seenv);
158 STATIC_PTR int NDECL(wiz_show_vision);
159 STATIC_PTR int NDECL(wiz_smell);
160 STATIC_PTR int NDECL(wiz_intrinsic);
161 STATIC_PTR int NDECL(wiz_show_wmodes);
162 STATIC_DCL void NDECL(wiz_map_levltyp);
163 STATIC_DCL void NDECL(wiz_levltyp_legend);
164 #if defined(__BORLANDC__) && !defined(_WIN32)
165 extern void FDECL(show_borlandc_stats, (winid));
167 #ifdef DEBUG_MIGRATING_MONS
168 STATIC_PTR int NDECL(wiz_migrate_mons);
170 STATIC_DCL int FDECL(size_monst, (struct monst *, BOOLEAN_P));
171 STATIC_DCL int FDECL(size_obj, (struct obj *));
172 STATIC_DCL void FDECL(count_obj, (struct obj *, long *, long *,
173 BOOLEAN_P, BOOLEAN_P));
174 STATIC_DCL void FDECL(obj_chain, (winid, const char *, struct obj *,
175 BOOLEAN_P, long *, long *));
176 STATIC_DCL void FDECL(mon_invent_chain, (winid, const char *, struct monst *,
178 STATIC_DCL void FDECL(mon_chain, (winid, const char *, struct monst *,
179 BOOLEAN_P, long *, long *));
180 STATIC_DCL void FDECL(contained_stats, (winid, const char *, long *, long *));
181 STATIC_DCL void FDECL(misc_stats, (winid, long *, long *));
182 STATIC_PTR int NDECL(wiz_show_stats);
183 STATIC_DCL boolean FDECL(accept_menu_prefix, (int NDECL((*))));
184 STATIC_PTR int NDECL(wiz_rumor_check);
185 STATIC_PTR int NDECL(doattributes);
187 STATIC_DCL void FDECL(enlght_out, (const char *));
188 STATIC_DCL void FDECL(enlght_line, (const char *, const char *, const char *,
190 STATIC_DCL char *FDECL(enlght_combatinc, (const char *, int, int, char *));
191 STATIC_DCL void FDECL(enlght_halfdmg, (int, int));
192 STATIC_DCL boolean NDECL(walking_on_water);
193 STATIC_DCL boolean FDECL(cause_known, (int));
194 STATIC_DCL char *FDECL(attrval, (int, int, char *));
195 STATIC_DCL void FDECL(background_enlightenment, (int, int));
196 STATIC_DCL void FDECL(basics_enlightenment, (int, int));
197 STATIC_DCL void FDECL(characteristics_enlightenment, (int, int));
198 STATIC_DCL void FDECL(one_characteristic, (int, int, int));
199 STATIC_DCL void FDECL(status_enlightenment, (int, int));
200 STATIC_DCL void FDECL(attributes_enlightenment, (int, int));
202 STATIC_DCL void FDECL(add_herecmd_menuitem, (winid, int NDECL((*)),
204 STATIC_DCL char FDECL(here_cmd_menu, (BOOLEAN_P));
205 STATIC_DCL char FDECL(there_cmd_menu, (BOOLEAN_P, int, int));
206 STATIC_DCL char *NDECL(parse);
207 STATIC_DCL void FDECL(show_direction_keys, (winid, CHAR_P, BOOLEAN_P));
208 STATIC_DCL boolean FDECL(help_dir, (CHAR_P, int, const char *));
210 static const char *readchar_queue = "";
211 static coord clicklook_cc;
212 /* for rejecting attempts to use wizard mode commands */
214 static const char unavailcmd[] = "Unavailable command '%s'.";
216 static const char unavailcmd[] = "'%s'
\83R
\83}
\83\93\83h
\82Í
\8eg
\82¦
\82È
\82¢
\81D";
217 /* for rejecting #if !SHELL, !SUSPEND */
219 static const char cmdnotavail[] = "'%s' command not available.";
221 static const char cmdnotavail[] = "'%s'
\83R
\83}
\83\93\83h
\82Í
\97\98\97p
\82Å
\82«
\82Ü
\82¹
\82ñ
\81D";
224 doprev_message(VOID_ARGS)
226 return nh_doprev_message();
229 /* Count down by decrementing multi */
231 timed_occupation(VOID_ARGS)
239 /* If you have moved since initially setting some occupations, they
240 * now shouldn't be able to restart.
242 * The basic rule is that if you are carrying it, you can continue
243 * since it is with you. If you are acting on something at a distance,
244 * your orientation to it must have changed when you moved.
246 * The exception to this is taking off items, since they can be taken
247 * off in a number of ways in the intervening time, screwing up ordering.
249 * Currently: Take off all armor.
250 * Picking Locks / Forcing Chests.
261 /* If a time is given, use it to timeout this function, otherwise the
262 * function times out by its own means.
265 set_occupation(fn, txt, xtime)
271 occupation = timed_occupation;
280 STATIC_DCL char NDECL(popch);
282 /* Provide a means to redo the last command. The flag `in_doagain' is set
283 * to true while redoing the command. This flag is tested in commands that
284 * require additional input (like `throw' which requires a thing and a
285 * direction), and the input prompt is not shown. Also, while in_doagain is
286 * TRUE, no keystrokes can be saved into the saveq.
289 static char pushq[BSIZE], saveq[BSIZE];
290 static NEARDATA int phead, ptail, shead, stail;
295 /* If occupied, return '\0', letting tgetch know a character should
296 * be read from the keyboard. If the character read is not the
297 * ABORT character (as checked in pcmain.c), that character will be
298 * pushed back on the pushq.
303 return (char) ((shead != stail) ? saveq[stail++] : '\0');
305 return (char) ((phead != ptail) ? pushq[ptail++] : '\0');
309 pgetchar() /* courtesy of aeb@cwi.nl */
313 if (iflags.debug_fuzzer)
320 /* A ch == 0 resets the pushq */
332 /* A ch == 0 resets the saveq. Only save keystrokes when not
333 * replaying a previous command.
341 phead = ptail = shead = stail = 0;
342 else if (shead < BSIZE)
348 /* here after # - now read a full-word command */
355 /* keep repeating until we don't run help or quit */
361 func = extcmdlist[idx].ef_funct;
362 if (!wizard && (extcmdlist[idx].flags & WIZMODECMD)) {
364 You("can't do that.");
366 pline("
\82»
\82ê
\82Í
\82Å
\82«
\82Ü
\82¹
\82ñ
\81D");
369 if (iflags.menu_requested && !accept_menu_prefix(func)) {
371 pline("'%s' prefix has no effect for the %s command.",
372 visctrl(Cmd.spkeys[NHKF_REQMENU]),
373 extcmdlist[idx].ef_txt);
375 pline("'%s'
\90Ú
\93ª
\8e«
\82Í%s
\83R
\83}
\83\93\83h
\82É
\82Í
\96³
\8cø
\81D",
376 visctrl(Cmd.spkeys[NHKF_REQMENU]),
377 extcmdlist[idx].ef_txt);
379 iflags.menu_requested = FALSE;
382 } while (func == doextlist);
387 /* here after #? - now list all full-word commands and provid
388 some navigation capability through the long list */
392 register const struct ext_func_tab *efp;
393 char buf[BUFSZ], searchbuf[BUFSZ], promptbuf[QBUFSZ];
398 int menumode = 0, menushown[2], onelist = 0;
399 boolean redisplay = TRUE, search = FALSE;
401 static const char *headings[] = { "Extended commands",
402 "Debugging Extended Commands" };
404 static const char *headings[] = { "
\8ag
\92£
\83R
\83}
\83\93\83h",
405 "
\83f
\83o
\83b
\83O
\8ag
\92£
\83R
\83}
\83\93\83h" };
409 menuwin = create_nhwindow(NHW_MENU);
416 add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
417 "Extended Commands List", MENU_UNSELECTED);
419 add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
420 "
\8ag
\92£
\83R
\83}
\83\93\83h
\88ê
\97\97", MENU_UNSELECTED);
422 add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
423 "", MENU_UNSELECTED);
426 Strcpy(buf, menumode ? "Show" : "Hide");
427 Strcat(buf, " commands that don't autocomplete");
429 Strcat(buf, " (those not marked with [A])");
431 Strcpy(buf, "
\8e©
\93®
\95â
\8a®
\82³
\82ê
\82È
\82¢
\83R
\83}
\83\93\83h
\82ð");
432 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¢)");
435 add_menu(menuwin, NO_GLYPH, &any, 'a', 0, ATR_NONE, buf,
440 /* was 's', but then using ':' handling within the interface
441 would only examine the two or three meta entries, not the
442 actual list of extended commands shown via separator lines;
443 having ':' as an explicit selector overrides the default
444 menu behavior for it; we retain 's' as a group accelerator */
446 add_menu(menuwin, NO_GLYPH, &any, ':', 's', ATR_NONE,
447 "Search extended commands", MENU_UNSELECTED);
449 add_menu(menuwin, NO_GLYPH, &any, ':', 's', ATR_NONE,
450 "
\8ag
\92£
\83R
\83}
\83\93\83h
\82ð
\8c\9f\8dõ
\82·
\82é", MENU_UNSELECTED);
454 Strcpy(buf, "Show all, clear search");
456 Strcpy(buf, "
\91S
\82Ä
\95\
\8e¦;
\8c\9f\8dõ
\82ð
\83N
\83\8a\83A");
458 if (strlen(buf) + strlen(searchbuf) + strlen(" (\"\")") < QBUFSZ)
459 Sprintf(eos(buf), " (\"%s\")", searchbuf);
461 /* specifying ':' as a group accelerator here is mostly a
462 statement of intent (we'd like to accept it as a synonym but
463 also want to hide it from general menu use) because it won't
464 work for interfaces which support ':' to search; use as a
465 general menu command takes precedence over group accelerator */
466 add_menu(menuwin, NO_GLYPH, &any, 's', ':', ATR_NONE,
467 buf, MENU_UNSELECTED);
472 add_menu(menuwin, NO_GLYPH, &any, 'z', 0, ATR_NONE,
473 onelist ? "Show debugging commands in separate section"
474 : "Show all alphabetically, including debugging commands",
477 add_menu(menuwin, NO_GLYPH, &any, 'z', 0, ATR_NONE,
478 onelist ? "
\83f
\83o
\83b
\83O
\83R
\83}
\83\93\83h
\82Í
\95Ê
\82Ì
\90ß
\82É
\95\
\8e¦
\82·
\82é"
479 : "
\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é",
484 add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
485 "", MENU_UNSELECTED);
486 menushown[0] = menushown[1] = 0;
488 for (pass = 0; pass <= 1; ++pass) {
489 /* skip second pass if not in wizard mode or wizard mode
490 commands are being integrated into a single list */
491 if (pass == 1 && (onelist || !wizard))
493 for (efp = extcmdlist; efp->ef_txt; efp++) {
496 if ((efp->flags & CMD_NOT_AVAILABLE) != 0)
498 /* if hiding non-autocomplete commands, skip such */
499 if (menumode == 1 && (efp->flags & AUTOCOMPLETE) == 0)
501 /* if searching, skip this command if it doesn't match */
503 /* first try case-insensitive substring match */
504 && !strstri(efp->ef_txt, searchbuf)
505 && !strstri(efp->ef_desc, searchbuf)
506 /* wildcard support; most interfaces use case-insensitve
507 pmatch rather than regexp for menu searching */
508 && !pmatchi(searchbuf, efp->ef_txt)
509 && !pmatchi(searchbuf, efp->ef_desc))
511 /* skip wizard mode commands if not in wizard mode;
512 when showing two sections, skip wizard mode commands
513 in pass==0 and skip other commands in pass==1 */
514 wizc = (efp->flags & WIZMODECMD) != 0;
517 if (!onelist && pass != wizc)
520 /* We're about to show an item, have we shown the menu yet?
521 Doing menu in inner loop like this on demand avoids a
522 heading with no subordinate entries on the search
524 if (!menushown[pass]) {
525 Strcpy(buf, headings[pass]);
526 add_menu(menuwin, NO_GLYPH, &any, 0, 0,
527 iflags.menu_headings, buf, MENU_UNSELECTED);
530 Sprintf(buf, " %-14s %-3s %s",
532 (efp->flags & AUTOCOMPLETE) ? "[A]" : " ",
534 add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
535 buf, MENU_UNSELECTED);
539 add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
540 "", MENU_UNSELECTED);
542 if (*searchbuf && !n)
544 add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
545 "no matches", MENU_UNSELECTED);
547 add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
548 "
\88ê
\92v
\82È
\82µ", MENU_UNSELECTED);
551 end_menu(menuwin, (char *) 0);
552 n = select_menu(menuwin, PICK_ONE, &selected);
554 switch (selected[0].item.a_int) {
555 case 1: /* 'a': toggle show/hide non-autocomplete */
556 menumode = 1 - menumode; /* toggle 0 -> 1, 1 -> 0 */
559 case 2: /* ':' when not searching yet: enable search */
562 case 3: /* 's' when already searching: disable search */
567 case 4: /* 'z': toggle showing wizard mode commands separately */
570 onelist = 1 - onelist; /* toggle 0 -> 1, 1 -> 0 */
574 free((genericptr_t) selected);
581 Strcpy(promptbuf, "Extended command list search phrase");
582 Strcat(promptbuf, "?");
584 Strcpy(promptbuf, "
\8ag
\92£
\83R
\83}
\83\93\83h
\82Ì
\8c\9f\8dõ
\95¶
\8e\9a\97ñ
\82Í?");
586 getlin(promptbuf, searchbuf);
587 (void) mungspaces(searchbuf);
588 if (searchbuf[0] == '\033')
595 destroy_nhwindow(menuwin);
599 #if defined(TTY_GRAPHICS) || defined(CURSES_GRAPHICS)
600 #define MAX_EXT_CMD 200 /* Change if we ever have more ext cmds */
603 * This is currently used only by the tty interface and is
604 * controlled via runtime option 'extmenu'. (Most other interfaces
605 * already use a menu all the time for extended commands.)
607 * ``# ?'' is counted towards the limit of the number of commands,
608 * so we actually support MAX_EXT_CMD-1 "real" extended commands.
610 * Here after # - now show pick-list of possible commands.
615 const struct ext_func_tab *efp;
616 menu_item *pick_list = (menu_item *) 0;
619 const struct ext_func_tab *choices[MAX_EXT_CMD + 1];
621 char cbuf[QBUFSZ], prompt[QBUFSZ], fmtstr[20];
622 int i, n, nchoices, acount;
623 int ret, len, biggest;
624 int accelerator, prevaccelerator;
626 boolean wastoolong, one_per_line;
634 /* populate choices */
635 for (efp = extcmdlist; efp->ef_txt; efp++) {
636 if ((efp->flags & CMD_NOT_AVAILABLE)
637 || !(efp->flags & AUTOCOMPLETE)
638 || (!wizard && (efp->flags & WIZMODECMD)))
640 if (!matchlevel || !strncmp(efp->ef_txt, cbuf, matchlevel)) {
642 if ((len = (int) strlen(efp->ef_desc)) > biggest)
644 if (++i > MAX_EXT_CMD) {
647 "Exceeded %d extended commands in doextcmd() menu; 'extmenu' disabled.",
655 choices[i] = (struct ext_func_tab *) 0;
657 /* if we're down to one, we have our selection so get out of here */
659 ret = (nchoices == 1) ? (int) (choices[0] - extcmdlist) : -1;
664 win = create_nhwindow(NHW_MENU);
666 Sprintf(fmtstr, "%%-%ds", biggest + 15);
668 wastoolong = FALSE; /* True => had to wrap due to line width
669 * ('w' in wizard mode) */
670 /* -3: two line menu header, 1 line menu footer (for prompt) */
671 one_per_line = (nchoices < ROWNO - 3);
672 accelerator = prevaccelerator = 0;
674 for (i = 0; choices[i]; ++i) {
675 accelerator = choices[i]->ef_txt[matchlevel];
676 if (accelerator != prevaccelerator || one_per_line)
678 if (accelerator != prevaccelerator || one_per_line
680 /* +4: + sizeof " or " - sizeof "" */
681 && (strlen(prompt) + 4 + strlen(choices[i]->ef_txt)
682 /* -6: enough room for 1 space left margin
683 * + "%c - " menu selector + 1 space right margin */
684 >= min(sizeof prompt, COLNO - 6)))) {
686 /* flush extended cmds for that letter already in buf */
687 Sprintf(buf, fmtstr, prompt);
688 any.a_char = prevaccelerator;
689 add_menu(win, NO_GLYPH, &any, any.a_char, 0, ATR_NONE,
692 if (!(accelerator != prevaccelerator || one_per_line))
696 prevaccelerator = accelerator;
697 if (!acount || one_per_line) {
699 Sprintf(prompt, "%s%s [%s]", wastoolong ? "or " : "",
700 choices[i]->ef_txt, choices[i]->ef_desc);
702 Sprintf(prompt, "%s%s [%s]", wastoolong ? "
\82Ü
\82½
\82Í" : "",
703 choices[i]->ef_txt, choices[i]->ef_desc);
705 } else if (acount == 1) {
707 Sprintf(prompt, "%s%s or %s", wastoolong ? "or " : "",
708 choices[i - 1]->ef_txt, choices[i]->ef_txt);
710 Sprintf(prompt, "%s%s
\82Ü
\82½
\82Í%s", wastoolong ? "
\82Ü
\82½
\82Í" : "",
711 choices[i - 1]->ef_txt, choices[i]->ef_txt);
715 Strcat(prompt, " or ");
717 Strcat(prompt,"
\82Ü
\82½
\82Í ");
718 Strcat(prompt, choices[i]->ef_txt);
724 Sprintf(buf, fmtstr, prompt);
725 any.a_char = prevaccelerator;
726 add_menu(win, NO_GLYPH, &any, any.a_char, 0, ATR_NONE, buf,
730 Sprintf(prompt, "Extended Command: %s", cbuf);
732 Sprintf(prompt, "
\8ag
\92£
\83R
\83}
\83\93\83h: %s", cbuf);
733 end_menu(win, prompt);
734 n = select_menu(win, PICK_ONE, &pick_list);
735 destroy_nhwindow(win);
737 if (matchlevel > (QBUFSZ - 2)) {
738 free((genericptr_t) pick_list);
740 impossible("Too many chars (%d) entered in extcmd_via_menu()",
745 cbuf[matchlevel++] = pick_list[0].item.a_char;
746 cbuf[matchlevel] = '\0';
747 free((genericptr_t) pick_list);
759 #endif /* TTY_GRAPHICS */
761 /* #monster command - use special monster ability while polymorphed */
763 domonability(VOID_ARGS)
765 if (can_breathe(youmonst.data))
767 else if (attacktype(youmonst.data, AT_SPIT))
769 else if (youmonst.data->mlet == S_NYMPH)
771 else if (attacktype(youmonst.data, AT_GAZE))
773 else if (is_were(youmonst.data))
775 else if (webmaker(youmonst.data))
777 else if (is_hider(youmonst.data))
779 else if (is_mind_flayer(youmonst.data))
780 return domindblast();
781 else if (u.umonnum == PM_GREMLIN) {
782 if (IS_FOUNTAIN(levl[u.ux][u.uy].typ)) {
783 if (split_mon(&youmonst, (struct monst *) 0))
784 dryup(u.ux, u.uy, TRUE);
787 There("is no fountain here.");
789 pline("
\82±
\82±
\82É
\82Í
\90ò
\82Í
\82È
\82¢
\81D");
790 } else if (is_unicorn(youmonst.data)) {
791 use_unicorn_horn((struct obj *) 0);
793 } else if (youmonst.data->msound == MS_SHRIEK) {
797 You("
\8bà
\90Ø
\82è
\90º
\82ð
\82 \82°
\82½
\81D");
800 pline("Unfortunately sound does not carry well through rock.");
802 pline("
\8ec
\94O
\82È
\82ª
\82ç
\89¹
\82Í
\8aâ
\82ð
\82¤
\82Ü
\82
\93`
\82í
\82ç
\82È
\82¢
\81D");
805 } else if (youmonst.data->mlet == S_VAMPIRE)
809 pline("Any special ability you may have is purely reflexive.");
811 pline("
\82 \82È
\82½
\82Ì
\8e\9d\82Á
\82Ä
\82¢
\82é
\93Á
\8eê
\94\
\97Í
\82Í
\82Ç
\82ê
\82à
\8eó
\93®
\93I
\82¾
\81D");
814 You("don't have a special ability in your normal form!");
816 You("
\95\81\92i
\82Ì
\8ep
\82Å
\82Ì
\93Á
\8eê
\94\
\97Í
\82ð
\8e\9d\82Á
\82Ä
\82¢
\82È
\82¢
\81I");
821 enter_explore_mode(VOID_ARGS)
825 You("are in debug mode.");
827 You("
\82·
\82Å
\82É
\83f
\83o
\83b
\83O
\83\82\81[
\83h
\82¾
\81D");
828 } else if (discover) {
830 You("are already in explore mode.");
832 You("
\82·
\82Å
\82É
\92T
\8c\9f\83\82\81[
\83h
\82¾
\81D");
836 if (!sysopt.explorers || !sysopt.explorers[0]
837 || !check_user_string(sysopt.explorers)) {
839 You("cannot access explore mode.");
841 You("
\92T
\8c\9f\83\82\81[
\83h
\82É
\83A
\83N
\83Z
\83X
\82Å
\82«
\82È
\82¢
\81D");
848 "Beware! From explore mode there will be no return to normal game.");
850 "
\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");
851 if (paranoid_query(ParanoidQuit,
853 "Do you want to enter explore mode?")) {
855 "
\94
\8c©
\83\82\81[
\83h
\82É
\88Ú
\82è
\82Ü
\82·
\82©
\81H")) {
856 clear_nhwindow(WIN_MESSAGE);
858 You("are now in non-scoring explore mode.");
860 You("
\83X
\83R
\83A
\82ª
\82Ì
\82ç
\82È
\82¢
\94
\8c©
\83\82\81[
\83h
\82É
\88Ú
\8ds
\82µ
\82½
\81D");
863 clear_nhwindow(WIN_MESSAGE);
865 pline("Resuming normal game.");
867 pline("
\92Ê
\8fí
\83\82\81[
\83h
\82ð
\91±
\82¯
\82é
\81D");
873 /* ^W command - wish for something */
875 wiz_wish(VOID_ARGS) /* Unlimited wishes for debug mode by Paul Polderman */
878 boolean save_verbose = flags.verbose;
880 flags.verbose = FALSE;
882 flags.verbose = save_verbose;
883 (void) encumber_msg();
885 pline(unavailcmd, visctrl((int) cmd_from_func(wiz_wish)));
889 /* ^I command - reveal and optionally identify hero's inventory */
891 wiz_identify(VOID_ARGS)
894 iflags.override_ID = (int) cmd_from_func(wiz_identify);
895 /* command remapping might leave #wizidentify as the only way
896 to invoke us, in which case cmd_from_func() will yield NUL;
897 it won't matter to display_inventory()/display_pickinv()
898 if ^I invokes some other command--what matters is that
899 display_pickinv() and xname() see override_ID as nonzero */
900 if (!iflags.override_ID)
901 iflags.override_ID = C('I');
902 (void) display_inventory((char *) 0, FALSE);
903 iflags.override_ID = 0;
905 pline(unavailcmd, visctrl((int) cmd_from_func(wiz_identify)));
909 /* #wizmakemap - discard current dungeon level and replace with a new one */
911 wiz_makemap(VOID_ARGS)
915 boolean was_in_W_tower = In_W_tower(u.ux, u.uy, &u.uz);
917 rm_mapseen(ledger_no(&u.uz));
918 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
919 if (mtmp->isgd) { /* vault is going away; get rid of guard */
923 if (DEADMONSTER(mtmp))
928 * Reduce 'born' tally for each monster about to be discarded
929 * by savelev(), otherwise replacing heavily populated levels
930 * tends to make their inhabitants become extinct.
937 /* reset lock picking unless it's for a carried container */
938 maybe_reset_pick((struct obj *) 0);
939 /* reset interrupted digging if it was taking place on this level */
940 if (on_level(&context.digging.level, &u.uz))
941 (void) memset((genericptr_t) &context.digging, 0,
942 sizeof (struct dig_info));
943 /* reset cached targets */
944 iflags.travelcc.x = iflags.travelcc.y = 0; /* travel destination */
945 context.polearm.hitmon = (struct monst *) 0; /* polearm target */
946 /* escape from trap */
948 check_special_room(TRUE); /* room exit */
949 u.ustuck = (struct monst *) 0;
952 u.uundetected = 0; /* not hidden, even if means are available */
953 dmonsfree(); /* purge dead monsters from 'fmon' */
954 /* keep steed and other adjacent pets after releasing them
955 from traps, stopping eating, &c as if hero were ascending */
956 keepdogs(TRUE); /* (pets-only; normally we'd be using 'FALSE' here) */
958 /* discard current level; "saving" is used to release dynamic data */
959 savelev(-1, ledger_no(&u.uz), FREE_SAVE);
960 /* create a new level; various things like bestowing a guardian
961 angel on Astral or setting off alarm on Ft.Ludios are handled
962 by goto_level(do.c) so won't occur for replacement levels */
966 vision_full_recalc = 1;
968 /* was using safe_teleds() but that doesn't honor arrival region
969 on levels which have such; we don't force stairs, just area */
970 u_on_rndspot((u.uhave.amulet ? 1 : 0) /* 'going up' flag */
971 | (was_in_W_tower ? 2 : 0));
973 /* u_on_rndspot() might pick a spot that has a monster, or losedogs()
974 might pick the hero's spot (only if there isn't already a monster
975 there), so we might have to move hero or the co-located monster */
976 if ((mtmp = m_at(u.ux, u.uy)) != 0)
985 deliver_splev_message(); /* level entry */
986 check_special_room(FALSE); /* room entry */
991 pline(unavailcmd, "#wizmakemap");
996 /* ^F command - reveal the level map and any traps on it */
1002 long save_Hconf = HConfusion, save_Hhallu = HHallucination;
1004 HConfusion = HHallucination = 0L;
1005 for (t = ftrap; t != 0; t = t->ntrap) {
1010 HConfusion = save_Hconf;
1011 HHallucination = save_Hhallu;
1013 pline(unavailcmd, visctrl((int) cmd_from_func(wiz_map)));
1017 /* ^G command - generate monster(s); a count prefix will be honored */
1019 wiz_genesis(VOID_ARGS)
1022 (void) create_particular();
1024 pline(unavailcmd, visctrl((int) cmd_from_func(wiz_genesis)));
1028 /* ^O command - display dungeon layout */
1030 wiz_where(VOID_ARGS)
1033 (void) print_dungeon(FALSE, (schar *) 0, (xchar *) 0);
1035 pline(unavailcmd, visctrl((int) cmd_from_func(wiz_where)));
1039 /* ^E command - detect unseen (secret doors, traps, hidden monsters) */
1041 wiz_detect(VOID_ARGS)
1046 pline(unavailcmd, visctrl((int) cmd_from_func(wiz_detect)));
1050 /* ^V command - level teleport */
1052 wiz_level_tele(VOID_ARGS)
1057 pline(unavailcmd, visctrl((int) cmd_from_func(wiz_level_tele)));
1061 /* #levelchange command - adjust hero's experience level */
1063 wiz_level_change(VOID_ARGS)
1065 char buf[BUFSZ] = DUMMY;
1070 getlin("To what experience level do you want to be set?", buf);
1072 getlin("
\8co
\8c±
\83\8c\83x
\83\8b\82ð
\82¢
\82
\82Â
\82É
\90Ý
\92è
\82µ
\82Ü
\82·
\82©
\81H", buf);
1073 (void) mungspaces(buf);
1074 if (buf[0] == '\033' || buf[0] == '\0')
1077 ret = sscanf(buf, "%d", &newlevel);
1083 if (newlevel == u.ulevel) {
1085 You("are already that experienced.");
1087 You("
\82·
\82Å
\82É
\82»
\82Ì
\8co
\8c±
\83\8c\83x
\83\8b\82¾
\81D");
1088 } else if (newlevel < u.ulevel) {
1089 if (u.ulevel == 1) {
1091 You("are already as inexperienced as you can get.");
1093 You("
\82·
\82Å
\82É
\89Â
\94\
\82È
\8cÀ
\82è
\82Ì
\8dÅ
\92á
\82Ì
\8co
\8c±
\83\8c\83x
\83\8b\82¾
\81D");
1098 while (u.ulevel > newlevel)
1100 losexp("#levelchange");
1102 losexp("#levelchange
\83R
\83}
\83\93\83h
\82Å");
1104 if (u.ulevel >= MAXULEV) {
1106 You("are already as experienced as you can get.");
1108 You("
\82·
\82Å
\82É
\89Â
\94\
\82È
\8cÀ
\82è
\82Ì
\8dÅ
\91å
\82Ì
\8co
\8c±
\83\8c\83x
\83\8b\82¾
\81D");
1111 if (newlevel > MAXULEV)
1113 while (u.ulevel < newlevel)
1116 u.ulevelmax = u.ulevel;
1120 /* #panic command - test program's panic handling */
1122 wiz_panic(VOID_ARGS)
1124 if (iflags.debug_fuzzer) {
1125 u.uhp = u.uhpmax = 1000;
1126 u.uen = u.uenmax = 1000;
1130 if (yn("Do you want to call panic() and end your game?") == 'y')
1132 if (yn("panic()
\8aÖ
\90\94\82ð
\8cÄ
\82Ñ
\8fo
\82µ
\82Ä
\83Q
\81[
\83\80\82ð
\8fI
\97¹
\82³
\82¹
\82Ü
\82·
\82©
\81H") == 'y')
1133 panic("Crash test.");
1137 /* #polyself command - change hero's form */
1139 wiz_polyself(VOID_ARGS)
1145 /* #seenv command */
1147 wiz_show_seenv(VOID_ARGS)
1150 int x, y, v, startx, stopx, curx;
1151 char row[COLNO + 1];
1153 win = create_nhwindow(NHW_TEXT);
1155 * Each seenv description takes up 2 characters, so center
1156 * the seenv display around the hero.
1158 startx = max(1, u.ux - (COLNO / 4));
1159 stopx = min(startx + (COLNO / 2), COLNO);
1160 /* can't have a line exactly 80 chars long */
1161 if (stopx - startx == COLNO / 2)
1164 for (y = 0; y < ROWNO; y++) {
1165 for (x = startx, curx = 0; x < stopx; x++, curx += 2) {
1166 if (x == u.ux && y == u.uy) {
1167 row[curx] = row[curx + 1] = '@';
1169 v = levl[x][y].seenv & 0xff;
1171 row[curx] = row[curx + 1] = ' ';
1173 Sprintf(&row[curx], "%02x", v);
1176 /* remove trailing spaces */
1177 for (x = curx - 1; x >= 0; x--)
1182 putstr(win, 0, row);
1184 display_nhwindow(win, TRUE);
1185 destroy_nhwindow(win);
1189 /* #vision command */
1191 wiz_show_vision(VOID_ARGS)
1195 char row[COLNO + 1];
1197 win = create_nhwindow(NHW_TEXT);
1198 Sprintf(row, "Flags: 0x%x could see, 0x%x in sight, 0x%x temp lit",
1199 COULD_SEE, IN_SIGHT, TEMP_LIT);
1200 putstr(win, 0, row);
1202 for (y = 0; y < ROWNO; y++) {
1203 for (x = 1; x < COLNO; x++) {
1204 if (x == u.ux && y == u.uy)
1207 v = viz_array[y][x]; /* data access should be hidden */
1211 row[x] = '0' + viz_array[y][x];
1214 /* remove trailing spaces */
1215 for (x = COLNO - 1; x >= 1; x--)
1220 putstr(win, 0, &row[1]);
1222 display_nhwindow(win, TRUE);
1223 destroy_nhwindow(win);
1227 /* #wmode command */
1229 wiz_show_wmodes(VOID_ARGS)
1233 char row[COLNO + 1];
1235 boolean istty = WINDOWPORT("tty");
1237 win = create_nhwindow(NHW_TEXT);
1239 putstr(win, 0, ""); /* tty only: blank top line */
1240 for (y = 0; y < ROWNO; y++) {
1241 for (x = 0; x < COLNO; x++) {
1243 if (x == u.ux && y == u.uy)
1245 else if (IS_WALL(lev->typ) || lev->typ == SDOOR)
1246 row[x] = '0' + (lev->wall_info & WM_MASK);
1247 else if (lev->typ == CORR)
1249 else if (IS_ROOM(lev->typ) || IS_DOOR(lev->typ))
1255 /* map column 0, levl[0][], is off the left edge of the screen */
1256 putstr(win, 0, &row[1]);
1258 display_nhwindow(win, TRUE);
1259 destroy_nhwindow(win);
1263 /* wizard mode variant of #terrain; internal levl[][].typ values in base-36 */
1265 wiz_map_levltyp(VOID_ARGS)
1269 char row[COLNO + 1];
1270 boolean istty = !strcmp(windowprocs.name, "tty");
1272 win = create_nhwindow(NHW_TEXT);
1273 /* map row 0, levl[][0], is drawn on the second line of tty screen */
1275 putstr(win, 0, ""); /* tty only: blank top line */
1276 for (y = 0; y < ROWNO; y++) {
1277 /* map column 0, levl[0][], is off the left edge of the screen;
1278 it should always have terrain type "undiggable stone" */
1279 for (x = 1; x < COLNO; x++) {
1280 terrain = levl[x][y].typ;
1281 /* assumes there aren't more than 10+26+26 terrain types */
1282 row[x - 1] = (char) ((terrain == STONE && !may_dig(x, y))
1287 ? 'a' + terrain - 10
1288 : 'A' + terrain - 36);
1291 if (levl[0][y].typ != STONE || may_dig(0, y))
1294 putstr(win, 0, row);
1299 s_level *slev = Is_special(&u.uz);
1301 Sprintf(dsc, "D:%d,L:%d", u.uz.dnum, u.uz.dlevel);
1302 /* [dungeon branch features currently omitted] */
1303 /* special level features */
1305 Sprintf(eos(dsc), " \"%s\"", slev->proto);
1306 /* special level flags (note: dungeon.def doesn't set `maze'
1307 or `hell' for any specific levels so those never show up) */
1308 if (slev->flags.maze_like)
1309 Strcat(dsc, " mazelike");
1310 if (slev->flags.hellish)
1311 Strcat(dsc, " hellish");
1312 if (slev->flags.town)
1313 Strcat(dsc, " town");
1314 if (slev->flags.rogue_like)
1315 Strcat(dsc, " roguelike");
1316 /* alignment currently omitted to save space */
1318 /* level features */
1319 if (level.flags.nfountains)
1320 Sprintf(eos(dsc), " %c:%d", defsyms[S_fountain].sym,
1321 (int) level.flags.nfountains);
1322 if (level.flags.nsinks)
1323 Sprintf(eos(dsc), " %c:%d", defsyms[S_sink].sym,
1324 (int) level.flags.nsinks);
1325 if (level.flags.has_vault)
1326 Strcat(dsc, " vault");
1327 if (level.flags.has_shop)
1328 Strcat(dsc, " shop");
1329 if (level.flags.has_temple)
1330 Strcat(dsc, " temple");
1331 if (level.flags.has_court)
1332 Strcat(dsc, " throne");
1333 if (level.flags.has_zoo)
1334 Strcat(dsc, " zoo");
1335 if (level.flags.has_morgue)
1336 Strcat(dsc, " morgue");
1337 if (level.flags.has_barracks)
1338 Strcat(dsc, " barracks");
1339 if (level.flags.has_beehive)
1340 Strcat(dsc, " hive");
1341 if (level.flags.has_swamp)
1342 Strcat(dsc, " swamp");
1344 if (level.flags.noteleport)
1345 Strcat(dsc, " noTport");
1346 if (level.flags.hardfloor)
1347 Strcat(dsc, " noDig");
1348 if (level.flags.nommap)
1349 Strcat(dsc, " noMMap");
1350 if (!level.flags.hero_memory)
1351 Strcat(dsc, " noMem");
1352 if (level.flags.shortsighted)
1353 Strcat(dsc, " shortsight");
1354 if (level.flags.graveyard)
1355 Strcat(dsc, " graveyard");
1356 if (level.flags.is_maze_lev)
1357 Strcat(dsc, " maze");
1358 if (level.flags.is_cavernous_lev)
1359 Strcat(dsc, " cave");
1360 if (level.flags.arboreal)
1361 Strcat(dsc, " tree");
1363 Strcat(dsc, " sokoban-rules");
1364 /* non-flag info; probably should include dungeon branching
1365 checks (extra stairs and magic portals) here */
1366 if (Invocation_lev(&u.uz))
1367 Strcat(dsc, " invoke");
1368 if (On_W_tower_level(&u.uz))
1369 Strcat(dsc, " tower");
1370 /* append a branch identifier for completeness' sake */
1372 Strcat(dsc, " dungeon");
1373 else if (u.uz.dnum == mines_dnum)
1374 Strcat(dsc, " mines");
1375 else if (In_sokoban(&u.uz))
1376 Strcat(dsc, " sokoban");
1377 else if (u.uz.dnum == quest_dnum)
1378 Strcat(dsc, " quest");
1379 else if (Is_knox(&u.uz))
1380 Strcat(dsc, " ludios");
1381 else if (u.uz.dnum == 1)
1382 Strcat(dsc, " gehennom");
1383 else if (u.uz.dnum == tower_dnum)
1384 Strcat(dsc, " vlad");
1385 else if (In_endgame(&u.uz))
1386 Strcat(dsc, " endgame");
1388 /* somebody's added a dungeon branch we're not expecting */
1389 const char *brname = dungeons[u.uz.dnum].dname;
1391 if (!brname || !*brname)
1393 if (!strncmpi(brname, "the ", 4))
1395 Sprintf(eos(dsc), " %s", brname);
1397 /* limit the line length to map width */
1398 if (strlen(dsc) >= COLNO)
1399 dsc[COLNO - 1] = '\0'; /* truncate */
1400 putstr(win, 0, dsc);
1403 display_nhwindow(win, TRUE);
1404 destroy_nhwindow(win);
1408 /* temporary? hack, since level type codes aren't the same as screen
1409 symbols and only the latter have easily accessible descriptions */
1410 static const char *levltyp[] = {
1411 "stone", "vertical wall", "horizontal wall", "top-left corner wall",
1412 "top-right corner wall", "bottom-left corner wall",
1413 "bottom-right corner wall", "cross wall", "tee-up wall", "tee-down wall",
1414 "tee-left wall", "tee-right wall", "drawbridge wall", "tree",
1415 "secret door", "secret corridor", "pool", "moat", "water",
1416 "drawbridge up", "lava pool", "iron bars", "door", "corridor", "room",
1417 "stairs", "ladder", "fountain", "throne", "sink", "grave", "altar", "ice",
1418 "drawbridge down", "air", "cloud",
1419 /* not a real terrain type, but used for undiggable stone
1420 by wiz_map_levltyp() */
1421 "unreachable/undiggable",
1422 /* padding in case the number of entries above is odd */
1426 /* explanation of base-36 output from wiz_map_levltyp() */
1428 wiz_levltyp_legend(VOID_ARGS)
1432 const char *dsc, *fmt;
1435 win = create_nhwindow(NHW_TEXT);
1436 putstr(win, 0, "#terrain encodings:");
1438 fmt = " %c - %-28s"; /* TODO: include tab-separated variant for win32 */
1440 /* output in pairs, left hand column holds [0],[1],...,[N/2-1]
1441 and right hand column holds [N/2],[N/2+1],...,[N-1];
1442 N ('last') will always be even, and may or may not include
1443 the empty string entry to pad out the final pair, depending
1444 upon how many other entries are present in levltyp[] */
1445 last = SIZE(levltyp) & ~1;
1446 for (i = 0; i < last / 2; ++i)
1447 for (j = i; j < last; j += last / 2) {
1450 : !strncmp(dsc, "unreachable", 11) ? '*'
1451 /* same int-to-char conversion as wiz_map_levltyp() */
1452 : (j < 10) ? '0' + j
1453 : (j < 36) ? 'a' + j - 10
1455 Sprintf(eos(buf), fmt, c, dsc);
1457 putstr(win, 0, buf);
1461 display_nhwindow(win, TRUE);
1462 destroy_nhwindow(win);
1466 /* #wizsmell command - test usmellmon(). */
1468 wiz_smell(VOID_ARGS)
1471 int mndx; /* monster index */
1472 coord cc; /* screen pos of unknown glyph */
1473 int glyph; /* glyph at selected position */
1477 mndx = 0; /* gcc -Wall lint */
1478 if (!olfaction(youmonst.data)) {
1479 You("are incapable of detecting odors in your present form.");
1483 pline("You can move the cursor to a monster that you want to smell.");
1485 pline("Pick a monster to smell.");
1486 ans = getpos(&cc, TRUE, "a monster");
1487 if (ans < 0 || cc.x < 0) {
1488 return 0; /* done */
1490 /* Convert the glyph at the selected position to a mndxbol. */
1491 glyph = glyph_at(cc.x, cc.y);
1492 if (glyph_is_monster(glyph))
1493 mndx = glyph_to_mon(glyph);
1496 /* Is it a monster? */
1498 if (!usmellmon(&mons[mndx]))
1499 pline("That monster seems to give off no smell.");
1501 pline("That is not a monster.");
1506 /* #wizinstrinsic command to set some intrinsics for testing */
1508 wiz_intrinsic(VOID_ARGS)
1511 extern const struct propname {
1513 const char *prop_name;
1514 } propertynames[]; /* timeout.c */
1515 static const char wizintrinsic[] = "#wizintrinsic";
1516 static const char fmt[] = "You are%s %s.";
1520 int i, j, n, p, amt, typ;
1521 long oldtimeout, newtimeout;
1522 const char *propname;
1523 menu_item *pick_list = (menu_item *) 0;
1526 win = create_nhwindow(NHW_MENU);
1528 for (i = 0; (propname = propertynames[i].prop_name) != 0; ++i) {
1529 p = propertynames[i].prop_num;
1530 if (p == HALLUC_RES) {
1531 /* Grayswandir vs hallucination; ought to be redone to
1532 use u.uprops[HALLUC].blocked instead of being treated
1533 as a separate property; letting in be manually toggled
1534 even only in wizard mode would be asking for trouble... */
1537 if (p == FIRE_RES) {
1539 add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, "--", FALSE);
1541 any.a_int = i + 1; /* +1: avoid 0 */
1542 oldtimeout = u.uprops[p].intrinsic & TIMEOUT;
1544 Sprintf(buf, "%-27s [%li]", propname, oldtimeout);
1546 Sprintf(buf, "%s", propname);
1547 add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
1549 end_menu(win, "Which intrinsics?");
1550 n = select_menu(win, PICK_ANY, &pick_list);
1551 destroy_nhwindow(win);
1553 amt = 30; /* TODO: prompt for duration */
1554 for (j = 0; j < n; ++j) {
1555 i = pick_list[j].item.a_int - 1; /* -1: reverse +1 above */
1556 p = propertynames[i].prop_num;
1557 oldtimeout = u.uprops[p].intrinsic & TIMEOUT;
1558 newtimeout = oldtimeout + (long) amt;
1563 if (oldtimeout > 0L && newtimeout > oldtimeout)
1564 newtimeout = oldtimeout;
1570 make_blinded(newtimeout, TRUE);
1572 #if 0 /* make_confused() only gives feedback when confusion is
1573 * ending so use the 'default' case for it instead */
1575 make_confused(newtimeout, TRUE);
1579 make_deaf(newtimeout, TRUE);
1582 make_hallucinated(newtimeout, TRUE, 0L);
1585 typ = !rn2(2) ? SICK_VOMITABLE : SICK_NONVOMITABLE;
1586 make_sick(newtimeout, wizintrinsic, TRUE, typ);
1590 !Slimed ? "" : " still", "turning into slime");
1591 make_slimed(newtimeout, buf);
1595 !Stoned ? "" : " still", "turning into stone");
1596 make_stoned(newtimeout, buf, KILLED_BY, wizintrinsic);
1599 make_stunned(newtimeout, TRUE);
1602 Sprintf(buf, fmt, !Vomiting ? "" : " still", "vomiting");
1603 make_vomiting(newtimeout, FALSE);
1608 context.warntype.speciesidx = PM_GRID_BUG;
1609 context.warntype.species
1610 = &mons[context.warntype.speciesidx];
1619 pline("Timeout for %s %s %d.", propertynames[i].prop_name,
1620 oldtimeout ? "increased by" : "set to", amt);
1621 incr_itimeout(&u.uprops[p].intrinsic, amt);
1624 context.botl = 1; /* probably not necessary... */
1627 free((genericptr_t) pick_list);
1630 pline(unavailcmd, visctrl((int) cmd_from_func(wiz_intrinsic)));
1634 /* #wizrumorcheck command - verify each rumor access */
1636 wiz_rumor_check(VOID_ARGS)
1642 /* #terrain command -- show known map, inspired by crawl's '|' command */
1644 doterrain(VOID_ARGS)
1653 * normal play: choose between known map without mons, obj, and traps
1654 * (to see underlying terrain only), or
1655 * known map without mons and objs (to see traps under mons and objs), or
1656 * known map without mons (to see objects under monsters);
1657 * explore mode: normal choices plus full map (w/o mons, objs, traps);
1658 * wizard mode: normal and explore choices plus
1659 * a dump of the internal levl[][].typ codes w/ level flags, or
1660 * a legend for the levl[][].typ codes dump
1662 men = create_nhwindow(NHW_MENU);
1666 add_menu(men, NO_GLYPH, &any, 0, 0, ATR_NONE,
1668 "known map without monsters, objects, and traps",
1670 "
\89ö
\95¨
\81C
\95¨
\81Cã©
\82È
\82µ
\82Ì
\92n
\90}",
1673 add_menu(men, NO_GLYPH, &any, 0, 0, ATR_NONE,
1675 "known map without monsters and objects",
1677 "
\89ö
\95¨
\81C
\95¨
\82È
\82µ
\82Ì
\92n
\90}",
1680 add_menu(men, NO_GLYPH, &any, 0, 0, ATR_NONE,
1682 "known map without monsters",
1684 "
\89ö
\95¨
\82È
\82µ
\82Ì
\92n
\90}",
1686 if (discover || wizard) {
1688 add_menu(men, NO_GLYPH, &any, 0, 0, ATR_NONE,
1690 "full map without monsters, objects, and traps",
1692 "
\89ö
\95¨
\81C
\95¨
\81Cã©
\82È
\82µ
\82Ì
\8a®
\91S
\82È
\92n
\90}",
1696 add_menu(men, NO_GLYPH, &any, 0, 0, ATR_NONE,
1697 "internal levl[][].typ codes in base-36",
1700 add_menu(men, NO_GLYPH, &any, 0, 0, ATR_NONE,
1701 "legend of base-36 levl[][].typ codes",
1706 end_menu(men, "View which?");
1708 end_menu(men, "
\82Ç
\82ê
\82ð
\8c©
\82é
\81H");
1710 n = select_menu(men, PICK_ONE, &sel);
1711 destroy_nhwindow(men);
1713 * n < 0: player used ESC to cancel;
1714 * n == 0: preselected entry was explicitly chosen and got toggled off;
1715 * n == 1: preselected entry was implicitly chosen via <space>|<enter>;
1716 * n == 2: another entry was explicitly chosen, so skip preselected one.
1718 which = (n < 0) ? -1 : (n == 0) ? 1 : sel[0].item.a_int;
1719 if (n > 1 && which == 1)
1720 which = sel[1].item.a_int;
1722 free((genericptr_t) sel);
1725 case 1: /* known map */
1726 reveal_terrain(0, TER_MAP);
1728 case 2: /* known map with known traps */
1729 reveal_terrain(0, TER_MAP | TER_TRP);
1731 case 3: /* known map with known traps and objects */
1732 reveal_terrain(0, TER_MAP | TER_TRP | TER_OBJ);
1734 case 4: /* full map */
1735 reveal_terrain(1, TER_MAP);
1737 case 5: /* map internals */
1740 case 6: /* internal details */
1741 wiz_levltyp_legend();
1746 return 0; /* no time elapses */
1749 /* -enlightenment and conduct- */
1750 static winid en_win = WIN_ERR;
1751 static boolean en_via_menu = FALSE;
1753 static const char You_[] = "You ", are[] = "are ", were[] = "were ",
1754 have[] = "have ", had[] = "had ", can[] = "can ",
1757 static const char You_[] = "
\82 \82È
\82½
\82Í",
1758 are[] = "
\82Å
\82 \82é", were[] = "
\82Å
\82 \82Á
\82½",
1759 have[] = "
\82ð
\82à
\82Á
\82Ä
\82¢
\82é", had[] = "
\82ð
\82à
\82Á
\82Ä
\82¢
\82½",
1760 can[] = "
\82Å
\82«
\82é", could[] = "
\82Å
\82«
\82½",
1761 iru[] = "
\82¢
\82é", ita[] = "
\82¢
\82½";
1763 #if 0 /*JP*//* not used */
1764 static const char have_been[] = "have been ", have_never[] = "have never ",
1769 #define enl_msg(prefix, present, past, suffix, ps) \
1770 enlght_line(prefix, final ? past : present, suffix, ps)
1772 #define enl_msg(prefix, present, past, suffix, ps) \
1773 enlght_line(prefix, ps, suffix, final ? past : present)
1775 #define you_are(attr, ps) enl_msg(You_, are, were, attr, ps)
1776 #define you_have(attr, ps) enl_msg(You_, have, had, attr, ps)
1777 #define you_can(attr, ps) enl_msg(You_, can, could, attr, ps)
1779 #define you_have_been(goodthing) enl_msg(You_, have_been, were, goodthing, "")
1781 #define you_have_been(goodthing) enl_msg(You_, are, were, goodthing, "")
1783 #define you_have_never(badthing) \
1784 enl_msg(You_, have_never, never, badthing, "")
1786 #define you_have_never(badthing) \
1787 enl_msg(badthing, "
\82Ä
\82¢
\82È
\82¢", "
\82È
\82©
\82Á
\82½", "", "")
1790 #define you_have_X(something) \
1791 enl_msg(You_, have, (const char *) "", something, "")
1793 #define you_have_X(something) \
1794 enl_msg(something, "
\82Ä
\82¢
\82é", "
\82½", "", "")
1797 #define you_are_ing(goodthing, ps) enl_msg(You_, iru, ita, goodthing, ps)
1808 add_menu(en_win, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
1810 putstr(en_win, 0, buf);
1814 enlght_line(start, middle, end, ps)
1815 const char *start, *middle, *end, *ps;
1820 Sprintf(buf, " %s%s%s%s.", start, middle, end, ps);
1822 Sprintf(buf, "%s%s%s%s
\81D", start, middle, end, ps);
1826 /* format increased chance to hit or damage or defense (Protection) */
1828 enlght_combatinc(inctyp, incamt, final, outbuf)
1833 const char *modif, *bonus;
1839 absamt = abs(incamt);
1840 /* Protection amount is typically larger than damage or to-hit;
1841 reduce magnitude by a third in order to stretch modifier ranges
1842 (small:1..5, moderate:6..10, large:11..19, huge:20+) */
1844 if (!strcmp(inctyp, "defense"))
1846 if (!strcmp(inctyp, "
\96h
\8cä"))
1848 absamt = (absamt * 2) / 3;
1854 modif = "
\8bÍ
\82©
\82È";
1855 else if (absamt <= 6)
1859 modif = "
\92\86\92ö
\93x
\82Ì";
1860 else if (absamt <= 12)
1864 modif = "
\91å
\82«
\82È";
1869 modif = "
\8b
\91å
\82È";
1872 modif = !incamt ? "no" : an(modif); /* ("no" case shouldn't happen) */
1875 bonus = (incamt >= 0) ? "bonus" : "penalty";
1877 bonus = (incamt > 0) ? "
\83{
\81[
\83i
\83X" : "
\83y
\83i
\83\8b\83e
\83B";
1878 /* "bonus <foo>" (to hit) vs "<bar> bonus" (damage, defense) */
1880 invrt = strcmp(inctyp, "to hit") ? TRUE : FALSE;
1884 Sprintf(outbuf, "%s %s %s", modif, invrt ? inctyp : bonus,
1885 invrt ? bonus : inctyp);
1887 Sprintf(outbuf, "%s
\82É%s%s", inctyp, modif, bonus);
1889 if (final || wizard)
1890 Sprintf(eos(outbuf), " (%s%d)", (incamt > 0) ? "+" : "", incamt);
1895 /* report half physical or half spell damage */
1897 enlght_halfdmg(category, final)
1901 const char *category_name;
1907 category_name = "physical";
1909 category_name = "
\95¨
\97\9d";
1913 category_name = "spell";
1915 category_name = "
\8eô
\95¶";
1919 category_name = "unknown";
1921 category_name = "
\95s
\96¾";
1925 Sprintf(buf, " %s %s damage", (final || wizard) ? "half" : "reduced",
1927 enl_msg(You_, "take", "took", buf, from_what(category));
1929 Sprintf(buf, " %s
\83_
\83\81\81[
\83W
\82ð%s", (final || wizard) ? "
\94¼
\8c¸" : "
\8c¸
\8f",
1931 enl_msg(You_, "
\82µ
\82Ä
\82¢
\82é", "
\82µ
\82Ä
\82¢
\82½", buf, from_what(category));
1935 /* is hero actively using water walking capability on water (or lava)? */
1939 if (u.uinwater || Levitation || Flying)
1941 return (boolean) (Wwalking
1942 && (is_pool(u.ux, u.uy) || is_lava(u.ux, u.uy)));
1945 /* check whether hero is wearing something that player definitely knows
1946 confers the target property; item must have been seen and its type
1947 discovered but it doesn't necessarily have to be fully identified */
1949 cause_known(propindx)
1950 int propindx; /* index of a property which can be conveyed by worn item */
1952 register struct obj *o;
1953 long mask = W_ARMOR | W_AMUL | W_RING | W_TOOL;
1955 /* simpler than from_what()/what_gives(); we don't attempt to
1956 handle artifacts and we deliberately ignore wielded items */
1957 for (o = invent; o; o = o->nobj) {
1958 if (!(o->owornmask & mask))
1960 if ((int) objects[o->otyp].oc_oprop == propindx
1961 && objects[o->otyp].oc_name_known && o->dknown)
1967 /* format a characteristic value, accommodating Strength's strangeness */
1969 attrval(attrindx, attrvalue, resultbuf)
1970 int attrindx, attrvalue;
1971 char resultbuf[]; /* should be at least [7] to hold "18/100\0" */
1973 if (attrindx != A_STR || attrvalue <= 18)
1974 Sprintf(resultbuf, "%d", attrvalue);
1975 else if (attrvalue > STR18(100)) /* 19 to 25 */
1976 Sprintf(resultbuf, "%d", attrvalue - 100);
1977 else /* simplify "18/ **" to be "18/100" */
1978 Sprintf(resultbuf, "18/%02d", attrvalue - 18);
1983 enlightenment(mode, final)
1984 int mode; /* BASICENLIGHTENMENT | MAGICENLIGHTENMENT (| both) */
1985 int final; /* ENL_GAMEINPROGRESS:0, ENL_GAMEOVERALIVE, ENL_GAMEOVERDEAD */
1987 char buf[BUFSZ], tmpbuf[BUFSZ];
1989 en_win = create_nhwindow(NHW_MENU);
1990 en_via_menu = !final;
1994 Strcpy(tmpbuf, plname);
1995 *tmpbuf = highc(*tmpbuf); /* same adjustment as bottom line */
1996 /* as in background_enlightenment, when poly'd we need to use the saved
1997 gender in u.mfemale rather than the current you-as-monster gender */
1999 Sprintf(buf, "%s the %s's attributes:", tmpbuf,
2000 ((Upolyd ? u.mfemale : flags.female) && urole.name.f)
2004 Sprintf(buf, "%s
\82Ì%s
\82Ì
\91®
\90«:",
2005 ((Upolyd ? u.mfemale : flags.female) && urole.name.f)
2012 enlght_out(buf); /* "Conan the Archeologist's attributes:" */
2013 /* background and characteristics; ^X or end-of-game disclosure */
2014 if (mode & BASICENLIGHTENMENT) {
2015 /* role, race, alignment, deities, dungeon level, time, experience */
2016 background_enlightenment(mode, final);
2017 /* hit points, energy points, armor class, gold */
2018 basics_enlightenment(mode, final);
2019 /* strength, dexterity, &c */
2020 characteristics_enlightenment(mode, final);
2022 /* expanded status line information, including things which aren't
2023 included there due to space considerations--such as obvious
2024 alternative movement indicators (riding, levitation, &c), and
2025 various troubles (turning to stone, trapped, confusion, &c);
2026 shown for both basic and magic enlightenment */
2027 status_enlightenment(mode, final);
2028 /* remaining attributes; shown for potion,&c or wizard mode and
2029 explore mode ^X or end of game disclosure */
2030 if (mode & MAGICENLIGHTENMENT) {
2031 /* intrinsics and other traditional enlightenment feedback */
2032 attributes_enlightenment(mode, final);
2036 display_nhwindow(en_win, TRUE);
2038 menu_item *selected = 0;
2040 end_menu(en_win, (char *) 0);
2041 if (select_menu(en_win, PICK_NONE, &selected) > 0)
2042 free((genericptr_t) selected);
2043 en_via_menu = FALSE;
2045 destroy_nhwindow(en_win);
2050 /* display role, race, alignment and such to en_win */
2052 background_enlightenment(unused_mode, final)
2053 int unused_mode UNUSED;
2056 const char *role_titl, *rank_titl;
2057 int innategend, difgend, difalgn;
2058 char buf[BUFSZ], tmpbuf[BUFSZ];
2060 /* note that if poly'd, we need to use u.mfemale instead of flags.female
2061 to access hero's saved gender-as-human/elf/&c rather than current one */
2062 innategend = (Upolyd ? u.mfemale : flags.female) ? 1 : 0;
2063 role_titl = (innategend && urole.name.f) ? urole.name.f : urole.name.m;
2064 rank_titl = rank_of(u.ulevel, Role_switch, innategend);
2066 enlght_out(""); /* separator after title */
2068 enlght_out("Background:");
2070 enlght_out("
\94w
\8ci
\8fî
\95ñ:");
2072 /* if polymorphed, report current shape before underlying role;
2073 will be repeated as first status: "you are transformed" and also
2074 among various attributes: "you are in beast form" (after being
2075 told about lycanthropy) or "you are polymorphed into <a foo>"
2076 (with countdown timer appended for wizard mode); we really want
2077 the player to know he's not a samurai at the moment... */
2079 struct permonst *uasmon = youmonst.data;
2082 /* here we always use current gender, not saved role gender */
2083 if (!is_male(uasmon) && !is_female(uasmon) && !is_neuter(uasmon))
2085 Sprintf(tmpbuf, "%s ", genders[flags.female ? 1 : 0].adj);
2087 Sprintf(tmpbuf, "%s
\82Ì", genders[flags.female ? 1 : 0].adj);
2089 Sprintf(buf, "%sin %s%s form", !final ? "currently " : "", tmpbuf,
2092 Sprintf(buf, "%s%s%s
\82Ì
\8ep", !final ? "
\8d¡
\82Ì
\82Æ
\82±
\82ë" : "", tmpbuf,
2098 you_are_ing(buf, "");
2101 /* report role; omit gender if it's redundant (eg, "female priestess") */
2104 && ((urole.allow & ROLE_GENDMASK) == (ROLE_MALE | ROLE_FEMALE)
2105 || innategend != flags.initgend))
2107 Sprintf(tmpbuf, "%s ", genders[innategend].adj);
2109 Sprintf(tmpbuf, "%s", genders[innategend].adj);
2113 Strcpy(buf, "actually "); /* "You are actually a ..." */
2115 Strcpy(buf, "
\8eÀ
\8dÛ
\82É
\82Í"); /* "
\82 \82È
\82½
\82Í
\8eÀ
\8dÛ
\82É
\82Í..." */
2117 if (!strcmpi(rank_titl, role_titl)) {
2118 /* omit role when rank title matches it */
2120 Sprintf(eos(buf), "%s, level %d %s%s", an(rank_titl), u.ulevel,
2121 tmpbuf, urace.noun);
2123 Sprintf(eos(buf), "
\83\8c\83x
\83\8b%d
\82Ì%s
\82Ì%s%s", u.ulevel,
2124 tmpbuf, urace.adj, role_titl);
2128 Sprintf(eos(buf), "%s, a level %d %s%s %s", an(rank_titl), u.ulevel,
2129 tmpbuf, urace.adj, role_titl);
2131 Sprintf(eos(buf), "
\83\8c\83x
\83\8b%d
\82Ì%s
\82Ì%s%s
\82Ì%s", u.ulevel,
2132 tmpbuf, urace.adj, role_titl, rank_titl);
2137 /* report alignment (bypass you_are() in order to omit ending period);
2138 adverb is used to distinguish between temporary change (helm of opp.
2139 alignment), permanent change (one-time conversion), and original */
2141 Sprintf(buf, " %s%s%s, %son a mission for %s",
2142 You_, !final ? are : were,
2143 align_str(u.ualign.type),
2144 /* helm of opposite alignment (might hide conversion) */
2145 (u.ualign.type != u.ualignbase[A_CURRENT])
2146 /* what's the past tense of "currently"? if we used "formerly"
2147 it would sound like a reference to the original alignment */
2148 ? (!final ? "currently " : "temporarily ")
2149 /* permanent conversion */
2150 : (u.ualign.type != u.ualignbase[A_ORIGINAL])
2151 /* and what's the past tense of "now"? certainly not "then"
2152 in a context like this...; "belatedly" == weren't that
2153 way sooner (in other words, didn't start that way) */
2154 ? (!final ? "now " : "belatedly ")
2155 /* atheist (ignored in very early game) */
2156 : (!u.uconduct.gnostic && moves > 1000L)
2158 /* lastly, normal case */
2162 Sprintf(buf, "
\82 \82È
\82½
\82Í%s
\82Å, %s%s
\82Ì
\82½
\82ß
\82Ì
\94C
\96±
\82ð
\8ds
\82Á
\82Ä%s
\81D",
2163 align_str(u.ualign.type),
2164 /* helm of opposite alignment (might hide conversion) */
2165 (u.ualign.type != u.ualignbase[A_CURRENT]) ? "
\88ê
\8e\9e\93I
\82É"
2166 /* permanent conversion */
2167 : (u.ualign.type != u.ualignbase[A_ORIGINAL]) ? "
\8c»
\8dÝ"
2168 /* atheist (ignored in very early game) */
2169 : (!u.uconduct.gnostic && moves > 1000L) ? "
\96¼
\8b`
\8fã"
2170 /* lastly, normal case */
2172 u_gname(), !final ? iru : ita);
2175 /* show the rest of this game's pantheon (finishes previous sentence)
2176 [appending "also Moloch" at the end would allow for straightforward
2177 trailing "and" on all three aligned entries but looks too verbose] */
2179 Sprintf(buf, " who %s opposed by", !final ? "is" : "was");
2181 Strcpy(buf, "
\82 \82È
\82½
\82Í");
2183 if (u.ualign.type != A_LAWFUL)
2185 Sprintf(eos(buf), " %s (%s) and", align_gname(A_LAWFUL),
2186 align_str(A_LAWFUL));
2188 Sprintf(eos(buf), "%s(%s)
\82¨
\82æ
\82Ñ", align_gname(A_LAWFUL),
2189 align_str(A_LAWFUL));
2191 if (u.ualign.type != A_NEUTRAL)
2193 Sprintf(eos(buf), " %s (%s)%s", align_gname(A_NEUTRAL),
2194 align_str(A_NEUTRAL),
2195 (u.ualign.type != A_CHAOTIC) ? " and" : "");
2197 Sprintf(eos(buf), "%s(%s)%s", align_gname(A_NEUTRAL),
2198 align_str(A_NEUTRAL),
2199 (u.ualign.type != A_CHAOTIC) ? "
\82¨
\82æ
\82Ñ" : "");
2201 if (u.ualign.type != A_CHAOTIC)
2203 Sprintf(eos(buf), " %s (%s)", align_gname(A_CHAOTIC),
2204 align_str(A_CHAOTIC));
2206 if (u.ualign.type != A_CHAOTIC)
2207 Sprintf(eos(buf), "%s(%s)", align_gname(A_CHAOTIC),
2208 align_str(A_CHAOTIC));
2211 Strcat(buf, "."); /* terminate sentence */
2213 Sprintf(eos(buf), "
\82Æ
\91Î
\97§
\82µ
\82Ä%s
\81D", !final ? iru : ita);
2217 /* show original alignment,gender,race,role if any have been changed;
2218 giving separate message for temporary alignment change bypasses need
2219 for tricky phrasing otherwise necessitated by possibility of having
2220 helm of opposite alignment mask a permanent alignment conversion */
2221 difgend = (innategend != flags.initgend);
2222 difalgn = (((u.ualign.type != u.ualignbase[A_CURRENT]) ? 1 : 0)
2223 + ((u.ualignbase[A_CURRENT] != u.ualignbase[A_ORIGINAL])
2225 if (difalgn & 1) { /* have temporary alignment so report permanent one */
2227 Sprintf(buf, "actually %s", align_str(u.ualignbase[A_CURRENT]));
2229 Sprintf(buf, "
\8eÀ
\8dÛ
\82É
\82Í%s", align_str(u.ualignbase[A_CURRENT]));
2233 enl_msg(buf, "
\82Ä
\82¢
\82é", "
\82Ä
\82¢
\82½", "", "");
2235 difalgn &= ~1; /* suppress helm from "started out <foo>" message */
2237 if (difgend || difalgn) { /* sex change or perm align change or both */
2239 Sprintf(buf, " You started out %s%s%s.",
2240 difgend ? genders[flags.initgend].adj : "",
2241 (difgend && difalgn) ? " and " : "",
2242 difalgn ? align_str(u.ualignbase[A_ORIGINAL]) : "");
2244 Sprintf(buf, "
\82 \82È
\82½
\82Í%s%s%s
\82Å
\8aJ
\8en
\82µ
\82½
\81D",
2245 difgend ? genders[flags.initgend].adj : "",
2246 (difgend && difalgn) ? "
\82©
\82Â" : "",
2247 difalgn ? align_str(u.ualignbase[A_ORIGINAL]) : "");
2252 /* 3.6.2: dungeon level, so that ^X really has all status info as
2253 claimed by the comment below; this reveals more information than
2254 the basic status display, but that's one of the purposes of ^X;
2255 similar information is revealed by #overview; the "You died in
2256 <location>" given by really_done() is more rudimentary than this */
2257 *buf = *tmpbuf = '\0';
2258 if (In_endgame(&u.uz)) {
2259 int egdepth = observable_depth(&u.uz);
2261 (void) endgamelevelname(tmpbuf, egdepth);
2263 Sprintf(buf, "in the endgame, on the %s%s",
2264 !strncmp(tmpbuf, "Plane", 5) ? "Elemental " : "", tmpbuf);
2266 Sprintf(buf, "
\8dÅ
\8fI
\8e\8e\97û
\82Ì%s", tmpbuf);
2268 } else if (Is_knox(&u.uz)) {
2269 /* this gives away the fact that the knox branch is only 1 level */
2271 Sprintf(buf, "on the %s level", dungeons[u.uz.dnum].dname);
2273 Sprintf(buf, "%s", dungeons[u.uz.dnum].dname);
2274 /* TODO? maybe phrase it differently when actually inside the fort,
2275 if we're able to determine that (not trivial) */
2277 char dgnbuf[QBUFSZ];
2279 Strcpy(dgnbuf, dungeons[u.uz.dnum].dname);
2281 if (!strncmpi(dgnbuf, "The ", 4))
2282 *dgnbuf = lowc(*dgnbuf);
2285 Sprintf(tmpbuf, "level %d",
2286 In_quest(&u.uz) ? dunlev(&u.uz) : depth(&u.uz));
2288 if (In_quest(&u.uz)) {
2289 Sprintf(tmpbuf, "
\91æ%d
\8aK
\91w", dunlev(&u.uz));
2291 Sprintf(tmpbuf, "
\92n
\89º%d
\8aK", depth(&u.uz));
2294 /* TODO? maybe extend this bit to include various other automatic
2295 annotations from the dungeon overview code */
2296 if (Is_rogue_level(&u.uz))
2298 Strcat(tmpbuf, ", a primitive area");
2300 Strcat(tmpbuf, ",
\92P
\8f\83\82È
\90¢
\8aE");
2301 else if (Is_bigroom(&u.uz) && !Blind)
2303 Strcat(tmpbuf, ", a very big room");
2305 Strcat(tmpbuf, ",
\82Æ
\82Ä
\82à
\91å
\82«
\82È
\95\94\89®");
2307 Sprintf(buf, "in %s, on %s", dgnbuf, tmpbuf);
2309 Sprintf(buf, "%s
\82Ì%s", dgnbuf, tmpbuf);
2314 /* this is shown even if the 'time' option is off */
2317 you_have("just started your adventure", "");
2319 enlght_line(You_, "", "
\96`
\8c¯
\82ð
\8aJ
\8en
\82µ
\82½
\82Æ
\82±
\82ë
\82¾", "");
2322 /* 'turns' grates on the nerves in this context... */
2324 Sprintf(buf, "the dungeon %ld turn%s ago", moves, plur(moves));
2326 Sprintf(buf, "%ld
\83^
\81[
\83\93\91O
\82É
\96À
\8b{
\82É
\93ü
\82Á
\82½", moves);
2327 /* same phrasing for current and final: "entered" is unconditional */
2329 enlght_line(You_, "entered ", buf, "");
2331 enlght_line(You_, "", buf, "");
2335 /* flags.showexp does not matter */
2336 /* experience level is already shown above */
2338 Sprintf(buf, "%-1ld experience point%s", u.uexp, plur(u.uexp));
2340 Sprintf(buf, "
\8co
\8c±
\92l%-1ld
\83|
\83C
\83\93\83g", u.uexp);
2343 if (u.ulevel < 30) {
2344 int ulvl = (int) u.ulevel;
2345 long nxtlvl = newuexp(ulvl);
2346 /* long oldlvl = (ulvl > 1) ? newuexp(ulvl - 1) : 0; */
2349 Sprintf(eos(buf), ", %ld %s%sneeded to attain level %d",
2350 (nxtlvl - u.uexp), (u.uexp > 0) ? "more " : "",
2351 !final ? "" : "were ", (ulvl + 1));
2353 Sprintf(eos(buf), "(
\83\8c\83x
\83\8b%d
\82Ü
\82Å%ld
\83|
\83C
\83\93\83g)",
2354 (ulvl + 1), (nxtlvl - u.uexp));
2360 #ifdef SCORE_ON_BOTL
2361 if (flags.showscore) {
2362 /* describes what's shown on status line, which is an approximation;
2363 only show it here if player has the 'showscore' option enabled */
2365 Sprintf(buf, "%ld%s", botl_score(),
2366 !final ? "" : " before end-of-game adjustments");
2367 enl_msg("Your score ", "is ", "was ", buf, "");
2369 Sprintf(buf, "%s%ld", botl_score(),
2370 !final ? "" : "
\83Q
\81[
\83\80\8fI
\97¹
\8e\9e\82Ì
\92²
\90®
\91O
\82Í");
2371 enl_msg("
\82 \82È
\82½
\82Ì
\83X
\83R
\83A
\82Í", "
\82Å
\82 \82é", "
\82Å
\82 \82Á
\82½", buf, "");
2377 /* hit points, energy points, armor class -- essential information which
2378 doesn't fit very well in other categories */
2381 basics_enlightenment(mode, final)
2385 static char Power[] = "energy points (spell power)";
2387 int pw = u.uen, hp = (Upolyd ? u.mh : u.uhp),
2388 pwmax = u.uenmax, hpmax = (Upolyd ? u.mhmax : u.uhpmax);
2390 enlght_out(""); /* separator after background */
2392 enlght_out("Basics:");
2394 enlght_out("
\8aî
\96{:");
2398 /* "1 out of 1" rather than "all" if max is only 1; should never happen */
2400 if (hp == hpmax && hpmax > 1)
2401 Sprintf(buf, "all %d hit points", hpmax);
2403 Sprintf(buf, "%d out of %d hit point%s", hp, hpmax, plur(hpmax));
2405 Sprintf(buf, "%d
\83q
\83b
\83g
\83|
\83C
\83\93\83g(
\8dÅ
\91å:%d)", hp, hpmax);
2409 /* low max energy is feasible, so handle couple of extra special cases */
2411 if (pwmax == 0 || (pw == pwmax && pwmax == 2)) /* both: "all 2" is silly */
2412 Sprintf(buf, "%s %s", !pwmax ? "no" : "both", Power);
2413 else if (pw == pwmax && pwmax > 2)
2414 Sprintf(buf, "all %d %s", pwmax, Power);
2416 Sprintf(buf, "%d out of %d %s", pw, pwmax, Power);
2418 Sprintf(buf, "%d
\96\82\97Í
\83|
\83C
\83\93\83g(
\8dÅ
\91å:%d)", pw, pwmax);
2423 switch (mons[u.umonnum].mlevel) {
2425 /* status line currently being explained shows "HD:0" */
2427 Strcpy(buf, "0 hit dice (actually 1/2)");
2429 Strcpy(buf, "HD0(
\8eÀ
\8dÛ
\82É
\82Í1/2)");
2433 Strcpy(buf, "1 hit die");
2439 Sprintf(buf, "%d hit dice", mons[u.umonnum].mlevel);
2441 Sprintf(buf, "HD%d", mons[u.umonnum].mlevel);
2447 Sprintf(buf, "%d", u.uac);
2449 enl_msg("Your armor class ", "is ", "was ", buf, "");
2451 enl_msg("
\82 \82È
\82½
\82Ì
\96h
\8cä
\92l
\82Í", "
\82Å
\82 \82é", "
\82Å
\82 \82Á
\82½", buf, "");
2453 /* gold; similar to doprgold(#seegold) but without shop billing info;
2454 same amount as shown on status line which ignores container contents */
2457 static const char Your_wallet[] = "Your wallet ";
2459 static const char Your_wallet[] = "
\82 \82È
\82½
\82Ì
\8dà
\95z";
2460 long umoney = money_cnt(invent);
2464 enl_msg(Your_wallet, "is ", "was ", "empty", "");
2466 enl_msg(Your_wallet, "
\82Å
\82 \82é", "
\82Å
\82¾
\82Á
\82½", "
\82Í
\8bó", "");
2469 Sprintf(buf, "%ld %s", umoney, currency(umoney));
2470 enl_msg(Your_wallet, "contains ", "contained ", buf, "");
2472 Sprintf(buf, "
\82É
\82Í%ld%s", umoney, currency(umoney));
2473 enl_msg(Your_wallet, "
\93ü
\82Á
\82Ä
\82¢
\82é", "
\93ü
\82Á
\82Ä
\82¢
\82½", buf, "");
2479 char ocl[MAXOCLASSES + 1];
2481 #if 0 /*JP*//*
\8cã
\82É
\89ñ
\82·*/
2484 oc_to_str(flags.pickup_types, ocl);
2486 Sprintf(eos(buf), " for %s%s%s",
2487 *ocl ? "'" : "", *ocl ? ocl : "all types", *ocl ? "'" : "");
2489 Sprintf(buf, "%s%s%s",
2490 *ocl ? "'" : "", *ocl ? ocl : "
\91S
\82Ä
\82Ì
\8eí
\97Þ", *ocl ? "'" : "");
2492 if (flags.pickup_thrown && *ocl) /* *ocl: don't show if 'all types' */
2494 Strcat(buf, " plus thrown");
2496 Strcat(buf, "
\82É
\89Á
\82¦
\82Ä
\93\8a\82°
\82é
\82à
\82Ì");
2497 if (iflags.autopickup_exceptions[AP_GRAB]
2498 || iflags.autopickup_exceptions[AP_LEAVE])
2500 Strcat(buf, ", with exceptions");
2502 Strcat(buf, "(
\97á
\8aO
\82 \82è)");
2504 Strcpy(buf, "
\82É
\91Î
\82µ
\82Ä
\83I
\83\93");
2511 Strcpy(buf, "
\83I
\83t");
2513 enl_msg("Autopickup ", "is ", "was ", buf, "");
2515 enl_msg("
\8e©
\93®
\8fE
\82¢
\90Ý
\92è
\82Í", "
\82Å
\82 \82é", "
\82Å
\82 \82Á
\82½", buf, "");
2518 /* characteristics: expanded version of bottom line strength, dexterity, &c */
2520 characteristics_enlightenment(mode, final)
2528 Sprintf(buf, "%s Characteristics:", !final ? "Current" : "Final");
2530 Sprintf(buf, "%s
\91®
\90«
\81F", !final ? "
\8c»
\8dÝ
\82Ì" : "
\8dÅ
\8fI");
2533 /* bottom line order */
2534 one_characteristic(mode, final, A_STR); /* strength */
2535 one_characteristic(mode, final, A_DEX); /* dexterity */
2536 one_characteristic(mode, final, A_CON); /* constitution */
2537 one_characteristic(mode, final, A_INT); /* intelligence */
2538 one_characteristic(mode, final, A_WIS); /* wisdom */
2539 one_characteristic(mode, final, A_CHA); /* charisma */
2542 /* display one attribute value for characteristics_enlightenment() */
2544 one_characteristic(mode, final, attrindx)
2545 int mode, final, attrindx;
2547 extern const char *const attrname[]; /* attrib.c */
2548 boolean hide_innate_value = FALSE, interesting_alimit;
2549 int acurrent, abase, apeak, alimit;
2550 const char *paren_pfx;
2551 char subjbuf[BUFSZ], valubuf[BUFSZ], valstring[32];
2553 /* being polymorphed or wearing certain cursed items prevents
2554 hero from reliably tracking changes to characteristics so
2555 we don't show base & peak values then; when the items aren't
2556 cursed, hero could take them off to check underlying values
2557 and we show those in such case so that player doesn't need
2558 to actually resort to doing that */
2560 hide_innate_value = TRUE;
2561 } else if (Fixed_abil) {
2562 if (stuck_ring(uleft, RIN_SUSTAIN_ABILITY)
2563 || stuck_ring(uright, RIN_SUSTAIN_ABILITY))
2564 hide_innate_value = TRUE;
2568 if (uarmg && uarmg->otyp == GAUNTLETS_OF_POWER && uarmg->cursed)
2569 hide_innate_value = TRUE;
2574 if (uwep && uwep->oartifact == ART_OGRESMASHER && uwep->cursed)
2575 hide_innate_value = TRUE;
2578 if (uarmh && uarmh->otyp == DUNCE_CAP && uarmh->cursed)
2579 hide_innate_value = TRUE;
2582 if (uarmh && uarmh->otyp == DUNCE_CAP && uarmh->cursed)
2583 hide_innate_value = TRUE;
2588 return; /* impossible */
2590 /* note: final disclosure includes MAGICENLIGHTENTMENT */
2591 if ((mode & MAGICENLIGHTENMENT) && !Upolyd)
2592 hide_innate_value = FALSE;
2594 acurrent = ACURR(attrindx);
2595 (void) attrval(attrindx, acurrent, valubuf); /* Sprintf(valubuf,"%d",) */
2597 Sprintf(subjbuf, "Your %s ", attrname[attrindx]);
2599 Sprintf(subjbuf, "
\82 \82È
\82½
\82Ì%s
\82Í", attrname[attrindx]);
2601 if (!hide_innate_value) {
2602 /* show abase, amax, and/or attrmax if acurr doesn't match abase
2603 (a magic bonus or penalty is in effect) or abase doesn't match
2604 amax (some points have been lost to poison or exercise abuse
2605 and are restorable) or attrmax is different from normal human
2606 (while game is in progress; trying to reduce dependency on
2607 spoilers to keep track of such stuff) or attrmax was different
2608 from abase (at end of game; this attribute wasn't maxed out) */
2609 abase = ABASE(attrindx);
2610 apeak = AMAX(attrindx);
2611 alimit = ATTRMAX(attrindx);
2612 /* criterium for whether the limit is interesting varies */
2613 interesting_alimit =
2614 final ? TRUE /* was originally `(abase != alimit)' */
2615 : (alimit != (attrindx != A_STR ? 18 : STR18(100)));
2617 paren_pfx = final ? " (" : " (current; ";
2619 paren_pfx = final ? " (" : " (
\8c»
\8dÝ; ";
2620 if (acurrent != abase) {
2622 Sprintf(eos(valubuf), "%sbase:%s", paren_pfx,
2623 attrval(attrindx, abase, valstring));
2625 Sprintf(eos(valubuf), "%s
\8aî
\96{:%s", paren_pfx,
2626 attrval(attrindx, abase, valstring));
2630 if (abase != apeak) {
2632 Sprintf(eos(valubuf), "%speak:%s", paren_pfx,
2633 attrval(attrindx, apeak, valstring));
2635 Sprintf(eos(valubuf), "%s
\8dÅ
\91å:%s", paren_pfx,
2636 attrval(attrindx, apeak, valstring));
2640 if (interesting_alimit) {
2642 Sprintf(eos(valubuf), "%s%slimit:%s", paren_pfx,
2643 /* more verbose if exceeding 'limit' due to magic bonus */
2644 (acurrent > alimit) ? "innate " : "",
2645 attrval(attrindx, alimit, valstring));
2647 Sprintf(eos(valubuf), "%s%s
\8fã
\8cÀ:%s", paren_pfx,
2648 /* more verbose if exceeding 'limit' due to magic bonus */
2649 (acurrent > alimit) ? "
\96{
\97\88\82Ì" : "",
2650 attrval(attrindx, alimit, valstring));
2652 /* paren_pfx = ", "; */
2654 if (acurrent != abase || abase != apeak || interesting_alimit)
2655 Strcat(valubuf, ")");
2658 enl_msg(subjbuf, "is ", "was ", valubuf, "");
2660 enl_msg(subjbuf, "
\82¾", "
\82¾
\82Á
\82½", valubuf, "");
2663 /* status: selected obvious capabilities, assorted troubles */
2665 status_enlightenment(mode, final)
2669 boolean magic = (mode & MAGICENLIGHTENMENT) ? TRUE : FALSE;
2671 char buf[BUFSZ], youtoo[BUFSZ];
2672 boolean Riding = (u.usteed
2673 /* if hero dies while dismounting, u.usteed will still
2674 be set; we want to ignore steed in that situation */
2675 && !(final == ENL_GAMEOVERDEAD
2677 && !strcmp(killer.name, "riding accident")));
2679 && !strcmp(killer.name, "
\8bR
\8fæ
\8e\96\8cÌ
\82Å")));
2680 const char *steedname = (!Riding ? (char *) 0
2681 : x_monnam(u.usteed,
2682 u.usteed->mtame ? ARTICLE_YOUR : ARTICLE_THE,
2684 (SUPPRESS_SADDLE | SUPPRESS_HALLUCINATION),
2688 * Status (many are abbreviated on bottom line; others are or
2689 * should be discernible to the hero hence to the player)
2691 enlght_out(""); /* separator after title or characteristics */
2693 enlght_out(final ? "Final Status:" : "Current Status:");
2695 enlght_out(final ? "
\8dÅ
\8fI
\8fó
\91Ô:" : "
\8c»
\8dÝ
\82Ì
\8fó
\91Ô:");
2697 Strcpy(youtoo, You_);
2698 /* not a traditional status but inherently obvious to player; more
2699 detail given below (attributes section) for magic enlightenment */
2702 Strcpy(buf, "transformed");
2704 Sprintf(eos(buf), " and %s %s inside",
2705 final ? "felt" : "feel", udeadinside());
2707 #else /*JP:TODO:
\95Ï
\89»+
\8bs
\8eE
\83p
\83^
\81[
\83\93*/
2708 you_are_ing("
\95Ï
\89»
\82µ
\82Ä", "");
2711 /* not a trouble, but we want to display riding status before maybe
2712 reporting steed as trapped or hero stuck to cursed saddle */
2715 Sprintf(buf, "riding %s", steedname);
2718 Sprintf(buf, "%s
\82É
\8fæ
\82Á
\82Ä", steedname);
2719 you_are_ing(buf, "");
2722 Sprintf(eos(youtoo), "and %s ", steedname);
2724 Sprintf(youtoo, "
\82 \82È
\82½
\82Æ%s
\82Í", steedname);
2726 /* other movement situations that hero should always know */
2728 if (Lev_at_will && magic)
2730 you_are("levitating, at will", "");
2732 you_are_ing("
\8e©
\95ª
\82Ì
\88Ó
\8eu
\82Å
\95\82\97V
\82µ
\82Ä", "");
2735 enl_msg(youtoo, are, were, "levitating", from_what(LEVITATION));
2737 enl_msg(youtoo, "
\82¢
\82é", "
\82¢
\82½", "
\95\82\97V
\82µ
\82Ä", from_what(LEVITATION));
2738 } else if (Flying) { /* can only fly when not levitating */
2740 enl_msg(youtoo, are, were, "flying", from_what(FLYING));
2742 enl_msg(youtoo, "
\82¢
\82é", "
\82¢
\82½", "
\94ò
\82ñ
\82Å", from_what(FLYING));
2746 you_are("underwater", "");
2748 enl_msg(You_, "
\82¢
\82é", "
\82¢
\82½", "
\90\85\96Ê
\89º
\82É", "");
2749 } else if (u.uinwater) {
2751 you_are(Swimming ? "swimming" : "in water", from_what(SWIMMING));
2753 enl_msg(You_, Swimming ? "
\89j
\82¢
\82Å" : "
\90\85\92\86\82É", "
\82¢
\82é", "
\82¢
\82½", from_what(SWIMMING));
2754 } else if (walking_on_water()) {
2755 /* show active Wwalking here, potential Wwalking elsewhere */
2757 Sprintf(buf, "walking on %s",
2758 is_pool(u.ux, u.uy) ? "water"
2759 : is_lava(u.ux, u.uy) ? "lava"
2760 : surface(u.ux, u.uy)); /* catchall; shouldn't happen */
2761 you_are(buf, from_what(WWALKING));
2763 Sprintf(buf, "%s
\82Ì
\8fã
\82ð
\95à
\82¢
\82Ä",
2764 is_pool(u.ux, u.uy) ? "
\90\85"
2765 : is_lava(u.ux, u.uy) ? "
\97n
\8aâ"
2766 : surface(u.ux, u.uy)); /* catchall; shouldn't happen */
2767 you_are_ing(buf, from_what(WWALKING));
2770 if (Upolyd && (u.uundetected || U_AP_TYPE != M_AP_NOTHING))
2771 youhiding(TRUE, final);
2773 /* internal troubles, mostly in the order that prayer ranks them */
2776 you_are("turning to stone", "");
2778 enl_msg("
\82 \82È
\82½
\82Í", "
\82È
\82è
\82Â
\82Â
\82 \82é", "
\82È
\82Á
\82½", "
\90Î
\82É", "");
2781 you_are("turning into slime", "");
2783 enl_msg("
\82 \82È
\82½
\82Í", "
\82È
\82è
\82Â
\82Â
\82 \82é", "
\82È
\82Á
\82½", "
\83X
\83\89\83C
\83\80\82É", "");
2787 you_are("buried", "");
2789 you_are_ing("
\92\82\91§
\82µ
\82Ä", "");
2792 Strcpy(buf, "being strangled");
2794 Strcpy(buf, "
\8eñ
\82ð
\8di
\82ß
\82ç
\82ê
\82Ä");
2796 Sprintf(eos(buf), " (%ld)", (Strangled & TIMEOUT));
2798 you_are(buf, from_what(STRANGLED));
2800 enl_msg("
\82 \82È
\82½
\82Í", "
\82¢
\82é", "
\82¢
\82½", buf, from_what(STRANGLED));
2804 /* prayer lumps these together; botl puts Ill before FoodPois */
2805 if (u.usick_type & SICK_NONVOMITABLE)
2807 you_are("terminally sick from illness", "");
2809 enl_msg("
\82 \82È
\82½
\82Í
\95a
\8bC
\82Å
\92v
\96½
\93I
\82É
\8bC
\95ª
\82ª
\88«", "
\82¢", "
\82©
\82Á
\82½", "", "");
2810 if (u.usick_type & SICK_VOMITABLE)
2812 you_are("terminally sick from food poisoning", "");
2814 enl_msg("
\82 \82È
\82½
\82Í
\90H
\92\86\93Å
\82Å
\92v
\96½
\93I
\82É
\8bC
\95ª
\82ª
\88«", "
\82¢", "
\82©
\82Á
\82½", "", "");
2818 you_are("nauseated", "");
2820 enl_msg(You_, "
\93f
\82«
\8bC
\82ª", "
\82 \82é", "
\82 \82Á
\82½", "");
2823 you_are("stunned", "");
2825 you_are("
\82
\82ç
\82
\82ç
\8fó
\91Ô", "");
2828 you_are("confused", "");
2830 you_are("
\8d¬
\97\90\8fó
\91Ô", "");
2833 you_are("hallucinating", "");
2835 you_are("
\8c¶
\8ao
\8fó
\91Ô", "");
2837 /* from_what() (currently wizard-mode only) checks !haseyes()
2838 before u.uroleplay.blind, so we should too */
2840 Sprintf(buf, "%s blind",
2841 !haseyes(youmonst.data) ? "innately"
2842 : u.uroleplay.blind ? "permanently"
2843 /* better phrasing desperately wanted... */
2844 : Blindfolded_only ? "deliberately"
2847 Sprintf(buf, "%s
\96Ó
\96Ú",
2848 !haseyes(youmonst.data) ? "
\90¶
\82Ü
\82ê
\82È
\82ª
\82ç
\82É"
2849 : u.uroleplay.blind ? "
\8dP
\8bv
\93I
\82É"
2850 /* better phrasing desperately wanted... */
2851 : Blindfolded_only ? "
\8cÌ
\88Ó
\82É"
2852 : "
\88ê
\8e\9e\93I
\82É");
2854 if (wizard && (Blinded & TIMEOUT) != 0L
2855 && !u.uroleplay.blind && haseyes(youmonst.data))
2856 Sprintf(eos(buf), " (%ld)", (Blinded & TIMEOUT));
2857 /* !haseyes: avoid "you are innately blind innately" */
2858 you_are(buf, !haseyes(youmonst.data) ? "" : from_what(BLINDED));
2862 you_are("deaf", from_what(DEAF));
2864 you_are("
\8e¨
\82ª
\95·
\82±
\82¦
\82È
\82¢
\8fó
\91Ô", from_what(DEAF));
2866 /* external troubles, more or less */
2870 Sprintf(buf, "chained to %s", ansimpleoname(uball));
2872 Sprintf(buf, "%s
\82É
\82Â
\82È
\82ª
\82ê
\82Ä", ansimpleoname(uball));
2874 impossible("Punished without uball?");
2876 Strcpy(buf, "punished");
2878 Strcpy(buf, "
\94±
\82ð
\8eó
\82¯
\82Ä");
2883 char predicament[BUFSZ];
2885 boolean anchored = (u.utraptype == TT_BURIEDBALL);
2889 Strcpy(predicament, "tethered to something buried");
2891 Strcpy(predicament, "
\89½
\82©
\96\84\82Ü
\82Á
\82Ä
\82¢
\82é
\82à
\82Ì
\82É
\82Â
\82È
\82ª
\82ê
\82Ä");
2892 } else if (u.utraptype == TT_INFLOOR || u.utraptype == TT_LAVA) {
2894 Sprintf(predicament, "stuck in %s", the(surface(u.ux, u.uy)));
2896 Sprintf(predicament, "%s
\82É
\96\84\82Ü
\82Á
\82Ä", surface(u.ux, u.uy));
2899 Strcpy(predicament, "trapped");
2900 if ((t = t_at(u.ux, u.uy)) != 0)
2901 Sprintf(eos(predicament), " in %s",
2902 an(defsyms[trap_to_defsym(t->ttyp)].explanation));
2904 predicament[0] = '\0';
2905 if ((t = t_at(u.ux, u.uy)) != 0)
2906 Sprintf(predicament, "%s
\82É",
2907 defsyms[trap_to_defsym(t->ttyp)].explanation);
2908 Strcat(predicament, "
\82Ð
\82Á
\82©
\82©
\82Á
\82Ä");
2911 if (u.usteed) { /* not `Riding' here */
2913 Sprintf(buf, "%s%s ", anchored ? "you and " : "", steedname);
2915 enl_msg(buf, (anchored ? "are " : "is "),
2916 (anchored ? "were " : "was "), predicament, "");
2918 Sprintf(buf, "%s%s
\82Í", anchored ? "
\82 \82È
\82½
\82Æ" : "", steedname);
2919 enl_msg(buf, "
\82¢
\82é", "
\82¢
\82½" , predicament, "");
2922 you_are(predicament, "");
2926 Sprintf(buf, "swallowed by %s", a_monnam(u.ustuck));
2928 Sprintf(buf, "%s
\82É
\88ù
\82Ý
\8d\9e\82Ü
\82ê
\82Ä", a_monnam(u.ustuck));
2930 Sprintf(eos(buf), " (%u)", u.uswldtim);
2932 } else if (u.ustuck) {
2934 Sprintf(buf, "%s %s",
2935 (Upolyd && sticks(youmonst.data)) ? "holding" : "held by",
2936 a_monnam(u.ustuck));
2939 Sprintf(buf, "%s%s",
2941 (Upolyd && sticks(youmonst.data)) ? "
\82ð
\95ß
\82Ü
\82¦
\82Ä" : "
\82É
\95ß
\82Ü
\82Á
\82Ä");
2942 you_are_ing(buf, "");
2946 struct obj *saddle = which_armor(u.usteed, W_SADDLE);
2948 if (saddle && saddle->cursed) {
2950 Sprintf(buf, "stuck to %s %s", s_suffix(steedname),
2951 simpleonames(saddle));
2954 Sprintf(buf, "%s
\82Ì%s
\82É
\82Â
\82©
\82Ü
\82Á
\82Ä", steedname,
2955 simpleonames(saddle));
2956 you_are_ing(buf, "");
2961 /* when mounted, Wounded_legs applies to steed rather than to
2962 hero; we only report steed's wounded legs in wizard mode */
2963 if (u.usteed) { /* not `Riding' here */
2964 if (wizard && steedname) {
2966 Strcpy(buf, steedname);
2968 enl_msg(buf, " has", " had", " wounded legs", "");
2970 enl_msg(buf, iru, ita, "
\82Í
\8e\88\82ð
\89ö
\89ä
\82µ
\82Ä", "");
2975 Sprintf(buf, "wounded %s", makeplural(body_part(LEG)));
2978 Sprintf(buf, "%s
\82ð
\89ö
\89ä
\82µ
\82Ä", makeplural(body_part(LEG)));
2979 you_are_ing(buf, "");
2985 Sprintf(buf, "slippery %s", makeplural(body_part(FINGER)));
2988 Sprintf(buf, "%s
\82ª
\82Ê
\82é
\82Ê
\82é
\82µ
\82Ä", body_part(FINGER));
2989 enl_msg(buf, iru, ita, "", "");
2993 if (magic || cause_known(FUMBLING))
2995 enl_msg(You_, "fumble", "fumbled", "", from_what(FUMBLING));
2997 you_are_ing("
\95s
\8aí
\97p
\82É
\82È
\82Á
\82Ä", from_what(FUMBLING));
3000 if (magic || cause_known(SLEEPY)) {
3001 Strcpy(buf, from_what(SLEEPY));
3003 Sprintf(eos(buf), " (%ld)", (HSleepy & TIMEOUT));
3005 enl_msg("You ", "fall", "fell", " asleep uncontrollably", buf);
3007 you_are_ing("
\96°
\82Á
\82Ä", buf);
3010 /* hunger/nutrition */
3012 if (magic || cause_known(HUNGER))
3014 enl_msg(You_, "hunger", "hungered", " rapidly",
3017 enl_msg("
\82 \82È
\82½
\82Í
\82·
\82®
\82É
\95 \82ª
\8c¸
\82é
\8fó
\91Ô", "
\82Å
\82 \82é", "
\82¾
\82Á
\82½", "", "");
3020 Strcpy(buf, hu_stat[u.uhs]); /* hunger status; omitted if "normal" */
3021 mungspaces(buf); /* strip trailing spaces */
3024 *buf = lowc(*buf); /* override capitalization */
3025 if (!strcmp(buf, "weak"))
3026 Strcat(buf, " from severe hunger");
3027 else if (!strncmp(buf, "faint", 5)) /* fainting, fainted */
3028 Strcat(buf, " due to starvation");
3031 Strcat(buf, "
\8fó
\91Ô");
3036 if ((cap = near_capacity()) > UNENCUMBERED) {
3038 const char *adj = "?_?"; /* (should always get overridden) */
3040 Strcpy(buf, enc_stat[cap]);
3045 break; /* burdened */
3048 break; /* stressed */
3051 break; /* strained */
3054 break; /* overtaxed */
3056 adj = "not possible";
3059 Sprintf(eos(buf), "; movement %s %s%s", !final ? "is" : "was", adj,
3060 (cap < OVERLOADED) ? " slowed" : "");
3063 Sprintf(buf, "
\89×
\95¨
\82É
\82æ
\82Á
\82Ä%s
\8fó
\91Ô", enc_stat[cap]);
3067 /* last resort entry, guarantees Status section is non-empty
3068 (no longer needed for that purpose since weapon status added;
3069 still useful though) */
3071 you_are("unencumbered", "");
3073 you_are("
\89×
\95¨
\82Í
\8e×
\96\82\82É
\82È
\82ç
\82È
\82¢
\8fó
\91Ô", "");
3076 /* report being weaponless; distinguish whether gloves are worn */
3079 you_are(uarmg ? "empty handed" /* gloves imply hands */
3080 : humanoid(youmonst.data)
3081 /* hands but no weapon and no gloves */
3083 /* alternate phrasing for paws or lack of hands */
3084 : "not wielding anything",
3087 enl_msg(You_, "
\82¢", "
\82©
\82Á
\82½", "
\95\90\8aí
\82ð
\91\95\94õ
\82µ
\82Ä
\82¢
\82È", "");
3089 /* two-weaponing implies hands (can't be polymorphed) and
3090 a weapon or wep-tool (not other odd stuff) in each hand */
3091 } else if (u.twoweap) {
3093 you_are("wielding two weapons at once", "");
3095 you_are("
\93ñ
\93\81\97¬", "");
3096 /* report most weapons by their skill class (so a katana will be
3097 described as a long sword, for instance; mattock and hook are
3098 exceptions), or wielded non-weapon item by its object class */
3100 const char *what = weapon_descr(uwep);
3103 if (!strcmpi(what, "armor") || !strcmpi(what, "food")
3104 || !strcmpi(what, "venom"))
3105 Sprintf(buf, "wielding some %s", what);
3107 Sprintf(buf, "wielding %s",
3108 (uwep->quan == 1L) ? an(what) : makeplural(what));
3111 Sprintf(buf, "%s
\82ð
\91\95\94õ
\82µ
\82Ä", what);
3112 enl_msg(You_, "
\82¢
\82é", "
\82¢
\82½", buf, "");
3116 * Skill with current weapon. Might help players who've never
3117 * noticed #enhance or decided that it was pointless.
3119 * TODO? Maybe merge wielding line and skill line into one sentence.
3121 if ((wtype = uwep_skill_type()) != P_NONE) {
3123 int sklvl = P_SKILL(wtype);
3124 boolean hav = (sklvl != P_UNSKILLED && sklvl != P_SKILLED);
3126 if (sklvl == P_ISRESTRICTED)
3127 Strcpy(sklvlbuf, "no");
3129 (void) lcase(skill_level_name(wtype, sklvlbuf));
3130 /* "you have no/basic/expert/master/grand-master skill with <skill>"
3131 or "you are unskilled/skilled in <skill>" */
3133 Sprintf(buf, "%s %s %s", sklvlbuf,
3134 hav ? "skill with" : "in", skill_name(wtype));
3136 Sprintf(buf, "%s
\82Ì%s
\83X
\83L
\83\8b", skill_name(wtype), sklvlbuf);
3138 if (can_advance(wtype, FALSE))
3139 Sprintf(eos(buf), " and %s that",
3140 !final ? "can enhance" : "could have enhanced");
3146 /* report 'nudity' */
3147 if (!uarm && !uarmu && !uarmc && !uarms && !uarmg && !uarmf && !uarmh) {
3148 if (u.uroleplay.nudist)
3150 enl_msg(You_, "do", "did", " not wear any armor", "");
3152 enl_msg(You_, "
\82¢", "
\82©
\82Á
\82½", "
\89½
\82Ì
\8aZ
\82à
\91\95\94õ
\82µ
\82È", "");
3156 you_are("not wearing any armor", "");
3158 enl_msg(You_, "
\82¢", "
\82©
\82Á
\82½", "
\89½
\82Ì
\8aZ
\82à
\91\95\94õ
\82µ
\82Ä
\82¢
\82È", "");
3163 /* attributes: intrinsics and the like, other non-obvious capabilities */
3165 attributes_enlightenment(unused_mode, final)
3166 int unused_mode UNUSED;
3170 static NEARDATA const char if_surroundings_permitted[] =
3171 " if surroundings permitted";
3181 enlght_out(final ? "Final Attributes:" : "Current Attributes:");
3183 enlght_out(final ? "
\8dÅ
\8fI
\91®
\90«:" : "
\8c»
\8dÝ
\82Ì
\91®
\90«:");
3185 if (u.uevent.uhand_of_elbereth) {
3187 static const char *const hofe_titles[3] = { "the Hand of Elbereth",
3188 "the Envoy of Balance",
3189 "the Glory of Arioch" };
3191 static const char *const hofe_titles[3] = { "
\83G
\83\8b\83x
\83\8c\83X
\82Ì
\8cä
\8eè",
3192 "
\92²
\98a
\82Ì
\8eg
\8eÒ",
3193 "
\83A
\83\8a\83I
\83b
\83`
\82Ì
\96¼
\97_" };
3195 you_are(hofe_titles[u.uevent.uhand_of_elbereth - 1], "");
3199 Sprintf(buf, "%s", piousness(TRUE, "aligned"));
3201 Sprintf(buf, "%s", piousness(TRUE, "
\90M
\8bÂ
\90S"));
3202 if (u.ualign.record >= 0)
3209 Sprintf(buf, " %d", u.ualign.record);
3210 enl_msg("Your alignment ", "is", "was", buf, "");
3212 Sprintf(buf, "
\82 \82È
\82½
\82Ì
\91®
\90«
\92l
\82Í%d", u.ualign.record);
3213 enl_msg(buf, "
\82Å
\82 \82é", "
\82¾
\82Á
\82½", "", "");
3217 /*** Resistances to troubles ***/
3220 you_are("invulnerable", from_what(INVULNERABLE));
3222 you_are("
\95s
\8e\80\90g", from_what(INVULNERABLE));
3225 you_are("magic-protected", from_what(ANTIMAGIC));
3227 you_have("
\96\82\96@
\96h
\8cä
\94\
\97Í", from_what(ANTIMAGIC));
3228 if (Fire_resistance)
3230 you_are("fire resistant", from_what(FIRE_RES));
3232 you_have("
\89Î
\82Ö
\82Ì
\91Ï
\90«", from_what(FIRE_RES));
3233 if (Cold_resistance)
3235 you_are("cold resistant", from_what(COLD_RES));
3237 you_have("
\8a¦
\82³
\82Ö
\82Ì
\91Ï
\90«", from_what(COLD_RES));
3238 if (Sleep_resistance)
3240 you_are("sleep resistant", from_what(SLEEP_RES));
3242 you_have("
\96°
\82è
\82Ö
\82Ì
\91Ï
\90«", from_what(SLEEP_RES));
3243 if (Disint_resistance)
3245 you_are("disintegration-resistant", from_what(DISINT_RES));
3247 you_have("
\95²
\8dÓ
\82Ö
\82Ì
\91Ï
\90«", from_what(DISINT_RES));
3248 if (Shock_resistance)
3250 you_are("shock resistant", from_what(SHOCK_RES));
3252 you_have("
\93d
\8c\82\82Ö
\82Ì
\91Ï
\90«", from_what(SHOCK_RES));
3253 if (Poison_resistance)
3255 you_are("poison resistant", from_what(POISON_RES));
3257 you_have("
\93Å
\82Ö
\82Ì
\91Ï
\90«", from_what(POISON_RES));
3258 if (Acid_resistance)
3260 you_are("acid resistant", from_what(ACID_RES));
3262 you_have("
\8e_
\82Ö
\82Ì
\91Ï
\90«", from_what(ACID_RES));
3263 if (Drain_resistance)
3265 you_are("level-drain resistant", from_what(DRAIN_RES));
3267 you_have("
\83\8c\83x
\83\8b\83_
\83E
\83\93\82Ö
\82Ì
\91Ï
\90«", from_what(DRAIN_RES));
3268 if (Sick_resistance)
3270 you_are("immune to sickness", from_what(SICK_RES));
3272 you_have("
\95a
\8bC
\82É
\91Î
\82·
\82é
\96Æ
\89u", from_what(SICK_RES));
3273 if (Stone_resistance)
3275 you_are("petrification resistant", from_what(STONE_RES));
3277 you_have("
\90Î
\89»
\82Ö
\82Ì
\91Ï
\90«", from_what(STONE_RES));
3278 if (Halluc_resistance)
3280 enl_msg(You_, "resist", "resisted", " hallucinations",
3281 from_what(HALLUC_RES));
3283 you_have("
\8c¶
\8ao
\82Ö
\82Ì
\91Ï
\90«", from_what(HALLUC_RES));
3287 you_can("recognize detrimental food", "");
3289 you_can("
\97L
\8aQ
\82È
\90H
\97¿
\82ð
\8e¯
\95Ê", "");
3291 /*** Vision and senses ***/
3292 if (!Blind && (Blinded || !haseyes(youmonst.data)))
3294 you_can("see", from_what(-BLINDED)); /* Eyes of the Overworld */
3295 #else /*
\81u
\92´
\90¢
\8aE
\82Ì
\96Ú
\82É
\82æ
\82Á
\82Ä
\8c©
\82é
\82±
\82Æ
\82ª
\82Å
\82«
\82é
\81v*/
3296 you_can("
\8c©
\82é
\82±
\82Æ
\82ª", from_what(-BLINDED)); /* Eyes of the Overworld */
3298 if (See_invisible) {
3301 enl_msg(You_, "see", "saw", " invisible", from_what(SEE_INVIS));
3303 enl_msg("
\82 \82È
\82½
\82Í
\93§
\96¾
\82È
\82à
\82Ì
\82ð
\8c©
\82ç
\82ê", "
\82é", "
\82½", "", from_what(SEE_INVIS));
3306 enl_msg(You_, "will see", "would have seen",
3307 " invisible when not blind", from_what(SEE_INVIS));
3309 enl_msg(You_, "
\82é", "
\82½",
3310 "
\96Ó
\96Ú
\82Å
\82È
\82¢
\82Æ
\82«
\82É
\82Í
\93§
\96¾
\82È
\82à
\82Ì
\82ð
\8c©
\82ç
\82ê", from_what(SEE_INVIS));
3315 you_are("telepathic", from_what(TELEPAT));
3317 you_have("
\83e
\83\8c\83p
\83V
\81[", from_what(TELEPAT));
3320 you_are("warned", from_what(WARNING));
3322 you_have("
\8cx
\89ú
\94\
\97Í", from_what(WARNING));
3323 if (Warn_of_mon && context.warntype.obj) {
3325 Sprintf(buf, "aware of the presence of %s",
3326 (context.warntype.obj & M2_ORC) ? "orcs"
3327 : (context.warntype.obj & M2_ELF) ? "elves"
3328 : (context.warntype.obj & M2_DEMON) ? "demons" : something);
3329 you_are(buf, from_what(WARN_OF_MON));
3331 Sprintf(buf, "%s
\82Ì
\91¶
\8dÝ
\82ð
\8a´
\82¶
\82é
\94\
\97Í",
3332 (context.warntype.obj & M2_ORC) ? "
\83I
\81[
\83N"
3333 : (context.warntype.obj & M2_ELF) ? "
\83G
\83\8b\83t"
3334 : (context.warntype.obj & M2_DEMON) ? "
\88«
\96\82" : something);
3338 if (Warn_of_mon && context.warntype.polyd) {
3340 Sprintf(buf, "aware of the presence of %s",
3341 ((context.warntype.polyd & (M2_HUMAN | M2_ELF))
3342 == (M2_HUMAN | M2_ELF))
3343 ? "humans and elves"
3344 : (context.warntype.polyd & M2_HUMAN)
3346 : (context.warntype.polyd & M2_ELF)
3348 : (context.warntype.polyd & M2_ORC)
3350 : (context.warntype.polyd & M2_DEMON)
3352 : "certain monsters");
3355 Sprintf(buf, "%s
\82Ì
\91¶
\8dÝ
\82ð
\8a´
\82¶
\82é
\94\
\97Í",
3356 ((context.warntype.polyd & (M2_HUMAN | M2_ELF))
3357 == (M2_HUMAN | M2_ELF))
3358 ? "
\90l
\8aÔ
\82Æ
\83G
\83\8b\83t"
3359 : (context.warntype.polyd & M2_HUMAN)
3361 : (context.warntype.polyd & M2_ELF)
3363 : (context.warntype.polyd & M2_ORC)
3365 : (context.warntype.polyd & M2_DEMON)
3367 : "
\82 \82é
\8eí
\82Ì
\89ö
\95¨");
3371 if (Warn_of_mon && context.warntype.speciesidx >= LOW_PM) {
3373 Sprintf(buf, "aware of the presence of %s",
3374 makeplural(mons[context.warntype.speciesidx].mname));
3375 you_are(buf, from_what(WARN_OF_MON));
3377 Sprintf(buf, "%s
\82Ì
\91¶
\8dÝ
\82ð
\8a´
\82¶
\82é
\94\
\97Í",
3378 mons[context.warntype.speciesidx].mname);
3379 you_have(buf, from_what(WARN_OF_MON));
3384 you_are("warned of undead", from_what(WARN_UNDEAD));
3386 you_have("
\95s
\8e\80\82Ì
\90¶
\95¨
\82Ö
\82Ì
\8cx
\89ú
\94\
\97Í", from_what(WARN_UNDEAD));
3389 you_have("automatic searching", from_what(SEARCHING));
3391 you_have("
\92T
\8d¸
\94\
\97Í", from_what(SEARCHING));
3394 you_are("clairvoyant", from_what(CLAIRVOYANT));
3396 you_have("
\90ç
\97¢
\8aá
\94\
\97Í", from_what(CLAIRVOYANT));
3397 else if ((HClairvoyant || EClairvoyant) && BClairvoyant) {
3398 Strcpy(buf, from_what(-CLAIRVOYANT));
3400 if (!strncmp(buf, " because of ", 12))
3401 /* overwrite substring; strncpy doesn't add terminator */
3402 (void) strncpy(buf, " if not for ", 12);
3403 enl_msg(You_, "could be", "could have been", " clairvoyant", buf);
3405 /*JP:
\81u
\81c
\82É
\82æ
\82Á
\82Ä
\81v*/
3406 if (!strncmp(buf, "
\82É
\82æ
\82Á
\82Ä", 8))
3407 /*JP:
\81u
\81c
\82ª
\82È
\82¯
\82ê
\82Î
\81v
\82É
\8f\91\82«
\8a·
\82¦
\82é*/
3408 strcpy(eos(buf) - 8, "
\82ª
\82È
\82¯
\82ê
\82Î");
3409 you_have("
\90ç
\97¢
\8aá
\94\
\97Í", buf);
3414 you_have("infravision", from_what(INFRAVISION));
3416 you_have("
\90Ô
\8aO
\90ü
\82ª
\8c©
\82¦
\82é
\8e\8b\8ao", from_what(INFRAVISION));
3417 if (Detect_monsters)
3419 you_are("sensing the presence of monsters", "");
3421 you_have("
\89ö
\95¨
\82ð
\92T
\82·
\94\
\97Í", "");
3424 you_are("going to confuse monsters", "");
3426 you_have("
\89ö
\95¨
\82ð
\8d¬
\97\90\82³
\82¹
\82é
\94\
\97Í", "");
3428 /*** Appearance and behavior ***/
3432 if (uleft && uleft->otyp == RIN_ADORNMENT)
3433 adorn += uleft->spe;
3434 if (uright && uright->otyp == RIN_ADORNMENT)
3435 adorn += uright->spe;
3436 /* the sum might be 0 (+0 ring or two which negate each other);
3437 that yields "you are charismatic" (which isn't pointless
3438 because it potentially impacts seduction attacks) */
3440 Sprintf(buf, "%scharismatic",
3441 (adorn > 0) ? "more " : (adorn < 0) ? "less " : "");
3442 you_are(buf, from_what(ADORNED));
3444 Sprintf(buf, "
\96£
\97Í%s
\82Ä",
3445 (adorn > 0) ? "
\82ª
\91\9d\89Á
\82µ" : (adorn < 0) ? "
\82ª
\8c¸
\8f
\82µ" : "
\93I
\82É
\82È
\82Á");
3446 enl_msg(You_, "
\82Ä
\82¢
\82é", "
\82½", buf, "");
3451 you_are("invisible", from_what(INVIS));
3453 you_are("
\93§
\96¾", from_what(INVIS));
3456 you_are("invisible to others", from_what(INVIS));
3458 you_are("
\91¼
\90l
\82É
\91Î
\82µ
\82Ä
\93§
\96¾", from_what(INVIS));
3459 /* ordinarily "visible" is redundant; this is a special case for
3460 the situation when invisibility would be an expected attribute */
3461 else if ((HInvis || EInvis) && BInvis)
3463 you_are("visible", from_what(-INVIS));
3465 you_are("
\95s
\93§
\96¾", from_what(-INVIS));
3468 you_are("displaced", from_what(DISPLACED));
3470 you_have("
\8c¶
\89e
\94\
\97Í", from_what(DISPLACED));
3473 you_are("stealthy", from_what(STEALTH));
3475 you_have("
\90l
\96Ú
\82ð
\93\90\82Þ
\94\
\97Í", from_what(STEALTH));
3476 if (Aggravate_monster)
3478 enl_msg("You aggravate", "", "d", " monsters",
3479 from_what(AGGRAVATE_MONSTER));
3481 you_are_ing("
\94½
\8a´
\82ð
\82©
\82Á
\82Ä", from_what(AGGRAVATE_MONSTER));
3485 enl_msg("You cause", "", "d", " conflict", from_what(CONFLICT));
3487 you_are_ing("
\93¬
\91\88\82ð
\88ø
\82«
\8bN
\82±
\82µ
\82Ä", from_what(CONFLICT));
3489 /*** Transportation ***/
3492 you_can("jump", from_what(JUMPING));
3494 you_can("
\92µ
\96ô
\82·
\82é
\82±
\82Æ
\82ª", from_what(JUMPING));
3497 you_can("teleport", from_what(TELEPORT));
3499 you_can("
\8fu
\8aÔ
\88Ú
\93®
\82ª", from_what(TELEPORT));
3500 if (Teleport_control)
3502 you_have("teleport control", from_what(TELEPORT_CONTROL));
3504 you_have("
\8fu
\8aÔ
\88Ú
\93®
\82Ì
\90§
\8cä
\94\
\97Í", from_what(TELEPORT_CONTROL));
3505 /* actively levitating handled earlier as a status condition */
3506 if (BLevitation) { /* levitation is blocked */
3507 long save_BLev = BLevitation;
3511 /* either trapped in the floor or inside solid rock
3512 (or both if chained to buried iron ball and have
3513 moved one step into solid rock somehow) */
3515 boolean trapped = (save_BLev & I_SPECIAL) != 0L,
3516 terrain = (save_BLev & FROMOUTSIDE) != 0L;
3518 Sprintf(buf, "%s%s%s",
3519 trapped ? " if not trapped" : "",
3520 (trapped && terrain) ? " and" : "",
3521 terrain ? if_surroundings_permitted : "");
3522 enl_msg(You_, "would levitate", "would have levitated", buf, "");
3524 you_are("
\8fó
\8bµ
\82ª
\8b\96\82¹
\82Î
\95\82\97V
\82·
\82é
\8fó
\91Ô", "");
3527 BLevitation = save_BLev;
3529 /* actively flying handled earlier as a status condition */
3530 if (BFlying) { /* flight is blocked */
3531 long save_BFly = BFlying;
3536 enl_msg(You_, "would fly", "would have flown",
3537 /* wording quibble: for past tense, "hadn't been"
3538 would sound better than "weren't" (and
3539 "had permitted" better than "permitted"), but
3540 "weren't" and "permitted" are adequate so the
3541 extra complexity to handle that isn't worth it */
3543 ? " if you weren't levitating"
3544 : (save_BFly == I_SPECIAL)
3545 /* this is an oversimpliction; being trapped
3546 might also be blocking levitation so flight
3547 would still be blocked after escaping trap */
3548 ? " if you weren't trapped"
3549 : (save_BFly == FROMOUTSIDE)
3550 ? if_surroundings_permitted
3551 /* two or more of levitation, surroundings,
3552 and being trapped in the floor */
3553 : " if circumstances permitted",
3556 enl_msg(You_, "
\94ò
\82Ô
\82±
\82Æ
\82ª
\82Å
\82«
\82é", "
\94ò
\82Ô
\82±
\82Æ
\82ª
\82Å
\82«
\82½",
3557 /* wording quibble: for past tense, "hadn't been"
3558 would sound better than "weren't" (and
3559 "had permitted" better than "permitted"), but
3560 "weren't" and "permitted" are adequate so the
3561 extra complexity to handle that isn't worth it */
3563 ? "
\95\82\97V
\82µ
\82Ä
\82¢
\82È
\82¯
\82ê
\82Î"
3564 : (save_BFly == I_SPECIAL)
3565 /* this is an oversimpliction; being trapped
3566 might also be blocking levitation so flight
3567 would still be blocked after escaping trap */
3568 ? "
\95ß
\82Ü
\82Á
\82Ä
\82¢
\82È
\82¯
\82ê
\82Î"
3569 : (save_BFly == FROMOUTSIDE)
3570 ? "
\8fó
\8bµ
\82ª
\8b\96\82¹
\82Î"
3571 /* two or more of levitation, surroundings,
3572 and being trapped in the floor */
3573 : "
\8e\96\8fî
\82ª
\8b\96\82¹
\82Î",
3577 BFlying = save_BFly;
3579 /* actively walking on water handled earlier as a status condition */
3580 if (Wwalking && !walking_on_water())
3582 you_can("walk on water", from_what(WWALKING));
3584 you_can("
\90\85\82Ì
\8fã
\82ð
\95à
\82
\82±
\82Æ
\82ª", from_what(WWALKING));
3585 /* actively swimming (in water but not under it) handled earlier */
3586 if (Swimming && (Underwater || !u.uinwater))
3588 you_can("swim", from_what(SWIMMING));
3590 you_can("
\89j
\82®
\82±
\82Æ
\82ª", from_what(SWIMMING));
3593 you_can("survive without air", from_what(MAGICAL_BREATHING));
3595 you_can("
\8bó
\8bC
\82È
\82µ
\82Å
\90¶
\82«
\89\84\82Ñ
\82é
\82±
\82Æ
\82ª", from_what(MAGICAL_BREATHING));
3596 else if (Amphibious)
3598 you_can("breathe water", from_what(MAGICAL_BREATHING));
3600 you_can("
\90\85\92\86\82Å
\8cÄ
\8bz
\82ª", from_what(MAGICAL_BREATHING));
3603 you_can("walk through walls", from_what(PASSES_WALLS));
3605 you_can("
\95Ç
\82ð
\92Ê
\82è
\94²
\82¯
\82é
\82±
\82Æ
\82ª", from_what(PASSES_WALLS));
3607 /*** Physical attributes ***/
3610 enl_msg("You regenerate", "", "d", "", from_what(REGENERATION));
3612 you_have("
\8dÄ
\90¶
\94\
\97Í", from_what(REGENERATION));
3615 you_have("slower digestion", from_what(SLOW_DIGESTION));
3617 enl_msg("
\90H
\95¨
\82Ì
\8fÁ
\89»
\82ª
\92x", "
\82¢", "
\82©
\82Á
\82½", "", from_what(SLOW_DIGESTION));
3620 you_have(enlght_combatinc("to hit", u.uhitinc, final, buf), "");
3622 you_have(enlght_combatinc("
\96½
\92\86\97¦", u.uhitinc, final, buf), "");
3625 you_have(enlght_combatinc("damage", u.udaminc, final, buf), "");
3627 you_have(enlght_combatinc("
\83_
\83\81\81[
\83W", u.udaminc, final, buf), "");
3628 if (u.uspellprot || Protection) {
3631 if (uleft && uleft->otyp == RIN_PROTECTION)
3633 if (uright && uright->otyp == RIN_PROTECTION)
3634 prot += uright->spe;
3635 if (HProtection & INTRINSIC)
3637 prot += u.uspellprot;
3640 you_have(enlght_combatinc("defense", prot, final, buf), "");
3642 you_have(enlght_combatinc("
\96h
\8cä", prot, final, buf), "");
3644 if ((armpro = magic_negation(&youmonst)) > 0) {
3645 /* magic cancellation factor, conferred by worn armor */
3646 static const char *const mc_types[] = {
3648 "" /*ordinary*/, "warded", "guarded", "protected",
3650 "" /*ordinary*/, "
\89q
\82ç
\82ê
\82Ä", "
\8cì
\82ç
\82ê
\82Ä", "
\8eç
\82ç
\82ê
\82Ä",
3654 if (armpro >= SIZE(mc_types))
3655 armpro = SIZE(mc_types) - 1;
3657 you_are(mc_types[armpro], "");
3659 you_are_ing(mc_types[armpro], "");
3661 if (Half_physical_damage)
3662 enlght_halfdmg(HALF_PHDAM, final);
3663 if (Half_spell_damage)
3664 enlght_halfdmg(HALF_SPDAM, final);
3665 /* polymorph and other shape change */
3666 if (Protection_from_shape_changers)
3668 you_are("protected from shape changers",
3669 from_what(PROT_FROM_SHAPE_CHANGERS));
3671 you_have("
\95Ï
\89»
\89ö
\95¨
\82Ö
\82Ì
\91Ï
\90«", from_what(PROT_FROM_SHAPE_CHANGERS));
3674 const char *what = 0;
3676 if (!Upolyd) /* Upolyd handled below after current form */
3678 you_can("not change from your current form",
3680 you_are("
\8c»
\8dÝ
\82Ì
\8ep
\82©
\82ç
\95Ï
\89»
\82Å
\82«
\82È
\82¢
\8fó
\91Ô",
3681 from_what(UNCHANGING));
3682 /* blocked shape changes */
3685 what = !final ? "polymorph" : "have polymorphed";
3687 what = "
\95Ï
\89»
\82µ
\82Ä";
3688 else if (u.ulycn >= LOW_PM)
3690 what = !final ? "change shape" : "have changed shape";
3692 what = "
\8ep
\82ð
\95Ï
\82¦
\82Ä";
3695 Sprintf(buf, "would %s periodically", what);
3696 /* omit from_what(UNCHANGING); too verbose */
3697 enl_msg(You_, buf, buf, " if not locked into your current form",
3700 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);
3701 you_are_ing(buf, "");
3704 } else if (Polymorph) {
3706 you_are("polymorphing periodically", from_what(POLYMORPH));
3708 you_are("
\92è
\8aú
\93I
\82É
\95Ï
\89»
\82µ
\82Ä", from_what(POLYMORPH));
3710 if (Polymorph_control)
3712 you_have("polymorph control", from_what(POLYMORPH_CONTROL));
3714 you_have("
\95Ï
\89»
\82Ì
\90§
\8cä
\94\
\97Í", from_what(POLYMORPH_CONTROL));
3715 if (Upolyd && u.umonnum != u.ulycn
3716 /* if we've died from turning into slime, we're polymorphed
3717 right now but don't want to list it as a temporary attribute
3718 [we need a more reliable way to detect this situation] */
3719 && !(final == ENL_GAMEOVERDEAD
3720 && u.umonnum == PM_GREEN_SLIME && !Unchanging)) {
3721 /* foreign shape (except were-form which is handled below) */
3723 Sprintf(buf, "polymorphed into %s", an(youmonst.data->mname));
3725 Sprintf(buf, "%s
\82É
\95Ï
\89»
\82µ
\82Ä", youmonst.data->mname);
3727 Sprintf(eos(buf), " (%d)", u.mtimedone);
3730 if (lays_eggs(youmonst.data) && flags.female) /* Upolyd */
3732 you_can("lay eggs", "");
3734 you_can("
\97\91\82ð
\8eY
\82Þ
\82±
\82Æ
\82ª", "");
3735 if (u.ulycn >= LOW_PM) {
3737 /* "you are a werecreature [in beast form]" */
3738 Strcpy(buf, an(mons[u.ulycn].mname));
3739 if (u.umonnum == u.ulycn) {
3740 Strcat(buf, " in beast form");
3742 Sprintf(eos(buf), " (%d)", u.mtimedone);
3745 /*JP:
\81u
\82 \82È
\82½
\82Í[
\8fb
\82Ì
\8ep
\82Ì]
\81\9b\81\9b\90l
\8aÔ
\82Å
\82 \82é
\81v*/
3747 if (u.umonnum == u.ulycn) {
3748 Strcpy(buf, "
\8fb
\82Ì
\8ep
\82Ì");
3750 Sprintf(eos(buf), " (%d)", u.mtimedone);
3752 Strcat(buf, mons[u.ulycn].mname);
3756 if (Unchanging && Upolyd) /* !Upolyd handled above */
3758 you_can("not change from your current form", from_what(UNCHANGING));
3760 enl_msg("
\8d¡
\82Ì
\8ep
\82©
\82ç
\95Ï
\89»
\82·
\82é
\82±
\82Æ
\82ª
\82Å
\82«
\82È", "
\82¢", "
\82©
\82Á
\82½", "", from_what(UNCHANGING));
3763 you_are("harmed by silver", "");
3765 enl_msg("
\82 \82È
\82½
\82Í
\8bâ
\82É
\8eã", "
\82¢", "
\82©
\82Á
\82½", "", "");
3766 /* movement and non-armor-based protection */
3769 you_are(Very_fast ? "very fast" : "fast", from_what(FAST));
3771 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));
3774 you_have("reflection", from_what(REFLECTING));
3776 you_have("
\94½
\8eË
\94\
\97Í", from_what(REFLECTING));
3779 you_have("free action", from_what(FREE_ACTION));
3781 you_have("
\8dS
\91©
\82³
\82ê
\82È
\82¢
\94\
\97Í", from_what(FREE_ACTION));
3784 you_have("fixed abilities", from_what(FIXED_ABIL));
3786 enl_msg("
\94\
\97Í
\82ª
\95Ï
\89»
\82µ
\82È", "
\82¢", "
\82©
\82Á
\82½", "", from_what(FIXED_ABIL));
3789 enl_msg("Your life ", "will be", "would have been", " saved", "");
3791 enl_msg("
\82 \82È
\82½
\82Ì
\90¶
\96½
\82Í
\95Û
\91¶
\82³
\82ê
\82Ä", iru, ita, "", "");
3793 /*** Miscellany ***/
3795 ltmp = abs((int) Luck);
3797 Sprintf(buf, "%s%slucky",
3798 ltmp >= 10 ? "extremely " : ltmp >= 5 ? "very " : "",
3799 Luck < 0 ? "un" : "");
3801 Sprintf(buf, "%s%s",
3802 ltmp >= 10 ? "
\96Ò
\97ó
\82É" : ltmp >= 5 ? "
\82Æ
\82Ä
\82à" : "",
3803 Luck < 0 ? "
\95s
\8dK" : "
\8dK
\95\9f");
3806 Sprintf(eos(buf), " (%d)", Luck);
3810 enl_msg("Your luck ", "is", "was", " zero", "");
3812 enl_msg("
\82 \82È
\82½
\82Ì
\89^
\82Í
\83[
\83\8d", "
\82Å
\82 \82é", "
\82¾
\82Á
\82½", "", "");
3815 you_have("extra luck", "");
3817 you_have("
\82³
\82ç
\82È
\82é
\8dK
\89^", "");
3818 else if (u.moreluck < 0)
3820 you_have("reduced luck", "");
3822 you_have("
\82³
\82ç
\82È
\82é
\95s
\89^", "");
3823 if (carrying(LUCKSTONE) || stone_luck(TRUE)) {
3824 ltmp = stone_luck(FALSE);
3827 enl_msg("Bad luck ", "does", "did", " not time out for you", "");
3829 enl_msg("
\95s
\89^
\82Í
\8e\9e\8aÔ
\90Ø
\82ê
\82É
\82È
\82ç
\82È", "
\82¢", "
\82©
\82Á
\82½", "", "");
3832 enl_msg("Good luck ", "does", "did", " not time out for you", "");
3834 enl_msg("
\8dK
\89^
\82Í
\8e\9e\8aÔ
\90Ø
\82ê
\82É
\82È
\82ç
\82È", "
\82¢", "
\82©
\82Á
\82½", "", "");
3839 Sprintf(buf, " %sangry with you",
3840 u.ugangr > 6 ? "extremely " : u.ugangr > 3 ? "very " : "");
3842 Sprintf(buf, "%s
\82Í%s
\93{
\82Á
\82Ä%s", u_gname(),
3843 u.ugangr > 6 ? "
\96Ò
\97ó
\82É" : u.ugangr > 3 ? "
\82Æ
\82Ä
\82à" : "", final ? ita : iru);
3846 Sprintf(eos(buf), " (%d)", u.ugangr);
3848 enl_msg(u_gname(), " is", " was", buf, "");
3850 enl_msg(buf, "", "", "", "");
3854 * We need to suppress this when the game is over, because death
3855 * can change the value calculated by can_pray(), potentially
3856 * resulting in a false claim that you could have prayed safely.
3861 /* "can [not] safely pray" vs "could [not] have safely prayed" */
3862 Sprintf(buf, "%s%ssafely pray%s", can_pray(FALSE) ? "" : "not ",
3863 final ? "have " : "", final ? "ed" : "");
3865 Sprintf(buf, "%ssafely pray", can_pray(FALSE) ? "" : "not ");
3868 Sprintf(eos(buf), " (%d)", u.ublesscnt);
3871 Sprintf(buf, "
\82 \82È
\82½
\82Í
\88À
\91S
\82É
\8bF
\82é
\82±
\82Æ
\82ª");
3872 Strcat(buf, can_pray(FALSE) ? can : "
\82Å
\82«
\82È
\82¢");
3874 Sprintf(eos(buf), " (%d)", u.ublesscnt);
3875 enl_msg(buf, "", "", "", "");
3881 /* named fruit debugging (doesn't really belong here...); to enable,
3882 include 'fruit' in DEBUGFILES list (even though it isn't a file...) */
3883 if (wizard && explicitdebug("fruit")) {
3886 reorder_fruit(TRUE); /* sort by fruit index, from low to high;
3887 * this modifies the ffruit chain, so could
3888 * possibly mask or even introduce a problem,
3889 * but it does useful sanity checking */
3890 for (f = ffruit; f; f = f->nextf) {
3892 Sprintf(buf, "Fruit #%d ", f->fid);
3894 Sprintf(buf, "fruit $%d
\82Í", f->fid);
3896 enl_msg(buf, "is ", "was ", f->fname, "");
3898 enl_msg(buf, "
\82¾", "
\82¾
\82Á
\82½", f->fname, "");
3901 enl_msg("The current fruit ", "is ", "was ", pl_fruit, "");
3903 enl_msg("
\8c»
\8dÝ
\82Ì fruit
\82Í", "
\82¾", "
\82¾
\82Á
\82½", pl_fruit, "");
3904 Sprintf(buf, "%d", flags.made_fruit);
3906 enl_msg("The made fruit flag ", "is ", "was ", buf, "");
3908 enl_msg("made fruit flag
\82Í", "
\82¾", "
\82¾
\82Á
\82½", buf, "");
3916 if (final < 2) { /* still in progress, or quit/escaped/ascended */
3918 p = "survived after being killed ";
3920 p = "
\8e\80\82ñ
\82¾
\8cã
\95\9c\8a\88\82µ
\82Ä
\82¢
\82½";
3921 switch (u.umortality) {
3924 p = !final ? (char *) 0 : "survived";
3926 p = !final ? (char *)0 : "
\90¶
\82«
\89\84\82Ñ
\82½";
3930 Strcpy(buf, "once");
3932 Strcpy(buf, "
\88ê
\93x");
3936 Strcpy(buf, "twice");
3938 Strcpy(buf, "
\93ñ
\93x");
3942 Strcpy(buf, "thrice");
3944 Strcpy(buf, "
\8eO
\93x");
3948 Sprintf(buf, "%d times", u.umortality);
3950 Sprintf(buf, "%d
\89ñ", u.umortality);
3953 } else { /* game ended in character's death */
3957 p = "
\8e\80\82ñ
\82Å
\82¢
\82é";
3958 switch (u.umortality) {
3960 impossible("dead without dying?");
3962 break; /* just "are dead" */
3965 Sprintf(buf, " (%d%s time!)", u.umortality,
3966 ordin(u.umortality));
3968 Sprintf(buf, "(%d
\89ñ
\81I)", u.umortality);
3975 enl_msg(You_, "have been killed ", p, buf, "");
3977 enl_msg(You_, "
\8e\80\82ñ
\82Å
\82¢
\82é", p, buf, "");
3981 #if 0 /* no longer used */
3982 STATIC_DCL boolean NDECL(minimal_enlightenment);
3985 * Courtesy function for non-debug, non-explorer mode players
3986 * to help refresh them about who/what they are.
3987 * Returns FALSE if menu cancelled (dismissed with ESC), TRUE otherwise.
3990 minimal_enlightenment()
3993 menu_item *selected;
3996 char buf[BUFSZ], buf2[BUFSZ];
3997 static const char untabbed_fmtstr[] = "%-15s: %-12s";
3998 static const char untabbed_deity_fmtstr[] = "%-17s%s";
3999 static const char tabbed_fmtstr[] = "%s:\t%-12s";
4000 static const char tabbed_deity_fmtstr[] = "%s\t%s";
4001 static const char *fmtstr;
4002 static const char *deity_fmtstr;
4004 fmtstr = iflags.menu_tab_sep ? tabbed_fmtstr : untabbed_fmtstr;
4005 deity_fmtstr = iflags.menu_tab_sep ? tabbed_deity_fmtstr
4006 : untabbed_deity_fmtstr;
4008 buf[0] = buf2[0] = '\0';
4009 tmpwin = create_nhwindow(NHW_MENU);
4011 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
4017 /* Starting name, race, role, gender */
4019 Sprintf(buf, fmtstr, "name", plname);
4021 Sprintf(buf, fmtstr, "
\96¼
\91O", plname);
4022 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4024 Sprintf(buf, fmtstr, "race", urace.noun);
4026 Sprintf(buf, fmtstr, "
\8eí
\91°", urace.noun);
4027 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4029 Sprintf(buf, fmtstr, "role",
4031 Sprintf(buf, fmtstr, "
\90E
\8bÆ",
4032 (flags.initgend && urole.name.f) ? urole.name.f : urole.name.m);
4033 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4035 Sprintf(buf, fmtstr, "gender", genders[flags.initgend].adj);
4037 Sprintf(buf, fmtstr, "
\90«
\95Ê", genders[flags.initgend].adj);
4038 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4040 /* Starting alignment */
4042 Sprintf(buf, fmtstr, "alignment", align_str(u.ualignbase[A_ORIGINAL]));
4044 Sprintf(buf, fmtstr, "
\91®
\90«", align_str(u.ualignbase[A_ORIGINAL]));
4045 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4047 /* Current name, race, role, gender */
4048 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, "", FALSE);
4049 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
4055 Sprintf(buf, fmtstr, "race", Upolyd ? youmonst.data->mname : urace.noun);
4057 Sprintf(buf, fmtstr, "
\8eí
\91°", Upolyd ? youmonst.data->mname : urace.noun);
4058 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4061 Sprintf(buf, fmtstr, "role (base)",
4063 Sprintf(buf, fmtstr, "
\90E
\8bÆ(
\8aî
\96{)",
4064 (u.mfemale && urole.name.f) ? urole.name.f
4066 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4069 Sprintf(buf, fmtstr, "role",
4071 Sprintf(buf, fmtstr, "
\90E
\8bÆ",
4072 (flags.female && urole.name.f) ? urole.name.f
4074 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4076 /* don't want poly_gender() here; it forces `2' for non-humanoids */
4077 genidx = is_neuter(youmonst.data) ? 2 : flags.female;
4079 Sprintf(buf, fmtstr, "gender", genders[genidx].adj);
4081 Sprintf(buf, fmtstr, "
\90«
\95Ê", genders[genidx].adj);
4082 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4083 if (Upolyd && (int) u.mfemale != genidx) {
4085 Sprintf(buf, fmtstr, "gender (base)", genders[u.mfemale].adj);
4087 Sprintf(buf, fmtstr, "
\90«
\95Ê(
\8aî
\96{)", genders[u.mfemale].adj);
4088 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4091 /* Current alignment */
4093 Sprintf(buf, fmtstr, "alignment", align_str(u.ualign.type));
4095 Sprintf(buf, fmtstr, "
\91®
\90«", align_str(u.ualign.type));
4096 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4099 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, "", FALSE);
4100 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
4106 Sprintf(buf2, deity_fmtstr, align_gname(A_CHAOTIC),
4107 (u.ualignbase[A_ORIGINAL] == u.ualign.type
4108 && u.ualign.type == A_CHAOTIC) ? " (s,c)"
4109 : (u.ualignbase[A_ORIGINAL] == A_CHAOTIC) ? " (s)"
4110 : (u.ualign.type == A_CHAOTIC) ? " (c)" : "");
4112 Sprintf(buf2, deity_fmtstr, align_gname(A_CHAOTIC),
4113 (u.ualignbase[A_ORIGINAL] == u.ualign.type
4114 && u.ualign.type == A_CHAOTIC) ? " (
\8f\89\81C
\8c»)"
4115 : (u.ualignbase[A_ORIGINAL] == A_CHAOTIC) ? " (
\8f\89)"
4116 : (u.ualign.type == A_CHAOTIC) ? " (
\8c»)" : "");
4119 Sprintf(buf, fmtstr, "Chaotic", buf2);
4121 Sprintf(buf, fmtstr, "
\8d¬
\93×", buf2);
4122 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4125 Sprintf(buf2, deity_fmtstr, align_gname(A_NEUTRAL),
4126 (u.ualignbase[A_ORIGINAL] == u.ualign.type
4127 && u.ualign.type == A_NEUTRAL) ? " (s,c)"
4128 : (u.ualignbase[A_ORIGINAL] == A_NEUTRAL) ? " (s)"
4129 : (u.ualign.type == A_NEUTRAL) ? " (c)" : "");
4131 Sprintf(buf2, deity_fmtstr, align_gname(A_NEUTRAL),
4132 (u.ualignbase[A_ORIGINAL] == u.ualign.type
4133 && u.ualign.type == A_NEUTRAL) ? " (
\8f\89\81C
\8c»)"
4134 : (u.ualignbase[A_ORIGINAL] == A_NEUTRAL) ? " (
\8f\89)"
4135 : (u.ualign.type == A_NEUTRAL) ? " (
\8c»)" : "");
4138 Sprintf(buf, fmtstr, "Neutral", buf2);
4140 Sprintf(buf, fmtstr, "
\92\86\97§", buf2);
4141 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4144 Sprintf(buf2, deity_fmtstr, align_gname(A_LAWFUL),
4145 (u.ualignbase[A_ORIGINAL] == u.ualign.type
4146 && u.ualign.type == A_LAWFUL) ? " (s,c)"
4147 : (u.ualignbase[A_ORIGINAL] == A_LAWFUL) ? " (s)"
4148 : (u.ualign.type == A_LAWFUL) ? " (c)" : "");
4150 Sprintf(buf2, deity_fmtstr, align_gname(A_LAWFUL),
4151 (u.ualignbase[A_ORIGINAL] == u.ualign.type
4152 && u.ualign.type == A_LAWFUL) ? " (
\8f\89\81C
\8c»)"
4153 : (u.ualignbase[A_ORIGINAL] == A_LAWFUL) ? " (
\8f\89)"
4154 : (u.ualign.type == A_LAWFUL) ? " (
\8c»)" : "");
4157 Sprintf(buf, fmtstr, "Lawful", buf2);
4159 Sprintf(buf, fmtstr, "
\92\81\8f\98", buf2);
4160 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4163 end_menu(tmpwin, "Base Attributes");
4165 end_menu(tmpwin, "
\8aî
\96{
\91®
\90«");
4166 n = select_menu(tmpwin, PICK_NONE, &selected);
4167 destroy_nhwindow(tmpwin);
4168 return (boolean) (n != -1);
4174 doattributes(VOID_ARGS)
4176 int mode = BASICENLIGHTENMENT;
4178 /* show more--as if final disclosure--for wizard and explore modes */
4179 if (wizard || discover)
4180 mode |= MAGICENLIGHTENMENT;
4182 enlightenment(mode, ENL_GAMEINPROGRESS);
4187 youhiding(via_enlghtmt, msgflag)
4188 boolean via_enlghtmt; /* englightment line vs topl message */
4189 int msgflag; /* for variant message phrasing */
4191 char *bp, buf[BUFSZ];
4194 Strcpy(buf, "hiding");
4196 Strcpy(buf, "
\89B
\82ê");
4197 if (U_AP_TYPE != M_AP_NOTHING) {
4198 /* mimic; hero is only able to mimic a strange object or gold
4199 or hallucinatory alternative to gold, so we skip the details
4200 for the hypothetical furniture and monster cases */
4201 #if 0 /*JP*//*
\8cã
\82ë
\82É
\89ñ
\82·*//* not used */
4202 bp = eos(strcpy(buf, "mimicking"));
4204 if (U_AP_TYPE == M_AP_OBJECT) {
4206 Sprintf(bp, " %s", an(simple_typename(youmonst.mappearance)));
4208 Strcpy(buf, simple_typename(youmonst.mappearance));
4209 } else if (U_AP_TYPE == M_AP_FURNITURE) {
4211 Strcpy(bp, " something");
4213 Strcpy(buf, "
\89½
\82©");
4214 } else if (U_AP_TYPE == M_AP_MONSTER) {
4216 Strcpy(bp, " someone");
4218 Strcpy(buf, "
\89½
\8eÒ
\82©");
4220 ; /* something unexpected; leave 'buf' as-is */
4222 #if 1 /*JP*//*
\82±
\82±
\82Å
\92Ç
\89Á*/
4223 Strcat(buf, "
\82Ì
\82Ó
\82è
\82ð
\82µ");
4225 } else if (u.uundetected) {
4226 bp = eos(buf); /* points past "hiding" */
4227 if (youmonst.data->mlet == S_EEL) {
4228 if (is_pool(u.ux, u.uy))
4230 Sprintf(bp, " in the %s", waterbody_name(u.ux, u.uy));
4232 Sprintf(bp, "%s
\82Ì
\92\86\82É", waterbody_name(u.ux, u.uy));
4233 } else if (hides_under(youmonst.data)) {
4234 struct obj *o = level.objects[u.ux][u.uy];
4238 Sprintf(bp, " underneath %s", ansimpleoname(o));
4240 Sprintf(bp, "%s
\82Ì
\89º
\82É", ansimpleoname(o));
4241 } else if (is_clinger(youmonst.data) || Flying) {
4242 /* Flying: 'lurker above' hides on ceiling but doesn't cling */
4244 Sprintf(bp, " on the %s", ceiling(u.ux, u.uy));
4246 Sprintf(bp, "%s
\82É", ceiling(u.ux, u.uy));
4248 /* on floor; is_hider() but otherwise not special: 'trapper' */
4249 if (u.utrap && u.utraptype == TT_PIT) {
4250 struct trap *t = t_at(u.ux, u.uy);
4253 Sprintf(bp, " in a %spit",
4254 (t && t->ttyp == SPIKED_PIT) ? "spiked " : "");
4256 Sprintf(bp, "%s
\97\8e\82µ
\8c\8a\82Ì
\92\86\82É",
4257 (t && t->ttyp == SPIKED_PIT) ? "
\83g
\83Q
\82¾
\82ç
\82¯
\82Ì" : "");
4261 Sprintf(bp, " on the %s", surface(u.ux, u.uy));
4263 Sprintf(bp, "%s
\82É", surface(u.ux, u.uy));
4265 #if 1 /*JP*//*
\82±
\82±
\82Å
\92Ç
\89Á*/
4266 Strcat(buf, "
\89B
\82ê");
4269 ; /* shouldn't happen; will result in generic "you are hiding" */
4273 int final = msgflag; /* 'final' is used by you_are() macro */
4277 /* for dohide(), when player uses '#monster' command */
4279 You("are %s %s.", msgflag ? "already" : "now", buf);
4282 You("
\82·
\82Å
\82É%s
\82Ä
\82¢
\82é
\81D", buf);
4284 You("%s
\82½
\81D", buf);
4291 * (shares enlightenment's tense handling)
4294 doconduct(VOID_ARGS)
4307 /* Create the conduct window */
4308 en_win = create_nhwindow(NHW_MENU);
4310 putstr(en_win, 0, "Voluntary challenges:");
4312 putstr(en_win, 0, "
\8e©
\94
\93I
\92§
\90í:");
4314 if (u.uroleplay.blind)
4316 you_have_been("blind from birth");
4318 you_have_been("
\90¶
\82Ü
\82ê
\82È
\82ª
\82ç
\82É
\96Ó
\96Ú");
4319 if (u.uroleplay.nudist)
4321 you_have_been("faithfully nudist");
4323 you_have_been("
\92\89\8eÀ
\82È
\97\87\91°");
4325 if (!u.uconduct.food)
4327 enl_msg(You_, "have gone", "went", " without food", "");
4329 enl_msg("
\82 \82È
\82½
\82Í
\90H
\8e\96\82ð
\82µ", "
\82Ä
\82¢
\82È
\82¢", "
\82È
\82©
\82Á
\82½", "", "");
4330 /* but beverages are okay */
4331 else if (!u.uconduct.unvegan)
4333 you_have_X("followed a strict vegan diet");
4335 you_have_been("
\8cµ
\8ai
\82È
\8dØ
\90H
\8eå
\8b`
\8eÒ");
4336 else if (!u.uconduct.unvegetarian)
4338 you_have_been("vegetarian");
4340 you_have_been("
\8dØ
\90H
\8eå
\8b`
\8eÒ");
4342 if (!u.uconduct.gnostic)
4344 you_have_been("an atheist");
4346 you_have_been("
\96³
\90_
\98_
\8eÒ");
4348 if (!u.uconduct.weaphit) {
4350 you_have_never("hit with a wielded weapon");
4352 you_have_never("
\82 \82È
\82½
\82Í
\91\95\94õ
\82µ
\82Ä
\82¢
\82é
\95\90\8aí
\82Å
\8dU
\8c\82\82µ");
4353 } else if (wizard) {
4355 Sprintf(buf, "used a wielded weapon %ld time%s", u.uconduct.weaphit,
4356 plur(u.uconduct.weaphit));
4359 Sprintf(buf, "
\82 \82È
\82½
\82Í%ld
\89ñ
\91\95\94õ
\82µ
\82½
\95\90\8aí
\82ð
\8eg
\97p
\82µ", u.uconduct.weaphit);
4363 if (!u.uconduct.killer)
4365 you_have_been("a pacifist");
4367 you_have_been("
\95½
\98a
\8eå
\8b`
\8eÒ");
4369 if (!u.uconduct.literate) {
4371 you_have_been("illiterate");
4373 you_have_never("
\82 \82È
\82½
\82Í
\93Ç
\82Ý
\8f\91\82«
\82µ");
4374 } else if (wizard) {
4376 Sprintf(buf, "read items or engraved %ld time%s", u.uconduct.literate,
4377 plur(u.uconduct.literate));
4380 Sprintf(buf, "%ld
\89ñ
\93Ç
\82ñ
\82¾
\82è
\8f\91\82¢
\82½
\82è
\82µ", u.uconduct.literate);
4385 ngenocided = num_genocides();
4386 if (ngenocided == 0) {
4388 you_have_never("genocided any monsters");
4390 you_have_never("
\82 \82È
\82½
\82Í
\89ö
\95¨
\82ð
\8bs
\8eE
\82µ");
4393 Sprintf(buf, "genocided %d type%s of monster%s", ngenocided,
4394 plur(ngenocided), plur(ngenocided));
4397 Sprintf(buf, "%d
\8eí
\82Ì
\89ö
\95¨
\82ð
\8bs
\8eE
\82µ", ngenocided);
4402 if (!u.uconduct.polypiles) {
4404 you_have_never("polymorphed an object");
4406 you_have_never("
\82 \82È
\82½
\82Í
\95¨
\91Ì
\82ð
\95Ï
\89»
\82³
\82¹");
4407 } else if (wizard) {
4409 Sprintf(buf, "polymorphed %ld item%s", u.uconduct.polypiles,
4410 plur(u.uconduct.polypiles));
4413 Sprintf(buf, "%ld
\8cÂ
\82Ì
\95¨
\82ð
\95Ï
\89»
\82³
\82¹", u.uconduct.polypiles);
4418 if (!u.uconduct.polyselfs) {
4420 you_have_never("changed form");
4422 you_have_never("
\82 \82È
\82½
\82Í
\95Ï
\89»
\82µ");
4423 } else if (wizard) {
4425 Sprintf(buf, "changed form %ld time%s", u.uconduct.polyselfs,
4426 plur(u.uconduct.polyselfs));
4429 Sprintf(buf, "%ld
\89ñ
\8ep
\82ð
\95Ï
\82¦", u.uconduct.polyselfs);
4434 if (!u.uconduct.wishes) {
4436 you_have_X("used no wishes");
4438 you_have_never("
\82 \82È
\82½
\82Í
\8aè
\82¢
\8e\96\82ð
\82µ");
4441 Sprintf(buf, "used %ld wish%s", u.uconduct.wishes,
4442 (u.uconduct.wishes > 1L) ? "es" : "");
4444 Sprintf(buf, "%ld
\89ñ
\8aè
\82¢
\8e\96\82ð
\82µ", u.uconduct.wishes);
4446 if (u.uconduct.wisharti) {
4447 /* if wisharti == wishes
4448 * 1 wish (for an artifact)
4449 * 2 wishes (both for artifacts)
4450 * N wishes (all for artifacts)
4451 * else (N is at least 2 in order to get here; M < N)
4452 * N wishes (1 for an artifact)
4453 * N wishes (M for artifacts)
4456 if (u.uconduct.wisharti == u.uconduct.wishes)
4457 Sprintf(eos(buf), " (%s",
4458 (u.uconduct.wisharti > 2L) ? "all "
4459 : (u.uconduct.wisharti == 2L) ? "both " : "");
4461 Sprintf(eos(buf), " (%ld ", u.uconduct.wisharti);
4463 Sprintf(eos(buf), "for %s)",
4464 (u.uconduct.wisharti == 1L) ? "an artifact"
4467 Sprintf(eos(buf), " (
\90¹
\8aí
\82Í%ld
\89ñ)", u.uconduct.wisharti);
4472 if (!u.uconduct.wisharti)
4474 enl_msg(You_, "have not wished", "did not wish",
4475 " for any artifacts", "");
4477 enl_msg("
\82 \82È
\82½
\82Í
\90¹
\8aí
\82ð
\8aè", "
\82Á
\82Ä
\82¢
\82È
\82¢", "
\82í
\82È
\82©
\82Á
\82½", "", "");
4481 /* Pop up the window and wait for a key */
4482 display_nhwindow(en_win, TRUE);
4483 destroy_nhwindow(en_win);
4487 /* ordered by command name */
4488 struct ext_func_tab extcmdlist[] = {
4489 { '#', "#", "perform an extended command",
4490 doextcmd, IFBURIED | GENERALCMD },
4492 { M('?'), "?", "list all extended commands",
4494 { M('?'), "?", "
\82±
\82Ì
\8ag
\92£
\83R
\83}
\83\93\83h
\88ê
\97\97\82ð
\95\
\8e¦
\82·
\82é",
4496 doextlist, IFBURIED | AUTOCOMPLETE | GENERALCMD },
4498 { M('a'), "adjust", "adjust inventory letters",
4500 { M('a'), "adjust", "
\8e\9d\82¿
\95¨
\88ê
\97\97\82Ì
\92²
\90®",
4502 doorganize, IFBURIED | AUTOCOMPLETE },
4504 { M('A'), "annotate", "name current level",
4506 { M('A'), "annotate", "
\8c»
\8dÝ
\82Ì
\8aK
\82É
\96¼
\91O
\82ð
\82Â
\82¯
\82é",
4508 donamelevel, IFBURIED | AUTOCOMPLETE },
4509 { 'a', "apply", "apply (use) a tool (pick-axe, key, lamp...)",
4511 { C('x'), "attributes", "show your attributes",
4512 doattributes, IFBURIED },
4513 { '@', "autopickup", "toggle the pickup option on/off",
4514 dotogglepickup, IFBURIED },
4515 { 'C', "call", "call (name) something", docallcmd, IFBURIED },
4516 { 'Z', "cast", "zap (cast) a spell", docast, IFBURIED },
4518 { M('c'), "chat", "talk to someone", dotalk, IFBURIED | AUTOCOMPLETE },
4520 { M('c'), "chat", "
\92N
\82©
\82Æ
\98b
\82·", dotalk, IFBURIED | AUTOCOMPLETE },
4522 { 'c', "close", "close a door", doclose },
4524 { M('C'), "conduct", "list voluntary challenges you have maintained",
4526 { M('C'), "conduct", "
\82Ç
\82¤
\82¢
\82¤
\8ds
\93®
\82ð
\82Æ
\82Á
\82½
\82©
\8c©
\82é",
4528 doconduct, IFBURIED | AUTOCOMPLETE },
4530 { M('d'), "dip", "dip an object into something", dodip, AUTOCOMPLETE },
4532 { M('d'), "dip", "
\89½
\82©
\82É
\95¨
\82ð
\90Z
\82·", dodip, AUTOCOMPLETE },
4534 { '>', "down", "go down a staircase", dodown },
4535 { 'd', "drop", "drop an item", dodrop },
4536 { 'D', "droptype", "drop specific item types", doddrop },
4537 { 'e', "eat", "eat something", doeat },
4538 { 'E', "engrave", "engrave writing on the floor", doengrave },
4540 { M('e'), "enhance", "advance or check weapon and spell skills",
4542 { M('e'), "enhance", "
\95\90\8aí
\8fn
\97û
\93x
\82ð
\8d\82\82ß
\82é",
4544 enhance_weapon_skill, IFBURIED | AUTOCOMPLETE },
4546 { '\0', "exploremode", "enter explore (discovery) mode",
4548 { '\0', "exploremode", "
\92T
\8c\9f(
\94
\8c©)
\83\82\81[
\83h
\82É
\93ü
\82é",
4550 enter_explore_mode, IFBURIED },
4551 { 'f', "fire", "fire ammunition from quiver", dofire },
4553 { M('f'), "force", "force a lock", doforce, AUTOCOMPLETE },
4555 { M('f'), "force", "
\8c®
\82ð
\82±
\82¶
\82 \82¯
\82é", doforce, AUTOCOMPLETE },
4557 { ';', "glance", "show what type of thing a map symbol corresponds to",
4558 doquickwhatis, IFBURIED | GENERALCMD },
4559 { '?', "help", "give a help message", dohelp, IFBURIED | GENERALCMD },
4560 { '\0', "herecmdmenu", "show menu of commands you can do here",
4561 doherecmdmenu, IFBURIED },
4562 { 'V', "history", "show long version and game history",
4563 dohistory, IFBURIED | GENERALCMD },
4564 { 'i', "inventory", "show your inventory", ddoinv, IFBURIED },
4565 { 'I', "inventtype", "inventory specific item types",
4566 dotypeinv, IFBURIED },
4568 { M('i'), "invoke", "invoke an object's special powers",
4570 { M('i'), "invoke", "
\95¨
\82Ì
\93Á
\95Ê
\82È
\97Í
\82ð
\8eg
\82¤",
4572 doinvoke, IFBURIED | AUTOCOMPLETE },
4574 { M('j'), "jump", "jump to another location", dojump, AUTOCOMPLETE },
4576 { M('j'), "jump", "
\91¼
\82Ì
\88Ê
\92u
\82É
\94ò
\82Ñ
\82¤
\82Â
\82é", dojump, AUTOCOMPLETE },
4578 { C('d'), "kick", "kick something", dokick },
4579 { '\\', "known", "show what object types have been discovered",
4580 dodiscovered, IFBURIED | GENERALCMD },
4581 { '`', "knownclass", "show discovered types for one class of objects",
4582 doclassdisco, IFBURIED | GENERALCMD },
4584 { '\0', "levelchange", "change experience level",
4586 { '\0', "levelchange", "
\8co
\8c±
\83\8c\83x
\83\8b\82ð
\95Ï
\82¦
\82é",
4588 wiz_level_change, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4590 { '\0', "lightsources", "show mobile light sources",
4592 { '\0', "lightsources", "
\88Ú
\93®
\8cõ
\8c¹
\82ð
\8c©
\82é",
4594 wiz_light_sources, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4595 { ':', "look", "look at what is here", dolook, IFBURIED },
4597 { M('l'), "loot", "loot a box on the floor", doloot, AUTOCOMPLETE },
4599 { M('l'), "loot", "
\8f°
\82Ì
\8fã
\82Ì
\94 \82ð
\8aJ
\82¯
\82é", doloot, AUTOCOMPLETE },
4601 #ifdef DEBUG_MIGRATING_MONS
4603 { '\0', "migratemons", "migrate N random monsters",
4605 { '\0', "migratemons", "
\83\89\83\93\83_
\83\80\82È
\89ö
\95¨
\82ð
\89½
\91Ì
\82©
\88Ú
\8fZ
\82³
\82¹
\82é",
4607 wiz_migrate_mons, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4610 { M('m'), "monster", "use monster's special ability",
4612 { M('m'), "monster", "
\89ö
\95¨
\82Ì
\93Á
\95Ê
\94\
\97Í
\82ð
\8eg
\82¤",
4614 domonability, IFBURIED | AUTOCOMPLETE },
4616 { 'N', "name", "name a monster or an object",
4618 { 'N', "name", "
\83A
\83C
\83e
\83\80\82â
\95¨
\82É
\96¼
\91O
\82ð
\82Â
\82¯
\82é",
4620 docallcmd, IFBURIED | AUTOCOMPLETE },
4622 { M('o'), "offer", "offer a sacrifice to the gods",
4624 { M('o'), "offer", "
\90_
\82É
\8b\9f\95¨
\82ð
\95ù
\82°
\82é",
4626 dosacrifice, AUTOCOMPLETE },
4627 { 'o', "open", "open a door", doopen },
4628 { 'O', "options", "show option settings, possibly change them",
4629 doset, IFBURIED | GENERALCMD },
4631 { C('o'), "overview", "show a summary of the explored dungeon",
4633 { C('o'), "overview", "
\92T
\8dõ
\82µ
\82½
\96À
\8b{
\82Ì
\8aT
\97v
\82ð
\95\
\8e¦
\82·
\82é",
4635 dooverview, IFBURIED | AUTOCOMPLETE },
4637 { '\0', "panic", "test panic routine (fatal to game)",
4639 { '\0', "panic", "
\83p
\83j
\83b
\83N
\83\8b\81[
\83`
\83\93\82ð
\83e
\83X
\83g
\82·
\82é(
\92v
\96½
\93I)",
4641 wiz_panic, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4642 { 'p', "pay", "pay your shopping bill", dopay },
4643 { ',', "pickup", "pick up things at the current location", dopickup },
4645 { '\0', "polyself", "polymorph self",
4647 { '\0', "polyself", "
\95Ï
\89»
\82·
\82é",
4649 wiz_polyself, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4651 { M('p'), "pray", "pray to the gods for help",
4653 { M('p'), "pray", "
\90_
\82É
\8bF
\82é",
4655 dopray, IFBURIED | AUTOCOMPLETE },
4656 { C('p'), "prevmsg", "view recent game messages",
4657 doprev_message, IFBURIED | GENERALCMD },
4658 { 'P', "puton", "put on an accessory (ring, amulet, etc)", doputon },
4659 { 'q', "quaff", "quaff (drink) something", dodrink },
4661 { M('q'), "quit", "exit without saving current game",
4663 { M('q'), "quit", "
\83Z
\81[
\83u
\82µ
\82È
\82¢
\82Å
\8fI
\97¹",
4665 done2, IFBURIED | AUTOCOMPLETE | GENERALCMD },
4666 { 'Q', "quiver", "select ammunition for quiver", dowieldquiver },
4667 { 'r', "read", "read a scroll or spellbook", doread },
4668 { C('r'), "redraw", "redraw screen", doredraw, IFBURIED | GENERALCMD },
4669 { 'R', "remove", "remove an accessory (ring, amulet, etc)", doremring },
4671 { M('R'), "ride", "mount or dismount a saddled steed",
4673 { M('R'), "ride", "
\89ö
\95¨
\82É
\8fæ
\82é(
\82Ü
\82½
\82Í
\8d~
\82è
\82é)",
4675 doride, AUTOCOMPLETE },
4677 { M('r'), "rub", "rub a lamp or a stone", dorub, AUTOCOMPLETE },
4679 { M('r'), "rub", "
\83\89\83\93\83v
\82ð
\82±
\82·
\82é", dorub, AUTOCOMPLETE },
4681 { 'S', "save", "save the game and exit", dosave, IFBURIED | GENERALCMD },
4683 { 's', "search", "search for traps and secret doors",
4684 dosearch, IFBURIED, "searching" },
4686 { 's', "search", "ã©
\82â
\89B
\82µ
\94à
\82ð
\92T
\82·",
4687 dosearch, IFBURIED, "
\92T
\82·" },
4689 { '*', "seeall", "show all equipment in use", doprinuse, IFBURIED },
4690 { AMULET_SYM, "seeamulet", "show the amulet currently worn",
4691 dopramulet, IFBURIED },
4692 { ARMOR_SYM, "seearmor", "show the armor currently worn",
4693 doprarm, IFBURIED },
4694 { GOLD_SYM, "seegold", "count your gold", doprgold, IFBURIED },
4696 { '\0', "seenv", "show seen vectors",
4698 { '\0', "seenv", "
\8e\8b\90ü
\83x
\83N
\83g
\83\8b\82ð
\8c©
\82é",
4700 wiz_show_seenv, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4701 { RING_SYM, "seerings", "show the ring(s) currently worn",
4702 doprring, IFBURIED },
4703 { SPBOOK_SYM, "seespells", "list and reorder known spells",
4704 dovspell, IFBURIED },
4705 { TOOL_SYM, "seetools", "show the tools currently in use",
4706 doprtool, IFBURIED },
4707 { '^', "seetrap", "show the type of adjacent trap", doidtrap, IFBURIED },
4708 { WEAPON_SYM, "seeweapon", "show the weapon currently wielded",
4709 doprwep, IFBURIED },
4710 { '!', "shell", "do a shell escape",
4711 dosh_core, IFBURIED | GENERALCMD
4717 { M('s'), "sit", "sit down", dosit, AUTOCOMPLETE },
4719 { M('s'), "sit", "
\8dÀ
\82é", dosit, AUTOCOMPLETE },
4722 { '\0', "stats", "show memory statistics",
4724 { '\0', "stats", "
\83\81\83\82\83\8a\8fó
\91Ô
\82ð
\8c©
\82é",
4726 wiz_show_stats, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4727 { C('z'), "suspend", "suspend the game",
4728 dosuspend_core, IFBURIED | GENERALCMD
4731 #endif /* SUSPEND */
4733 { 'x', "swap", "swap wielded and secondary weapons", doswapweapon },
4734 { 'T', "takeoff", "take off one piece of armor", dotakeoff },
4735 { 'A', "takeoffall", "remove all armor", doddoremarm },
4736 { C('t'), "teleport", "teleport around the level", dotelecmd, IFBURIED },
4738 { '\0', "terrain", "show map without obstructions",
4740 { '\0', "terrain", "
\8e×
\96\82\82³
\82ê
\82¸
\82É
\92n
\90}
\82ð
\8c©
\82é",
4742 doterrain, IFBURIED | AUTOCOMPLETE },
4743 { '\0', "therecmdmenu",
4744 "menu of commands you can do from here to adjacent spot",
4746 { 't', "throw", "throw something", dothrow },
4748 { '\0', "timeout", "look at timeout queue and hero's timed intrinsics",
4750 { '\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é",
4752 wiz_timeout_queue, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4754 { M('T'), "tip", "empty a container", dotip, AUTOCOMPLETE },
4756 { M('T'), "tip", "
\93ü
\82ê
\95¨
\82ð
\8bó
\82É
\82·
\82é", dotip, AUTOCOMPLETE },
4758 { '_', "travel", "travel to a specific location on the map", dotravel },
4760 { M('t'), "turn", "turn undead away", doturn, IFBURIED | AUTOCOMPLETE },
4762 { M('t'), "turn", "
\83A
\83\93\83f
\83b
\83g
\82ð
\93y
\82É
\95Ô
\82·", doturn, IFBURIED | AUTOCOMPLETE },
4765 { 'X', "twoweapon", "toggle two-weapon combat",
4767 { 'X', "twoweapon", "
\97¼
\8eè
\8e\9d\82¿
\82Ì
\90Ø
\82è
\91Ö
\82¦",
4769 dotwoweapon, AUTOCOMPLETE },
4771 { M('u'), "untrap", "untrap something", dountrap, AUTOCOMPLETE },
4773 { M('u'), "untrap", "ã©
\82ð
\82Í
\82¸
\82·", dountrap, AUTOCOMPLETE },
4775 { '<', "up", "go up a staircase", doup },
4777 { '\0', "vanquished", "list vanquished monsters",
4779 { '\0', "vanquished", "
\93|
\82µ
\82½
\89ö
\95¨
\82Ì
\88ê
\97\97\82ð
\8c©
\82é",
4781 dovanquished, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4782 { M('v'), "version",
4784 "list compile time options for this version of NetHack",
4786 "
\83R
\83\93\83p
\83C
\83\8b\8e\9e\82Ì
\83I
\83v
\83V
\83\87\83\93\82ð
\95\
\8e¦
\82·
\82é",
4788 doextversion, IFBURIED | AUTOCOMPLETE | GENERALCMD },
4789 { 'v', "versionshort", "show version", doversion, IFBURIED | GENERALCMD },
4791 { '\0', "vision", "show vision array",
4793 { '\0', "vision", "
\8e\8b\8aE
\94z
\97ñ
\82ð
\8c©
\82é",
4795 wiz_show_vision, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4797 { '.', "wait", "rest one move while doing nothing",
4798 donull, IFBURIED, "waiting" },
4800 { '.', "wait", "
\88ê
\95à
\95ª
\89½
\82à
\82µ
\82È
\82¢",
4801 donull, IFBURIED, "
\8bx
\8ce
\82·
\82é" },
4803 { 'W', "wear", "wear a piece of armor", dowear },
4804 { '&', "whatdoes", "tell what a command does", dowhatdoes, IFBURIED },
4805 { '/', "whatis", "show what type of thing a symbol corresponds to",
4806 dowhatis, IFBURIED | GENERALCMD },
4807 { 'w', "wield", "wield (put in use) a weapon", dowield },
4809 { M('w'), "wipe", "wipe off your face", dowipe, AUTOCOMPLETE },
4811 { M('w'), "wipe", "
\8aç
\82ð
\90@
\82¤", dowipe, AUTOCOMPLETE },
4815 { '\0', "wizbury", "bury objs under and around you",
4817 { '\0', "wizbury", "
\95¨
\82ð
\82 \82È
\82½
\82Ì
\8eü
\82è
\82É
\96\84\82ß
\82é",
4819 wiz_debug_cmd_bury, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4821 { C('e'), "wizdetect", "reveal hidden things within a small radius",
4822 wiz_detect, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4823 { C('g'), "wizgenesis", "create a monster",
4824 wiz_genesis, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4825 { C('i'), "wizidentify", "identify all items in inventory",
4826 wiz_identify, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4827 { '\0', "wizintrinsic", "set an intrinsic",
4828 wiz_intrinsic, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4829 { C('v'), "wizlevelport", "teleport to another level",
4830 wiz_level_tele, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4831 { '\0', "wizmakemap", "recreate the current level",
4832 wiz_makemap, IFBURIED | WIZMODECMD },
4833 { C('f'), "wizmap", "map the level",
4834 wiz_map, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4836 { '\0', "wizrumorcheck", "verify rumor boundaries",
4838 { '\0', "wizrumorcheck", "
\89\
\82Ì
\8b«
\8aE
\82ð
\8c\9f\8fØ
\82·
\82é",
4840 wiz_rumor_check, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4842 { '\0', "wizsmell", "smell monster",
4844 { '\0', "wizsmell", "
\89ö
\95¨
\82Ì
\93õ
\82¢
\82ð
\9ak
\82®",
4846 wiz_smell, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4847 { '\0', "wizwhere", "show locations of special levels",
4848 wiz_where, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4849 { C('w'), "wizwish", "wish for something",
4850 wiz_wish, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4852 { '\0', "wmode", "show wall modes",
4854 { '\0', "wmode", "
\95Ç
\83\82\81[
\83h
\82ð
\8c©
\82é",
4856 wiz_show_wmodes, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4857 { 'z', "zap", "zap a wand", dozap },
4858 { '\0', (char *) 0, (char *) 0, donull, 0, (char *) 0 } /* sentinel */
4861 int extcmdlist_length = SIZE(extcmdlist) - 1;
4867 if (Cmd.commands[key] && Cmd.commands[key]->ef_txt)
4868 return Cmd.commands[key]->ef_desc;
4873 bind_key(key, command)
4875 const char *command;
4877 struct ext_func_tab *extcmd;
4879 /* special case: "nothing" is reserved for unbinding */
4880 if (!strcmp(command, "nothing")) {
4881 Cmd.commands[key] = (struct ext_func_tab *) 0;
4885 for (extcmd = extcmdlist; extcmd->ef_txt; extcmd++) {
4886 if (strcmp(command, extcmd->ef_txt))
4888 Cmd.commands[key] = extcmd;
4889 #if 0 /* silently accept key binding for unavailable command (!SHELL,&c) */
4890 if ((extcmd->flags & CMD_NOT_AVAILABLE) != 0) {
4893 Sprintf(buf, cmdnotavail, extcmd->ef_txt);
4894 config_error_add("%s", buf);
4903 /* initialize all keyboard commands */
4907 struct ext_func_tab *extcmd;
4909 for (extcmd = extcmdlist; extcmd->ef_txt; extcmd++)
4911 Cmd.commands[extcmd->key] = extcmd;
4913 (void) bind_key(C('l'), "redraw"); /* if number_pad is set */
4914 /* 'b', 'B' : go sw */
4915 /* 'F' : fight (one time) */
4916 /* 'g', 'G' : multiple go */
4917 /* 'h', 'H' : go west */
4918 (void) bind_key('h', "help"); /* if number_pad is set */
4919 (void) bind_key('j', "jump"); /* if number_pad is on */
4920 /* 'j', 'J', 'k', 'K', 'l', 'L', 'm', 'M', 'n', 'N' move commands */
4921 (void) bind_key('k', "kick"); /* if number_pad is on */
4922 (void) bind_key('l', "loot"); /* if number_pad is on */
4923 (void) bind_key(C('n'), "annotate"); /* if number_pad is on */
4924 (void) bind_key(M('n'), "name");
4925 (void) bind_key(M('N'), "name");
4926 (void) bind_key('u', "untrap"); /* if number_pad is on */
4929 (void) bind_key(M('O'), "overview");
4930 (void) bind_key(M('2'), "twoweapon");
4933 (void) bind_key(' ', "wait");
4937 dokeylist_putcmds(datawin, docount, cmdflags, exflags, keys_used)
4940 int cmdflags, exflags;
4941 boolean *keys_used; /* boolean keys_used[256] */
4948 for (i = 0; i < 256; i++) {
4949 const struct ext_func_tab *extcmd;
4950 uchar key = (uchar) i;
4954 if (key == ' ' && !flags.rest_on_space)
4956 if ((extcmd = Cmd.commands[i]) != (struct ext_func_tab *) 0) {
4957 if ((cmdflags && !(extcmd->flags & cmdflags))
4958 || (exflags && (extcmd->flags & exflags)))
4964 Sprintf(buf, "%-8s %-12s %s", key2txt(key, buf2),
4967 putstr(datawin, 0, buf);
4968 keys_used[i] = TRUE;
4974 /* list all keys and their bindings, like dat/hh but dynamic */
4976 dokeylist(VOID_ARGS)
4978 char buf[BUFSZ], buf2[BUFSZ];
4980 boolean keys_used[256] = {0};
4984 run_desc[] = "Prefix: run until something very interesting is seen",
4986 "Prefix: force fight even if you don't see a monster";
4987 static const struct {
4992 { NHKF_ESC, "escape from the current query/action", FALSE },
4994 "Prefix: rush until something interesting is seen", FALSE },
4995 { NHKF_RUN, run_desc, FALSE },
4996 { NHKF_RUN2, run_desc, TRUE },
4997 { NHKF_FIGHT, forcefight_desc, FALSE },
4998 { NHKF_FIGHT2, forcefight_desc, TRUE } ,
5000 "Prefix: move without picking up objects/fighting", FALSE },
5001 { NHKF_RUN_NOPICKUP,
5002 "Prefix: run without picking up objects/fighting", FALSE },
5003 { NHKF_DOINV, "view inventory", TRUE },
5004 { NHKF_REQMENU, "Prefix: request a menu", FALSE },
5006 { NHKF_DOAGAIN , "re-do: perform the previous command again", FALSE },
5008 { 0, (const char *) 0, FALSE }
5011 datawin = create_nhwindow(NHW_TEXT);
5012 putstr(datawin, 0, "");
5013 putstr(datawin, 0, " Full Current Key Bindings List");
5015 /* directional keys */
5016 putstr(datawin, 0, "");
5017 putstr(datawin, 0, "Directional keys:");
5018 show_direction_keys(datawin, '.', FALSE); /* '.'==self in direction grid */
5020 keys_used[(uchar) Cmd.move_NW] = keys_used[(uchar) Cmd.move_N]
5021 = keys_used[(uchar) Cmd.move_NE] = keys_used[(uchar) Cmd.move_W]
5022 = keys_used[(uchar) Cmd.move_E] = keys_used[(uchar) Cmd.move_SW]
5023 = keys_used[(uchar) Cmd.move_S] = keys_used[(uchar) Cmd.move_SE]
5026 if (!iflags.num_pad) {
5027 keys_used[(uchar) highc(Cmd.move_NW)]
5028 = keys_used[(uchar) highc(Cmd.move_N)]
5029 = keys_used[(uchar) highc(Cmd.move_NE)]
5030 = keys_used[(uchar) highc(Cmd.move_W)]
5031 = keys_used[(uchar) highc(Cmd.move_E)]
5032 = keys_used[(uchar) highc(Cmd.move_SW)]
5033 = keys_used[(uchar) highc(Cmd.move_S)]
5034 = keys_used[(uchar) highc(Cmd.move_SE)] = TRUE;
5035 keys_used[(uchar) C(Cmd.move_NW)]
5036 = keys_used[(uchar) C(Cmd.move_N)]
5037 = keys_used[(uchar) C(Cmd.move_NE)]
5038 = keys_used[(uchar) C(Cmd.move_W)]
5039 = keys_used[(uchar) C(Cmd.move_E)]
5040 = keys_used[(uchar) C(Cmd.move_SW)]
5041 = keys_used[(uchar) C(Cmd.move_S)]
5042 = keys_used[(uchar) C(Cmd.move_SE)] = TRUE;
5043 putstr(datawin, 0, "");
5045 "Shift-<direction> will move in specified direction until you hit");
5046 putstr(datawin, 0, " a wall or run into something.");
5048 "Ctrl-<direction> will run in specified direction until something");
5049 putstr(datawin, 0, " very interesting is seen.");
5052 putstr(datawin, 0, "");
5053 putstr(datawin, 0, "Miscellaneous keys:");
5054 for (i = 0; misc_keys[i].desc; i++) {
5055 key = Cmd.spkeys[misc_keys[i].nhkf];
5056 if (key && ((misc_keys[i].numpad && iflags.num_pad)
5057 || !misc_keys[i].numpad)) {
5058 keys_used[(uchar) key] = TRUE;
5059 Sprintf(buf, "%-8s %s", key2txt(key, buf2), misc_keys[i].desc);
5060 putstr(datawin, 0, buf);
5064 putstr(datawin, 0, "^c break out of NetHack (SIGINT)");
5065 keys_used[(uchar) C('c')] = TRUE;
5068 putstr(datawin, 0, "");
5069 show_menu_controls(datawin, TRUE);
5071 if (dokeylist_putcmds(datawin, TRUE, GENERALCMD, WIZMODECMD, keys_used)) {
5072 putstr(datawin, 0, "");
5073 putstr(datawin, 0, "General commands:");
5074 (void) dokeylist_putcmds(datawin, FALSE, GENERALCMD, WIZMODECMD,
5078 if (dokeylist_putcmds(datawin, TRUE, 0, WIZMODECMD, keys_used)) {
5079 putstr(datawin, 0, "");
5080 putstr(datawin, 0, "Game commands:");
5081 (void) dokeylist_putcmds(datawin, FALSE, 0, WIZMODECMD, keys_used);
5085 && dokeylist_putcmds(datawin, TRUE, WIZMODECMD, 0, keys_used)) {
5086 putstr(datawin, 0, "");
5087 putstr(datawin, 0, "Wizard-mode commands:");
5088 (void) dokeylist_putcmds(datawin, FALSE, WIZMODECMD, 0, keys_used);
5091 display_nhwindow(datawin, FALSE);
5092 destroy_nhwindow(datawin);
5101 for (i = 0; i < 256; ++i)
5102 if (Cmd.commands[i] && Cmd.commands[i]->ef_funct == fn)
5108 * wizard mode sanity_check code
5111 static const char template[] = "%-27s %4ld %6ld";
5112 static const char stats_hdr[] = " count bytes";
5113 static const char stats_sep[] = "--------------------------- ----- -------";
5119 int sz = (int) sizeof (struct obj);
5122 sz += (int) sizeof (struct oextra);
5124 sz += (int) strlen(ONAME(otmp)) + 1;
5126 sz += size_monst(OMONST(otmp), FALSE);
5128 sz += (int) sizeof (unsigned);
5130 sz += (int) sizeof (long);
5132 sz += (int) strlen(OMAILCMD(otmp)) + 1;
5138 count_obj(chain, total_count, total_size, top, recurse)
5148 for (count = size = 0, obj = chain; obj; obj = obj->nobj) {
5151 size += size_obj(obj);
5153 if (recurse && obj->cobj)
5154 count_obj(obj->cobj, total_count, total_size, TRUE, TRUE);
5156 *total_count += count;
5157 *total_size += size;
5161 obj_chain(win, src, chain, force, total_count, total_size)
5170 long count = 0L, size = 0L;
5172 count_obj(chain, &count, &size, TRUE, FALSE);
5174 if (count || size || force) {
5175 *total_count += count;
5176 *total_size += size;
5177 Sprintf(buf, template, src, count, size);
5178 putstr(win, 0, buf);
5183 mon_invent_chain(win, src, chain, total_count, total_size)
5186 struct monst *chain;
5191 long count = 0, size = 0;
5194 for (mon = chain; mon; mon = mon->nmon)
5195 count_obj(mon->minvent, &count, &size, TRUE, FALSE);
5197 if (count || size) {
5198 *total_count += count;
5199 *total_size += size;
5200 Sprintf(buf, template, src, count, size);
5201 putstr(win, 0, buf);
5206 contained_stats(win, src, total_count, total_size)
5213 long count = 0, size = 0;
5216 count_obj(invent, &count, &size, FALSE, TRUE);
5217 count_obj(fobj, &count, &size, FALSE, TRUE);
5218 count_obj(level.buriedobjlist, &count, &size, FALSE, TRUE);
5219 count_obj(migrating_objs, &count, &size, FALSE, TRUE);
5220 /* DEADMONSTER check not required in this loop since they have no
5222 for (mon = fmon; mon; mon = mon->nmon)
5223 count_obj(mon->minvent, &count, &size, FALSE, TRUE);
5224 for (mon = migrating_mons; mon; mon = mon->nmon)
5225 count_obj(mon->minvent, &count, &size, FALSE, TRUE);
5227 if (count || size) {
5228 *total_count += count;
5229 *total_size += size;
5230 Sprintf(buf, template, src, count, size);
5231 putstr(win, 0, buf);
5236 size_monst(mtmp, incl_wsegs)
5240 int sz = (int) sizeof (struct monst);
5242 if (mtmp->wormno && incl_wsegs)
5243 sz += size_wseg(mtmp);
5246 sz += (int) sizeof (struct mextra);
5248 sz += (int) strlen(MNAME(mtmp)) + 1;
5250 sz += (int) sizeof (struct egd);
5252 sz += (int) sizeof (struct epri);
5254 sz += (int) sizeof (struct eshk);
5256 sz += (int) sizeof (struct emin);
5258 sz += (int) sizeof (struct edog);
5259 /* mextra->mcorpsenm doesn't point to more memory */
5265 mon_chain(win, src, chain, force, total_count, total_size)
5268 struct monst *chain;
5276 /* mon->wormno means something different for migrating_mons and mydogs */
5277 boolean incl_wsegs = !strcmpi(src, "fmon");
5280 for (mon = chain; mon; mon = mon->nmon) {
5282 size += size_monst(mon, incl_wsegs);
5284 if (count || size || force) {
5285 *total_count += count;
5286 *total_size += size;
5287 Sprintf(buf, template, src, count, size);
5288 putstr(win, 0, buf);
5293 misc_stats(win, total_count, total_size)
5298 char buf[BUFSZ], hdrbuf[QBUFSZ];
5302 struct damage *sd; /* shop damage */
5303 struct kinfo *k; /* delayed killer */
5304 struct cemetery *bi; /* bones info */
5306 /* traps and engravings are output unconditionally;
5307 * others only if nonzero
5310 for (tt = ftrap; tt; tt = tt->ntrap) {
5312 size += (long) sizeof *tt;
5314 *total_count += count;
5315 *total_size += size;
5316 Sprintf(hdrbuf, "traps, size %ld", (long) sizeof (struct trap));
5317 Sprintf(buf, template, hdrbuf, count, size);
5318 putstr(win, 0, buf);
5321 engr_stats("engravings, size %ld+text", hdrbuf, &count, &size);
5322 *total_count += count;
5323 *total_size += size;
5324 Sprintf(buf, template, hdrbuf, count, size);
5325 putstr(win, 0, buf);
5328 light_stats("light sources, size %ld", hdrbuf, &count, &size);
5329 if (count || size) {
5330 *total_count += count;
5331 *total_size += size;
5332 Sprintf(buf, template, hdrbuf, count, size);
5333 putstr(win, 0, buf);
5337 timer_stats("timers, size %ld", hdrbuf, &count, &size);
5338 if (count || size) {
5339 *total_count += count;
5340 *total_size += size;
5341 Sprintf(buf, template, hdrbuf, count, size);
5342 putstr(win, 0, buf);
5346 for (sd = level.damagelist; sd; sd = sd->next) {
5348 size += (long) sizeof *sd;
5350 if (count || size) {
5351 *total_count += count;
5352 *total_size += size;
5353 Sprintf(hdrbuf, "shop damage, size %ld",
5354 (long) sizeof (struct damage));
5355 Sprintf(buf, template, hdrbuf, count, size);
5356 putstr(win, 0, buf);
5360 region_stats("regions, size %ld+%ld*rect+N", hdrbuf, &count, &size);
5361 if (count || size) {
5362 *total_count += count;
5363 *total_size += size;
5364 Sprintf(buf, template, hdrbuf, count, size);
5365 putstr(win, 0, buf);
5369 for (k = killer.next; k; k = k->next) {
5371 size += (long) sizeof *k;
5373 if (count || size) {
5374 *total_count += count;
5375 *total_size += size;
5376 Sprintf(hdrbuf, "delayed killer%s, size %ld",
5377 plur(count), (long) sizeof (struct kinfo));
5378 Sprintf(buf, template, hdrbuf, count, size);
5379 putstr(win, 0, buf);
5383 for (bi = level.bonesinfo; bi; bi = bi->next) {
5385 size += (long) sizeof *bi;
5387 if (count || size) {
5388 *total_count += count;
5389 *total_size += size;
5390 Sprintf(hdrbuf, "bones history, size %ld",
5391 (long) sizeof (struct cemetery));
5392 Sprintf(buf, template, hdrbuf, count, size);
5393 putstr(win, 0, buf);
5397 for (idx = 0; idx < NUM_OBJECTS; ++idx)
5398 if (objects[idx].oc_uname) {
5400 size += (long) (strlen(objects[idx].oc_uname) + 1);
5402 if (count || size) {
5403 *total_count += count;
5404 *total_size += size;
5405 Strcpy(hdrbuf, "object type names, text");
5406 Sprintf(buf, template, hdrbuf, count, size);
5407 putstr(win, 0, buf);
5412 * Display memory usage of all monsters and objects on the level.
5419 long total_obj_size, total_obj_count,
5420 total_mon_size, total_mon_count,
5421 total_ovr_size, total_ovr_count,
5422 total_misc_size, total_misc_count;
5424 win = create_nhwindow(NHW_TEXT);
5425 putstr(win, 0, "Current memory statistics:");
5427 total_obj_count = total_obj_size = 0L;
5428 putstr(win, 0, stats_hdr);
5429 Sprintf(buf, " Objects, base size %ld", (long) sizeof (struct obj));
5430 putstr(win, 0, buf);
5431 obj_chain(win, "invent", invent, TRUE, &total_obj_count, &total_obj_size);
5432 obj_chain(win, "fobj", fobj, TRUE, &total_obj_count, &total_obj_size);
5433 obj_chain(win, "buried", level.buriedobjlist, FALSE,
5434 &total_obj_count, &total_obj_size);
5435 obj_chain(win, "migrating obj", migrating_objs, FALSE,
5436 &total_obj_count, &total_obj_size);
5437 obj_chain(win, "billobjs", billobjs, FALSE,
5438 &total_obj_count, &total_obj_size);
5439 mon_invent_chain(win, "minvent", fmon, &total_obj_count, &total_obj_size);
5440 mon_invent_chain(win, "migrating minvent", migrating_mons,
5441 &total_obj_count, &total_obj_size);
5442 contained_stats(win, "contained", &total_obj_count, &total_obj_size);
5443 putstr(win, 0, stats_sep);
5444 Sprintf(buf, template, " Obj total", total_obj_count, total_obj_size);
5445 putstr(win, 0, buf);
5447 total_mon_count = total_mon_size = 0L;
5449 Sprintf(buf, " Monsters, base size %ld", (long) sizeof (struct monst));
5450 putstr(win, 0, buf);
5451 mon_chain(win, "fmon", fmon, TRUE, &total_mon_count, &total_mon_size);
5452 mon_chain(win, "migrating", migrating_mons, FALSE,
5453 &total_mon_count, &total_mon_size);
5454 /* 'mydogs' is only valid during level change or end of game disclosure,
5455 but conceivably we've been called from within debugger at such time */
5456 if (mydogs) /* monsters accompanying hero */
5457 mon_chain(win, "mydogs", mydogs, FALSE,
5458 &total_mon_count, &total_mon_size);
5459 putstr(win, 0, stats_sep);
5460 Sprintf(buf, template, " Mon total", total_mon_count, total_mon_size);
5461 putstr(win, 0, buf);
5463 total_ovr_count = total_ovr_size = 0L;
5465 putstr(win, 0, " Overview");
5466 overview_stats(win, template, &total_ovr_count, &total_ovr_size);
5467 putstr(win, 0, stats_sep);
5468 Sprintf(buf, template, " Over total", total_ovr_count, total_ovr_size);
5469 putstr(win, 0, buf);
5471 total_misc_count = total_misc_size = 0L;
5473 putstr(win, 0, " Miscellaneous");
5474 misc_stats(win, &total_misc_count, &total_misc_size);
5475 putstr(win, 0, stats_sep);
5476 Sprintf(buf, template, " Misc total", total_misc_count, total_misc_size);
5477 putstr(win, 0, buf);
5480 putstr(win, 0, stats_sep);
5481 Sprintf(buf, template, " Grand total",
5482 (total_obj_count + total_mon_count
5483 + total_ovr_count + total_misc_count),
5484 (total_obj_size + total_mon_size
5485 + total_ovr_size + total_misc_size));
5486 putstr(win, 0, buf);
5488 #if defined(__BORLANDC__) && !defined(_WIN32)
5489 show_borlandc_stats(win);
5492 display_nhwindow(win, FALSE);
5493 destroy_nhwindow(win);
5501 timer_sanity_check();
5503 light_sources_sanity_check();
5507 #ifdef DEBUG_MIGRATING_MONS
5512 char inbuf[BUFSZ] = DUMMY;
5513 struct permonst *ptr;
5517 getlin("How many random monsters to migrate? [0]", inbuf);
5518 if (*inbuf == '\033')
5520 mcount = atoi(inbuf);
5521 if (mcount < 0 || mcount > (COLNO * ROWNO) || Is_botlevel(&u.uz))
5523 while (mcount > 0) {
5524 if (Is_stronghold(&u.uz))
5525 assign_level(&tolevel, &valley_level);
5527 get_level(&tolevel, depth(&u.uz) + 1);
5529 mtmp = makemon(ptr, 0, 0, NO_MM_FLAGS);
5531 migrate_to_level(mtmp, ledger_no(&tolevel), MIGR_RANDOM,
5539 #define unctrl(c) ((c) <= C('z') ? (0x60 | (c)) : (c))
5540 #define unmeta(c) (0x7f & (c))
5546 } const spkeys_binds[] = {
5547 { NHKF_ESC, '\033', (char *) 0 }, /* no binding */
5548 { NHKF_DOAGAIN, DOAGAIN, "repeat" },
5549 { NHKF_REQMENU, 'm', "reqmenu" },
5550 { NHKF_RUN, 'G', "run" },
5551 { NHKF_RUN2, '5', "run.numpad" },
5552 { NHKF_RUSH, 'g', "rush" },
5553 { NHKF_FIGHT, 'F', "fight" },
5554 { NHKF_FIGHT2, '-', "fight.numpad" },
5555 { NHKF_NOPICKUP, 'm', "nopickup" },
5556 { NHKF_RUN_NOPICKUP, 'M', "run.nopickup" },
5557 { NHKF_DOINV, '0', "doinv" },
5558 { NHKF_TRAVEL, CMD_TRAVEL, (char *) 0 }, /* no binding */
5559 { NHKF_CLICKLOOK, CMD_CLICKLOOK, (char *) 0 }, /* no binding */
5560 { NHKF_REDRAW, C('r'), "redraw" },
5561 { NHKF_REDRAW2, C('l'), "redraw.numpad" },
5562 { NHKF_GETDIR_SELF, '.', "getdir.self" },
5563 { NHKF_GETDIR_SELF2, 's', "getdir.self2" },
5564 { NHKF_GETDIR_HELP, '?', "getdir.help" },
5565 { NHKF_COUNT, 'n', "count" },
5566 { NHKF_GETPOS_SELF, '@', "getpos.self" },
5567 { NHKF_GETPOS_PICK, '.', "getpos.pick" },
5568 { NHKF_GETPOS_PICK_Q, ',', "getpos.pick.quick" },
5569 { NHKF_GETPOS_PICK_O, ';', "getpos.pick.once" },
5570 { NHKF_GETPOS_PICK_V, ':', "getpos.pick.verbose" },
5571 { NHKF_GETPOS_SHOWVALID, '$', "getpos.valid" },
5572 { NHKF_GETPOS_AUTODESC, '#', "getpos.autodescribe" },
5573 { NHKF_GETPOS_MON_NEXT, 'm', "getpos.mon.next" },
5574 { NHKF_GETPOS_MON_PREV, 'M', "getpos.mon.prev" },
5575 { NHKF_GETPOS_OBJ_NEXT, 'o', "getpos.obj.next" },
5576 { NHKF_GETPOS_OBJ_PREV, 'O', "getpos.obj.prev" },
5577 { NHKF_GETPOS_DOOR_NEXT, 'd', "getpos.door.next" },
5578 { NHKF_GETPOS_DOOR_PREV, 'D', "getpos.door.prev" },
5579 { NHKF_GETPOS_UNEX_NEXT, 'x', "getpos.unexplored.next" },
5580 { NHKF_GETPOS_UNEX_PREV, 'X', "getpos.unexplored.prev" },
5581 { NHKF_GETPOS_VALID_NEXT, 'z', "getpos.valid.next" },
5582 { NHKF_GETPOS_VALID_PREV, 'Z', "getpos.valid.prev" },
5583 { NHKF_GETPOS_INTERESTING_NEXT, 'a', "getpos.all.next" },
5584 { NHKF_GETPOS_INTERESTING_PREV, 'A', "getpos.all.prev" },
5585 { NHKF_GETPOS_HELP, '?', "getpos.help" },
5586 { NHKF_GETPOS_LIMITVIEW, '"', "getpos.filter" },
5587 { NHKF_GETPOS_MOVESKIP, '*', "getpos.moveskip" },
5588 { NHKF_GETPOS_MENU, '!', "getpos.menu" }
5592 bind_specialkey(key, command)
5594 const char *command;
5597 for (i = 0; i < SIZE(spkeys_binds); i++) {
5598 if (!spkeys_binds[i].name || strcmp(command, spkeys_binds[i].name))
5600 Cmd.spkeys[spkeys_binds[i].nhkf] = key;
5606 /* returns a one-byte character from the text (it may massacre the txt
5612 txt = trimspaces(txt);
5616 /* simple character */
5620 /* a few special entries */
5621 if (!strcmp(txt, "<enter>"))
5623 if (!strcmp(txt, "<space>"))
5625 if (!strcmp(txt, "<esc>"))
5628 /* control and meta keys */
5630 case 'm': /* can be mx, Mx, m-x, M-x */
5633 if (*txt == '-' && txt[1])
5638 case 'c': /* can be cx, Cx, ^x, c-x, C-x, ^-x */
5642 if (*txt == '-' && txt[1])
5649 /* ascii codes: must be three-digit decimal */
5650 if (*txt >= '0' && *txt <= '9') {
5654 for (i = 0; i < 3; i++) {
5655 if (txt[i] < '0' || txt[i] > '9')
5657 key = 10 * key + txt[i] - '0';
5665 /* returns the text for a one-byte encoding;
5666 * must be shorter than a tab for proper formatting */
5670 char *txt; /* sufficiently long buffer */
5672 /* should probably switch to "SPC", "ESC", "RET"
5673 since nethack's documentation uses ESC for <escape> */
5675 Sprintf(txt, "<space>");
5676 else if (c == '\033')
5677 Sprintf(txt, "<esc>");
5679 Sprintf(txt, "<enter>");
5680 else if (c == '\177')
5681 Sprintf(txt, "<del>"); /* "<delete>" won't fit */
5683 Strcpy(txt, visctrl((char) c));
5689 parseautocomplete(autocomplete, condition)
5693 struct ext_func_tab *efp;
5694 register char *autoc;
5696 /* break off first autocomplete from the rest; parse the rest */
5697 if ((autoc = index(autocomplete, ',')) != 0
5698 || (autoc = index(autocomplete, ':')) != 0) {
5700 parseautocomplete(autoc, condition);
5703 /* strip leading and trailing white space */
5704 autocomplete = trimspaces(autocomplete);
5709 /* take off negation */
5710 if (*autocomplete == '!') {
5711 /* unlike most options, a leading "no" might actually be a part of
5712 * the extended command. Thus you have to use ! */
5714 autocomplete = trimspaces(autocomplete);
5715 condition = !condition;
5718 /* find and modify the extended command */
5719 for (efp = extcmdlist; efp->ef_txt; efp++) {
5720 if (!strcmp(autocomplete, efp->ef_txt)) {
5722 efp->flags |= AUTOCOMPLETE;
5724 efp->flags &= ~AUTOCOMPLETE;
5729 /* not a real extended command */
5730 raw_printf("Bad autocomplete: invalid extended command '%s'.",
5735 /* called at startup and after number_pad is twiddled */
5737 reset_commands(initial)
5740 static const char sdir[] = "hykulnjb><",
5741 sdir_swap_yz[] = "hzkulnjb><",
5742 ndir[] = "47896321><",
5743 ndir_phone_layout[] = "41236987><";
5744 static const int ylist[] = {
5745 'y', 'Y', C('y'), M('y'), M('Y'), M(C('y'))
5747 static struct ext_func_tab *back_dir_cmd[8];
5748 const struct ext_func_tab *cmdtmp;
5750 int c, i, updated = 0;
5751 static boolean backed_dir_cmd = FALSE;
5755 Cmd.num_pad = FALSE;
5756 Cmd.pcHack_compat = Cmd.phone_layout = Cmd.swap_yz = FALSE;
5757 for (i = 0; i < SIZE(spkeys_binds); i++)
5758 Cmd.spkeys[spkeys_binds[i].nhkf] = spkeys_binds[i].key;
5762 if (backed_dir_cmd) {
5763 for (i = 0; i < 8; i++) {
5764 Cmd.commands[(uchar) Cmd.dirchars[i]] = back_dir_cmd[i];
5769 flagtemp = iflags.num_pad;
5770 if (flagtemp != Cmd.num_pad) {
5771 Cmd.num_pad = flagtemp;
5774 /* swap_yz mode (only applicable for !num_pad); intended for
5775 QWERTZ keyboard used in Central Europe, particularly Germany */
5776 flagtemp = (iflags.num_pad_mode & 1) ? !Cmd.num_pad : FALSE;
5777 if (flagtemp != Cmd.swap_yz) {
5778 Cmd.swap_yz = flagtemp;
5780 /* Cmd.swap_yz has been toggled;
5781 perform the swap (or reverse previous one) */
5782 for (i = 0; i < SIZE(ylist); i++) {
5783 c = ylist[i] & 0xff;
5784 cmdtmp = Cmd.commands[c]; /* tmp = [y] */
5785 Cmd.commands[c] = Cmd.commands[c + 1]; /* [y] = [z] */
5786 Cmd.commands[c + 1] = cmdtmp; /* [z] = tmp */
5789 /* MSDOS compatibility mode (only applicable for num_pad) */
5790 flagtemp = (iflags.num_pad_mode & 1) ? Cmd.num_pad : FALSE;
5791 if (flagtemp != Cmd.pcHack_compat) {
5792 Cmd.pcHack_compat = flagtemp;
5794 /* pcHack_compat has been toggled */
5796 cmdtmp = Cmd.commands['5'];
5797 Cmd.commands['5'] = Cmd.commands[c];
5798 Cmd.commands[c] = cmdtmp;
5800 Cmd.commands[c] = Cmd.pcHack_compat ? Cmd.commands['I'] : 0;
5802 /* phone keypad layout (only applicable for num_pad) */
5803 flagtemp = (iflags.num_pad_mode & 2) ? Cmd.num_pad : FALSE;
5804 if (flagtemp != Cmd.phone_layout) {
5805 Cmd.phone_layout = flagtemp;
5807 /* phone_layout has been toggled */
5808 for (i = 0; i < 3; i++) {
5809 c = '1' + i; /* 1,2,3 <-> 7,8,9 */
5810 cmdtmp = Cmd.commands[c]; /* tmp = [1] */
5811 Cmd.commands[c] = Cmd.commands[c + 6]; /* [1] = [7] */
5812 Cmd.commands[c + 6] = cmdtmp; /* [7] = tmp */
5813 c = (M('1') & 0xff) + i; /* M-1,M-2,M-3 <-> M-7,M-8,M-9 */
5814 cmdtmp = Cmd.commands[c]; /* tmp = [M-1] */
5815 Cmd.commands[c] = Cmd.commands[c + 6]; /* [M-1] = [M-7] */
5816 Cmd.commands[c + 6] = cmdtmp; /* [M-7] = tmp */
5823 Cmd.dirchars = !Cmd.num_pad
5824 ? (!Cmd.swap_yz ? sdir : sdir_swap_yz)
5825 : (!Cmd.phone_layout ? ndir : ndir_phone_layout);
5826 Cmd.alphadirchars = !Cmd.num_pad ? Cmd.dirchars : sdir;
5828 Cmd.move_W = Cmd.dirchars[0];
5829 Cmd.move_NW = Cmd.dirchars[1];
5830 Cmd.move_N = Cmd.dirchars[2];
5831 Cmd.move_NE = Cmd.dirchars[3];
5832 Cmd.move_E = Cmd.dirchars[4];
5833 Cmd.move_SE = Cmd.dirchars[5];
5834 Cmd.move_S = Cmd.dirchars[6];
5835 Cmd.move_SW = Cmd.dirchars[7];
5838 for (i = 0; i < 8; i++) {
5840 (struct ext_func_tab *) Cmd.commands[(uchar) Cmd.dirchars[i]];
5841 Cmd.commands[(uchar) Cmd.dirchars[i]] = (struct ext_func_tab *) 0;
5843 backed_dir_cmd = TRUE;
5844 for (i = 0; i < 8; i++)
5845 (void) bind_key(Cmd.dirchars[i], "nothing");
5849 /* non-movement commands which accept 'm' prefix to request menu operation */
5851 accept_menu_prefix(cmd_func)
5852 int NDECL((*cmd_func));
5854 if (cmd_func == dopickup || cmd_func == dotip
5855 /* eat, #offer, and apply tinning-kit all use floorfood() to pick
5856 an item on floor or in invent; 'm' skips picking from floor
5857 (ie, inventory only) rather than request use of menu operation */
5858 || cmd_func == doeat || cmd_func == dosacrifice || cmd_func == doapply
5859 /* 'm' for removing saddle from adjacent monster without checking
5860 for containers at <u.ux,u.uy> */
5861 || cmd_func == doloot
5862 /* travel: pop up a menu of interesting targets in view */
5863 || cmd_func == dotravel
5864 /* wizard mode ^V and ^T */
5865 || cmd_func == wiz_level_tele || cmd_func == dotelecmd
5866 /* 'm' prefix allowed for some extended commands */
5867 || cmd_func == doextcmd || cmd_func == doextlist)
5879 default: c = '\033'; break;
5880 case 0: c = '\n'; break;
5884 case 4: c = (char)(' ' + rn2((int)('~' - ' '))); break;
5885 case 5: c = '\t'; break;
5886 case 6: c = (char)('a' + rn2((int)('z' - 'a'))); break;
5887 case 7: c = (char)('A' + rn2((int)('Z' - 'A'))); break;
5888 case 8: c = extcmdlist[(i++) % SIZE(extcmdlist)].key; break;
5889 case 9: c = '#'; break;
5896 random_response(buf, sz)
5918 rnd_extcmd_idx(VOID_ARGS)
5920 return rn2(extcmdlist_length + 1) - 1;
5924 ch2spkeys(c, start, end)
5930 for (i = start; i <= end; i++)
5931 if (Cmd.spkeys[i] == c)
5941 boolean prefix_seen, bad_command,
5942 firsttime = (cmd == 0);
5944 iflags.menu_requested = FALSE;
5946 if (program_state.done_hup)
5953 if (*cmd == Cmd.spkeys[NHKF_ESC]) {
5954 context.move = FALSE;
5957 if (*cmd == DOAGAIN && !in_doagain && saveq[0]) {
5960 rhack((char *) 0); /* read and execute command */
5964 /* Special case of *cmd == ' ' handled better below */
5965 if (!*cmd || *cmd == (char) 0377) {
5967 context.move = FALSE;
5968 return; /* probably we just had an interrupt */
5971 /* handle most movement commands */
5972 prefix_seen = FALSE;
5973 context.travel = context.travel1 = 0;
5974 spkey = ch2spkeys(*cmd, NHKF_RUN, NHKF_CLICKLOOK);
5978 if (movecmd(cmd[1])) {
5980 domove_attempting |= DOMOVE_RUSH;
5989 if (movecmd(lowc(cmd[1]))) {
5991 domove_attempting |= DOMOVE_RUSH;
5999 /* Effects of movement commands and invisible monsters:
6000 * m: always move onto space (even if 'I' remembered)
6001 * F: always attack space (even if 'I' not remembered)
6002 * normal movement: attack if 'I', move otherwise.
6005 if (movecmd(cmd[1])) {
6006 context.forcefight = 1;
6007 domove_attempting |= DOMOVE_WALK;
6012 if (movecmd(cmd[1]) || u.dz) {
6016 domove_attempting |= DOMOVE_WALK;
6018 cmd[0] = cmd[1]; /* "m<" or "m>" */
6022 case NHKF_RUN_NOPICKUP:
6023 if (movecmd(lowc(cmd[1]))) {
6026 domove_attempting |= DOMOVE_RUSH;
6033 (void) ddoinv(); /* a convenience borrowed from the PC */
6034 context.move = FALSE;
6037 case NHKF_CLICKLOOK:
6038 if (iflags.clicklook) {
6039 context.move = FALSE;
6040 do_look(2, &clicklook_cc);
6044 if (flags.travelcmd) {
6046 context.travel1 = 1;
6049 domove_attempting |= DOMOVE_RUSH;
6054 if (movecmd(*cmd)) { /* ordinary movement */
6055 context.run = 0; /* only matters here if it was 8 */
6056 domove_attempting |= DOMOVE_WALK;
6057 } else if (movecmd(Cmd.num_pad ? unmeta(*cmd) : lowc(*cmd))) {
6059 domove_attempting |= DOMOVE_RUSH;
6060 } else if (movecmd(unctrl(*cmd))) {
6062 domove_attempting |= DOMOVE_RUSH;
6067 /* some special prefix handling */
6068 /* overload 'm' prefix to mean "request a menu" */
6069 if (prefix_seen && cmd[0] == Cmd.spkeys[NHKF_REQMENU]) {
6070 /* (for func_tab cast, see below) */
6071 const struct ext_func_tab *ft = Cmd.commands[cmd[1] & 0xff];
6072 int NDECL((*func)) = ft ? ((struct ext_func_tab *) ft)->ef_funct : 0;
6074 if (func && accept_menu_prefix(func)) {
6075 iflags.menu_requested = TRUE;
6080 if (((domove_attempting & (DOMOVE_RUSH | DOMOVE_WALK)) != 0L)
6081 && !context.travel && !dxdy_moveok()) {
6082 /* trying to move diagonally as a grid bug;
6083 this used to be treated by movecmd() as not being
6084 a movement attempt, but that didn't provide for any
6085 feedback and led to strangeness if the key pressed
6086 ('u' in particular) was overloaded for num_pad use */
6088 You_cant("get there from here...");
6090 You_cant("
\82±
\82±
\82©
\82ç
\82»
\82±
\82Ö
\82Í
\8ds
\82¯
\82Ü
\82¹
\82ñ
\81D
\81D
\81D");
6092 context.nopick = context.forcefight = FALSE;
6093 context.move = context.mv = FALSE;
6098 if ((domove_attempting & DOMOVE_WALK) != 0L) {
6102 context.forcefight = 0;
6104 } else if ((domove_attempting & DOMOVE_RUSH) != 0L) {
6107 multi = max(COLNO, ROWNO);
6108 u.last_str_turn = 0;
6113 } else if (prefix_seen && cmd[1] == Cmd.spkeys[NHKF_ESC]) {
6114 /* <prefix><escape> */
6115 /* don't report "unknown command" for change of heart... */
6116 bad_command = FALSE;
6117 } else if (*cmd == ' ' && !flags.rest_on_space) {
6118 bad_command = TRUE; /* skip cmdlist[] loop */
6120 /* handle all other commands */
6122 register const struct ext_func_tab *tlist;
6123 int res, NDECL((*func));
6125 /* current - use *cmd to directly index cmdlist array */
6126 if ((tlist = Cmd.commands[*cmd & 0xff]) != 0) {
6127 if (!wizard && (tlist->flags & WIZMODECMD)) {
6129 You_cant("do that!");
6131 pline("
\82»
\82ê
\82Í
\82Å
\82«
\82Ü
\82¹
\82ñ
\81I");
6133 } else if (u.uburied && !(tlist->flags & IFBURIED)) {
6135 You_cant("do that while you are buried!");
6137 You("
\96\84\82Ü
\82Á
\82Ä
\82¢
\82é
\8e\9e\82É
\82»
\82ñ
\82È
\82±
\82Æ
\82Í
\82Å
\82«
\82È
\82¢
\81I");
6140 /* we discard 'const' because some compilers seem to have
6141 trouble with the pointer passed to set_occupation() */
6142 func = ((struct ext_func_tab *) tlist)->ef_funct;
6143 if (tlist->f_text && !occupation && multi)
6144 set_occupation(func, tlist->f_text, multi);
6145 res = (*func)(); /* perform the command */
6148 context.move = FALSE;
6153 /* if we reach here, cmd wasn't found in cmdlist[] */
6158 char expcmd[20]; /* we expect 'cmd' to point to 1 or 2 chars */
6159 char c, c1 = cmd[1];
6162 while ((c = *cmd++) != '\0')
6163 Strcat(expcmd, visctrl(c)); /* add 1..4 chars plus terminator */
6166 if (!prefix_seen || !help_dir(c1, spkey, "Invalid direction key!"))
6168 if (!prefix_seen || !help_dir(c1, spkey, "
\96³
\8cø
\82È
\95û
\8cü
\8ew
\92è
\82Å
\82·
\81I"))
6170 Norep("Unknown command '%s'.", expcmd);
6172 Norep("'%s'
\83R
\83}
\83\93\83h
\81H", expcmd);
6175 context.move = FALSE;
6180 /* convert an x,y pair into a direction code */
6187 for (dd = 0; dd < 8; dd++)
6188 if (x == xdir[dd] && y == ydir[dd])
6193 /* convert a direction code into an x,y pair */
6204 /* also sets u.dz, but returns false for <> */
6209 register const char *dp = index(Cmd.dirchars, sym);
6214 u.dx = xdir[dp - Cmd.dirchars];
6215 u.dy = ydir[dp - Cmd.dirchars];
6216 u.dz = zdir[dp - Cmd.dirchars];
6217 #if 0 /* now handled elsewhere */
6218 if (u.dx && u.dy && NODIAG(u.umonnum)) {
6226 /* grid bug handling which used to be in movecmd() */
6230 if (u.dx && u.dy && NODIAG(u.umonnum))
6232 return u.dx || u.dy;
6235 /* decide whether a character (user input keystroke) requests screen repaint */
6240 return (boolean) (c == Cmd.spkeys[NHKF_REDRAW]
6241 || (Cmd.num_pad && c == Cmd.spkeys[NHKF_REDRAW2]));
6248 return (c == Cmd.spkeys[NHKF_RUSH]
6249 || c == Cmd.spkeys[NHKF_RUN]
6250 || c == Cmd.spkeys[NHKF_NOPICKUP]
6251 || c == Cmd.spkeys[NHKF_RUN_NOPICKUP]
6252 || c == Cmd.spkeys[NHKF_FIGHT]
6253 || (Cmd.num_pad && (c == Cmd.spkeys[NHKF_RUN2]
6254 || c == Cmd.spkeys[NHKF_FIGHT2])));
6258 * uses getdir() but unlike getdir() it specifically
6259 * produces coordinates using the direction from getdir()
6260 * and verifies that those coordinates are ok.
6262 * If the call to getdir() returns 0, Never_mind is displayed.
6263 * If the resulting coordinates are not okay, emsg is displayed.
6265 * Returns non-zero if coordinates in cc are valid.
6268 get_adjacent_loc(prompt, emsg, x, y, cc)
6269 const char *prompt, *emsg;
6274 if (!getdir(prompt)) {
6280 if (cc && isok(new_x, new_y)) {
6299 if (in_doagain || *readchar_queue)
6300 dirsym = readchar();
6303 dirsym = yn_function((s && *s != '^') ? s : "In what direction?",
6305 dirsym = yn_function((s && *s != '^') ? s : "
\82Ç
\82Ì
\95û
\8cü
\81H",
6307 /* remove the prompt string so caller won't have to */
6308 clear_nhwindow(WIN_MESSAGE);
6310 if (redraw_cmd(dirsym)) { /* ^R */
6311 docrt(); /* redraw */
6316 if (dirsym == Cmd.spkeys[NHKF_GETDIR_SELF]
6317 || dirsym == Cmd.spkeys[NHKF_GETDIR_SELF2]) {
6318 u.dx = u.dy = u.dz = 0;
6319 } else if (!(is_mov = movecmd(dirsym)) && !u.dz) {
6320 boolean did_help = FALSE, help_requested;
6322 if (!index(quitchars, dirsym)) {
6323 help_requested = (dirsym == Cmd.spkeys[NHKF_GETDIR_HELP]);
6324 if (help_requested || iflags.cmdassist) {
6325 did_help = help_dir((s && *s == '^') ? dirsym : '\0',
6327 help_requested ? (const char *) 0
6329 : "Invalid direction key!");
6331 : "
\96³
\8cø
\82È
\95û
\8cü
\8ew
\92è
\82Å
\82·
\81I");
6337 pline("What a strange direction!");
6339 pline("
\82¸
\82¢
\82Ô
\82ñ
\82Æ
\8aï
\96
\82È
\95û
\8cü
\82¾
\81I");
6342 } else if (is_mov && !dxdy_moveok()) {
6344 You_cant("orient yourself that direction.");
6346 You_cant("
\8cü
\82«
\82É
\8e©
\95ª
\8e©
\90g
\82ð
\8ew
\92è
\82Å
\82«
\82È
\82¢
\81D");
6349 if (!u.dz && (Stunned || (Confusion && !rn2(5))))
6355 show_direction_keys(win, centerchar, nodiag)
6356 winid win; /* should specify a window which is using a fixed-width font... */
6357 char centerchar; /* '.' or '@' or ' ' */
6366 Sprintf(buf, " %c ", Cmd.move_N);
6367 putstr(win, 0, buf);
6368 putstr(win, 0, " | ");
6369 Sprintf(buf, " %c- %c -%c",
6370 Cmd.move_W, centerchar, Cmd.move_E);
6371 putstr(win, 0, buf);
6372 putstr(win, 0, " | ");
6373 Sprintf(buf, " %c ", Cmd.move_S);
6374 putstr(win, 0, buf);
6376 Sprintf(buf, " %c %c %c",
6377 Cmd.move_NW, Cmd.move_N, Cmd.move_NE);
6378 putstr(win, 0, buf);
6379 putstr(win, 0, " \\ | / ");
6380 Sprintf(buf, " %c- %c -%c",
6381 Cmd.move_W, centerchar, Cmd.move_E);
6382 putstr(win, 0, buf);
6383 putstr(win, 0, " / | \\ ");
6384 Sprintf(buf, " %c %c %c",
6385 Cmd.move_SW, Cmd.move_S, Cmd.move_SE);
6386 putstr(win, 0, buf);
6390 /* explain choices if player has asked for getdir() help or has given
6391 an invalid direction after a prefix key ('F', 'g', 'm', &c), which
6392 might be bogus but could be up, down, or self when not applicable */
6394 help_dir(sym, spkey, msg)
6396 int spkey; /* NHKF_ code for prefix key, if one was used, or for ESC */
6399 static const char wiz_only_list[] = "EFGIVW";
6402 char buf[BUFSZ], buf2[BUFSZ], *explain;
6403 const char *dothat, *how;
6404 boolean prefixhandling, viawindow;
6406 /* NHKF_ESC indicates that player asked for help at getdir prompt */
6407 viawindow = (spkey == NHKF_ESC || iflags.cmdassist);
6408 prefixhandling = (spkey != NHKF_ESC);
6410 * Handling for prefix keys that don't want special directions.
6411 * Delivered via pline if 'cmdassist' is off, or instead of the
6412 * general message if it's on.
6415 how = " at"; /* for "<action> at yourself"; not used for up/down */
6428 case NHKF_RUN_NOPICKUP:
6437 how = ""; /* avoid "fight at yourself" */
6440 prefixhandling = FALSE;
6445 /* for movement prefix followed by '.' or (numpad && 's') to mean 'self';
6446 note: '-' for hands (inventory form of 'self') is not handled here */
6448 && (sym == Cmd.spkeys[NHKF_GETDIR_SELF]
6449 || (Cmd.num_pad && sym == Cmd.spkeys[NHKF_GETDIR_SELF2]))) {
6450 Sprintf(buf, "You can't %s%s yourself.", dothat, how);
6451 /* for movement prefix followed by up or down */
6452 } else if (prefixhandling && (sym == '<' || sym == '>')) {
6453 Sprintf(buf, "You can't %s %s.", dothat,
6454 /* was "upwards" and "downwards", but they're considered
6455 to be variants of canonical "upward" and "downward" */
6456 (sym == '<') ? "upward" : "downward");
6459 /* if '!cmdassist', display via pline() and we're done (note: asking
6460 for help at getdir() prompt forces cmdassist for this operation) */
6462 if (prefixhandling) {
6464 Sprintf(buf, "Invalid direction for '%s' prefix.",
6465 visctrl(Cmd.spkeys[spkey]));
6469 /* when 'cmdassist' is off and caller doesn't insist, do nothing */
6473 win = create_nhwindow(NHW_TEXT);
6478 /* show bad-prefix message instead of general invalid-direction one */
6479 putstr(win, 0, buf);
6482 Sprintf(buf, "cmdassist: %s", msg);
6483 putstr(win, 0, buf);
6487 if (!prefixhandling && (letter(sym) || sym == '[')) {
6488 /* '[': old 'cmdhelp' showed ESC as ^[ */
6489 sym = highc(sym); /* @A-Z[ (note: letter() accepts '@') */
6490 ctrl = (sym - 'A') + 1; /* 0-27 (note: 28-31 aren't applicable) */
6491 if ((explain = dowhatdoes_core(ctrl, buf2)) != 0
6492 && (!index(wiz_only_list, sym) || wizard)) {
6493 Sprintf(buf, "Are you trying to use ^%c%s?", sym,
6494 index(wiz_only_list, sym) ? ""
6495 : " as specified in the Guidebook");
6496 putstr(win, 0, buf);
6498 putstr(win, 0, explain);
6501 "To use that command, hold down the <Ctrl> key as a shift");
6502 Sprintf(buf, "and press the <%c> key.", sym);
6503 putstr(win, 0, buf);
6509 Sprintf(buf, "Valid direction keys%s%s%s are:",
6510 prefixhandling ? " to " : "", prefixhandling ? dothat : "",
6511 NODIAG(u.umonnum) ? " in your current form" : "");
6513 Sprintf(buf, "%s%s%s
\82Å
\82Ì
\97L
\8cø
\82È
\95û
\8cü
\8ew
\92è
\82Í:",
6514 prefixhandling ? " to " : "", prefixhandling ? dothat : "",
6515 NODIAG(u.umonnum) ? " in your current form" : "");
6517 putstr(win, 0, buf);
6518 show_direction_keys(win, !prefixhandling ? '.' : ' ', NODIAG(u.umonnum));
6520 if (!prefixhandling || spkey == NHKF_NOPICKUP) {
6521 /* NOPICKUP: unlike the other prefix keys, 'm' allows up/down for
6522 stair traversal; we won't get here when "m<" or "m>" has been
6523 given but we include up and down for 'm'+invalid_direction;
6524 self is excluded as a viable direction for every prefix */
6526 putstr(win, 0, " < up");
6527 putstr(win, 0, " > down");
6528 if (!prefixhandling) {
6529 int selfi = Cmd.num_pad ? NHKF_GETDIR_SELF2 : NHKF_GETDIR_SELF;
6531 Sprintf(buf, " %4s direct at yourself",
6532 visctrl(Cmd.spkeys[selfi]));
6533 putstr(win, 0, buf);
6538 /* non-null msg means that this wasn't an explicit user request */
6542 "(Suppress this message with !cmdassist in config file.)");
6544 "(
\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)");
6546 display_nhwindow(win, FALSE);
6547 destroy_nhwindow(win);
6554 register int x = NODIAG(u.umonnum) ? 2 * rn2(4) : rn2(8);
6565 static NEARDATA const char *const dirnames[] = {
6566 "west", "northwest", "north", "northeast", "east",
6567 "southeast", "south", "southwest", "down", "up",
6570 if (dir < 0 || dir >= SIZE(dirnames))
6572 return dirnames[dir];
6579 /* x corresponds to curx, so x==1 is the first column. Ach. %% */
6580 return x >= 1 && x <= COLNO - 1 && y >= 0 && y <= ROWNO - 1;
6583 /* #herecmdmenu command */
6585 doherecmdmenu(VOID_ARGS)
6587 char ch = here_cmd_menu(TRUE);
6592 /* #therecmdmenu command, a way to test there_cmd_menu without mouse */
6594 dotherecmdmenu(VOID_ARGS)
6598 if (!getdir((const char *) 0) || !isok(u.ux + u.dx, u.uy + u.dy))
6602 ch = there_cmd_menu(TRUE, u.ux + u.dx, u.uy + u.dy);
6604 ch = here_cmd_menu(TRUE);
6610 add_herecmd_menuitem(win, func, text)
6618 if ((ch = cmd_from_func(func)) != '\0') {
6621 add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, text, MENU_UNSELECTED);
6626 there_cmd_menu(doit, x, y)
6633 schar typ = levl[x][y].typ;
6635 menu_item *picks = (menu_item *) 0;
6639 win = create_nhwindow(NHW_MENU);
6643 boolean key_or_pick, card;
6644 int dm = levl[x][y].doormask;
6646 if ((dm & (D_CLOSED | D_LOCKED))) {
6647 add_herecmd_menuitem(win, doopen, "Open the door"), ++K;
6648 /* unfortunately there's no lknown flag for doors to
6649 remember the locked/unlocked state */
6650 key_or_pick = (carrying(SKELETON_KEY) || carrying(LOCK_PICK));
6651 card = (carrying(CREDIT_CARD) != 0);
6652 if (key_or_pick || card) {
6653 Sprintf(buf, "%sunlock the door",
6654 key_or_pick ? "lock or " : "");
6655 add_herecmd_menuitem(win, doapply, upstart(buf)), ++K;
6657 /* unfortunately there's no tknown flag for doors (or chests)
6658 to remember whether a trap had been found */
6659 add_herecmd_menuitem(win, dountrap,
6660 "Search the door for a trap"), ++K;
6661 /* [what about #force?] */
6662 add_herecmd_menuitem(win, dokick, "Kick the door"), ++K;
6663 } else if ((dm & D_ISOPEN)) {
6664 add_herecmd_menuitem(win, doclose, "Close the door"), ++K;
6669 add_herecmd_menuitem(win, dosearch, "Search for secret doors"), ++K;
6671 if ((ttmp = t_at(x, y)) != 0 && ttmp->tseen) {
6672 add_herecmd_menuitem(win, doidtrap, "Examine trap"), ++K;
6673 if (ttmp->ttyp != VIBRATING_SQUARE)
6674 add_herecmd_menuitem(win, dountrap, "Attempt to disarm trap"), ++K;
6678 if (mtmp && !canspotmon(mtmp))
6680 if (mtmp && which_armor(mtmp, W_SADDLE)) {
6681 char *mnam = x_monnam(mtmp, ARTICLE_THE, (char *) 0,
6682 SUPPRESS_SADDLE, FALSE);
6685 Sprintf(buf, "Ride %s", mnam);
6686 add_herecmd_menuitem(win, doride, buf), ++K;
6688 Sprintf(buf, "Remove saddle from %s", mnam);
6689 add_herecmd_menuitem(win, doloot, buf), ++K;
6691 if (mtmp && can_saddle(mtmp) && !which_armor(mtmp, W_SADDLE)
6692 && carrying(SADDLE)) {
6693 Sprintf(buf, "Put saddle on %s", mon_nam(mtmp)), ++K;
6694 add_herecmd_menuitem(win, doapply, buf);
6697 if (mtmp || glyph_is_invisible(glyph_at(x, y))) {
6698 /* "Attack %s", mtmp ? mon_nam(mtmp) : "unseen creature" */
6700 /* "Move %s", direction */
6705 end_menu(win, "What do you want to do?");
6706 npick = select_menu(win, PICK_ONE, &picks);
6708 pline("No applicable actions.");
6711 destroy_nhwindow(win);
6714 int NDECL((*func)) = picks->item.a_nfunc;
6715 free((genericptr_t) picks);
6718 int ret = (*func)();
6722 ch = cmd_from_func(func);
6735 schar typ = levl[u.ux][u.uy].typ;
6737 menu_item *picks = (menu_item *) 0;
6739 win = create_nhwindow(NHW_MENU);
6742 if (IS_FOUNTAIN(typ) || IS_SINK(typ)) {
6743 Sprintf(buf, "Drink from the %s",
6744 defsyms[IS_FOUNTAIN(typ) ? S_fountain : S_sink].explanation);
6745 add_herecmd_menuitem(win, dodrink, buf);
6747 if (IS_FOUNTAIN(typ))
6748 add_herecmd_menuitem(win, dodip,
6749 "Dip something into the fountain");
6751 add_herecmd_menuitem(win, dosit,
6752 "Sit on the throne");
6754 if ((u.ux == xupstair && u.uy == yupstair)
6755 || (u.ux == sstairs.sx && u.uy == sstairs.sy && sstairs.up)
6756 || (u.ux == xupladder && u.uy == yupladder)) {
6757 Sprintf(buf, "Go up the %s",
6758 (u.ux == xupladder && u.uy == yupladder)
6759 ? "ladder" : "stairs");
6760 add_herecmd_menuitem(win, doup, buf);
6762 if ((u.ux == xdnstair && u.uy == ydnstair)
6763 || (u.ux == sstairs.sx && u.uy == sstairs.sy && !sstairs.up)
6764 || (u.ux == xdnladder && u.uy == ydnladder)) {
6765 Sprintf(buf, "Go down the %s",
6766 (u.ux == xupladder && u.uy == yupladder)
6767 ? "ladder" : "stairs");
6768 add_herecmd_menuitem(win, dodown, buf);
6770 if (u.usteed) { /* another movement choice */
6771 Sprintf(buf, "Dismount %s",
6772 x_monnam(u.usteed, ARTICLE_THE, (char *) 0,
6773 SUPPRESS_SADDLE, FALSE));
6774 add_herecmd_menuitem(win, doride, buf);
6778 if (Upolyd) { /* before objects */
6779 Sprintf(buf, "Use %s special ability",
6780 s_suffix(mons[u.umonnum].mname));
6781 add_herecmd_menuitem(win, domonability, buf);
6785 if (OBJ_AT(u.ux, u.uy)) {
6786 struct obj *otmp = level.objects[u.ux][u.uy];
6788 Sprintf(buf, "Pick up %s", otmp->nexthere ? "items" : doname(otmp));
6789 add_herecmd_menuitem(win, dopickup, buf);
6791 if (Is_container(otmp)) {
6792 Sprintf(buf, "Loot %s", doname(otmp));
6793 add_herecmd_menuitem(win, doloot, buf);
6795 if (otmp->oclass == FOOD_CLASS) {
6796 Sprintf(buf, "Eat %s", doname(otmp));
6797 add_herecmd_menuitem(win, doeat, buf);
6802 add_herecmd_menuitem(win, dodrop, "Drop items");
6804 add_herecmd_menuitem(win, donull, "Rest one turn");
6805 add_herecmd_menuitem(win, dosearch, "Search around you");
6806 add_herecmd_menuitem(win, dolook, "Look at what is here");
6808 end_menu(win, "What do you want to do?");
6809 npick = select_menu(win, PICK_ONE, &picks);
6810 destroy_nhwindow(win);
6813 int NDECL((*func)) = picks->item.a_nfunc;
6814 free((genericptr_t) picks);
6817 int ret = (*func)();
6821 ch = cmd_from_func(func);
6828 static NEARDATA int last_multi;
6831 * convert a MAP window position into a movecmd
6834 click_to_cmd(x, y, mod)
6841 if (iflags.clicklook && mod == CLICK_2) {
6844 cmd[0] = Cmd.spkeys[NHKF_CLICKLOOK];
6851 if (flags.travelcmd) {
6852 if (abs(x) <= 1 && abs(y) <= 1) {
6853 x = sgn(x), y = sgn(y);
6857 cmd[0] = Cmd.spkeys[NHKF_TRAVEL];
6861 if (x == 0 && y == 0) {
6862 if (iflags.herecmd_menu) {
6863 cmd[0] = here_cmd_menu(FALSE);
6868 if (IS_FOUNTAIN(levl[u.ux][u.uy].typ)
6869 || IS_SINK(levl[u.ux][u.uy].typ)) {
6870 cmd[0] = cmd_from_func(mod == CLICK_1 ? dodrink : dodip);
6872 } else if (IS_THRONE(levl[u.ux][u.uy].typ)) {
6873 cmd[0] = cmd_from_func(dosit);
6875 } else if ((u.ux == xupstair && u.uy == yupstair)
6876 || (u.ux == sstairs.sx && u.uy == sstairs.sy
6878 || (u.ux == xupladder && u.uy == yupladder)) {
6879 cmd[0] = cmd_from_func(doup);
6881 } else if ((u.ux == xdnstair && u.uy == ydnstair)
6882 || (u.ux == sstairs.sx && u.uy == sstairs.sy
6884 || (u.ux == xdnladder && u.uy == ydnladder)) {
6885 cmd[0] = cmd_from_func(dodown);
6887 } else if (OBJ_AT(u.ux, u.uy)) {
6888 cmd[0] = cmd_from_func(Is_container(level.objects[u.ux][u.uy])
6889 ? doloot : dopickup);
6892 cmd[0] = cmd_from_func(donull); /* just rest */
6897 /* directional commands */
6901 if (!m_at(u.ux + x, u.uy + y)
6902 && !test_move(u.ux, u.uy, x, y, TEST_MOVE)) {
6903 cmd[1] = Cmd.dirchars[dir];
6905 if (iflags.herecmd_menu) {
6906 cmd[0] = there_cmd_menu(FALSE, u.ux + x, u.uy + y);
6912 if (IS_DOOR(levl[u.ux + x][u.uy + y].typ)) {
6913 /* slight assistance to the player: choose kick/open for them
6915 if (levl[u.ux + x][u.uy + y].doormask & D_LOCKED) {
6916 cmd[0] = cmd_from_func(dokick);
6919 if (levl[u.ux + x][u.uy + y].doormask & D_CLOSED) {
6920 cmd[0] = cmd_from_func(doopen);
6924 if (levl[u.ux + x][u.uy + y].typ <= SCORR) {
6925 cmd[0] = cmd_from_func(dosearch);
6931 /* convert without using floating point, allowing sloppy clicking */
6934 else if (y > 2 * abs(x))
6936 else if (x < -2 * abs(y))
6938 else if (y < -2 * abs(x))
6941 x = sgn(x), y = sgn(y);
6943 if (x == 0 && y == 0) {
6944 /* map click on player to "rest" command */
6945 cmd[0] = cmd_from_func(donull);
6951 /* move, attack, etc. */
6953 if (mod == CLICK_1) {
6954 cmd[0] = Cmd.dirchars[dir];
6956 cmd[0] = (Cmd.num_pad
6957 ? M(Cmd.dirchars[dir])
6958 : (Cmd.dirchars[dir] - 'a' + 'A')); /* run command */
6965 get_count(allowchars, inkey, maxcount, count, historical)
6970 boolean historical; /* whether to include in message history: True => yes */
6975 boolean backspaced = FALSE;
6976 /* this should be done in port code so that we have erase_char
6977 and kill_char available; we can at least fake erase_char */
6978 #define STANDBY_erase_char '\177'
6988 cnt = 10L * cnt + (long) (key - '0');
6991 else if (maxcount > 0 && cnt > maxcount)
6993 } else if (cnt && (key == '\b' || key == STANDBY_erase_char)) {
6996 } else if (key == Cmd.spkeys[NHKF_ESC]) {
6998 } else if (!allowchars || index(allowchars, key)) {
7003 if (cnt > 9 || backspaced) {
7004 clear_nhwindow(WIN_MESSAGE);
7005 if (backspaced && !cnt) {
7007 Sprintf(qbuf, "Count: ");
7009 Sprintf(qbuf, "
\90\94: ");
7012 Sprintf(qbuf, "Count: %ld", cnt);
7014 Sprintf(qbuf, "
\90\94: %ld", cnt);
7017 custompline(SUPPRESS_HISTORY, "%s", qbuf);
7024 Sprintf(qbuf, "Count: %ld ", *count);
7026 Sprintf(qbuf, "
\90\94: %ld ", *count);
7027 (void) key2txt((uchar) key, eos(qbuf));
7028 putmsghistory(qbuf, FALSE);
7038 #ifdef LINT /* static char in_line[COLNO]; */
7039 char in_line[COLNO];
7041 static char in_line[COLNO];
7045 iflags.in_parse = TRUE;
7048 flush_screen(1); /* Flush screen buffer. Put the cursor on the hero. */
7051 alt_esc = iflags.altmeta; /* readchar() hack */
7053 if (!Cmd.num_pad || (foo = readchar()) == Cmd.spkeys[NHKF_COUNT]) {
7054 long tmpmulti = multi;
7056 foo = get_count((char *) 0, '\0', LARGEST_INT, &tmpmulti, FALSE);
7057 last_multi = multi = tmpmulti;
7060 alt_esc = FALSE; /* readchar() reset */
7063 if (iflags.debug_fuzzer /* if fuzzing, override '!' and ^Z */
7064 && (Cmd.commands[foo & 0x0ff]
7065 && (Cmd.commands[foo & 0x0ff]->ef_funct == dosuspend_core
7066 || Cmd.commands[foo & 0x0ff]->ef_funct == dosh_core)))
7067 foo = Cmd.spkeys[NHKF_ESC];
7069 if (foo == Cmd.spkeys[NHKF_ESC]) { /* esc cancels count (TH) */
7070 clear_nhwindow(WIN_MESSAGE);
7071 multi = last_multi = 0;
7072 } else if (foo == Cmd.spkeys[NHKF_DOAGAIN] || in_doagain) {
7076 savech(0); /* reset input queue */
7084 save_cm = (char *) 0;
7086 /* in 3.4.3 this was in rhack(), where it was too late to handle M-5 */
7087 if (Cmd.pcHack_compat) {
7088 /* This handles very old inconsistent DOS/Windows behaviour
7089 in a different way: earlier, the keyboard handler mapped
7090 these, which caused counts to be strange when entered
7091 from the number pad. Now do not map them until here. */
7094 foo = Cmd.spkeys[NHKF_RUSH];
7097 foo = Cmd.spkeys[NHKF_RUN];
7100 foo = Cmd.spkeys[NHKF_DOINV];
7109 if (prefix_cmd(foo)) {
7115 clear_nhwindow(WIN_MESSAGE);
7117 iflags.in_parse = FALSE;
7121 #ifdef HANGUPHANDLING
7122 /* some very old systems, or descendents of such systems, expect signal
7123 handlers to have return type `int', but they don't actually inspect
7124 the return value so we should be safe using `void' unconditionally */
7127 hangup(sig_unused) /* called as signal() handler, so sent at least one arg */
7128 int sig_unused UNUSED;
7130 if (program_state.exiting)
7131 program_state.in_moveloop = 0;
7134 /* When using SAFERHANGUP, the done_hup flag it tested in rhack
7135 and a couple of other places; actual hangup handling occurs then.
7136 This is 'safer' because it disallows certain cheats and also
7137 protects against losing objects in the process of being thrown,
7138 but also potentially riskier because the disconnected program
7139 must continue running longer before attempting a hangup save. */
7140 program_state.done_hup++;
7141 /* defer hangup iff game appears to be in progress */
7142 if (program_state.in_moveloop && program_state.something_worth_saving)
7144 #endif /* SAFERHANGUP */
7151 #ifdef NOSAVEONHANGUP
7153 if (flags.ins_chkpt && program_state.something_worth_saving)
7154 program_statue.preserve_locks = 1; /* keep files for recovery */
7156 program_state.something_worth_saving = 0; /* don't save */
7160 if (!program_state.done_hup++)
7162 if (program_state.something_worth_saving)
7164 if (iflags.window_inited)
7165 exit_nhwindows((char *) 0);
7167 nh_terminate(EXIT_SUCCESS);
7168 /*NOTREACHED*/ /* not necessarily true for vms... */
7171 #endif /* HANGUPHANDLING */
7177 int x = u.ux, y = u.uy, mod = 0;
7179 if (iflags.debug_fuzzer)
7181 if (*readchar_queue)
7182 sym = *readchar_queue++;
7184 sym = in_doagain ? pgetchar() : nh_poskey(&x, &y, &mod);
7188 register int cnt = NR_OF_EOFS;
7190 * Some SYSV systems seem to return EOFs for various reasons
7191 * (?like when one hits break or for interrupted systemcalls?),
7192 * and we must see several before we quit.
7195 clearerr(stdin); /* omit if clearerr is undefined */
7197 } while (--cnt && sym == EOF);
7199 #endif /* NR_OF_EOFS */
7202 #ifdef HANGUPHANDLING
7203 hangup(0); /* call end_of_input() or set program_state.done_hup */
7207 } else if (sym == '\033' && alt_esc) {
7208 /* iflags.altmeta: treat two character ``ESC c'' as single `M-c' */
7209 sym = *readchar_queue ? *readchar_queue++ : pgetchar();
7210 if (sym == EOF || sym == 0)
7212 else if (sym != '\033')
7213 sym |= 0200; /* force 8th bit on */
7215 } else if (sym == 0) {
7217 readchar_queue = click_to_cmd(x, y, mod);
7218 sym = *readchar_queue++;
7223 /* '_' command, #travel, via keyboard rather than mouse click */
7230 /* [FIXME? Supporting the ability to disable traveling via mouse
7231 click makes some sense, depending upon overall mouse usage.
7232 Disabling '_' on a user by user basis makes no sense at all since
7233 even if it is typed by accident, aborting when picking a target
7234 destination is trivial. Travel via mouse predates travel via '_',
7235 and this use of OPTION=!travel is probably just a mistake....] */
7236 if (!flags.travelcmd)
7240 cc.x = iflags.travelcc.x;
7241 cc.y = iflags.travelcc.y;
7242 if (cc.x == 0 && cc.y == 0) {
7243 /* No cached destination, start attempt from current position */
7247 iflags.getloc_travelmode = TRUE;
7248 if (iflags.menu_requested) {
7249 int gf = iflags.getloc_filter;
7250 iflags.getloc_filter = GFILTER_VIEW;
7251 if (!getpos_menu(&cc, GLOC_INTERESTING)) {
7252 iflags.getloc_filter = gf;
7253 iflags.getloc_travelmode = FALSE;
7256 iflags.getloc_filter = gf;
7259 pline("Where do you want to travel to?");
7261 pline("
\82Ç
\82±
\82É
\88Ú
\93®
\82·
\82é
\81H");
7263 if (getpos(&cc, TRUE, "the desired destination") < 0) {
7265 if (getpos(&cc, TRUE, "
\88Ú
\93®
\90æ") < 0) {
7266 /* user pressed ESC */
7267 iflags.getloc_travelmode = FALSE;
7271 iflags.getloc_travelmode = FALSE;
7272 iflags.travelcc.x = u.tx = cc.x;
7273 iflags.travelcc.y = u.ty = cc.y;
7274 cmd[0] = Cmd.spkeys[NHKF_TRAVEL];
7275 readchar_queue = cmd;
7280 * Parameter validator for generic yes/no function to prevent
7281 * the core from sending too long a prompt string to the
7282 * window port causing a buffer overflow there.
7285 yn_function(query, resp, def)
7286 const char *query, *resp;
7289 char res, qbuf[QBUFSZ];
7291 extern unsigned saved_pline_index; /* pline.c */
7292 unsigned idx = saved_pline_index;
7293 /* buffer to hold query+space+formatted_single_char_response */
7294 char dumplog_buf[QBUFSZ + 1 + 15]; /* [QBUFSZ+1+7] should suffice */
7297 iflags.last_msg = PLNMSG_UNKNOWN; /* most recent pline is clobbered */
7299 /* maximum acceptable length is QBUFSZ-1 */
7300 if (strlen(query) >= QBUFSZ) {
7301 /* caller shouldn't have passed anything this long */
7302 paniclog("Query truncated: ", query);
7303 (void) strncpy(qbuf, query, QBUFSZ - 1 - 3);
7304 Strcpy(&qbuf[QBUFSZ - 1 - 3], "...");
7307 res = (*windowprocs.win_yn_function)(query, resp, def);
7309 if (idx == saved_pline_index) {
7310 /* when idx is still the same as saved_pline_index, the interface
7311 didn't put the prompt into saved_plines[]; we put a simplified
7312 version in there now (without response choices or default) */
7313 Sprintf(dumplog_buf, "%s ", query);
7314 (void) key2txt((uchar) res, eos(dumplog_buf));
7315 dumplogmsg(dumplog_buf);
7321 /* for paranoid_confirm:quit,die,attack prompting */
7323 paranoid_query(be_paranoid, prompt)
7324 boolean be_paranoid;
7327 boolean confirmed_ok;
7329 /* when paranoid, player must respond with "yes" rather than just 'y'
7330 to give the go-ahead for this query; default is "no" unless the
7331 ParanoidConfirm flag is set in which case there's no default */
7333 char qbuf[QBUFSZ], ans[BUFSZ] = DUMMY;
7334 const char *promptprefix = "", *responsetype = ParanoidConfirm
7337 int trylimit = 6; /* 1 normal, 5 more with "Yes or No:" prefix */
7339 /* in addition to being paranoid about this particular
7340 query, we might be even more paranoid about all paranoia
7341 responses (ie, ParanoidConfirm is set) in which case we
7342 require "no" to reject in addition to "yes" to confirm
7343 (except we won't loop if response is ESC; it means no) */
7345 Sprintf(qbuf, "%s%s %s", promptprefix, prompt, responsetype);
7347 (void) mungspaces(ans);
7348 confirmed_ok = !strcmpi(ans, "yes");
7349 if (confirmed_ok || *ans == '\033')
7351 promptprefix = "\"Yes\" or \"No\": ";
7352 } while (ParanoidConfirm && strcmpi(ans, "no") && --trylimit);
7354 confirmed_ok = (yn(prompt) == 'y');
7356 return confirmed_ok;
7359 /* ^Z command, #suspend */
7361 dosuspend_core(VOID_ARGS)
7364 /* Does current window system support suspend? */
7365 if ((*windowprocs.win_can_suspend)()) {
7366 /* NB: SYSCF SHELLERS handled in port code. */
7370 Norep(cmdnotavail, "#suspend");
7374 /* '!' command, #shell */
7376 dosh_core(VOID_ARGS)
7379 /* access restrictions, if any, are handled in port code */
7382 Norep(cmdnotavail, "#shell");