OSDN Git Service

update year to 2023
[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-2023            */
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         Strcat(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 (!STRNCMP2(buf, "\82É\82æ\82Á\82Ä"))
3554             /*JP:\81u\81c\82ª\82È\82¯\82ê\82Î\81v\82É\8f\91\82«\8a·\82¦\82é*/
3555             strcpy(eos(buf) - strlen("\82É\82æ\82Á\82Ä"), "\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 #if 0 /*JP:T*/
4637     { '#', "#", "perform an extended command",
4638 #else
4639     { '#', "#", "\8ag\92£\83R\83}\83\93\83h\82ð\8eÀ\8ds\82·\82é",
4640 #endif
4641             doextcmd, IFBURIED | GENERALCMD },
4642 #if 0 /*JP:T*/
4643     { M('?'), "?", "list all extended commands",
4644 #else
4645     { M('?'), "?", "\8ag\92£\83R\83}\83\93\83h\88ê\97\97\82ð\95\\8e¦\82·\82é",
4646 #endif
4647             doextlist, IFBURIED | AUTOCOMPLETE | GENERALCMD },
4648 #if 0 /*JP:T*/
4649     { M('a'), "adjust", "adjust inventory letters",
4650 #else
4651     { M('a'), "adjust", "\8e\9d\82¿\95¨\88ê\97\97\82Ì\92²\90®",
4652 #endif
4653             doorganize, IFBURIED | AUTOCOMPLETE },
4654 #if 0 /*JP:T*/
4655     { M('A'), "annotate", "name current level",
4656 #else
4657     { M('A'), "annotate", "\8c»\8dÝ\82Ì\8aK\82É\96¼\91O\82ð\82Â\82¯\82é",
4658 #endif
4659             donamelevel, IFBURIED | AUTOCOMPLETE },
4660 #if 0 /*JP:T*/
4661     { 'a', "apply", "apply (use) a tool (pick-axe, key, lamp...)",
4662 #else
4663     { 'a', "apply", "\93¹\8bï\82ð\8eg\82¤\81D(\82Â\82é\82Í\82µ, \8c®, \83\89\83\93\83v\81c)",
4664 #endif
4665             doapply },
4666 #if 0 /*JP:T*/
4667     { C('x'), "attributes", "show your attributes",
4668 #else
4669     { C('x'), "attributes", "\91®\90«\82ð\95\\8e¦\82·\82é",
4670 #endif
4671             doattributes, IFBURIED },
4672 #if 0 /*JP:T*/
4673     { '@', "autopickup", "toggle the pickup option on/off",
4674 #else
4675     { '@', "autopickup", "\8e©\93®\8fE\82¢\83I\83v\83V\83\87\83\93\82ð\90Ø\82è\91Ö\82¦\82é",
4676 #endif
4677             dotogglepickup, IFBURIED },
4678 #if 0 /*JP:T*/
4679     { 'C', "call", "call (name) something", docallcmd, IFBURIED },
4680 #else
4681     { 'C', "call", "\96¼\91O\82ð\82Â\82¯\82é", docallcmd, IFBURIED },
4682 #endif
4683 #if 0 /*JP:T*/
4684     { 'Z', "cast", "zap (cast) a spell", docast, IFBURIED },
4685 #else
4686     { 'Z', "cast", "\8eô\95\82ð\8f¥\82¦\82é", docast, IFBURIED },
4687 #endif
4688 #if 0 /*JP:T*/
4689     { M('c'), "chat", "talk to someone", dotalk, IFBURIED | AUTOCOMPLETE },
4690 #else
4691     { M('c'), "chat", "\92N\82©\82Æ\98b\82·", dotalk, IFBURIED | AUTOCOMPLETE },
4692 #endif
4693 #if 0 /*JP:T*/
4694     { 'c', "close", "close a door", doclose },
4695 #else
4696     { 'c', "close", "\83h\83A\82ð\95Â\82ß\82é", doclose },
4697 #endif
4698 #if 0 /*JP:T*/
4699     { M('C'), "conduct", "list voluntary challenges you have maintained",
4700 #else
4701     { M('C'), "conduct", "\82Ç\82¤\82¢\82¤\8ds\93®\82ð\82Æ\82Á\82½\82©\8c©\82é",
4702 #endif
4703             doconduct, IFBURIED | AUTOCOMPLETE },
4704 #if 0 /*JP:T*/
4705     { M('d'), "dip", "dip an object into something", dodip, AUTOCOMPLETE },
4706 #else
4707     { M('d'), "dip", "\89½\82©\82É\95¨\82ð\90Z\82·", dodip, AUTOCOMPLETE },
4708 #endif
4709 #if 0 /*JP:T*/
4710     { '>', "down", "go down a staircase", dodown },
4711 #else
4712     { '>', "down", "\8aK\92i\82ð\8d~\82è\82ée", dodown },
4713 #endif
4714 #if 0 /*JP:T*/
4715     { 'd', "drop", "drop an item", dodrop },
4716 #else
4717     { 'd', "drop", "\95¨\82ð\92u\82­", dodrop },
4718 #endif
4719 #if 0 /*JP:T*/
4720     { 'D', "droptype", "drop specific item types", doddrop },
4721 #else
4722     { 'D', "droptype", "\8ew\92è\82µ\82½\8eí\97Þ\82Ì\95¨\82ð\92u\82­", doddrop },
4723 #endif
4724 #if 0 /*JP:T*/
4725     { 'e', "eat", "eat something", doeat },
4726 #else
4727     { 'e', "eat", "\89½\82©\82ð\90H\82×\82é", doeat },
4728 #endif
4729 #if 0 /*JP:T*/
4730     { 'E', "engrave", "engrave writing on the floor", doengrave },
4731 #else
4732     { 'E', "engrave", "\8f°\82É\95\8e\9a\82ð\8f\91\82­", doengrave },
4733 #endif
4734 #if 0 /*JP:T*/
4735     { M('e'), "enhance", "advance or check weapon and spell skills",
4736 #else
4737     { M('e'), "enhance", "\95\90\8aí\8fn\97û\93x\82ð\8d\82\82ß\82é",
4738 #endif
4739             enhance_weapon_skill, IFBURIED | AUTOCOMPLETE },
4740 #if 0 /*JP:T*/
4741     { '\0', "exploremode", "enter explore (discovery) mode",
4742 #else
4743     { '\0', "exploremode", "\92T\8c\9f(\94­\8c©)\83\82\81[\83h\82É\93ü\82é",
4744 #endif
4745             enter_explore_mode, IFBURIED },
4746 #if 0 /*JP:T*/
4747     { 'f', "fire", "fire ammunition from quiver", dofire },
4748 #else
4749     { 'f', "fire", "\91\95\93U\82³\82ê\82½\95¨\82ð\8eË\82é", dofire },
4750 #endif
4751 #if 0 /*JP:T*/
4752     { M('f'), "force", "force a lock", doforce, AUTOCOMPLETE },
4753 #else
4754     { M('f'), "force", "\8c®\82ð\82±\82\82 \82¯\82é", doforce, AUTOCOMPLETE },
4755 #endif
4756 #if 0 /*JP:T*/
4757     { ';', "glance", "show what type of thing a map symbol corresponds to",
4758 #else
4759     { ';', "glance", "\92n\90}\8fã\82Ì\83V\83\93\83{\83\8b\82ª\89½\82É\91Î\89\9e\82·\82é\82©\82ð\8c©\82é",
4760 #endif
4761             doquickwhatis, IFBURIED | GENERALCMD },
4762 #if 0 /*JP:T*/
4763     { '?', "help", "give a help message", dohelp, IFBURIED | GENERALCMD },
4764 #else
4765     { '?', "help", "\83w\83\8b\83v\83\81\83b\83Z\81[\83W\82ð\95\\8e¦\82·\82é", dohelp, IFBURIED | GENERALCMD },
4766 #endif
4767 #if 0 /*JP:T*/
4768     { '\0', "herecmdmenu", "show menu of commands you can do here",
4769 #else
4770     { '\0', "herecmdmenu", "\82±\82±\82Å\8fo\97\88\82é\83R\83}\83\93\83h\82Ì\83\81\83j\83\85\81[\82ð\95\\8e¦\82·\82é",
4771 #endif
4772             doherecmdmenu, IFBURIED },
4773 #if 0 /*JP:T*/
4774     { 'V', "history", "show long version and game history",
4775 #else
4776     { 'V', "history", "\92·\82¢\83o\81[\83W\83\87\83\93\82Æ\83Q\81[\83\80\82Ì\97ð\8ej\82ð\95\\8e¦\82·\82é",
4777 #endif
4778             dohistory, IFBURIED | GENERALCMD },
4779 #if 0 /*JP:T*/
4780     { 'i', "inventory", "show your inventory", ddoinv, IFBURIED },
4781 #else
4782     { 'i', "inventory", "\8e\9d\95¨\82ð\95\\8e¦\82·\82é", ddoinv, IFBURIED },
4783 #endif
4784 #if 0 /*JP:T*/
4785     { 'I', "inventtype", "inventory specific item types",
4786 #else
4787     { 'I', "inventtype", "\8ew\92è\82µ\82½\8eí\97Þ\82Ì\8e\9d\95¨\82ð\8c©\82é",
4788 #endif
4789             dotypeinv, IFBURIED },
4790 #if 0 /*JP:T*/
4791     { M('i'), "invoke", "invoke an object's special powers",
4792 #else
4793     { M('i'), "invoke", "\95¨\82Ì\93Á\95Ê\82È\97Í\82ð\8eg\82¤",
4794 #endif
4795             doinvoke, IFBURIED | AUTOCOMPLETE },
4796 #if 0 /*JP:T*/
4797     { M('j'), "jump", "jump to another location", dojump, AUTOCOMPLETE },
4798 #else
4799     { M('j'), "jump", "\91¼\82Ì\88Ê\92u\82É\94ò\82Ñ\82¤\82Â\82é", dojump, AUTOCOMPLETE },
4800 #endif
4801 #if 0 /*JP:T*/
4802     { C('d'), "kick", "kick something", dokick },
4803 #else
4804     { C('d'), "kick", "\89½\82©\82ð\8fR\82é", dokick },
4805 #endif
4806 #if 0 /*JP:T*/
4807     { '\\', "known", "show what object types have been discovered",
4808 #else
4809     { '\\', "known", "\94­\8c©\82µ\82½\95¨\82Ì\8eí\97Þ\82ð\95\\8e¦\82·\82é",
4810 #endif
4811             dodiscovered, IFBURIED | GENERALCMD },
4812 #if 0 /*JP:T*/
4813     { '`', "knownclass", "show discovered types for one class of objects",
4814 #else
4815     { '`', "knownclass", "\88ê\82Â\82Ì\8eí\97Þ\82Ì\92\86\82Å\94­\8c©\82µ\82½\95¨\82ð\95\\8e¦\82·\82é",
4816 #endif
4817             doclassdisco, IFBURIED | GENERALCMD },
4818 #if 0 /*JP:T*/
4819     { '\0', "levelchange", "change experience level",
4820 #else
4821     { '\0', "levelchange", "\8co\8c±\83\8c\83x\83\8b\82ð\95Ï\82¦\82é",
4822 #endif
4823             wiz_level_change, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4824 #if 0 /*JP:T*/
4825     { '\0', "lightsources", "show mobile light sources",
4826 #else
4827     { '\0', "lightsources", "\88Ú\93®\8cõ\8c¹\82ð\8c©\82é",
4828 #endif
4829             wiz_light_sources, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4830 #if 0 /*JP:T*/
4831     { ':', "look", "look at what is here", dolook, IFBURIED },
4832 #else
4833     { ':', "look", "\82±\82±\82É\89½\82ª\82 \82é\82Ì\82©\8c©\82é", dolook, IFBURIED },
4834 #endif
4835 #if 0 /*JP:T*/
4836     { M('l'), "loot", "loot a box on the floor", doloot, AUTOCOMPLETE },
4837 #else
4838     { M('l'), "loot", "\8f°\82Ì\8fã\82Ì\94 \82ð\8aJ\82¯\82é", doloot, AUTOCOMPLETE },
4839 #endif
4840 #ifdef DEBUG_MIGRATING_MONS
4841 #if 0 /*JP:T*/
4842     { '\0', "migratemons", "migrate N random monsters",
4843 #else
4844     { '\0', "migratemons", "\83\89\83\93\83_\83\80\82È\89ö\95¨\82ð\89½\91Ì\82©\88Ú\8fZ\82³\82¹\82é",
4845 #endif
4846             wiz_migrate_mons, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4847 #endif
4848 #if 0 /*JP:T*/
4849     { M('m'), "monster", "use monster's special ability",
4850 #else
4851     { M('m'), "monster", "\89ö\95¨\82Ì\93Á\95Ê\94\\97Í\82ð\8eg\82¤",
4852 #endif
4853             domonability, IFBURIED | AUTOCOMPLETE },
4854 #if 0 /*JP:T*/
4855     { 'N', "name", "name a monster or an object",
4856 #else
4857     { 'N', "name", "\83A\83C\83e\83\80\82â\95¨\82É\96¼\91O\82ð\82Â\82¯\82é",
4858 #endif
4859             docallcmd, IFBURIED | AUTOCOMPLETE },
4860 #if 0 /*JP:T*/
4861     { M('o'), "offer", "offer a sacrifice to the gods",
4862 #else
4863     { M('o'), "offer", "\90_\82É\8b\9f\95¨\82ð\95ù\82°\82é",
4864 #endif
4865             dosacrifice, AUTOCOMPLETE },
4866 #if 0 /*JP:T*/
4867     { 'o', "open", "open a door", doopen },
4868 #else
4869     { 'o', "open", "\94à\82ð\8aJ\82¯\82é", doopen },
4870 #endif
4871 #if 0 /*JP:T*/
4872     { 'O', "options", "show option settings, possibly change them",
4873 #else
4874     { 'O', "options", "\8c»\8dÝ\82Ì\83I\83v\83V\83\87\83\93\90Ý\92è\82ð\95\\8e¦\82µ\89Â\94\\82È\82ç\95Ï\8dX\82·\82é",
4875 #endif
4876             doset, IFBURIED | GENERALCMD },
4877 #if 0 /*JP:T*/
4878     { C('o'), "overview", "show a summary of the explored dungeon",
4879 #else
4880     { C('o'), "overview", "\92T\8dõ\82µ\82½\96À\8b{\82Ì\8aT\97v\82ð\95\\8e¦\82·\82é",
4881 #endif
4882             dooverview, IFBURIED | AUTOCOMPLETE },
4883 #if 0 /*JP:T*/
4884     { '\0', "panic", "test panic routine (fatal to game)",
4885 #else
4886     { '\0', "panic", "\83p\83j\83b\83N\83\8b\81[\83`\83\93\82ð\83e\83X\83g\82·\82é(\92v\96½\93I)",
4887 #endif
4888             wiz_panic, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4889 #if 0 /*JP:T*/
4890     { 'p', "pay", "pay your shopping bill", dopay },
4891 #else
4892     { 'p', "pay", "\94\83\82¢\95¨\82Ì\8a¨\92è\82ð\95¥\82¤", dopay },
4893 #endif
4894 #if 0 /*JP:T*/
4895     { ',', "pickup", "pick up things at the current location", dopickup },
4896 #else
4897     { ',', "pickup", "\8c»\8dÝ\82Ì\88Ê\92u\82É\82 \82é\95¨\82ð\8fE\82¤", dopickup },
4898 #endif
4899 #if 0 /*JP:T*/
4900     { '\0', "polyself", "polymorph self",
4901 #else
4902     { '\0', "polyself", "\95Ï\89»\82·\82é",
4903 #endif
4904             wiz_polyself, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4905 #if 0 /*JP:T*/
4906     { M('p'), "pray", "pray to the gods for help",
4907 #else
4908     { M('p'), "pray", "\90_\82É\8bF\82é",
4909 #endif
4910             dopray, IFBURIED | AUTOCOMPLETE },
4911 #if 0 /*JP:T*/
4912     { C('p'), "prevmsg", "view recent game messages",
4913 #else
4914     { C('p'), "prevmsg", "\8dÅ\8bß\82Ì\83\81\83b\83Z\81[\83W\82ð\8c©\82é",
4915 #endif
4916             doprev_message, IFBURIED | GENERALCMD },
4917 #if 0 /*JP:T*/
4918     { 'P', "puton", "put on an accessory (ring, amulet, etc)", doputon },
4919 #else
4920     { 'P', "puton", "\83A\83N\83Z\83T\83\8a\82ð\82Â\82¯\82é (\8ew\97Ö\81C\96\82\8f\9c\82¯\82È\82Ç)", doputon },
4921 #endif
4922 #if 0 /*JP:T*/
4923     { 'q', "quaff", "quaff (drink) something", dodrink },
4924 #else
4925     { 'q', "quaff", "\89½\82©\82ð\88ù\82Þ", dodrink },
4926 #endif
4927 #if 0 /*JP:T*/
4928     { M('q'), "quit", "exit without saving current game",
4929 #else
4930     { M('q'), "quit", "\83Z\81[\83u\82µ\82È\82¢\82Å\8fI\97¹",
4931 #endif
4932             done2, IFBURIED | AUTOCOMPLETE | GENERALCMD },
4933 #if 0 /*JP:T*/
4934     { 'Q', "quiver", "select ammunition for quiver", dowieldquiver },
4935 #else
4936     { 'Q', "quiver", "\91\95\93U\82·\82é\95¨\82ð\91I\91ð\82·\82é", dowieldquiver },
4937 #endif
4938 #if 0 /*JP:T*/
4939     { 'r', "read", "read a scroll or spellbook", doread },
4940 #else
4941     { 'r', "read", "\8aª\95¨\82â\96\82\96@\8f\91\82ð\93Ç\82Þ", doread },
4942 #endif
4943 #if 0 /*JP:T*/
4944     { C('r'), "redraw", "redraw screen", doredraw, IFBURIED | GENERALCMD },
4945 #else
4946     { C('r'), "redraw", "\89æ\96Ê\82ð\8dÄ\95\\8e¦\82·\82é", doredraw, IFBURIED | GENERALCMD },
4947 #endif
4948 #if 0 /*JP:T*/
4949     { 'R', "remove", "remove an accessory (ring, amulet, etc)", doremring },
4950 #else
4951     { 'R', "remove", "\83A\83N\83Z\83T\83\8a\82ð\82Í\82¸\82· (\8ew\97Ö\81C\96\82\8f\9c\82¯\82È\82Ç)", doremring },
4952 #endif
4953 #if 0 /*JP:T*/
4954     { M('R'), "ride", "mount or dismount a saddled steed",
4955 #else
4956     { M('R'), "ride", "\89ö\95¨\82É\8fæ\82é(\82Ü\82½\82Í\8d~\82è\82é)",
4957 #endif
4958             doride, AUTOCOMPLETE },
4959 #if 0 /*JP:T*/
4960     { M('r'), "rub", "rub a lamp or a stone", dorub, AUTOCOMPLETE },
4961 #else
4962     { M('r'), "rub", "\83\89\83\93\83v\82ð\82±\82·\82é", dorub, AUTOCOMPLETE },
4963 #endif
4964 #if 0 /*JP:T*/
4965     { 'S', "save", "save the game and exit", dosave, IFBURIED | GENERALCMD },
4966 #else
4967     { 'S', "save", "\83Q\81[\83\80\82ð\95Û\91\82µ\82Ä\8fI\97¹\82·\82é", dosave, IFBURIED | GENERALCMD },
4968 #endif
4969 #if 0 /*JP:T*/
4970     { 's', "search", "search for traps and secret doors",
4971             dosearch, IFBURIED, "searching" },
4972 #else
4973     { 's', "search", "ã©\82â\89B\82µ\94à\82ð\92T\82·",
4974             dosearch, IFBURIED, "\92T\82·" },
4975 #endif
4976 #if 0 /*JP:T*/
4977     { '*', "seeall", "show all equipment in use", doprinuse, IFBURIED },
4978 #else
4979     { '*', "seeall", "\8eg\97p\82µ\82Ä\82¢\82é\91S\82Ä\82Ì\91\95\94õ\97Þ\82ð\95\\8e¦\82·\82é", doprinuse, IFBURIED },
4980 #endif
4981 #if 0 /*JP:T*/
4982     { AMULET_SYM, "seeamulet", "show the amulet currently worn",
4983 #else
4984     { AMULET_SYM, "seeamulet", "\90g\82É\82Â\82¯\82Ä\82¢\82é\96\82\8f\9c\82¯\82ð\95\\8e¦\82·\82é",
4985 #endif
4986             dopramulet, IFBURIED },
4987 #if 0 /*JP:T*/
4988     { ARMOR_SYM, "seearmor", "show the armor currently worn",
4989 #else
4990     { ARMOR_SYM, "seearmor", "\8eg\82Á\82Ä\82¢\82é\96h\8bï\82ð\95\\8e¦\82·\82é",
4991 #endif
4992             doprarm, IFBURIED },
4993 #if 0 /*JP:T*/
4994     { GOLD_SYM, "seegold", "count your gold", doprgold, IFBURIED },
4995 #else
4996     { GOLD_SYM, "seegold", "\8e\9d\82Á\82Ä\82¢\82é\8bà\89Ý\82Ì\90\94\82ð\90\94\82¦\82é", doprgold, IFBURIED },
4997 #endif
4998 #if 0 /*JP:T*/
4999     { '\0', "seenv", "show seen vectors",
5000 #else
5001     { '\0', "seenv", "\8e\8b\90ü\83x\83N\83g\83\8b\82ð\8c©\82é",
5002 #endif
5003             wiz_show_seenv, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
5004 #if 0 /*JP:T*/
5005     { RING_SYM, "seerings", "show the ring(s) currently worn",
5006 #else
5007     { RING_SYM, "seerings", "\82Í\82ß\82Ä\82¢\82é\8ew\97Ö\82ð\95\\8e¦\82·\82é",
5008 #endif
5009             doprring, IFBURIED },
5010 #if 0 /*JP:T*/
5011     { SPBOOK_SYM, "seespells", "list and reorder known spells",
5012 #else
5013     { SPBOOK_SYM, "seespells", "\92m\82Á\82Ä\82¢\82é\8eô\95\82ð\95\\8e¦\82µ\82Ä\95À\82×\91Ö\82¦\82é",
5014 #endif
5015             dovspell, IFBURIED },
5016 #if 0 /*JP:T*/
5017     { TOOL_SYM, "seetools", "show the tools currently in use",
5018 #else
5019     { TOOL_SYM, "seetools", "\8eg\82Á\82Ä\82¢\82é\93¹\8bï\82ð\95\\8e¦\82·\82é",
5020 #endif
5021             doprtool, IFBURIED },
5022 #if 0 /*JP:T*/
5023     { '^', "seetrap", "show the type of adjacent trap", doidtrap, IFBURIED },
5024 #else
5025     { '^', "seetrap", "\97×\82É\82 \82éã©\82Ì\8eí\97Þ\82ð\95\\8e¦\82·\82é", doidtrap, IFBURIED },
5026 #endif
5027 #if 0 /*JP:T*/
5028     { WEAPON_SYM, "seeweapon", "show the weapon currently wielded",
5029 #else
5030     { WEAPON_SYM, "seeweapon", "\8eg\82Á\82Ä\82¢\82é\95\90\8aí\82ð\95\\8e¦\82·\82é",
5031 #endif
5032             doprwep, IFBURIED },
5033 #if 0 /*JP:T*/
5034     { '!', "shell", "do a shell escape",
5035 #else
5036     { '!', "shell", "\83V\83F\83\8b\82É\94²\82¯\82é",
5037 #endif
5038             dosh_core, IFBURIED | GENERALCMD
5039 #ifndef SHELL
5040                        | CMD_NOT_AVAILABLE
5041 #endif /* SHELL */
5042     },
5043 #if 0 /*JP:T*/
5044     { M('s'), "sit", "sit down", dosit, AUTOCOMPLETE },
5045 #else
5046     { M('s'), "sit", "\8dÀ\82é", dosit, AUTOCOMPLETE },
5047 #endif
5048 #if 0 /*JP:T*/
5049     { '\0', "stats", "show memory statistics",
5050 #else
5051     { '\0', "stats", "\83\81\83\82\83\8a\8fó\91Ô\82ð\8c©\82é",
5052 #endif
5053             wiz_show_stats, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
5054 #if 0 /*JP:T*/
5055     { C('z'), "suspend", "suspend the game",
5056 #else
5057     { C('z'), "suspend", "\83Q\81[\83\80\82ð\92\86\92f\82·\82é",
5058 #endif
5059             dosuspend_core, IFBURIED | GENERALCMD
5060 #ifndef SUSPEND
5061                             | CMD_NOT_AVAILABLE
5062 #endif /* SUSPEND */
5063     },
5064 #if 0 /*JP:T*/
5065     { 'x', "swap", "swap wielded and secondary weapons", doswapweapon },
5066 #else
5067     { 'x', "swap", "\8d\89E\82Ì\95\90\8aí\82ð\8cð\8a·\82·\82é", doswapweapon },
5068 #endif
5069 #if 0 /*JP:T*/
5070     { 'T', "takeoff", "take off one piece of armor", dotakeoff },
5071 #else
5072     { 'T', "takeoff", "\96h\8bï\82ð\88ê\82Â\8aO\82·", dotakeoff },
5073 #endif
5074 #if 0 /*JP:T*/
5075     { 'A', "takeoffall", "remove all armor", doddoremarm },
5076 #else
5077     { 'A', "takeoffall", "\91S\82Ä\82Ì\96h\8bï\82ð\8aO\82·", doddoremarm },
5078 #endif
5079 #if 0 /*JP:T*/
5080     { C('t'), "teleport", "teleport around the level", dotelecmd, IFBURIED },
5081 #else
5082     { C('t'), "teleport", "\93¯\82\8aK\82Ì\92\86\82Å\8fu\8aÔ\88Ú\93®\82·\82é", dotelecmd, IFBURIED },
5083 #endif
5084 #if 0 /*JP:T*/
5085     { '\0', "terrain", "show map without obstructions",
5086 #else
5087     { '\0', "terrain", "\8e×\96\82\82³\82ê\82¸\82É\92n\90}\82ð\8c©\82é",
5088 #endif
5089             doterrain, IFBURIED | AUTOCOMPLETE },
5090 #if 0 /*JP:T*/
5091     { '\0', "therecmdmenu",
5092             "menu of commands you can do from here to adjacent spot",
5093 #else
5094     { '\0', "therecmdmenu",
5095             "\82±\82±\82©\82ç\97×\82Ì\83}\83X\82É\91Î\82µ\82Ä\8fo\97\88\82é\83R\83}\83\93\83h\82Ì\83\81\83j\83\85\81[",
5096 #endif
5097             dotherecmdmenu },
5098 #if 0 /*JP:T*/
5099     { 't', "throw", "throw something", dothrow },
5100 #else
5101     { 't', "throw", "\89½\82©\82ð\93\8a\82°\82é", dothrow },
5102 #endif
5103 #if 0 /*JP:T*/
5104     { '\0', "timeout", "look at timeout queue and hero's timed intrinsics",
5105 #else
5106     { '\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é",
5107 #endif
5108             wiz_timeout_queue, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
5109 #if 0 /*JP:T*/
5110     { M('T'), "tip", "empty a container", dotip, AUTOCOMPLETE },
5111 #else
5112     { M('T'), "tip", "\93ü\82ê\95¨\82ð\8bó\82É\82·\82é", dotip, AUTOCOMPLETE },
5113 #endif
5114 #if 0 /*JP:T*/
5115     { '_', "travel", "travel to a specific location on the map", dotravel },
5116 #else
5117     { '_', "travel", "\92n\90}\82Å\8ew\92è\82³\82ê\82½\88Ê\92u\82Ü\82Å\88Ú\93®\82·\82é", dotravel },
5118 #endif
5119 #if 0 /*JP:T*/
5120     { M('t'), "turn", "turn undead away", doturn, IFBURIED | AUTOCOMPLETE },
5121 #else
5122     { M('t'), "turn", "\83A\83\93\83f\83b\83g\82ð\93y\82É\95Ô\82·", doturn, IFBURIED | AUTOCOMPLETE },
5123 #endif
5124 #if 0 /*JP:T*/
5125     { 'X', "twoweapon", "toggle two-weapon combat",
5126 #else
5127     { 'X', "twoweapon", "\97¼\8eè\8e\9d\82¿\82Ì\90Ø\82è\91Ö\82¦",
5128 #endif
5129             dotwoweapon, AUTOCOMPLETE },
5130 #if 0 /*JP:T*/
5131     { M('u'), "untrap", "untrap something", dountrap, AUTOCOMPLETE },
5132 #else
5133     { M('u'), "untrap", "ã©\82ð\82Í\82¸\82·", dountrap, AUTOCOMPLETE },
5134 #endif
5135 #if 0 /*JP:T*/
5136     { '<', "up", "go up a staircase", doup },
5137 #else
5138     { '<', "up", "\8aK\92i\82ð\8fã\82é", doup },
5139 #endif
5140 #if 0 /*JP:T*/
5141     { '\0', "vanquished", "list vanquished monsters",
5142 #else
5143     { '\0', "vanquished", "\93|\82µ\82½\89ö\95¨\82Ì\88ê\97\97\82ð\8c©\82é",
5144 #endif
5145             dovanquished, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
5146     { M('v'), "version",
5147 #if 0 /*JP:T*/
5148             "list compile time options for this version of NetHack",
5149 #else
5150             "\83R\83\93\83p\83C\83\8b\8e\9e\82Ì\83I\83v\83V\83\87\83\93\82ð\95\\8e¦\82·\82é",
5151 #endif
5152             doextversion, IFBURIED | AUTOCOMPLETE | GENERALCMD },
5153 #if 0 /*JP:T*/
5154     { 'v', "versionshort", "show version", doversion, IFBURIED | GENERALCMD },
5155 #else
5156     { 'v', "versionshort", "\83o\81[\83W\83\87\83\93\82ð\95\\8e¦\82·\82é", doversion, IFBURIED | GENERALCMD },
5157 #endif
5158 #if 0 /*JP:T*/
5159     { '\0', "vision", "show vision array",
5160 #else
5161     { '\0', "vision", "\8e\8b\8aE\94z\97ñ\82ð\8c©\82é",
5162 #endif
5163             wiz_show_vision, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
5164 #if 0 /*JP:T*/
5165     { '.', "wait", "rest one move while doing nothing",
5166             donull, IFBURIED, "waiting" },
5167 #else
5168     { '.', "wait", "\88ê\95à\95ª\89½\82à\82µ\82È\82¢",
5169             donull, IFBURIED, "\8bx\8ce\82·\82é" },
5170 #endif
5171 #if 0 /*JP:T*/
5172     { 'W', "wear", "wear a piece of armor", dowear },
5173 #else
5174     { 'W', "wear", "\96h\8bï\82ð\88ê\82Â\82Â\82¯\82é", dowear },
5175 #endif
5176 #if 0 /*JP:T*/
5177     { '&', "whatdoes", "tell what a command does", dowhatdoes, IFBURIED },
5178 #else
5179     { '&', "whatdoes", "\83R\83}\83\93\83h\82Ì\88Ó\96¡\82ð\95\\8e¦\82·\82é", dowhatdoes, IFBURIED },
5180 #endif
5181 #if 0 /*JP:T*/
5182     { '/', "whatis", "show what type of thing a symbol corresponds to",
5183 #else
5184     { '/', "whatis", "\83V\83\93\83{\83\8b\82ª\89½\82ð\95\\82µ\82Ä\82¢\82é\82©\82ð\95\\8e¦\82·\82é",
5185 #endif
5186             dowhatis, IFBURIED | GENERALCMD },
5187 #if 0 /*JP:T*/
5188     { 'w', "wield", "wield (put in use) a weapon", dowield },
5189 #else
5190     { 'w', "wield", "\95\90\8aí\82ð\90g\82É\82Â\82¯\82é", dowield },
5191 #endif
5192 #if 0 /*JP:T*/
5193     { M('w'), "wipe", "wipe off your face", dowipe, AUTOCOMPLETE },
5194 #else
5195     { M('w'), "wipe", "\8aç\82ð\90@\82¤", dowipe, AUTOCOMPLETE },
5196 #endif
5197 #ifdef DEBUG
5198 #if 0 /*JP:T*/
5199     { '\0', "wizbury", "bury objs under and around you",
5200 #else
5201     { '\0', "wizbury", "\95¨\82ð\82 \82È\82½\82Ì\8eü\82è\82É\96\84\82ß\82é",
5202 #endif
5203             wiz_debug_cmd_bury, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
5204 #endif
5205     { C('e'), "wizdetect", "reveal hidden things within a small radius",
5206             wiz_detect, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
5207     { C('g'), "wizgenesis", "create a monster",
5208             wiz_genesis, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
5209     { C('i'), "wizidentify", "identify all items in inventory",
5210             wiz_identify, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
5211     { '\0', "wizintrinsic", "set an intrinsic",
5212             wiz_intrinsic, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
5213     { C('v'), "wizlevelport", "teleport to another level",
5214             wiz_level_tele, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
5215     { '\0', "wizmakemap", "recreate the current level",
5216             wiz_makemap, IFBURIED | WIZMODECMD },
5217     { C('f'), "wizmap", "map the level",
5218             wiz_map, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
5219 #if 0 /*JP:T*/
5220     { '\0', "wizrumorcheck", "verify rumor boundaries",
5221 #else
5222     { '\0', "wizrumorcheck", "\89\\82Ì\8b«\8aE\82ð\8c\9f\8fØ\82·\82é",
5223 #endif
5224             wiz_rumor_check, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
5225 #if 0 /*JP:T*/
5226     { '\0', "wizsmell", "smell monster",
5227 #else
5228     { '\0', "wizsmell", "\89ö\95¨\82Ì\93õ\82¢\82ð\9ak\82®",
5229 #endif
5230             wiz_smell, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
5231     { '\0', "wizwhere", "show locations of special levels",
5232             wiz_where, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
5233     { C('w'), "wizwish", "wish for something",
5234             wiz_wish, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
5235 #if 0 /*JP:T*/
5236     { '\0', "wmode", "show wall modes",
5237 #else
5238     { '\0', "wmode", "\95Ç\83\82\81[\83h\82ð\8c©\82é",
5239 #endif
5240             wiz_show_wmodes, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
5241 #if 0 /*JP:T*/
5242     { 'z', "zap", "zap a wand", dozap },
5243 #else
5244     { 'z', "zap", "\8fñ\82ð\90U\82é", dozap },
5245 #endif
5246     { '\0', (char *) 0, (char *) 0, donull, 0, (char *) 0 } /* sentinel */
5247 };
5248
5249 /* for key2extcmddesc() to support dowhatdoes() */
5250 struct movcmd {
5251     uchar k1, k2, k3, k4; /* 'normal', 'qwertz', 'numpad', 'phone' */
5252     const char *txt, *alt; /* compass direction, screen direction */
5253 };
5254 static const struct movcmd movtab[] = {
5255     { 'h', 'h', '4', '4', "west",      "left" },
5256     { 'j', 'j', '2', '8', "south",     "down" },
5257     { 'k', 'k', '8', '2', "north",     "up" },
5258     { 'l', 'l', '6', '6', "east",      "right" },
5259     { 'b', 'b', '1', '7', "southwest", "lower left" },
5260     { 'n', 'n', '3', '9', "southeast", "lower right" },
5261     { 'u', 'u', '9', '3', "northeast", "upper right" },
5262     { 'y', 'z', '7', '1', "northwest", "upper left" },
5263     {   0,   0,   0,   0,  (char *) 0, (char *) 0 }
5264 };
5265
5266 int extcmdlist_length = SIZE(extcmdlist) - 1;
5267
5268 const char *
5269 key2extcmddesc(key)
5270 uchar key;
5271 {
5272     static char key2cmdbuf[48];
5273     const struct movcmd *mov;
5274     int k, c;
5275     uchar M_5 = (uchar) M('5'), M_0 = (uchar) M('0');
5276
5277     /* need to check for movement commands before checking the extended
5278        commands table because it contains entries for number_pad commands
5279        that match !number_pad movement (like 'j' for "jump") */
5280     key2cmdbuf[0] = '\0';
5281     if (movecmd(k = key))
5282         Strcpy(key2cmdbuf, "move"); /* "move or attack"? */
5283     else if (movecmd(k = unctrl(key)))
5284         Strcpy(key2cmdbuf, "rush");
5285     else if (movecmd(k = (Cmd.num_pad ? unmeta(key) : lowc(key))))
5286         Strcpy(key2cmdbuf, "run");
5287     if (*key2cmdbuf) {
5288         for (mov = &movtab[0]; mov->k1; ++mov) {
5289             c = !Cmd.num_pad ? (!Cmd.swap_yz ? mov->k1 : mov->k2)
5290                              : (!Cmd.phone_layout ? mov->k3 : mov->k4);
5291             if (c == k) {
5292                 Sprintf(eos(key2cmdbuf), " %s (screen %s)",
5293                         mov->txt, mov->alt);
5294                 return key2cmdbuf;
5295             }
5296         }
5297     } else if (digit(key) || (Cmd.num_pad && digit(unmeta(key)))) {
5298         key2cmdbuf[0] = '\0';
5299         if (!Cmd.num_pad)
5300             Strcpy(key2cmdbuf, "start of, or continuation of, a count");
5301         else if (key == '5' || key == M_5)
5302             Sprintf(key2cmdbuf, "%s prefix",
5303                     (!!Cmd.pcHack_compat ^ (key == M_5)) ? "run" : "rush");
5304         else if (key == '0' || (Cmd.pcHack_compat && key == M_0))
5305             Strcpy(key2cmdbuf, "synonym for 'i'");
5306         if (*key2cmdbuf)
5307             return key2cmdbuf;
5308     }
5309     if (Cmd.commands[key]) {
5310         if (Cmd.commands[key]->ef_txt)
5311             return Cmd.commands[key]->ef_desc;
5312
5313     }
5314     return (char *) 0;
5315 }
5316
5317 boolean
5318 bind_key(key, command)
5319 uchar key;
5320 const char *command;
5321 {
5322     struct ext_func_tab *extcmd;
5323
5324     /* special case: "nothing" is reserved for unbinding */
5325     if (!strcmp(command, "nothing")) {
5326         Cmd.commands[key] = (struct ext_func_tab *) 0;
5327         return TRUE;
5328     }
5329
5330     for (extcmd = extcmdlist; extcmd->ef_txt; extcmd++) {
5331         if (strcmp(command, extcmd->ef_txt))
5332             continue;
5333         Cmd.commands[key] = extcmd;
5334 #if 0 /* silently accept key binding for unavailable command (!SHELL,&c) */
5335         if ((extcmd->flags & CMD_NOT_AVAILABLE) != 0) {
5336             char buf[BUFSZ];
5337
5338             Sprintf(buf, cmdnotavail, extcmd->ef_txt);
5339             config_error_add("%s", buf);
5340         }
5341 #endif
5342         return TRUE;
5343     }
5344
5345     return FALSE;
5346 }
5347
5348 /* initialize all keyboard commands */
5349 void
5350 commands_init()
5351 {
5352     struct ext_func_tab *extcmd;
5353
5354     for (extcmd = extcmdlist; extcmd->ef_txt; extcmd++)
5355         if (extcmd->key)
5356             Cmd.commands[extcmd->key] = extcmd;
5357
5358     (void) bind_key(C('l'), "redraw"); /* if number_pad is set */
5359     /*       'b', 'B' : go sw */
5360     /*       'F' : fight (one time) */
5361     /*       'g', 'G' : multiple go */
5362     /*       'h', 'H' : go west */
5363     (void) bind_key('h',    "help"); /* if number_pad is set */
5364     (void) bind_key('j',    "jump"); /* if number_pad is on */
5365     /*       'j', 'J', 'k', 'K', 'l', 'L', 'm', 'M', 'n', 'N' move commands */
5366     (void) bind_key('k',    "kick"); /* if number_pad is on */
5367     (void) bind_key('l',    "loot"); /* if number_pad is on */
5368     (void) bind_key(C('n'), "annotate"); /* if number_pad is on */
5369     (void) bind_key(M('n'), "name");
5370     (void) bind_key(M('N'), "name");
5371     (void) bind_key('u',    "untrap"); /* if number_pad is on */
5372
5373     /* alt keys: */
5374     (void) bind_key(M('O'), "overview");
5375     (void) bind_key(M('2'), "twoweapon");
5376
5377     /* wait_on_space */
5378     (void) bind_key(' ',    "wait");
5379 }
5380
5381 int
5382 dokeylist_putcmds(datawin, docount, cmdflags, exflags, keys_used)
5383 winid datawin;
5384 boolean docount;
5385 int cmdflags, exflags;
5386 boolean *keys_used; /* boolean keys_used[256] */
5387 {
5388     int i;
5389     char buf[BUFSZ];
5390     char buf2[QBUFSZ];
5391     int count = 0;
5392
5393     for (i = 0; i < 256; i++) {
5394         const struct ext_func_tab *extcmd;
5395         uchar key = (uchar) i;
5396
5397         if (keys_used[i])
5398             continue;
5399         if (key == ' ' && !flags.rest_on_space)
5400             continue;
5401         if ((extcmd = Cmd.commands[i]) != (struct ext_func_tab *) 0) {
5402             if ((cmdflags && !(extcmd->flags & cmdflags))
5403                 || (exflags && (extcmd->flags & exflags)))
5404                 continue;
5405             if (docount) {
5406                 count++;
5407                 continue;
5408             }
5409             Sprintf(buf, "%-8s %-12s %s", key2txt(key, buf2),
5410                     extcmd->ef_txt,
5411                     extcmd->ef_desc);
5412             putstr(datawin, 0, buf);
5413             keys_used[i] = TRUE;
5414         }
5415     }
5416     return count;
5417 }
5418
5419 /* list all keys and their bindings, like dat/hh but dynamic */
5420 void
5421 dokeylist(VOID_ARGS)
5422 {
5423     char buf[BUFSZ], buf2[BUFSZ];
5424     uchar key;
5425     boolean keys_used[256] = {0};
5426     winid datawin;
5427     int i;
5428     static const char
5429 #if 0 /*JP:T*/
5430         run_desc[] = "Prefix: run until something very interesting is seen",
5431 #else
5432         run_desc[] = "\90Ú\93ª\8e«: \89½\82©\82Æ\82Ä\82à\8b»\96¡\90[\82¢\82à\82Ì\82ª\8c©\82¦\82é\82Ü\82Å\91\96\82é",
5433 #endif
5434         forcefight_desc[] =
5435 #if 0 /*JP:T*/
5436                      "Prefix: force fight even if you don't see a monster";
5437 #else
5438                      "\90Ú\93ª\8e«: \82½\82Æ\82¦\89ö\95¨\82ª\8c©\82¦\82Ä\82¢\82È\82­\82Ä\82à\90í\82¤";
5439 #endif
5440     static const struct {
5441         int nhkf;
5442         const char *desc;
5443         boolean numpad;
5444     } misc_keys[] = {
5445 #if 0 /*JP:T*/
5446         { NHKF_ESC, "escape from the current query/action", FALSE },
5447 #else
5448         { NHKF_ESC, "\8c»\8dÝ\82Ì\8ds\93®\82ð\92\86\92f\82·\82é", FALSE },
5449 #endif
5450         { NHKF_RUSH,
5451 #if 0 /*JP:T*/
5452           "Prefix: rush until something interesting is seen", FALSE },
5453 #else
5454           "\90Ú\93ª\8e«: \89½\82©\8b»\96¡\90[\82¢\82à\82Ì\82ª\8c©\82¦\82é\82Ü\82Å\91\96\82é", FALSE },
5455 #endif
5456         { NHKF_RUN, run_desc, FALSE },
5457         { NHKF_RUN2, run_desc, TRUE },
5458         { NHKF_FIGHT, forcefight_desc, FALSE },
5459         { NHKF_FIGHT2, forcefight_desc, TRUE } ,
5460         { NHKF_NOPICKUP,
5461 #if 0 /*JP:T*/
5462           "Prefix: move without picking up objects/fighting", FALSE },
5463 #else
5464           "\90Ú\93ª\8e«: \95¨\82ð\8fE\82Á\82½\82è\90í\82Á\82½\82è\82¹\82¸\82É\88Ú\93®\82·\82é", FALSE },
5465 #endif
5466         { NHKF_RUN_NOPICKUP,
5467 #if 0 /*JP:T*/
5468           "Prefix: run without picking up objects/fighting", FALSE },
5469 #else
5470           "\90Ú\93ª\8e«: \95¨\82ð\8fE\82Á\82½\82è\90í\82Á\82½\82è\82¹\82¸\82É\91\96\82é", FALSE },
5471 #endif
5472 #if 0 /*JP:T*/
5473         { NHKF_DOINV, "view inventory", TRUE },
5474 #else
5475         { NHKF_DOINV, "\8e\9d\95¨\82ð\95\\8e¦\82·\82é", TRUE },
5476 #endif
5477 #if 0 /*JP:T*/
5478         { NHKF_REQMENU, "Prefix: request a menu", FALSE },
5479 #else
5480         { NHKF_REQMENU, "\90Ú\93ª\8e«: \83\81\83j\83\85\81[\82ð\97v\8b\81\82·\82é", FALSE },
5481 #endif
5482 #ifdef REDO
5483 #if 0 /*JP:T*/
5484         { NHKF_DOAGAIN , "re-do: perform the previous command again", FALSE },
5485 #else
5486         { NHKF_DOAGAIN , "\8dÄ\8eÀ\8ds: \91O\89ñ\82Ì\83R\83}\83\93\83h\82ð\82à\82¤\88ê\93x\8eÀ\8ds\82·\82é", FALSE },
5487 #endif
5488 #endif
5489         { 0, (const char *) 0, FALSE }
5490     };
5491
5492     datawin = create_nhwindow(NHW_TEXT);
5493     putstr(datawin, 0, "");
5494 /*JP
5495     putstr(datawin, 0, "            Full Current Key Bindings List");
5496 */
5497     putstr(datawin, 0, "             \8c»\8dÝ\82Ì\8a®\91S\82È\83L\81[\8a\84\82è\93\96\82Ä\88ê\97\97");
5498
5499     /* directional keys */
5500     putstr(datawin, 0, "");
5501 /*JP
5502     putstr(datawin, 0, "Directional keys:");
5503 */
5504     putstr(datawin, 0, "\95û\8cü\83L\81[:");
5505     show_direction_keys(datawin, '.', FALSE); /* '.'==self in direction grid */
5506
5507     keys_used[(uchar) Cmd.move_NW] = keys_used[(uchar) Cmd.move_N]
5508         = keys_used[(uchar) Cmd.move_NE] = keys_used[(uchar) Cmd.move_W]
5509         = keys_used[(uchar) Cmd.move_E] = keys_used[(uchar) Cmd.move_SW]
5510         = keys_used[(uchar) Cmd.move_S] = keys_used[(uchar) Cmd.move_SE]
5511         = TRUE;
5512
5513     if (!iflags.num_pad) {
5514         keys_used[(uchar) highc(Cmd.move_NW)]
5515             = keys_used[(uchar) highc(Cmd.move_N)]
5516             = keys_used[(uchar) highc(Cmd.move_NE)]
5517             = keys_used[(uchar) highc(Cmd.move_W)]
5518             = keys_used[(uchar) highc(Cmd.move_E)]
5519             = keys_used[(uchar) highc(Cmd.move_SW)]
5520             = keys_used[(uchar) highc(Cmd.move_S)]
5521             = keys_used[(uchar) highc(Cmd.move_SE)] = TRUE;
5522         keys_used[(uchar) C(Cmd.move_NW)]
5523             = keys_used[(uchar) C(Cmd.move_N)]
5524             = keys_used[(uchar) C(Cmd.move_NE)]
5525             = keys_used[(uchar) C(Cmd.move_W)]
5526             = keys_used[(uchar) C(Cmd.move_E)]
5527             = keys_used[(uchar) C(Cmd.move_SW)]
5528             = keys_used[(uchar) C(Cmd.move_S)]
5529             = keys_used[(uchar) C(Cmd.move_SE)] = TRUE;
5530         putstr(datawin, 0, "");
5531 #if 0 /*JP:T*/
5532         putstr(datawin, 0,
5533           "Shift-<direction> will move in specified direction until you hit");
5534         putstr(datawin, 0, "        a wall or run into something.");
5535 #else
5536         putstr(datawin, 0,
5537           "Shift-<\95û\8cü> \82Í\81A\95Ç\82É\82Ô\82Â\82©\82é\82©\89½\82©\82ª\82 \82é\82Ü\82Å\8ew\92è\82³\82ê\82½\95û\8cü\82É");
5538         putstr(datawin, 0, "        \88Ú\93®\82·\82é\81D");
5539 #endif
5540 #if 0 /*JP:T*/
5541         putstr(datawin, 0,
5542           "Ctrl-<direction> will run in specified direction until something");
5543         putstr(datawin, 0, "        very interesting is seen.");
5544 #else
5545         putstr(datawin, 0,
5546           "Ctrl-<\95û\8cü> \82Í\81A\89½\82©\8b»\96¡\90[\82¢\82à\82Ì\82ª\8c©\82¦\82é\82Ü\82Å\8ew\92è\82³\82ê\82½\95û\8cü\82É");
5547         putstr(datawin, 0, "        \88Ú\93®\82·\82é\81D");
5548 #endif
5549     }
5550
5551     putstr(datawin, 0, "");
5552 /*JP
5553     putstr(datawin, 0, "Miscellaneous keys:");
5554 */
5555     putstr(datawin, 0, "\97l\81X\82È\83L\81[:");
5556     for (i = 0; misc_keys[i].desc; i++) {
5557         key = Cmd.spkeys[misc_keys[i].nhkf];
5558         if (key && ((misc_keys[i].numpad && iflags.num_pad)
5559                     || !misc_keys[i].numpad)) {
5560             keys_used[(uchar) key] = TRUE;
5561             Sprintf(buf, "%-8s %s", key2txt(key, buf2), misc_keys[i].desc);
5562             putstr(datawin, 0, buf);
5563         }
5564     }
5565 #ifndef NO_SIGNAL
5566     putstr(datawin, 0, "^c       break out of NetHack (SIGINT)");
5567     keys_used[(uchar) C('c')] = TRUE;
5568 #endif
5569
5570     putstr(datawin, 0, "");
5571     show_menu_controls(datawin, TRUE);
5572
5573     if (dokeylist_putcmds(datawin, TRUE, GENERALCMD, WIZMODECMD, keys_used)) {
5574         putstr(datawin, 0, "");
5575 /*JP
5576         putstr(datawin, 0, "General commands:");
5577 */
5578         putstr(datawin, 0, "\88ê\94Ê\83R\83}\83\93\83h:");
5579         (void) dokeylist_putcmds(datawin, FALSE, GENERALCMD, WIZMODECMD,
5580                                  keys_used);
5581     }
5582
5583     if (dokeylist_putcmds(datawin, TRUE, 0, WIZMODECMD, keys_used)) {
5584         putstr(datawin, 0, "");
5585 /*JP
5586         putstr(datawin, 0, "Game commands:");
5587 */
5588         putstr(datawin, 0, "\83Q\81[\83\80\83R\83}\83\93\83h:");
5589         (void) dokeylist_putcmds(datawin, FALSE, 0, WIZMODECMD, keys_used);
5590     }
5591
5592     if (wizard
5593         && dokeylist_putcmds(datawin, TRUE, WIZMODECMD, 0, keys_used)) {
5594         putstr(datawin, 0, "");
5595 /*JP
5596         putstr(datawin, 0, "Wizard-mode commands:");
5597 */
5598         putstr(datawin, 0, "\83E\83B\83U\81[\83h\83\82\81[\83h\83R\83}\83\93\83h:");
5599         (void) dokeylist_putcmds(datawin, FALSE, WIZMODECMD, 0, keys_used);
5600     }
5601
5602     display_nhwindow(datawin, FALSE);
5603     destroy_nhwindow(datawin);
5604 }
5605
5606 char
5607 cmd_from_func(fn)
5608 int NDECL((*fn));
5609 {
5610     int i;
5611
5612     for (i = 0; i < 256; ++i)
5613         if (Cmd.commands[i] && Cmd.commands[i]->ef_funct == fn)
5614             return (char) i;
5615     return '\0';
5616 }
5617
5618 /*
5619  * wizard mode sanity_check code
5620  */
5621
5622 static const char template[] = "%-27s  %4ld  %6ld";
5623 static const char stats_hdr[] = "                             count  bytes";
5624 static const char stats_sep[] = "---------------------------  ----- -------";
5625
5626 STATIC_OVL int
5627 size_obj(otmp)
5628 struct obj *otmp;
5629 {
5630     int sz = (int) sizeof (struct obj);
5631
5632     if (otmp->oextra) {
5633         sz += (int) sizeof (struct oextra);
5634         if (ONAME(otmp))
5635             sz += (int) strlen(ONAME(otmp)) + 1;
5636         if (OMONST(otmp))
5637             sz += size_monst(OMONST(otmp), FALSE);
5638         if (OMID(otmp))
5639             sz += (int) sizeof (unsigned);
5640         if (OLONG(otmp))
5641             sz += (int) sizeof (long);
5642         if (OMAILCMD(otmp))
5643             sz += (int) strlen(OMAILCMD(otmp)) + 1;
5644     }
5645     return sz;
5646 }
5647
5648 STATIC_OVL void
5649 count_obj(chain, total_count, total_size, top, recurse)
5650 struct obj *chain;
5651 long *total_count;
5652 long *total_size;
5653 boolean top;
5654 boolean recurse;
5655 {
5656     long count, size;
5657     struct obj *obj;
5658
5659     for (count = size = 0, obj = chain; obj; obj = obj->nobj) {
5660         if (top) {
5661             count++;
5662             size += size_obj(obj);
5663         }
5664         if (recurse && obj->cobj)
5665             count_obj(obj->cobj, total_count, total_size, TRUE, TRUE);
5666     }
5667     *total_count += count;
5668     *total_size += size;
5669 }
5670
5671 STATIC_OVL void
5672 obj_chain(win, src, chain, force, total_count, total_size)
5673 winid win;
5674 const char *src;
5675 struct obj *chain;
5676 boolean force;
5677 long *total_count;
5678 long *total_size;
5679 {
5680     char buf[BUFSZ];
5681     long count = 0L, size = 0L;
5682
5683     count_obj(chain, &count, &size, TRUE, FALSE);
5684
5685     if (count || size || force) {
5686         *total_count += count;
5687         *total_size += size;
5688         Sprintf(buf, template, src, count, size);
5689         putstr(win, 0, buf);
5690     }
5691 }
5692
5693 STATIC_OVL void
5694 mon_invent_chain(win, src, chain, total_count, total_size)
5695 winid win;
5696 const char *src;
5697 struct monst *chain;
5698 long *total_count;
5699 long *total_size;
5700 {
5701     char buf[BUFSZ];
5702     long count = 0, size = 0;
5703     struct monst *mon;
5704
5705     for (mon = chain; mon; mon = mon->nmon)
5706         count_obj(mon->minvent, &count, &size, TRUE, FALSE);
5707
5708     if (count || size) {
5709         *total_count += count;
5710         *total_size += size;
5711         Sprintf(buf, template, src, count, size);
5712         putstr(win, 0, buf);
5713     }
5714 }
5715
5716 STATIC_OVL void
5717 contained_stats(win, src, total_count, total_size)
5718 winid win;
5719 const char *src;
5720 long *total_count;
5721 long *total_size;
5722 {
5723     char buf[BUFSZ];
5724     long count = 0, size = 0;
5725     struct monst *mon;
5726
5727     count_obj(invent, &count, &size, FALSE, TRUE);
5728     count_obj(fobj, &count, &size, FALSE, TRUE);
5729     count_obj(level.buriedobjlist, &count, &size, FALSE, TRUE);
5730     count_obj(migrating_objs, &count, &size, FALSE, TRUE);
5731     /* DEADMONSTER check not required in this loop since they have no
5732      * inventory */
5733     for (mon = fmon; mon; mon = mon->nmon)
5734         count_obj(mon->minvent, &count, &size, FALSE, TRUE);
5735     for (mon = migrating_mons; mon; mon = mon->nmon)
5736         count_obj(mon->minvent, &count, &size, FALSE, TRUE);
5737
5738     if (count || size) {
5739         *total_count += count;
5740         *total_size += size;
5741         Sprintf(buf, template, src, count, size);
5742         putstr(win, 0, buf);
5743     }
5744 }
5745
5746 STATIC_OVL int
5747 size_monst(mtmp, incl_wsegs)
5748 struct monst *mtmp;
5749 boolean incl_wsegs;
5750 {
5751     int sz = (int) sizeof (struct monst);
5752
5753     if (mtmp->wormno && incl_wsegs)
5754         sz += size_wseg(mtmp);
5755
5756     if (mtmp->mextra) {
5757         sz += (int) sizeof (struct mextra);
5758         if (MNAME(mtmp))
5759             sz += (int) strlen(MNAME(mtmp)) + 1;
5760         if (EGD(mtmp))
5761             sz += (int) sizeof (struct egd);
5762         if (EPRI(mtmp))
5763             sz += (int) sizeof (struct epri);
5764         if (ESHK(mtmp))
5765             sz += (int) sizeof (struct eshk);
5766         if (EMIN(mtmp))
5767             sz += (int) sizeof (struct emin);
5768         if (EDOG(mtmp))
5769             sz += (int) sizeof (struct edog);
5770         /* mextra->mcorpsenm doesn't point to more memory */
5771     }
5772     return sz;
5773 }
5774
5775 STATIC_OVL void
5776 mon_chain(win, src, chain, force, total_count, total_size)
5777 winid win;
5778 const char *src;
5779 struct monst *chain;
5780 boolean force;
5781 long *total_count;
5782 long *total_size;
5783 {
5784     char buf[BUFSZ];
5785     long count, size;
5786     struct monst *mon;
5787     /* mon->wormno means something different for migrating_mons and mydogs */
5788     boolean incl_wsegs = !strcmpi(src, "fmon");
5789
5790     count = size = 0L;
5791     for (mon = chain; mon; mon = mon->nmon) {
5792         count++;
5793         size += size_monst(mon, incl_wsegs);
5794     }
5795     if (count || size || force) {
5796         *total_count += count;
5797         *total_size += size;
5798         Sprintf(buf, template, src, count, size);
5799         putstr(win, 0, buf);
5800     }
5801 }
5802
5803 STATIC_OVL void
5804 misc_stats(win, total_count, total_size)
5805 winid win;
5806 long *total_count;
5807 long *total_size;
5808 {
5809     char buf[BUFSZ], hdrbuf[QBUFSZ];
5810     long count, size;
5811     int idx;
5812     struct trap *tt;
5813     struct damage *sd; /* shop damage */
5814     struct kinfo *k; /* delayed killer */
5815     struct cemetery *bi; /* bones info */
5816
5817     /* traps and engravings are output unconditionally;
5818      * others only if nonzero
5819      */
5820     count = size = 0L;
5821     for (tt = ftrap; tt; tt = tt->ntrap) {
5822         ++count;
5823         size += (long) sizeof *tt;
5824     }
5825     *total_count += count;
5826     *total_size += size;
5827     Sprintf(hdrbuf, "traps, size %ld", (long) sizeof (struct trap));
5828     Sprintf(buf, template, hdrbuf, count, size);
5829     putstr(win, 0, buf);
5830
5831     count = size = 0L;
5832     engr_stats("engravings, size %ld+text", hdrbuf, &count, &size);
5833     *total_count += count;
5834     *total_size += size;
5835     Sprintf(buf, template, hdrbuf, count, size);
5836     putstr(win, 0, buf);
5837
5838     count = size = 0L;
5839     light_stats("light sources, size %ld", hdrbuf, &count, &size);
5840     if (count || size) {
5841         *total_count += count;
5842         *total_size += size;
5843         Sprintf(buf, template, hdrbuf, count, size);
5844         putstr(win, 0, buf);
5845     }
5846
5847     count = size = 0L;
5848     timer_stats("timers, size %ld", hdrbuf, &count, &size);
5849     if (count || size) {
5850         *total_count += count;
5851         *total_size += size;
5852         Sprintf(buf, template, hdrbuf, count, size);
5853         putstr(win, 0, buf);
5854     }
5855
5856     count = size = 0L;
5857     for (sd = level.damagelist; sd; sd = sd->next) {
5858         ++count;
5859         size += (long) sizeof *sd;
5860     }
5861     if (count || size) {
5862         *total_count += count;
5863         *total_size += size;
5864         Sprintf(hdrbuf, "shop damage, size %ld",
5865                 (long) sizeof (struct damage));
5866         Sprintf(buf, template, hdrbuf, count, size);
5867         putstr(win, 0, buf);
5868     }
5869
5870     count = size = 0L;
5871     region_stats("regions, size %ld+%ld*rect+N", hdrbuf, &count, &size);
5872     if (count || size) {
5873         *total_count += count;
5874         *total_size += size;
5875         Sprintf(buf, template, hdrbuf, count, size);
5876         putstr(win, 0, buf);
5877     }
5878
5879     count = size = 0L;
5880     for (k = killer.next; k; k = k->next) {
5881         ++count;
5882         size += (long) sizeof *k;
5883     }
5884     if (count || size) {
5885         *total_count += count;
5886         *total_size += size;
5887         Sprintf(hdrbuf, "delayed killer%s, size %ld",
5888                 plur(count), (long) sizeof (struct kinfo));
5889         Sprintf(buf, template, hdrbuf, count, size);
5890         putstr(win, 0, buf);
5891     }
5892
5893     count = size = 0L;
5894     for (bi = level.bonesinfo; bi; bi = bi->next) {
5895         ++count;
5896         size += (long) sizeof *bi;
5897     }
5898     if (count || size) {
5899         *total_count += count;
5900         *total_size += size;
5901         Sprintf(hdrbuf, "bones history, size %ld",
5902                 (long) sizeof (struct cemetery));
5903         Sprintf(buf, template, hdrbuf, count, size);
5904         putstr(win, 0, buf);
5905     }
5906
5907     count = size = 0L;
5908     for (idx = 0; idx < NUM_OBJECTS; ++idx)
5909         if (objects[idx].oc_uname) {
5910             ++count;
5911             size += (long) (strlen(objects[idx].oc_uname) + 1);
5912         }
5913     if (count || size) {
5914         *total_count += count;
5915         *total_size += size;
5916         Strcpy(hdrbuf, "object type names, text");
5917         Sprintf(buf, template, hdrbuf, count, size);
5918         putstr(win, 0, buf);
5919     }
5920 }
5921
5922 /*
5923  * Display memory usage of all monsters and objects on the level.
5924  */
5925 static int
5926 wiz_show_stats()
5927 {
5928     char buf[BUFSZ];
5929     winid win;
5930     long total_obj_size, total_obj_count,
5931          total_mon_size, total_mon_count,
5932          total_ovr_size, total_ovr_count,
5933          total_misc_size, total_misc_count;
5934
5935     win = create_nhwindow(NHW_TEXT);
5936     putstr(win, 0, "Current memory statistics:");
5937
5938     total_obj_count = total_obj_size = 0L;
5939     putstr(win, 0, stats_hdr);
5940     Sprintf(buf, "  Objects, base size %ld", (long) sizeof (struct obj));
5941     putstr(win, 0, buf);
5942     obj_chain(win, "invent", invent, TRUE, &total_obj_count, &total_obj_size);
5943     obj_chain(win, "fobj", fobj, TRUE, &total_obj_count, &total_obj_size);
5944     obj_chain(win, "buried", level.buriedobjlist, FALSE,
5945               &total_obj_count, &total_obj_size);
5946     obj_chain(win, "migrating obj", migrating_objs, FALSE,
5947               &total_obj_count, &total_obj_size);
5948     obj_chain(win, "billobjs", billobjs, FALSE,
5949               &total_obj_count, &total_obj_size);
5950     mon_invent_chain(win, "minvent", fmon, &total_obj_count, &total_obj_size);
5951     mon_invent_chain(win, "migrating minvent", migrating_mons,
5952                      &total_obj_count, &total_obj_size);
5953     contained_stats(win, "contained", &total_obj_count, &total_obj_size);
5954     putstr(win, 0, stats_sep);
5955     Sprintf(buf, template, "  Obj total", total_obj_count, total_obj_size);
5956     putstr(win, 0, buf);
5957
5958     total_mon_count = total_mon_size = 0L;
5959     putstr(win, 0, "");
5960     Sprintf(buf, "  Monsters, base size %ld", (long) sizeof (struct monst));
5961     putstr(win, 0, buf);
5962     mon_chain(win, "fmon", fmon, TRUE, &total_mon_count, &total_mon_size);
5963     mon_chain(win, "migrating", migrating_mons, FALSE,
5964               &total_mon_count, &total_mon_size);
5965     /* 'mydogs' is only valid during level change or end of game disclosure,
5966        but conceivably we've been called from within debugger at such time */
5967     if (mydogs) /* monsters accompanying hero */
5968         mon_chain(win, "mydogs", mydogs, FALSE,
5969                   &total_mon_count, &total_mon_size);
5970     putstr(win, 0, stats_sep);
5971     Sprintf(buf, template, "  Mon total", total_mon_count, total_mon_size);
5972     putstr(win, 0, buf);
5973
5974     total_ovr_count = total_ovr_size = 0L;
5975     putstr(win, 0, "");
5976     putstr(win, 0, "  Overview");
5977     overview_stats(win, template, &total_ovr_count, &total_ovr_size);
5978     putstr(win, 0, stats_sep);
5979     Sprintf(buf, template, "  Over total", total_ovr_count, total_ovr_size);
5980     putstr(win, 0, buf);
5981
5982     total_misc_count = total_misc_size = 0L;
5983     putstr(win, 0, "");
5984     putstr(win, 0, "  Miscellaneous");
5985     misc_stats(win, &total_misc_count, &total_misc_size);
5986     putstr(win, 0, stats_sep);
5987     Sprintf(buf, template, "  Misc total", total_misc_count, total_misc_size);
5988     putstr(win, 0, buf);
5989
5990     putstr(win, 0, "");
5991     putstr(win, 0, stats_sep);
5992     Sprintf(buf, template, "  Grand total",
5993             (total_obj_count + total_mon_count
5994              + total_ovr_count + total_misc_count),
5995             (total_obj_size + total_mon_size
5996              + total_ovr_size + total_misc_size));
5997     putstr(win, 0, buf);
5998
5999 #if defined(__BORLANDC__) && !defined(_WIN32)
6000     show_borlandc_stats(win);
6001 #endif
6002
6003     display_nhwindow(win, FALSE);
6004     destroy_nhwindow(win);
6005     return 0;
6006 }
6007
6008 void
6009 sanity_check()
6010 {
6011     obj_sanity_check();
6012     timer_sanity_check();
6013     mon_sanity_check();
6014     light_sources_sanity_check();
6015     bc_sanity_check();
6016 }
6017
6018 #ifdef DEBUG_MIGRATING_MONS
6019 static int
6020 wiz_migrate_mons()
6021 {
6022     int mcount = 0;
6023     char inbuf[BUFSZ] = DUMMY;
6024     struct permonst *ptr;
6025     struct monst *mtmp;
6026     d_level tolevel;
6027
6028     getlin("How many random monsters to migrate? [0]", inbuf);
6029     if (*inbuf == '\033')
6030         return 0;
6031     mcount = atoi(inbuf);
6032     if (mcount < 0 || mcount > (COLNO * ROWNO) || Is_botlevel(&u.uz))
6033         return 0;
6034     while (mcount > 0) {
6035         if (Is_stronghold(&u.uz))
6036             assign_level(&tolevel, &valley_level);
6037         else
6038             get_level(&tolevel, depth(&u.uz) + 1);
6039         ptr = rndmonst();
6040         mtmp = makemon(ptr, 0, 0, NO_MM_FLAGS);
6041         if (mtmp)
6042             migrate_to_level(mtmp, ledger_no(&tolevel), MIGR_RANDOM,
6043                              (coord *) 0);
6044         mcount--;
6045     }
6046     return 0;
6047 }
6048 #endif
6049
6050 struct {
6051     int nhkf;
6052     char key;
6053     const char *name;
6054 } const spkeys_binds[] = {
6055     { NHKF_ESC,              '\033', (char *) 0 }, /* no binding */
6056     { NHKF_DOAGAIN,          DOAGAIN, "repeat" },
6057     { NHKF_REQMENU,          'm', "reqmenu" },
6058     { NHKF_RUN,              'G', "run" },
6059     { NHKF_RUN2,             '5', "run.numpad" },
6060     { NHKF_RUSH,             'g', "rush" },
6061     { NHKF_FIGHT,            'F', "fight" },
6062     { NHKF_FIGHT2,           '-', "fight.numpad" },
6063     { NHKF_NOPICKUP,         'm', "nopickup" },
6064     { NHKF_RUN_NOPICKUP,     'M', "run.nopickup" },
6065     { NHKF_DOINV,            '0', "doinv" },
6066     { NHKF_TRAVEL,           CMD_TRAVEL, (char *) 0 }, /* no binding */
6067     { NHKF_CLICKLOOK,        CMD_CLICKLOOK, (char *) 0 }, /* no binding */
6068     { NHKF_REDRAW,           C('r'), "redraw" },
6069     { NHKF_REDRAW2,          C('l'), "redraw.numpad" },
6070     { NHKF_GETDIR_SELF,      '.', "getdir.self" },
6071     { NHKF_GETDIR_SELF2,     's', "getdir.self2" },
6072     { NHKF_GETDIR_HELP,      '?', "getdir.help" },
6073     { NHKF_COUNT,            'n', "count" },
6074     { NHKF_GETPOS_SELF,      '@', "getpos.self" },
6075     { NHKF_GETPOS_PICK,      '.', "getpos.pick" },
6076     { NHKF_GETPOS_PICK_Q,    ',', "getpos.pick.quick" },
6077     { NHKF_GETPOS_PICK_O,    ';', "getpos.pick.once" },
6078     { NHKF_GETPOS_PICK_V,    ':', "getpos.pick.verbose" },
6079     { NHKF_GETPOS_SHOWVALID, '$', "getpos.valid" },
6080     { NHKF_GETPOS_AUTODESC,  '#', "getpos.autodescribe" },
6081     { NHKF_GETPOS_MON_NEXT,  'm', "getpos.mon.next" },
6082     { NHKF_GETPOS_MON_PREV,  'M', "getpos.mon.prev" },
6083     { NHKF_GETPOS_OBJ_NEXT,  'o', "getpos.obj.next" },
6084     { NHKF_GETPOS_OBJ_PREV,  'O', "getpos.obj.prev" },
6085     { NHKF_GETPOS_DOOR_NEXT, 'd', "getpos.door.next" },
6086     { NHKF_GETPOS_DOOR_PREV, 'D', "getpos.door.prev" },
6087     { NHKF_GETPOS_UNEX_NEXT, 'x', "getpos.unexplored.next" },
6088     { NHKF_GETPOS_UNEX_PREV, 'X', "getpos.unexplored.prev" },
6089     { NHKF_GETPOS_VALID_NEXT, 'z', "getpos.valid.next" },
6090     { NHKF_GETPOS_VALID_PREV, 'Z', "getpos.valid.prev" },
6091     { NHKF_GETPOS_INTERESTING_NEXT, 'a', "getpos.all.next" },
6092     { NHKF_GETPOS_INTERESTING_PREV, 'A', "getpos.all.prev" },
6093     { NHKF_GETPOS_HELP,      '?', "getpos.help" },
6094     { NHKF_GETPOS_LIMITVIEW, '"', "getpos.filter" },
6095     { NHKF_GETPOS_MOVESKIP,  '*', "getpos.moveskip" },
6096     { NHKF_GETPOS_MENU,      '!', "getpos.menu" }
6097 };
6098
6099 boolean
6100 bind_specialkey(key, command)
6101 uchar key;
6102 const char *command;
6103 {
6104     int i;
6105     for (i = 0; i < SIZE(spkeys_binds); i++) {
6106         if (!spkeys_binds[i].name || strcmp(command, spkeys_binds[i].name))
6107             continue;
6108         Cmd.spkeys[spkeys_binds[i].nhkf] = key;
6109         return TRUE;
6110     }
6111     return FALSE;
6112 }
6113
6114 /* returns a one-byte character from the text (it may massacre the txt
6115  * buffer) */
6116 char
6117 txt2key(txt)
6118 char *txt;
6119 {
6120     txt = trimspaces(txt);
6121     if (!*txt)
6122         return '\0';
6123
6124     /* simple character */
6125     if (!txt[1])
6126         return txt[0];
6127
6128     /* a few special entries */
6129     if (!strcmp(txt, "<enter>"))
6130         return '\n';
6131     if (!strcmp(txt, "<space>"))
6132         return ' ';
6133     if (!strcmp(txt, "<esc>"))
6134         return '\033';
6135
6136     /* control and meta keys */
6137     switch (*txt) {
6138     case 'm': /* can be mx, Mx, m-x, M-x */
6139     case 'M':
6140         txt++;
6141         if (*txt == '-' && txt[1])
6142             txt++;
6143         if (txt[1])
6144             return '\0';
6145         return M(*txt);
6146     case 'c': /* can be cx, Cx, ^x, c-x, C-x, ^-x */
6147     case 'C':
6148     case '^':
6149         txt++;
6150         if (*txt == '-' && txt[1])
6151             txt++;
6152         if (txt[1])
6153             return '\0';
6154         return C(*txt);
6155     }
6156
6157     /* ascii codes: must be three-digit decimal */
6158     if (*txt >= '0' && *txt <= '9') {
6159         uchar key = 0;
6160         int i;
6161
6162         for (i = 0; i < 3; i++) {
6163             if (txt[i] < '0' || txt[i] > '9')
6164                 return '\0';
6165             key = 10 * key + txt[i] - '0';
6166         }
6167         return key;
6168     }
6169
6170     return '\0';
6171 }
6172
6173 /* returns the text for a one-byte encoding;
6174  * must be shorter than a tab for proper formatting */
6175 char *
6176 key2txt(c, txt)
6177 uchar c;
6178 char *txt; /* sufficiently long buffer */
6179 {
6180     /* should probably switch to "SPC", "ESC", "RET"
6181        since nethack's documentation uses ESC for <escape> */
6182     if (c == ' ')
6183         Sprintf(txt, "<space>");
6184     else if (c == '\033')
6185         Sprintf(txt, "<esc>");
6186     else if (c == '\n')
6187         Sprintf(txt, "<enter>");
6188     else if (c == '\177')
6189         Sprintf(txt, "<del>"); /* "<delete>" won't fit */
6190     else
6191         Strcpy(txt, visctrl((char) c));
6192     return txt;
6193 }
6194
6195
6196 void
6197 parseautocomplete(autocomplete, condition)
6198 char *autocomplete;
6199 boolean condition;
6200 {
6201     struct ext_func_tab *efp;
6202     register char *autoc;
6203
6204     /* break off first autocomplete from the rest; parse the rest */
6205     if ((autoc = index(autocomplete, ',')) != 0
6206         || (autoc = index(autocomplete, ':')) != 0) {
6207         *autoc++ = '\0';
6208         parseautocomplete(autoc, condition);
6209     }
6210
6211     /* strip leading and trailing white space */
6212     autocomplete = trimspaces(autocomplete);
6213
6214     if (!*autocomplete)
6215         return;
6216
6217     /* take off negation */
6218     if (*autocomplete == '!') {
6219         /* unlike most options, a leading "no" might actually be a part of
6220          * the extended command.  Thus you have to use ! */
6221         autocomplete++;
6222         autocomplete = trimspaces(autocomplete);
6223         condition = !condition;
6224     }
6225
6226     /* find and modify the extended command */
6227     for (efp = extcmdlist; efp->ef_txt; efp++) {
6228         if (!strcmp(autocomplete, efp->ef_txt)) {
6229             if (condition)
6230                 efp->flags |= AUTOCOMPLETE;
6231             else
6232                 efp->flags &= ~AUTOCOMPLETE;
6233             return;
6234         }
6235     }
6236
6237     /* not a real extended command */
6238     raw_printf("Bad autocomplete: invalid extended command '%s'.",
6239                autocomplete);
6240     wait_synch();
6241 }
6242
6243 /* called at startup and after number_pad is twiddled */
6244 void
6245 reset_commands(initial)
6246 boolean initial;
6247 {
6248     static const char sdir[] = "hykulnjb><",
6249                       sdir_swap_yz[] = "hzkulnjb><",
6250                       ndir[] = "47896321><",
6251                       ndir_phone_layout[] = "41236987><";
6252     static const int ylist[] = {
6253         'y', 'Y', C('y'), M('y'), M('Y'), M(C('y'))
6254     };
6255     static struct ext_func_tab *back_dir_cmd[8];
6256     const struct ext_func_tab *cmdtmp;
6257     boolean flagtemp;
6258     int c, i, updated = 0;
6259     static boolean backed_dir_cmd = FALSE;
6260
6261     if (initial) {
6262         updated = 1;
6263         Cmd.num_pad = FALSE;
6264         Cmd.pcHack_compat = Cmd.phone_layout = Cmd.swap_yz = FALSE;
6265         for (i = 0; i < SIZE(spkeys_binds); i++)
6266             Cmd.spkeys[spkeys_binds[i].nhkf] = spkeys_binds[i].key;
6267         commands_init();
6268     } else {
6269
6270         if (backed_dir_cmd) {
6271             for (i = 0; i < 8; i++) {
6272                 Cmd.commands[(uchar) Cmd.dirchars[i]] = back_dir_cmd[i];
6273             }
6274         }
6275
6276         /* basic num_pad */
6277         flagtemp = iflags.num_pad;
6278         if (flagtemp != Cmd.num_pad) {
6279             Cmd.num_pad = flagtemp;
6280             ++updated;
6281         }
6282         /* swap_yz mode (only applicable for !num_pad); intended for
6283            QWERTZ keyboard used in Central Europe, particularly Germany */
6284         flagtemp = (iflags.num_pad_mode & 1) ? !Cmd.num_pad : FALSE;
6285         if (flagtemp != Cmd.swap_yz) {
6286             Cmd.swap_yz = flagtemp;
6287             ++updated;
6288             /* Cmd.swap_yz has been toggled;
6289                perform the swap (or reverse previous one) */
6290             for (i = 0; i < SIZE(ylist); i++) {
6291                 c = ylist[i] & 0xff;
6292                 cmdtmp = Cmd.commands[c];              /* tmp = [y] */
6293                 Cmd.commands[c] = Cmd.commands[c + 1]; /* [y] = [z] */
6294                 Cmd.commands[c + 1] = cmdtmp;          /* [z] = tmp */
6295             }
6296         }
6297         /* MSDOS compatibility mode (only applicable for num_pad) */
6298         flagtemp = (iflags.num_pad_mode & 1) ? Cmd.num_pad : FALSE;
6299         if (flagtemp != Cmd.pcHack_compat) {
6300             Cmd.pcHack_compat = flagtemp;
6301             ++updated;
6302             /* pcHack_compat has been toggled */
6303             c = M('5') & 0xff;
6304             cmdtmp = Cmd.commands['5'];
6305             Cmd.commands['5'] = Cmd.commands[c];
6306             Cmd.commands[c] = cmdtmp;
6307             c = M('0') & 0xff;
6308             Cmd.commands[c] = Cmd.pcHack_compat ? Cmd.commands['I'] : 0;
6309         }
6310         /* phone keypad layout (only applicable for num_pad) */
6311         flagtemp = (iflags.num_pad_mode & 2) ? Cmd.num_pad : FALSE;
6312         if (flagtemp != Cmd.phone_layout) {
6313             Cmd.phone_layout = flagtemp;
6314             ++updated;
6315             /* phone_layout has been toggled */
6316             for (i = 0; i < 3; i++) {
6317                 c = '1' + i;             /* 1,2,3 <-> 7,8,9 */
6318                 cmdtmp = Cmd.commands[c];              /* tmp = [1] */
6319                 Cmd.commands[c] = Cmd.commands[c + 6]; /* [1] = [7] */
6320                 Cmd.commands[c + 6] = cmdtmp;          /* [7] = tmp */
6321                 c = (M('1') & 0xff) + i; /* M-1,M-2,M-3 <-> M-7,M-8,M-9 */
6322                 cmdtmp = Cmd.commands[c];              /* tmp = [M-1] */
6323                 Cmd.commands[c] = Cmd.commands[c + 6]; /* [M-1] = [M-7] */
6324                 Cmd.commands[c + 6] = cmdtmp;          /* [M-7] = tmp */
6325             }
6326         }
6327     } /*?initial*/
6328
6329     if (updated)
6330         Cmd.serialno++;
6331     Cmd.dirchars = !Cmd.num_pad
6332                        ? (!Cmd.swap_yz ? sdir : sdir_swap_yz)
6333                        : (!Cmd.phone_layout ? ndir : ndir_phone_layout);
6334     Cmd.alphadirchars = !Cmd.num_pad ? Cmd.dirchars : sdir;
6335
6336     Cmd.move_W = Cmd.dirchars[0];
6337     Cmd.move_NW = Cmd.dirchars[1];
6338     Cmd.move_N = Cmd.dirchars[2];
6339     Cmd.move_NE = Cmd.dirchars[3];
6340     Cmd.move_E = Cmd.dirchars[4];
6341     Cmd.move_SE = Cmd.dirchars[5];
6342     Cmd.move_S = Cmd.dirchars[6];
6343     Cmd.move_SW = Cmd.dirchars[7];
6344
6345     if (!initial) {
6346         for (i = 0; i < 8; i++) {
6347             back_dir_cmd[i] =
6348                 (struct ext_func_tab *) Cmd.commands[(uchar) Cmd.dirchars[i]];
6349             Cmd.commands[(uchar) Cmd.dirchars[i]] = (struct ext_func_tab *) 0;
6350         }
6351         backed_dir_cmd = TRUE;
6352         for (i = 0; i < 8; i++)
6353             (void) bind_key(Cmd.dirchars[i], "nothing");
6354     }
6355 }
6356
6357 /* non-movement commands which accept 'm' prefix to request menu operation */
6358 STATIC_OVL boolean
6359 accept_menu_prefix(cmd_func)
6360 int NDECL((*cmd_func));
6361 {
6362     if (cmd_func == dopickup || cmd_func == dotip
6363         /* eat, #offer, and apply tinning-kit all use floorfood() to pick
6364            an item on floor or in invent; 'm' skips picking from floor
6365            (ie, inventory only) rather than request use of menu operation */
6366         || cmd_func == doeat || cmd_func == dosacrifice || cmd_func == doapply
6367         /* 'm' for removing saddle from adjacent monster without checking
6368            for containers at <u.ux,u.uy> */
6369         || cmd_func == doloot
6370         /* travel: pop up a menu of interesting targets in view */
6371         || cmd_func == dotravel
6372         /* wizard mode ^V and ^T */
6373         || cmd_func == wiz_level_tele || cmd_func == dotelecmd
6374         /* 'm' prefix allowed for some extended commands */
6375         || cmd_func == doextcmd || cmd_func == doextlist)
6376         return TRUE;
6377     return FALSE;
6378 }
6379
6380 char
6381 randomkey()
6382 {
6383     static unsigned i = 0;
6384     char c;
6385
6386     switch (rn2(16)) {
6387     default:
6388         c = '\033';
6389         break;
6390     case 0:
6391         c = '\n';
6392         break;
6393     case 1:
6394     case 2:
6395     case 3:
6396     case 4:
6397         c = (char) rn1('~' - ' ' + 1, ' ');
6398         break;
6399     case 5:
6400         c = (char) (rn2(2) ? '\t' : ' ');
6401         break;
6402     case 6:
6403         c = (char) rn1('z' - 'a' + 1, 'a');
6404         break;
6405     case 7:
6406         c = (char) rn1('Z' - 'A' + 1, 'A');
6407         break;
6408     case 8:
6409         c = extcmdlist[i++ % SIZE(extcmdlist)].key;
6410         break;
6411     case 9:
6412         c = '#';
6413         break;
6414     case 10:
6415     case 11:
6416     case 12:
6417         c = Cmd.dirchars[rn2(8)];
6418         if (!rn2(7))
6419             c = !Cmd.num_pad ? (!rn2(3) ? C(c) : (c + 'A' - 'a')) : M(c);
6420         break;
6421     case 13:
6422         c = (char) rn1('9' - '0' + 1, '0');
6423         break;
6424     case 14:
6425         /* any char, but avoid '\0' because it's used for mouse click */
6426         c = (char) rnd(iflags.wc_eight_bit_input ? 255 : 127);
6427         break;
6428     }
6429
6430     return c;
6431 }
6432
6433 void
6434 random_response(buf, sz)
6435 char *buf;
6436 int sz;
6437 {
6438     char c;
6439     int count = 0;
6440
6441     for (;;) {
6442         c = randomkey();
6443         if (c == '\n')
6444             break;
6445         if (c == '\033') {
6446             count = 0;
6447             break;
6448         }
6449         if (count < sz - 1)
6450             buf[count++] = c;
6451     }
6452     buf[count] = '\0';
6453 }
6454
6455 int
6456 rnd_extcmd_idx(VOID_ARGS)
6457 {
6458     return rn2(extcmdlist_length + 1) - 1;
6459 }
6460
6461 int
6462 ch2spkeys(c, start, end)
6463 char c;
6464 int start,end;
6465 {
6466     int i;
6467
6468     for (i = start; i <= end; i++)
6469         if (Cmd.spkeys[i] == c)
6470             return i;
6471     return NHKF_ESC;
6472 }
6473
6474 void
6475 rhack(cmd)
6476 register char *cmd;
6477 {
6478     int spkey;
6479     boolean prefix_seen, bad_command,
6480         firsttime = (cmd == 0);
6481
6482     iflags.menu_requested = FALSE;
6483 #ifdef SAFERHANGUP
6484     if (program_state.done_hup)
6485         end_of_input();
6486 #endif
6487     if (firsttime) {
6488         context.nopick = 0;
6489         cmd = parse();
6490     }
6491     if (*cmd == Cmd.spkeys[NHKF_ESC]) {
6492         context.move = FALSE;
6493         return;
6494     }
6495     if (*cmd == DOAGAIN && !in_doagain && saveq[0]) {
6496         in_doagain = TRUE;
6497         stail = 0;
6498         rhack((char *) 0); /* read and execute command */
6499         in_doagain = FALSE;
6500         return;
6501     }
6502     /* Special case of *cmd == ' ' handled better below */
6503     if (!*cmd || *cmd == (char) 0377) {
6504         nhbell();
6505         context.move = FALSE;
6506         return; /* probably we just had an interrupt */
6507     }
6508
6509     /* handle most movement commands */
6510     prefix_seen = FALSE;
6511     context.travel = context.travel1 = 0;
6512     spkey = ch2spkeys(*cmd, NHKF_RUN, NHKF_CLICKLOOK);
6513
6514     switch (spkey) {
6515     case NHKF_RUSH:
6516         if (movecmd(cmd[1])) {
6517             context.run = 2;
6518             domove_attempting |= DOMOVE_RUSH;
6519         } else
6520             prefix_seen = TRUE;
6521         break;
6522     case NHKF_RUN2:
6523         if (!Cmd.num_pad)
6524             break;
6525         /*FALLTHRU*/
6526     case NHKF_RUN:
6527         if (movecmd(lowc(cmd[1]))) {
6528             context.run = 3;
6529             domove_attempting |= DOMOVE_RUSH;
6530         } else
6531             prefix_seen = TRUE;
6532         break;
6533     case NHKF_FIGHT2:
6534         if (!Cmd.num_pad)
6535             break;
6536         /*FALLTHRU*/
6537     /* Effects of movement commands and invisible monsters:
6538      * m: always move onto space (even if 'I' remembered)
6539      * F: always attack space (even if 'I' not remembered)
6540      * normal movement: attack if 'I', move otherwise.
6541      */
6542     case NHKF_FIGHT:
6543         if (movecmd(cmd[1])) {
6544             context.forcefight = 1;
6545             domove_attempting |= DOMOVE_WALK;
6546         } else
6547             prefix_seen = TRUE;
6548         break;
6549     case NHKF_NOPICKUP:
6550         if (movecmd(cmd[1]) || u.dz) {
6551             context.run = 0;
6552             context.nopick = 1;
6553             if (!u.dz)
6554                 domove_attempting |= DOMOVE_WALK;
6555             else
6556                 cmd[0] = cmd[1]; /* "m<" or "m>" */
6557         } else
6558             prefix_seen = TRUE;
6559         break;
6560     case NHKF_RUN_NOPICKUP:
6561         if (movecmd(lowc(cmd[1]))) {
6562             context.run = 1;
6563             context.nopick = 1;
6564             domove_attempting |= DOMOVE_RUSH;
6565         } else
6566             prefix_seen = TRUE;
6567         break;
6568     case NHKF_DOINV:
6569         if (!Cmd.num_pad)
6570             break;
6571         (void) ddoinv(); /* a convenience borrowed from the PC */
6572         context.move = FALSE;
6573         multi = 0;
6574         return;
6575     case NHKF_CLICKLOOK:
6576         if (iflags.clicklook) {
6577             context.move = FALSE;
6578             do_look(2, &clicklook_cc);
6579         }
6580         return;
6581     case NHKF_TRAVEL:
6582         if (flags.travelcmd) {
6583             context.travel = 1;
6584             context.travel1 = 1;
6585             context.run = 8;
6586             context.nopick = 1;
6587             domove_attempting |= DOMOVE_RUSH;
6588             break;
6589         }
6590         /*FALLTHRU*/
6591     default:
6592         if (movecmd(*cmd)) { /* ordinary movement */
6593             context.run = 0; /* only matters here if it was 8 */
6594             domove_attempting |= DOMOVE_WALK;
6595         } else if (movecmd(Cmd.num_pad ? unmeta(*cmd) : lowc(*cmd))) {
6596             context.run = 1;
6597             domove_attempting |= DOMOVE_RUSH;
6598         } else if (movecmd(unctrl(*cmd))) {
6599             context.run = 3;
6600             domove_attempting |= DOMOVE_RUSH;
6601         }
6602         break;
6603     }
6604
6605     /* some special prefix handling */
6606     /* overload 'm' prefix to mean "request a menu" */
6607     if (prefix_seen && cmd[0] == Cmd.spkeys[NHKF_REQMENU]) {
6608         /* (for func_tab cast, see below) */
6609         const struct ext_func_tab *ft = Cmd.commands[cmd[1] & 0xff];
6610         int NDECL((*func)) = ft ? ((struct ext_func_tab *) ft)->ef_funct : 0;
6611
6612         if (func && accept_menu_prefix(func)) {
6613             iflags.menu_requested = TRUE;
6614             ++cmd;
6615         }
6616     }
6617
6618     if (((domove_attempting & (DOMOVE_RUSH | DOMOVE_WALK)) != 0L)
6619                             && !context.travel && !dxdy_moveok()) {
6620         /* trying to move diagonally as a grid bug;
6621            this used to be treated by movecmd() as not being
6622            a movement attempt, but that didn't provide for any
6623            feedback and led to strangeness if the key pressed
6624            ('u' in particular) was overloaded for num_pad use */
6625 /*JP
6626         You_cant("get there from here...");
6627 */
6628         You_cant("\82±\82±\82©\82ç\82»\82±\82Ö\82Í\8ds\82¯\82Ü\82¹\82ñ\81D\81D\81D");
6629         context.run = 0;
6630         context.nopick = context.forcefight = FALSE;
6631         context.move = context.mv = FALSE;
6632         multi = 0;
6633         return;
6634     }
6635
6636     if ((domove_attempting & DOMOVE_WALK) != 0L) {
6637         if (multi)
6638             context.mv = TRUE;
6639         domove();
6640         context.forcefight = 0;
6641         return;
6642     } else if ((domove_attempting & DOMOVE_RUSH) != 0L) {
6643         if (firsttime) {
6644             if (!multi)
6645                 multi = max(COLNO, ROWNO);
6646             u.last_str_turn = 0;
6647         }
6648         context.mv = TRUE;
6649         domove();
6650         return;
6651     } else if (prefix_seen && cmd[1] == Cmd.spkeys[NHKF_ESC]) {
6652         /* <prefix><escape> */
6653         /* don't report "unknown command" for change of heart... */
6654         bad_command = FALSE;
6655     } else if (*cmd == ' ' && !flags.rest_on_space) {
6656         bad_command = TRUE; /* skip cmdlist[] loop */
6657
6658     /* handle all other commands */
6659     } else {
6660         register const struct ext_func_tab *tlist;
6661         int res, NDECL((*func));
6662
6663         /* current - use *cmd to directly index cmdlist array */
6664         if ((tlist = Cmd.commands[*cmd & 0xff]) != 0) {
6665             if (!wizard && (tlist->flags & WIZMODECMD)) {
6666 /*JP
6667                 You_cant("do that!");
6668 */
6669                 pline("\82»\82ê\82Í\82Å\82«\82Ü\82¹\82ñ\81I");
6670                 res = 0;
6671             } else if (u.uburied && !(tlist->flags & IFBURIED)) {
6672 /*JP
6673                 You_cant("do that while you are buried!");
6674 */
6675                 You("\96\84\82Ü\82Á\82Ä\82¢\82é\8e\9e\82É\82»\82ñ\82È\82±\82Æ\82Í\82Å\82«\82È\82¢\81I");
6676                 res = 0;
6677             } else {
6678                 /* we discard 'const' because some compilers seem to have
6679                    trouble with the pointer passed to set_occupation() */
6680                 func = ((struct ext_func_tab *) tlist)->ef_funct;
6681                 if (tlist->f_text && !occupation && multi)
6682                     set_occupation(func, tlist->f_text, multi);
6683                 res = (*func)(); /* perform the command */
6684             }
6685             if (!res) {
6686                 context.move = FALSE;
6687                 multi = 0;
6688             }
6689             return;
6690         }
6691         /* if we reach here, cmd wasn't found in cmdlist[] */
6692         bad_command = TRUE;
6693     }
6694
6695     if (bad_command) {
6696         char expcmd[20]; /* we expect 'cmd' to point to 1 or 2 chars */
6697         char c, c1 = cmd[1];
6698
6699         expcmd[0] = '\0';
6700         while ((c = *cmd++) != '\0')
6701             Strcat(expcmd, visctrl(c)); /* add 1..4 chars plus terminator */
6702
6703 /*JP
6704         if (!prefix_seen || !help_dir(c1, spkey, "Invalid direction key!"))
6705 */
6706         if (!prefix_seen || !help_dir(c1, spkey, "\96³\8cø\82È\95û\8cü\8ew\92è\82Å\82·\81I"))
6707 /*JP
6708             Norep("Unknown command '%s'.", expcmd);
6709 */
6710             Norep("'%s'\83R\83}\83\93\83h\81H", expcmd);
6711     }
6712     /* didn't move */
6713     context.move = FALSE;
6714     multi = 0;
6715     return;
6716 }
6717
6718 /* convert an x,y pair into a direction code */
6719 int
6720 xytod(x, y)
6721 schar x, y;
6722 {
6723     register int dd;
6724
6725     for (dd = 0; dd < 8; dd++)
6726         if (x == xdir[dd] && y == ydir[dd])
6727             return dd;
6728     return -1;
6729 }
6730
6731 /* convert a direction code into an x,y pair */
6732 void
6733 dtoxy(cc, dd)
6734 coord *cc;
6735 register int dd;
6736 {
6737     cc->x = xdir[dd];
6738     cc->y = ydir[dd];
6739     return;
6740 }
6741
6742 /* also sets u.dz, but returns false for <> */
6743 int
6744 movecmd(sym)
6745 char sym;
6746 {
6747     register const char *dp = index(Cmd.dirchars, sym);
6748
6749     u.dz = 0;
6750     if (!dp || !*dp)
6751         return 0;
6752     u.dx = xdir[dp - Cmd.dirchars];
6753     u.dy = ydir[dp - Cmd.dirchars];
6754     u.dz = zdir[dp - Cmd.dirchars];
6755 #if 0 /* now handled elsewhere */
6756     if (u.dx && u.dy && NODIAG(u.umonnum)) {
6757         u.dx = u.dy = 0;
6758         return 0;
6759     }
6760 #endif
6761     return !u.dz;
6762 }
6763
6764 /* grid bug handling which used to be in movecmd() */
6765 int
6766 dxdy_moveok()
6767 {
6768     if (u.dx && u.dy && NODIAG(u.umonnum))
6769         u.dx = u.dy = 0;
6770     return u.dx || u.dy;
6771 }
6772
6773 /* decide whether a character (user input keystroke) requests screen repaint */
6774 boolean
6775 redraw_cmd(c)
6776 char c;
6777 {
6778     return (boolean) (c == Cmd.spkeys[NHKF_REDRAW]
6779                       || (Cmd.num_pad && c == Cmd.spkeys[NHKF_REDRAW2]));
6780 }
6781
6782 boolean
6783 prefix_cmd(c)
6784 char c;
6785 {
6786     return (c == Cmd.spkeys[NHKF_RUSH]
6787             || c == Cmd.spkeys[NHKF_RUN]
6788             || c == Cmd.spkeys[NHKF_NOPICKUP]
6789             || c == Cmd.spkeys[NHKF_RUN_NOPICKUP]
6790             || c == Cmd.spkeys[NHKF_FIGHT]
6791             || (Cmd.num_pad && (c == Cmd.spkeys[NHKF_RUN2]
6792                                 || c == Cmd.spkeys[NHKF_FIGHT2])));
6793 }
6794
6795 /*
6796  * uses getdir() but unlike getdir() it specifically
6797  * produces coordinates using the direction from getdir()
6798  * and verifies that those coordinates are ok.
6799  *
6800  * If the call to getdir() returns 0, Never_mind is displayed.
6801  * If the resulting coordinates are not okay, emsg is displayed.
6802  *
6803  * Returns non-zero if coordinates in cc are valid.
6804  */
6805 int
6806 get_adjacent_loc(prompt, emsg, x, y, cc)
6807 const char *prompt, *emsg;
6808 xchar x, y;
6809 coord *cc;
6810 {
6811     xchar new_x, new_y;
6812     if (!getdir(prompt)) {
6813         pline1(Never_mind);
6814         return 0;
6815     }
6816     new_x = x + u.dx;
6817     new_y = y + u.dy;
6818     if (cc && isok(new_x, new_y)) {
6819         cc->x = new_x;
6820         cc->y = new_y;
6821     } else {
6822         if (emsg)
6823             pline1(emsg);
6824         return 0;
6825     }
6826     return 1;
6827 }
6828
6829 int
6830 getdir(s)
6831 const char *s;
6832 {
6833     char dirsym;
6834     int is_mov;
6835
6836  retry:
6837     if (in_doagain || *readchar_queue)
6838         dirsym = readchar();
6839     else
6840 /*JP
6841         dirsym = yn_function((s && *s != '^') ? s : "In what direction?",
6842 */
6843         dirsym = yn_function((s && *s != '^') ? s : "\82Ç\82Ì\95û\8cü\81H",
6844                              (char *) 0, '\0');
6845     /* remove the prompt string so caller won't have to */
6846     clear_nhwindow(WIN_MESSAGE);
6847
6848     if (redraw_cmd(dirsym)) { /* ^R */
6849         docrt();              /* redraw */
6850         goto retry;
6851     }
6852     savech(dirsym);
6853
6854     if (dirsym == Cmd.spkeys[NHKF_GETDIR_SELF]
6855         || dirsym == Cmd.spkeys[NHKF_GETDIR_SELF2]) {
6856         u.dx = u.dy = u.dz = 0;
6857     } else if (!(is_mov = movecmd(dirsym)) && !u.dz) {
6858         boolean did_help = FALSE, help_requested;
6859
6860         if (!index(quitchars, dirsym)) {
6861             help_requested = (dirsym == Cmd.spkeys[NHKF_GETDIR_HELP]);
6862             if (help_requested || iflags.cmdassist) {
6863                 did_help = help_dir((s && *s == '^') ? dirsym : '\0',
6864                                     NHKF_ESC,
6865                                     help_requested ? (const char *) 0
6866 /*JP
6867                                                   : "Invalid direction key!");
6868 */
6869                                                   : "\96³\8cø\82È\95û\8cü\8ew\92è\82Å\82·\81I");
6870                 if (help_requested)
6871                     goto retry;
6872             }
6873             if (!did_help)
6874 /*JP
6875                 pline("What a strange direction!");
6876 */
6877                 pline("\82¸\82¢\82Ô\82ñ\82Æ\8aï\96­\82È\95û\8cü\82¾\81I");
6878         }
6879         return 0;
6880     } else if (is_mov && !dxdy_moveok()) {
6881 /*JP
6882         You_cant("orient yourself that direction.");
6883 */
6884         You_cant("\8cü\82«\82É\8e©\95ª\8e©\90g\82ð\8ew\92è\82Å\82«\82È\82¢\81D");
6885         return 0;
6886     }
6887     if (!u.dz && (Stunned || (Confusion && !rn2(5))))
6888         confdir();
6889     return 1;
6890 }
6891
6892 STATIC_OVL void
6893 show_direction_keys(win, centerchar, nodiag)
6894 winid win; /* should specify a window which is using a fixed-width font... */
6895 char centerchar; /* '.' or '@' or ' ' */
6896 boolean nodiag;
6897 {
6898     char buf[BUFSZ];
6899
6900     if (!centerchar)
6901         centerchar = ' ';
6902
6903     if (nodiag) {
6904         Sprintf(buf, "             %c   ", Cmd.move_N);
6905         putstr(win, 0, buf);
6906         putstr(win, 0, "             |   ");
6907         Sprintf(buf, "          %c- %c -%c",
6908                 Cmd.move_W, centerchar, Cmd.move_E);
6909         putstr(win, 0, buf);
6910         putstr(win, 0, "             |   ");
6911         Sprintf(buf, "             %c   ", Cmd.move_S);
6912         putstr(win, 0, buf);
6913     } else {
6914         Sprintf(buf, "          %c  %c  %c",
6915                 Cmd.move_NW, Cmd.move_N, Cmd.move_NE);
6916         putstr(win, 0, buf);
6917         putstr(win, 0, "           \\ | / ");
6918         Sprintf(buf, "          %c- %c -%c",
6919                 Cmd.move_W, centerchar, Cmd.move_E);
6920         putstr(win, 0, buf);
6921         putstr(win, 0, "           / | \\ ");
6922         Sprintf(buf, "          %c  %c  %c",
6923                 Cmd.move_SW, Cmd.move_S, Cmd.move_SE);
6924         putstr(win, 0, buf);
6925     };
6926 }
6927
6928 /* explain choices if player has asked for getdir() help or has given
6929    an invalid direction after a prefix key ('F', 'g', 'm', &c), which
6930    might be bogus but could be up, down, or self when not applicable */
6931 STATIC_OVL boolean
6932 help_dir(sym, spkey, msg)
6933 char sym;
6934 int spkey; /* NHKF_ code for prefix key, if one was used, or for ESC */
6935 const char *msg;
6936 {
6937     static const char wiz_only_list[] = "EFGIVW";
6938     char ctrl;
6939     winid win;
6940     char buf[BUFSZ], buf2[BUFSZ], *explain;
6941     const char *dothat, *how;
6942     boolean prefixhandling, viawindow;
6943
6944     /* NHKF_ESC indicates that player asked for help at getdir prompt */
6945     viawindow = (spkey == NHKF_ESC || iflags.cmdassist);
6946     prefixhandling = (spkey != NHKF_ESC);
6947     /*
6948      * Handling for prefix keys that don't want special directions.
6949      * Delivered via pline if 'cmdassist' is off, or instead of the
6950      * general message if it's on.
6951      */
6952     dothat = "do that";
6953 #if 0 /*JP*/
6954     how = " at"; /* for "<action> at yourself"; not used for up/down */
6955 #else
6956     how = "";
6957 #endif
6958     switch (spkey) {
6959     case NHKF_NOPICKUP:
6960 #if 0 /*JP*/
6961         dothat = "move";
6962 #else
6963         dothat = "\88Ú\93®\82·\82é";
6964 #endif
6965         break;
6966     case NHKF_RUSH:
6967 #if 0 /*JP*/
6968         dothat = "rush";
6969 #else
6970         dothat = "\93Ë\90i\82·\82é";
6971 #endif
6972         break;
6973     case NHKF_RUN2:
6974         if (!Cmd.num_pad)
6975             break;
6976         /*FALLTHRU*/
6977     case NHKF_RUN:
6978     case NHKF_RUN_NOPICKUP:
6979 #if 0 /*JP*/
6980         dothat = "run";
6981 #else
6982         dothat = "\91\96\82é";
6983 #endif
6984         break;
6985     case NHKF_FIGHT2:
6986         if (!Cmd.num_pad)
6987             break;
6988         /*FALLTHRU*/
6989     case NHKF_FIGHT:
6990 #if 0 /*JP*/
6991         dothat = "fight";
6992 #else
6993         dothat = "\90í\82¤";
6994 #endif
6995         how = ""; /* avoid "fight at yourself" */
6996         break;
6997     default:
6998         prefixhandling = FALSE;
6999         break;
7000     }
7001
7002     buf[0] = '\0';
7003     /* for movement prefix followed by '.' or (numpad && 's') to mean 'self';
7004        note: '-' for hands (inventory form of 'self') is not handled here */
7005     if (prefixhandling
7006         && (sym == Cmd.spkeys[NHKF_GETDIR_SELF]
7007             || (Cmd.num_pad && sym == Cmd.spkeys[NHKF_GETDIR_SELF2]))) {
7008 /*JP
7009         Sprintf(buf, "You can't %s%s yourself.", dothat, how);
7010 */
7011         Sprintf(buf, "\8e©\95ª\8e©\90g\82É%s%s\82±\82Æ\82Í\82Å\82«\82È\82¢\81D", dothat, how);
7012     /* for movement prefix followed by up or down */
7013     } else if (prefixhandling && (sym == '<' || sym == '>')) {
7014 #if 0 /*JP*/
7015         Sprintf(buf, "You can't %s %s.", dothat,
7016                 /* was "upwards" and "downwards", but they're considered
7017                    to be variants of canonical "upward" and "downward" */
7018                 (sym == '<') ? "upward" : "downward");
7019 #else
7020         Sprintf(buf, "%s%s\82±\82Æ\82Í\82Å\82«\82È\82¢\81D",
7021                 (sym == '<') ? "\8fã\95û\8cü\82É" : "\89º\95û\8cü\82É", dothat);
7022 #endif
7023     }
7024
7025     /* if '!cmdassist', display via pline() and we're done (note: asking
7026        for help at getdir() prompt forces cmdassist for this operation) */
7027     if (!viawindow) {
7028         if (prefixhandling) {
7029             if (!*buf)
7030 #if 0 /*JP*/
7031                 Sprintf(buf, "Invalid direction for '%s' prefix.",
7032                         visctrl(Cmd.spkeys[spkey]));
7033 #else
7034                 Sprintf(buf, "'%s'\90Ú\93ª\8e«\82É\82Í\95s\90³\82È\95û\8cü\81D",
7035                         visctrl(Cmd.spkeys[spkey]));
7036 #endif
7037             pline("%s", buf);
7038             return TRUE;
7039         }
7040         /* when 'cmdassist' is off and caller doesn't insist, do nothing */
7041         return FALSE;
7042     }
7043
7044     win = create_nhwindow(NHW_TEXT);
7045     if (!win)
7046         return FALSE;
7047
7048     if (*buf) {
7049         /* show bad-prefix message instead of general invalid-direction one */
7050         putstr(win, 0, buf);
7051         putstr(win, 0, "");
7052     } else if (msg) {
7053         Sprintf(buf, "cmdassist: %s", msg);
7054         putstr(win, 0, buf);
7055         putstr(win, 0, "");
7056     }
7057
7058     if (!prefixhandling && (letter(sym) || sym == '[')) {
7059         /* '[': old 'cmdhelp' showed ESC as ^[ */
7060         sym = highc(sym); /* @A-Z[ (note: letter() accepts '@') */
7061         ctrl = (sym - 'A') + 1; /* 0-27 (note: 28-31 aren't applicable) */
7062         if ((explain = dowhatdoes_core(ctrl, buf2)) != 0
7063             && (!index(wiz_only_list, sym) || wizard)) {
7064             Sprintf(buf, "Are you trying to use ^%c%s?", sym,
7065                     index(wiz_only_list, sym) ? ""
7066                         : " as specified in the Guidebook");
7067             putstr(win, 0, buf);
7068             putstr(win, 0, "");
7069             putstr(win, 0, explain);
7070             putstr(win, 0, "");
7071             putstr(win, 0,
7072                   "To use that command, hold down the <Ctrl> key as a shift");
7073             Sprintf(buf, "and press the <%c> key.", sym);
7074             putstr(win, 0, buf);
7075             putstr(win, 0, "");
7076         }
7077     }
7078
7079 #if 0 /*JP:T*/
7080     Sprintf(buf, "Valid direction keys%s%s%s are:",
7081             prefixhandling ? " to " : "", prefixhandling ? dothat : "",
7082             NODIAG(u.umonnum) ? " in your current form" : "");
7083 #else
7084     Sprintf(buf, "%s%s%s\97L\8cø\82È\95û\8cü\8ew\92è\82Í:",
7085             prefixhandling ? dothat : "", prefixhandling ? "\82½\82ß\82Ì" : "",
7086             NODIAG(u.umonnum) ? " \8c»\8dÝ\82Ì\8ep\82Å\82Ì" : "");
7087 #endif
7088     putstr(win, 0, buf);
7089     show_direction_keys(win, !prefixhandling ? '.' : ' ', NODIAG(u.umonnum));
7090
7091     if (!prefixhandling || spkey == NHKF_NOPICKUP) {
7092         /* NOPICKUP: unlike the other prefix keys, 'm' allows up/down for
7093            stair traversal; we won't get here when "m<" or "m>" has been
7094            given but we include up and down for 'm'+invalid_direction;
7095            self is excluded as a viable direction for every prefix */
7096         putstr(win, 0, "");
7097 /*JP
7098         putstr(win, 0, "          <  up");
7099 */
7100         putstr(win, 0, "          <  \8fã");
7101 /*JP
7102         putstr(win, 0, "          >  down");
7103 */
7104         putstr(win, 0, "          >  \89º");
7105         if (!prefixhandling) {
7106             int selfi = Cmd.num_pad ? NHKF_GETDIR_SELF2 : NHKF_GETDIR_SELF;
7107
7108 #if 0 /*JP:T*/
7109             Sprintf(buf,   "       %4s  direct at yourself",
7110                     visctrl(Cmd.spkeys[selfi]));
7111 #else
7112             Sprintf(buf,   "       %4s  \8e©\95ª\82É\8cü\82¯\82é",
7113                     visctrl(Cmd.spkeys[selfi]));
7114 #endif
7115             putstr(win, 0, buf);
7116         }
7117     }
7118
7119     if (msg) {
7120         /* non-null msg means that this wasn't an explicit user request */
7121         putstr(win, 0, "");
7122         putstr(win, 0,
7123 /*JP
7124                "(Suppress this message with !cmdassist in config file.)");
7125 */
7126                "(\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)");
7127     }
7128     display_nhwindow(win, FALSE);
7129     destroy_nhwindow(win);
7130     return TRUE;
7131 }
7132
7133 void
7134 confdir()
7135 {
7136     register int x = NODIAG(u.umonnum) ? 2 * rn2(4) : rn2(8);
7137
7138     u.dx = xdir[x];
7139     u.dy = ydir[x];
7140     return;
7141 }
7142
7143 const char *
7144 directionname(dir)
7145 int dir;
7146 {
7147     static NEARDATA const char *const dirnames[] = {
7148         "west",      "northwest", "north",     "northeast", "east",
7149         "southeast", "south",     "southwest", "down",      "up",
7150     };
7151
7152     if (dir < 0 || dir >= SIZE(dirnames))
7153         return "invalid";
7154     return dirnames[dir];
7155 }
7156
7157 int
7158 isok(x, y)
7159 register int x, y;
7160 {
7161     /* x corresponds to curx, so x==1 is the first column. Ach. %% */
7162     return x >= 1 && x <= COLNO - 1 && y >= 0 && y <= ROWNO - 1;
7163 }
7164
7165 /* #herecmdmenu command */
7166 STATIC_PTR int
7167 doherecmdmenu(VOID_ARGS)
7168 {
7169     char ch = here_cmd_menu(TRUE);
7170
7171     return ch ? 1 : 0;
7172 }
7173
7174 /* #therecmdmenu command, a way to test there_cmd_menu without mouse */
7175 STATIC_PTR int
7176 dotherecmdmenu(VOID_ARGS)
7177 {
7178     char ch;
7179
7180     if (!getdir((const char *) 0) || !isok(u.ux + u.dx, u.uy + u.dy))
7181         return 0;
7182
7183     if (u.dx || u.dy)
7184         ch = there_cmd_menu(TRUE, u.ux + u.dx, u.uy + u.dy);
7185     else
7186         ch = here_cmd_menu(TRUE);
7187
7188     return ch ? 1 : 0;
7189 }
7190
7191 STATIC_OVL void
7192 add_herecmd_menuitem(win, func, text)
7193 winid win;
7194 int NDECL((*func));
7195 const char *text;
7196 {
7197     char ch;
7198     anything any;
7199
7200     if ((ch = cmd_from_func(func)) != '\0') {
7201         any = zeroany;
7202         any.a_nfunc = func;
7203         add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, text, MENU_UNSELECTED);
7204     }
7205 }
7206
7207 STATIC_OVL char
7208 there_cmd_menu(doit, x, y)
7209 boolean doit;
7210 int x, y;
7211 {
7212     winid win;
7213     char ch;
7214     char buf[BUFSZ];
7215     schar typ = levl[x][y].typ;
7216     int npick, K = 0;
7217     menu_item *picks = (menu_item *) 0;
7218     struct trap *ttmp;
7219     struct monst *mtmp;
7220
7221     win = create_nhwindow(NHW_MENU);
7222     start_menu(win);
7223
7224     if (IS_DOOR(typ)) {
7225         boolean key_or_pick, card;
7226         int dm = levl[x][y].doormask;
7227
7228         if ((dm & (D_CLOSED | D_LOCKED))) {
7229             add_herecmd_menuitem(win, doopen, "Open the door"), ++K;
7230             /* unfortunately there's no lknown flag for doors to
7231                remember the locked/unlocked state */
7232             key_or_pick = (carrying(SKELETON_KEY) || carrying(LOCK_PICK));
7233             card = (carrying(CREDIT_CARD) != 0);
7234             if (key_or_pick || card) {
7235                 Sprintf(buf, "%sunlock the door",
7236                         key_or_pick ? "lock or " : "");
7237                 add_herecmd_menuitem(win, doapply, upstart(buf)), ++K;
7238             }
7239             /* unfortunately there's no tknown flag for doors (or chests)
7240                to remember whether a trap had been found */
7241             add_herecmd_menuitem(win, dountrap,
7242                                  "Search the door for a trap"), ++K;
7243             /* [what about #force?] */
7244             add_herecmd_menuitem(win, dokick, "Kick the door"), ++K;
7245         } else if ((dm & D_ISOPEN)) {
7246             add_herecmd_menuitem(win, doclose, "Close the door"), ++K;
7247         }
7248     }
7249
7250     if (typ <= SCORR)
7251         add_herecmd_menuitem(win, dosearch, "Search for secret doors"), ++K;
7252
7253     if ((ttmp = t_at(x, y)) != 0 && ttmp->tseen) {
7254         add_herecmd_menuitem(win, doidtrap, "Examine trap"), ++K;
7255         if (ttmp->ttyp != VIBRATING_SQUARE)
7256             add_herecmd_menuitem(win, dountrap, "Attempt to disarm trap"), ++K;
7257     }
7258
7259     mtmp = m_at(x, y);
7260     if (mtmp && !canspotmon(mtmp))
7261         mtmp = 0;
7262     if (mtmp && which_armor(mtmp, W_SADDLE)) {
7263         char *mnam = x_monnam(mtmp, ARTICLE_THE, (char *) 0,
7264                               SUPPRESS_SADDLE, FALSE);
7265
7266         if (!u.usteed) {
7267             Sprintf(buf, "Ride %s", mnam);
7268             add_herecmd_menuitem(win, doride, buf), ++K;
7269         }
7270         Sprintf(buf, "Remove saddle from %s", mnam);
7271         add_herecmd_menuitem(win, doloot, buf), ++K;
7272     }
7273     if (mtmp && can_saddle(mtmp) && !which_armor(mtmp, W_SADDLE)
7274         && carrying(SADDLE)) {
7275         Sprintf(buf, "Put saddle on %s", mon_nam(mtmp)), ++K;
7276         add_herecmd_menuitem(win, doapply, buf);
7277     }
7278 #if 0
7279     if (mtmp || glyph_is_invisible(glyph_at(x, y))) {
7280         /* "Attack %s", mtmp ? mon_nam(mtmp) : "unseen creature" */
7281     } else {
7282         /* "Move %s", direction */
7283     }
7284 #endif
7285
7286     if (K) {
7287         end_menu(win, "What do you want to do?");
7288         npick = select_menu(win, PICK_ONE, &picks);
7289     } else {
7290         pline("No applicable actions.");
7291         npick = 0;
7292     }
7293     destroy_nhwindow(win);
7294     ch = '\0';
7295     if (npick > 0) {
7296         int NDECL((*func)) = picks->item.a_nfunc;
7297         free((genericptr_t) picks);
7298
7299         if (doit) {
7300             int ret = (*func)();
7301
7302             ch = (char) ret;
7303         } else {
7304             ch = cmd_from_func(func);
7305         }
7306     }
7307     return ch;
7308 }
7309
7310 STATIC_OVL char
7311 here_cmd_menu(doit)
7312 boolean doit;
7313 {
7314     winid win;
7315     char ch;
7316     char buf[BUFSZ];
7317     schar typ = levl[u.ux][u.uy].typ;
7318     int npick;
7319     menu_item *picks = (menu_item *) 0;
7320
7321     win = create_nhwindow(NHW_MENU);
7322     start_menu(win);
7323
7324     if (IS_FOUNTAIN(typ) || IS_SINK(typ)) {
7325         Sprintf(buf, "Drink from the %s",
7326                 defsyms[IS_FOUNTAIN(typ) ? S_fountain : S_sink].explanation);
7327         add_herecmd_menuitem(win, dodrink, buf);
7328     }
7329     if (IS_FOUNTAIN(typ))
7330         add_herecmd_menuitem(win, dodip,
7331                              "Dip something into the fountain");
7332     if (IS_THRONE(typ))
7333         add_herecmd_menuitem(win, dosit,
7334                              "Sit on the throne");
7335
7336     if ((u.ux == xupstair && u.uy == yupstair)
7337         || (u.ux == sstairs.sx && u.uy == sstairs.sy && sstairs.up)
7338         || (u.ux == xupladder && u.uy == yupladder)) {
7339         Sprintf(buf, "Go up the %s",
7340                 (u.ux == xupladder && u.uy == yupladder)
7341                 ? "ladder" : "stairs");
7342         add_herecmd_menuitem(win, doup, buf);
7343     }
7344     if ((u.ux == xdnstair && u.uy == ydnstair)
7345         || (u.ux == sstairs.sx && u.uy == sstairs.sy && !sstairs.up)
7346         || (u.ux == xdnladder && u.uy == ydnladder)) {
7347         Sprintf(buf, "Go down the %s",
7348                 (u.ux == xupladder && u.uy == yupladder)
7349                 ? "ladder" : "stairs");
7350         add_herecmd_menuitem(win, dodown, buf);
7351     }
7352     if (u.usteed) { /* another movement choice */
7353         Sprintf(buf, "Dismount %s",
7354                 x_monnam(u.usteed, ARTICLE_THE, (char *) 0,
7355                          SUPPRESS_SADDLE, FALSE));
7356         add_herecmd_menuitem(win, doride, buf);
7357     }
7358
7359 #if 0
7360     if (Upolyd) { /* before objects */
7361         Sprintf(buf, "Use %s special ability",
7362                 s_suffix(mons[u.umonnum].mname));
7363         add_herecmd_menuitem(win, domonability, buf);
7364     }
7365 #endif
7366
7367     if (OBJ_AT(u.ux, u.uy)) {
7368         struct obj *otmp = level.objects[u.ux][u.uy];
7369
7370         Sprintf(buf, "Pick up %s", otmp->nexthere ? "items" : doname(otmp));
7371         add_herecmd_menuitem(win, dopickup, buf);
7372
7373         if (Is_container(otmp)) {
7374             Sprintf(buf, "Loot %s", doname(otmp));
7375             add_herecmd_menuitem(win, doloot, buf);
7376         }
7377         if (otmp->oclass == FOOD_CLASS) {
7378             Sprintf(buf, "Eat %s", doname(otmp));
7379             add_herecmd_menuitem(win, doeat, buf);
7380         }
7381     }
7382
7383     if (invent)
7384         add_herecmd_menuitem(win, dodrop, "Drop items");
7385
7386     add_herecmd_menuitem(win, donull, "Rest one turn");
7387     add_herecmd_menuitem(win, dosearch, "Search around you");
7388     add_herecmd_menuitem(win, dolook, "Look at what is here");
7389
7390     end_menu(win, "What do you want to do?");
7391     npick = select_menu(win, PICK_ONE, &picks);
7392     destroy_nhwindow(win);
7393     ch = '\0';
7394     if (npick > 0) {
7395         int NDECL((*func)) = picks->item.a_nfunc;
7396         free((genericptr_t) picks);
7397
7398         if (doit) {
7399             int ret = (*func)();
7400
7401             ch = (char) ret;
7402         } else {
7403             ch = cmd_from_func(func);
7404         }
7405     }
7406     return ch;
7407 }
7408
7409
7410 static NEARDATA int last_multi;
7411
7412 /*
7413  * convert a MAP window position into a movecmd
7414  */
7415 const char *
7416 click_to_cmd(x, y, mod)
7417 int x, y, mod;
7418 {
7419     int dir;
7420     static char cmd[4];
7421     cmd[1] = 0;
7422
7423     if (iflags.clicklook && mod == CLICK_2) {
7424         clicklook_cc.x = x;
7425         clicklook_cc.y = y;
7426         cmd[0] = Cmd.spkeys[NHKF_CLICKLOOK];
7427         return cmd;
7428     }
7429
7430     x -= u.ux;
7431     y -= u.uy;
7432
7433     if (flags.travelcmd) {
7434         if (abs(x) <= 1 && abs(y) <= 1) {
7435             x = sgn(x), y = sgn(y);
7436         } else {
7437             u.tx = u.ux + x;
7438             u.ty = u.uy + y;
7439             cmd[0] = Cmd.spkeys[NHKF_TRAVEL];
7440             return cmd;
7441         }
7442
7443         if (x == 0 && y == 0) {
7444             if (iflags.herecmd_menu) {
7445                 cmd[0] = here_cmd_menu(FALSE);
7446                 return cmd;
7447             }
7448
7449             /* here */
7450             if (IS_FOUNTAIN(levl[u.ux][u.uy].typ)
7451                 || IS_SINK(levl[u.ux][u.uy].typ)) {
7452                 cmd[0] = cmd_from_func(mod == CLICK_1 ? dodrink : dodip);
7453                 return cmd;
7454             } else if (IS_THRONE(levl[u.ux][u.uy].typ)) {
7455                 cmd[0] = cmd_from_func(dosit);
7456                 return cmd;
7457             } else if ((u.ux == xupstair && u.uy == yupstair)
7458                        || (u.ux == sstairs.sx && u.uy == sstairs.sy
7459                            && sstairs.up)
7460                        || (u.ux == xupladder && u.uy == yupladder)) {
7461                 cmd[0] = cmd_from_func(doup);
7462                 return cmd;
7463             } else if ((u.ux == xdnstair && u.uy == ydnstair)
7464                        || (u.ux == sstairs.sx && u.uy == sstairs.sy
7465                            && !sstairs.up)
7466                        || (u.ux == xdnladder && u.uy == ydnladder)) {
7467                 cmd[0] = cmd_from_func(dodown);
7468                 return cmd;
7469             } else if (OBJ_AT(u.ux, u.uy)) {
7470                 cmd[0] = cmd_from_func(Is_container(level.objects[u.ux][u.uy])
7471                                        ? doloot : dopickup);
7472                 return cmd;
7473             } else {
7474                 cmd[0] = cmd_from_func(donull); /* just rest */
7475                 return cmd;
7476             }
7477         }
7478
7479         /* directional commands */
7480
7481         dir = xytod(x, y);
7482
7483         if (!m_at(u.ux + x, u.uy + y)
7484             && !test_move(u.ux, u.uy, x, y, TEST_MOVE)) {
7485             cmd[1] = Cmd.dirchars[dir];
7486             cmd[2] = '\0';
7487             if (iflags.herecmd_menu) {
7488                 cmd[0] = there_cmd_menu(FALSE, u.ux + x, u.uy + y);
7489                 if (cmd[0] == '\0')
7490                     cmd[1] = '\0';
7491                 return cmd;
7492             }
7493
7494             if (IS_DOOR(levl[u.ux + x][u.uy + y].typ)) {
7495                 /* slight assistance to the player: choose kick/open for them
7496                  */
7497                 if (levl[u.ux + x][u.uy + y].doormask & D_LOCKED) {
7498                     cmd[0] = cmd_from_func(dokick);
7499                     return cmd;
7500                 }
7501                 if (levl[u.ux + x][u.uy + y].doormask & D_CLOSED) {
7502                     cmd[0] = cmd_from_func(doopen);
7503                     return cmd;
7504                 }
7505             }
7506             if (levl[u.ux + x][u.uy + y].typ <= SCORR) {
7507                 cmd[0] = cmd_from_func(dosearch);
7508                 cmd[1] = 0;
7509                 return cmd;
7510             }
7511         }
7512     } else {
7513         /* convert without using floating point, allowing sloppy clicking */
7514         if (x > 2 * abs(y))
7515             x = 1, y = 0;
7516         else if (y > 2 * abs(x))
7517             x = 0, y = 1;
7518         else if (x < -2 * abs(y))
7519             x = -1, y = 0;
7520         else if (y < -2 * abs(x))
7521             x = 0, y = -1;
7522         else
7523             x = sgn(x), y = sgn(y);
7524
7525         if (x == 0 && y == 0) {
7526             /* map click on player to "rest" command */
7527             cmd[0] = cmd_from_func(donull);
7528             return cmd;
7529         }
7530         dir = xytod(x, y);
7531     }
7532
7533     /* move, attack, etc. */
7534     cmd[1] = 0;
7535     if (mod == CLICK_1) {
7536         cmd[0] = Cmd.dirchars[dir];
7537     } else {
7538         cmd[0] = (Cmd.num_pad
7539                      ? M(Cmd.dirchars[dir])
7540                      : (Cmd.dirchars[dir] - 'a' + 'A')); /* run command */
7541     }
7542
7543     return cmd;
7544 }
7545
7546 char
7547 get_count(allowchars, inkey, maxcount, count, historical)
7548 char *allowchars;
7549 char inkey;
7550 long maxcount;
7551 long *count;
7552 boolean historical; /* whether to include in message history: True => yes */
7553 {
7554     char qbuf[QBUFSZ];
7555     int key;
7556     long cnt = 0L;
7557     boolean backspaced = FALSE;
7558     /* this should be done in port code so that we have erase_char
7559        and kill_char available; we can at least fake erase_char */
7560 #define STANDBY_erase_char '\177'
7561
7562     for (;;) {
7563         if (inkey) {
7564             key = inkey;
7565             inkey = '\0';
7566         } else
7567             key = readchar();
7568
7569         if (digit(key)) {
7570             cnt = 10L * cnt + (long) (key - '0');
7571             if (cnt < 0)
7572                 cnt = 0;
7573             else if (maxcount > 0 && cnt > maxcount)
7574                 cnt = maxcount;
7575         } else if (cnt && (key == '\b' || key == STANDBY_erase_char)) {
7576             cnt = cnt / 10;
7577             backspaced = TRUE;
7578         } else if (key == Cmd.spkeys[NHKF_ESC]) {
7579             break;
7580         } else if (!allowchars || index(allowchars, key)) {
7581             *count = cnt;
7582             break;
7583         }
7584
7585         if (cnt > 9 || backspaced) {
7586             clear_nhwindow(WIN_MESSAGE);
7587             if (backspaced && !cnt) {
7588 /*JP
7589                 Sprintf(qbuf, "Count: ");
7590 */
7591                 Sprintf(qbuf, "\90\94: ");
7592             } else {
7593 /*JP
7594                 Sprintf(qbuf, "Count: %ld", cnt);
7595 */
7596                 Sprintf(qbuf, "\90\94: %ld", cnt);
7597                 backspaced = FALSE;
7598             }
7599             custompline(SUPPRESS_HISTORY, "%s", qbuf);
7600             mark_synch();
7601         }
7602     }
7603
7604     if (historical) {
7605 /*JP
7606         Sprintf(qbuf, "Count: %ld ", *count);
7607 */
7608         Sprintf(qbuf, "\90\94: %ld ", *count);
7609         (void) key2txt((uchar) key, eos(qbuf));
7610         putmsghistory(qbuf, FALSE);
7611     }
7612
7613     return key;
7614 }
7615
7616
7617 STATIC_OVL char *
7618 parse()
7619 {
7620 #ifdef LINT /* static char in_line[COLNO]; */
7621     char in_line[COLNO];
7622 #else
7623     static char in_line[COLNO];
7624 #endif
7625     register int foo;
7626
7627     iflags.in_parse = TRUE;
7628     multi = 0;
7629     context.move = 1;
7630     flush_screen(1); /* Flush screen buffer. Put the cursor on the hero. */
7631
7632 #ifdef ALTMETA
7633     alt_esc = iflags.altmeta; /* readchar() hack */
7634 #endif
7635     if (!Cmd.num_pad || (foo = readchar()) == Cmd.spkeys[NHKF_COUNT]) {
7636         long tmpmulti = multi;
7637
7638         foo = get_count((char *) 0, '\0', LARGEST_INT, &tmpmulti, FALSE);
7639         last_multi = multi = tmpmulti;
7640     }
7641 #ifdef ALTMETA
7642     alt_esc = FALSE; /* readchar() reset */
7643 #endif
7644
7645     if (iflags.debug_fuzzer /* if fuzzing, override '!' and ^Z */
7646         && (Cmd.commands[foo & 0x0ff]
7647             && (Cmd.commands[foo & 0x0ff]->ef_funct == dosuspend_core
7648                 || Cmd.commands[foo & 0x0ff]->ef_funct == dosh_core)))
7649         foo = Cmd.spkeys[NHKF_ESC];
7650
7651     if (foo == Cmd.spkeys[NHKF_ESC]) { /* esc cancels count (TH) */
7652         clear_nhwindow(WIN_MESSAGE);
7653         multi = last_multi = 0;
7654     } else if (foo == Cmd.spkeys[NHKF_DOAGAIN] || in_doagain) {
7655         multi = last_multi;
7656     } else {
7657         last_multi = multi;
7658         savech(0); /* reset input queue */
7659         savech((char) foo);
7660     }
7661
7662     if (multi) {
7663         multi--;
7664         save_cm = in_line;
7665     } else {
7666         save_cm = (char *) 0;
7667     }
7668     /* in 3.4.3 this was in rhack(), where it was too late to handle M-5 */
7669     if (Cmd.pcHack_compat) {
7670         /* This handles very old inconsistent DOS/Windows behaviour
7671            in a different way: earlier, the keyboard handler mapped
7672            these, which caused counts to be strange when entered
7673            from the number pad. Now do not map them until here. */
7674         switch (foo) {
7675         case '5':
7676             foo = Cmd.spkeys[NHKF_RUSH];
7677             break;
7678         case M('5'):
7679             foo = Cmd.spkeys[NHKF_RUN];
7680             break;
7681         case M('0'):
7682             foo = Cmd.spkeys[NHKF_DOINV];
7683             break;
7684         default:
7685             break; /* as is */
7686         }
7687     }
7688
7689     in_line[0] = foo;
7690     in_line[1] = '\0';
7691     if (prefix_cmd(foo)) {
7692         foo = readchar();
7693         savech((char) foo);
7694         in_line[1] = foo;
7695         in_line[2] = 0;
7696     }
7697     clear_nhwindow(WIN_MESSAGE);
7698
7699     iflags.in_parse = FALSE;
7700     return in_line;
7701 }
7702
7703 #ifdef HANGUPHANDLING
7704 /* some very old systems, or descendents of such systems, expect signal
7705    handlers to have return type `int', but they don't actually inspect
7706    the return value so we should be safe using `void' unconditionally */
7707 /*ARGUSED*/
7708 void
7709 hangup(sig_unused) /* called as signal() handler, so sent at least one arg */
7710 int sig_unused UNUSED;
7711 {
7712     if (program_state.exiting)
7713         program_state.in_moveloop = 0;
7714     nhwindows_hangup();
7715 #ifdef SAFERHANGUP
7716     /* When using SAFERHANGUP, the done_hup flag it tested in rhack
7717        and a couple of other places; actual hangup handling occurs then.
7718        This is 'safer' because it disallows certain cheats and also
7719        protects against losing objects in the process of being thrown,
7720        but also potentially riskier because the disconnected program
7721        must continue running longer before attempting a hangup save. */
7722     program_state.done_hup++;
7723     /* defer hangup iff game appears to be in progress */
7724     if (program_state.in_moveloop && program_state.something_worth_saving)
7725         return;
7726 #endif /* SAFERHANGUP */
7727     end_of_input();
7728 }
7729
7730 void
7731 end_of_input()
7732 {
7733 #ifdef NOSAVEONHANGUP
7734 #ifdef INSURANCE
7735     if (flags.ins_chkpt && program_state.something_worth_saving)
7736         program_state.preserve_locks = 1; /* keep files for recovery */
7737 #endif
7738     program_state.something_worth_saving = 0; /* don't save */
7739 #endif
7740
7741 #ifndef SAFERHANGUP
7742     if (!program_state.done_hup++)
7743 #endif
7744         if (program_state.something_worth_saving)
7745             (void) dosave0();
7746     if (iflags.window_inited)
7747         exit_nhwindows((char *) 0);
7748     clearlocks();
7749     nh_terminate(EXIT_SUCCESS);
7750     /*NOTREACHED*/ /* not necessarily true for vms... */
7751     return;
7752 }
7753 #endif /* HANGUPHANDLING */
7754
7755 char
7756 readchar()
7757 {
7758     register int sym;
7759     int x = u.ux, y = u.uy, mod = 0;
7760
7761     if (iflags.debug_fuzzer)
7762         return randomkey();
7763     if (*readchar_queue)
7764         sym = *readchar_queue++;
7765     else
7766         sym = in_doagain ? pgetchar() : nh_poskey(&x, &y, &mod);
7767
7768 #ifdef NR_OF_EOFS
7769     if (sym == EOF) {
7770         register int cnt = NR_OF_EOFS;
7771         /*
7772          * Some SYSV systems seem to return EOFs for various reasons
7773          * (?like when one hits break or for interrupted systemcalls?),
7774          * and we must see several before we quit.
7775          */
7776         do {
7777             clearerr(stdin); /* omit if clearerr is undefined */
7778             sym = pgetchar();
7779         } while (--cnt && sym == EOF);
7780     }
7781 #endif /* NR_OF_EOFS */
7782
7783     if (sym == EOF) {
7784 #ifdef HANGUPHANDLING
7785         hangup(0); /* call end_of_input() or set program_state.done_hup */
7786 #endif
7787         sym = '\033';
7788 #ifdef ALTMETA
7789     } else if (sym == '\033' && alt_esc) {
7790         /* iflags.altmeta: treat two character ``ESC c'' as single `M-c' */
7791         sym = *readchar_queue ? *readchar_queue++ : pgetchar();
7792         if (sym == EOF || sym == 0)
7793             sym = '\033';
7794         else if (sym != '\033')
7795             sym |= 0200; /* force 8th bit on */
7796 #endif /*ALTMETA*/
7797     } else if (sym == 0) {
7798         /* click event */
7799         readchar_queue = click_to_cmd(x, y, mod);
7800         sym = *readchar_queue++;
7801     }
7802     return (char) sym;
7803 }
7804
7805 /* '_' command, #travel, via keyboard rather than mouse click */
7806 STATIC_PTR int
7807 dotravel(VOID_ARGS)
7808 {
7809     static char cmd[2];
7810     coord cc;
7811
7812     /* [FIXME?  Supporting the ability to disable traveling via mouse
7813        click makes some sense, depending upon overall mouse usage.
7814        Disabling '_' on a user by user basis makes no sense at all since
7815        even if it is typed by accident, aborting when picking a target
7816        destination is trivial.  Travel via mouse predates travel via '_',
7817        and this use of OPTION=!travel is probably just a mistake....] */
7818     if (!flags.travelcmd)
7819         return 0;
7820
7821     cmd[1] = 0;
7822     cc.x = iflags.travelcc.x;
7823     cc.y = iflags.travelcc.y;
7824     if (cc.x == 0 && cc.y == 0) {
7825         /* No cached destination, start attempt from current position */
7826         cc.x = u.ux;
7827         cc.y = u.uy;
7828     }
7829     iflags.getloc_travelmode = TRUE;
7830     if (iflags.menu_requested) {
7831         int gf = iflags.getloc_filter;
7832         iflags.getloc_filter = GFILTER_VIEW;
7833         if (!getpos_menu(&cc, GLOC_INTERESTING)) {
7834             iflags.getloc_filter = gf;
7835             iflags.getloc_travelmode = FALSE;
7836             return 0;
7837         }
7838         iflags.getloc_filter = gf;
7839     } else {
7840 /*JP
7841         pline("Where do you want to travel to?");
7842 */
7843         pline("\82Ç\82±\82É\88Ú\93®\82·\82é\81H");
7844 /*JP
7845         if (getpos(&cc, TRUE, "the desired destination") < 0) {
7846 */
7847         if (getpos(&cc, TRUE, "\88Ú\93®\90æ") < 0) {
7848             /* user pressed ESC */
7849             iflags.getloc_travelmode = FALSE;
7850             return 0;
7851         }
7852     }
7853     iflags.getloc_travelmode = FALSE;
7854     iflags.travelcc.x = u.tx = cc.x;
7855     iflags.travelcc.y = u.ty = cc.y;
7856     cmd[0] = Cmd.spkeys[NHKF_TRAVEL];
7857     readchar_queue = cmd;
7858     return 0;
7859 }
7860
7861 /*
7862  *   Parameter validator for generic yes/no function to prevent
7863  *   the core from sending too long a prompt string to the
7864  *   window port causing a buffer overflow there.
7865  */
7866 char
7867 yn_function(query, resp, def)
7868 const char *query, *resp;
7869 char def;
7870 {
7871     char res, qbuf[QBUFSZ];
7872 #ifdef DUMPLOG
7873     extern unsigned saved_pline_index; /* pline.c */
7874     unsigned idx = saved_pline_index;
7875     /* buffer to hold query+space+formatted_single_char_response */
7876     char dumplog_buf[QBUFSZ + 1 + 15]; /* [QBUFSZ+1+7] should suffice */
7877 #endif
7878
7879     iflags.last_msg = PLNMSG_UNKNOWN; /* most recent pline is clobbered */
7880
7881     /* maximum acceptable length is QBUFSZ-1 */
7882     if (strlen(query) >= QBUFSZ) {
7883         /* caller shouldn't have passed anything this long */
7884         paniclog("Query truncated: ", query);
7885         (void) strncpy(qbuf, query, QBUFSZ - 1 - 3);
7886         Strcpy(&qbuf[QBUFSZ - 1 - 3], "...");
7887         query = qbuf;
7888     }
7889     res = (*windowprocs.win_yn_function)(query, resp, def);
7890 #ifdef DUMPLOG
7891     if (idx == saved_pline_index) {
7892         /* when idx is still the same as saved_pline_index, the interface
7893            didn't put the prompt into saved_plines[]; we put a simplified
7894            version in there now (without response choices or default) */
7895         Sprintf(dumplog_buf, "%s ", query);
7896         (void) key2txt((uchar) res, eos(dumplog_buf));
7897         dumplogmsg(dumplog_buf);
7898     }
7899 #endif
7900     return res;
7901 }
7902
7903 /* for paranoid_confirm:quit,die,attack prompting */
7904 boolean
7905 paranoid_query(be_paranoid, prompt)
7906 boolean be_paranoid;
7907 const char *prompt;
7908 {
7909     boolean confirmed_ok;
7910
7911     /* when paranoid, player must respond with "yes" rather than just 'y'
7912        to give the go-ahead for this query; default is "no" unless the
7913        ParanoidConfirm flag is set in which case there's no default */
7914     if (be_paranoid) {
7915         char pbuf[BUFSZ], qbuf[QBUFSZ], ans[BUFSZ];
7916         const char *promptprefix = "",
7917                 *responsetype = ParanoidConfirm ? "(yes|no)" : "(yes) [no]";
7918         int k, trylimit = 6; /* 1 normal, 5 more with "Yes or No:" prefix */
7919
7920         copynchars(pbuf, prompt, BUFSZ - 1);
7921         /* in addition to being paranoid about this particular
7922            query, we might be even more paranoid about all paranoia
7923            responses (ie, ParanoidConfirm is set) in which case we
7924            require "no" to reject in addition to "yes" to confirm
7925            (except we won't loop if response is ESC; it means no) */
7926         do {
7927             /* make sure we won't overflow a QBUFSZ sized buffer */
7928             k = (int) (strlen(promptprefix) + 1 + strlen(responsetype));
7929             if ((int) strlen(pbuf) + k > QBUFSZ - 1) {
7930                 /* chop off some at the end */
7931                 Strcpy(pbuf + (QBUFSZ - 1) - k - 4, "...?"); /* -4: "...?" */
7932             }
7933
7934             Sprintf(qbuf, "%s%s %s", promptprefix, pbuf, responsetype);
7935             *ans = '\0';
7936             getlin(qbuf, ans);
7937             (void) mungspaces(ans);
7938             confirmed_ok = !strcmpi(ans, "yes");
7939             if (confirmed_ok || *ans == '\033')
7940                 break;
7941             promptprefix = "\"Yes\" or \"No\": ";
7942         } while (ParanoidConfirm && strcmpi(ans, "no") && --trylimit);
7943     } else
7944         confirmed_ok = (yn(prompt) == 'y');
7945
7946     return confirmed_ok;
7947 }
7948
7949 /* ^Z command, #suspend */
7950 STATIC_PTR int
7951 dosuspend_core(VOID_ARGS)
7952 {
7953 #ifdef SUSPEND
7954     /* Does current window system support suspend? */
7955     if ((*windowprocs.win_can_suspend)()) {
7956         /* NB: SYSCF SHELLERS handled in port code. */
7957         dosuspend();
7958     } else
7959 #endif
7960         Norep(cmdnotavail, "#suspend");
7961     return 0;
7962 }
7963
7964 /* '!' command, #shell */
7965 STATIC_PTR int
7966 dosh_core(VOID_ARGS)
7967 {
7968 #ifdef SHELL
7969     /* access restrictions, if any, are handled in port code */
7970     dosh();
7971 #else
7972     Norep(cmdnotavail, "#shell");
7973 #endif
7974     return 0;
7975 }
7976
7977 /*cmd.c*/