OSDN Git Service

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