OSDN Git Service

dace38de3ab8d86b47376809e38be2455d6ee18e
[jnethack/source.git] / src / cmd.c
1 /* NetHack 3.6  cmd.c   $NHDT-Date: 1575245052 2019/12/02 00:04:12 $  $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.350 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /*-Copyright (c) Robert Patrick Rankin, 2013. */
4 /* NetHack may be freely redistributed.  See license for details. */
5
6 /* JNetHack Copyright */
7 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000  */
8 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2020            */
9 /* JNetHack may be freely redistributed.  See license for details. */
10
11 #include "hack.h"
12 #include "lev.h"
13 #include "func_tab.h"
14
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
18  */
19 #ifndef M
20 #ifndef NHSTDC
21 #define M(c) (0x80 | (c))
22 #else
23 #define M(c) ((c) - 128)
24 #endif /* NHSTDC */
25 #endif
26
27 #ifndef C
28 #define C(c) (0x1f & (c))
29 #endif
30
31 #define unctrl(c) ((c) <= C('z') ? (0x60 | (c)) : (c))
32 #define unmeta(c) (0x7f & (c))
33
34 #ifdef ALTMETA
35 STATIC_VAR boolean alt_esc = FALSE;
36 #endif
37
38 struct cmd Cmd = { 0 }; /* flag.h */
39
40 extern const char *hu_stat[];  /* hunger status from eat.c */
41 extern const char *enc_stat[]; /* encumbrance status from botl.c */
42
43 #ifdef UNIX
44 /*
45  * Some systems may have getchar() return EOF for various reasons, and
46  * we should not quit before seeing at least NR_OF_EOFS consecutive EOFs.
47  */
48 #if defined(SYSV) || defined(DGUX) || defined(HPUX)
49 #define NR_OF_EOFS 20
50 #endif
51 #endif
52
53 #define CMD_TRAVEL (char) 0x90
54 #define CMD_CLICKLOOK (char) 0x8F
55
56 #ifdef DEBUG
57 extern int NDECL(wiz_debug_cmd_bury);
58 #endif
59
60 #ifdef DUMB /* stuff commented out in extern.h, but needed here */
61 extern int NDECL(doapply);            /**/
62 extern int NDECL(dorub);              /**/
63 extern int NDECL(dojump);             /**/
64 extern int NDECL(doextlist);          /**/
65 extern int NDECL(enter_explore_mode); /**/
66 extern int NDECL(dodrop);             /**/
67 extern int NDECL(doddrop);            /**/
68 extern int NDECL(dodown);             /**/
69 extern int NDECL(doup);               /**/
70 extern int NDECL(donull);             /**/
71 extern int NDECL(dowipe);             /**/
72 extern int NDECL(docallcnd);          /**/
73 extern int NDECL(dotakeoff);          /**/
74 extern int NDECL(doremring);          /**/
75 extern int NDECL(dowear);             /**/
76 extern int NDECL(doputon);            /**/
77 extern int NDECL(doddoremarm);        /**/
78 extern int NDECL(dokick);             /**/
79 extern int NDECL(dofire);             /**/
80 extern int NDECL(dothrow);            /**/
81 extern int NDECL(doeat);              /**/
82 extern int NDECL(done2);              /**/
83 extern int NDECL(vanquished);         /**/
84 extern int NDECL(doengrave);          /**/
85 extern int NDECL(dopickup);           /**/
86 extern int NDECL(ddoinv);             /**/
87 extern int NDECL(dotypeinv);          /**/
88 extern int NDECL(dolook);             /**/
89 extern int NDECL(doprgold);           /**/
90 extern int NDECL(doprwep);            /**/
91 extern int NDECL(doprarm);            /**/
92 extern int NDECL(doprring);           /**/
93 extern int NDECL(dopramulet);         /**/
94 extern int NDECL(doprtool);           /**/
95 extern int NDECL(dosuspend);          /**/
96 extern int NDECL(doforce);            /**/
97 extern int NDECL(doopen);             /**/
98 extern int NDECL(doclose);            /**/
99 extern int NDECL(dosh);               /**/
100 extern int NDECL(dodiscovered);       /**/
101 extern int NDECL(doclassdisco);       /**/
102 extern int NDECL(doset);              /**/
103 extern int NDECL(dotogglepickup);     /**/
104 extern int NDECL(dowhatis);           /**/
105 extern int NDECL(doquickwhatis);      /**/
106 extern int NDECL(dowhatdoes);         /**/
107 extern int NDECL(dohelp);             /**/
108 extern int NDECL(dohistory);          /**/
109 extern int NDECL(doloot);             /**/
110 extern int NDECL(dodrink);            /**/
111 extern int NDECL(dodip);              /**/
112 extern int NDECL(dosacrifice);        /**/
113 extern int NDECL(dopray);             /**/
114 extern int NDECL(dotip);              /**/
115 extern int NDECL(doturn);             /**/
116 extern int NDECL(doredraw);           /**/
117 extern int NDECL(doread);             /**/
118 extern int NDECL(dosave);             /**/
119 extern int NDECL(dosearch);           /**/
120 extern int NDECL(doidtrap);           /**/
121 extern int NDECL(dopay);              /**/
122 extern int NDECL(dosit);              /**/
123 extern int NDECL(dotalk);             /**/
124 extern int NDECL(docast);             /**/
125 extern int NDECL(dovspell);           /**/
126 extern int NDECL(dotelecmd);          /**/
127 extern int NDECL(dountrap);           /**/
128 extern int NDECL(doversion);          /**/
129 extern int NDECL(doextversion);       /**/
130 extern int NDECL(doswapweapon);       /**/
131 extern int NDECL(dowield);            /**/
132 extern int NDECL(dowieldquiver);      /**/
133 extern int NDECL(dozap);              /**/
134 extern int NDECL(doorganize);         /**/
135 #endif /* DUMB */
136
137 static int NDECL((*timed_occ_fn));
138
139 STATIC_PTR int NDECL(dosuspend_core);
140 STATIC_PTR int NDECL(dosh_core);
141 STATIC_PTR int NDECL(doherecmdmenu);
142 STATIC_PTR int NDECL(dotherecmdmenu);
143 STATIC_PTR int NDECL(doprev_message);
144 STATIC_PTR int NDECL(timed_occupation);
145 STATIC_PTR int NDECL(doextcmd);
146 STATIC_PTR int NDECL(dotravel);
147 STATIC_PTR int NDECL(doterrain);
148 STATIC_PTR int NDECL(wiz_wish);
149 STATIC_PTR int NDECL(wiz_identify);
150 STATIC_PTR int NDECL(wiz_intrinsic);
151 STATIC_PTR int NDECL(wiz_map);
152 STATIC_PTR int NDECL(wiz_makemap);
153 STATIC_PTR int NDECL(wiz_genesis);
154 STATIC_PTR int NDECL(wiz_where);
155 STATIC_PTR int NDECL(wiz_detect);
156 STATIC_PTR int NDECL(wiz_panic);
157 STATIC_PTR int NDECL(wiz_polyself);
158 STATIC_PTR int NDECL(wiz_level_tele);
159 STATIC_PTR int NDECL(wiz_level_change);
160 STATIC_PTR int NDECL(wiz_show_seenv);
161 STATIC_PTR int NDECL(wiz_show_vision);
162 STATIC_PTR int NDECL(wiz_smell);
163 STATIC_PTR int NDECL(wiz_show_wmodes);
164 STATIC_DCL void NDECL(wiz_map_levltyp);
165 STATIC_DCL void NDECL(wiz_levltyp_legend);
166 #if defined(__BORLANDC__) && !defined(_WIN32)
167 extern void FDECL(show_borlandc_stats, (winid));
168 #endif
169 #ifdef DEBUG_MIGRATING_MONS
170 STATIC_PTR int NDECL(wiz_migrate_mons);
171 #endif
172 STATIC_DCL int FDECL(size_monst, (struct monst *, BOOLEAN_P));
173 STATIC_DCL int FDECL(size_obj, (struct obj *));
174 STATIC_DCL void FDECL(count_obj, (struct obj *, long *, long *,
175                                   BOOLEAN_P, BOOLEAN_P));
176 STATIC_DCL void FDECL(obj_chain, (winid, const char *, struct obj *,
177                                   BOOLEAN_P, long *, long *));
178 STATIC_DCL void FDECL(mon_invent_chain, (winid, const char *, struct monst *,
179                                          long *, long *));
180 STATIC_DCL void FDECL(mon_chain, (winid, const char *, struct monst *,
181                                   BOOLEAN_P, long *, long *));
182 STATIC_DCL void FDECL(contained_stats, (winid, const char *, long *, long *));
183 STATIC_DCL void FDECL(misc_stats, (winid, long *, long *));
184 STATIC_PTR int NDECL(wiz_show_stats);
185 STATIC_DCL boolean FDECL(accept_menu_prefix, (int NDECL((*))));
186 STATIC_PTR int NDECL(wiz_rumor_check);
187 STATIC_PTR int NDECL(doattributes);
188
189 STATIC_DCL void FDECL(enlght_out, (const char *));
190 STATIC_DCL void FDECL(enlght_line, (const char *, const char *, const char *,
191                                     const char *));
192 STATIC_DCL char *FDECL(enlght_combatinc, (const char *, int, int, char *));
193 STATIC_DCL void FDECL(enlght_halfdmg, (int, int));
194 STATIC_DCL boolean NDECL(walking_on_water);
195 STATIC_DCL boolean FDECL(cause_known, (int));
196 STATIC_DCL char *FDECL(attrval, (int, int, char *));
197 STATIC_DCL void FDECL(background_enlightenment, (int, int));
198 STATIC_DCL void FDECL(basics_enlightenment, (int, int));
199 STATIC_DCL void FDECL(characteristics_enlightenment, (int, int));
200 STATIC_DCL void FDECL(one_characteristic, (int, int, int));
201 STATIC_DCL void FDECL(status_enlightenment, (int, int));
202 STATIC_DCL void FDECL(attributes_enlightenment, (int, int));
203
204 STATIC_DCL void FDECL(add_herecmd_menuitem, (winid, int NDECL((*)),
205                                              const char *));
206 STATIC_DCL char FDECL(here_cmd_menu, (BOOLEAN_P));
207 STATIC_DCL char FDECL(there_cmd_menu, (BOOLEAN_P, int, int));
208 STATIC_DCL char *NDECL(parse);
209 STATIC_DCL void FDECL(show_direction_keys, (winid, CHAR_P, BOOLEAN_P));
210 STATIC_DCL boolean FDECL(help_dir, (CHAR_P, int, const char *));
211
212 static const char *readchar_queue = "";
213 static coord clicklook_cc;
214 /* for rejecting attempts to use wizard mode commands */
215 /*JP
216 static const char unavailcmd[] = "Unavailable command '%s'.";
217 */
218 static const char unavailcmd[] = "'%s'\83R\83}\83\93\83h\82Í\8eg\82¦\82È\82¢\81D";
219 /* for rejecting #if !SHELL, !SUSPEND */
220 /*JP
221 static const char cmdnotavail[] = "'%s' command not available.";
222 */
223 static const char cmdnotavail[] = "'%s'\83R\83}\83\93\83h\82Í\97\98\97p\82Å\82«\82Ü\82¹\82ñ\81D";
224
225 STATIC_PTR int
226 doprev_message(VOID_ARGS)
227 {
228     return nh_doprev_message();
229 }
230
231 /* Count down by decrementing multi */
232 STATIC_PTR int
233 timed_occupation(VOID_ARGS)
234 {
235     (*timed_occ_fn)();
236     if (multi > 0)
237         multi--;
238     return multi > 0;
239 }
240
241 /* If you have moved since initially setting some occupations, they
242  * now shouldn't be able to restart.
243  *
244  * The basic rule is that if you are carrying it, you can continue
245  * since it is with you.  If you are acting on something at a distance,
246  * your orientation to it must have changed when you moved.
247  *
248  * The exception to this is taking off items, since they can be taken
249  * off in a number of ways in the intervening time, screwing up ordering.
250  *
251  *      Currently:      Take off all armor.
252  *                      Picking Locks / Forcing Chests.
253  *                      Setting traps.
254  */
255 void
256 reset_occupations()
257 {
258     reset_remarm();
259     reset_pick();
260     reset_trapset();
261 }
262
263 /* If a time is given, use it to timeout this function, otherwise the
264  * function times out by its own means.
265  */
266 void
267 set_occupation(fn, txt, xtime)
268 int NDECL((*fn));
269 const char *txt;
270 int xtime;
271 {
272     if (xtime) {
273         occupation = timed_occupation;
274         timed_occ_fn = fn;
275     } else
276         occupation = fn;
277     occtxt = txt;
278     occtime = 0;
279     return;
280 }
281
282 STATIC_DCL char NDECL(popch);
283
284 /* Provide a means to redo the last command.  The flag `in_doagain' is set
285  * to true while redoing the command.  This flag is tested in commands that
286  * require additional input (like `throw' which requires a thing and a
287  * direction), and the input prompt is not shown.  Also, while in_doagain is
288  * TRUE, no keystrokes can be saved into the saveq.
289  */
290 #define BSIZE 20
291 static char pushq[BSIZE], saveq[BSIZE];
292 static NEARDATA int phead, ptail, shead, stail;
293
294 STATIC_OVL char
295 popch()
296 {
297     /* If occupied, return '\0', letting tgetch know a character should
298      * be read from the keyboard.  If the character read is not the
299      * ABORT character (as checked in pcmain.c), that character will be
300      * pushed back on the pushq.
301      */
302     if (occupation)
303         return '\0';
304     if (in_doagain)
305         return (char) ((shead != stail) ? saveq[stail++] : '\0');
306     else
307         return (char) ((phead != ptail) ? pushq[ptail++] : '\0');
308 }
309
310 char
311 pgetchar() /* courtesy of aeb@cwi.nl */
312 {
313     register int ch;
314
315     if (iflags.debug_fuzzer)
316         return randomkey();
317     if (!(ch = popch()))
318         ch = nhgetch();
319     return (char) ch;
320 }
321
322 /* A ch == 0 resets the pushq */
323 void
324 pushch(ch)
325 char ch;
326 {
327     if (!ch)
328         phead = ptail = 0;
329     if (phead < BSIZE)
330         pushq[phead++] = ch;
331     return;
332 }
333
334 /* A ch == 0 resets the saveq.  Only save keystrokes when not
335  * replaying a previous command.
336  */
337 void
338 savech(ch)
339 char ch;
340 {
341     if (!in_doagain) {
342         if (!ch)
343             phead = ptail = shead = stail = 0;
344         else if (shead < BSIZE)
345             saveq[shead++] = ch;
346     }
347     return;
348 }
349
350 /* here after # - now read a full-word command */
351 STATIC_PTR int
352 doextcmd(VOID_ARGS)
353 {
354     int idx, retval;
355     int NDECL((*func));
356
357     /* keep repeating until we don't run help or quit */
358     do {
359         idx = get_ext_cmd();
360         if (idx < 0)
361             return 0; /* quit */
362
363         func = extcmdlist[idx].ef_funct;
364         if (!wizard && (extcmdlist[idx].flags & WIZMODECMD)) {
365 /*JP
366             You("can't do that.");
367 */
368             pline("\82»\82ê\82Í\82Å\82«\82Ü\82¹\82ñ\81D");
369             return 0;
370         }
371         if (iflags.menu_requested && !accept_menu_prefix(func)) {
372 #if 0 /*JP:T*/
373             pline("'%s' prefix has no effect for the %s command.",
374                   visctrl(Cmd.spkeys[NHKF_REQMENU]),
375                   extcmdlist[idx].ef_txt);
376 #else
377             pline("'%s'\90Ú\93ª\8e«\82Í%s\83R\83}\83\93\83h\82É\82Í\96³\8cø\81D",
378                   visctrl(Cmd.spkeys[NHKF_REQMENU]),
379                   extcmdlist[idx].ef_txt);
380 #endif
381             iflags.menu_requested = FALSE;
382         }
383         retval = (*func)();
384     } while (func == doextlist);
385
386     return retval;
387 }
388
389 /* here after #? - now list all full-word commands and provid
390    some navigation capability through the long list */
391 int
392 doextlist(VOID_ARGS)
393 {
394     register const struct ext_func_tab *efp;
395     char buf[BUFSZ], searchbuf[BUFSZ], promptbuf[QBUFSZ];
396     winid menuwin;
397     anything any;
398     menu_item *selected;
399     int n, pass;
400     int menumode = 0, menushown[2], onelist = 0;
401     boolean redisplay = TRUE, search = FALSE;
402 #if 0 /*JP:T*/
403     static const char *headings[] = { "Extended commands",
404                                       "Debugging Extended Commands" };
405 #else
406     static const char *headings[] = { "\8ag\92£\83R\83}\83\93\83h",
407                                       "\83f\83o\83b\83O\8ag\92£\83R\83}\83\93\83h" };
408 #endif
409
410     searchbuf[0] = '\0';
411     menuwin = create_nhwindow(NHW_MENU);
412
413     while (redisplay) {
414         redisplay = FALSE;
415         any = zeroany;
416         start_menu(menuwin);
417 #if 0 /*JP:T*/
418         add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
419                  "Extended Commands List", MENU_UNSELECTED);
420 #else
421         add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
422                  "\8ag\92£\83R\83}\83\93\83h\88ê\97\97", MENU_UNSELECTED);
423 #endif
424         add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
425                  "", MENU_UNSELECTED);
426
427 #if 0 /*JP:T*/
428         Strcpy(buf, menumode ? "Show" : "Hide");
429         Strcat(buf, " commands that don't autocomplete");
430         if (!menumode)
431             Strcat(buf, " (those not marked with [A])");
432 #else
433         Strcpy(buf, "\8e©\93®\95â\8a®\82³\82ê\82È\82¢\83R\83}\83\93\83h\82ð");
434         Strcat(buf, menumode ? "\95\\8e¦\82·\82é" : "\95\\8e¦\82µ\82È\82¢ (\82±\82ê\82ç\82Í[A]\83}\81[\83N\82ª\82Â\82©\82È\82¢)");
435 #endif
436         any.a_int = 1;
437         add_menu(menuwin, NO_GLYPH, &any, 'a', 0, ATR_NONE, buf,
438                  MENU_UNSELECTED);
439
440         if (!*searchbuf) {
441             any.a_int = 2;
442             /* was 's', but then using ':' handling within the interface
443                would only examine the two or three meta entries, not the
444                actual list of extended commands shown via separator lines;
445                having ':' as an explicit selector overrides the default
446                menu behavior for it; we retain 's' as a group accelerator */
447 #if 0 /*JP:T*/
448             add_menu(menuwin, NO_GLYPH, &any, ':', 's', ATR_NONE,
449                      "Search extended commands", MENU_UNSELECTED);
450 #else
451             add_menu(menuwin, NO_GLYPH, &any, ':', 's', ATR_NONE,
452                      "\8ag\92£\83R\83}\83\93\83h\82ð\8c\9f\8dõ\82·\82é", MENU_UNSELECTED);
453 #endif
454         } else {
455 #if 0 /*JP:T*/
456             Strcpy(buf, "Show all, clear search");
457 #else
458             Strcpy(buf, "\91S\82Ä\95\\8e¦; \8c\9f\8dõ\82ð\83N\83\8a\83A");
459 #endif
460             if (strlen(buf) + strlen(searchbuf) + strlen(" (\"\")") < QBUFSZ)
461                 Sprintf(eos(buf), " (\"%s\")", searchbuf);
462             any.a_int = 3;
463             /* specifying ':' as a group accelerator here is mostly a
464                statement of intent (we'd like to accept it as a synonym but
465                also want to hide it from general menu use) because it won't
466                work for interfaces which support ':' to search; use as a
467                general menu command takes precedence over group accelerator */
468             add_menu(menuwin, NO_GLYPH, &any, 's', ':', ATR_NONE,
469                      buf, MENU_UNSELECTED);
470         }
471         if (wizard) {
472             any.a_int = 4;
473 #if 0 /*JP:T*/
474             add_menu(menuwin, NO_GLYPH, &any, 'z', 0, ATR_NONE,
475                      onelist ? "Show debugging commands in separate section"
476                      : "Show all alphabetically, including debugging commands",
477                      MENU_UNSELECTED);
478 #else
479             add_menu(menuwin, NO_GLYPH, &any, 'z', 0, ATR_NONE,
480                      onelist ? "\83f\83o\83b\83O\83R\83}\83\93\83h\82Í\95Ê\82Ì\90ß\82É\95\\8e¦\82·\82é"
481                      : "\83f\83o\83b\83O\83R\83}\83\93\83h\82ð\8aÜ\82Þ\91S\82Ä\82Ì\83R\83}\83\93\83h\82ð\83A\83\8b\83t\83@\83x\83b\83g\8f\87\82É\95\\8e¦\82·\82é",
482                      MENU_UNSELECTED);
483 #endif
484         }
485         any = zeroany;
486         add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
487                  "", MENU_UNSELECTED);
488         menushown[0] = menushown[1] = 0;
489         n = 0;
490         for (pass = 0; pass <= 1; ++pass) {
491             /* skip second pass if not in wizard mode or wizard mode
492                commands are being integrated into a single list */
493             if (pass == 1 && (onelist || !wizard))
494                 break;
495             for (efp = extcmdlist; efp->ef_txt; efp++) {
496                 int wizc;
497
498                 if ((efp->flags & CMD_NOT_AVAILABLE) != 0)
499                     continue;
500                 /* if hiding non-autocomplete commands, skip such */
501                 if (menumode == 1 && (efp->flags & AUTOCOMPLETE) == 0)
502                     continue;
503                 /* if searching, skip this command if it doesn't match */
504                 if (*searchbuf
505                     /* first try case-insensitive substring match */
506                     && !strstri(efp->ef_txt, searchbuf)
507                     && !strstri(efp->ef_desc, searchbuf)
508                     /* wildcard support; most interfaces use case-insensitve
509                        pmatch rather than regexp for menu searching */
510                     && !pmatchi(searchbuf, efp->ef_txt)
511                     && !pmatchi(searchbuf, efp->ef_desc))
512                     continue;
513                 /* skip wizard mode commands if not in wizard mode;
514                    when showing two sections, skip wizard mode commands
515                    in pass==0 and skip other commands in pass==1 */
516                 wizc = (efp->flags & WIZMODECMD) != 0;
517                 if (wizc && !wizard)
518                     continue;
519                 if (!onelist && pass != wizc)
520                     continue;
521
522                 /* We're about to show an item, have we shown the menu yet?
523                    Doing menu in inner loop like this on demand avoids a
524                    heading with no subordinate entries on the search
525                    results menu. */
526                 if (!menushown[pass]) {
527                     Strcpy(buf, headings[pass]);
528                     add_menu(menuwin, NO_GLYPH, &any, 0, 0,
529                              iflags.menu_headings, buf, MENU_UNSELECTED);
530                     menushown[pass] = 1;
531                 }
532                 Sprintf(buf, " %-14s %-3s %s",
533                         efp->ef_txt,
534                         (efp->flags & AUTOCOMPLETE) ? "[A]" : " ",
535                         efp->ef_desc);
536                 add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
537                          buf, MENU_UNSELECTED);
538                 ++n;
539             }
540             if (n)
541                 add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
542                          "", MENU_UNSELECTED);
543         }
544         if (*searchbuf && !n)
545 #if 0 /*JP:T*/
546             add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
547                      "no matches", MENU_UNSELECTED);
548 #else
549             add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
550                      "\88ê\92v\82È\82µ", MENU_UNSELECTED);
551 #endif
552
553         end_menu(menuwin, (char *) 0);
554         n = select_menu(menuwin, PICK_ONE, &selected);
555         if (n > 0) {
556             switch (selected[0].item.a_int) {
557             case 1: /* 'a': toggle show/hide non-autocomplete */
558                 menumode = 1 - menumode;  /* toggle 0 -> 1, 1 -> 0 */
559                 redisplay = TRUE;
560                 break;
561             case 2: /* ':' when not searching yet: enable search */
562                 search = TRUE;
563                 break;
564             case 3: /* 's' when already searching: disable search */
565                 search = FALSE;
566                 searchbuf[0] = '\0';
567                 redisplay = TRUE;
568                 break;
569             case 4: /* 'z': toggle showing wizard mode commands separately */
570                 search = FALSE;
571                 searchbuf[0] = '\0';
572                 onelist = 1 - onelist;  /* toggle 0 -> 1, 1 -> 0 */
573                 redisplay = TRUE;
574                 break;
575             }
576             free((genericptr_t) selected);
577         } else {
578             search = FALSE;
579             searchbuf[0] = '\0';
580         }
581         if (search) {
582 #if 0 /*JP:T*/
583             Strcpy(promptbuf, "Extended command list search phrase");
584             Strcat(promptbuf, "?");
585 #else
586             Strcpy(promptbuf, "\8ag\92£\83R\83}\83\93\83h\82Ì\8c\9f\8dõ\95\8e\9a\97ñ\82Í?");
587 #endif
588             getlin(promptbuf, searchbuf);
589             (void) mungspaces(searchbuf);
590             if (searchbuf[0] == '\033')
591                 searchbuf[0] = '\0';
592             if (*searchbuf)
593                 redisplay = TRUE;
594             search = FALSE;
595         }
596     }
597     destroy_nhwindow(menuwin);
598     return 0;
599 }
600
601 #if defined(TTY_GRAPHICS) || defined(CURSES_GRAPHICS)
602 #define MAX_EXT_CMD 200 /* Change if we ever have more ext cmds */
603
604 /*
605  * This is currently used only by the tty interface and is
606  * controlled via runtime option 'extmenu'.  (Most other interfaces
607  * already use a menu all the time for extended commands.)
608  *
609  * ``# ?'' is counted towards the limit of the number of commands,
610  * so we actually support MAX_EXT_CMD-1 "real" extended commands.
611  *
612  * Here after # - now show pick-list of possible commands.
613  */
614 int
615 extcmd_via_menu()
616 {
617     const struct ext_func_tab *efp;
618     menu_item *pick_list = (menu_item *) 0;
619     winid win;
620     anything any;
621     const struct ext_func_tab *choices[MAX_EXT_CMD + 1];
622     char buf[BUFSZ];
623     char cbuf[QBUFSZ], prompt[QBUFSZ], fmtstr[20];
624     int i, n, nchoices, acount;
625     int ret, len, biggest;
626     int accelerator, prevaccelerator;
627     int matchlevel = 0;
628     boolean wastoolong, one_per_line;
629
630     ret = 0;
631     cbuf[0] = '\0';
632     biggest = 0;
633     while (!ret) {
634         i = n = 0;
635         any = zeroany;
636         /* populate choices */
637         for (efp = extcmdlist; efp->ef_txt; efp++) {
638             if ((efp->flags & CMD_NOT_AVAILABLE)
639                 || !(efp->flags & AUTOCOMPLETE)
640                 || (!wizard && (efp->flags & WIZMODECMD)))
641                 continue;
642             if (!matchlevel || !strncmp(efp->ef_txt, cbuf, matchlevel)) {
643                 choices[i] = efp;
644                 if ((len = (int) strlen(efp->ef_desc)) > biggest)
645                     biggest = len;
646                 if (++i > MAX_EXT_CMD) {
647 #if (NH_DEVEL_STATUS != NH_STATUS_RELEASED)
648                     impossible(
649       "Exceeded %d extended commands in doextcmd() menu; 'extmenu' disabled.",
650                                MAX_EXT_CMD);
651 #endif /* NH_DEVEL_STATUS != NH_STATUS_RELEASED */
652                     iflags.extmenu = 0;
653                     return -1;
654                 }
655             }
656         }
657         choices[i] = (struct ext_func_tab *) 0;
658         nchoices = i;
659         /* if we're down to one, we have our selection so get out of here */
660         if (nchoices  <= 1) {
661             ret = (nchoices == 1) ? (int) (choices[0] - extcmdlist) : -1;
662             break;
663         }
664
665         /* otherwise... */
666         win = create_nhwindow(NHW_MENU);
667         start_menu(win);
668         Sprintf(fmtstr, "%%-%ds", biggest + 15);
669         prompt[0] = '\0';
670         wastoolong = FALSE; /* True => had to wrap due to line width
671                              * ('w' in wizard mode) */
672         /* -3: two line menu header, 1 line menu footer (for prompt) */
673         one_per_line = (nchoices < ROWNO - 3);
674         accelerator = prevaccelerator = 0;
675         acount = 0;
676         for (i = 0; choices[i]; ++i) {
677             accelerator = choices[i]->ef_txt[matchlevel];
678             if (accelerator != prevaccelerator || one_per_line)
679                 wastoolong = FALSE;
680             if (accelerator != prevaccelerator || one_per_line
681                 || (acount >= 2
682                     /* +4: + sizeof " or " - sizeof "" */
683                     && (strlen(prompt) + 4 + strlen(choices[i]->ef_txt)
684                         /* -6: enough room for 1 space left margin
685                          *   + "%c - " menu selector + 1 space right margin */
686                         >= min(sizeof prompt, COLNO - 6)))) {
687                 if (acount) {
688                     /* flush extended cmds for that letter already in buf */
689                     Sprintf(buf, fmtstr, prompt);
690                     any.a_char = prevaccelerator;
691                     add_menu(win, NO_GLYPH, &any, any.a_char, 0, ATR_NONE,
692                              buf, FALSE);
693                     acount = 0;
694                     if (!(accelerator != prevaccelerator || one_per_line))
695                         wastoolong = TRUE;
696                 }
697             }
698             prevaccelerator = accelerator;
699             if (!acount || one_per_line) {
700 #if 0 /*JP:T*/
701                 Sprintf(prompt, "%s%s [%s]", wastoolong ? "or " : "",
702                         choices[i]->ef_txt, choices[i]->ef_desc);
703 #else
704                 Sprintf(prompt, "%s%s [%s]", wastoolong ? "\82Ü\82½\82Í" : "",
705                         choices[i]->ef_txt, choices[i]->ef_desc);
706 #endif
707             } else if (acount == 1) {
708 #if 0 /*JP:T*/
709                 Sprintf(prompt, "%s%s or %s", wastoolong ? "or " : "",
710                         choices[i - 1]->ef_txt, choices[i]->ef_txt);
711 #else
712                 Sprintf(prompt, "%s%s\82Ü\82½\82Í%s", wastoolong ? "\82Ü\82½\82Í" : "",
713                         choices[i - 1]->ef_txt, choices[i]->ef_txt);
714 #endif
715             } else {
716 /*JP
717                 Strcat(prompt, " or ");
718 */
719                 Strcat(prompt," \82Ü\82½\82Í ");
720                 Strcat(prompt, choices[i]->ef_txt);
721             }
722             ++acount;
723         }
724         if (acount) {
725             /* flush buf */
726             Sprintf(buf, fmtstr, prompt);
727             any.a_char = prevaccelerator;
728             add_menu(win, NO_GLYPH, &any, any.a_char, 0, ATR_NONE, buf,
729                      FALSE);
730         }
731 /*JP
732         Sprintf(prompt, "Extended Command: %s", cbuf);
733 */
734         Sprintf(prompt, "\8ag\92£\83R\83}\83\93\83h: %s", cbuf);
735         end_menu(win, prompt);
736         n = select_menu(win, PICK_ONE, &pick_list);
737         destroy_nhwindow(win);
738         if (n == 1) {
739             if (matchlevel > (QBUFSZ - 2)) {
740                 free((genericptr_t) pick_list);
741 #if (NH_DEVEL_STATUS != NH_STATUS_RELEASED)
742                 impossible("Too many chars (%d) entered in extcmd_via_menu()",
743                            matchlevel);
744 #endif
745                 ret = -1;
746             } else {
747                 cbuf[matchlevel++] = pick_list[0].item.a_char;
748                 cbuf[matchlevel] = '\0';
749                 free((genericptr_t) pick_list);
750             }
751         } else {
752             if (matchlevel) {
753                 ret = 0;
754                 matchlevel = 0;
755             } else
756                 ret = -1;
757         }
758     }
759     return ret;
760 }
761 #endif /* TTY_GRAPHICS */
762
763 /* #monster command - use special monster ability while polymorphed */
764 int
765 domonability(VOID_ARGS)
766 {
767     if (can_breathe(youmonst.data))
768         return dobreathe();
769     else if (attacktype(youmonst.data, AT_SPIT))
770         return dospit();
771     else if (youmonst.data->mlet == S_NYMPH)
772         return doremove();
773     else if (attacktype(youmonst.data, AT_GAZE))
774         return dogaze();
775     else if (is_were(youmonst.data))
776         return dosummon();
777     else if (webmaker(youmonst.data))
778         return dospinweb();
779     else if (is_hider(youmonst.data))
780         return dohide();
781     else if (is_mind_flayer(youmonst.data))
782         return domindblast();
783     else if (u.umonnum == PM_GREMLIN) {
784         if (IS_FOUNTAIN(levl[u.ux][u.uy].typ)) {
785             if (split_mon(&youmonst, (struct monst *) 0))
786                 dryup(u.ux, u.uy, TRUE);
787         } else
788 /*JP
789             There("is no fountain here.");
790 */
791             pline("\82±\82±\82É\82Í\90ò\82Í\82È\82¢\81D");
792     } else if (is_unicorn(youmonst.data)) {
793         use_unicorn_horn((struct obj *) 0);
794         return 1;
795     } else if (youmonst.data->msound == MS_SHRIEK) {
796 /*JP
797         You("shriek.");
798 */
799         You("\8bà\90Ø\82è\90º\82ð\82 \82°\82½\81D");
800         if (u.uburied)
801 /*JP
802             pline("Unfortunately sound does not carry well through rock.");
803 */
804             pline("\8ec\94O\82È\82ª\82ç\89¹\82Í\8aâ\82ð\82¤\82Ü\82­\93`\82í\82ç\82È\82¢\81D");
805         else
806             aggravate();
807     } else if (youmonst.data->mlet == S_VAMPIRE)
808         return dopoly();
809     else if (Upolyd)
810 /*JP
811         pline("Any special ability you may have is purely reflexive.");
812 */
813         pline("\82 \82È\82½\82Ì\8e\9d\82Á\82Ä\82¢\82é\93Á\8eê\94\\97Í\82Í\82Ç\82ê\82à\8eó\93®\93I\82¾\81D");
814     else
815 /*JP
816         You("don't have a special ability in your normal form!");
817 */
818         You("\95\81\92i\82Ì\8ep\82Å\82Ì\93Á\8eê\94\\97Í\82ð\8e\9d\82Á\82Ä\82¢\82È\82¢\81I");
819     return 0;
820 }
821
822 int
823 enter_explore_mode(VOID_ARGS)
824 {
825     if (wizard) {
826 /*JP
827         You("are in debug mode.");
828 */
829         You("\82·\82Å\82É\83f\83o\83b\83O\83\82\81[\83h\82¾\81D");
830     } else if (discover) {
831 /*JP
832         You("are already in explore mode.");
833 */
834         You("\82·\82Å\82É\92T\8c\9f\83\82\81[\83h\82¾\81D");
835     } else {
836 #ifdef SYSCF
837 #if defined(UNIX)
838         if (!sysopt.explorers || !sysopt.explorers[0]
839             || !check_user_string(sysopt.explorers)) {
840 /*JP
841             You("cannot access explore mode.");
842 */
843             You("\92T\8c\9f\83\82\81[\83h\82É\83A\83N\83Z\83X\82Å\82«\82È\82¢\81D");
844             return 0;
845         }
846 #endif
847 #endif
848         pline(
849 /*JP
850         "Beware!  From explore mode there will be no return to normal game.");
851 */
852         "\8cx\8d\90\81I\94­\8c©\83\82\81[\83h\82É\93ü\82Á\82½\82ç\92Ê\8fí\83\82\81[\83h\82É\82Í\96ß\82ê\82È\82¢\81D");
853         if (paranoid_query(ParanoidQuit,
854 /*JP
855                            "Do you want to enter explore mode?")) {
856 */
857                            "\94­\8c©\83\82\81[\83h\82É\88Ú\82è\82Ü\82·\82©\81H")) {
858             clear_nhwindow(WIN_MESSAGE);
859 /*JP
860             You("are now in non-scoring explore mode.");
861 */
862             You("\83X\83R\83A\82ª\82Ì\82ç\82È\82¢\94­\8c©\83\82\81[\83h\82É\88Ú\8ds\82µ\82½\81D");
863             discover = TRUE;
864         } else {
865             clear_nhwindow(WIN_MESSAGE);
866 /*JP
867             pline("Resuming normal game.");
868 */
869             pline("\92Ê\8fí\83\82\81[\83h\82ð\91±\82¯\82é\81D");
870         }
871     }
872     return 0;
873 }
874
875 /* ^W command - wish for something */
876 STATIC_PTR int
877 wiz_wish(VOID_ARGS) /* Unlimited wishes for debug mode by Paul Polderman */
878 {
879     if (wizard) {
880         boolean save_verbose = flags.verbose;
881
882         flags.verbose = FALSE;
883         makewish();
884         flags.verbose = save_verbose;
885         (void) encumber_msg();
886     } else
887         pline(unavailcmd, visctrl((int) cmd_from_func(wiz_wish)));
888     return 0;
889 }
890
891 /* ^I command - reveal and optionally identify hero's inventory */
892 STATIC_PTR int
893 wiz_identify(VOID_ARGS)
894 {
895     if (wizard) {
896         iflags.override_ID = (int) cmd_from_func(wiz_identify);
897         /* command remapping might leave #wizidentify as the only way
898            to invoke us, in which case cmd_from_func() will yield NUL;
899            it won't matter to display_inventory()/display_pickinv()
900            if ^I invokes some other command--what matters is that
901            display_pickinv() and xname() see override_ID as nonzero */
902         if (!iflags.override_ID)
903             iflags.override_ID = C('I');
904         (void) display_inventory((char *) 0, FALSE);
905         iflags.override_ID = 0;
906     } else
907         pline(unavailcmd, visctrl((int) cmd_from_func(wiz_identify)));
908     return 0;
909 }
910
911 /* #wizmakemap - discard current dungeon level and replace with a new one */
912 STATIC_PTR int
913 wiz_makemap(VOID_ARGS)
914 {
915     if (wizard) {
916         struct monst *mtmp;
917         boolean was_in_W_tower = In_W_tower(u.ux, u.uy, &u.uz);
918
919         rm_mapseen(ledger_no(&u.uz));
920         for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
921             if (mtmp->isgd) { /* vault is going away; get rid of guard */
922                 mtmp->isgd = 0;
923                 mongone(mtmp);
924             }
925             if (DEADMONSTER(mtmp))
926                 continue;
927             if (mtmp->isshk)
928                 setpaid(mtmp);
929             /* TODO?
930              *  Reduce 'born' tally for each monster about to be discarded
931              *  by savelev(), otherwise replacing heavily populated levels
932              *  tends to make their inhabitants become extinct.
933              */
934         }
935         if (Punished) {
936             ballrelease(FALSE);
937             unplacebc();
938         }
939         /* reset lock picking unless it's for a carried container */
940         maybe_reset_pick((struct obj *) 0);
941         /* reset interrupted digging if it was taking place on this level */
942         if (on_level(&context.digging.level, &u.uz))
943             (void) memset((genericptr_t) &context.digging, 0,
944                           sizeof (struct dig_info));
945         /* reset cached targets */
946         iflags.travelcc.x = iflags.travelcc.y = 0; /* travel destination */
947         context.polearm.hitmon = (struct monst *) 0; /* polearm target */
948         /* escape from trap */
949         reset_utrap(FALSE);
950         check_special_room(TRUE); /* room exit */
951         u.ustuck = (struct monst *) 0;
952         u.uswallow = 0;
953         u.uinwater = 0;
954         u.uundetected = 0; /* not hidden, even if means are available */
955         dmonsfree(); /* purge dead monsters from 'fmon' */
956         /* keep steed and other adjacent pets after releasing them
957            from traps, stopping eating, &c as if hero were ascending */
958         keepdogs(TRUE); /* (pets-only; normally we'd be using 'FALSE' here) */
959
960         /* discard current level; "saving" is used to release dynamic data */
961         savelev(-1, ledger_no(&u.uz), FREE_SAVE);
962         /* create a new level; various things like bestowing a guardian
963            angel on Astral or setting off alarm on Ft.Ludios are handled
964            by goto_level(do.c) so won't occur for replacement levels */
965         mklev();
966
967         vision_reset();
968         vision_full_recalc = 1;
969         cls();
970         /* was using safe_teleds() but that doesn't honor arrival region
971            on levels which have such; we don't force stairs, just area */
972         u_on_rndspot((u.uhave.amulet ? 1 : 0) /* 'going up' flag */
973                      | (was_in_W_tower ? 2 : 0));
974         losedogs();
975         kill_genocided_monsters();
976         /* u_on_rndspot() might pick a spot that has a monster, or losedogs()
977            might pick the hero's spot (only if there isn't already a monster
978            there), so we might have to move hero or the co-located monster */
979         if ((mtmp = m_at(u.ux, u.uy)) != 0)
980             u_collide_m(mtmp);
981         initrack();
982         if (Punished) {
983             unplacebc();
984             placebc();
985         }
986         docrt();
987         flush_screen(1);
988         deliver_splev_message(); /* level entry */
989         check_special_room(FALSE); /* room entry */
990 #ifdef INSURANCE
991         save_currentstate();
992 #endif
993     } else {
994         pline(unavailcmd, "#wizmakemap");
995     }
996     return 0;
997 }
998
999 /* ^F command - reveal the level map and any traps on it */
1000 STATIC_PTR int
1001 wiz_map(VOID_ARGS)
1002 {
1003     if (wizard) {
1004         struct trap *t;
1005         long save_Hconf = HConfusion, save_Hhallu = HHallucination;
1006
1007         HConfusion = HHallucination = 0L;
1008         for (t = ftrap; t != 0; t = t->ntrap) {
1009             t->tseen = 1;
1010             map_trap(t, TRUE);
1011         }
1012         do_mapping();
1013         HConfusion = save_Hconf;
1014         HHallucination = save_Hhallu;
1015     } else
1016         pline(unavailcmd, visctrl((int) cmd_from_func(wiz_map)));
1017     return 0;
1018 }
1019
1020 /* ^G command - generate monster(s); a count prefix will be honored */
1021 STATIC_PTR int
1022 wiz_genesis(VOID_ARGS)
1023 {
1024     if (wizard)
1025         (void) create_particular();
1026     else
1027         pline(unavailcmd, visctrl((int) cmd_from_func(wiz_genesis)));
1028     return 0;
1029 }
1030
1031 /* ^O command - display dungeon layout */
1032 STATIC_PTR int
1033 wiz_where(VOID_ARGS)
1034 {
1035     if (wizard)
1036         (void) print_dungeon(FALSE, (schar *) 0, (xchar *) 0);
1037     else
1038         pline(unavailcmd, visctrl((int) cmd_from_func(wiz_where)));
1039     return 0;
1040 }
1041
1042 /* ^E command - detect unseen (secret doors, traps, hidden monsters) */
1043 STATIC_PTR int
1044 wiz_detect(VOID_ARGS)
1045 {
1046     if (wizard)
1047         (void) findit();
1048     else
1049         pline(unavailcmd, visctrl((int) cmd_from_func(wiz_detect)));
1050     return 0;
1051 }
1052
1053 /* ^V command - level teleport */
1054 STATIC_PTR int
1055 wiz_level_tele(VOID_ARGS)
1056 {
1057     if (wizard)
1058         level_tele();
1059     else
1060         pline(unavailcmd, visctrl((int) cmd_from_func(wiz_level_tele)));
1061     return 0;
1062 }
1063
1064 /* #levelchange command - adjust hero's experience level */
1065 STATIC_PTR int
1066 wiz_level_change(VOID_ARGS)
1067 {
1068     char buf[BUFSZ] = DUMMY;
1069     int newlevel = 0;
1070     int ret;
1071
1072 /*JP
1073     getlin("To what experience level do you want to be set?", buf);
1074 */
1075     getlin("\8co\8c±\83\8c\83x\83\8b\82ð\82¢\82­\82Â\82É\90Ý\92è\82µ\82Ü\82·\82©\81H", buf);
1076     (void) mungspaces(buf);
1077     if (buf[0] == '\033' || buf[0] == '\0')
1078         ret = 0;
1079     else
1080         ret = sscanf(buf, "%d", &newlevel);
1081
1082     if (ret != 1) {
1083         pline1(Never_mind);
1084         return 0;
1085     }
1086     if (newlevel == u.ulevel) {
1087 /*JP
1088         You("are already that experienced.");
1089 */
1090         You("\82·\82Å\82É\82»\82Ì\8co\8c±\83\8c\83x\83\8b\82¾\81D");
1091     } else if (newlevel < u.ulevel) {
1092         if (u.ulevel == 1) {
1093 /*JP
1094             You("are already as inexperienced as you can get.");
1095 */
1096             You("\82·\82Å\82É\89Â\94\\82È\8cÀ\82è\82Ì\8dÅ\92á\82Ì\8co\8c±\83\8c\83x\83\8b\82¾\81D");
1097             return 0;
1098         }
1099         if (newlevel < 1)
1100             newlevel = 1;
1101         while (u.ulevel > newlevel)
1102 /*JP
1103             losexp("#levelchange");
1104 */
1105             losexp("#levelchange\83R\83}\83\93\83h\82Å");
1106     } else {
1107         if (u.ulevel >= MAXULEV) {
1108 /*JP
1109             You("are already as experienced as you can get.");
1110 */
1111             You("\82·\82Å\82É\89Â\94\\82È\8cÀ\82è\82Ì\8dÅ\91å\82Ì\8co\8c±\83\8c\83x\83\8b\82¾\81D");
1112             return 0;
1113         }
1114         if (newlevel > MAXULEV)
1115             newlevel = MAXULEV;
1116         while (u.ulevel < newlevel)
1117             pluslvl(FALSE);
1118     }
1119     u.ulevelmax = u.ulevel;
1120     return 0;
1121 }
1122
1123 /* #panic command - test program's panic handling */
1124 STATIC_PTR int
1125 wiz_panic(VOID_ARGS)
1126 {
1127     if (iflags.debug_fuzzer) {
1128         u.uhp = u.uhpmax = 1000;
1129         u.uen = u.uenmax = 1000;
1130         return 0;
1131     }
1132 #if 0 /*JP:T*/
1133     if (paranoid_query(ParanoidQuit,
1134                        "Do you want to call panic() and end your game?"))
1135 #else
1136     if (paranoid_query(ParanoidQuit,
1137                        "panic()\8aÖ\90\94\82ð\8cÄ\82Ñ\8fo\82µ\82Ä\83Q\81[\83\80\82ð\8fI\97¹\82³\82¹\82Ü\82·\82©\81H"))
1138 #endif
1139         panic("Crash test.");
1140     return 0;
1141 }
1142
1143 /* #polyself command - change hero's form */
1144 STATIC_PTR int
1145 wiz_polyself(VOID_ARGS)
1146 {
1147     polyself(1);
1148     return 0;
1149 }
1150
1151 /* #seenv command */
1152 STATIC_PTR int
1153 wiz_show_seenv(VOID_ARGS)
1154 {
1155     winid win;
1156     int x, y, v, startx, stopx, curx;
1157     char row[COLNO + 1];
1158
1159     win = create_nhwindow(NHW_TEXT);
1160     /*
1161      * Each seenv description takes up 2 characters, so center
1162      * the seenv display around the hero.
1163      */
1164     startx = max(1, u.ux - (COLNO / 4));
1165     stopx = min(startx + (COLNO / 2), COLNO);
1166     /* can't have a line exactly 80 chars long */
1167     if (stopx - startx == COLNO / 2)
1168         startx++;
1169
1170     for (y = 0; y < ROWNO; y++) {
1171         for (x = startx, curx = 0; x < stopx; x++, curx += 2) {
1172             if (x == u.ux && y == u.uy) {
1173                 row[curx] = row[curx + 1] = '@';
1174             } else {
1175                 v = levl[x][y].seenv & 0xff;
1176                 if (v == 0)
1177                     row[curx] = row[curx + 1] = ' ';
1178                 else
1179                     Sprintf(&row[curx], "%02x", v);
1180             }
1181         }
1182         /* remove trailing spaces */
1183         for (x = curx - 1; x >= 0; x--)
1184             if (row[x] != ' ')
1185                 break;
1186         row[x + 1] = '\0';
1187
1188         putstr(win, 0, row);
1189     }
1190     display_nhwindow(win, TRUE);
1191     destroy_nhwindow(win);
1192     return 0;
1193 }
1194
1195 /* #vision command */
1196 STATIC_PTR int
1197 wiz_show_vision(VOID_ARGS)
1198 {
1199     winid win;
1200     int x, y, v;
1201     char row[COLNO + 1];
1202
1203     win = create_nhwindow(NHW_TEXT);
1204     Sprintf(row, "Flags: 0x%x could see, 0x%x in sight, 0x%x temp lit",
1205             COULD_SEE, IN_SIGHT, TEMP_LIT);
1206     putstr(win, 0, row);
1207     putstr(win, 0, "");
1208     for (y = 0; y < ROWNO; y++) {
1209         for (x = 1; x < COLNO; x++) {
1210             if (x == u.ux && y == u.uy)
1211                 row[x] = '@';
1212             else {
1213                 v = viz_array[y][x]; /* data access should be hidden */
1214                 if (v == 0)
1215                     row[x] = ' ';
1216                 else
1217                     row[x] = '0' + viz_array[y][x];
1218             }
1219         }
1220         /* remove trailing spaces */
1221         for (x = COLNO - 1; x >= 1; x--)
1222             if (row[x] != ' ')
1223                 break;
1224         row[x + 1] = '\0';
1225
1226         putstr(win, 0, &row[1]);
1227     }
1228     display_nhwindow(win, TRUE);
1229     destroy_nhwindow(win);
1230     return 0;
1231 }
1232
1233 /* #wmode command */
1234 STATIC_PTR int
1235 wiz_show_wmodes(VOID_ARGS)
1236 {
1237     winid win;
1238     int x, y;
1239     char row[COLNO + 1];
1240     struct rm *lev;
1241     boolean istty = WINDOWPORT("tty");
1242
1243     win = create_nhwindow(NHW_TEXT);
1244     if (istty)
1245         putstr(win, 0, ""); /* tty only: blank top line */
1246     for (y = 0; y < ROWNO; y++) {
1247         for (x = 0; x < COLNO; x++) {
1248             lev = &levl[x][y];
1249             if (x == u.ux && y == u.uy)
1250                 row[x] = '@';
1251             else if (IS_WALL(lev->typ) || lev->typ == SDOOR)
1252                 row[x] = '0' + (lev->wall_info & WM_MASK);
1253             else if (lev->typ == CORR)
1254                 row[x] = '#';
1255             else if (IS_ROOM(lev->typ) || IS_DOOR(lev->typ))
1256                 row[x] = '.';
1257             else
1258                 row[x] = 'x';
1259         }
1260         row[COLNO] = '\0';
1261         /* map column 0, levl[0][], is off the left edge of the screen */
1262         putstr(win, 0, &row[1]);
1263     }
1264     display_nhwindow(win, TRUE);
1265     destroy_nhwindow(win);
1266     return 0;
1267 }
1268
1269 /* wizard mode variant of #terrain; internal levl[][].typ values in base-36 */
1270 STATIC_OVL void
1271 wiz_map_levltyp(VOID_ARGS)
1272 {
1273     winid win;
1274     int x, y, terrain;
1275     char row[COLNO + 1];
1276     boolean istty = !strcmp(windowprocs.name, "tty");
1277
1278     win = create_nhwindow(NHW_TEXT);
1279     /* map row 0, levl[][0], is drawn on the second line of tty screen */
1280     if (istty)
1281         putstr(win, 0, ""); /* tty only: blank top line */
1282     for (y = 0; y < ROWNO; y++) {
1283         /* map column 0, levl[0][], is off the left edge of the screen;
1284            it should always have terrain type "undiggable stone" */
1285         for (x = 1; x < COLNO; x++) {
1286             terrain = levl[x][y].typ;
1287             /* assumes there aren't more than 10+26+26 terrain types */
1288             row[x - 1] = (char) ((terrain == STONE && !may_dig(x, y))
1289                                     ? '*'
1290                                     : (terrain < 10)
1291                                        ? '0' + terrain
1292                                        : (terrain < 36)
1293                                           ? 'a' + terrain - 10
1294                                           : 'A' + terrain - 36);
1295         }
1296         x--;
1297         if (levl[0][y].typ != STONE || may_dig(0, y))
1298             row[x++] = '!';
1299         row[x] = '\0';
1300         putstr(win, 0, row);
1301     }
1302
1303     {
1304         char dsc[BUFSZ];
1305         s_level *slev = Is_special(&u.uz);
1306
1307         Sprintf(dsc, "D:%d,L:%d", u.uz.dnum, u.uz.dlevel);
1308         /* [dungeon branch features currently omitted] */
1309         /* special level features */
1310         if (slev) {
1311             Sprintf(eos(dsc), " \"%s\"", slev->proto);
1312             /* special level flags (note: dungeon.def doesn't set `maze'
1313                or `hell' for any specific levels so those never show up) */
1314             if (slev->flags.maze_like)
1315                 Strcat(dsc, " mazelike");
1316             if (slev->flags.hellish)
1317                 Strcat(dsc, " hellish");
1318             if (slev->flags.town)
1319                 Strcat(dsc, " town");
1320             if (slev->flags.rogue_like)
1321                 Strcat(dsc, " roguelike");
1322             /* alignment currently omitted to save space */
1323         }
1324         /* level features */
1325         if (level.flags.nfountains)
1326             Sprintf(eos(dsc), " %c:%d", defsyms[S_fountain].sym,
1327                     (int) level.flags.nfountains);
1328         if (level.flags.nsinks)
1329             Sprintf(eos(dsc), " %c:%d", defsyms[S_sink].sym,
1330                     (int) level.flags.nsinks);
1331         if (level.flags.has_vault)
1332             Strcat(dsc, " vault");
1333         if (level.flags.has_shop)
1334             Strcat(dsc, " shop");
1335         if (level.flags.has_temple)
1336             Strcat(dsc, " temple");
1337         if (level.flags.has_court)
1338             Strcat(dsc, " throne");
1339         if (level.flags.has_zoo)
1340             Strcat(dsc, " zoo");
1341         if (level.flags.has_morgue)
1342             Strcat(dsc, " morgue");
1343         if (level.flags.has_barracks)
1344             Strcat(dsc, " barracks");
1345         if (level.flags.has_beehive)
1346             Strcat(dsc, " hive");
1347         if (level.flags.has_swamp)
1348             Strcat(dsc, " swamp");
1349         /* level flags */
1350         if (level.flags.noteleport)
1351             Strcat(dsc, " noTport");
1352         if (level.flags.hardfloor)
1353             Strcat(dsc, " noDig");
1354         if (level.flags.nommap)
1355             Strcat(dsc, " noMMap");
1356         if (!level.flags.hero_memory)
1357             Strcat(dsc, " noMem");
1358         if (level.flags.shortsighted)
1359             Strcat(dsc, " shortsight");
1360         if (level.flags.graveyard)
1361             Strcat(dsc, " graveyard");
1362         if (level.flags.is_maze_lev)
1363             Strcat(dsc, " maze");
1364         if (level.flags.is_cavernous_lev)
1365             Strcat(dsc, " cave");
1366         if (level.flags.arboreal)
1367             Strcat(dsc, " tree");
1368         if (Sokoban)
1369             Strcat(dsc, " sokoban-rules");
1370         /* non-flag info; probably should include dungeon branching
1371            checks (extra stairs and magic portals) here */
1372         if (Invocation_lev(&u.uz))
1373             Strcat(dsc, " invoke");
1374         if (On_W_tower_level(&u.uz))
1375             Strcat(dsc, " tower");
1376         /* append a branch identifier for completeness' sake */
1377         if (u.uz.dnum == 0)
1378             Strcat(dsc, " dungeon");
1379         else if (u.uz.dnum == mines_dnum)
1380             Strcat(dsc, " mines");
1381         else if (In_sokoban(&u.uz))
1382             Strcat(dsc, " sokoban");
1383         else if (u.uz.dnum == quest_dnum)
1384             Strcat(dsc, " quest");
1385         else if (Is_knox(&u.uz))
1386             Strcat(dsc, " ludios");
1387         else if (u.uz.dnum == 1)
1388             Strcat(dsc, " gehennom");
1389         else if (u.uz.dnum == tower_dnum)
1390             Strcat(dsc, " vlad");
1391         else if (In_endgame(&u.uz))
1392             Strcat(dsc, " endgame");
1393         else {
1394             /* somebody's added a dungeon branch we're not expecting */
1395             const char *brname = dungeons[u.uz.dnum].dname;
1396
1397             if (!brname || !*brname)
1398                 brname = "unknown";
1399             if (!strncmpi(brname, "the ", 4))
1400                 brname += 4;
1401             Sprintf(eos(dsc), " %s", brname);
1402         }
1403         /* limit the line length to map width */
1404         if (strlen(dsc) >= COLNO)
1405             dsc[COLNO - 1] = '\0'; /* truncate */
1406         putstr(win, 0, dsc);
1407     }
1408
1409     display_nhwindow(win, TRUE);
1410     destroy_nhwindow(win);
1411     return;
1412 }
1413
1414 /* temporary? hack, since level type codes aren't the same as screen
1415    symbols and only the latter have easily accessible descriptions */
1416 static const char *levltyp[] = {
1417     "stone", "vertical wall", "horizontal wall", "top-left corner wall",
1418     "top-right corner wall", "bottom-left corner wall",
1419     "bottom-right corner wall", "cross wall", "tee-up wall", "tee-down wall",
1420     "tee-left wall", "tee-right wall", "drawbridge wall", "tree",
1421     "secret door", "secret corridor", "pool", "moat", "water",
1422     "drawbridge up", "lava pool", "iron bars", "door", "corridor", "room",
1423     "stairs", "ladder", "fountain", "throne", "sink", "grave", "altar", "ice",
1424     "drawbridge down", "air", "cloud",
1425     /* not a real terrain type, but used for undiggable stone
1426        by wiz_map_levltyp() */
1427     "unreachable/undiggable",
1428     /* padding in case the number of entries above is odd */
1429     ""
1430 };
1431
1432 /* explanation of base-36 output from wiz_map_levltyp() */
1433 STATIC_OVL void
1434 wiz_levltyp_legend(VOID_ARGS)
1435 {
1436     winid win;
1437     int i, j, last, c;
1438     const char *dsc, *fmt;
1439     char buf[BUFSZ];
1440
1441     win = create_nhwindow(NHW_TEXT);
1442     putstr(win, 0, "#terrain encodings:");
1443     putstr(win, 0, "");
1444     fmt = " %c - %-28s"; /* TODO: include tab-separated variant for win32 */
1445     *buf = '\0';
1446     /* output in pairs, left hand column holds [0],[1],...,[N/2-1]
1447        and right hand column holds [N/2],[N/2+1],...,[N-1];
1448        N ('last') will always be even, and may or may not include
1449        the empty string entry to pad out the final pair, depending
1450        upon how many other entries are present in levltyp[] */
1451     last = SIZE(levltyp) & ~1;
1452     for (i = 0; i < last / 2; ++i)
1453         for (j = i; j < last; j += last / 2) {
1454             dsc = levltyp[j];
1455             c = !*dsc ? ' '
1456                    : !strncmp(dsc, "unreachable", 11) ? '*'
1457                       /* same int-to-char conversion as wiz_map_levltyp() */
1458                       : (j < 10) ? '0' + j
1459                          : (j < 36) ? 'a' + j - 10
1460                             : 'A' + j - 36;
1461             Sprintf(eos(buf), fmt, c, dsc);
1462             if (j > i) {
1463                 putstr(win, 0, buf);
1464                 *buf = '\0';
1465             }
1466         }
1467     display_nhwindow(win, TRUE);
1468     destroy_nhwindow(win);
1469     return;
1470 }
1471
1472 /* #wizsmell command - test usmellmon(). */
1473 STATIC_PTR int
1474 wiz_smell(VOID_ARGS)
1475 {
1476     int ans = 0;
1477     int mndx;  /* monster index */
1478     coord cc;  /* screen pos of unknown glyph */
1479     int glyph; /* glyph at selected position */
1480
1481     cc.x = u.ux;
1482     cc.y = u.uy;
1483     mndx = 0; /* gcc -Wall lint */
1484     if (!olfaction(youmonst.data)) {
1485         You("are incapable of detecting odors in your present form.");
1486         return 0;
1487     }
1488
1489     pline("You can move the cursor to a monster that you want to smell.");
1490     do {
1491         pline("Pick a monster to smell.");
1492         ans = getpos(&cc, TRUE, "a monster");
1493         if (ans < 0 || cc.x < 0) {
1494             return 0; /* done */
1495         }
1496         /* Convert the glyph at the selected position to a mndxbol. */
1497         glyph = glyph_at(cc.x, cc.y);
1498         if (glyph_is_monster(glyph))
1499             mndx = glyph_to_mon(glyph);
1500         else
1501             mndx = 0;
1502         /* Is it a monster? */
1503         if (mndx) {
1504             if (!usmellmon(&mons[mndx]))
1505                 pline("That monster seems to give off no smell.");
1506         } else
1507             pline("That is not a monster.");
1508     } while (TRUE);
1509     return 0;
1510 }
1511
1512 /* #wizinstrinsic command to set some intrinsics for testing */
1513 STATIC_PTR int
1514 wiz_intrinsic(VOID_ARGS)
1515 {
1516     if (wizard) {
1517         extern const struct propname {
1518             int prop_num;
1519             const char *prop_name;
1520         } propertynames[]; /* timeout.c */
1521         static const char wizintrinsic[] = "#wizintrinsic";
1522         static const char fmt[] = "You are%s %s.";
1523         winid win;
1524         anything any;
1525         char buf[BUFSZ];
1526         int i, j, n, p, amt, typ;
1527         long oldtimeout, newtimeout;
1528         const char *propname;
1529         menu_item *pick_list = (menu_item *) 0;
1530
1531         any = zeroany;
1532         win = create_nhwindow(NHW_MENU);
1533         start_menu(win);
1534         for (i = 0; (propname = propertynames[i].prop_name) != 0; ++i) {
1535             p = propertynames[i].prop_num;
1536             if (p == HALLUC_RES) {
1537                 /* Grayswandir vs hallucination; ought to be redone to
1538                    use u.uprops[HALLUC].blocked instead of being treated
1539                    as a separate property; letting in be manually toggled
1540                    even only in wizard mode would be asking for trouble... */
1541                 continue;
1542             }
1543             if (p == FIRE_RES) {
1544                 any.a_int = 0;
1545                 add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, "--", FALSE);
1546             }
1547             any.a_int = i + 1; /* +1: avoid 0 */
1548             oldtimeout = u.uprops[p].intrinsic & TIMEOUT;
1549             if (oldtimeout)
1550                 Sprintf(buf, "%-27s [%li]", propname, oldtimeout);
1551             else
1552                 Sprintf(buf, "%s", propname);
1553             add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
1554         }
1555         end_menu(win, "Which intrinsics?");
1556         n = select_menu(win, PICK_ANY, &pick_list);
1557         destroy_nhwindow(win);
1558
1559         amt = 30; /* TODO: prompt for duration */
1560         for (j = 0; j < n; ++j) {
1561             i = pick_list[j].item.a_int - 1; /* -1: reverse +1 above */
1562             p = propertynames[i].prop_num;
1563             oldtimeout = u.uprops[p].intrinsic & TIMEOUT;
1564             newtimeout = oldtimeout + (long) amt;
1565             switch (p) {
1566             case SICK:
1567             case SLIMED:
1568             case STONED:
1569                 if (oldtimeout > 0L && newtimeout > oldtimeout)
1570                     newtimeout = oldtimeout;
1571                 break;
1572             }
1573
1574             switch (p) {
1575             case BLINDED:
1576                 make_blinded(newtimeout, TRUE);
1577                 break;
1578 #if 0       /* make_confused() only gives feedback when confusion is
1579              * ending so use the 'default' case for it instead */
1580             case CONFUSION:
1581                 make_confused(newtimeout, TRUE);
1582                 break;
1583 #endif /*0*/
1584             case DEAF:
1585                 make_deaf(newtimeout, TRUE);
1586                 break;
1587             case HALLUC:
1588                 make_hallucinated(newtimeout, TRUE, 0L);
1589                 break;
1590             case SICK:
1591                 typ = !rn2(2) ? SICK_VOMITABLE : SICK_NONVOMITABLE;
1592                 make_sick(newtimeout, wizintrinsic, TRUE, typ);
1593                 break;
1594             case SLIMED:
1595                 Sprintf(buf, fmt,
1596                         !Slimed ? "" : " still", "turning into slime");
1597                 make_slimed(newtimeout, buf);
1598                 break;
1599             case STONED:
1600                 Sprintf(buf, fmt,
1601                         !Stoned ? "" : " still", "turning into stone");
1602                 make_stoned(newtimeout, buf, KILLED_BY, wizintrinsic);
1603                 break;
1604             case STUNNED:
1605                 make_stunned(newtimeout, TRUE);
1606                 break;
1607             case VOMITING:
1608                 Sprintf(buf, fmt, !Vomiting ? "" : " still", "vomiting");
1609                 make_vomiting(newtimeout, FALSE);
1610                 pline1(buf);
1611                 break;
1612             case WARN_OF_MON:
1613                 if (!Warn_of_mon) {
1614                     context.warntype.speciesidx = PM_GRID_BUG;
1615                     context.warntype.species
1616                                          = &mons[context.warntype.speciesidx];
1617                 }
1618                 goto def_feedback;
1619             case GLIB:
1620                 /* slippery fingers applies to gloves if worn at the time
1621                    so persistent inventory might need updating */
1622                 make_glib((int) newtimeout);
1623                 goto def_feedback;
1624             case LEVITATION:
1625             case FLYING:
1626                 float_vs_flight();
1627                 /*FALLTHRU*/
1628             default:
1629  def_feedback:
1630                 pline("Timeout for %s %s %d.", propertynames[i].prop_name,
1631                       oldtimeout ? "increased by" : "set to", amt);
1632                 if (p != GLIB)
1633                     incr_itimeout(&u.uprops[p].intrinsic, amt);
1634                 break;
1635             }
1636             context.botl = 1; /* probably not necessary... */
1637         }
1638         if (n >= 1)
1639             free((genericptr_t) pick_list);
1640         doredraw();
1641     } else
1642         pline(unavailcmd, visctrl((int) cmd_from_func(wiz_intrinsic)));
1643     return 0;
1644 }
1645
1646 /* #wizrumorcheck command - verify each rumor access */
1647 STATIC_PTR int
1648 wiz_rumor_check(VOID_ARGS)
1649 {
1650     rumor_check();
1651     return 0;
1652 }
1653
1654 /* #terrain command -- show known map, inspired by crawl's '|' command */
1655 STATIC_PTR int
1656 doterrain(VOID_ARGS)
1657 {
1658     winid men;
1659     menu_item *sel;
1660     anything any;
1661     int n;
1662     int which;
1663
1664     /*
1665      * normal play: choose between known map without mons, obj, and traps
1666      *  (to see underlying terrain only), or
1667      *  known map without mons and objs (to see traps under mons and objs), or
1668      *  known map without mons (to see objects under monsters);
1669      * explore mode: normal choices plus full map (w/o mons, objs, traps);
1670      * wizard mode: normal and explore choices plus
1671      *  a dump of the internal levl[][].typ codes w/ level flags, or
1672      *  a legend for the levl[][].typ codes dump
1673      */
1674     men = create_nhwindow(NHW_MENU);
1675     start_menu(men);
1676     any = zeroany;
1677     any.a_int = 1;
1678     add_menu(men, NO_GLYPH, &any, 0, 0, ATR_NONE,
1679 /*JP
1680              "known map without monsters, objects, and traps",
1681 */
1682              "\89ö\95¨\81C\95¨\81Cã©\82È\82µ\82Ì\92n\90}",
1683              MENU_SELECTED);
1684     any.a_int = 2;
1685     add_menu(men, NO_GLYPH, &any, 0, 0, ATR_NONE,
1686 /*JP
1687              "known map without monsters and objects",
1688 */
1689              "\89ö\95¨\81C\95¨\82È\82µ\82Ì\92n\90}",
1690              MENU_UNSELECTED);
1691     any.a_int = 3;
1692     add_menu(men, NO_GLYPH, &any, 0, 0, ATR_NONE,
1693 /*JP
1694              "known map without monsters",
1695 */
1696              "\89ö\95¨\82È\82µ\82Ì\92n\90}",
1697              MENU_UNSELECTED);
1698     if (discover || wizard) {
1699         any.a_int = 4;
1700         add_menu(men, NO_GLYPH, &any, 0, 0, ATR_NONE,
1701 /*JP
1702                  "full map without monsters, objects, and traps",
1703 */
1704                  "\89ö\95¨\81C\95¨\81Cã©\82È\82µ\82Ì\8a®\91S\82È\92n\90}",
1705                  MENU_UNSELECTED);
1706         if (wizard) {
1707             any.a_int = 5;
1708             add_menu(men, NO_GLYPH, &any, 0, 0, ATR_NONE,
1709                      "internal levl[][].typ codes in base-36",
1710                      MENU_UNSELECTED);
1711             any.a_int = 6;
1712             add_menu(men, NO_GLYPH, &any, 0, 0, ATR_NONE,
1713                      "legend of base-36 levl[][].typ codes",
1714                      MENU_UNSELECTED);
1715         }
1716     }
1717 /*JP
1718     end_menu(men, "View which?");
1719 */
1720     end_menu(men, "\82Ç\82ê\82ð\8c©\82é\81H");
1721
1722     n = select_menu(men, PICK_ONE, &sel);
1723     destroy_nhwindow(men);
1724     /*
1725      * n <  0: player used ESC to cancel;
1726      * n == 0: preselected entry was explicitly chosen and got toggled off;
1727      * n == 1: preselected entry was implicitly chosen via <space>|<enter>;
1728      * n == 2: another entry was explicitly chosen, so skip preselected one.
1729      */
1730     which = (n < 0) ? -1 : (n == 0) ? 1 : sel[0].item.a_int;
1731     if (n > 1 && which == 1)
1732         which = sel[1].item.a_int;
1733     if (n > 0)
1734         free((genericptr_t) sel);
1735
1736     switch (which) {
1737     case 1: /* known map */
1738         reveal_terrain(0, TER_MAP);
1739         break;
1740     case 2: /* known map with known traps */
1741         reveal_terrain(0, TER_MAP | TER_TRP);
1742         break;
1743     case 3: /* known map with known traps and objects */
1744         reveal_terrain(0, TER_MAP | TER_TRP | TER_OBJ);
1745         break;
1746     case 4: /* full map */
1747         reveal_terrain(1, TER_MAP);
1748         break;
1749     case 5: /* map internals */
1750         wiz_map_levltyp();
1751         break;
1752     case 6: /* internal details */
1753         wiz_levltyp_legend();
1754         break;
1755     default:
1756         break;
1757     }
1758     return 0; /* no time elapses */
1759 }
1760
1761 /* -enlightenment and conduct- */
1762 static winid en_win = WIN_ERR;
1763 static boolean en_via_menu = FALSE;
1764 #if 0 /*JP*/
1765 static const char You_[] = "You ", are[] = "are ", were[] = "were ",
1766                   have[] = "have ", had[] = "had ", can[] = "can ",
1767                   could[] = "could ";
1768 #else
1769 static const char You_[] = "\82 \82È\82½\82Í", 
1770                   are[]  = "\82Å\82 \82é",       were[]  = "\82Å\82 \82Á\82½",
1771                   have[] = "\82ð\82à\82Á\82Ä\82¢\82é", had[]   = "\82ð\82à\82Á\82Ä\82¢\82½",
1772                   can[]  = "\82Å\82«\82é",       could[] = "\82Å\82«\82½",
1773                   iru[]  = "\82¢\82é",         ita[]   = "\82¢\82½";
1774 #endif
1775 #if 0 /*JP*//* not used */
1776 static const char have_been[] = "have been ", have_never[] = "have never ",
1777                   never[] = "never ";
1778 #endif
1779
1780 #if 0 /*JP*/
1781 #define enl_msg(prefix, present, past, suffix, ps) \
1782     enlght_line(prefix, final ? past : present, suffix, ps)
1783 #else
1784 #define enl_msg(prefix, present, past, suffix, ps) \
1785     enlght_line(prefix, ps, suffix, final ? past : present)
1786 #endif
1787 #define you_are(attr, ps) enl_msg(You_, are, were, attr, ps)
1788 #define you_have(attr, ps) enl_msg(You_, have, had, attr, ps)
1789 #define you_can(attr, ps) enl_msg(You_, can, could, attr, ps)
1790 /*JP
1791 #define you_have_been(goodthing) enl_msg(You_, have_been, were, goodthing, "")
1792 */
1793 #define you_have_been(goodthing) enl_msg(You_, are, were, goodthing, "")
1794 #if 0 /*JP*/
1795 #define you_have_never(badthing) \
1796     enl_msg(You_, have_never, never, badthing, "")
1797 #else
1798 #define you_have_never(badthing) \
1799     enl_msg(badthing, "\82Ä\82¢\82È\82¢", "\82È\82©\82Á\82½", "", "")
1800 #endif
1801 #if 0 /*JP*/
1802 #define you_have_X(something) \
1803     enl_msg(You_, have, (const char *) "", something, "")
1804 #else
1805 #define you_have_X(something) \
1806     enl_msg(something, "\82Ä\82¢\82é", "\82½", "", "")
1807 #endif
1808 #if 1 /*JP*/
1809 #define you_are_ing(goodthing, ps) enl_msg(You_, iru, ita, goodthing, ps)
1810 #endif
1811
1812 static void
1813 enlght_out(buf)
1814 const char *buf;
1815 {
1816     if (en_via_menu) {
1817         anything any;
1818
1819         any = zeroany;
1820         add_menu(en_win, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
1821     } else
1822         putstr(en_win, 0, buf);
1823 }
1824
1825 static void
1826 enlght_line(start, middle, end, ps)
1827 const char *start, *middle, *end, *ps;
1828 {
1829     char buf[BUFSZ];
1830
1831 /*JP
1832     Sprintf(buf, " %s%s%s%s.", start, middle, end, ps);
1833 */
1834     Sprintf(buf, "%s%s%s%s\81D", start, middle, end, ps);
1835     enlght_out(buf);
1836 }
1837
1838 /* format increased chance to hit or damage or defense (Protection) */
1839 static char *
1840 enlght_combatinc(inctyp, incamt, final, outbuf)
1841 const char *inctyp;
1842 int incamt, final;
1843 char *outbuf;
1844 {
1845     const char *modif, *bonus;
1846 #if 0 /*JP*/
1847     boolean invrt;
1848 #endif
1849     int absamt;
1850
1851     absamt = abs(incamt);
1852     /* Protection amount is typically larger than damage or to-hit;
1853        reduce magnitude by a third in order to stretch modifier ranges
1854        (small:1..5, moderate:6..10, large:11..19, huge:20+) */
1855 #if 0 /*JP:T*/
1856     if (!strcmp(inctyp, "defense"))
1857 #else
1858     if (!strcmp(inctyp, "\96h\8cä"))
1859 #endif
1860         absamt = (absamt * 2) / 3;
1861
1862     if (absamt <= 3)
1863 /*JP
1864         modif = "small";
1865 */
1866         modif = "\8bÍ\82©\82È";
1867     else if (absamt <= 6)
1868 /*JP
1869         modif = "moderate";
1870 */
1871         modif = "\92\86\92ö\93x\82Ì";
1872     else if (absamt <= 12)
1873 /*JP
1874         modif = "large";
1875 */
1876         modif = "\91å\82«\82È";
1877     else
1878 /*JP
1879         modif = "huge";
1880 */
1881         modif = "\8b­\91å\82È";
1882
1883 #if 0 /*JP*/
1884     modif = !incamt ? "no" : an(modif); /* ("no" case shouldn't happen) */
1885 #endif
1886 /*JP
1887     bonus = (incamt >= 0) ? "bonus" : "penalty";
1888 */
1889     bonus = (incamt > 0) ? "\83{\81[\83i\83X" : "\83y\83i\83\8b\83e\83B";
1890     /* "bonus <foo>" (to hit) vs "<bar> bonus" (damage, defense) */
1891 #if 0 /*JP*/
1892     invrt = strcmp(inctyp, "to hit") ? TRUE : FALSE;
1893 #endif
1894
1895 #if 0 /*JP*/
1896     Sprintf(outbuf, "%s %s %s", modif, invrt ? inctyp : bonus,
1897             invrt ? bonus : inctyp);
1898 #else
1899     Sprintf(outbuf, "%s\82É%s%s", inctyp, modif, bonus);
1900 #endif
1901     if (final || wizard)
1902         Sprintf(eos(outbuf), " (%s%d)", (incamt > 0) ? "+" : "", incamt);
1903
1904     return outbuf;
1905 }
1906
1907 /* report half physical or half spell damage */
1908 STATIC_OVL void
1909 enlght_halfdmg(category, final)
1910 int category;
1911 int final;
1912 {
1913     const char *category_name;
1914     char buf[BUFSZ];
1915
1916     switch (category) {
1917     case HALF_PHDAM:
1918 /*JP
1919         category_name = "physical";
1920 */
1921         category_name = "\95¨\97\9d";
1922         break;
1923     case HALF_SPDAM:
1924 /*JP
1925         category_name = "spell";
1926 */
1927         category_name = "\8eô\95¶";
1928         break;
1929     default:
1930 /*JP
1931         category_name = "unknown";
1932 */
1933         category_name = "\95s\96¾";
1934         break;
1935     }
1936 #if 0 /*JP:T*/
1937     Sprintf(buf, " %s %s damage", (final || wizard) ? "half" : "reduced",
1938             category_name);
1939     enl_msg(You_, "take", "took", buf, from_what(category));
1940 #else
1941     Sprintf(buf, " %s\83_\83\81\81[\83W\82ð%s", (final || wizard) ? "\94¼\8c¸" : "\8c¸\8f­",
1942             category_name);
1943     enl_msg(You_, "\82µ\82Ä\82¢\82é", "\82µ\82Ä\82¢\82½", buf, from_what(category));
1944 #endif
1945 }
1946
1947 /* is hero actively using water walking capability on water (or lava)? */
1948 STATIC_OVL boolean
1949 walking_on_water()
1950 {
1951     if (u.uinwater || Levitation || Flying)
1952         return FALSE;
1953     return (boolean) (Wwalking
1954                       && (is_pool(u.ux, u.uy) || is_lava(u.ux, u.uy)));
1955 }
1956
1957 /* check whether hero is wearing something that player definitely knows
1958    confers the target property; item must have been seen and its type
1959    discovered but it doesn't necessarily have to be fully identified */
1960 STATIC_OVL boolean
1961 cause_known(propindx)
1962 int propindx; /* index of a property which can be conveyed by worn item */
1963 {
1964     register struct obj *o;
1965     long mask = W_ARMOR | W_AMUL | W_RING | W_TOOL;
1966
1967     /* simpler than from_what()/what_gives(); we don't attempt to
1968        handle artifacts and we deliberately ignore wielded items */
1969     for (o = invent; o; o = o->nobj) {
1970         if (!(o->owornmask & mask))
1971             continue;
1972         if ((int) objects[o->otyp].oc_oprop == propindx
1973             && objects[o->otyp].oc_name_known && o->dknown)
1974             return TRUE;
1975     }
1976     return FALSE;
1977 }
1978
1979 /* format a characteristic value, accommodating Strength's strangeness */
1980 STATIC_OVL char *
1981 attrval(attrindx, attrvalue, resultbuf)
1982 int attrindx, attrvalue;
1983 char resultbuf[]; /* should be at least [7] to hold "18/100\0" */
1984 {
1985     if (attrindx != A_STR || attrvalue <= 18)
1986         Sprintf(resultbuf, "%d", attrvalue);
1987     else if (attrvalue > STR18(100)) /* 19 to 25 */
1988         Sprintf(resultbuf, "%d", attrvalue - 100);
1989     else /* simplify "18/ **" to be "18/100" */
1990         Sprintf(resultbuf, "18/%02d", attrvalue - 18);
1991     return resultbuf;
1992 }
1993
1994 void
1995 enlightenment(mode, final)
1996 int mode;  /* BASICENLIGHTENMENT | MAGICENLIGHTENMENT (| both) */
1997 int final; /* ENL_GAMEINPROGRESS:0, ENL_GAMEOVERALIVE, ENL_GAMEOVERDEAD */
1998 {
1999     char buf[BUFSZ], tmpbuf[BUFSZ];
2000
2001     en_win = create_nhwindow(NHW_MENU);
2002     en_via_menu = !final;
2003     if (en_via_menu)
2004         start_menu(en_win);
2005
2006     Strcpy(tmpbuf, plname);
2007     *tmpbuf = highc(*tmpbuf); /* same adjustment as bottom line */
2008     /* as in background_enlightenment, when poly'd we need to use the saved
2009        gender in u.mfemale rather than the current you-as-monster gender */
2010 #if 0 /*JP:T*/
2011     Sprintf(buf, "%s the %s's attributes:", tmpbuf,
2012             ((Upolyd ? u.mfemale : flags.female) && urole.name.f)
2013                 ? urole.name.f
2014                 : urole.name.m);
2015 #else
2016     Sprintf(buf, "%s\82Ì%s\82Ì\91®\90«:",
2017             ((Upolyd ? u.mfemale : flags.female) && urole.name.f)
2018                 ? urole.name.f
2019                 : urole.name.m,
2020              tmpbuf);
2021 #endif
2022
2023     /* title */
2024     enlght_out(buf); /* "Conan the Archeologist's attributes:" */
2025     /* background and characteristics; ^X or end-of-game disclosure */
2026     if (mode & BASICENLIGHTENMENT) {
2027         /* role, race, alignment, deities, dungeon level, time, experience */
2028         background_enlightenment(mode, final);
2029         /* hit points, energy points, armor class, gold */
2030         basics_enlightenment(mode, final);
2031         /* strength, dexterity, &c */
2032         characteristics_enlightenment(mode, final);
2033     }
2034     /* expanded status line information, including things which aren't
2035        included there due to space considerations--such as obvious
2036        alternative movement indicators (riding, levitation, &c), and
2037        various troubles (turning to stone, trapped, confusion, &c);
2038        shown for both basic and magic enlightenment */
2039     status_enlightenment(mode, final);
2040     /* remaining attributes; shown for potion,&c or wizard mode and
2041        explore mode ^X or end of game disclosure */
2042     if (mode & MAGICENLIGHTENMENT) {
2043         /* intrinsics and other traditional enlightenment feedback */
2044         attributes_enlightenment(mode, final);
2045     }
2046
2047     if (!en_via_menu) {
2048         display_nhwindow(en_win, TRUE);
2049     } else {
2050         menu_item *selected = 0;
2051
2052         end_menu(en_win, (char *) 0);
2053         if (select_menu(en_win, PICK_NONE, &selected) > 0)
2054             free((genericptr_t) selected);
2055         en_via_menu = FALSE;
2056     }
2057     destroy_nhwindow(en_win);
2058     en_win = WIN_ERR;
2059 }
2060
2061 /*ARGSUSED*/
2062 /* display role, race, alignment and such to en_win */
2063 STATIC_OVL void
2064 background_enlightenment(unused_mode, final)
2065 int unused_mode UNUSED;
2066 int final;
2067 {
2068     const char *role_titl, *rank_titl;
2069     int innategend, difgend, difalgn;
2070     char buf[BUFSZ], tmpbuf[BUFSZ];
2071
2072     /* note that if poly'd, we need to use u.mfemale instead of flags.female
2073        to access hero's saved gender-as-human/elf/&c rather than current one */
2074     innategend = (Upolyd ? u.mfemale : flags.female) ? 1 : 0;
2075     role_titl = (innategend && urole.name.f) ? urole.name.f : urole.name.m;
2076     rank_titl = rank_of(u.ulevel, Role_switch, innategend);
2077
2078     enlght_out(""); /* separator after title */
2079 /*JP
2080     enlght_out("Background:");
2081 */
2082     enlght_out("\94w\8ci\8fî\95ñ:");
2083
2084     /* if polymorphed, report current shape before underlying role;
2085        will be repeated as first status: "you are transformed" and also
2086        among various attributes: "you are in beast form" (after being
2087        told about lycanthropy) or "you are polymorphed into <a foo>"
2088        (with countdown timer appended for wizard mode); we really want
2089        the player to know he's not a samurai at the moment... */
2090     if (Upolyd) {
2091         struct permonst *uasmon = youmonst.data;
2092
2093         tmpbuf[0] = '\0';
2094         /* here we always use current gender, not saved role gender */
2095         if (!is_male(uasmon) && !is_female(uasmon) && !is_neuter(uasmon))
2096 /*JP
2097             Sprintf(tmpbuf, "%s ", genders[flags.female ? 1 : 0].adj);
2098 */
2099             Sprintf(tmpbuf, "%s\82Ì", genders[flags.female ? 1 : 0].adj);
2100 #if 0 /*JP:T*/
2101         Sprintf(buf, "%sin %s%s form", !final ? "currently " : "", tmpbuf,
2102                 uasmon->mname);
2103 #else
2104         Sprintf(buf, "%s%s%s\82Ì\8ep", !final ? "\8d¡\82Ì\82Æ\82±\82ë" : "", tmpbuf,
2105                 uasmon->mname);
2106 #endif
2107 /*JP
2108         you_are(buf, "");
2109 */
2110         you_are_ing(buf, "");
2111     }
2112
2113     /* report role; omit gender if it's redundant (eg, "female priestess") */
2114     tmpbuf[0] = '\0';
2115     if (!urole.name.f
2116         && ((urole.allow & ROLE_GENDMASK) == (ROLE_MALE | ROLE_FEMALE)
2117             || innategend != flags.initgend))
2118 /*JP
2119         Sprintf(tmpbuf, "%s ", genders[innategend].adj);
2120 */
2121         Sprintf(tmpbuf, "%s", genders[innategend].adj);
2122     buf[0] = '\0';
2123     if (Upolyd)
2124 #if 0 /*JP:T*/
2125         Strcpy(buf, "actually "); /* "You are actually a ..." */
2126 #else
2127         Strcpy(buf, "\8eÀ\8dÛ\82É\82Í"); /* "\82 \82È\82½\82Í\8eÀ\8dÛ\82É\82Í..." */
2128 #endif
2129     if (!strcmpi(rank_titl, role_titl)) {
2130         /* omit role when rank title matches it */
2131 #if 0 /*JP:T*/
2132         Sprintf(eos(buf), "%s, level %d %s%s", an(rank_titl), u.ulevel,
2133                 tmpbuf, urace.noun);
2134 #else
2135         Sprintf(eos(buf), "\83\8c\83x\83\8b%d\82Ì%s\82Ì%s%s", u.ulevel,
2136                 tmpbuf, urace.adj, role_titl);
2137 #endif
2138     } else {
2139 #if 0 /*JP:T*/
2140         Sprintf(eos(buf), "%s, a level %d %s%s %s", an(rank_titl), u.ulevel,
2141                 tmpbuf, urace.adj, role_titl);
2142 #else
2143         Sprintf(eos(buf), "\83\8c\83x\83\8b%d\82Ì%s\82Ì%s%s\82Ì%s", u.ulevel,
2144                 tmpbuf, urace.adj, role_titl, rank_titl);
2145 #endif
2146     }
2147     you_are(buf, "");
2148
2149     /* report alignment (bypass you_are() in order to omit ending period);
2150        adverb is used to distinguish between temporary change (helm of opp.
2151        alignment), permanent change (one-time conversion), and original */
2152 #if 0 /*JP*/
2153     Sprintf(buf, " %s%s%s, %son a mission for %s",
2154             You_, !final ? are : were,
2155             align_str(u.ualign.type),
2156             /* helm of opposite alignment (might hide conversion) */
2157             (u.ualign.type != u.ualignbase[A_CURRENT])
2158                /* what's the past tense of "currently"? if we used "formerly"
2159                   it would sound like a reference to the original alignment */
2160                ? (!final ? "currently " : "temporarily ")
2161                /* permanent conversion */
2162                : (u.ualign.type != u.ualignbase[A_ORIGINAL])
2163                   /* and what's the past tense of "now"? certainly not "then"
2164                      in a context like this...; "belatedly" == weren't that
2165                      way sooner (in other words, didn't start that way) */
2166                   ? (!final ? "now " : "belatedly ")
2167                   /* atheist (ignored in very early game) */
2168                   : (!u.uconduct.gnostic && moves > 1000L)
2169                      ? "nominally "
2170                      /* lastly, normal case */
2171                      : "",
2172             u_gname());
2173 #else
2174     Sprintf(buf, "\82 \82È\82½\82Í%s\82Å, %s%s\82Ì\82½\82ß\82Ì\94C\96±\82ð\8ds\82Á\82Ä%s\81D",
2175             align_str(u.ualign.type),
2176             /* helm of opposite alignment (might hide conversion) */
2177             (u.ualign.type != u.ualignbase[A_CURRENT]) ? "\88ê\8e\9e\93I\82É"
2178                /* permanent conversion */
2179                : (u.ualign.type != u.ualignbase[A_ORIGINAL]) ? "\8c»\8dÝ"
2180                   /* atheist (ignored in very early game) */
2181                   : (!u.uconduct.gnostic && moves > 1000L) ? "\96¼\8b`\8fã"
2182                      /* lastly, normal case */
2183                      : "",
2184             u_gname(), !final ? iru : ita);
2185 #endif
2186     enlght_out(buf);
2187     /* show the rest of this game's pantheon (finishes previous sentence)
2188        [appending "also Moloch" at the end would allow for straightforward
2189        trailing "and" on all three aligned entries but looks too verbose] */
2190 #if 0 /*JP*/
2191     Sprintf(buf, " who %s opposed by", !final ? "is" : "was");
2192 #else
2193     Strcpy(buf, "\82 \82È\82½\82Í");
2194 #endif
2195     if (u.ualign.type != A_LAWFUL)
2196 #if 0 /*JP:T*/
2197         Sprintf(eos(buf), " %s (%s) and", align_gname(A_LAWFUL),
2198                 align_str(A_LAWFUL));
2199 #else
2200         Sprintf(eos(buf), "%s(%s)\82¨\82æ\82Ñ", align_gname(A_LAWFUL),
2201                 align_str(A_LAWFUL));
2202 #endif
2203     if (u.ualign.type != A_NEUTRAL)
2204 #if 0 /*JP:T*/
2205         Sprintf(eos(buf), " %s (%s)%s", align_gname(A_NEUTRAL),
2206                 align_str(A_NEUTRAL),
2207                 (u.ualign.type != A_CHAOTIC) ? " and" : "");
2208 #else
2209         Sprintf(eos(buf), "%s(%s)%s", align_gname(A_NEUTRAL),
2210                 align_str(A_NEUTRAL),
2211                 (u.ualign.type != A_CHAOTIC) ? "\82¨\82æ\82Ñ" : "");
2212 #endif
2213     if (u.ualign.type != A_CHAOTIC)
2214 #if 0 /*JP:T*/
2215         Sprintf(eos(buf), " %s (%s)", align_gname(A_CHAOTIC),
2216                 align_str(A_CHAOTIC));
2217 #else
2218     if (u.ualign.type != A_CHAOTIC)
2219         Sprintf(eos(buf), "%s(%s)", align_gname(A_CHAOTIC),
2220                 align_str(A_CHAOTIC));
2221 #endif
2222 #if 0 /*JP*/
2223     Strcat(buf, "."); /* terminate sentence */
2224 #else
2225     Sprintf(eos(buf), "\82Æ\91Î\97§\82µ\82Ä%s\81D", !final ? iru : ita);
2226 #endif
2227     enlght_out(buf);
2228
2229     /* show original alignment,gender,race,role if any have been changed;
2230        giving separate message for temporary alignment change bypasses need
2231        for tricky phrasing otherwise necessitated by possibility of having
2232        helm of opposite alignment mask a permanent alignment conversion */
2233     difgend = (innategend != flags.initgend);
2234     difalgn = (((u.ualign.type != u.ualignbase[A_CURRENT]) ? 1 : 0)
2235                + ((u.ualignbase[A_CURRENT] != u.ualignbase[A_ORIGINAL])
2236                   ? 2 : 0));
2237     if (difalgn & 1) { /* have temporary alignment so report permanent one */
2238 /*JP
2239         Sprintf(buf, "actually %s", align_str(u.ualignbase[A_CURRENT]));
2240 */
2241         Sprintf(buf, "\8eÀ\8dÛ\82É\82Í%s", align_str(u.ualignbase[A_CURRENT]));
2242 #if 0 /*JP*/
2243         you_are(buf, "");
2244 #else
2245         enl_msg(buf, "\82Ä\82¢\82é", "\82Ä\82¢\82½", "", "");
2246 #endif
2247         difalgn &= ~1; /* suppress helm from "started out <foo>" message */
2248     }
2249     if (difgend || difalgn) { /* sex change or perm align change or both */
2250 #if 0 /*JP:T*/
2251         Sprintf(buf, " You started out %s%s%s.",
2252                 difgend ? genders[flags.initgend].adj : "",
2253                 (difgend && difalgn) ? " and " : "",
2254                 difalgn ? align_str(u.ualignbase[A_ORIGINAL]) : "");
2255 #else
2256         Sprintf(buf, "\82 \82È\82½\82Í%s%s%s\82Å\8aJ\8en\82µ\82½\81D",
2257                 difgend ? genders[flags.initgend].adj : "",
2258                 (difgend && difalgn) ? "\82©\82Â" : "",
2259                 difalgn ? align_str(u.ualignbase[A_ORIGINAL]) : "");
2260 #endif
2261         enlght_out(buf);
2262     }
2263
2264     /* As of 3.6.2: dungeon level, so that ^X really has all status info as
2265        claimed by the comment below; this reveals more information than
2266        the basic status display, but that's one of the purposes of ^X;
2267        similar information is revealed by #overview; the "You died in
2268        <location>" given by really_done() is more rudimentary than this */
2269     *buf = *tmpbuf = '\0';
2270     if (In_endgame(&u.uz)) {
2271         int egdepth = observable_depth(&u.uz);
2272
2273         (void) endgamelevelname(tmpbuf, egdepth);
2274 #if 0 /*JP*/
2275         Sprintf(buf, "in the endgame, on the %s%s",
2276                 !strncmp(tmpbuf, "Plane", 5) ? "Elemental " : "", tmpbuf);
2277 #else
2278         Sprintf(buf, "\8dÅ\8fI\8e\8e\97û\82Ì%s", tmpbuf);
2279 #endif
2280     } else if (Is_knox(&u.uz)) {
2281         /* this gives away the fact that the knox branch is only 1 level */
2282 /*JP
2283         Sprintf(buf, "on the %s level", dungeons[u.uz.dnum].dname);
2284 */
2285         Sprintf(buf, "%s", dungeons[u.uz.dnum].dname);
2286         /* TODO? maybe phrase it differently when actually inside the fort,
2287            if we're able to determine that (not trivial) */
2288     } else {
2289         char dgnbuf[QBUFSZ];
2290
2291         Strcpy(dgnbuf, dungeons[u.uz.dnum].dname);
2292 #if 0 /*JP*/
2293         if (!strncmpi(dgnbuf, "The ", 4))
2294             *dgnbuf = lowc(*dgnbuf);
2295 #endif
2296 #if 0 /*JP*/
2297         Sprintf(tmpbuf, "level %d",
2298                 In_quest(&u.uz) ? dunlev(&u.uz) : depth(&u.uz));
2299 #else
2300         if (In_quest(&u.uz)) {
2301             Sprintf(tmpbuf, "\91æ%d\8aK\91w", dunlev(&u.uz));
2302         } else {
2303             Sprintf(tmpbuf, "\92n\89º%d\8aK", depth(&u.uz));
2304         }
2305 #endif
2306         /* TODO? maybe extend this bit to include various other automatic
2307            annotations from the dungeon overview code */
2308         if (Is_rogue_level(&u.uz))
2309 /*JP
2310             Strcat(tmpbuf, ", a primitive area");
2311 */
2312             Strcat(tmpbuf, ", \92P\8f\83\82È\90¢\8aE");
2313         else if (Is_bigroom(&u.uz) && !Blind)
2314 /*JP
2315             Strcat(tmpbuf, ", a very big room");
2316 */
2317             Strcat(tmpbuf, ", \82Æ\82Ä\82à\91å\82«\82È\95\94\89®");
2318 #if 0 /*JP*/
2319         Sprintf(buf, "in %s, on %s", dgnbuf, tmpbuf);
2320 #else
2321         Sprintf(buf, "%s\82Ì%s", dgnbuf, tmpbuf);
2322 #endif
2323     }
2324     you_are(buf, "");
2325
2326     /* this is shown even if the 'time' option is off */
2327     if (moves == 1L) {
2328 #if 0 /*JP*/
2329         you_have("just started your adventure", "");
2330 #else
2331         enlght_line(You_, "", "\96`\8c¯\82ð\8aJ\8en\82µ\82½\82Æ\82±\82ë\82¾", "");
2332 #endif
2333     } else {
2334         /* 'turns' grates on the nerves in this context... */
2335 /*JP
2336         Sprintf(buf, "the dungeon %ld turn%s ago", moves, plur(moves));
2337 */
2338         Sprintf(buf, "%ld\83^\81[\83\93\91O\82É\96À\8b{\82É\93ü\82Á\82½", moves);
2339         /* same phrasing for current and final: "entered" is unconditional */
2340 #if 0 /*JP*/
2341         enlght_line(You_, "entered ", buf, "");
2342 #else
2343         enlght_line(You_, "", buf, "");
2344 #endif
2345     }
2346
2347     /* for gameover, these have been obtained in really_done() so that they
2348        won't vary if user leaves a disclosure prompt or --More-- unanswered
2349        long enough for the dynamic value to change between then and now */
2350     if (final ? iflags.at_midnight : midnight()) {
2351 #if 0 /*JP:T*/
2352         enl_msg("It ", "is ", "was ", "the midnight hour", "");
2353 #else
2354         enl_msg("\8e\9e\8aÔ\91Ñ\82Í\90[\96é", "\82¾", "\82¾\82Á\82½", "", "");
2355 #endif
2356     } else if (final ? iflags.at_night : night()) {
2357 #if 0 /*JP:T*/
2358         enl_msg("It ", "is ", "was ", "nighttime", "");
2359 #else
2360         enl_msg("\8e\9e\8aÔ\91Ñ\82Í\96é", "\82¾", "\82¾\82Á\82½", "", "");
2361 #endif
2362     }
2363     /* other environmental factors */
2364     if (flags.moonphase == FULL_MOON || flags.moonphase == NEW_MOON) {
2365         /* [This had "tonight" but has been changed to "in effect".
2366            There is a similar issue to Friday the 13th--it's the value
2367            at the start of the current session but that session might
2368            have dragged on for an arbitrary amount of time.  We want to
2369            report the values that currently affect play--or affected
2370            play when game ended--rather than actual outside situation.] */
2371 #if 0 /*JP:T*/
2372         Sprintf(buf, "a %s moon in effect%s",
2373                 (flags.moonphase == FULL_MOON) ? "full"
2374                 : (flags.moonphase == NEW_MOON) ? "new"
2375                   /* showing these would probably just lead to confusion
2376                      since they have no effect on game play... */
2377                   : (flags.moonphase < FULL_MOON) ? "first quarter"
2378                     : "last quarter",
2379                 /* we don't have access to 'how' here--aside from survived
2380                    vs died--so settle for general platitude */
2381                 final ? " when your adventure ended" : "");
2382         enl_msg("There ", "is ", "was ", buf, "");
2383 #else
2384         Sprintf(buf, "%s%s\8c\8e",
2385                 /* we don't have access to 'how' here--aside from survived
2386                    vs died--so settle for general platitude */
2387                 final ? "\96`\8c¯\82ð\8fI\82¦\82½\82Æ\82«\81C" : "",
2388                 (flags.moonphase == FULL_MOON) ? "\96\9e"
2389                 : (flags.moonphase == NEW_MOON) ? "\90V"
2390                   /* showing these would probably just lead to confusion
2391                      since they have no effect on game play... */
2392                   : (flags.moonphase < FULL_MOON) ? "\8fã\8c·\82Ì"
2393                     : "\89º\8c·\82Ì");
2394         enl_msg("", "\82¾", "\82¾\82Á\82½", buf, "");
2395 #endif
2396     }
2397     if (flags.friday13) {
2398         /* let player know that friday13 penalty is/was in effect;
2399            we don't say "it is/was Friday the 13th" because that was at
2400            the start of the session and it might be past midnight (or
2401            days later if the game has been paused without save/restore),
2402            so phrase this similar to the start up message */
2403 #if 0 /*JP:T*/
2404         Sprintf(buf, " Bad things %s on Friday the 13th.",
2405                 !final ? "can happen"
2406                 : (final == ENL_GAMEOVERALIVE) ? "could have happened"
2407                   /* there's no may to tell whether -1 Luck made a
2408                      difference but hero has died... */
2409                   : "happened");
2410 #else
2411         Sprintf(buf, "\82P\82R\93ú\82Ì\8bà\97j\93ú\82É\82Í\82æ\82­\82È\82¢\82±\82Æ\82ª%s\81D",
2412                 !final ? "\82 \82é"
2413                 : (final == ENL_GAMEOVERALIVE) ? "\82 \82Á\82½\82©\82à\82µ\82ê\82È\82¢"
2414                   /* there's no may to tell whether -1 Luck made a
2415                      difference but hero has died... */
2416                   : "\82 \82Á\82½");
2417 #endif
2418         enlght_out(buf);
2419     }
2420
2421     if (!Upolyd) {
2422         int ulvl = (int) u.ulevel;
2423         /* [flags.showexp currently does not matter; should it?] */
2424
2425         /* experience level is already shown above */
2426 #if 0 /*JP*/
2427         Sprintf(buf, "%-1ld experience point%s", u.uexp, plur(u.uexp));
2428 #else
2429         Sprintf(buf, "\8co\8c±\92l%-1ld\83|\83C\83\93\83g", u.uexp);
2430 #endif
2431         /* TODO?
2432          *  Remove wizard-mode restriction since patient players can
2433          *  determine the numbers needed without resorting to spoilers
2434          *  (even before this started being disclosed for 'final';
2435          *  just enable 'showexp' and look at normal status lines
2436          *  after drinking gain level potions or eating wraith corpses
2437          *  or being level-drained by vampires).
2438          */
2439         if (ulvl < 30 && (final || wizard)) {
2440             long nxtlvl = newuexp(ulvl), delta = nxtlvl - u.uexp;
2441
2442 #if 0 /*JP*/
2443             Sprintf(eos(buf), ", %ld %s%sneeded %s level %d",
2444                     delta, (u.uexp > 0) ? "more " : "",
2445                     /* present tense=="needed", past tense=="were needed" */
2446                     !final ? "" : (delta == 1L) ? "was " : "were ",
2447                     /* "for": grammatically iffy but less likely to wrap */
2448                     (ulvl < 18) ? "to attain" : "for", (ulvl + 1));
2449 #else
2450             Sprintf(eos(buf), "(\83\8c\83x\83\8b%d\82Ü\82Å%ld\83|\83C\83\93\83g)",
2451                     (ulvl + 1), delta);
2452 #endif
2453         }
2454         you_have(buf, "");
2455     }
2456 #ifdef SCORE_ON_BOTL
2457     if (flags.showscore) {
2458         /* describes what's shown on status line, which is an approximation;
2459            only show it here if player has the 'showscore' option enabled */
2460 #if 0 /*JP*/
2461         Sprintf(buf, "%ld%s", botl_score(),
2462                 !final ? "" : " before end-of-game adjustments");
2463         enl_msg("Your score ", "is ", "was ", buf, "");
2464 #else
2465         Sprintf(buf, "%s%ld", botl_score(),
2466                 !final ? "" : "\83Q\81[\83\80\8fI\97¹\8e\9e\82Ì\92²\90®\91O\82Í");
2467         enl_msg("\82 \82È\82½\82Ì\83X\83R\83A\82Í", "\82Å\82 \82é", "\82Å\82 \82Á\82½", buf, "");
2468 #endif
2469     }
2470 #endif
2471 }
2472
2473 /* hit points, energy points, armor class -- essential information which
2474    doesn't fit very well in other categories */
2475 /*ARGSUSED*/
2476 STATIC_OVL void
2477 basics_enlightenment(mode, final)
2478 int mode UNUSED;
2479 int final;
2480 {
2481 #if 0 /*JP*//*unused*/
2482     static char Power[] = "energy points (spell power)";
2483 #endif
2484     char buf[BUFSZ];
2485     int pw = u.uen, hp = (Upolyd ? u.mh : u.uhp),
2486         pwmax = u.uenmax, hpmax = (Upolyd ? u.mhmax : u.uhpmax);
2487
2488     enlght_out(""); /* separator after background */
2489 /*JP
2490     enlght_out("Basics:");
2491 */
2492     enlght_out("\8aî\96{:");
2493
2494     if (hp < 0)
2495         hp = 0;
2496     /* "1 out of 1" rather than "all" if max is only 1; should never happen */
2497 #if 0 /*JP*/
2498     if (hp == hpmax && hpmax > 1)
2499         Sprintf(buf, "all %d hit points", hpmax);
2500     else
2501         Sprintf(buf, "%d out of %d hit point%s", hp, hpmax, plur(hpmax));
2502 #else
2503     Sprintf(buf, "%d\83q\83b\83g\83|\83C\83\93\83g(\8dÅ\91å:%d)", hp, hpmax);
2504 #endif
2505     you_have(buf, "");
2506
2507     /* low max energy is feasible, so handle couple of extra special cases */
2508 #if 0 /*JP*/
2509     if (pwmax == 0 || (pw == pwmax && pwmax == 2)) /* both: "all 2" is silly */
2510         Sprintf(buf, "%s %s", !pwmax ? "no" : "both", Power);
2511     else if (pw == pwmax && pwmax > 2)
2512         Sprintf(buf, "all %d %s", pwmax, Power);
2513     else
2514         Sprintf(buf, "%d out of %d %s", pw, pwmax, Power);
2515 #else
2516     Sprintf(buf, "%d\96\82\97Í\83|\83C\83\93\83g(\8dÅ\91å:%d)", pw, pwmax);
2517 #endif
2518     you_have(buf, "");
2519
2520     if (Upolyd) {
2521         switch (mons[u.umonnum].mlevel) {
2522         case 0:
2523             /* status line currently being explained shows "HD:0" */
2524 /*JP
2525             Strcpy(buf, "0 hit dice (actually 1/2)");
2526 */
2527             Strcpy(buf, "HD0(\8eÀ\8dÛ\82É\82Í1/2)");
2528             break;
2529         case 1:
2530 /*JP
2531             Strcpy(buf, "1 hit die");
2532 */
2533             Strcpy(buf, "HD1");
2534             break;
2535         default:
2536 /*JP
2537             Sprintf(buf, "%d hit dice", mons[u.umonnum].mlevel);
2538 */
2539             Sprintf(buf, "HD%d", mons[u.umonnum].mlevel);
2540             break;
2541         }
2542         you_have(buf, "");
2543     }
2544
2545     Sprintf(buf, "%d", u.uac);
2546 /*JP
2547     enl_msg("Your armor class ", "is ", "was ", buf, "");
2548 */
2549     enl_msg("\82 \82È\82½\82Ì\96h\8cä\92l\82Í", "\82Å\82 \82é", "\82Å\82 \82Á\82½", buf, "");
2550
2551     /* gold; similar to doprgold(#seegold) but without shop billing info;
2552        same amount as shown on status line which ignores container contents */
2553     {
2554 /*JP
2555         static const char Your_wallet[] = "Your wallet ";
2556 */
2557         static const char Your_wallet[] = "\82 \82È\82½\82Ì\8dà\95z";
2558         long umoney = money_cnt(invent);
2559
2560         if (!umoney) {
2561 /*JP
2562             enl_msg(Your_wallet, "is ", "was ", "empty", "");
2563 */
2564             enl_msg(Your_wallet, "\82Å\82 \82é", "\82¾\82Á\82½", "\82Í\8bó", "");
2565         } else {
2566 #if 0 /*JP:T*/
2567             Sprintf(buf, "%ld %s", umoney, currency(umoney));
2568             enl_msg(Your_wallet, "contains ", "contained ", buf, "");
2569 #else
2570             Sprintf(buf, "\82É\82Í%ld%s", umoney, currency(umoney));
2571             enl_msg(Your_wallet, "\93ü\82Á\82Ä\82¢\82é", "\93ü\82Á\82Ä\82¢\82½", buf, "");
2572 #endif
2573         }
2574     }
2575
2576     if (flags.pickup) {
2577         char ocl[MAXOCLASSES + 1];
2578
2579 #if 0 /*JP*//*\8cã\82É\89ñ\82·*/
2580         Strcpy(buf, "on");
2581 #endif
2582         oc_to_str(flags.pickup_types, ocl);
2583 #if 0 /*JP*/
2584         Sprintf(eos(buf), " for %s%s%s",
2585                 *ocl ? "'" : "", *ocl ? ocl : "all types", *ocl ? "'" : "");
2586 #else
2587         Sprintf(buf, "%s%s%s",
2588                 *ocl ? "'" : "", *ocl ? ocl : "\91S\82Ä\82Ì\8eí\97Þ", *ocl ? "'" : "");
2589 #endif
2590         if (flags.pickup_thrown && *ocl) /* *ocl: don't show if 'all types' */
2591 /*JP
2592             Strcat(buf, " plus thrown");
2593 */
2594             Strcat(buf, "\82É\89Á\82¦\82Ä\93\8a\82°\82é\82à\82Ì");
2595         if (apelist)
2596 /*JP
2597             Strcat(buf, ", with exceptions");
2598 */
2599             Strcat(buf, "(\97á\8aO\82 \82è)");
2600 #if 1 /*JP*/
2601         Strcpy(buf, "\82É\91Î\82µ\82Ä\83I\83\93");
2602 #endif
2603     } else
2604 /*JP
2605         Strcpy(buf, "off");
2606 */
2607         Strcpy(buf, "\83I\83t");
2608 /*JP
2609     enl_msg("Autopickup ", "is ", "was ", buf, "");
2610 */
2611     enl_msg("\8e©\93®\8fE\82¢\90Ý\92è\82Í", "\82Å\82 \82é", "\82Å\82 \82Á\82½", buf, "");
2612 }
2613
2614 /* characteristics: expanded version of bottom line strength, dexterity, &c */
2615 STATIC_OVL void
2616 characteristics_enlightenment(mode, final)
2617 int mode;
2618 int final;
2619 {
2620     char buf[BUFSZ];
2621
2622     enlght_out("");
2623 /*JP
2624     Sprintf(buf, "%s Characteristics:", !final ? "Current" : "Final");
2625 */
2626     Sprintf(buf, "%s\93Á\90«\81F", !final ? "\8c»\8dÝ\82Ì" : "\8dÅ\8fI");
2627     enlght_out(buf);
2628
2629     /* bottom line order */
2630     one_characteristic(mode, final, A_STR); /* strength */
2631     one_characteristic(mode, final, A_DEX); /* dexterity */
2632     one_characteristic(mode, final, A_CON); /* constitution */
2633     one_characteristic(mode, final, A_INT); /* intelligence */
2634     one_characteristic(mode, final, A_WIS); /* wisdom */
2635     one_characteristic(mode, final, A_CHA); /* charisma */
2636 }
2637
2638 /* display one attribute value for characteristics_enlightenment() */
2639 STATIC_OVL void
2640 one_characteristic(mode, final, attrindx)
2641 int mode, final, attrindx;
2642 {
2643     extern const char *const attrname[]; /* attrib.c */
2644     boolean hide_innate_value = FALSE, interesting_alimit;
2645     int acurrent, abase, apeak, alimit;
2646     const char *paren_pfx;
2647     char subjbuf[BUFSZ], valubuf[BUFSZ], valstring[32];
2648
2649     /* being polymorphed or wearing certain cursed items prevents
2650        hero from reliably tracking changes to characteristics so
2651        we don't show base & peak values then; when the items aren't
2652        cursed, hero could take them off to check underlying values
2653        and we show those in such case so that player doesn't need
2654        to actually resort to doing that */
2655     if (Upolyd) {
2656         hide_innate_value = TRUE;
2657     } else if (Fixed_abil) {
2658         if (stuck_ring(uleft, RIN_SUSTAIN_ABILITY)
2659             || stuck_ring(uright, RIN_SUSTAIN_ABILITY))
2660             hide_innate_value = TRUE;
2661     }
2662     switch (attrindx) {
2663     case A_STR:
2664         if (uarmg && uarmg->otyp == GAUNTLETS_OF_POWER && uarmg->cursed)
2665             hide_innate_value = TRUE;
2666         break;
2667     case A_DEX:
2668         break;
2669     case A_CON:
2670         if (uwep && uwep->oartifact == ART_OGRESMASHER && uwep->cursed)
2671             hide_innate_value = TRUE;
2672         break;
2673     case A_INT:
2674         if (uarmh && uarmh->otyp == DUNCE_CAP && uarmh->cursed)
2675             hide_innate_value = TRUE;
2676         break;
2677     case A_WIS:
2678         if (uarmh && uarmh->otyp == DUNCE_CAP && uarmh->cursed)
2679             hide_innate_value = TRUE;
2680         break;
2681     case A_CHA:
2682         break;
2683     default:
2684         return; /* impossible */
2685     };
2686     /* note: final disclosure includes MAGICENLIGHTENTMENT */
2687     if ((mode & MAGICENLIGHTENMENT) && !Upolyd)
2688         hide_innate_value = FALSE;
2689
2690     acurrent = ACURR(attrindx);
2691     (void) attrval(attrindx, acurrent, valubuf); /* Sprintf(valubuf,"%d",) */
2692 /*JP
2693     Sprintf(subjbuf, "Your %s ", attrname[attrindx]);
2694 */
2695     Sprintf(subjbuf, "\82 \82È\82½\82Ì%s\82Í", attrname[attrindx]);
2696
2697     if (!hide_innate_value) {
2698         /* show abase, amax, and/or attrmax if acurr doesn't match abase
2699            (a magic bonus or penalty is in effect) or abase doesn't match
2700            amax (some points have been lost to poison or exercise abuse
2701            and are restorable) or attrmax is different from normal human
2702            (while game is in progress; trying to reduce dependency on
2703            spoilers to keep track of such stuff) or attrmax was different
2704            from abase (at end of game; this attribute wasn't maxed out) */
2705         abase = ABASE(attrindx);
2706         apeak = AMAX(attrindx);
2707         alimit = ATTRMAX(attrindx);
2708         /* criterium for whether the limit is interesting varies */
2709         interesting_alimit =
2710             final ? TRUE /* was originally `(abase != alimit)' */
2711                   : (alimit != (attrindx != A_STR ? 18 : STR18(100)));
2712 /*JP
2713         paren_pfx = final ? " (" : " (current; ";
2714 */
2715         paren_pfx = final ? " (" : " (\8c»\8dÝ; ";
2716         if (acurrent != abase) {
2717 #if 0 /*JP:T*/
2718             Sprintf(eos(valubuf), "%sbase:%s", paren_pfx,
2719                     attrval(attrindx, abase, valstring));
2720 #else
2721             Sprintf(eos(valubuf), "%s\8aî\96{:%s", paren_pfx,
2722                     attrval(attrindx, abase, valstring));
2723 #endif
2724             paren_pfx = ", ";
2725         }
2726         if (abase != apeak) {
2727 #if 0 /*JP:T*/
2728             Sprintf(eos(valubuf), "%speak:%s", paren_pfx,
2729                     attrval(attrindx, apeak, valstring));
2730 #else
2731             Sprintf(eos(valubuf), "%s\8dÅ\91å:%s", paren_pfx,
2732                     attrval(attrindx, apeak, valstring));
2733 #endif
2734             paren_pfx = ", ";
2735         }
2736         if (interesting_alimit) {
2737 #if 0 /*JP:T*/
2738             Sprintf(eos(valubuf), "%s%slimit:%s", paren_pfx,
2739                     /* more verbose if exceeding 'limit' due to magic bonus */
2740                     (acurrent > alimit) ? "innate " : "",
2741                     attrval(attrindx, alimit, valstring));
2742 #else
2743             Sprintf(eos(valubuf), "%s%s\8fã\8cÀ:%s", paren_pfx,
2744                     /* more verbose if exceeding 'limit' due to magic bonus */
2745                     (acurrent > alimit) ? "\96{\97\88\82Ì" : "",
2746                     attrval(attrindx, alimit, valstring));
2747 #endif
2748             /* paren_pfx = ", "; */
2749         }
2750         if (acurrent != abase || abase != apeak || interesting_alimit)
2751             Strcat(valubuf, ")");
2752     }
2753 /*JP
2754     enl_msg(subjbuf, "is ", "was ", valubuf, "");
2755 */
2756     enl_msg(subjbuf, "\82¾", "\82¾\82Á\82½", valubuf, "");
2757 }
2758
2759 /* status: selected obvious capabilities, assorted troubles */
2760 STATIC_OVL void
2761 status_enlightenment(mode, final)
2762 int mode;
2763 int final;
2764 {
2765     boolean magic = (mode & MAGICENLIGHTENMENT) ? TRUE : FALSE;
2766     int cap, wtype;
2767     char buf[BUFSZ], youtoo[BUFSZ];
2768     boolean Riding = (u.usteed
2769                       /* if hero dies while dismounting, u.usteed will still
2770                          be set; we want to ignore steed in that situation */
2771                       && !(final == ENL_GAMEOVERDEAD
2772 /*JP
2773                            && !strcmp(killer.name, "riding accident")));
2774 */
2775                            && !strcmp(killer.name, "\8bR\8fæ\8e\96\8cÌ\82Å")));
2776     const char *steedname = (!Riding ? (char *) 0
2777                       : x_monnam(u.usteed,
2778                                  u.usteed->mtame ? ARTICLE_YOUR : ARTICLE_THE,
2779                                  (char *) 0,
2780                                  (SUPPRESS_SADDLE | SUPPRESS_HALLUCINATION),
2781                                  FALSE));
2782
2783     /*\
2784      * Status (many are abbreviated on bottom line; others are or
2785      *     should be discernible to the hero hence to the player)
2786     \*/
2787     enlght_out(""); /* separator after title or characteristics */
2788 /*JP
2789     enlght_out(final ? "Final Status:" : "Current Status:");
2790 */
2791     enlght_out(final ? "\8dÅ\8fI\8fó\91Ô:" : "\8c»\8dÝ\82Ì\8fó\91Ô:");
2792
2793     Strcpy(youtoo, You_);
2794     /* not a traditional status but inherently obvious to player; more
2795        detail given below (attributes section) for magic enlightenment */
2796     if (Upolyd) {
2797 #if 0 /*JP*/
2798         Strcpy(buf, "transformed");
2799         if (ugenocided())
2800             Sprintf(eos(buf), " and %s %s inside",
2801                     final ? "felt" : "feel", udeadinside());
2802         you_are(buf, "");
2803 #else /*JP:TODO:\95Ï\89»+\8bs\8eE\83p\83^\81[\83\93*/
2804         you_are_ing("\95Ï\89»\82µ\82Ä", "");
2805 #endif
2806     }
2807     /* not a trouble, but we want to display riding status before maybe
2808        reporting steed as trapped or hero stuck to cursed saddle */
2809     if (Riding) {
2810 #if 0 /*JP:T*/
2811         Sprintf(buf, "riding %s", steedname);
2812         you_are(buf, "");
2813 #else
2814         Sprintf(buf, "%s\82É\8fæ\82Á\82Ä", steedname);
2815         you_are_ing(buf, "");
2816 #endif
2817 /*JP
2818         Sprintf(eos(youtoo), "and %s ", steedname);
2819 */
2820         Sprintf(youtoo, "\82 \82È\82½\82Æ%s\82Í", steedname);
2821     }
2822     /* other movement situations that hero should always know */
2823     if (Levitation) {
2824         if (Lev_at_will && magic)
2825 /*JP
2826             you_are("levitating, at will", "");
2827 */
2828             you_are_ing("\8e©\95ª\82Ì\88Ó\8eu\82Å\95\82\97V\82µ\82Ä", "");
2829         else
2830 /*JP
2831             enl_msg(youtoo, are, were, "levitating", from_what(LEVITATION));
2832 */
2833             enl_msg(youtoo, "\82¢\82é", "\82¢\82½", "\95\82\97V\82µ\82Ä", from_what(LEVITATION));
2834     } else if (Flying) { /* can only fly when not levitating */
2835 /*JP
2836         enl_msg(youtoo, are, were, "flying", from_what(FLYING));
2837 */
2838         enl_msg(youtoo, "\82¢\82é", "\82¢\82½", "\94ò\82ñ\82Å", from_what(FLYING));
2839     }
2840     if (Underwater) {
2841 /*JP
2842         you_are("underwater", "");
2843 */
2844         enl_msg(You_, "\82¢\82é", "\82¢\82½", "\90\85\96Ê\89º\82É", "");
2845     } else if (u.uinwater) {
2846 /*JP
2847         you_are(Swimming ? "swimming" : "in water", from_what(SWIMMING));
2848 */
2849         enl_msg(You_, Swimming ? "\89j\82¢\82Å" : "\90\85\92\86\82É", "\82¢\82é", "\82¢\82½", from_what(SWIMMING));
2850     } else if (walking_on_water()) {
2851         /* show active Wwalking here, potential Wwalking elsewhere */
2852 #if 0 /*JP*/
2853         Sprintf(buf, "walking on %s",
2854                 is_pool(u.ux, u.uy) ? "water"
2855                 : is_lava(u.ux, u.uy) ? "lava"
2856                   : surface(u.ux, u.uy)); /* catchall; shouldn't happen */
2857         you_are(buf, from_what(WWALKING));
2858 #else
2859         Sprintf(buf, "%s\82Ì\8fã\82ð\95à\82¢\82Ä",
2860                 is_pool(u.ux, u.uy) ? "\90\85"
2861                 : is_lava(u.ux, u.uy) ? "\97n\8aâ"
2862                   : surface(u.ux, u.uy)); /* catchall; shouldn't happen */
2863         you_are_ing(buf, from_what(WWALKING));
2864 #endif
2865     }
2866     if (Upolyd && (u.uundetected || U_AP_TYPE != M_AP_NOTHING))
2867         youhiding(TRUE, final);
2868
2869     /* internal troubles, mostly in the order that prayer ranks them */
2870     if (Stoned) {
2871         if (final && (Stoned & I_SPECIAL))
2872 /*JP
2873             enlght_out(" You turned into stone.");
2874 */
2875             enlght_out(" \82 \82È\82½\82Í\90Î\82É\82È\82Á\82½\81D");
2876         else
2877 /*JP
2878             you_are("turning to stone", "");
2879 */
2880             enl_msg("\82 \82È\82½\82Í", "\82È\82è\82Â\82Â\82 \82é", "\82È\82Á\82½", "\90Î\82É", "");
2881     }
2882     if (Slimed) {
2883         if (final && (Slimed & I_SPECIAL))
2884 /*JP
2885             enlght_out(" You turned into slime.");
2886 */
2887             enlght_out(" \82 \82È\82½\82Í\83X\83\89\83C\83\80\82É\82È\82Á\82½\81D");
2888         else
2889 /*JP
2890             you_are("turning into slime", "");
2891 */
2892             enl_msg("\82 \82È\82½\82Í", "\82È\82è\82Â\82Â\82 \82é", "\82È\82Á\82½", "\83X\83\89\83C\83\80\82É", "");
2893     }
2894     if (Strangled) {
2895         if (u.uburied) {
2896 /*JP
2897             you_are("buried", "");
2898 */
2899             you_are_ing("\92\82\91§\82µ\82Ä", "");
2900         } else {
2901             if (final && (Strangled & I_SPECIAL)) {
2902 /*JP
2903                 enlght_out(" You died from strangulation.");
2904 */
2905                 enlght_out(" \82 \82È\82½\82Í\92\82\91§\8e\80\82µ\82½\81D");
2906             } else {
2907 /*JP
2908                 Strcpy(buf, "being strangled");
2909 */
2910                 Strcpy(buf, "\8eñ\82ð\8di\82ß\82ç\82ê\82Ä");
2911                 if (wizard)
2912                     Sprintf(eos(buf), " (%ld)", (Strangled & TIMEOUT));
2913 /*JP
2914                 you_are(buf, from_what(STRANGLED));
2915 */
2916                 enl_msg("\82 \82È\82½\82Í", "\82¢\82é", "\82¢\82½", buf, from_what(STRANGLED));
2917             }
2918         }
2919     }
2920     if (Sick) {
2921         /* the two types of sickness are lumped together; hero can be
2922            afflicted by both but there is only one timeout; botl status
2923            puts TermIll before FoodPois and death due to timeout reports
2924            terminal illness if both are in effect, so do the same here */
2925         if (final && (Sick & I_SPECIAL)) {
2926 #if 0 /*JP:T*/
2927             Sprintf(buf, " %sdied from %s.", You_, /* has trailing space */
2928                     (u.usick_type & SICK_NONVOMITABLE)
2929                     ? "terminal illness" : "food poisoning");
2930 #else
2931             Sprintf(buf, " %s%s\82Å\8e\80\82ñ\82¾\81D", You_, /* has trailing space */
2932                     (u.usick_type & SICK_NONVOMITABLE)
2933                     ? "\95a\8bC" : "\90H\92\86\93Å");
2934 #endif
2935             enlght_out(buf);
2936         } else {
2937             /* unlike death due to sickness, report the two cases separately
2938                because it is possible to cure one without curing the other */
2939             if (u.usick_type & SICK_NONVOMITABLE)
2940 /*JP
2941                 you_are("terminally sick from illness", "");
2942 */
2943                 enl_msg("\82 \82È\82½\82Í\95a\8bC\82Å\92v\96½\93I\82É\8bC\95ª\82ª\88«", "\82¢", "\82©\82Á\82½", "", "");
2944             if (u.usick_type & SICK_VOMITABLE)
2945 /*JP
2946                 you_are("terminally sick from food poisoning", "");
2947 */
2948                 enl_msg("\82 \82È\82½\82Í\90H\92\86\93Å\82Å\92v\96½\93I\82É\8bC\95ª\82ª\88«", "\82¢", "\82©\82Á\82½", "", "");
2949         }
2950     }
2951     if (Vomiting)
2952 /*JP
2953         you_are("nauseated", "");
2954 */
2955         enl_msg(You_, "\93f\82«\8bC\82ª", "\82 \82é", "\82 \82Á\82½", "");
2956     if (Stunned)
2957 /*JP
2958         you_are("stunned", "");
2959 */
2960         you_are("\82­\82ç\82­\82ç\8fó\91Ô", "");
2961     if (Confusion)
2962 /*JP
2963         you_are("confused", "");
2964 */
2965         you_are("\8d¬\97\90\8fó\91Ô", "");
2966     if (Hallucination)
2967 /*JP
2968         you_are("hallucinating", "");
2969 */
2970         you_are("\8c\8ao\8fó\91Ô", "");
2971     if (Blind) {
2972         /* from_what() (currently wizard-mode only) checks !haseyes()
2973            before u.uroleplay.blind, so we should too */
2974 #if 0 /*JP:T*/
2975         Sprintf(buf, "%s blind",
2976                 !haseyes(youmonst.data) ? "innately"
2977                 : u.uroleplay.blind ? "permanently"
2978                   /* better phrasing desperately wanted... */
2979                   : Blindfolded_only ? "deliberately"
2980                     : "temporarily");
2981 #else
2982         Sprintf(buf, "%s\96Ó\96Ú",
2983                 !haseyes(youmonst.data) ? "\90\82Ü\82ê\82È\82ª\82ç\82É"
2984                 : u.uroleplay.blind ? "\8dP\8bv\93I\82É"
2985                   /* better phrasing desperately wanted... */
2986                   : Blindfolded_only ? "\8cÌ\88Ó\82É"
2987                     : "\88ê\8e\9e\93I\82É");
2988 #endif
2989         if (wizard && (Blinded & TIMEOUT) != 0L
2990             && !u.uroleplay.blind && haseyes(youmonst.data))
2991             Sprintf(eos(buf), " (%ld)", (Blinded & TIMEOUT));
2992         /* !haseyes: avoid "you are innately blind innately" */
2993         you_are(buf, !haseyes(youmonst.data) ? "" : from_what(BLINDED));
2994     }
2995     if (Deaf)
2996 /*JP
2997         you_are("deaf", from_what(DEAF));
2998 */
2999         you_are("\8e¨\82ª\95·\82±\82¦\82È\82¢\8fó\91Ô", from_what(DEAF));
3000
3001     /* external troubles, more or less */
3002     if (Punished) {
3003         if (uball) {
3004 /*JP
3005             Sprintf(buf, "chained to %s", ansimpleoname(uball));
3006 */
3007             Sprintf(buf, "%s\82É\82Â\82È\82ª\82ê\82Ä", ansimpleoname(uball));
3008         } else {
3009             impossible("Punished without uball?");
3010 /*JP
3011             Strcpy(buf, "punished");
3012 */
3013             Strcpy(buf, "\94±\82ð\8eó\82¯\82Ä");
3014         }
3015         you_are(buf, "");
3016     }
3017     if (u.utrap) {
3018         char predicament[BUFSZ];
3019         struct trap *t;
3020         boolean anchored = (u.utraptype == TT_BURIEDBALL);
3021
3022         if (anchored) {
3023 /*JP
3024             Strcpy(predicament, "tethered to something buried");
3025 */
3026             Strcpy(predicament, "\89½\82©\96\84\82Ü\82Á\82Ä\82¢\82é\82à\82Ì\82É\82Â\82È\82ª\82ê\82Ä");
3027         } else if (u.utraptype == TT_INFLOOR || u.utraptype == TT_LAVA) {
3028 /*JP
3029             Sprintf(predicament, "stuck in %s", the(surface(u.ux, u.uy)));
3030 */
3031             Sprintf(predicament, "%s\82É\96\84\82Ü\82Á\82Ä", surface(u.ux, u.uy));
3032         } else {
3033 #if 0 /*JP*/
3034             Strcpy(predicament, "trapped");
3035             if ((t = t_at(u.ux, u.uy)) != 0)
3036                 Sprintf(eos(predicament), " in %s",
3037                         an(defsyms[trap_to_defsym(t->ttyp)].explanation));
3038 #else
3039             predicament[0] = '\0';
3040             if ((t = t_at(u.ux, u.uy)) != 0)
3041                 Sprintf(predicament, "%s\82É",
3042                         defsyms[trap_to_defsym(t->ttyp)].explanation);
3043             Strcat(predicament, "\82Ð\82Á\82©\82©\82Á\82Ä");
3044 #endif
3045         }
3046         if (u.usteed) { /* not `Riding' here */
3047 #if 0 /*JP*/
3048             Sprintf(buf, "%s%s ", anchored ? "you and " : "", steedname);
3049             *buf = highc(*buf);
3050             enl_msg(buf, (anchored ? "are " : "is "),
3051                     (anchored ? "were " : "was "), predicament, "");
3052 #else
3053             Sprintf(buf, "%s%s\82Í", anchored ? "\82 \82È\82½\82Æ" : "", steedname);
3054             enl_msg(buf, "\82¢\82é", "\82¢\82½" , predicament, "");
3055 #endif
3056         } else
3057             you_are(predicament, "");
3058     } /* (u.utrap) */
3059     if (u.uswallow) {
3060 /*JP
3061         Sprintf(buf, "swallowed by %s", a_monnam(u.ustuck));
3062 */
3063         Sprintf(buf, "%s\82É\88ù\82Ý\8d\9e\82Ü\82ê\82Ä", a_monnam(u.ustuck));
3064         if (wizard)
3065             Sprintf(eos(buf), " (%u)", u.uswldtim);
3066         you_are(buf, "");
3067     } else if (u.ustuck) {
3068 #if 0 /*JP*/
3069         Sprintf(buf, "%s %s",
3070                 (Upolyd && sticks(youmonst.data)) ? "holding" : "held by",
3071                 a_monnam(u.ustuck));
3072         you_are(buf, "");
3073 #else
3074         Sprintf(buf, "%s%s",
3075                 a_monnam(u.ustuck),
3076                 (Upolyd && sticks(youmonst.data)) ? "\82ð\95ß\82Ü\82¦\82Ä" : "\82É\95ß\82Ü\82Á\82Ä");
3077         you_are_ing(buf, "");
3078 #endif
3079     }
3080     if (Riding) {
3081         struct obj *saddle = which_armor(u.usteed, W_SADDLE);
3082
3083         if (saddle && saddle->cursed) {
3084 #if 0 /*JP*/
3085             Sprintf(buf, "stuck to %s %s", s_suffix(steedname),
3086                     simpleonames(saddle));
3087             you_are(buf, "");
3088 #else
3089             Sprintf(buf, "%s\82Ì%s\82É\82Â\82©\82Ü\82Á\82Ä", steedname,
3090                     simpleonames(saddle));
3091             you_are_ing(buf, "");
3092 #endif
3093         }
3094     }
3095     if (Wounded_legs) {
3096         /* when mounted, Wounded_legs applies to steed rather than to
3097            hero; we only report steed's wounded legs in wizard mode */
3098         if (u.usteed) { /* not `Riding' here */
3099             if (wizard && steedname) {
3100 #if 0 /*JP*/
3101                 Strcpy(buf, steedname);
3102                 *buf = highc(*buf);
3103                 enl_msg(buf, " has", " had", " wounded legs", "");
3104 #else
3105                 enl_msg(buf, iru, ita, "\82Í\8e\88\82ð\89ö\89ä\82µ\82Ä", "");
3106 #endif
3107             }
3108         } else {
3109 #if 0 /*JP*/
3110             Sprintf(buf, "wounded %s", makeplural(body_part(LEG)));
3111             you_have(buf, "");
3112 #else
3113             Sprintf(buf, "%s\82ð\89ö\89ä\82µ\82Ä", makeplural(body_part(LEG)));
3114             you_are_ing(buf, "");
3115 #endif
3116         }
3117     }
3118     if (Glib) {
3119 #if 0 /*JP*/
3120         Sprintf(buf, "slippery %s", fingers_or_gloves(TRUE));
3121         if (wizard)
3122             Sprintf(eos(buf), " (%ld)", (Glib & TIMEOUT));
3123         you_have(buf, "");
3124 #else
3125         Sprintf(buf, "%s\82ª\82Ê\82é\82Ê\82é\82µ\82Ä", body_part(FINGER));
3126         if (wizard)
3127             Sprintf(eos(buf), " (%ld)", (Glib & TIMEOUT));
3128         enl_msg(buf, iru, ita, "", "");
3129 #endif
3130     }
3131     if (Fumbling) {
3132         if (magic || cause_known(FUMBLING))
3133 /*JP
3134             enl_msg(You_, "fumble", "fumbled", "", from_what(FUMBLING));
3135 */
3136             you_are_ing("\95s\8aí\97p\82É\82È\82Á\82Ä", from_what(FUMBLING));
3137     }
3138     if (Sleepy) {
3139         if (magic || cause_known(SLEEPY)) {
3140             Strcpy(buf, from_what(SLEEPY));
3141             if (wizard)
3142                 Sprintf(eos(buf), " (%ld)", (HSleepy & TIMEOUT));
3143 /*JP
3144             enl_msg("You ", "fall", "fell", " asleep uncontrollably", buf);
3145 */
3146             you_are_ing("\96°\82Á\82Ä", buf);
3147         }
3148     }
3149     /* hunger/nutrition */
3150     if (Hunger) {
3151         if (magic || cause_known(HUNGER))
3152 #if 0 /*JP*/
3153             enl_msg(You_, "hunger", "hungered", " rapidly",
3154                     from_what(HUNGER));
3155 #else
3156             enl_msg("\82 \82È\82½\82Í\82·\82®\82É\95 \82ª\8c¸\82é\8fó\91Ô", "\82Å\82 \82é", "\82¾\82Á\82½", "", "");
3157 #endif
3158     }
3159     Strcpy(buf, hu_stat[u.uhs]); /* hunger status; omitted if "normal" */
3160     mungspaces(buf);             /* strip trailing spaces */
3161     if (*buf) {
3162 #if 0 /*JP*/
3163         *buf = lowc(*buf); /* override capitalization */
3164         if (!strcmp(buf, "weak"))
3165             Strcat(buf, " from severe hunger");
3166         else if (!strncmp(buf, "faint", 5)) /* fainting, fainted */
3167             Strcat(buf, " due to starvation");
3168         you_are(buf, "");
3169 #else
3170         Strcat(buf, "\8fó\91Ô");
3171         you_are(buf, "");
3172 #endif
3173     }
3174     /* encumbrance */
3175     if ((cap = near_capacity()) > UNENCUMBERED) {
3176 #if 0 /*JP*/
3177         const char *adj = "?_?"; /* (should always get overridden) */
3178
3179         Strcpy(buf, enc_stat[cap]);
3180         *buf = lowc(*buf);
3181         switch (cap) {
3182         case SLT_ENCUMBER:
3183             adj = "slightly";
3184             break; /* burdened */
3185         case MOD_ENCUMBER:
3186             adj = "moderately";
3187             break; /* stressed */
3188         case HVY_ENCUMBER:
3189             adj = "very";
3190             break; /* strained */
3191         case EXT_ENCUMBER:
3192             adj = "extremely";
3193             break; /* overtaxed */
3194         case OVERLOADED:
3195             adj = "not possible";
3196             break;
3197         }
3198         Sprintf(eos(buf), "; movement %s %s%s", !final ? "is" : "was", adj,
3199                 (cap < OVERLOADED) ? " slowed" : "");
3200         you_are(buf, "");
3201 #else
3202         Sprintf(buf, "\89×\95¨\82É\82æ\82Á\82Ä%s\8fó\91Ô", enc_stat[cap]);
3203         you_are(buf, "");
3204 #endif
3205     } else {
3206         /* last resort entry, guarantees Status section is non-empty
3207            (no longer needed for that purpose since weapon status added;
3208            still useful though) */
3209 /*JP
3210         you_are("unencumbered", "");
3211 */
3212         you_are("\89×\95¨\82Í\8e×\96\82\82É\82È\82ç\82È\82¢\8fó\91Ô", "");
3213     }
3214
3215     /* report being weaponless; distinguish whether gloves are worn */
3216     if (!uwep) {
3217 #if 0 /*JP*/
3218         you_are(uarmg ? "empty handed" /* gloves imply hands */
3219                       : humanoid(youmonst.data)
3220                          /* hands but no weapon and no gloves */
3221                          ? "bare handed"
3222                          /* alternate phrasing for paws or lack of hands */
3223                          : "not wielding anything",
3224                 "");
3225 #else
3226         enl_msg(You_, "\82¢", "\82©\82Á\82½", "\95\90\8aí\82ð\91\95\94õ\82µ\82Ä\82¢\82È", "");
3227 #endif
3228     /* two-weaponing implies hands (can't be polymorphed) and
3229        a weapon or wep-tool (not other odd stuff) in each hand */
3230     } else if (u.twoweap) {
3231 /*JP
3232         you_are("wielding two weapons at once", "");
3233 */
3234         you_are("\93ñ\93\81\97¬", "");
3235     /* report most weapons by their skill class (so a katana will be
3236        described as a long sword, for instance; mattock and hook are
3237        exceptions), or wielded non-weapon item by its object class */
3238     } else {
3239         const char *what = weapon_descr(uwep);
3240
3241 #if 0 /*JP*/
3242         if (!strcmpi(what, "armor") || !strcmpi(what, "food")
3243             || !strcmpi(what, "venom"))
3244             Sprintf(buf, "wielding some %s", what);
3245         else
3246             Sprintf(buf, "wielding %s",
3247                     (uwep->quan == 1L) ? an(what) : makeplural(what));
3248         you_are(buf, "");
3249 #else
3250         Sprintf(buf, "%s\82ð\91\95\94õ\82µ\82Ä", what);
3251         enl_msg(You_, "\82¢\82é", "\82¢\82½", buf, "");
3252 #endif
3253     }
3254     /*
3255      * Skill with current weapon.  Might help players who've never
3256      * noticed #enhance or decided that it was pointless.
3257      *
3258      * TODO?  Maybe merge wielding line and skill line into one sentence.
3259      */
3260     if ((wtype = uwep_skill_type()) != P_NONE) {
3261         char sklvlbuf[20];
3262         int sklvl = P_SKILL(wtype);
3263         boolean hav = (sklvl != P_UNSKILLED && sklvl != P_SKILLED);
3264
3265         if (sklvl == P_ISRESTRICTED)
3266 /*JP
3267             Strcpy(sklvlbuf, "no");
3268 */
3269             Strcpy(sklvlbuf, "\90§\8cÀ");
3270         else
3271             (void) lcase(skill_level_name(wtype, sklvlbuf));
3272         /* "you have no/basic/expert/master/grand-master skill with <skill>"
3273            or "you are unskilled/skilled in <skill>" */
3274 #if 0 /*JP:T*/
3275         Sprintf(buf, "%s %s %s", sklvlbuf,
3276                 hav ? "skill with" : "in", skill_name(wtype));
3277 #else
3278         Sprintf(buf, "%s\82Ì%s\83X\83L\83\8b", skill_name(wtype), sklvlbuf);
3279 #endif
3280         if (can_advance(wtype, FALSE))
3281 #if 0 /*JP:T*/
3282             Sprintf(eos(buf), " and %s that",
3283                     !final ? "can enhance" : "could have enhanced");
3284 #else
3285             Sprintf(eos(buf), "(\8d\82\82ß\82é\82±\82Æ\82ª\82Å\82«%s)",
3286                     !final ? "\82é" : "\82½");
3287 #endif
3288         if (hav)
3289             you_have(buf, "");
3290         else
3291             you_are(buf, "");
3292     }
3293     /* report 'nudity' */
3294     if (!uarm && !uarmu && !uarmc && !uarms && !uarmg && !uarmf && !uarmh) {
3295         if (u.uroleplay.nudist)
3296 #if 0 /*JP:T*/
3297             enl_msg(You_, "do", "did", " not wear any armor", "");
3298 #else
3299             enl_msg(You_, "\82¢", "\82©\82Á\82½", "\89½\82Ì\8aZ\82à\91\95\94õ\82µ\82È", "");
3300 #endif
3301         else
3302 #if 0 /*JP:T*/
3303             you_are("not wearing any armor", "");
3304 #else
3305             enl_msg(You_, "\82¢", "\82©\82Á\82½", "\89½\82Ì\8aZ\82à\91\95\94õ\82µ\82Ä\82¢\82È", "");
3306 #endif
3307     }
3308 }
3309
3310 /* attributes: intrinsics and the like, other non-obvious capabilities */
3311 STATIC_OVL void
3312 attributes_enlightenment(unused_mode, final)
3313 int unused_mode UNUSED;
3314 int final;
3315 {
3316 #if 0 /*JP*/
3317     static NEARDATA const char if_surroundings_permitted[] =
3318         " if surroundings permitted";
3319 #endif
3320     int ltmp, armpro;
3321     char buf[BUFSZ];
3322
3323     /*\
3324      *  Attributes
3325     \*/
3326     enlght_out("");
3327 /*JP
3328     enlght_out(final ? "Final Attributes:" : "Current Attributes:");
3329 */
3330     enlght_out(final ? "\8dÅ\8fI\91®\90«:" : "\8c»\8dÝ\82Ì\91®\90«:");
3331
3332     if (u.uevent.uhand_of_elbereth) {
3333 #if 0 /*JP:T*/
3334         static const char *const hofe_titles[3] = { "the Hand of Elbereth",
3335                                                     "the Envoy of Balance",
3336                                                     "the Glory of Arioch" };
3337 #else
3338         static const char *const hofe_titles[3] = { "\83G\83\8b\83x\83\8c\83X\82Ì\8cä\8eè",
3339                                                     "\92²\98a\82Ì\8eg\8eÒ",
3340                                                     "\83A\83\8a\83I\83b\83`\82Ì\96¼\97_" };
3341 #endif
3342         you_are(hofe_titles[u.uevent.uhand_of_elbereth - 1], "");
3343     }
3344
3345 /*JP
3346     Sprintf(buf, "%s", piousness(TRUE, "aligned"));
3347 */
3348     Sprintf(buf, "%s", piousness(TRUE, "\90M\8bÂ\90S"));
3349     if (u.ualign.record >= 0)
3350         you_are(buf, "");
3351     else
3352         you_have(buf, "");
3353
3354     if (wizard) {
3355 #if 0 /*JP:T*/
3356         Sprintf(buf, " %d", u.ualign.record);
3357         enl_msg("Your alignment ", "is", "was", buf, "");
3358 #else
3359         Sprintf(buf, "\82 \82È\82½\82Ì\91®\90«\92l\82Í%d", u.ualign.record);
3360         enl_msg(buf, "\82Å\82 \82é", "\82¾\82Á\82½", "", "");
3361 #endif
3362     }
3363
3364     /*** Resistances to troubles ***/
3365     if (Invulnerable)
3366 /*JP
3367         you_are("invulnerable", from_what(INVULNERABLE));
3368 */
3369         you_are("\95s\8e\80\90g", from_what(INVULNERABLE));
3370     if (Antimagic)
3371 /*JP
3372         you_are("magic-protected", from_what(ANTIMAGIC));
3373 */
3374         you_have("\96\82\96@\96h\8cä\94\\97Í", from_what(ANTIMAGIC));
3375     if (Fire_resistance)
3376 /*JP
3377         you_are("fire resistant", from_what(FIRE_RES));
3378 */
3379         you_have("\89Î\82Ö\82Ì\91Ï\90«", from_what(FIRE_RES));
3380     if (Cold_resistance)
3381 /*JP
3382         you_are("cold resistant", from_what(COLD_RES));
3383 */
3384         you_have("\8a¦\82³\82Ö\82Ì\91Ï\90«", from_what(COLD_RES));
3385     if (Sleep_resistance)
3386 /*JP
3387         you_are("sleep resistant", from_what(SLEEP_RES));
3388 */
3389         you_have("\96°\82è\82Ö\82Ì\91Ï\90«", from_what(SLEEP_RES));
3390     if (Disint_resistance)
3391 /*JP
3392         you_are("disintegration-resistant", from_what(DISINT_RES));
3393 */
3394         you_have("\95²\8dÓ\82Ö\82Ì\91Ï\90«", from_what(DISINT_RES));
3395     if (Shock_resistance)
3396 /*JP
3397         you_are("shock resistant", from_what(SHOCK_RES));
3398 */
3399         you_have("\93d\8c\82\82Ö\82Ì\91Ï\90«", from_what(SHOCK_RES));
3400     if (Poison_resistance)
3401 /*JP
3402         you_are("poison resistant", from_what(POISON_RES));
3403 */
3404         you_have("\93Å\82Ö\82Ì\91Ï\90«", from_what(POISON_RES));
3405     if (Acid_resistance)
3406 /*JP
3407         you_are("acid resistant", from_what(ACID_RES));
3408 */
3409         you_have("\8e_\82Ö\82Ì\91Ï\90«", from_what(ACID_RES));
3410     if (Drain_resistance)
3411 /*JP
3412         you_are("level-drain resistant", from_what(DRAIN_RES));
3413 */
3414         you_have("\83\8c\83x\83\8b\83_\83E\83\93\82Ö\82Ì\91Ï\90«", from_what(DRAIN_RES));
3415     if (Sick_resistance)
3416 /*JP
3417         you_are("immune to sickness", from_what(SICK_RES));
3418 */
3419         you_have("\95a\8bC\82É\91Î\82·\82é\96Æ\89u", from_what(SICK_RES));
3420     if (Stone_resistance)
3421 /*JP
3422         you_are("petrification resistant", from_what(STONE_RES));
3423 */
3424         you_have("\90Î\89»\82Ö\82Ì\91Ï\90«", from_what(STONE_RES));
3425     if (Halluc_resistance)
3426 #if 0 /*JP:T*/
3427         enl_msg(You_, "resist", "resisted", " hallucinations",
3428                 from_what(HALLUC_RES));
3429 #else
3430         you_have("\8c\8ao\82Ö\82Ì\91Ï\90«", from_what(HALLUC_RES));
3431 #endif
3432     if (u.uedibility)
3433 /*JP
3434         you_can("recognize detrimental food", "");
3435 */
3436         you_can("\97L\8aQ\82È\90H\97¿\82ð\8e¯\95Ê", "");
3437
3438     /*** Vision and senses ***/
3439     if (!Blind && (Blinded || !haseyes(youmonst.data)))
3440 #if 0 /*JP*/
3441         you_can("see", from_what(-BLINDED)); /* Eyes of the Overworld */
3442 #else /*\81u\92´\90¢\8aE\82Ì\96Ú\82É\82æ\82Á\82Ä\8c©\82é\82±\82Æ\82ª\82Å\82«\82é\81v*/
3443         you_can("\8c©\82é\82±\82Æ\82ª", from_what(-BLINDED)); /* Eyes of the Overworld */
3444 #endif
3445     if (See_invisible) {
3446         if (!Blind)
3447 /*JP
3448             enl_msg(You_, "see", "saw", " invisible", from_what(SEE_INVIS));
3449 */
3450             enl_msg("\82 \82È\82½\82Í\93§\96¾\82È\82à\82Ì\82ð\8c©\82ç\82ê", "\82é", "\82½", "", from_what(SEE_INVIS));
3451         else
3452 #if 0 /*JP:T*/
3453             enl_msg(You_, "will see", "would have seen",
3454                     " invisible when not blind", from_what(SEE_INVIS));
3455 #else
3456             enl_msg(You_, "\82é", "\82½",
3457                     "\96Ó\96Ú\82Å\82È\82¢\82Æ\82«\82É\82Í\93§\96¾\82È\82à\82Ì\82ð\8c©\82ç\82ê", from_what(SEE_INVIS));
3458 #endif
3459     }
3460     if (Blind_telepat)
3461 /*JP
3462         you_are("telepathic", from_what(TELEPAT));
3463 */
3464         you_have("\83e\83\8c\83p\83V\81[", from_what(TELEPAT));
3465     if (Warning)
3466 /*JP
3467         you_are("warned", from_what(WARNING));
3468 */
3469         you_have("\8cx\89ú\94\\97Í", from_what(WARNING));
3470     if (Warn_of_mon && context.warntype.obj) {
3471 #if 0 /*JP:T*/
3472         Sprintf(buf, "aware of the presence of %s",
3473                 (context.warntype.obj & M2_ORC) ? "orcs"
3474                 : (context.warntype.obj & M2_ELF) ? "elves"
3475                 : (context.warntype.obj & M2_DEMON) ? "demons" : something);
3476         you_are(buf, from_what(WARN_OF_MON));
3477 #else
3478         Sprintf(buf, "%s\82Ì\91\8dÝ\82ð\8a´\82\82é\94\\97Í",
3479                 (context.warntype.obj & M2_ORC) ? "\83I\81[\83N"
3480                 : (context.warntype.obj & M2_ELF) ? "\83G\83\8b\83t"
3481                 : (context.warntype.obj & M2_DEMON) ? "\88«\96\82" : something);
3482         you_have(buf, "");
3483 #endif
3484     }
3485     if (Warn_of_mon && context.warntype.polyd) {
3486 #if 0 /*JP*/
3487         Sprintf(buf, "aware of the presence of %s",
3488                 ((context.warntype.polyd & (M2_HUMAN | M2_ELF))
3489                  == (M2_HUMAN | M2_ELF))
3490                     ? "humans and elves"
3491                     : (context.warntype.polyd & M2_HUMAN)
3492                           ? "humans"
3493                           : (context.warntype.polyd & M2_ELF)
3494                                 ? "elves"
3495                                 : (context.warntype.polyd & M2_ORC)
3496                                       ? "orcs"
3497                                       : (context.warntype.polyd & M2_DEMON)
3498                                             ? "demons"
3499                                             : "certain monsters");
3500         you_are(buf, "");
3501 #else
3502         Sprintf(buf, "%s\82Ì\91\8dÝ\82ð\8a´\82\82é\94\\97Í",
3503                 ((context.warntype.polyd & (M2_HUMAN | M2_ELF))
3504                  == (M2_HUMAN | M2_ELF))
3505                     ? "\90l\8aÔ\82Æ\83G\83\8b\83t"
3506                     : (context.warntype.polyd & M2_HUMAN)
3507                           ? "\90l\8aÔ"
3508                           : (context.warntype.polyd & M2_ELF)
3509                                 ? "\83G\83\8b\83t"
3510                                 : (context.warntype.polyd & M2_ORC)
3511                                       ? "\83I\81[\83N"
3512                                       : (context.warntype.polyd & M2_DEMON)
3513                                             ? "\88«\96\82"
3514                                             : "\82 \82é\8eí\82Ì\89ö\95¨");
3515         you_have(buf, "");
3516 #endif
3517     }
3518     if (Warn_of_mon && context.warntype.speciesidx >= LOW_PM) {
3519 #if 0 /*JP*/
3520         Sprintf(buf, "aware of the presence of %s",
3521                 makeplural(mons[context.warntype.speciesidx].mname));
3522         you_are(buf, from_what(WARN_OF_MON));
3523 #else
3524         Sprintf(buf, "%s\82Ì\91\8dÝ\82ð\8a´\82\82é\94\\97Í",
3525                 mons[context.warntype.speciesidx].mname);
3526         you_have(buf, from_what(WARN_OF_MON));
3527 #endif
3528     }
3529     if (Undead_warning)
3530 /*JP
3531         you_are("warned of undead", from_what(WARN_UNDEAD));
3532 */
3533         you_have("\95s\8e\80\82Ì\90\95¨\82Ö\82Ì\8cx\89ú\94\\97Í", from_what(WARN_UNDEAD));
3534     if (Searching)
3535 /*JP
3536         you_have("automatic searching", from_what(SEARCHING));
3537 */
3538         you_have("\92T\8d¸\94\\97Í", from_what(SEARCHING));
3539     if (Clairvoyant)
3540 /*JP
3541         you_are("clairvoyant", from_what(CLAIRVOYANT));
3542 */
3543         you_have("\90ç\97¢\8aá\94\\97Í", from_what(CLAIRVOYANT));
3544     else if ((HClairvoyant || EClairvoyant) && BClairvoyant) {
3545         Strcpy(buf, from_what(-CLAIRVOYANT));
3546 #if 0 /*JP*/
3547         if (!strncmp(buf, " because of ", 12))
3548             /* overwrite substring; strncpy doesn't add terminator */
3549             (void) strncpy(buf, " if not for ", 12);
3550         enl_msg(You_, "could be", "could have been", " clairvoyant", buf);
3551 #else
3552         /*JP:\81u\81c\82É\82æ\82Á\82Ä\81v*/
3553         if (!strncmp(buf, "\82É\82æ\82Á\82Ä", 8))
3554             /*JP:\81u\81c\82ª\82È\82¯\82ê\82Î\81v\82É\8f\91\82«\8a·\82¦\82é*/
3555             strcpy(eos(buf) - 8, "\82ª\82È\82¯\82ê\82Î");
3556         you_have("\90ç\97¢\8aá\94\\97Í", buf);
3557 #endif
3558     }
3559     if (Infravision)
3560 /*JP
3561         you_have("infravision", from_what(INFRAVISION));
3562 */
3563         you_have("\90Ô\8aO\90ü\82ª\8c©\82¦\82é\8e\8b\8ao", from_what(INFRAVISION));
3564     if (Detect_monsters)
3565 /*JP
3566         you_are("sensing the presence of monsters", "");
3567 */
3568         you_have("\89ö\95¨\82ð\92T\82·\94\\97Í", "");
3569     if (u.umconf)
3570 /*JP
3571         you_are("going to confuse monsters", "");
3572 */
3573         you_have("\89ö\95¨\82ð\8d¬\97\90\82³\82¹\82é\94\\97Í", "");
3574
3575     /*** Appearance and behavior ***/
3576     if (Adornment) {
3577         int adorn = 0;
3578
3579         if (uleft && uleft->otyp == RIN_ADORNMENT)
3580             adorn += uleft->spe;
3581         if (uright && uright->otyp == RIN_ADORNMENT)
3582             adorn += uright->spe;
3583         /* the sum might be 0 (+0 ring or two which negate each other);
3584            that yields "you are charismatic" (which isn't pointless
3585            because it potentially impacts seduction attacks) */
3586 #if 0 /*JP*/
3587         Sprintf(buf, "%scharismatic",
3588                 (adorn > 0) ? "more " : (adorn < 0) ? "less " : "");
3589         you_are(buf, from_what(ADORNED));
3590 #else
3591         Sprintf(buf, "\96£\97Í%s\82Ä",
3592                 (adorn > 0) ? "\82ª\91\9d\89Á\82µ" : (adorn < 0) ? "\82ª\8c¸\8f­\82µ" : "\93I\82É\82È\82Á");
3593         enl_msg(You_, "\82Ä\82¢\82é", "\82½", buf, "");
3594 #endif
3595     }
3596     if (Invisible)
3597 /*JP
3598         you_are("invisible", from_what(INVIS));
3599 */
3600         you_are("\93§\96¾", from_what(INVIS));
3601     else if (Invis)
3602 /*JP
3603         you_are("invisible to others", from_what(INVIS));
3604 */
3605         you_are("\91¼\90l\82É\91Î\82µ\82Ä\93§\96¾", from_what(INVIS));
3606     /* ordinarily "visible" is redundant; this is a special case for
3607        the situation when invisibility would be an expected attribute */
3608     else if ((HInvis || EInvis) && BInvis)
3609 /*JP
3610         you_are("visible", from_what(-INVIS));
3611 */
3612         you_are("\95s\93§\96¾", from_what(-INVIS));
3613     if (Displaced)
3614 /*JP
3615         you_are("displaced", from_what(DISPLACED));
3616 */
3617         you_have("\8c\89e\94\\97Í", from_what(DISPLACED));
3618     if (Stealth)
3619 /*JP
3620         you_are("stealthy", from_what(STEALTH));
3621 */
3622         you_have("\90l\96Ú\82ð\93\90\82Þ\94\\97Í", from_what(STEALTH));
3623     if (Aggravate_monster)
3624 #if 0 /*JP*/
3625         enl_msg("You aggravate", "", "d", " monsters",
3626                 from_what(AGGRAVATE_MONSTER));
3627 #else
3628         you_are_ing("\94½\8a´\82ð\82©\82Á\82Ä", from_what(AGGRAVATE_MONSTER));
3629 #endif
3630     if (Conflict)
3631 /*JP
3632         enl_msg("You cause", "", "d", " conflict", from_what(CONFLICT));
3633 */
3634         you_are_ing("\93¬\91\88\82ð\88ø\82«\8bN\82±\82µ\82Ä", from_what(CONFLICT));
3635
3636     /*** Transportation ***/
3637     if (Jumping)
3638 /*JP
3639         you_can("jump", from_what(JUMPING));
3640 */
3641         you_can("\92µ\96ô\82·\82é\82±\82Æ\82ª", from_what(JUMPING));
3642     if (Teleportation)
3643 /*JP
3644         you_can("teleport", from_what(TELEPORT));
3645 */
3646         you_can("\8fu\8aÔ\88Ú\93®\82ª", from_what(TELEPORT));
3647     if (Teleport_control)
3648 /*JP
3649         you_have("teleport control", from_what(TELEPORT_CONTROL));
3650 */
3651         you_have("\8fu\8aÔ\88Ú\93®\82Ì\90§\8cä\94\\97Í", from_what(TELEPORT_CONTROL));
3652     /* actively levitating handled earlier as a status condition */
3653     if (BLevitation) { /* levitation is blocked */
3654         long save_BLev = BLevitation;
3655
3656         BLevitation = 0L;
3657         if (Levitation) {
3658             /* either trapped in the floor or inside solid rock
3659                (or both if chained to buried iron ball and have
3660                moved one step into solid rock somehow) */
3661 #if 0 /*JP*/
3662             boolean trapped = (save_BLev & I_SPECIAL) != 0L,
3663                     terrain = (save_BLev & FROMOUTSIDE) != 0L;
3664
3665             Sprintf(buf, "%s%s%s",
3666                     trapped ? " if not trapped" : "",
3667                     (trapped && terrain) ? " and" : "",
3668                     terrain ? if_surroundings_permitted : "");
3669             enl_msg(You_, "would levitate", "would have levitated", buf, "");
3670 #else
3671             you_are("\8fó\8bµ\82ª\8b\96\82¹\82Î\95\82\97V\82·\82é\8fó\91Ô", "");
3672 #endif
3673         }
3674         BLevitation = save_BLev;
3675     }
3676     /* actively flying handled earlier as a status condition */
3677     if (BFlying) { /* flight is blocked */
3678         long save_BFly = BFlying;
3679
3680         BFlying = 0L;
3681         if (Flying) {
3682 #if 0 /*JP:T*/
3683             enl_msg(You_, "would fly", "would have flown",
3684                     /* wording quibble: for past tense, "hadn't been"
3685                        would sound better than "weren't" (and
3686                        "had permitted" better than "permitted"), but
3687                        "weren't" and "permitted" are adequate so the
3688                        extra complexity to handle that isn't worth it */
3689                     Levitation
3690                        ? " if you weren't levitating"
3691                        : (save_BFly == I_SPECIAL)
3692                           /* this is an oversimpliction; being trapped
3693                              might also be blocking levitation so flight
3694                              would still be blocked after escaping trap */
3695                           ? " if you weren't trapped"
3696                           : (save_BFly == FROMOUTSIDE)
3697                              ? if_surroundings_permitted
3698                              /* two or more of levitation, surroundings,
3699                                 and being trapped in the floor */
3700                              : " if circumstances permitted",
3701                     "");
3702 #else
3703             enl_msg(You_, "\94ò\82Ô\82±\82Æ\82ª\82Å\82«\82é", "\94ò\82Ô\82±\82Æ\82ª\82Å\82«\82½",
3704                     /* wording quibble: for past tense, "hadn't been"
3705                        would sound better than "weren't" (and
3706                        "had permitted" better than "permitted"), but
3707                        "weren't" and "permitted" are adequate so the
3708                        extra complexity to handle that isn't worth it */
3709                     Levitation
3710                        ? "\95\82\97V\82µ\82Ä\82¢\82È\82¯\82ê\82Î"
3711                        : (save_BFly == I_SPECIAL)
3712                           /* this is an oversimpliction; being trapped
3713                              might also be blocking levitation so flight
3714                              would still be blocked after escaping trap */
3715                           ? "\95ß\82Ü\82Á\82Ä\82¢\82È\82¯\82ê\82Î"
3716                           : (save_BFly == FROMOUTSIDE)
3717                              ? "\8fó\8bµ\82ª\8b\96\82¹\82Î"
3718                              /* two or more of levitation, surroundings,
3719                                 and being trapped in the floor */
3720                              : "\8e\96\8fî\82ª\8b\96\82¹\82Î",
3721                     "");
3722 #endif
3723         }
3724         BFlying = save_BFly;
3725     }
3726     /* actively walking on water handled earlier as a status condition */
3727     if (Wwalking && !walking_on_water())
3728 /*JP
3729         you_can("walk on water", from_what(WWALKING));
3730 */
3731         you_can("\90\85\82Ì\8fã\82ð\95à\82­\82±\82Æ\82ª", from_what(WWALKING));
3732     /* actively swimming (in water but not under it) handled earlier */
3733     if (Swimming && (Underwater || !u.uinwater))
3734 /*JP
3735         you_can("swim", from_what(SWIMMING));
3736 */
3737         you_can("\89j\82®\82±\82Æ\82ª", from_what(SWIMMING));
3738     if (Breathless)
3739 /*JP
3740         you_can("survive without air", from_what(MAGICAL_BREATHING));
3741 */
3742         you_can("\8bó\8bC\82È\82µ\82Å\90\82«\89\84\82Ñ\82é\82±\82Æ\82ª", from_what(MAGICAL_BREATHING));
3743     else if (Amphibious)
3744 /*JP
3745         you_can("breathe water", from_what(MAGICAL_BREATHING));
3746 */
3747         you_can("\90\85\92\86\82Å\8cÄ\8bz\82ª", from_what(MAGICAL_BREATHING));
3748     if (Passes_walls)
3749 /*JP
3750         you_can("walk through walls", from_what(PASSES_WALLS));
3751 */
3752         you_can("\95Ç\82ð\92Ê\82è\94²\82¯\82é\82±\82Æ\82ª", from_what(PASSES_WALLS));
3753
3754     /*** Physical attributes ***/
3755     if (Regeneration)
3756 /*JP
3757         enl_msg("You regenerate", "", "d", "", from_what(REGENERATION));
3758 */
3759         you_have("\8dÄ\90\94\\97Í", from_what(REGENERATION));
3760     if (Slow_digestion)
3761 /*JP
3762         you_have("slower digestion", from_what(SLOW_DIGESTION));
3763 */
3764         enl_msg("\90H\95¨\82Ì\8fÁ\89»\82ª\92x", "\82¢", "\82©\82Á\82½", "", from_what(SLOW_DIGESTION));
3765     if (u.uhitinc)
3766 /*JP
3767         you_have(enlght_combatinc("to hit", u.uhitinc, final, buf), "");
3768 */
3769         you_have(enlght_combatinc("\96½\92\86\97¦", u.uhitinc, final, buf), "");
3770     if (u.udaminc)
3771 /*JP
3772         you_have(enlght_combatinc("damage", u.udaminc, final, buf), "");
3773 */
3774         you_have(enlght_combatinc("\83_\83\81\81[\83W", u.udaminc, final, buf), "");
3775     if (u.uspellprot || Protection) {
3776         int prot = 0;
3777
3778         if (uleft && uleft->otyp == RIN_PROTECTION)
3779             prot += uleft->spe;
3780         if (uright && uright->otyp == RIN_PROTECTION)
3781             prot += uright->spe;
3782         if (HProtection & INTRINSIC)
3783             prot += u.ublessed;
3784         prot += u.uspellprot;
3785         if (prot)
3786 /*JP
3787             you_have(enlght_combatinc("defense", prot, final, buf), "");
3788 */
3789             you_have(enlght_combatinc("\96h\8cä", prot, final, buf), "");
3790     }
3791     if ((armpro = magic_negation(&youmonst)) > 0) {
3792         /* magic cancellation factor, conferred by worn armor */
3793         static const char *const mc_types[] = {
3794 #if 0 /*JP:T*/
3795             "" /*ordinary*/, "warded", "guarded", "protected",
3796 #else
3797             "" /*ordinary*/, "\89q\82ç\82ê\82Ä", "\8cì\82ç\82ê\82Ä", "\8eç\82ç\82ê\82Ä",
3798 #endif
3799         };
3800         /* sanity check */
3801         if (armpro >= SIZE(mc_types))
3802             armpro = SIZE(mc_types) - 1;
3803 /*JP
3804         you_are(mc_types[armpro], "");
3805 */
3806         you_are_ing(mc_types[armpro], "");
3807     }
3808     if (Half_physical_damage)
3809         enlght_halfdmg(HALF_PHDAM, final);
3810     if (Half_spell_damage)
3811         enlght_halfdmg(HALF_SPDAM, final);
3812     /* polymorph and other shape change */
3813     if (Protection_from_shape_changers)
3814 #if 0 /*JP*/
3815         you_are("protected from shape changers",
3816                 from_what(PROT_FROM_SHAPE_CHANGERS));
3817 #else
3818         you_have("\95Ï\89»\89ö\95¨\82Ö\82Ì\91Ï\90«", from_what(PROT_FROM_SHAPE_CHANGERS));
3819 #endif
3820     if (Unchanging) {
3821         const char *what = 0;
3822
3823         if (!Upolyd) /* Upolyd handled below after current form */
3824 /*JP
3825             you_can("not change from your current form",
3826 */
3827             you_are("\8c»\8dÝ\82Ì\8ep\82©\82ç\95Ï\89»\82Å\82«\82È\82¢\8fó\91Ô",
3828                     from_what(UNCHANGING));
3829         /* blocked shape changes */
3830         if (Polymorph)
3831 /*JP
3832             what = !final ? "polymorph" : "have polymorphed";
3833 */
3834             what = "\95Ï\89»\82µ\82Ä";
3835         else if (u.ulycn >= LOW_PM)
3836 /*JP
3837             what = !final ? "change shape" : "have changed shape";
3838 */
3839             what = "\8ep\82ð\95Ï\82¦\82Ä";
3840         if (what) {
3841 #if 0 /*JP*/
3842             Sprintf(buf, "would %s periodically", what);
3843             /* omit from_what(UNCHANGING); too verbose */
3844             enl_msg(You_, buf, buf, " if not locked into your current form",
3845                     "");
3846 #else
3847             Sprintf(buf, "\82à\82µ\8c»\8dÝ\82Ì\8ep\82É\8cÅ\92è\82³\82ê\82Ä\82¢\82È\82¯\82ê\82Î\92è\8aú\93I\82É%s", what);
3848             you_are_ing(buf, "");
3849 #endif
3850         }
3851     } else if (Polymorph) {
3852 /*JP
3853         you_are("polymorphing periodically", from_what(POLYMORPH));
3854 */
3855         you_are("\92è\8aú\93I\82É\95Ï\89»\82µ\82Ä", from_what(POLYMORPH));
3856     }
3857     if (Polymorph_control)
3858 /*JP
3859         you_have("polymorph control", from_what(POLYMORPH_CONTROL));
3860 */
3861         you_have("\95Ï\89»\82Ì\90§\8cä\94\\97Í", from_what(POLYMORPH_CONTROL));
3862     if (Upolyd && u.umonnum != u.ulycn
3863         /* if we've died from turning into slime, we're polymorphed
3864            right now but don't want to list it as a temporary attribute
3865            [we need a more reliable way to detect this situation] */
3866         && !(final == ENL_GAMEOVERDEAD
3867              && u.umonnum == PM_GREEN_SLIME && !Unchanging)) {
3868         /* foreign shape (except were-form which is handled below) */
3869 /*JP
3870         Sprintf(buf, "polymorphed into %s", an(youmonst.data->mname));
3871 */
3872         Sprintf(buf, "%s\82É\95Ï\89»\82µ\82Ä", youmonst.data->mname);
3873         if (wizard)
3874             Sprintf(eos(buf), " (%d)", u.mtimedone);
3875         you_are(buf, "");
3876     }
3877     if (lays_eggs(youmonst.data) && flags.female) /* Upolyd */
3878 /*JP
3879         you_can("lay eggs", "");
3880 */
3881         you_can("\97\91\82ð\8eY\82Þ\82±\82Æ\82ª", "");
3882     if (u.ulycn >= LOW_PM) {
3883 #if 0 /*JP*/
3884         /* "you are a werecreature [in beast form]" */
3885         Strcpy(buf, an(mons[u.ulycn].mname));
3886         if (u.umonnum == u.ulycn) {
3887             Strcat(buf, " in beast form");
3888             if (wizard)
3889                 Sprintf(eos(buf), " (%d)", u.mtimedone);
3890         }
3891 #else
3892         /*JP:\81u\82 \82È\82½\82Í[\8fb\82Ì\8ep\82Ì]\81\9b\81\9b\90l\8aÔ\82Å\82 \82é\81v*/
3893         buf[0] = '\0';
3894         if (u.umonnum == u.ulycn) {
3895             Strcpy(buf, "\8fb\82Ì\8ep\82Ì");
3896             if (wizard)
3897                 Sprintf(eos(buf), " (%d)", u.mtimedone);
3898         }
3899         Strcat(buf, mons[u.ulycn].mname);
3900 #endif
3901         you_are(buf, "");
3902     }
3903     if (Unchanging && Upolyd) /* !Upolyd handled above */
3904 /*JP
3905         you_can("not change from your current form", from_what(UNCHANGING));
3906 */
3907         enl_msg("\8d¡\82Ì\8ep\82©\82ç\95Ï\89»\82·\82é\82±\82Æ\82ª\82Å\82«\82È", "\82¢", "\82©\82Á\82½", "", from_what(UNCHANGING));
3908     if (Hate_silver)
3909 /*JP
3910         you_are("harmed by silver", "");
3911 */
3912         enl_msg("\82 \82È\82½\82Í\8bâ\82É\8eã", "\82¢", "\82©\82Á\82½", "", "");
3913     /* movement and non-armor-based protection */
3914     if (Fast)
3915 /*JP
3916         you_are(Very_fast ? "very fast" : "fast", from_what(FAST));
3917 */
3918         you_have(Very_fast ? "\82Æ\82Ä\82à\91f\91\81\82­\8ds\93®\82·\82é\94\\97Í" : "\91f\91\81\82­\8ds\93®\82·\82é\94\\97Í", from_what(FAST));
3919     if (Reflecting)
3920 /*JP
3921         you_have("reflection", from_what(REFLECTING));
3922 */
3923         you_have("\94½\8eË\94\\97Í", from_what(REFLECTING));
3924     if (Free_action)
3925 /*JP
3926         you_have("free action", from_what(FREE_ACTION));
3927 */
3928         you_have("\8dS\91©\82³\82ê\82È\82¢\94\\97Í", from_what(FREE_ACTION));
3929     if (Fixed_abil)
3930 /*JP
3931         you_have("fixed abilities", from_what(FIXED_ABIL));
3932 */
3933         enl_msg("\94\\97Í\82ª\95Ï\89»\82µ\82È", "\82¢", "\82©\82Á\82½", "", from_what(FIXED_ABIL));
3934     if (Lifesaved)
3935 /*JP
3936         enl_msg("Your life ", "will be", "would have been", " saved", "");
3937 */
3938         enl_msg("\82 \82È\82½\82Ì\90\96½\82Í\95Û\91\82³\82ê\82Ä", iru, ita, "", "");
3939
3940     /*** Miscellany ***/
3941     if (Luck) {
3942         ltmp = abs((int) Luck);
3943 #if 0 /*JP:T*/
3944         Sprintf(buf, "%s%slucky",
3945                 ltmp >= 10 ? "extremely " : ltmp >= 5 ? "very " : "",
3946                 Luck < 0 ? "un" : "");
3947 #else
3948         Sprintf(buf, "%s%s",
3949                 ltmp >= 10 ? "\96Ò\97ó\82É" : ltmp >= 5 ? "\82Æ\82Ä\82à" : "",
3950                 Luck < 0 ? "\95s\8dK" : "\8dK\95\9f");
3951 #endif
3952         if (wizard)
3953             Sprintf(eos(buf), " (%d)", Luck);
3954         you_are(buf, "");
3955     } else if (wizard)
3956 /*JP
3957         enl_msg("Your luck ", "is", "was", " zero", "");
3958 */
3959         enl_msg("\82 \82È\82½\82Ì\89^\82Í\83[\83\8d", "\82Å\82 \82é", "\82¾\82Á\82½", "", "");
3960     if (u.moreluck > 0)
3961 /*JP
3962         you_have("extra luck", "");
3963 */
3964         you_have("\82³\82ç\82È\82é\8dK\89^", "");
3965     else if (u.moreluck < 0)
3966 /*JP
3967         you_have("reduced luck", "");
3968 */
3969         you_have("\82³\82ç\82È\82é\95s\89^", "");
3970     if (carrying(LUCKSTONE) || stone_luck(TRUE)) {
3971         ltmp = stone_luck(FALSE);
3972         if (ltmp <= 0)
3973 /*JP
3974             enl_msg("Bad luck ", "does", "did", " not time out for you", "");
3975 */
3976             enl_msg("\95s\89^\82Í\8e\9e\8aÔ\90Ø\82ê\82É\82È\82ç\82È", "\82¢", "\82©\82Á\82½", "", "");
3977         if (ltmp >= 0)
3978 /*JP
3979             enl_msg("Good luck ", "does", "did", " not time out for you", "");
3980 */
3981             enl_msg("\8dK\89^\82Í\8e\9e\8aÔ\90Ø\82ê\82É\82È\82ç\82È", "\82¢", "\82©\82Á\82½", "", "");
3982     }
3983
3984     if (u.ugangr) {
3985 #if 0 /*JP*/
3986         Sprintf(buf, " %sangry with you",
3987                 u.ugangr > 6 ? "extremely " : u.ugangr > 3 ? "very " : "");
3988 #else
3989         Sprintf(buf, "%s\82Í%s\93{\82Á\82Ä%s", u_gname(),
3990                 u.ugangr > 6 ? "\96Ò\97ó\82É" : u.ugangr > 3 ? "\82Æ\82Ä\82à" : "", final ? ita : iru);
3991 #endif
3992         if (wizard)
3993             Sprintf(eos(buf), " (%d)", u.ugangr);
3994 #if 0 /*JP*/
3995         enl_msg(u_gname(), " is", " was", buf, "");
3996 #else
3997         enl_msg(buf, "", "", "", "");
3998 #endif
3999     } else {
4000         /*
4001          * We need to suppress this when the game is over, because death
4002          * can change the value calculated by can_pray(), potentially
4003          * resulting in a false claim that you could have prayed safely.
4004          */
4005         if (!final) {
4006 #if 0 /*JP*/
4007 #if 0
4008             /* "can [not] safely pray" vs "could [not] have safely prayed" */
4009             Sprintf(buf, "%s%ssafely pray%s", can_pray(FALSE) ? "" : "not ",
4010                     final ? "have " : "", final ? "ed" : "");
4011 #else
4012             Sprintf(buf, "%ssafely pray", can_pray(FALSE) ? "" : "not ");
4013 #endif
4014             if (wizard)
4015                 Sprintf(eos(buf), " (%d)", u.ublesscnt);
4016             you_can(buf, "");
4017 #else /*JP*/
4018             Sprintf(buf, "\82 \82È\82½\82Í\88À\91S\82É\8bF\82é\82±\82Æ\82ª");
4019             Strcat(buf, can_pray(FALSE) ? can : "\82Å\82«\82È\82¢");
4020             if (wizard)
4021               Sprintf(eos(buf), " (%d)", u.ublesscnt);
4022             enl_msg(buf, "", "", "", "");
4023 #endif
4024         }
4025     }
4026
4027 #ifdef DEBUG
4028     /* named fruit debugging (doesn't really belong here...); to enable,
4029        include 'fruit' in DEBUGFILES list (even though it isn't a file...) */
4030     if (wizard && explicitdebug("fruit")) {
4031         struct fruit *f;
4032
4033         reorder_fruit(TRUE); /* sort by fruit index, from low to high;
4034                               * this modifies the ffruit chain, so could
4035                               * possibly mask or even introduce a problem,
4036                               * but it does useful sanity checking */
4037         for (f = ffruit; f; f = f->nextf) {
4038 /*JP
4039             Sprintf(buf, "Fruit #%d ", f->fid);
4040 */
4041             Sprintf(buf, "fruit $%d \82Í", f->fid);
4042 /*JP
4043             enl_msg(buf, "is ", "was ", f->fname, "");
4044 */
4045             enl_msg(buf, "\82¾", "\82¾\82Á\82½", f->fname, "");
4046         }
4047 /*JP
4048         enl_msg("The current fruit ", "is ", "was ", pl_fruit, "");
4049 */
4050         enl_msg("\8c»\8dÝ\82Ì fruit \82Í", "\82¾", "\82¾\82Á\82½", pl_fruit, "");
4051         Sprintf(buf, "%d", flags.made_fruit);
4052 /*JP
4053         enl_msg("The made fruit flag ", "is ", "was ", buf, "");
4054 */
4055         enl_msg("made fruit flag \82Í", "\82¾", "\82¾\82Á\82½", buf, "");
4056     }
4057 #endif
4058
4059     {
4060         const char *p;
4061
4062         buf[0] = '\0';
4063         if (final < 2) { /* still in progress, or quit/escaped/ascended */
4064 /*JP
4065             p = "survived after being killed ";
4066 */
4067             p = "\8e\80\82ñ\82¾\8cã\95\9c\8a\88\82µ\82Ä\82¢\82½";
4068             switch (u.umortality) {
4069             case 0:
4070 /*JP
4071                 p = !final ? (char *) 0 : "survived";
4072 */
4073                 p = !final ? (char *)0 : "\90\82«\89\84\82Ñ\82½";
4074                 break;
4075             case 1:
4076 /*JP
4077                 Strcpy(buf, "once");
4078 */
4079                 Strcpy(buf, "\88ê\93x");
4080                 break;
4081             case 2:
4082 /*JP
4083                 Strcpy(buf, "twice");
4084 */
4085                 Strcpy(buf, "\93ñ\93x");
4086                 break;
4087             case 3:
4088 /*JP
4089                 Strcpy(buf, "thrice");
4090 */
4091                 Strcpy(buf, "\8eO\93x");
4092                 break;
4093             default:
4094 /*JP
4095                 Sprintf(buf, "%d times", u.umortality);
4096 */
4097                 Sprintf(buf, "%d\89ñ", u.umortality);
4098                 break;
4099             }
4100         } else { /* game ended in character's death */
4101 /*JP
4102             p = "are dead";
4103 */
4104             p = "\8e\80\82ñ\82Å\82¢\82é";
4105             switch (u.umortality) {
4106             case 0:
4107                 impossible("dead without dying?");
4108             case 1:
4109                 break; /* just "are dead" */
4110             default:
4111 #if 0 /*JP:T*/
4112                 Sprintf(buf, " (%d%s time!)", u.umortality,
4113                         ordin(u.umortality));
4114 #else
4115                  Sprintf(buf, "(%d\89ñ\81I)", u.umortality);
4116 #endif
4117                 break;
4118             }
4119         }
4120         if (p)
4121 /*JP
4122             enl_msg(You_, "have been killed ", p, buf, "");
4123 */
4124             enl_msg(You_, "\8e\80\82ñ\82Å\82¢\82é", p, buf, "");
4125     }
4126 }
4127
4128 #if 0  /* no longer used */
4129 STATIC_DCL boolean NDECL(minimal_enlightenment);
4130
4131 /*
4132  * Courtesy function for non-debug, non-explorer mode players
4133  * to help refresh them about who/what they are.
4134  * Returns FALSE if menu cancelled (dismissed with ESC), TRUE otherwise.
4135  */
4136 STATIC_OVL boolean
4137 minimal_enlightenment()
4138 {
4139     winid tmpwin;
4140     menu_item *selected;
4141     anything any;
4142     int genidx, n;
4143     char buf[BUFSZ], buf2[BUFSZ];
4144     static const char untabbed_fmtstr[] = "%-15s: %-12s";
4145     static const char untabbed_deity_fmtstr[] = "%-17s%s";
4146     static const char tabbed_fmtstr[] = "%s:\t%-12s";
4147     static const char tabbed_deity_fmtstr[] = "%s\t%s";
4148     static const char *fmtstr;
4149     static const char *deity_fmtstr;
4150
4151     fmtstr = iflags.menu_tab_sep ? tabbed_fmtstr : untabbed_fmtstr;
4152     deity_fmtstr = iflags.menu_tab_sep ? tabbed_deity_fmtstr
4153                                        : untabbed_deity_fmtstr;
4154     any = zeroany;
4155     buf[0] = buf2[0] = '\0';
4156     tmpwin = create_nhwindow(NHW_MENU);
4157     start_menu(tmpwin);
4158     add_menu(tmpwin, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
4159 /*JP
4160              "Starting", FALSE);
4161 */
4162              "\8aJ\8en", FALSE);
4163
4164     /* Starting name, race, role, gender */
4165 /*JP
4166     Sprintf(buf, fmtstr, "name", plname);
4167 */
4168     Sprintf(buf, fmtstr, "\96¼\91O", plname);
4169     add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4170 /*JP
4171     Sprintf(buf, fmtstr, "race", urace.noun);
4172 */
4173     Sprintf(buf, fmtstr, "\8eí\91°", urace.noun);
4174     add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4175 /*JP
4176     Sprintf(buf, fmtstr, "role",
4177 */
4178     Sprintf(buf, fmtstr, "\90E\8bÆ",
4179             (flags.initgend && urole.name.f) ? urole.name.f : urole.name.m);
4180     add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4181 /*JP
4182     Sprintf(buf, fmtstr, "gender", genders[flags.initgend].adj);
4183 */
4184     Sprintf(buf, fmtstr, "\90«\95Ê", genders[flags.initgend].adj);
4185     add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4186
4187     /* Starting alignment */
4188 /*JP
4189     Sprintf(buf, fmtstr, "alignment", align_str(u.ualignbase[A_ORIGINAL]));
4190 */
4191     Sprintf(buf, fmtstr, "\91®\90«", align_str(u.ualignbase[A_ORIGINAL]));
4192     add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4193
4194     /* Current name, race, role, gender */
4195     add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, "", FALSE);
4196     add_menu(tmpwin, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
4197 /*JP
4198              "Current", FALSE);
4199 */
4200              "\8c»\8dÝ", FALSE);
4201 /*JP
4202     Sprintf(buf, fmtstr, "race", Upolyd ? youmonst.data->mname : urace.noun);
4203 */
4204     Sprintf(buf, fmtstr, "\8eí\91°", Upolyd ? youmonst.data->mname : urace.noun);
4205     add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4206     if (Upolyd) {
4207 /*JP
4208         Sprintf(buf, fmtstr, "role (base)",
4209 */
4210         Sprintf(buf, fmtstr, "\90E\8bÆ(\8aî\96{)",
4211                 (u.mfemale && urole.name.f) ? urole.name.f
4212                                             : urole.name.m);
4213         add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4214     } else {
4215 /*JP
4216         Sprintf(buf, fmtstr, "role",
4217 */
4218         Sprintf(buf, fmtstr, "\90E\8bÆ",
4219                 (flags.female && urole.name.f) ? urole.name.f
4220                                                : urole.name.m);
4221         add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4222     }
4223     /* don't want poly_gender() here; it forces `2' for non-humanoids */
4224     genidx = is_neuter(youmonst.data) ? 2 : flags.female;
4225 /*JP
4226     Sprintf(buf, fmtstr, "gender", genders[genidx].adj);
4227 */
4228     Sprintf(buf, fmtstr, "\90«\95Ê", genders[genidx].adj);
4229     add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4230     if (Upolyd && (int) u.mfemale != genidx) {
4231 /*JP
4232         Sprintf(buf, fmtstr, "gender (base)", genders[u.mfemale].adj);
4233 */
4234         Sprintf(buf, fmtstr, "\90«\95Ê(\8aî\96{)", genders[u.mfemale].adj);
4235         add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4236     }
4237
4238     /* Current alignment */
4239 /*JP
4240     Sprintf(buf, fmtstr, "alignment", align_str(u.ualign.type));
4241 */
4242     Sprintf(buf, fmtstr, "\91®\90«", align_str(u.ualign.type));
4243     add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4244
4245     /* Deity list */
4246     add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, "", FALSE);
4247     add_menu(tmpwin, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
4248 /*JP
4249              "Deities", FALSE);
4250 */
4251              "\90_", FALSE);
4252 #if 0 /*JP:T*/
4253     Sprintf(buf2, deity_fmtstr, align_gname(A_CHAOTIC),
4254             (u.ualignbase[A_ORIGINAL] == u.ualign.type
4255              && u.ualign.type == A_CHAOTIC)               ? " (s,c)"
4256                 : (u.ualignbase[A_ORIGINAL] == A_CHAOTIC) ? " (s)"
4257                 : (u.ualign.type   == A_CHAOTIC)          ? " (c)" : "");
4258 #else
4259     Sprintf(buf2, deity_fmtstr, align_gname(A_CHAOTIC),
4260             (u.ualignbase[A_ORIGINAL] == u.ualign.type
4261              && u.ualign.type == A_CHAOTIC)               ? " (\8f\89\81C\8c»)"
4262                 : (u.ualignbase[A_ORIGINAL] == A_CHAOTIC) ? " (\8f\89)"
4263                 : (u.ualign.type   == A_CHAOTIC)          ? " (\8c»)" : "");
4264 #endif
4265 /*JP
4266     Sprintf(buf, fmtstr, "Chaotic", buf2);
4267 */
4268     Sprintf(buf, fmtstr, "\8d¬\93×", buf2);
4269     add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4270
4271 #if 0 /*JP:T*/
4272     Sprintf(buf2, deity_fmtstr, align_gname(A_NEUTRAL),
4273             (u.ualignbase[A_ORIGINAL] == u.ualign.type
4274              && u.ualign.type == A_NEUTRAL)               ? " (s,c)"
4275                 : (u.ualignbase[A_ORIGINAL] == A_NEUTRAL) ? " (s)"
4276                 : (u.ualign.type   == A_NEUTRAL)          ? " (c)" : "");
4277 #else
4278     Sprintf(buf2, deity_fmtstr, align_gname(A_NEUTRAL),
4279             (u.ualignbase[A_ORIGINAL] == u.ualign.type
4280              && u.ualign.type == A_NEUTRAL)               ? " (\8f\89\81C\8c»)"
4281                 : (u.ualignbase[A_ORIGINAL] == A_NEUTRAL) ? " (\8f\89)"
4282                 : (u.ualign.type   == A_NEUTRAL)          ? " (\8c»)" : "");
4283 #endif
4284 /*JP
4285     Sprintf(buf, fmtstr, "Neutral", buf2);
4286 */
4287     Sprintf(buf, fmtstr, "\92\86\97§", buf2);
4288     add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4289
4290 #if 0 /*JP:T*/
4291     Sprintf(buf2, deity_fmtstr, align_gname(A_LAWFUL),
4292             (u.ualignbase[A_ORIGINAL] == u.ualign.type
4293              && u.ualign.type == A_LAWFUL)                ? " (s,c)"
4294                 : (u.ualignbase[A_ORIGINAL] == A_LAWFUL)  ? " (s)"
4295                 : (u.ualign.type   == A_LAWFUL)           ? " (c)" : "");
4296 #else
4297     Sprintf(buf2, deity_fmtstr, align_gname(A_LAWFUL),
4298             (u.ualignbase[A_ORIGINAL] == u.ualign.type
4299              && u.ualign.type == A_LAWFUL)                ? " (\8f\89\81C\8c»)"
4300                 : (u.ualignbase[A_ORIGINAL] == A_LAWFUL)  ? " (\8f\89)"
4301                 : (u.ualign.type   == A_LAWFUL)           ? " (\8c»)" : "");
4302 #endif
4303 /*JP
4304     Sprintf(buf, fmtstr, "Lawful", buf2);
4305 */
4306     Sprintf(buf, fmtstr, "\92\81\8f\98", buf2);
4307     add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4308
4309 /*JP
4310     end_menu(tmpwin, "Base Attributes");
4311 */
4312     end_menu(tmpwin, "\8aî\96{\91®\90«");
4313     n = select_menu(tmpwin, PICK_NONE, &selected);
4314     destroy_nhwindow(tmpwin);
4315     return (boolean) (n != -1);
4316 }
4317 #endif /*0*/
4318
4319 /* ^X command */
4320 STATIC_PTR int
4321 doattributes(VOID_ARGS)
4322 {
4323     int mode = BASICENLIGHTENMENT;
4324
4325     /* show more--as if final disclosure--for wizard and explore modes */
4326     if (wizard || discover)
4327         mode |= MAGICENLIGHTENMENT;
4328
4329     enlightenment(mode, ENL_GAMEINPROGRESS);
4330     return 0;
4331 }
4332
4333 void
4334 youhiding(via_enlghtmt, msgflag)
4335 boolean via_enlghtmt; /* englightment line vs topl message */
4336 int msgflag;          /* for variant message phrasing */
4337 {
4338     char *bp, buf[BUFSZ];
4339
4340 /*JP
4341     Strcpy(buf, "hiding");
4342 */
4343     Strcpy(buf, "\89B\82ê");
4344     if (U_AP_TYPE != M_AP_NOTHING) {
4345         /* mimic; hero is only able to mimic a strange object or gold
4346            or hallucinatory alternative to gold, so we skip the details
4347            for the hypothetical furniture and monster cases */
4348 #if 0 /*JP*//*\8cã\82ë\82É\89ñ\82·*//* not used */
4349         bp = eos(strcpy(buf, "mimicking"));
4350 #endif
4351         if (U_AP_TYPE == M_AP_OBJECT) {
4352 /*JP
4353             Sprintf(bp, " %s", an(simple_typename(youmonst.mappearance)));
4354 */
4355             Strcpy(buf, simple_typename(youmonst.mappearance));
4356         } else if (U_AP_TYPE == M_AP_FURNITURE) {
4357 /*JP
4358             Strcpy(bp, " something");
4359 */
4360             Strcpy(buf, "\89½\82©");
4361         } else if (U_AP_TYPE == M_AP_MONSTER) {
4362 /*JP
4363             Strcpy(bp, " someone");
4364 */
4365             Strcpy(buf, "\89½\8eÒ\82©");
4366         } else {
4367             ; /* something unexpected; leave 'buf' as-is */
4368         }
4369 #if 1 /*JP*//*\82±\82±\82Å\92Ç\89Á*/
4370         Strcat(buf, "\82Ì\82Ó\82è\82ð\82µ");
4371 #endif
4372     } else if (u.uundetected) {
4373         bp = eos(buf); /* points past "hiding" */
4374         if (youmonst.data->mlet == S_EEL) {
4375             if (is_pool(u.ux, u.uy))
4376 /*JP
4377                 Sprintf(bp, " in the %s", waterbody_name(u.ux, u.uy));
4378 */
4379                 Sprintf(bp, "%s\82Ì\92\86\82É", waterbody_name(u.ux, u.uy));
4380         } else if (hides_under(youmonst.data)) {
4381             struct obj *o = level.objects[u.ux][u.uy];
4382
4383             if (o)
4384 /*JP
4385                 Sprintf(bp, " underneath %s", ansimpleoname(o));
4386 */
4387                 Sprintf(bp, "%s\82Ì\89º\82É", ansimpleoname(o));
4388         } else if (is_clinger(youmonst.data) || Flying) {
4389             /* Flying: 'lurker above' hides on ceiling but doesn't cling */
4390 /*JP
4391             Sprintf(bp, " on the %s", ceiling(u.ux, u.uy));
4392 */
4393             Sprintf(bp, "%s\82É", ceiling(u.ux, u.uy));
4394         } else {
4395             /* on floor; is_hider() but otherwise not special: 'trapper' */
4396             if (u.utrap && u.utraptype == TT_PIT) {
4397                 struct trap *t = t_at(u.ux, u.uy);
4398
4399 #if 0 /*JP:T*/
4400                 Sprintf(bp, " in a %spit",
4401                         (t && t->ttyp == SPIKED_PIT) ? "spiked " : "");
4402 #else
4403                 Sprintf(bp, "%s\97\8e\82µ\8c\8a\82Ì\92\86\82É",
4404                         (t && t->ttyp == SPIKED_PIT) ? "\83g\83Q\82¾\82ç\82¯\82Ì" : "");
4405 #endif
4406             } else
4407 /*JP
4408                 Sprintf(bp, " on the %s", surface(u.ux, u.uy));
4409 */
4410                 Sprintf(bp, "%s\82É", surface(u.ux, u.uy));
4411         }
4412 #if 1 /*JP*//*\82±\82±\82Å\92Ç\89Á*/
4413         Strcat(buf, "\89B\82ê");
4414 #endif
4415     } else {
4416         ; /* shouldn't happen; will result in generic "you are hiding" */
4417     }
4418
4419     if (via_enlghtmt) {
4420         int final = msgflag; /* 'final' is used by you_are() macro */
4421
4422         you_are(buf, "");
4423     } else {
4424         /* for dohide(), when player uses '#monster' command */
4425 #if 0 /*JP*/
4426         You("are %s %s.", msgflag ? "already" : "now", buf);
4427 #else
4428         if (msgflag) {
4429             You("\82·\82Å\82É%s\82Ä\82¢\82é\81D", buf);
4430         } else {
4431             You("%s\82½\81D", buf);
4432         }
4433 #endif
4434     }
4435 }
4436
4437 /* KMH, #conduct
4438  * (shares enlightenment's tense handling)
4439  */
4440 int
4441 doconduct(VOID_ARGS)
4442 {
4443     show_conduct(0);
4444     return 0;
4445 }
4446
4447 void
4448 show_conduct(final)
4449 int final;
4450 {
4451     char buf[BUFSZ];
4452     int ngenocided;
4453
4454     /* Create the conduct window */
4455     en_win = create_nhwindow(NHW_MENU);
4456 /*JP
4457     putstr(en_win, 0, "Voluntary challenges:");
4458 */
4459     putstr(en_win, 0, "\8e©\94­\93I\92§\90í:");
4460
4461     if (u.uroleplay.blind)
4462 /*JP
4463         you_have_been("blind from birth");
4464 */
4465         you_have_been("\90\82Ü\82ê\82È\82ª\82ç\82É\96Ó\96Ú");
4466     if (u.uroleplay.nudist)
4467 /*JP
4468         you_have_been("faithfully nudist");
4469 */
4470         you_have_been("\92\89\8eÀ\82È\97\87\91°");
4471
4472     if (!u.uconduct.food)
4473 /*JP
4474         enl_msg(You_, "have gone", "went", " without food", "");
4475 */
4476         enl_msg("\82 \82È\82½\82Í\90H\8e\96\82ð\82µ", "\82Ä\82¢\82È\82¢", "\82È\82©\82Á\82½", "", "");
4477         /* but beverages are okay */
4478     else if (!u.uconduct.unvegan)
4479 /*JP
4480         you_have_X("followed a strict vegan diet");
4481 */
4482         you_have_been("\8cµ\8ai\82È\8dØ\90H\8eå\8b`\8eÒ");
4483     else if (!u.uconduct.unvegetarian)
4484 /*JP
4485         you_have_been("vegetarian");
4486 */
4487         you_have_been("\8dØ\90H\8eå\8b`\8eÒ");
4488
4489     if (!u.uconduct.gnostic)
4490 /*JP
4491         you_have_been("an atheist");
4492 */
4493         you_have_been("\96³\90_\98_\8eÒ");
4494
4495     if (!u.uconduct.weaphit) {
4496 /*JP
4497         you_have_never("hit with a wielded weapon");
4498 */
4499         you_have_never("\82 \82È\82½\82Í\91\95\94õ\82µ\82Ä\82¢\82é\95\90\8aí\82Å\8dU\8c\82\82µ");
4500     } else if (wizard) {
4501 #if 0 /*JP:T*/
4502         Sprintf(buf, "used a wielded weapon %ld time%s", u.uconduct.weaphit,
4503                 plur(u.uconduct.weaphit));
4504         you_have_X(buf);
4505 #else
4506         Sprintf(buf, "\82 \82È\82½\82Í%ld\89ñ\91\95\94õ\82µ\82½\95\90\8aí\82ð\8eg\97p\82µ", u.uconduct.weaphit);
4507         you_have_X(buf);
4508 #endif
4509     }
4510     if (!u.uconduct.killer)
4511 /*JP
4512         you_have_been("a pacifist");
4513 */
4514         you_have_been("\95½\98a\8eå\8b`\8eÒ");
4515
4516     if (!u.uconduct.literate) {
4517 /*JP
4518         you_have_been("illiterate");
4519 */
4520         you_have_never("\82 \82È\82½\82Í\93Ç\82Ý\8f\91\82«\82µ");
4521     } else if (wizard) {
4522 #if 0 /*JP:T*/
4523         Sprintf(buf, "read items or engraved %ld time%s", u.uconduct.literate,
4524                 plur(u.uconduct.literate));
4525         you_have_X(buf);
4526 #else
4527         Sprintf(buf, "%ld\89ñ\93Ç\82ñ\82¾\82è\8f\91\82¢\82½\82è\82µ", u.uconduct.literate);
4528         you_have_X(buf);
4529 #endif
4530     }
4531
4532     ngenocided = num_genocides();
4533     if (ngenocided == 0) {
4534 /*JP
4535         you_have_never("genocided any monsters");
4536 */
4537         you_have_never("\82 \82È\82½\82Í\89ö\95¨\82ð\8bs\8eE\82µ");
4538     } else {
4539 #if 0 /*JP:T*/
4540         Sprintf(buf, "genocided %d type%s of monster%s", ngenocided,
4541                 plur(ngenocided), plur(ngenocided));
4542         you_have_X(buf);
4543 #else
4544         Sprintf(buf, "%d\8eí\82Ì\89ö\95¨\82ð\8bs\8eE\82µ", ngenocided);
4545         you_have_X(buf);
4546 #endif
4547     }
4548
4549     if (!u.uconduct.polypiles) {
4550 /*JP
4551         you_have_never("polymorphed an object");
4552 */
4553         you_have_never("\82 \82È\82½\82Í\95¨\91Ì\82ð\95Ï\89»\82³\82¹");
4554     } else if (wizard) {
4555 #if 0 /*JP:T*/
4556         Sprintf(buf, "polymorphed %ld item%s", u.uconduct.polypiles,
4557                 plur(u.uconduct.polypiles));
4558         you_have_X(buf);
4559 #else
4560         Sprintf(buf, "%ld\8cÂ\82Ì\95¨\82ð\95Ï\89»\82³\82¹", u.uconduct.polypiles);
4561         you_have_X(buf);
4562 #endif
4563     }
4564
4565     if (!u.uconduct.polyselfs) {
4566 /*JP
4567         you_have_never("changed form");
4568 */
4569         you_have_never("\82 \82È\82½\82Í\95Ï\89»\82µ");
4570     } else if (wizard) {
4571 #if 0 /*JP:T*/
4572         Sprintf(buf, "changed form %ld time%s", u.uconduct.polyselfs,
4573                 plur(u.uconduct.polyselfs));
4574         you_have_X(buf);
4575 #else
4576         Sprintf(buf, "%ld\89ñ\8ep\82ð\95Ï\82¦", u.uconduct.polyselfs);
4577         you_have_X(buf);
4578 #endif
4579     }
4580
4581     if (!u.uconduct.wishes) {
4582 /*JP
4583         you_have_X("used no wishes");
4584 */
4585         you_have_never("\82 \82È\82½\82Í\8aè\82¢\8e\96\82ð\82µ");
4586     } else {
4587 #if 0 /*JP:T*/
4588         Sprintf(buf, "used %ld wish%s", u.uconduct.wishes,
4589                 (u.uconduct.wishes > 1L) ? "es" : "");
4590 #else
4591         Sprintf(buf, "%ld\89ñ\8aè\82¢\8e\96\82ð\82µ", u.uconduct.wishes);
4592 #endif
4593         if (u.uconduct.wisharti) {
4594             /* if wisharti == wishes
4595              *  1 wish (for an artifact)
4596              *  2 wishes (both for artifacts)
4597              *  N wishes (all for artifacts)
4598              * else (N is at least 2 in order to get here; M < N)
4599              *  N wishes (1 for an artifact)
4600              *  N wishes (M for artifacts)
4601              */
4602 #if 0 /*JP*/
4603             if (u.uconduct.wisharti == u.uconduct.wishes)
4604                 Sprintf(eos(buf), " (%s",
4605                         (u.uconduct.wisharti > 2L) ? "all "
4606                           : (u.uconduct.wisharti == 2L) ? "both " : "");
4607             else
4608                 Sprintf(eos(buf), " (%ld ", u.uconduct.wisharti);
4609
4610             Sprintf(eos(buf), "for %s)",
4611                     (u.uconduct.wisharti == 1L) ? "an artifact"
4612                                                 : "artifacts");
4613 #else
4614             Sprintf(eos(buf), " (\90¹\8aí\82Í%ld\89ñ)", u.uconduct.wisharti);
4615 #endif
4616         }
4617         you_have_X(buf);
4618
4619         if (!u.uconduct.wisharti)
4620 #if 0 /*JP*/
4621             enl_msg(You_, "have not wished", "did not wish",
4622                     " for any artifacts", "");
4623 #else
4624             enl_msg("\82 \82È\82½\82Í\90¹\8aí\82ð\8aè", "\82Á\82Ä\82¢\82È\82¢", "\82í\82È\82©\82Á\82½", "", "");
4625 #endif
4626     }
4627
4628     /* Pop up the window and wait for a key */
4629     display_nhwindow(en_win, TRUE);
4630     destroy_nhwindow(en_win);
4631     en_win = WIN_ERR;
4632 }
4633
4634 /* ordered by command name */
4635 struct ext_func_tab extcmdlist[] = {
4636     { '#', "#", "perform an extended command",
4637             doextcmd, IFBURIED | GENERALCMD },
4638 #if 0 /*JP:T*/
4639     { M('?'), "?", "list all extended commands",
4640 #else
4641     { M('?'), "?", "\82±\82Ì\8ag\92£\83R\83}\83\93\83h\88ê\97\97\82ð\95\\8e¦\82·\82é",
4642 #endif
4643             doextlist, IFBURIED | AUTOCOMPLETE | GENERALCMD },
4644 #if 0 /*JP:T*/
4645     { M('a'), "adjust", "adjust inventory letters",
4646 #else
4647     { M('a'), "adjust", "\8e\9d\82¿\95¨\88ê\97\97\82Ì\92²\90®",
4648 #endif
4649             doorganize, IFBURIED | AUTOCOMPLETE },
4650 #if 0 /*JP:T*/
4651     { M('A'), "annotate", "name current level",
4652 #else
4653     { M('A'), "annotate", "\8c»\8dÝ\82Ì\8aK\82É\96¼\91O\82ð\82Â\82¯\82é",
4654 #endif
4655             donamelevel, IFBURIED | AUTOCOMPLETE },
4656 #if 0 /*JP*/
4657     { 'a', "apply", "apply (use) a tool (pick-axe, key, lamp...)",
4658 #else
4659     { 'a', "apply", "\93¹\8bï\82ð\8eg\82¤\81D(\82Â\82é\82Í\82µ, \8c®, \83\89\83\93\83v\81c)",
4660 #endif
4661             doapply },
4662     { C('x'), "attributes", "show your attributes",
4663             doattributes, IFBURIED },
4664 #if 0 /*JP:T*/
4665     { '@', "autopickup", "toggle the pickup option on/off",
4666 #else
4667     { '@', "autopickup", "\8e©\93®\8fE\82¢\83I\83v\83V\83\87\83\93\82ð\90Ø\82è\91Ö\82¦\82é",
4668 #endif
4669             dotogglepickup, IFBURIED },
4670 #if 0 /*JP:T*/
4671     { 'C', "call", "call (name) something", docallcmd, IFBURIED },
4672 #else
4673     { 'C', "call", "\96¼\91O\82ð\82Â\82¯\82é", docallcmd, IFBURIED },
4674 #endif
4675 #if 0 /*JP:T*/
4676     { 'Z', "cast", "zap (cast) a spell", docast, IFBURIED },
4677 #else
4678     { 'Z', "cast", "\8eô\95\82ð\8f¥\82¦\82é", docast, IFBURIED },
4679 #endif
4680 #if 0 /*JP:T*/
4681     { M('c'), "chat", "talk to someone", dotalk, IFBURIED | AUTOCOMPLETE },
4682 #else
4683     { M('c'), "chat", "\92N\82©\82Æ\98b\82·", dotalk, IFBURIED | AUTOCOMPLETE },
4684 #endif
4685 #if 0 /*JP:T*/
4686     { 'c', "close", "close a door", doclose },
4687 #else
4688     { 'c', "close", "\83h\83A\82ð\95Â\82ß\82é", doclose },
4689 #endif
4690 #if 0 /*JP:T*/
4691     { M('C'), "conduct", "list voluntary challenges you have maintained",
4692 #else
4693     { M('C'), "conduct", "\82Ç\82¤\82¢\82¤\8ds\93®\82ð\82Æ\82Á\82½\82©\8c©\82é",
4694 #endif
4695             doconduct, IFBURIED | AUTOCOMPLETE },
4696 #if 0 /*JP:T*/
4697     { M('d'), "dip", "dip an object into something", dodip, AUTOCOMPLETE },
4698 #else
4699     { M('d'), "dip", "\89½\82©\82É\95¨\82ð\90Z\82·", dodip, AUTOCOMPLETE },
4700 #endif
4701     { '>', "down", "go down a staircase", dodown },
4702     { 'd', "drop", "drop an item", dodrop },
4703     { 'D', "droptype", "drop specific item types", doddrop },
4704     { 'e', "eat", "eat something", doeat },
4705     { 'E', "engrave", "engrave writing on the floor", doengrave },
4706 #if 0 /*JP:T*/
4707     { M('e'), "enhance", "advance or check weapon and spell skills",
4708 #else
4709     { M('e'), "enhance", "\95\90\8aí\8fn\97û\93x\82ð\8d\82\82ß\82é",
4710 #endif
4711             enhance_weapon_skill, IFBURIED | AUTOCOMPLETE },
4712 #if 0 /*JP:T*/
4713     { '\0', "exploremode", "enter explore (discovery) mode",
4714 #else
4715     { '\0', "exploremode", "\92T\8c\9f(\94­\8c©)\83\82\81[\83h\82É\93ü\82é",
4716 #endif
4717             enter_explore_mode, IFBURIED },
4718     { 'f', "fire", "fire ammunition from quiver", dofire },
4719 #if 0 /*JP:T*/
4720     { M('f'), "force", "force a lock", doforce, AUTOCOMPLETE },
4721 #else
4722     { M('f'), "force", "\8c®\82ð\82±\82\82 \82¯\82é", doforce, AUTOCOMPLETE },
4723 #endif
4724     { ';', "glance", "show what type of thing a map symbol corresponds to",
4725             doquickwhatis, IFBURIED | GENERALCMD },
4726     { '?', "help", "give a help message", dohelp, IFBURIED | GENERALCMD },
4727     { '\0', "herecmdmenu", "show menu of commands you can do here",
4728             doherecmdmenu, IFBURIED },
4729     { 'V', "history", "show long version and game history",
4730             dohistory, IFBURIED | GENERALCMD },
4731     { 'i', "inventory", "show your inventory", ddoinv, IFBURIED },
4732     { 'I', "inventtype", "inventory specific item types",
4733             dotypeinv, IFBURIED },
4734 #if 0 /*JP:T*/
4735     { M('i'), "invoke", "invoke an object's special powers",
4736 #else
4737     { M('i'), "invoke", "\95¨\82Ì\93Á\95Ê\82È\97Í\82ð\8eg\82¤",
4738 #endif
4739             doinvoke, IFBURIED | AUTOCOMPLETE },
4740 #if 0 /*JP:T*/
4741     { M('j'), "jump", "jump to another location", dojump, AUTOCOMPLETE },
4742 #else
4743     { M('j'), "jump", "\91¼\82Ì\88Ê\92u\82É\94ò\82Ñ\82¤\82Â\82é", dojump, AUTOCOMPLETE },
4744 #endif
4745     { C('d'), "kick", "kick something", dokick },
4746     { '\\', "known", "show what object types have been discovered",
4747             dodiscovered, IFBURIED | GENERALCMD },
4748     { '`', "knownclass", "show discovered types for one class of objects",
4749             doclassdisco, IFBURIED | GENERALCMD },
4750 #if 0 /*JP:T*/
4751     { '\0', "levelchange", "change experience level",
4752 #else
4753     { '\0', "levelchange", "\8co\8c±\83\8c\83x\83\8b\82ð\95Ï\82¦\82é",
4754 #endif
4755             wiz_level_change, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4756 #if 0 /*JP:T*/
4757     { '\0', "lightsources", "show mobile light sources",
4758 #else
4759     { '\0', "lightsources", "\88Ú\93®\8cõ\8c¹\82ð\8c©\82é",
4760 #endif
4761             wiz_light_sources, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4762     { ':', "look", "look at what is here", dolook, IFBURIED },
4763 #if 0 /*JP:T*/
4764     { M('l'), "loot", "loot a box on the floor", doloot, AUTOCOMPLETE },
4765 #else
4766     { M('l'), "loot", "\8f°\82Ì\8fã\82Ì\94 \82ð\8aJ\82¯\82é", doloot, AUTOCOMPLETE },
4767 #endif
4768 #ifdef DEBUG_MIGRATING_MONS
4769 #if 0 /*JP:T*/
4770     { '\0', "migratemons", "migrate N random monsters",
4771 #else
4772     { '\0', "migratemons", "\83\89\83\93\83_\83\80\82È\89ö\95¨\82ð\89½\91Ì\82©\88Ú\8fZ\82³\82¹\82é",
4773 #endif
4774             wiz_migrate_mons, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4775 #endif
4776 #if 0 /*JP:T*/
4777     { M('m'), "monster", "use monster's special ability",
4778 #else
4779     { M('m'), "monster", "\89ö\95¨\82Ì\93Á\95Ê\94\\97Í\82ð\8eg\82¤",
4780 #endif
4781             domonability, IFBURIED | AUTOCOMPLETE },
4782 #if 0 /*JP:T*/
4783     { 'N', "name", "name a monster or an object",
4784 #else
4785     { 'N', "name", "\83A\83C\83e\83\80\82â\95¨\82É\96¼\91O\82ð\82Â\82¯\82é",
4786 #endif
4787             docallcmd, IFBURIED | AUTOCOMPLETE },
4788 #if 0 /*JP:T*/
4789     { M('o'), "offer", "offer a sacrifice to the gods",
4790 #else
4791     { M('o'), "offer", "\90_\82É\8b\9f\95¨\82ð\95ù\82°\82é",
4792 #endif
4793             dosacrifice, AUTOCOMPLETE },
4794     { 'o', "open", "open a door", doopen },
4795     { 'O', "options", "show option settings, possibly change them",
4796             doset, IFBURIED | GENERALCMD },
4797 #if 0 /*JP:T*/
4798     { C('o'), "overview", "show a summary of the explored dungeon",
4799 #else
4800     { C('o'), "overview", "\92T\8dõ\82µ\82½\96À\8b{\82Ì\8aT\97v\82ð\95\\8e¦\82·\82é",
4801 #endif
4802             dooverview, IFBURIED | AUTOCOMPLETE },
4803 #if 0 /*JP:T*/
4804     { '\0', "panic", "test panic routine (fatal to game)",
4805 #else
4806     { '\0', "panic", "\83p\83j\83b\83N\83\8b\81[\83`\83\93\82ð\83e\83X\83g\82·\82é(\92v\96½\93I)",
4807 #endif
4808             wiz_panic, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4809     { 'p', "pay", "pay your shopping bill", dopay },
4810     { ',', "pickup", "pick up things at the current location", dopickup },
4811 #if 0 /*JP:T*/
4812     { '\0', "polyself", "polymorph self",
4813 #else
4814     { '\0', "polyself", "\95Ï\89»\82·\82é",
4815 #endif
4816             wiz_polyself, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4817 #if 0 /*JP:T*/
4818     { M('p'), "pray", "pray to the gods for help",
4819 #else
4820     { M('p'), "pray", "\90_\82É\8bF\82é",
4821 #endif
4822             dopray, IFBURIED | AUTOCOMPLETE },
4823     { C('p'), "prevmsg", "view recent game messages",
4824             doprev_message, IFBURIED | GENERALCMD },
4825     { 'P', "puton", "put on an accessory (ring, amulet, etc)", doputon },
4826     { 'q', "quaff", "quaff (drink) something", dodrink },
4827 #if 0 /*JP:T*/
4828     { M('q'), "quit", "exit without saving current game",
4829 #else
4830     { M('q'), "quit", "\83Z\81[\83u\82µ\82È\82¢\82Å\8fI\97¹",
4831 #endif
4832             done2, IFBURIED | AUTOCOMPLETE | GENERALCMD },
4833     { 'Q', "quiver", "select ammunition for quiver", dowieldquiver },
4834     { 'r', "read", "read a scroll or spellbook", doread },
4835     { C('r'), "redraw", "redraw screen", doredraw, IFBURIED | GENERALCMD },
4836     { 'R', "remove", "remove an accessory (ring, amulet, etc)", doremring },
4837 #if 0 /*JP:T*/
4838     { M('R'), "ride", "mount or dismount a saddled steed",
4839 #else
4840     { M('R'), "ride", "\89ö\95¨\82É\8fæ\82é(\82Ü\82½\82Í\8d~\82è\82é)",
4841 #endif
4842             doride, AUTOCOMPLETE },
4843 #if 0 /*JP:T*/
4844     { M('r'), "rub", "rub a lamp or a stone", dorub, AUTOCOMPLETE },
4845 #else
4846     { M('r'), "rub", "\83\89\83\93\83v\82ð\82±\82·\82é", dorub, AUTOCOMPLETE },
4847 #endif
4848     { 'S', "save", "save the game and exit", dosave, IFBURIED | GENERALCMD },
4849 #if 0 /*JP:T*/
4850     { 's', "search", "search for traps and secret doors",
4851             dosearch, IFBURIED, "searching" },
4852 #else
4853     { 's', "search", "ã©\82â\89B\82µ\94à\82ð\92T\82·",
4854             dosearch, IFBURIED, "\92T\82·" },
4855 #endif
4856     { '*', "seeall", "show all equipment in use", doprinuse, IFBURIED },
4857     { AMULET_SYM, "seeamulet", "show the amulet currently worn",
4858             dopramulet, IFBURIED },
4859     { ARMOR_SYM, "seearmor", "show the armor currently worn",
4860             doprarm, IFBURIED },
4861     { GOLD_SYM, "seegold", "count your gold", doprgold, IFBURIED },
4862 #if 0 /*JP:T*/
4863     { '\0', "seenv", "show seen vectors",
4864 #else
4865     { '\0', "seenv", "\8e\8b\90ü\83x\83N\83g\83\8b\82ð\8c©\82é",
4866 #endif
4867             wiz_show_seenv, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4868     { RING_SYM, "seerings", "show the ring(s) currently worn",
4869             doprring, IFBURIED },
4870     { SPBOOK_SYM, "seespells", "list and reorder known spells",
4871             dovspell, IFBURIED },
4872     { TOOL_SYM, "seetools", "show the tools currently in use",
4873             doprtool, IFBURIED },
4874     { '^', "seetrap", "show the type of adjacent trap", doidtrap, IFBURIED },
4875     { WEAPON_SYM, "seeweapon", "show the weapon currently wielded",
4876             doprwep, IFBURIED },
4877     { '!', "shell", "do a shell escape",
4878             dosh_core, IFBURIED | GENERALCMD
4879 #ifndef SHELL
4880                        | CMD_NOT_AVAILABLE
4881 #endif /* SHELL */
4882     },
4883 #if 0 /*JP:T*/
4884     { M('s'), "sit", "sit down", dosit, AUTOCOMPLETE },
4885 #else
4886     { M('s'), "sit", "\8dÀ\82é", dosit, AUTOCOMPLETE },
4887 #endif
4888 #if 0 /*JP:T*/
4889     { '\0', "stats", "show memory statistics",
4890 #else
4891     { '\0', "stats", "\83\81\83\82\83\8a\8fó\91Ô\82ð\8c©\82é",
4892 #endif
4893             wiz_show_stats, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4894     { C('z'), "suspend", "suspend the game",
4895             dosuspend_core, IFBURIED | GENERALCMD
4896 #ifndef SUSPEND
4897                             | CMD_NOT_AVAILABLE
4898 #endif /* SUSPEND */
4899     },
4900     { 'x', "swap", "swap wielded and secondary weapons", doswapweapon },
4901     { 'T', "takeoff", "take off one piece of armor", dotakeoff },
4902     { 'A', "takeoffall", "remove all armor", doddoremarm },
4903     { C('t'), "teleport", "teleport around the level", dotelecmd, IFBURIED },
4904 #if 0 /*JP:T*/
4905     { '\0', "terrain", "show map without obstructions",
4906 #else
4907     { '\0', "terrain", "\8e×\96\82\82³\82ê\82¸\82É\92n\90}\82ð\8c©\82é",
4908 #endif
4909             doterrain, IFBURIED | AUTOCOMPLETE },
4910     { '\0', "therecmdmenu",
4911             "menu of commands you can do from here to adjacent spot",
4912             dotherecmdmenu },
4913     { 't', "throw", "throw something", dothrow },
4914 #if 0 /*JP:T*/
4915     { '\0', "timeout", "look at timeout queue and hero's timed intrinsics",
4916 #else
4917     { '\0', "timeout", "\8e\9e\8aÔ\90Ø\82ê\83L\83\85\81[\82Æ\83v\83\8c\83C\83\84\81[\82Ì\8e\9e\8aÔ\8co\89ß\82ð\8c©\82é",
4918 #endif
4919             wiz_timeout_queue, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4920 #if 0 /*JP:T*/
4921     { M('T'), "tip", "empty a container", dotip, AUTOCOMPLETE },
4922 #else
4923     { M('T'), "tip", "\93ü\82ê\95¨\82ð\8bó\82É\82·\82é", dotip, AUTOCOMPLETE },
4924 #endif
4925     { '_', "travel", "travel to a specific location on the map", dotravel },
4926 #if 0 /*JP:T*/
4927     { M('t'), "turn", "turn undead away", doturn, IFBURIED | AUTOCOMPLETE },
4928 #else
4929     { M('t'), "turn", "\83A\83\93\83f\83b\83g\82ð\93y\82É\95Ô\82·", doturn, IFBURIED | AUTOCOMPLETE },
4930 #endif
4931 #if 0 /*JP:T*/
4932     { 'X', "twoweapon", "toggle two-weapon combat",
4933 #else
4934     { 'X', "twoweapon", "\97¼\8eè\8e\9d\82¿\82Ì\90Ø\82è\91Ö\82¦",
4935 #endif
4936             dotwoweapon, AUTOCOMPLETE },
4937 #if 0 /*JP:T*/
4938     { M('u'), "untrap", "untrap something", dountrap, AUTOCOMPLETE },
4939 #else
4940     { M('u'), "untrap", "ã©\82ð\82Í\82¸\82·", dountrap, AUTOCOMPLETE },
4941 #endif
4942     { '<', "up", "go up a staircase", doup },
4943 #if 0 /*JP:T*/
4944     { '\0', "vanquished", "list vanquished monsters",
4945 #else
4946     { '\0', "vanquished", "\93|\82µ\82½\89ö\95¨\82Ì\88ê\97\97\82ð\8c©\82é",
4947 #endif
4948             dovanquished, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4949     { M('v'), "version",
4950 #if 0 /*JP:T*/
4951             "list compile time options for this version of NetHack",
4952 #else
4953             "\83R\83\93\83p\83C\83\8b\8e\9e\82Ì\83I\83v\83V\83\87\83\93\82ð\95\\8e¦\82·\82é",
4954 #endif
4955             doextversion, IFBURIED | AUTOCOMPLETE | GENERALCMD },
4956     { 'v', "versionshort", "show version", doversion, IFBURIED | GENERALCMD },
4957 #if 0 /*JP:T*/
4958     { '\0', "vision", "show vision array",
4959 #else
4960     { '\0', "vision", "\8e\8b\8aE\94z\97ñ\82ð\8c©\82é",
4961 #endif
4962             wiz_show_vision, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4963 #if 0 /*JP:T*/
4964     { '.', "wait", "rest one move while doing nothing",
4965             donull, IFBURIED, "waiting" },
4966 #else
4967     { '.', "wait", "\88ê\95à\95ª\89½\82à\82µ\82È\82¢",
4968             donull, IFBURIED, "\8bx\8ce\82·\82é" },
4969 #endif
4970     { 'W', "wear", "wear a piece of armor", dowear },
4971     { '&', "whatdoes", "tell what a command does", dowhatdoes, IFBURIED },
4972     { '/', "whatis", "show what type of thing a symbol corresponds to",
4973             dowhatis, IFBURIED | GENERALCMD },
4974     { 'w', "wield", "wield (put in use) a weapon", dowield },
4975 #if 0 /*JP:T*/
4976     { M('w'), "wipe", "wipe off your face", dowipe, AUTOCOMPLETE },
4977 #else
4978     { M('w'), "wipe", "\8aç\82ð\90@\82¤", dowipe, AUTOCOMPLETE },
4979 #endif
4980 #ifdef DEBUG
4981 #if 0 /*JP:T*/
4982     { '\0', "wizbury", "bury objs under and around you",
4983 #else
4984     { '\0', "wizbury", "\95¨\82ð\82 \82È\82½\82Ì\8eü\82è\82É\96\84\82ß\82é",
4985 #endif
4986             wiz_debug_cmd_bury, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4987 #endif
4988     { C('e'), "wizdetect", "reveal hidden things within a small radius",
4989             wiz_detect, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4990     { C('g'), "wizgenesis", "create a monster",
4991             wiz_genesis, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4992     { C('i'), "wizidentify", "identify all items in inventory",
4993             wiz_identify, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4994     { '\0', "wizintrinsic", "set an intrinsic",
4995             wiz_intrinsic, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4996     { C('v'), "wizlevelport", "teleport to another level",
4997             wiz_level_tele, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4998     { '\0', "wizmakemap", "recreate the current level",
4999             wiz_makemap, IFBURIED | WIZMODECMD },
5000     { C('f'), "wizmap", "map the level",
5001             wiz_map, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
5002 #if 0 /*JP:T*/
5003     { '\0', "wizrumorcheck", "verify rumor boundaries",
5004 #else
5005     { '\0', "wizrumorcheck", "\89\\82Ì\8b«\8aE\82ð\8c\9f\8fØ\82·\82é",
5006 #endif
5007             wiz_rumor_check, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
5008 #if 0 /*JP:T*/
5009     { '\0', "wizsmell", "smell monster",
5010 #else
5011     { '\0', "wizsmell", "\89ö\95¨\82Ì\93õ\82¢\82ð\9ak\82®",
5012 #endif
5013             wiz_smell, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
5014     { '\0', "wizwhere", "show locations of special levels",
5015             wiz_where, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
5016     { C('w'), "wizwish", "wish for something",
5017             wiz_wish, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
5018 #if 0 /*JP:T*/
5019     { '\0', "wmode", "show wall modes",
5020 #else
5021     { '\0', "wmode", "\95Ç\83\82\81[\83h\82ð\8c©\82é",
5022 #endif
5023             wiz_show_wmodes, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
5024     { 'z', "zap", "zap a wand", dozap },
5025     { '\0', (char *) 0, (char *) 0, donull, 0, (char *) 0 } /* sentinel */
5026 };
5027
5028 /* for key2extcmddesc() to support dowhatdoes() */
5029 struct movcmd {
5030     uchar k1, k2, k3, k4; /* 'normal', 'qwertz', 'numpad', 'phone' */
5031     const char *txt, *alt; /* compass direction, screen direction */
5032 };
5033 static const struct movcmd movtab[] = {
5034     { 'h', 'h', '4', '4', "west",      "left" },
5035     { 'j', 'j', '2', '8', "south",     "down" },
5036     { 'k', 'k', '8', '2', "north",     "up" },
5037     { 'l', 'l', '6', '6', "east",      "right" },
5038     { 'b', 'b', '1', '7', "southwest", "lower left" },
5039     { 'n', 'n', '3', '9', "southeast", "lower right" },
5040     { 'u', 'u', '9', '3', "northeast", "upper right" },
5041     { 'y', 'z', '7', '1', "northwest", "upper left" },
5042     {   0,   0,   0,   0,  (char *) 0, (char *) 0 }
5043 };
5044
5045 int extcmdlist_length = SIZE(extcmdlist) - 1;
5046
5047 const char *
5048 key2extcmddesc(key)
5049 uchar key;
5050 {
5051     static char key2cmdbuf[48];
5052     const struct movcmd *mov;
5053     int k, c;
5054     uchar M_5 = (uchar) M('5'), M_0 = (uchar) M('0');
5055
5056     /* need to check for movement commands before checking the extended
5057        commands table because it contains entries for number_pad commands
5058        that match !number_pad movement (like 'j' for "jump") */
5059     key2cmdbuf[0] = '\0';
5060     if (movecmd(k = key))
5061         Strcpy(key2cmdbuf, "move"); /* "move or attack"? */
5062     else if (movecmd(k = unctrl(key)))
5063         Strcpy(key2cmdbuf, "rush");
5064     else if (movecmd(k = (Cmd.num_pad ? unmeta(key) : lowc(key))))
5065         Strcpy(key2cmdbuf, "run");
5066     if (*key2cmdbuf) {
5067         for (mov = &movtab[0]; mov->k1; ++mov) {
5068             c = !Cmd.num_pad ? (!Cmd.swap_yz ? mov->k1 : mov->k2)
5069                              : (!Cmd.phone_layout ? mov->k3 : mov->k4);
5070             if (c == k) {
5071                 Sprintf(eos(key2cmdbuf), " %s (screen %s)",
5072                         mov->txt, mov->alt);
5073                 return key2cmdbuf;
5074             }
5075         }
5076     } else if (digit(key) || (Cmd.num_pad && digit(unmeta(key)))) {
5077         key2cmdbuf[0] = '\0';
5078         if (!Cmd.num_pad)
5079             Strcpy(key2cmdbuf, "start of, or continuation of, a count");
5080         else if (key == '5' || key == M_5)
5081             Sprintf(key2cmdbuf, "%s prefix",
5082                     (!!Cmd.pcHack_compat ^ (key == M_5)) ? "run" : "rush");
5083         else if (key == '0' || (Cmd.pcHack_compat && key == M_0))
5084             Strcpy(key2cmdbuf, "synonym for 'i'");
5085         if (*key2cmdbuf)
5086             return key2cmdbuf;
5087     }
5088     if (Cmd.commands[key]) {
5089         if (Cmd.commands[key]->ef_txt)
5090             return Cmd.commands[key]->ef_desc;
5091
5092     }
5093     return (char *) 0;
5094 }
5095
5096 boolean
5097 bind_key(key, command)
5098 uchar key;
5099 const char *command;
5100 {
5101     struct ext_func_tab *extcmd;
5102
5103     /* special case: "nothing" is reserved for unbinding */
5104     if (!strcmp(command, "nothing")) {
5105         Cmd.commands[key] = (struct ext_func_tab *) 0;
5106         return TRUE;
5107     }
5108
5109     for (extcmd = extcmdlist; extcmd->ef_txt; extcmd++) {
5110         if (strcmp(command, extcmd->ef_txt))
5111             continue;
5112         Cmd.commands[key] = extcmd;
5113 #if 0 /* silently accept key binding for unavailable command (!SHELL,&c) */
5114         if ((extcmd->flags & CMD_NOT_AVAILABLE) != 0) {
5115             char buf[BUFSZ];
5116
5117             Sprintf(buf, cmdnotavail, extcmd->ef_txt);
5118             config_error_add("%s", buf);
5119         }
5120 #endif
5121         return TRUE;
5122     }
5123
5124     return FALSE;
5125 }
5126
5127 /* initialize all keyboard commands */
5128 void
5129 commands_init()
5130 {
5131     struct ext_func_tab *extcmd;
5132
5133     for (extcmd = extcmdlist; extcmd->ef_txt; extcmd++)
5134         if (extcmd->key)
5135             Cmd.commands[extcmd->key] = extcmd;
5136
5137     (void) bind_key(C('l'), "redraw"); /* if number_pad is set */
5138     /*       'b', 'B' : go sw */
5139     /*       'F' : fight (one time) */
5140     /*       'g', 'G' : multiple go */
5141     /*       'h', 'H' : go west */
5142     (void) bind_key('h',    "help"); /* if number_pad is set */
5143     (void) bind_key('j',    "jump"); /* if number_pad is on */
5144     /*       'j', 'J', 'k', 'K', 'l', 'L', 'm', 'M', 'n', 'N' move commands */
5145     (void) bind_key('k',    "kick"); /* if number_pad is on */
5146     (void) bind_key('l',    "loot"); /* if number_pad is on */
5147     (void) bind_key(C('n'), "annotate"); /* if number_pad is on */
5148     (void) bind_key(M('n'), "name");
5149     (void) bind_key(M('N'), "name");
5150     (void) bind_key('u',    "untrap"); /* if number_pad is on */
5151
5152     /* alt keys: */
5153     (void) bind_key(M('O'), "overview");
5154     (void) bind_key(M('2'), "twoweapon");
5155
5156     /* wait_on_space */
5157     (void) bind_key(' ',    "wait");
5158 }
5159
5160 int
5161 dokeylist_putcmds(datawin, docount, cmdflags, exflags, keys_used)
5162 winid datawin;
5163 boolean docount;
5164 int cmdflags, exflags;
5165 boolean *keys_used; /* boolean keys_used[256] */
5166 {
5167     int i;
5168     char buf[BUFSZ];
5169     char buf2[QBUFSZ];
5170     int count = 0;
5171
5172     for (i = 0; i < 256; i++) {
5173         const struct ext_func_tab *extcmd;
5174         uchar key = (uchar) i;
5175
5176         if (keys_used[i])
5177             continue;
5178         if (key == ' ' && !flags.rest_on_space)
5179             continue;
5180         if ((extcmd = Cmd.commands[i]) != (struct ext_func_tab *) 0) {
5181             if ((cmdflags && !(extcmd->flags & cmdflags))
5182                 || (exflags && (extcmd->flags & exflags)))
5183                 continue;
5184             if (docount) {
5185                 count++;
5186                 continue;
5187             }
5188             Sprintf(buf, "%-8s %-12s %s", key2txt(key, buf2),
5189                     extcmd->ef_txt,
5190                     extcmd->ef_desc);
5191             putstr(datawin, 0, buf);
5192             keys_used[i] = TRUE;
5193         }
5194     }
5195     return count;
5196 }
5197
5198 /* list all keys and their bindings, like dat/hh but dynamic */
5199 void
5200 dokeylist(VOID_ARGS)
5201 {
5202     char buf[BUFSZ], buf2[BUFSZ];
5203     uchar key;
5204     boolean keys_used[256] = {0};
5205     winid datawin;
5206     int i;
5207     static const char
5208         run_desc[] = "Prefix: run until something very interesting is seen",
5209         forcefight_desc[] =
5210                      "Prefix: force fight even if you don't see a monster";
5211     static const struct {
5212         int nhkf;
5213         const char *desc;
5214         boolean numpad;
5215     } misc_keys[] = {
5216         { NHKF_ESC, "escape from the current query/action", FALSE },
5217         { NHKF_RUSH,
5218           "Prefix: rush until something interesting is seen", FALSE },
5219         { NHKF_RUN, run_desc, FALSE },
5220         { NHKF_RUN2, run_desc, TRUE },
5221         { NHKF_FIGHT, forcefight_desc, FALSE },
5222         { NHKF_FIGHT2, forcefight_desc, TRUE } ,
5223         { NHKF_NOPICKUP,
5224           "Prefix: move without picking up objects/fighting", FALSE },
5225         { NHKF_RUN_NOPICKUP,
5226           "Prefix: run without picking up objects/fighting", FALSE },
5227         { NHKF_DOINV, "view inventory", TRUE },
5228         { NHKF_REQMENU, "Prefix: request a menu", FALSE },
5229 #ifdef REDO
5230         { NHKF_DOAGAIN , "re-do: perform the previous command again", FALSE },
5231 #endif
5232         { 0, (const char *) 0, FALSE }
5233     };
5234
5235     datawin = create_nhwindow(NHW_TEXT);
5236     putstr(datawin, 0, "");
5237     putstr(datawin, 0, "            Full Current Key Bindings List");
5238
5239     /* directional keys */
5240     putstr(datawin, 0, "");
5241     putstr(datawin, 0, "Directional keys:");
5242     show_direction_keys(datawin, '.', FALSE); /* '.'==self in direction grid */
5243
5244     keys_used[(uchar) Cmd.move_NW] = keys_used[(uchar) Cmd.move_N]
5245         = keys_used[(uchar) Cmd.move_NE] = keys_used[(uchar) Cmd.move_W]
5246         = keys_used[(uchar) Cmd.move_E] = keys_used[(uchar) Cmd.move_SW]
5247         = keys_used[(uchar) Cmd.move_S] = keys_used[(uchar) Cmd.move_SE]
5248         = TRUE;
5249
5250     if (!iflags.num_pad) {
5251         keys_used[(uchar) highc(Cmd.move_NW)]
5252             = keys_used[(uchar) highc(Cmd.move_N)]
5253             = keys_used[(uchar) highc(Cmd.move_NE)]
5254             = keys_used[(uchar) highc(Cmd.move_W)]
5255             = keys_used[(uchar) highc(Cmd.move_E)]
5256             = keys_used[(uchar) highc(Cmd.move_SW)]
5257             = keys_used[(uchar) highc(Cmd.move_S)]
5258             = keys_used[(uchar) highc(Cmd.move_SE)] = TRUE;
5259         keys_used[(uchar) C(Cmd.move_NW)]
5260             = keys_used[(uchar) C(Cmd.move_N)]
5261             = keys_used[(uchar) C(Cmd.move_NE)]
5262             = keys_used[(uchar) C(Cmd.move_W)]
5263             = keys_used[(uchar) C(Cmd.move_E)]
5264             = keys_used[(uchar) C(Cmd.move_SW)]
5265             = keys_used[(uchar) C(Cmd.move_S)]
5266             = keys_used[(uchar) C(Cmd.move_SE)] = TRUE;
5267         putstr(datawin, 0, "");
5268         putstr(datawin, 0,
5269           "Shift-<direction> will move in specified direction until you hit");
5270         putstr(datawin, 0, "        a wall or run into something.");
5271         putstr(datawin, 0,
5272           "Ctrl-<direction> will run in specified direction until something");
5273         putstr(datawin, 0, "        very interesting is seen.");
5274     }
5275
5276     putstr(datawin, 0, "");
5277     putstr(datawin, 0, "Miscellaneous keys:");
5278     for (i = 0; misc_keys[i].desc; i++) {
5279         key = Cmd.spkeys[misc_keys[i].nhkf];
5280         if (key && ((misc_keys[i].numpad && iflags.num_pad)
5281                     || !misc_keys[i].numpad)) {
5282             keys_used[(uchar) key] = TRUE;
5283             Sprintf(buf, "%-8s %s", key2txt(key, buf2), misc_keys[i].desc);
5284             putstr(datawin, 0, buf);
5285         }
5286     }
5287 #ifndef NO_SIGNAL
5288     putstr(datawin, 0, "^c       break out of NetHack (SIGINT)");
5289     keys_used[(uchar) C('c')] = TRUE;
5290 #endif
5291
5292     putstr(datawin, 0, "");
5293     show_menu_controls(datawin, TRUE);
5294
5295     if (dokeylist_putcmds(datawin, TRUE, GENERALCMD, WIZMODECMD, keys_used)) {
5296         putstr(datawin, 0, "");
5297         putstr(datawin, 0, "General commands:");
5298         (void) dokeylist_putcmds(datawin, FALSE, GENERALCMD, WIZMODECMD,
5299                                  keys_used);
5300     }
5301
5302     if (dokeylist_putcmds(datawin, TRUE, 0, WIZMODECMD, keys_used)) {
5303         putstr(datawin, 0, "");
5304         putstr(datawin, 0, "Game commands:");
5305         (void) dokeylist_putcmds(datawin, FALSE, 0, WIZMODECMD, keys_used);
5306     }
5307
5308     if (wizard
5309         && dokeylist_putcmds(datawin, TRUE, WIZMODECMD, 0, keys_used)) {
5310         putstr(datawin, 0, "");
5311         putstr(datawin, 0, "Wizard-mode commands:");
5312         (void) dokeylist_putcmds(datawin, FALSE, WIZMODECMD, 0, keys_used);
5313     }
5314
5315     display_nhwindow(datawin, FALSE);
5316     destroy_nhwindow(datawin);
5317 }
5318
5319 char
5320 cmd_from_func(fn)
5321 int NDECL((*fn));
5322 {
5323     int i;
5324
5325     for (i = 0; i < 256; ++i)
5326         if (Cmd.commands[i] && Cmd.commands[i]->ef_funct == fn)
5327             return (char) i;
5328     return '\0';
5329 }
5330
5331 /*
5332  * wizard mode sanity_check code
5333  */
5334
5335 static const char template[] = "%-27s  %4ld  %6ld";
5336 static const char stats_hdr[] = "                             count  bytes";
5337 static const char stats_sep[] = "---------------------------  ----- -------";
5338
5339 STATIC_OVL int
5340 size_obj(otmp)
5341 struct obj *otmp;
5342 {
5343     int sz = (int) sizeof (struct obj);
5344
5345     if (otmp->oextra) {
5346         sz += (int) sizeof (struct oextra);
5347         if (ONAME(otmp))
5348             sz += (int) strlen(ONAME(otmp)) + 1;
5349         if (OMONST(otmp))
5350             sz += size_monst(OMONST(otmp), FALSE);
5351         if (OMID(otmp))
5352             sz += (int) sizeof (unsigned);
5353         if (OLONG(otmp))
5354             sz += (int) sizeof (long);
5355         if (OMAILCMD(otmp))
5356             sz += (int) strlen(OMAILCMD(otmp)) + 1;
5357     }
5358     return sz;
5359 }
5360
5361 STATIC_OVL void
5362 count_obj(chain, total_count, total_size, top, recurse)
5363 struct obj *chain;
5364 long *total_count;
5365 long *total_size;
5366 boolean top;
5367 boolean recurse;
5368 {
5369     long count, size;
5370     struct obj *obj;
5371
5372     for (count = size = 0, obj = chain; obj; obj = obj->nobj) {
5373         if (top) {
5374             count++;
5375             size += size_obj(obj);
5376         }
5377         if (recurse && obj->cobj)
5378             count_obj(obj->cobj, total_count, total_size, TRUE, TRUE);
5379     }
5380     *total_count += count;
5381     *total_size += size;
5382 }
5383
5384 STATIC_OVL void
5385 obj_chain(win, src, chain, force, total_count, total_size)
5386 winid win;
5387 const char *src;
5388 struct obj *chain;
5389 boolean force;
5390 long *total_count;
5391 long *total_size;
5392 {
5393     char buf[BUFSZ];
5394     long count = 0L, size = 0L;
5395
5396     count_obj(chain, &count, &size, TRUE, FALSE);
5397
5398     if (count || size || force) {
5399         *total_count += count;
5400         *total_size += size;
5401         Sprintf(buf, template, src, count, size);
5402         putstr(win, 0, buf);
5403     }
5404 }
5405
5406 STATIC_OVL void
5407 mon_invent_chain(win, src, chain, total_count, total_size)
5408 winid win;
5409 const char *src;
5410 struct monst *chain;
5411 long *total_count;
5412 long *total_size;
5413 {
5414     char buf[BUFSZ];
5415     long count = 0, size = 0;
5416     struct monst *mon;
5417
5418     for (mon = chain; mon; mon = mon->nmon)
5419         count_obj(mon->minvent, &count, &size, TRUE, FALSE);
5420
5421     if (count || size) {
5422         *total_count += count;
5423         *total_size += size;
5424         Sprintf(buf, template, src, count, size);
5425         putstr(win, 0, buf);
5426     }
5427 }
5428
5429 STATIC_OVL void
5430 contained_stats(win, src, total_count, total_size)
5431 winid win;
5432 const char *src;
5433 long *total_count;
5434 long *total_size;
5435 {
5436     char buf[BUFSZ];
5437     long count = 0, size = 0;
5438     struct monst *mon;
5439
5440     count_obj(invent, &count, &size, FALSE, TRUE);
5441     count_obj(fobj, &count, &size, FALSE, TRUE);
5442     count_obj(level.buriedobjlist, &count, &size, FALSE, TRUE);
5443     count_obj(migrating_objs, &count, &size, FALSE, TRUE);
5444     /* DEADMONSTER check not required in this loop since they have no
5445      * inventory */
5446     for (mon = fmon; mon; mon = mon->nmon)
5447         count_obj(mon->minvent, &count, &size, FALSE, TRUE);
5448     for (mon = migrating_mons; mon; mon = mon->nmon)
5449         count_obj(mon->minvent, &count, &size, FALSE, TRUE);
5450
5451     if (count || size) {
5452         *total_count += count;
5453         *total_size += size;
5454         Sprintf(buf, template, src, count, size);
5455         putstr(win, 0, buf);
5456     }
5457 }
5458
5459 STATIC_OVL int
5460 size_monst(mtmp, incl_wsegs)
5461 struct monst *mtmp;
5462 boolean incl_wsegs;
5463 {
5464     int sz = (int) sizeof (struct monst);
5465
5466     if (mtmp->wormno && incl_wsegs)
5467         sz += size_wseg(mtmp);
5468
5469     if (mtmp->mextra) {
5470         sz += (int) sizeof (struct mextra);
5471         if (MNAME(mtmp))
5472             sz += (int) strlen(MNAME(mtmp)) + 1;
5473         if (EGD(mtmp))
5474             sz += (int) sizeof (struct egd);
5475         if (EPRI(mtmp))
5476             sz += (int) sizeof (struct epri);
5477         if (ESHK(mtmp))
5478             sz += (int) sizeof (struct eshk);
5479         if (EMIN(mtmp))
5480             sz += (int) sizeof (struct emin);
5481         if (EDOG(mtmp))
5482             sz += (int) sizeof (struct edog);
5483         /* mextra->mcorpsenm doesn't point to more memory */
5484     }
5485     return sz;
5486 }
5487
5488 STATIC_OVL void
5489 mon_chain(win, src, chain, force, total_count, total_size)
5490 winid win;
5491 const char *src;
5492 struct monst *chain;
5493 boolean force;
5494 long *total_count;
5495 long *total_size;
5496 {
5497     char buf[BUFSZ];
5498     long count, size;
5499     struct monst *mon;
5500     /* mon->wormno means something different for migrating_mons and mydogs */
5501     boolean incl_wsegs = !strcmpi(src, "fmon");
5502
5503     count = size = 0L;
5504     for (mon = chain; mon; mon = mon->nmon) {
5505         count++;
5506         size += size_monst(mon, incl_wsegs);
5507     }
5508     if (count || size || force) {
5509         *total_count += count;
5510         *total_size += size;
5511         Sprintf(buf, template, src, count, size);
5512         putstr(win, 0, buf);
5513     }
5514 }
5515
5516 STATIC_OVL void
5517 misc_stats(win, total_count, total_size)
5518 winid win;
5519 long *total_count;
5520 long *total_size;
5521 {
5522     char buf[BUFSZ], hdrbuf[QBUFSZ];
5523     long count, size;
5524     int idx;
5525     struct trap *tt;
5526     struct damage *sd; /* shop damage */
5527     struct kinfo *k; /* delayed killer */
5528     struct cemetery *bi; /* bones info */
5529
5530     /* traps and engravings are output unconditionally;
5531      * others only if nonzero
5532      */
5533     count = size = 0L;
5534     for (tt = ftrap; tt; tt = tt->ntrap) {
5535         ++count;
5536         size += (long) sizeof *tt;
5537     }
5538     *total_count += count;
5539     *total_size += size;
5540     Sprintf(hdrbuf, "traps, size %ld", (long) sizeof (struct trap));
5541     Sprintf(buf, template, hdrbuf, count, size);
5542     putstr(win, 0, buf);
5543
5544     count = size = 0L;
5545     engr_stats("engravings, size %ld+text", hdrbuf, &count, &size);
5546     *total_count += count;
5547     *total_size += size;
5548     Sprintf(buf, template, hdrbuf, count, size);
5549     putstr(win, 0, buf);
5550
5551     count = size = 0L;
5552     light_stats("light sources, size %ld", hdrbuf, &count, &size);
5553     if (count || size) {
5554         *total_count += count;
5555         *total_size += size;
5556         Sprintf(buf, template, hdrbuf, count, size);
5557         putstr(win, 0, buf);
5558     }
5559
5560     count = size = 0L;
5561     timer_stats("timers, size %ld", hdrbuf, &count, &size);
5562     if (count || size) {
5563         *total_count += count;
5564         *total_size += size;
5565         Sprintf(buf, template, hdrbuf, count, size);
5566         putstr(win, 0, buf);
5567     }
5568
5569     count = size = 0L;
5570     for (sd = level.damagelist; sd; sd = sd->next) {
5571         ++count;
5572         size += (long) sizeof *sd;
5573     }
5574     if (count || size) {
5575         *total_count += count;
5576         *total_size += size;
5577         Sprintf(hdrbuf, "shop damage, size %ld",
5578                 (long) sizeof (struct damage));
5579         Sprintf(buf, template, hdrbuf, count, size);
5580         putstr(win, 0, buf);
5581     }
5582
5583     count = size = 0L;
5584     region_stats("regions, size %ld+%ld*rect+N", hdrbuf, &count, &size);
5585     if (count || size) {
5586         *total_count += count;
5587         *total_size += size;
5588         Sprintf(buf, template, hdrbuf, count, size);
5589         putstr(win, 0, buf);
5590     }
5591
5592     count = size = 0L;
5593     for (k = killer.next; k; k = k->next) {
5594         ++count;
5595         size += (long) sizeof *k;
5596     }
5597     if (count || size) {
5598         *total_count += count;
5599         *total_size += size;
5600         Sprintf(hdrbuf, "delayed killer%s, size %ld",
5601                 plur(count), (long) sizeof (struct kinfo));
5602         Sprintf(buf, template, hdrbuf, count, size);
5603         putstr(win, 0, buf);
5604     }
5605
5606     count = size = 0L;
5607     for (bi = level.bonesinfo; bi; bi = bi->next) {
5608         ++count;
5609         size += (long) sizeof *bi;
5610     }
5611     if (count || size) {
5612         *total_count += count;
5613         *total_size += size;
5614         Sprintf(hdrbuf, "bones history, size %ld",
5615                 (long) sizeof (struct cemetery));
5616         Sprintf(buf, template, hdrbuf, count, size);
5617         putstr(win, 0, buf);
5618     }
5619
5620     count = size = 0L;
5621     for (idx = 0; idx < NUM_OBJECTS; ++idx)
5622         if (objects[idx].oc_uname) {
5623             ++count;
5624             size += (long) (strlen(objects[idx].oc_uname) + 1);
5625         }
5626     if (count || size) {
5627         *total_count += count;
5628         *total_size += size;
5629         Strcpy(hdrbuf, "object type names, text");
5630         Sprintf(buf, template, hdrbuf, count, size);
5631         putstr(win, 0, buf);
5632     }
5633 }
5634
5635 /*
5636  * Display memory usage of all monsters and objects on the level.
5637  */
5638 static int
5639 wiz_show_stats()
5640 {
5641     char buf[BUFSZ];
5642     winid win;
5643     long total_obj_size, total_obj_count,
5644          total_mon_size, total_mon_count,
5645          total_ovr_size, total_ovr_count,
5646          total_misc_size, total_misc_count;
5647
5648     win = create_nhwindow(NHW_TEXT);
5649     putstr(win, 0, "Current memory statistics:");
5650
5651     total_obj_count = total_obj_size = 0L;
5652     putstr(win, 0, stats_hdr);
5653     Sprintf(buf, "  Objects, base size %ld", (long) sizeof (struct obj));
5654     putstr(win, 0, buf);
5655     obj_chain(win, "invent", invent, TRUE, &total_obj_count, &total_obj_size);
5656     obj_chain(win, "fobj", fobj, TRUE, &total_obj_count, &total_obj_size);
5657     obj_chain(win, "buried", level.buriedobjlist, FALSE,
5658               &total_obj_count, &total_obj_size);
5659     obj_chain(win, "migrating obj", migrating_objs, FALSE,
5660               &total_obj_count, &total_obj_size);
5661     obj_chain(win, "billobjs", billobjs, FALSE,
5662               &total_obj_count, &total_obj_size);
5663     mon_invent_chain(win, "minvent", fmon, &total_obj_count, &total_obj_size);
5664     mon_invent_chain(win, "migrating minvent", migrating_mons,
5665                      &total_obj_count, &total_obj_size);
5666     contained_stats(win, "contained", &total_obj_count, &total_obj_size);
5667     putstr(win, 0, stats_sep);
5668     Sprintf(buf, template, "  Obj total", total_obj_count, total_obj_size);
5669     putstr(win, 0, buf);
5670
5671     total_mon_count = total_mon_size = 0L;
5672     putstr(win, 0, "");
5673     Sprintf(buf, "  Monsters, base size %ld", (long) sizeof (struct monst));
5674     putstr(win, 0, buf);
5675     mon_chain(win, "fmon", fmon, TRUE, &total_mon_count, &total_mon_size);
5676     mon_chain(win, "migrating", migrating_mons, FALSE,
5677               &total_mon_count, &total_mon_size);
5678     /* 'mydogs' is only valid during level change or end of game disclosure,
5679        but conceivably we've been called from within debugger at such time */
5680     if (mydogs) /* monsters accompanying hero */
5681         mon_chain(win, "mydogs", mydogs, FALSE,
5682                   &total_mon_count, &total_mon_size);
5683     putstr(win, 0, stats_sep);
5684     Sprintf(buf, template, "  Mon total", total_mon_count, total_mon_size);
5685     putstr(win, 0, buf);
5686
5687     total_ovr_count = total_ovr_size = 0L;
5688     putstr(win, 0, "");
5689     putstr(win, 0, "  Overview");
5690     overview_stats(win, template, &total_ovr_count, &total_ovr_size);
5691     putstr(win, 0, stats_sep);
5692     Sprintf(buf, template, "  Over total", total_ovr_count, total_ovr_size);
5693     putstr(win, 0, buf);
5694
5695     total_misc_count = total_misc_size = 0L;
5696     putstr(win, 0, "");
5697     putstr(win, 0, "  Miscellaneous");
5698     misc_stats(win, &total_misc_count, &total_misc_size);
5699     putstr(win, 0, stats_sep);
5700     Sprintf(buf, template, "  Misc total", total_misc_count, total_misc_size);
5701     putstr(win, 0, buf);
5702
5703     putstr(win, 0, "");
5704     putstr(win, 0, stats_sep);
5705     Sprintf(buf, template, "  Grand total",
5706             (total_obj_count + total_mon_count
5707              + total_ovr_count + total_misc_count),
5708             (total_obj_size + total_mon_size
5709              + total_ovr_size + total_misc_size));
5710     putstr(win, 0, buf);
5711
5712 #if defined(__BORLANDC__) && !defined(_WIN32)
5713     show_borlandc_stats(win);
5714 #endif
5715
5716     display_nhwindow(win, FALSE);
5717     destroy_nhwindow(win);
5718     return 0;
5719 }
5720
5721 void
5722 sanity_check()
5723 {
5724     obj_sanity_check();
5725     timer_sanity_check();
5726     mon_sanity_check();
5727     light_sources_sanity_check();
5728     bc_sanity_check();
5729 }
5730
5731 #ifdef DEBUG_MIGRATING_MONS
5732 static int
5733 wiz_migrate_mons()
5734 {
5735     int mcount = 0;
5736     char inbuf[BUFSZ] = DUMMY;
5737     struct permonst *ptr;
5738     struct monst *mtmp;
5739     d_level tolevel;
5740
5741     getlin("How many random monsters to migrate? [0]", inbuf);
5742     if (*inbuf == '\033')
5743         return 0;
5744     mcount = atoi(inbuf);
5745     if (mcount < 0 || mcount > (COLNO * ROWNO) || Is_botlevel(&u.uz))
5746         return 0;
5747     while (mcount > 0) {
5748         if (Is_stronghold(&u.uz))
5749             assign_level(&tolevel, &valley_level);
5750         else
5751             get_level(&tolevel, depth(&u.uz) + 1);
5752         ptr = rndmonst();
5753         mtmp = makemon(ptr, 0, 0, NO_MM_FLAGS);
5754         if (mtmp)
5755             migrate_to_level(mtmp, ledger_no(&tolevel), MIGR_RANDOM,
5756                              (coord *) 0);
5757         mcount--;
5758     }
5759     return 0;
5760 }
5761 #endif
5762
5763 struct {
5764     int nhkf;
5765     char key;
5766     const char *name;
5767 } const spkeys_binds[] = {
5768     { NHKF_ESC,              '\033', (char *) 0 }, /* no binding */
5769     { NHKF_DOAGAIN,          DOAGAIN, "repeat" },
5770     { NHKF_REQMENU,          'm', "reqmenu" },
5771     { NHKF_RUN,              'G', "run" },
5772     { NHKF_RUN2,             '5', "run.numpad" },
5773     { NHKF_RUSH,             'g', "rush" },
5774     { NHKF_FIGHT,            'F', "fight" },
5775     { NHKF_FIGHT2,           '-', "fight.numpad" },
5776     { NHKF_NOPICKUP,         'm', "nopickup" },
5777     { NHKF_RUN_NOPICKUP,     'M', "run.nopickup" },
5778     { NHKF_DOINV,            '0', "doinv" },
5779     { NHKF_TRAVEL,           CMD_TRAVEL, (char *) 0 }, /* no binding */
5780     { NHKF_CLICKLOOK,        CMD_CLICKLOOK, (char *) 0 }, /* no binding */
5781     { NHKF_REDRAW,           C('r'), "redraw" },
5782     { NHKF_REDRAW2,          C('l'), "redraw.numpad" },
5783     { NHKF_GETDIR_SELF,      '.', "getdir.self" },
5784     { NHKF_GETDIR_SELF2,     's', "getdir.self2" },
5785     { NHKF_GETDIR_HELP,      '?', "getdir.help" },
5786     { NHKF_COUNT,            'n', "count" },
5787     { NHKF_GETPOS_SELF,      '@', "getpos.self" },
5788     { NHKF_GETPOS_PICK,      '.', "getpos.pick" },
5789     { NHKF_GETPOS_PICK_Q,    ',', "getpos.pick.quick" },
5790     { NHKF_GETPOS_PICK_O,    ';', "getpos.pick.once" },
5791     { NHKF_GETPOS_PICK_V,    ':', "getpos.pick.verbose" },
5792     { NHKF_GETPOS_SHOWVALID, '$', "getpos.valid" },
5793     { NHKF_GETPOS_AUTODESC,  '#', "getpos.autodescribe" },
5794     { NHKF_GETPOS_MON_NEXT,  'm', "getpos.mon.next" },
5795     { NHKF_GETPOS_MON_PREV,  'M', "getpos.mon.prev" },
5796     { NHKF_GETPOS_OBJ_NEXT,  'o', "getpos.obj.next" },
5797     { NHKF_GETPOS_OBJ_PREV,  'O', "getpos.obj.prev" },
5798     { NHKF_GETPOS_DOOR_NEXT, 'd', "getpos.door.next" },
5799     { NHKF_GETPOS_DOOR_PREV, 'D', "getpos.door.prev" },
5800     { NHKF_GETPOS_UNEX_NEXT, 'x', "getpos.unexplored.next" },
5801     { NHKF_GETPOS_UNEX_PREV, 'X', "getpos.unexplored.prev" },
5802     { NHKF_GETPOS_VALID_NEXT, 'z', "getpos.valid.next" },
5803     { NHKF_GETPOS_VALID_PREV, 'Z', "getpos.valid.prev" },
5804     { NHKF_GETPOS_INTERESTING_NEXT, 'a', "getpos.all.next" },
5805     { NHKF_GETPOS_INTERESTING_PREV, 'A', "getpos.all.prev" },
5806     { NHKF_GETPOS_HELP,      '?', "getpos.help" },
5807     { NHKF_GETPOS_LIMITVIEW, '"', "getpos.filter" },
5808     { NHKF_GETPOS_MOVESKIP,  '*', "getpos.moveskip" },
5809     { NHKF_GETPOS_MENU,      '!', "getpos.menu" }
5810 };
5811
5812 boolean
5813 bind_specialkey(key, command)
5814 uchar key;
5815 const char *command;
5816 {
5817     int i;
5818     for (i = 0; i < SIZE(spkeys_binds); i++) {
5819         if (!spkeys_binds[i].name || strcmp(command, spkeys_binds[i].name))
5820             continue;
5821         Cmd.spkeys[spkeys_binds[i].nhkf] = key;
5822         return TRUE;
5823     }
5824     return FALSE;
5825 }
5826
5827 /* returns a one-byte character from the text (it may massacre the txt
5828  * buffer) */
5829 char
5830 txt2key(txt)
5831 char *txt;
5832 {
5833     txt = trimspaces(txt);
5834     if (!*txt)
5835         return '\0';
5836
5837     /* simple character */
5838     if (!txt[1])
5839         return txt[0];
5840
5841     /* a few special entries */
5842     if (!strcmp(txt, "<enter>"))
5843         return '\n';
5844     if (!strcmp(txt, "<space>"))
5845         return ' ';
5846     if (!strcmp(txt, "<esc>"))
5847         return '\033';
5848
5849     /* control and meta keys */
5850     switch (*txt) {
5851     case 'm': /* can be mx, Mx, m-x, M-x */
5852     case 'M':
5853         txt++;
5854         if (*txt == '-' && txt[1])
5855             txt++;
5856         if (txt[1])
5857             return '\0';
5858         return M(*txt);
5859     case 'c': /* can be cx, Cx, ^x, c-x, C-x, ^-x */
5860     case 'C':
5861     case '^':
5862         txt++;
5863         if (*txt == '-' && txt[1])
5864             txt++;
5865         if (txt[1])
5866             return '\0';
5867         return C(*txt);
5868     }
5869
5870     /* ascii codes: must be three-digit decimal */
5871     if (*txt >= '0' && *txt <= '9') {
5872         uchar key = 0;
5873         int i;
5874
5875         for (i = 0; i < 3; i++) {
5876             if (txt[i] < '0' || txt[i] > '9')
5877                 return '\0';
5878             key = 10 * key + txt[i] - '0';
5879         }
5880         return key;
5881     }
5882
5883     return '\0';
5884 }
5885
5886 /* returns the text for a one-byte encoding;
5887  * must be shorter than a tab for proper formatting */
5888 char *
5889 key2txt(c, txt)
5890 uchar c;
5891 char *txt; /* sufficiently long buffer */
5892 {
5893     /* should probably switch to "SPC", "ESC", "RET"
5894        since nethack's documentation uses ESC for <escape> */
5895     if (c == ' ')
5896         Sprintf(txt, "<space>");
5897     else if (c == '\033')
5898         Sprintf(txt, "<esc>");
5899     else if (c == '\n')
5900         Sprintf(txt, "<enter>");
5901     else if (c == '\177')
5902         Sprintf(txt, "<del>"); /* "<delete>" won't fit */
5903     else
5904         Strcpy(txt, visctrl((char) c));
5905     return txt;
5906 }
5907
5908
5909 void
5910 parseautocomplete(autocomplete, condition)
5911 char *autocomplete;
5912 boolean condition;
5913 {
5914     struct ext_func_tab *efp;
5915     register char *autoc;
5916
5917     /* break off first autocomplete from the rest; parse the rest */
5918     if ((autoc = index(autocomplete, ',')) != 0
5919         || (autoc = index(autocomplete, ':')) != 0) {
5920         *autoc++ = '\0';
5921         parseautocomplete(autoc, condition);
5922     }
5923
5924     /* strip leading and trailing white space */
5925     autocomplete = trimspaces(autocomplete);
5926
5927     if (!*autocomplete)
5928         return;
5929
5930     /* take off negation */
5931     if (*autocomplete == '!') {
5932         /* unlike most options, a leading "no" might actually be a part of
5933          * the extended command.  Thus you have to use ! */
5934         autocomplete++;
5935         autocomplete = trimspaces(autocomplete);
5936         condition = !condition;
5937     }
5938
5939     /* find and modify the extended command */
5940     for (efp = extcmdlist; efp->ef_txt; efp++) {
5941         if (!strcmp(autocomplete, efp->ef_txt)) {
5942             if (condition)
5943                 efp->flags |= AUTOCOMPLETE;
5944             else
5945                 efp->flags &= ~AUTOCOMPLETE;
5946             return;
5947         }
5948     }
5949
5950     /* not a real extended command */
5951     raw_printf("Bad autocomplete: invalid extended command '%s'.",
5952                autocomplete);
5953     wait_synch();
5954 }
5955
5956 /* called at startup and after number_pad is twiddled */
5957 void
5958 reset_commands(initial)
5959 boolean initial;
5960 {
5961     static const char sdir[] = "hykulnjb><",
5962                       sdir_swap_yz[] = "hzkulnjb><",
5963                       ndir[] = "47896321><",
5964                       ndir_phone_layout[] = "41236987><";
5965     static const int ylist[] = {
5966         'y', 'Y', C('y'), M('y'), M('Y'), M(C('y'))
5967     };
5968     static struct ext_func_tab *back_dir_cmd[8];
5969     const struct ext_func_tab *cmdtmp;
5970     boolean flagtemp;
5971     int c, i, updated = 0;
5972     static boolean backed_dir_cmd = FALSE;
5973
5974     if (initial) {
5975         updated = 1;
5976         Cmd.num_pad = FALSE;
5977         Cmd.pcHack_compat = Cmd.phone_layout = Cmd.swap_yz = FALSE;
5978         for (i = 0; i < SIZE(spkeys_binds); i++)
5979             Cmd.spkeys[spkeys_binds[i].nhkf] = spkeys_binds[i].key;
5980         commands_init();
5981     } else {
5982
5983         if (backed_dir_cmd) {
5984             for (i = 0; i < 8; i++) {
5985                 Cmd.commands[(uchar) Cmd.dirchars[i]] = back_dir_cmd[i];
5986             }
5987         }
5988
5989         /* basic num_pad */
5990         flagtemp = iflags.num_pad;
5991         if (flagtemp != Cmd.num_pad) {
5992             Cmd.num_pad = flagtemp;
5993             ++updated;
5994         }
5995         /* swap_yz mode (only applicable for !num_pad); intended for
5996            QWERTZ keyboard used in Central Europe, particularly Germany */
5997         flagtemp = (iflags.num_pad_mode & 1) ? !Cmd.num_pad : FALSE;
5998         if (flagtemp != Cmd.swap_yz) {
5999             Cmd.swap_yz = flagtemp;
6000             ++updated;
6001             /* Cmd.swap_yz has been toggled;
6002                perform the swap (or reverse previous one) */
6003             for (i = 0; i < SIZE(ylist); i++) {
6004                 c = ylist[i] & 0xff;
6005                 cmdtmp = Cmd.commands[c];              /* tmp = [y] */
6006                 Cmd.commands[c] = Cmd.commands[c + 1]; /* [y] = [z] */
6007                 Cmd.commands[c + 1] = cmdtmp;          /* [z] = tmp */
6008             }
6009         }
6010         /* MSDOS compatibility mode (only applicable for num_pad) */
6011         flagtemp = (iflags.num_pad_mode & 1) ? Cmd.num_pad : FALSE;
6012         if (flagtemp != Cmd.pcHack_compat) {
6013             Cmd.pcHack_compat = flagtemp;
6014             ++updated;
6015             /* pcHack_compat has been toggled */
6016             c = M('5') & 0xff;
6017             cmdtmp = Cmd.commands['5'];
6018             Cmd.commands['5'] = Cmd.commands[c];
6019             Cmd.commands[c] = cmdtmp;
6020             c = M('0') & 0xff;
6021             Cmd.commands[c] = Cmd.pcHack_compat ? Cmd.commands['I'] : 0;
6022         }
6023         /* phone keypad layout (only applicable for num_pad) */
6024         flagtemp = (iflags.num_pad_mode & 2) ? Cmd.num_pad : FALSE;
6025         if (flagtemp != Cmd.phone_layout) {
6026             Cmd.phone_layout = flagtemp;
6027             ++updated;
6028             /* phone_layout has been toggled */
6029             for (i = 0; i < 3; i++) {
6030                 c = '1' + i;             /* 1,2,3 <-> 7,8,9 */
6031                 cmdtmp = Cmd.commands[c];              /* tmp = [1] */
6032                 Cmd.commands[c] = Cmd.commands[c + 6]; /* [1] = [7] */
6033                 Cmd.commands[c + 6] = cmdtmp;          /* [7] = tmp */
6034                 c = (M('1') & 0xff) + i; /* M-1,M-2,M-3 <-> M-7,M-8,M-9 */
6035                 cmdtmp = Cmd.commands[c];              /* tmp = [M-1] */
6036                 Cmd.commands[c] = Cmd.commands[c + 6]; /* [M-1] = [M-7] */
6037                 Cmd.commands[c + 6] = cmdtmp;          /* [M-7] = tmp */
6038             }
6039         }
6040     } /*?initial*/
6041
6042     if (updated)
6043         Cmd.serialno++;
6044     Cmd.dirchars = !Cmd.num_pad
6045                        ? (!Cmd.swap_yz ? sdir : sdir_swap_yz)
6046                        : (!Cmd.phone_layout ? ndir : ndir_phone_layout);
6047     Cmd.alphadirchars = !Cmd.num_pad ? Cmd.dirchars : sdir;
6048
6049     Cmd.move_W = Cmd.dirchars[0];
6050     Cmd.move_NW = Cmd.dirchars[1];
6051     Cmd.move_N = Cmd.dirchars[2];
6052     Cmd.move_NE = Cmd.dirchars[3];
6053     Cmd.move_E = Cmd.dirchars[4];
6054     Cmd.move_SE = Cmd.dirchars[5];
6055     Cmd.move_S = Cmd.dirchars[6];
6056     Cmd.move_SW = Cmd.dirchars[7];
6057
6058     if (!initial) {
6059         for (i = 0; i < 8; i++) {
6060             back_dir_cmd[i] =
6061                 (struct ext_func_tab *) Cmd.commands[(uchar) Cmd.dirchars[i]];
6062             Cmd.commands[(uchar) Cmd.dirchars[i]] = (struct ext_func_tab *) 0;
6063         }
6064         backed_dir_cmd = TRUE;
6065         for (i = 0; i < 8; i++)
6066             (void) bind_key(Cmd.dirchars[i], "nothing");
6067     }
6068 }
6069
6070 /* non-movement commands which accept 'm' prefix to request menu operation */
6071 STATIC_OVL boolean
6072 accept_menu_prefix(cmd_func)
6073 int NDECL((*cmd_func));
6074 {
6075     if (cmd_func == dopickup || cmd_func == dotip
6076         /* eat, #offer, and apply tinning-kit all use floorfood() to pick
6077            an item on floor or in invent; 'm' skips picking from floor
6078            (ie, inventory only) rather than request use of menu operation */
6079         || cmd_func == doeat || cmd_func == dosacrifice || cmd_func == doapply
6080         /* 'm' for removing saddle from adjacent monster without checking
6081            for containers at <u.ux,u.uy> */
6082         || cmd_func == doloot
6083         /* travel: pop up a menu of interesting targets in view */
6084         || cmd_func == dotravel
6085         /* wizard mode ^V and ^T */
6086         || cmd_func == wiz_level_tele || cmd_func == dotelecmd
6087         /* 'm' prefix allowed for some extended commands */
6088         || cmd_func == doextcmd || cmd_func == doextlist)
6089         return TRUE;
6090     return FALSE;
6091 }
6092
6093 char
6094 randomkey()
6095 {
6096     static unsigned i = 0;
6097     char c;
6098
6099     switch (rn2(16)) {
6100     default:
6101         c = '\033';
6102         break;
6103     case 0:
6104         c = '\n';
6105         break;
6106     case 1:
6107     case 2:
6108     case 3:
6109     case 4:
6110         c = (char) rn1('~' - ' ' + 1, ' ');
6111         break;
6112     case 5:
6113         c = (char) (rn2(2) ? '\t' : ' ');
6114         break;
6115     case 6:
6116         c = (char) rn1('z' - 'a' + 1, 'a');
6117         break;
6118     case 7:
6119         c = (char) rn1('Z' - 'A' + 1, 'A');
6120         break;
6121     case 8:
6122         c = extcmdlist[i++ % SIZE(extcmdlist)].key;
6123         break;
6124     case 9:
6125         c = '#';
6126         break;
6127     case 10:
6128     case 11:
6129     case 12:
6130         c = Cmd.dirchars[rn2(8)];
6131         if (!rn2(7))
6132             c = !Cmd.num_pad ? (!rn2(3) ? C(c) : (c + 'A' - 'a')) : M(c);
6133         break;
6134     case 13:
6135         c = (char) rn1('9' - '0' + 1, '0');
6136         break;
6137     case 14:
6138         /* any char, but avoid '\0' because it's used for mouse click */
6139         c = (char) rnd(iflags.wc_eight_bit_input ? 255 : 127);
6140         break;
6141     }
6142
6143     return c;
6144 }
6145
6146 void
6147 random_response(buf, sz)
6148 char *buf;
6149 int sz;
6150 {
6151     char c;
6152     int count = 0;
6153
6154     for (;;) {
6155         c = randomkey();
6156         if (c == '\n')
6157             break;
6158         if (c == '\033') {
6159             count = 0;
6160             break;
6161         }
6162         if (count < sz - 1)
6163             buf[count++] = c;
6164     }
6165     buf[count] = '\0';
6166 }
6167
6168 int
6169 rnd_extcmd_idx(VOID_ARGS)
6170 {
6171     return rn2(extcmdlist_length + 1) - 1;
6172 }
6173
6174 int
6175 ch2spkeys(c, start, end)
6176 char c;
6177 int start,end;
6178 {
6179     int i;
6180
6181     for (i = start; i <= end; i++)
6182         if (Cmd.spkeys[i] == c)
6183             return i;
6184     return NHKF_ESC;
6185 }
6186
6187 void
6188 rhack(cmd)
6189 register char *cmd;
6190 {
6191     int spkey;
6192     boolean prefix_seen, bad_command,
6193         firsttime = (cmd == 0);
6194
6195     iflags.menu_requested = FALSE;
6196 #ifdef SAFERHANGUP
6197     if (program_state.done_hup)
6198         end_of_input();
6199 #endif
6200     if (firsttime) {
6201         context.nopick = 0;
6202         cmd = parse();
6203     }
6204     if (*cmd == Cmd.spkeys[NHKF_ESC]) {
6205         context.move = FALSE;
6206         return;
6207     }
6208     if (*cmd == DOAGAIN && !in_doagain && saveq[0]) {
6209         in_doagain = TRUE;
6210         stail = 0;
6211         rhack((char *) 0); /* read and execute command */
6212         in_doagain = FALSE;
6213         return;
6214     }
6215     /* Special case of *cmd == ' ' handled better below */
6216     if (!*cmd || *cmd == (char) 0377) {
6217         nhbell();
6218         context.move = FALSE;
6219         return; /* probably we just had an interrupt */
6220     }
6221
6222     /* handle most movement commands */
6223     prefix_seen = FALSE;
6224     context.travel = context.travel1 = 0;
6225     spkey = ch2spkeys(*cmd, NHKF_RUN, NHKF_CLICKLOOK);
6226
6227     switch (spkey) {
6228     case NHKF_RUSH:
6229         if (movecmd(cmd[1])) {
6230             context.run = 2;
6231             domove_attempting |= DOMOVE_RUSH;
6232         } else
6233             prefix_seen = TRUE;
6234         break;
6235     case NHKF_RUN2:
6236         if (!Cmd.num_pad)
6237             break;
6238         /*FALLTHRU*/
6239     case NHKF_RUN:
6240         if (movecmd(lowc(cmd[1]))) {
6241             context.run = 3;
6242             domove_attempting |= DOMOVE_RUSH;
6243         } else
6244             prefix_seen = TRUE;
6245         break;
6246     case NHKF_FIGHT2:
6247         if (!Cmd.num_pad)
6248             break;
6249         /*FALLTHRU*/
6250     /* Effects of movement commands and invisible monsters:
6251      * m: always move onto space (even if 'I' remembered)
6252      * F: always attack space (even if 'I' not remembered)
6253      * normal movement: attack if 'I', move otherwise.
6254      */
6255     case NHKF_FIGHT:
6256         if (movecmd(cmd[1])) {
6257             context.forcefight = 1;
6258             domove_attempting |= DOMOVE_WALK;
6259         } else
6260             prefix_seen = TRUE;
6261         break;
6262     case NHKF_NOPICKUP:
6263         if (movecmd(cmd[1]) || u.dz) {
6264             context.run = 0;
6265             context.nopick = 1;
6266             if (!u.dz)
6267                 domove_attempting |= DOMOVE_WALK;
6268             else
6269                 cmd[0] = cmd[1]; /* "m<" or "m>" */
6270         } else
6271             prefix_seen = TRUE;
6272         break;
6273     case NHKF_RUN_NOPICKUP:
6274         if (movecmd(lowc(cmd[1]))) {
6275             context.run = 1;
6276             context.nopick = 1;
6277             domove_attempting |= DOMOVE_RUSH;
6278         } else
6279             prefix_seen = TRUE;
6280         break;
6281     case NHKF_DOINV:
6282         if (!Cmd.num_pad)
6283             break;
6284         (void) ddoinv(); /* a convenience borrowed from the PC */
6285         context.move = FALSE;
6286         multi = 0;
6287         return;
6288     case NHKF_CLICKLOOK:
6289         if (iflags.clicklook) {
6290             context.move = FALSE;
6291             do_look(2, &clicklook_cc);
6292         }
6293         return;
6294     case NHKF_TRAVEL:
6295         if (flags.travelcmd) {
6296             context.travel = 1;
6297             context.travel1 = 1;
6298             context.run = 8;
6299             context.nopick = 1;
6300             domove_attempting |= DOMOVE_RUSH;
6301             break;
6302         }
6303         /*FALLTHRU*/
6304     default:
6305         if (movecmd(*cmd)) { /* ordinary movement */
6306             context.run = 0; /* only matters here if it was 8 */
6307             domove_attempting |= DOMOVE_WALK;
6308         } else if (movecmd(Cmd.num_pad ? unmeta(*cmd) : lowc(*cmd))) {
6309             context.run = 1;
6310             domove_attempting |= DOMOVE_RUSH;
6311         } else if (movecmd(unctrl(*cmd))) {
6312             context.run = 3;
6313             domove_attempting |= DOMOVE_RUSH;
6314         }
6315         break;
6316     }
6317
6318     /* some special prefix handling */
6319     /* overload 'm' prefix to mean "request a menu" */
6320     if (prefix_seen && cmd[0] == Cmd.spkeys[NHKF_REQMENU]) {
6321         /* (for func_tab cast, see below) */
6322         const struct ext_func_tab *ft = Cmd.commands[cmd[1] & 0xff];
6323         int NDECL((*func)) = ft ? ((struct ext_func_tab *) ft)->ef_funct : 0;
6324
6325         if (func && accept_menu_prefix(func)) {
6326             iflags.menu_requested = TRUE;
6327             ++cmd;
6328         }
6329     }
6330
6331     if (((domove_attempting & (DOMOVE_RUSH | DOMOVE_WALK)) != 0L)
6332                             && !context.travel && !dxdy_moveok()) {
6333         /* trying to move diagonally as a grid bug;
6334            this used to be treated by movecmd() as not being
6335            a movement attempt, but that didn't provide for any
6336            feedback and led to strangeness if the key pressed
6337            ('u' in particular) was overloaded for num_pad use */
6338 /*JP
6339         You_cant("get there from here...");
6340 */
6341         You_cant("\82±\82±\82©\82ç\82»\82±\82Ö\82Í\8ds\82¯\82Ü\82¹\82ñ\81D\81D\81D");
6342         context.run = 0;
6343         context.nopick = context.forcefight = FALSE;
6344         context.move = context.mv = FALSE;
6345         multi = 0;
6346         return;
6347     }
6348
6349     if ((domove_attempting & DOMOVE_WALK) != 0L) {
6350         if (multi)
6351             context.mv = TRUE;
6352         domove();
6353         context.forcefight = 0;
6354         return;
6355     } else if ((domove_attempting & DOMOVE_RUSH) != 0L) {
6356         if (firsttime) {
6357             if (!multi)
6358                 multi = max(COLNO, ROWNO);
6359             u.last_str_turn = 0;
6360         }
6361         context.mv = TRUE;
6362         domove();
6363         return;
6364     } else if (prefix_seen && cmd[1] == Cmd.spkeys[NHKF_ESC]) {
6365         /* <prefix><escape> */
6366         /* don't report "unknown command" for change of heart... */
6367         bad_command = FALSE;
6368     } else if (*cmd == ' ' && !flags.rest_on_space) {
6369         bad_command = TRUE; /* skip cmdlist[] loop */
6370
6371     /* handle all other commands */
6372     } else {
6373         register const struct ext_func_tab *tlist;
6374         int res, NDECL((*func));
6375
6376         /* current - use *cmd to directly index cmdlist array */
6377         if ((tlist = Cmd.commands[*cmd & 0xff]) != 0) {
6378             if (!wizard && (tlist->flags & WIZMODECMD)) {
6379 /*JP
6380                 You_cant("do that!");
6381 */
6382                 pline("\82»\82ê\82Í\82Å\82«\82Ü\82¹\82ñ\81I");
6383                 res = 0;
6384             } else if (u.uburied && !(tlist->flags & IFBURIED)) {
6385 /*JP
6386                 You_cant("do that while you are buried!");
6387 */
6388                 You("\96\84\82Ü\82Á\82Ä\82¢\82é\8e\9e\82É\82»\82ñ\82È\82±\82Æ\82Í\82Å\82«\82È\82¢\81I");
6389                 res = 0;
6390             } else {
6391                 /* we discard 'const' because some compilers seem to have
6392                    trouble with the pointer passed to set_occupation() */
6393                 func = ((struct ext_func_tab *) tlist)->ef_funct;
6394                 if (tlist->f_text && !occupation && multi)
6395                     set_occupation(func, tlist->f_text, multi);
6396                 res = (*func)(); /* perform the command */
6397             }
6398             if (!res) {
6399                 context.move = FALSE;
6400                 multi = 0;
6401             }
6402             return;
6403         }
6404         /* if we reach here, cmd wasn't found in cmdlist[] */
6405         bad_command = TRUE;
6406     }
6407
6408     if (bad_command) {
6409         char expcmd[20]; /* we expect 'cmd' to point to 1 or 2 chars */
6410         char c, c1 = cmd[1];
6411
6412         expcmd[0] = '\0';
6413         while ((c = *cmd++) != '\0')
6414             Strcat(expcmd, visctrl(c)); /* add 1..4 chars plus terminator */
6415
6416 /*JP
6417         if (!prefix_seen || !help_dir(c1, spkey, "Invalid direction key!"))
6418 */
6419         if (!prefix_seen || !help_dir(c1, spkey, "\96³\8cø\82È\95û\8cü\8ew\92è\82Å\82·\81I"))
6420 /*JP
6421             Norep("Unknown command '%s'.", expcmd);
6422 */
6423             Norep("'%s'\83R\83}\83\93\83h\81H", expcmd);
6424     }
6425     /* didn't move */
6426     context.move = FALSE;
6427     multi = 0;
6428     return;
6429 }
6430
6431 /* convert an x,y pair into a direction code */
6432 int
6433 xytod(x, y)
6434 schar x, y;
6435 {
6436     register int dd;
6437
6438     for (dd = 0; dd < 8; dd++)
6439         if (x == xdir[dd] && y == ydir[dd])
6440             return dd;
6441     return -1;
6442 }
6443
6444 /* convert a direction code into an x,y pair */
6445 void
6446 dtoxy(cc, dd)
6447 coord *cc;
6448 register int dd;
6449 {
6450     cc->x = xdir[dd];
6451     cc->y = ydir[dd];
6452     return;
6453 }
6454
6455 /* also sets u.dz, but returns false for <> */
6456 int
6457 movecmd(sym)
6458 char sym;
6459 {
6460     register const char *dp = index(Cmd.dirchars, sym);
6461
6462     u.dz = 0;
6463     if (!dp || !*dp)
6464         return 0;
6465     u.dx = xdir[dp - Cmd.dirchars];
6466     u.dy = ydir[dp - Cmd.dirchars];
6467     u.dz = zdir[dp - Cmd.dirchars];
6468 #if 0 /* now handled elsewhere */
6469     if (u.dx && u.dy && NODIAG(u.umonnum)) {
6470         u.dx = u.dy = 0;
6471         return 0;
6472     }
6473 #endif
6474     return !u.dz;
6475 }
6476
6477 /* grid bug handling which used to be in movecmd() */
6478 int
6479 dxdy_moveok()
6480 {
6481     if (u.dx && u.dy && NODIAG(u.umonnum))
6482         u.dx = u.dy = 0;
6483     return u.dx || u.dy;
6484 }
6485
6486 /* decide whether a character (user input keystroke) requests screen repaint */
6487 boolean
6488 redraw_cmd(c)
6489 char c;
6490 {
6491     return (boolean) (c == Cmd.spkeys[NHKF_REDRAW]
6492                       || (Cmd.num_pad && c == Cmd.spkeys[NHKF_REDRAW2]));
6493 }
6494
6495 boolean
6496 prefix_cmd(c)
6497 char c;
6498 {
6499     return (c == Cmd.spkeys[NHKF_RUSH]
6500             || c == Cmd.spkeys[NHKF_RUN]
6501             || c == Cmd.spkeys[NHKF_NOPICKUP]
6502             || c == Cmd.spkeys[NHKF_RUN_NOPICKUP]
6503             || c == Cmd.spkeys[NHKF_FIGHT]
6504             || (Cmd.num_pad && (c == Cmd.spkeys[NHKF_RUN2]
6505                                 || c == Cmd.spkeys[NHKF_FIGHT2])));
6506 }
6507
6508 /*
6509  * uses getdir() but unlike getdir() it specifically
6510  * produces coordinates using the direction from getdir()
6511  * and verifies that those coordinates are ok.
6512  *
6513  * If the call to getdir() returns 0, Never_mind is displayed.
6514  * If the resulting coordinates are not okay, emsg is displayed.
6515  *
6516  * Returns non-zero if coordinates in cc are valid.
6517  */
6518 int
6519 get_adjacent_loc(prompt, emsg, x, y, cc)
6520 const char *prompt, *emsg;
6521 xchar x, y;
6522 coord *cc;
6523 {
6524     xchar new_x, new_y;
6525     if (!getdir(prompt)) {
6526         pline1(Never_mind);
6527         return 0;
6528     }
6529     new_x = x + u.dx;
6530     new_y = y + u.dy;
6531     if (cc && isok(new_x, new_y)) {
6532         cc->x = new_x;
6533         cc->y = new_y;
6534     } else {
6535         if (emsg)
6536             pline1(emsg);
6537         return 0;
6538     }
6539     return 1;
6540 }
6541
6542 int
6543 getdir(s)
6544 const char *s;
6545 {
6546     char dirsym;
6547     int is_mov;
6548
6549  retry:
6550     if (in_doagain || *readchar_queue)
6551         dirsym = readchar();
6552     else
6553 /*JP
6554         dirsym = yn_function((s && *s != '^') ? s : "In what direction?",
6555 */
6556         dirsym = yn_function((s && *s != '^') ? s : "\82Ç\82Ì\95û\8cü\81H",
6557                              (char *) 0, '\0');
6558     /* remove the prompt string so caller won't have to */
6559     clear_nhwindow(WIN_MESSAGE);
6560
6561     if (redraw_cmd(dirsym)) { /* ^R */
6562         docrt();              /* redraw */
6563         goto retry;
6564     }
6565     savech(dirsym);
6566
6567     if (dirsym == Cmd.spkeys[NHKF_GETDIR_SELF]
6568         || dirsym == Cmd.spkeys[NHKF_GETDIR_SELF2]) {
6569         u.dx = u.dy = u.dz = 0;
6570     } else if (!(is_mov = movecmd(dirsym)) && !u.dz) {
6571         boolean did_help = FALSE, help_requested;
6572
6573         if (!index(quitchars, dirsym)) {
6574             help_requested = (dirsym == Cmd.spkeys[NHKF_GETDIR_HELP]);
6575             if (help_requested || iflags.cmdassist) {
6576                 did_help = help_dir((s && *s == '^') ? dirsym : '\0',
6577                                     NHKF_ESC,
6578                                     help_requested ? (const char *) 0
6579 /*JP
6580                                                   : "Invalid direction key!");
6581 */
6582                                                   : "\96³\8cø\82È\95û\8cü\8ew\92è\82Å\82·\81I");
6583                 if (help_requested)
6584                     goto retry;
6585             }
6586             if (!did_help)
6587 /*JP
6588                 pline("What a strange direction!");
6589 */
6590                 pline("\82¸\82¢\82Ô\82ñ\82Æ\8aï\96­\82È\95û\8cü\82¾\81I");
6591         }
6592         return 0;
6593     } else if (is_mov && !dxdy_moveok()) {
6594 /*JP
6595         You_cant("orient yourself that direction.");
6596 */
6597         You_cant("\8cü\82«\82É\8e©\95ª\8e©\90g\82ð\8ew\92è\82Å\82«\82È\82¢\81D");
6598         return 0;
6599     }
6600     if (!u.dz && (Stunned || (Confusion && !rn2(5))))
6601         confdir();
6602     return 1;
6603 }
6604
6605 STATIC_OVL void
6606 show_direction_keys(win, centerchar, nodiag)
6607 winid win; /* should specify a window which is using a fixed-width font... */
6608 char centerchar; /* '.' or '@' or ' ' */
6609 boolean nodiag;
6610 {
6611     char buf[BUFSZ];
6612
6613     if (!centerchar)
6614         centerchar = ' ';
6615
6616     if (nodiag) {
6617         Sprintf(buf, "             %c   ", Cmd.move_N);
6618         putstr(win, 0, buf);
6619         putstr(win, 0, "             |   ");
6620         Sprintf(buf, "          %c- %c -%c",
6621                 Cmd.move_W, centerchar, Cmd.move_E);
6622         putstr(win, 0, buf);
6623         putstr(win, 0, "             |   ");
6624         Sprintf(buf, "             %c   ", Cmd.move_S);
6625         putstr(win, 0, buf);
6626     } else {
6627         Sprintf(buf, "          %c  %c  %c",
6628                 Cmd.move_NW, Cmd.move_N, Cmd.move_NE);
6629         putstr(win, 0, buf);
6630         putstr(win, 0, "           \\ | / ");
6631         Sprintf(buf, "          %c- %c -%c",
6632                 Cmd.move_W, centerchar, Cmd.move_E);
6633         putstr(win, 0, buf);
6634         putstr(win, 0, "           / | \\ ");
6635         Sprintf(buf, "          %c  %c  %c",
6636                 Cmd.move_SW, Cmd.move_S, Cmd.move_SE);
6637         putstr(win, 0, buf);
6638     };
6639 }
6640
6641 /* explain choices if player has asked for getdir() help or has given
6642    an invalid direction after a prefix key ('F', 'g', 'm', &c), which
6643    might be bogus but could be up, down, or self when not applicable */
6644 STATIC_OVL boolean
6645 help_dir(sym, spkey, msg)
6646 char sym;
6647 int spkey; /* NHKF_ code for prefix key, if one was used, or for ESC */
6648 const char *msg;
6649 {
6650     static const char wiz_only_list[] = "EFGIVW";
6651     char ctrl;
6652     winid win;
6653     char buf[BUFSZ], buf2[BUFSZ], *explain;
6654     const char *dothat, *how;
6655     boolean prefixhandling, viawindow;
6656
6657     /* NHKF_ESC indicates that player asked for help at getdir prompt */
6658     viawindow = (spkey == NHKF_ESC || iflags.cmdassist);
6659     prefixhandling = (spkey != NHKF_ESC);
6660     /*
6661      * Handling for prefix keys that don't want special directions.
6662      * Delivered via pline if 'cmdassist' is off, or instead of the
6663      * general message if it's on.
6664      */
6665     dothat = "do that";
6666     how = " at"; /* for "<action> at yourself"; not used for up/down */
6667     switch (spkey) {
6668     case NHKF_NOPICKUP:
6669         dothat = "move";
6670         break;
6671     case NHKF_RUSH:
6672         dothat = "rush";
6673         break;
6674     case NHKF_RUN2:
6675         if (!Cmd.num_pad)
6676             break;
6677         /*FALLTHRU*/
6678     case NHKF_RUN:
6679     case NHKF_RUN_NOPICKUP:
6680         dothat = "run";
6681         break;
6682     case NHKF_FIGHT2:
6683         if (!Cmd.num_pad)
6684             break;
6685         /*FALLTHRU*/
6686     case NHKF_FIGHT:
6687         dothat = "fight";
6688         how = ""; /* avoid "fight at yourself" */
6689         break;
6690     default:
6691         prefixhandling = FALSE;
6692         break;
6693     }
6694
6695     buf[0] = '\0';
6696     /* for movement prefix followed by '.' or (numpad && 's') to mean 'self';
6697        note: '-' for hands (inventory form of 'self') is not handled here */
6698     if (prefixhandling
6699         && (sym == Cmd.spkeys[NHKF_GETDIR_SELF]
6700             || (Cmd.num_pad && sym == Cmd.spkeys[NHKF_GETDIR_SELF2]))) {
6701         Sprintf(buf, "You can't %s%s yourself.", dothat, how);
6702     /* for movement prefix followed by up or down */
6703     } else if (prefixhandling && (sym == '<' || sym == '>')) {
6704         Sprintf(buf, "You can't %s %s.", dothat,
6705                 /* was "upwards" and "downwards", but they're considered
6706                    to be variants of canonical "upward" and "downward" */
6707                 (sym == '<') ? "upward" : "downward");
6708     }
6709
6710     /* if '!cmdassist', display via pline() and we're done (note: asking
6711        for help at getdir() prompt forces cmdassist for this operation) */
6712     if (!viawindow) {
6713         if (prefixhandling) {
6714             if (!*buf)
6715                 Sprintf(buf, "Invalid direction for '%s' prefix.",
6716                         visctrl(Cmd.spkeys[spkey]));
6717             pline("%s", buf);
6718             return TRUE;
6719         }
6720         /* when 'cmdassist' is off and caller doesn't insist, do nothing */
6721         return FALSE;
6722     }
6723
6724     win = create_nhwindow(NHW_TEXT);
6725     if (!win)
6726         return FALSE;
6727
6728     if (*buf) {
6729         /* show bad-prefix message instead of general invalid-direction one */
6730         putstr(win, 0, buf);
6731         putstr(win, 0, "");
6732     } else if (msg) {
6733         Sprintf(buf, "cmdassist: %s", msg);
6734         putstr(win, 0, buf);
6735         putstr(win, 0, "");
6736     }
6737
6738     if (!prefixhandling && (letter(sym) || sym == '[')) {
6739         /* '[': old 'cmdhelp' showed ESC as ^[ */
6740         sym = highc(sym); /* @A-Z[ (note: letter() accepts '@') */
6741         ctrl = (sym - 'A') + 1; /* 0-27 (note: 28-31 aren't applicable) */
6742         if ((explain = dowhatdoes_core(ctrl, buf2)) != 0
6743             && (!index(wiz_only_list, sym) || wizard)) {
6744             Sprintf(buf, "Are you trying to use ^%c%s?", sym,
6745                     index(wiz_only_list, sym) ? ""
6746                         : " as specified in the Guidebook");
6747             putstr(win, 0, buf);
6748             putstr(win, 0, "");
6749             putstr(win, 0, explain);
6750             putstr(win, 0, "");
6751             putstr(win, 0,
6752                   "To use that command, hold down the <Ctrl> key as a shift");
6753             Sprintf(buf, "and press the <%c> key.", sym);
6754             putstr(win, 0, buf);
6755             putstr(win, 0, "");
6756         }
6757     }
6758
6759 #if 0 /*JP:T*/
6760     Sprintf(buf, "Valid direction keys%s%s%s are:",
6761             prefixhandling ? " to " : "", prefixhandling ? dothat : "",
6762             NODIAG(u.umonnum) ? " in your current form" : "");
6763 #else
6764     Sprintf(buf, "%s%s%s\97L\8cø\82È\95û\8cü\8ew\92è\82Í:",
6765             prefixhandling ? dothat : "", prefixhandling ? "\82½\82ß\82Ì" : "",
6766             NODIAG(u.umonnum) ? " \8c»\8dÝ\82Ì\8ep\82Å\82Ì" : "");
6767 #endif
6768     putstr(win, 0, buf);
6769     show_direction_keys(win, !prefixhandling ? '.' : ' ', NODIAG(u.umonnum));
6770
6771     if (!prefixhandling || spkey == NHKF_NOPICKUP) {
6772         /* NOPICKUP: unlike the other prefix keys, 'm' allows up/down for
6773            stair traversal; we won't get here when "m<" or "m>" has been
6774            given but we include up and down for 'm'+invalid_direction;
6775            self is excluded as a viable direction for every prefix */
6776         putstr(win, 0, "");
6777         putstr(win, 0, "          <  up");
6778         putstr(win, 0, "          >  down");
6779         if (!prefixhandling) {
6780             int selfi = Cmd.num_pad ? NHKF_GETDIR_SELF2 : NHKF_GETDIR_SELF;
6781
6782             Sprintf(buf,   "       %4s  direct at yourself",
6783                     visctrl(Cmd.spkeys[selfi]));
6784             putstr(win, 0, buf);
6785         }
6786     }
6787
6788     if (msg) {
6789         /* non-null msg means that this wasn't an explicit user request */
6790         putstr(win, 0, "");
6791         putstr(win, 0,
6792 /*JP
6793                "(Suppress this message with !cmdassist in config file.)");
6794 */
6795                "(\82±\82Ì\83\81\83b\83Z\81[\83W\82ð\95\\8e¦\82µ\82½\82­\82È\82¢\8fê\8d\87\82Í\90Ý\92è\83t\83@\83C\83\8b\82É !cmdassist \82ð\90Ý\92è\82µ\82Ä\82­\82¾\82³\82¢\81D)");
6796     }
6797     display_nhwindow(win, FALSE);
6798     destroy_nhwindow(win);
6799     return TRUE;
6800 }
6801
6802 void
6803 confdir()
6804 {
6805     register int x = NODIAG(u.umonnum) ? 2 * rn2(4) : rn2(8);
6806
6807     u.dx = xdir[x];
6808     u.dy = ydir[x];
6809     return;
6810 }
6811
6812 const char *
6813 directionname(dir)
6814 int dir;
6815 {
6816     static NEARDATA const char *const dirnames[] = {
6817         "west",      "northwest", "north",     "northeast", "east",
6818         "southeast", "south",     "southwest", "down",      "up",
6819     };
6820
6821     if (dir < 0 || dir >= SIZE(dirnames))
6822         return "invalid";
6823     return dirnames[dir];
6824 }
6825
6826 int
6827 isok(x, y)
6828 register int x, y;
6829 {
6830     /* x corresponds to curx, so x==1 is the first column. Ach. %% */
6831     return x >= 1 && x <= COLNO - 1 && y >= 0 && y <= ROWNO - 1;
6832 }
6833
6834 /* #herecmdmenu command */
6835 STATIC_PTR int
6836 doherecmdmenu(VOID_ARGS)
6837 {
6838     char ch = here_cmd_menu(TRUE);
6839
6840     return ch ? 1 : 0;
6841 }
6842
6843 /* #therecmdmenu command, a way to test there_cmd_menu without mouse */
6844 STATIC_PTR int
6845 dotherecmdmenu(VOID_ARGS)
6846 {
6847     char ch;
6848
6849     if (!getdir((const char *) 0) || !isok(u.ux + u.dx, u.uy + u.dy))
6850         return 0;
6851
6852     if (u.dx || u.dy)
6853         ch = there_cmd_menu(TRUE, u.ux + u.dx, u.uy + u.dy);
6854     else
6855         ch = here_cmd_menu(TRUE);
6856
6857     return ch ? 1 : 0;
6858 }
6859
6860 STATIC_OVL void
6861 add_herecmd_menuitem(win, func, text)
6862 winid win;
6863 int NDECL((*func));
6864 const char *text;
6865 {
6866     char ch;
6867     anything any;
6868
6869     if ((ch = cmd_from_func(func)) != '\0') {
6870         any = zeroany;
6871         any.a_nfunc = func;
6872         add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, text, MENU_UNSELECTED);
6873     }
6874 }
6875
6876 STATIC_OVL char
6877 there_cmd_menu(doit, x, y)
6878 boolean doit;
6879 int x, y;
6880 {
6881     winid win;
6882     char ch;
6883     char buf[BUFSZ];
6884     schar typ = levl[x][y].typ;
6885     int npick, K = 0;
6886     menu_item *picks = (menu_item *) 0;
6887     struct trap *ttmp;
6888     struct monst *mtmp;
6889
6890     win = create_nhwindow(NHW_MENU);
6891     start_menu(win);
6892
6893     if (IS_DOOR(typ)) {
6894         boolean key_or_pick, card;
6895         int dm = levl[x][y].doormask;
6896
6897         if ((dm & (D_CLOSED | D_LOCKED))) {
6898             add_herecmd_menuitem(win, doopen, "Open the door"), ++K;
6899             /* unfortunately there's no lknown flag for doors to
6900                remember the locked/unlocked state */
6901             key_or_pick = (carrying(SKELETON_KEY) || carrying(LOCK_PICK));
6902             card = (carrying(CREDIT_CARD) != 0);
6903             if (key_or_pick || card) {
6904                 Sprintf(buf, "%sunlock the door",
6905                         key_or_pick ? "lock or " : "");
6906                 add_herecmd_menuitem(win, doapply, upstart(buf)), ++K;
6907             }
6908             /* unfortunately there's no tknown flag for doors (or chests)
6909                to remember whether a trap had been found */
6910             add_herecmd_menuitem(win, dountrap,
6911                                  "Search the door for a trap"), ++K;
6912             /* [what about #force?] */
6913             add_herecmd_menuitem(win, dokick, "Kick the door"), ++K;
6914         } else if ((dm & D_ISOPEN)) {
6915             add_herecmd_menuitem(win, doclose, "Close the door"), ++K;
6916         }
6917     }
6918
6919     if (typ <= SCORR)
6920         add_herecmd_menuitem(win, dosearch, "Search for secret doors"), ++K;
6921
6922     if ((ttmp = t_at(x, y)) != 0 && ttmp->tseen) {
6923         add_herecmd_menuitem(win, doidtrap, "Examine trap"), ++K;
6924         if (ttmp->ttyp != VIBRATING_SQUARE)
6925             add_herecmd_menuitem(win, dountrap, "Attempt to disarm trap"), ++K;
6926     }
6927
6928     mtmp = m_at(x, y);
6929     if (mtmp && !canspotmon(mtmp))
6930         mtmp = 0;
6931     if (mtmp && which_armor(mtmp, W_SADDLE)) {
6932         char *mnam = x_monnam(mtmp, ARTICLE_THE, (char *) 0,
6933                               SUPPRESS_SADDLE, FALSE);
6934
6935         if (!u.usteed) {
6936             Sprintf(buf, "Ride %s", mnam);
6937             add_herecmd_menuitem(win, doride, buf), ++K;
6938         }
6939         Sprintf(buf, "Remove saddle from %s", mnam);
6940         add_herecmd_menuitem(win, doloot, buf), ++K;
6941     }
6942     if (mtmp && can_saddle(mtmp) && !which_armor(mtmp, W_SADDLE)
6943         && carrying(SADDLE)) {
6944         Sprintf(buf, "Put saddle on %s", mon_nam(mtmp)), ++K;
6945         add_herecmd_menuitem(win, doapply, buf);
6946     }
6947 #if 0
6948     if (mtmp || glyph_is_invisible(glyph_at(x, y))) {
6949         /* "Attack %s", mtmp ? mon_nam(mtmp) : "unseen creature" */
6950     } else {
6951         /* "Move %s", direction */
6952     }
6953 #endif
6954
6955     if (K) {
6956         end_menu(win, "What do you want to do?");
6957         npick = select_menu(win, PICK_ONE, &picks);
6958     } else {
6959         pline("No applicable actions.");
6960         npick = 0;
6961     }
6962     destroy_nhwindow(win);
6963     ch = '\0';
6964     if (npick > 0) {
6965         int NDECL((*func)) = picks->item.a_nfunc;
6966         free((genericptr_t) picks);
6967
6968         if (doit) {
6969             int ret = (*func)();
6970
6971             ch = (char) ret;
6972         } else {
6973             ch = cmd_from_func(func);
6974         }
6975     }
6976     return ch;
6977 }
6978
6979 STATIC_OVL char
6980 here_cmd_menu(doit)
6981 boolean doit;
6982 {
6983     winid win;
6984     char ch;
6985     char buf[BUFSZ];
6986     schar typ = levl[u.ux][u.uy].typ;
6987     int npick;
6988     menu_item *picks = (menu_item *) 0;
6989
6990     win = create_nhwindow(NHW_MENU);
6991     start_menu(win);
6992
6993     if (IS_FOUNTAIN(typ) || IS_SINK(typ)) {
6994         Sprintf(buf, "Drink from the %s",
6995                 defsyms[IS_FOUNTAIN(typ) ? S_fountain : S_sink].explanation);
6996         add_herecmd_menuitem(win, dodrink, buf);
6997     }
6998     if (IS_FOUNTAIN(typ))
6999         add_herecmd_menuitem(win, dodip,
7000                              "Dip something into the fountain");
7001     if (IS_THRONE(typ))
7002         add_herecmd_menuitem(win, dosit,
7003                              "Sit on the throne");
7004
7005     if ((u.ux == xupstair && u.uy == yupstair)
7006         || (u.ux == sstairs.sx && u.uy == sstairs.sy && sstairs.up)
7007         || (u.ux == xupladder && u.uy == yupladder)) {
7008         Sprintf(buf, "Go up the %s",
7009                 (u.ux == xupladder && u.uy == yupladder)
7010                 ? "ladder" : "stairs");
7011         add_herecmd_menuitem(win, doup, buf);
7012     }
7013     if ((u.ux == xdnstair && u.uy == ydnstair)
7014         || (u.ux == sstairs.sx && u.uy == sstairs.sy && !sstairs.up)
7015         || (u.ux == xdnladder && u.uy == ydnladder)) {
7016         Sprintf(buf, "Go down the %s",
7017                 (u.ux == xupladder && u.uy == yupladder)
7018                 ? "ladder" : "stairs");
7019         add_herecmd_menuitem(win, dodown, buf);
7020     }
7021     if (u.usteed) { /* another movement choice */
7022         Sprintf(buf, "Dismount %s",
7023                 x_monnam(u.usteed, ARTICLE_THE, (char *) 0,
7024                          SUPPRESS_SADDLE, FALSE));
7025         add_herecmd_menuitem(win, doride, buf);
7026     }
7027
7028 #if 0
7029     if (Upolyd) { /* before objects */
7030         Sprintf(buf, "Use %s special ability",
7031                 s_suffix(mons[u.umonnum].mname));
7032         add_herecmd_menuitem(win, domonability, buf);
7033     }
7034 #endif
7035
7036     if (OBJ_AT(u.ux, u.uy)) {
7037         struct obj *otmp = level.objects[u.ux][u.uy];
7038
7039         Sprintf(buf, "Pick up %s", otmp->nexthere ? "items" : doname(otmp));
7040         add_herecmd_menuitem(win, dopickup, buf);
7041
7042         if (Is_container(otmp)) {
7043             Sprintf(buf, "Loot %s", doname(otmp));
7044             add_herecmd_menuitem(win, doloot, buf);
7045         }
7046         if (otmp->oclass == FOOD_CLASS) {
7047             Sprintf(buf, "Eat %s", doname(otmp));
7048             add_herecmd_menuitem(win, doeat, buf);
7049         }
7050     }
7051
7052     if (invent)
7053         add_herecmd_menuitem(win, dodrop, "Drop items");
7054
7055     add_herecmd_menuitem(win, donull, "Rest one turn");
7056     add_herecmd_menuitem(win, dosearch, "Search around you");
7057     add_herecmd_menuitem(win, dolook, "Look at what is here");
7058
7059     end_menu(win, "What do you want to do?");
7060     npick = select_menu(win, PICK_ONE, &picks);
7061     destroy_nhwindow(win);
7062     ch = '\0';
7063     if (npick > 0) {
7064         int NDECL((*func)) = picks->item.a_nfunc;
7065         free((genericptr_t) picks);
7066
7067         if (doit) {
7068             int ret = (*func)();
7069
7070             ch = (char) ret;
7071         } else {
7072             ch = cmd_from_func(func);
7073         }
7074     }
7075     return ch;
7076 }
7077
7078
7079 static NEARDATA int last_multi;
7080
7081 /*
7082  * convert a MAP window position into a movecmd
7083  */
7084 const char *
7085 click_to_cmd(x, y, mod)
7086 int x, y, mod;
7087 {
7088     int dir;
7089     static char cmd[4];
7090     cmd[1] = 0;
7091
7092     if (iflags.clicklook && mod == CLICK_2) {
7093         clicklook_cc.x = x;
7094         clicklook_cc.y = y;
7095         cmd[0] = Cmd.spkeys[NHKF_CLICKLOOK];
7096         return cmd;
7097     }
7098
7099     x -= u.ux;
7100     y -= u.uy;
7101
7102     if (flags.travelcmd) {
7103         if (abs(x) <= 1 && abs(y) <= 1) {
7104             x = sgn(x), y = sgn(y);
7105         } else {
7106             u.tx = u.ux + x;
7107             u.ty = u.uy + y;
7108             cmd[0] = Cmd.spkeys[NHKF_TRAVEL];
7109             return cmd;
7110         }
7111
7112         if (x == 0 && y == 0) {
7113             if (iflags.herecmd_menu) {
7114                 cmd[0] = here_cmd_menu(FALSE);
7115                 return cmd;
7116             }
7117
7118             /* here */
7119             if (IS_FOUNTAIN(levl[u.ux][u.uy].typ)
7120                 || IS_SINK(levl[u.ux][u.uy].typ)) {
7121                 cmd[0] = cmd_from_func(mod == CLICK_1 ? dodrink : dodip);
7122                 return cmd;
7123             } else if (IS_THRONE(levl[u.ux][u.uy].typ)) {
7124                 cmd[0] = cmd_from_func(dosit);
7125                 return cmd;
7126             } else if ((u.ux == xupstair && u.uy == yupstair)
7127                        || (u.ux == sstairs.sx && u.uy == sstairs.sy
7128                            && sstairs.up)
7129                        || (u.ux == xupladder && u.uy == yupladder)) {
7130                 cmd[0] = cmd_from_func(doup);
7131                 return cmd;
7132             } else if ((u.ux == xdnstair && u.uy == ydnstair)
7133                        || (u.ux == sstairs.sx && u.uy == sstairs.sy
7134                            && !sstairs.up)
7135                        || (u.ux == xdnladder && u.uy == ydnladder)) {
7136                 cmd[0] = cmd_from_func(dodown);
7137                 return cmd;
7138             } else if (OBJ_AT(u.ux, u.uy)) {
7139                 cmd[0] = cmd_from_func(Is_container(level.objects[u.ux][u.uy])
7140                                        ? doloot : dopickup);
7141                 return cmd;
7142             } else {
7143                 cmd[0] = cmd_from_func(donull); /* just rest */
7144                 return cmd;
7145             }
7146         }
7147
7148         /* directional commands */
7149
7150         dir = xytod(x, y);
7151
7152         if (!m_at(u.ux + x, u.uy + y)
7153             && !test_move(u.ux, u.uy, x, y, TEST_MOVE)) {
7154             cmd[1] = Cmd.dirchars[dir];
7155             cmd[2] = '\0';
7156             if (iflags.herecmd_menu) {
7157                 cmd[0] = there_cmd_menu(FALSE, u.ux + x, u.uy + y);
7158                 if (cmd[0] == '\0')
7159                     cmd[1] = '\0';
7160                 return cmd;
7161             }
7162
7163             if (IS_DOOR(levl[u.ux + x][u.uy + y].typ)) {
7164                 /* slight assistance to the player: choose kick/open for them
7165                  */
7166                 if (levl[u.ux + x][u.uy + y].doormask & D_LOCKED) {
7167                     cmd[0] = cmd_from_func(dokick);
7168                     return cmd;
7169                 }
7170                 if (levl[u.ux + x][u.uy + y].doormask & D_CLOSED) {
7171                     cmd[0] = cmd_from_func(doopen);
7172                     return cmd;
7173                 }
7174             }
7175             if (levl[u.ux + x][u.uy + y].typ <= SCORR) {
7176                 cmd[0] = cmd_from_func(dosearch);
7177                 cmd[1] = 0;
7178                 return cmd;
7179             }
7180         }
7181     } else {
7182         /* convert without using floating point, allowing sloppy clicking */
7183         if (x > 2 * abs(y))
7184             x = 1, y = 0;
7185         else if (y > 2 * abs(x))
7186             x = 0, y = 1;
7187         else if (x < -2 * abs(y))
7188             x = -1, y = 0;
7189         else if (y < -2 * abs(x))
7190             x = 0, y = -1;
7191         else
7192             x = sgn(x), y = sgn(y);
7193
7194         if (x == 0 && y == 0) {
7195             /* map click on player to "rest" command */
7196             cmd[0] = cmd_from_func(donull);
7197             return cmd;
7198         }
7199         dir = xytod(x, y);
7200     }
7201
7202     /* move, attack, etc. */
7203     cmd[1] = 0;
7204     if (mod == CLICK_1) {
7205         cmd[0] = Cmd.dirchars[dir];
7206     } else {
7207         cmd[0] = (Cmd.num_pad
7208                      ? M(Cmd.dirchars[dir])
7209                      : (Cmd.dirchars[dir] - 'a' + 'A')); /* run command */
7210     }
7211
7212     return cmd;
7213 }
7214
7215 char
7216 get_count(allowchars, inkey, maxcount, count, historical)
7217 char *allowchars;
7218 char inkey;
7219 long maxcount;
7220 long *count;
7221 boolean historical; /* whether to include in message history: True => yes */
7222 {
7223     char qbuf[QBUFSZ];
7224     int key;
7225     long cnt = 0L;
7226     boolean backspaced = FALSE;
7227     /* this should be done in port code so that we have erase_char
7228        and kill_char available; we can at least fake erase_char */
7229 #define STANDBY_erase_char '\177'
7230
7231     for (;;) {
7232         if (inkey) {
7233             key = inkey;
7234             inkey = '\0';
7235         } else
7236             key = readchar();
7237
7238         if (digit(key)) {
7239             cnt = 10L * cnt + (long) (key - '0');
7240             if (cnt < 0)
7241                 cnt = 0;
7242             else if (maxcount > 0 && cnt > maxcount)
7243                 cnt = maxcount;
7244         } else if (cnt && (key == '\b' || key == STANDBY_erase_char)) {
7245             cnt = cnt / 10;
7246             backspaced = TRUE;
7247         } else if (key == Cmd.spkeys[NHKF_ESC]) {
7248             break;
7249         } else if (!allowchars || index(allowchars, key)) {
7250             *count = cnt;
7251             break;
7252         }
7253
7254         if (cnt > 9 || backspaced) {
7255             clear_nhwindow(WIN_MESSAGE);
7256             if (backspaced && !cnt) {
7257 /*JP
7258                 Sprintf(qbuf, "Count: ");
7259 */
7260                 Sprintf(qbuf, "\90\94: ");
7261             } else {
7262 /*JP
7263                 Sprintf(qbuf, "Count: %ld", cnt);
7264 */
7265                 Sprintf(qbuf, "\90\94: %ld", cnt);
7266                 backspaced = FALSE;
7267             }
7268             custompline(SUPPRESS_HISTORY, "%s", qbuf);
7269             mark_synch();
7270         }
7271     }
7272
7273     if (historical) {
7274 /*JP
7275         Sprintf(qbuf, "Count: %ld ", *count);
7276 */
7277         Sprintf(qbuf, "\90\94: %ld ", *count);
7278         (void) key2txt((uchar) key, eos(qbuf));
7279         putmsghistory(qbuf, FALSE);
7280     }
7281
7282     return key;
7283 }
7284
7285
7286 STATIC_OVL char *
7287 parse()
7288 {
7289 #ifdef LINT /* static char in_line[COLNO]; */
7290     char in_line[COLNO];
7291 #else
7292     static char in_line[COLNO];
7293 #endif
7294     register int foo;
7295
7296     iflags.in_parse = TRUE;
7297     multi = 0;
7298     context.move = 1;
7299     flush_screen(1); /* Flush screen buffer. Put the cursor on the hero. */
7300
7301 #ifdef ALTMETA
7302     alt_esc = iflags.altmeta; /* readchar() hack */
7303 #endif
7304     if (!Cmd.num_pad || (foo = readchar()) == Cmd.spkeys[NHKF_COUNT]) {
7305         long tmpmulti = multi;
7306
7307         foo = get_count((char *) 0, '\0', LARGEST_INT, &tmpmulti, FALSE);
7308         last_multi = multi = tmpmulti;
7309     }
7310 #ifdef ALTMETA
7311     alt_esc = FALSE; /* readchar() reset */
7312 #endif
7313
7314     if (iflags.debug_fuzzer /* if fuzzing, override '!' and ^Z */
7315         && (Cmd.commands[foo & 0x0ff]
7316             && (Cmd.commands[foo & 0x0ff]->ef_funct == dosuspend_core
7317                 || Cmd.commands[foo & 0x0ff]->ef_funct == dosh_core)))
7318         foo = Cmd.spkeys[NHKF_ESC];
7319
7320     if (foo == Cmd.spkeys[NHKF_ESC]) { /* esc cancels count (TH) */
7321         clear_nhwindow(WIN_MESSAGE);
7322         multi = last_multi = 0;
7323     } else if (foo == Cmd.spkeys[NHKF_DOAGAIN] || in_doagain) {
7324         multi = last_multi;
7325     } else {
7326         last_multi = multi;
7327         savech(0); /* reset input queue */
7328         savech((char) foo);
7329     }
7330
7331     if (multi) {
7332         multi--;
7333         save_cm = in_line;
7334     } else {
7335         save_cm = (char *) 0;
7336     }
7337     /* in 3.4.3 this was in rhack(), where it was too late to handle M-5 */
7338     if (Cmd.pcHack_compat) {
7339         /* This handles very old inconsistent DOS/Windows behaviour
7340            in a different way: earlier, the keyboard handler mapped
7341            these, which caused counts to be strange when entered
7342            from the number pad. Now do not map them until here. */
7343         switch (foo) {
7344         case '5':
7345             foo = Cmd.spkeys[NHKF_RUSH];
7346             break;
7347         case M('5'):
7348             foo = Cmd.spkeys[NHKF_RUN];
7349             break;
7350         case M('0'):
7351             foo = Cmd.spkeys[NHKF_DOINV];
7352             break;
7353         default:
7354             break; /* as is */
7355         }
7356     }
7357
7358     in_line[0] = foo;
7359     in_line[1] = '\0';
7360     if (prefix_cmd(foo)) {
7361         foo = readchar();
7362         savech((char) foo);
7363         in_line[1] = foo;
7364         in_line[2] = 0;
7365     }
7366     clear_nhwindow(WIN_MESSAGE);
7367
7368     iflags.in_parse = FALSE;
7369     return in_line;
7370 }
7371
7372 #ifdef HANGUPHANDLING
7373 /* some very old systems, or descendents of such systems, expect signal
7374    handlers to have return type `int', but they don't actually inspect
7375    the return value so we should be safe using `void' unconditionally */
7376 /*ARGUSED*/
7377 void
7378 hangup(sig_unused) /* called as signal() handler, so sent at least one arg */
7379 int sig_unused UNUSED;
7380 {
7381     if (program_state.exiting)
7382         program_state.in_moveloop = 0;
7383     nhwindows_hangup();
7384 #ifdef SAFERHANGUP
7385     /* When using SAFERHANGUP, the done_hup flag it tested in rhack
7386        and a couple of other places; actual hangup handling occurs then.
7387        This is 'safer' because it disallows certain cheats and also
7388        protects against losing objects in the process of being thrown,
7389        but also potentially riskier because the disconnected program
7390        must continue running longer before attempting a hangup save. */
7391     program_state.done_hup++;
7392     /* defer hangup iff game appears to be in progress */
7393     if (program_state.in_moveloop && program_state.something_worth_saving)
7394         return;
7395 #endif /* SAFERHANGUP */
7396     end_of_input();
7397 }
7398
7399 void
7400 end_of_input()
7401 {
7402 #ifdef NOSAVEONHANGUP
7403 #ifdef INSURANCE
7404     if (flags.ins_chkpt && program_state.something_worth_saving)
7405         program_state.preserve_locks = 1; /* keep files for recovery */
7406 #endif
7407     program_state.something_worth_saving = 0; /* don't save */
7408 #endif
7409
7410 #ifndef SAFERHANGUP
7411     if (!program_state.done_hup++)
7412 #endif
7413         if (program_state.something_worth_saving)
7414             (void) dosave0();
7415     if (iflags.window_inited)
7416         exit_nhwindows((char *) 0);
7417     clearlocks();
7418     nh_terminate(EXIT_SUCCESS);
7419     /*NOTREACHED*/ /* not necessarily true for vms... */
7420     return;
7421 }
7422 #endif /* HANGUPHANDLING */
7423
7424 char
7425 readchar()
7426 {
7427     register int sym;
7428     int x = u.ux, y = u.uy, mod = 0;
7429
7430     if (iflags.debug_fuzzer)
7431         return randomkey();
7432     if (*readchar_queue)
7433         sym = *readchar_queue++;
7434     else
7435         sym = in_doagain ? pgetchar() : nh_poskey(&x, &y, &mod);
7436
7437 #ifdef NR_OF_EOFS
7438     if (sym == EOF) {
7439         register int cnt = NR_OF_EOFS;
7440         /*
7441          * Some SYSV systems seem to return EOFs for various reasons
7442          * (?like when one hits break or for interrupted systemcalls?),
7443          * and we must see several before we quit.
7444          */
7445         do {
7446             clearerr(stdin); /* omit if clearerr is undefined */
7447             sym = pgetchar();
7448         } while (--cnt && sym == EOF);
7449     }
7450 #endif /* NR_OF_EOFS */
7451
7452     if (sym == EOF) {
7453 #ifdef HANGUPHANDLING
7454         hangup(0); /* call end_of_input() or set program_state.done_hup */
7455 #endif
7456         sym = '\033';
7457 #ifdef ALTMETA
7458     } else if (sym == '\033' && alt_esc) {
7459         /* iflags.altmeta: treat two character ``ESC c'' as single `M-c' */
7460         sym = *readchar_queue ? *readchar_queue++ : pgetchar();
7461         if (sym == EOF || sym == 0)
7462             sym = '\033';
7463         else if (sym != '\033')
7464             sym |= 0200; /* force 8th bit on */
7465 #endif /*ALTMETA*/
7466     } else if (sym == 0) {
7467         /* click event */
7468         readchar_queue = click_to_cmd(x, y, mod);
7469         sym = *readchar_queue++;
7470     }
7471     return (char) sym;
7472 }
7473
7474 /* '_' command, #travel, via keyboard rather than mouse click */
7475 STATIC_PTR int
7476 dotravel(VOID_ARGS)
7477 {
7478     static char cmd[2];
7479     coord cc;
7480
7481     /* [FIXME?  Supporting the ability to disable traveling via mouse
7482        click makes some sense, depending upon overall mouse usage.
7483        Disabling '_' on a user by user basis makes no sense at all since
7484        even if it is typed by accident, aborting when picking a target
7485        destination is trivial.  Travel via mouse predates travel via '_',
7486        and this use of OPTION=!travel is probably just a mistake....] */
7487     if (!flags.travelcmd)
7488         return 0;
7489
7490     cmd[1] = 0;
7491     cc.x = iflags.travelcc.x;
7492     cc.y = iflags.travelcc.y;
7493     if (cc.x == 0 && cc.y == 0) {
7494         /* No cached destination, start attempt from current position */
7495         cc.x = u.ux;
7496         cc.y = u.uy;
7497     }
7498     iflags.getloc_travelmode = TRUE;
7499     if (iflags.menu_requested) {
7500         int gf = iflags.getloc_filter;
7501         iflags.getloc_filter = GFILTER_VIEW;
7502         if (!getpos_menu(&cc, GLOC_INTERESTING)) {
7503             iflags.getloc_filter = gf;
7504             iflags.getloc_travelmode = FALSE;
7505             return 0;
7506         }
7507         iflags.getloc_filter = gf;
7508     } else {
7509 /*JP
7510         pline("Where do you want to travel to?");
7511 */
7512         pline("\82Ç\82±\82É\88Ú\93®\82·\82é\81H");
7513 /*JP
7514         if (getpos(&cc, TRUE, "the desired destination") < 0) {
7515 */
7516         if (getpos(&cc, TRUE, "\88Ú\93®\90æ") < 0) {
7517             /* user pressed ESC */
7518             iflags.getloc_travelmode = FALSE;
7519             return 0;
7520         }
7521     }
7522     iflags.getloc_travelmode = FALSE;
7523     iflags.travelcc.x = u.tx = cc.x;
7524     iflags.travelcc.y = u.ty = cc.y;
7525     cmd[0] = Cmd.spkeys[NHKF_TRAVEL];
7526     readchar_queue = cmd;
7527     return 0;
7528 }
7529
7530 /*
7531  *   Parameter validator for generic yes/no function to prevent
7532  *   the core from sending too long a prompt string to the
7533  *   window port causing a buffer overflow there.
7534  */
7535 char
7536 yn_function(query, resp, def)
7537 const char *query, *resp;
7538 char def;
7539 {
7540     char res, qbuf[QBUFSZ];
7541 #ifdef DUMPLOG
7542     extern unsigned saved_pline_index; /* pline.c */
7543     unsigned idx = saved_pline_index;
7544     /* buffer to hold query+space+formatted_single_char_response */
7545     char dumplog_buf[QBUFSZ + 1 + 15]; /* [QBUFSZ+1+7] should suffice */
7546 #endif
7547
7548     iflags.last_msg = PLNMSG_UNKNOWN; /* most recent pline is clobbered */
7549
7550     /* maximum acceptable length is QBUFSZ-1 */
7551     if (strlen(query) >= QBUFSZ) {
7552         /* caller shouldn't have passed anything this long */
7553         paniclog("Query truncated: ", query);
7554         (void) strncpy(qbuf, query, QBUFSZ - 1 - 3);
7555         Strcpy(&qbuf[QBUFSZ - 1 - 3], "...");
7556         query = qbuf;
7557     }
7558     res = (*windowprocs.win_yn_function)(query, resp, def);
7559 #ifdef DUMPLOG
7560     if (idx == saved_pline_index) {
7561         /* when idx is still the same as saved_pline_index, the interface
7562            didn't put the prompt into saved_plines[]; we put a simplified
7563            version in there now (without response choices or default) */
7564         Sprintf(dumplog_buf, "%s ", query);
7565         (void) key2txt((uchar) res, eos(dumplog_buf));
7566         dumplogmsg(dumplog_buf);
7567     }
7568 #endif
7569     return res;
7570 }
7571
7572 /* for paranoid_confirm:quit,die,attack prompting */
7573 boolean
7574 paranoid_query(be_paranoid, prompt)
7575 boolean be_paranoid;
7576 const char *prompt;
7577 {
7578     boolean confirmed_ok;
7579
7580     /* when paranoid, player must respond with "yes" rather than just 'y'
7581        to give the go-ahead for this query; default is "no" unless the
7582        ParanoidConfirm flag is set in which case there's no default */
7583     if (be_paranoid) {
7584         char pbuf[BUFSZ], qbuf[QBUFSZ], ans[BUFSZ];
7585         const char *promptprefix = "",
7586                 *responsetype = ParanoidConfirm ? "(yes|no)" : "(yes) [no]";
7587         int k, trylimit = 6; /* 1 normal, 5 more with "Yes or No:" prefix */
7588
7589         copynchars(pbuf, prompt, BUFSZ - 1);
7590         /* in addition to being paranoid about this particular
7591            query, we might be even more paranoid about all paranoia
7592            responses (ie, ParanoidConfirm is set) in which case we
7593            require "no" to reject in addition to "yes" to confirm
7594            (except we won't loop if response is ESC; it means no) */
7595         do {
7596             /* make sure we won't overflow a QBUFSZ sized buffer */
7597             k = (int) (strlen(promptprefix) + 1 + strlen(responsetype));
7598             if ((int) strlen(pbuf) + k > QBUFSZ - 1) {
7599                 /* chop off some at the end */
7600                 Strcpy(pbuf + (QBUFSZ - 1) - k - 4, "...?"); /* -4: "...?" */
7601             }
7602
7603             Sprintf(qbuf, "%s%s %s", promptprefix, pbuf, responsetype);
7604             *ans = '\0';
7605             getlin(qbuf, ans);
7606             (void) mungspaces(ans);
7607             confirmed_ok = !strcmpi(ans, "yes");
7608             if (confirmed_ok || *ans == '\033')
7609                 break;
7610             promptprefix = "\"Yes\" or \"No\": ";
7611         } while (ParanoidConfirm && strcmpi(ans, "no") && --trylimit);
7612     } else
7613         confirmed_ok = (yn(prompt) == 'y');
7614
7615     return confirmed_ok;
7616 }
7617
7618 /* ^Z command, #suspend */
7619 STATIC_PTR int
7620 dosuspend_core(VOID_ARGS)
7621 {
7622 #ifdef SUSPEND
7623     /* Does current window system support suspend? */
7624     if ((*windowprocs.win_can_suspend)()) {
7625         /* NB: SYSCF SHELLERS handled in port code. */
7626         dosuspend();
7627     } else
7628 #endif
7629         Norep(cmdnotavail, "#suspend");
7630     return 0;
7631 }
7632
7633 /* '!' command, #shell */
7634 STATIC_PTR int
7635 dosh_core(VOID_ARGS)
7636 {
7637 #ifdef SHELL
7638     /* access restrictions, if any, are handled in port code */
7639     dosh();
7640 #else
7641     Norep(cmdnotavail, "#shell");
7642 #endif
7643     return 0;
7644 }
7645
7646 /*cmd.c*/