OSDN Git Service

add translations for command
[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         Strcat(buf, "\82É\91Î\82µ\82Ä\83I\83\93");
2602 #endif
2603     } else
2604 /*JP
2605         Strcpy(buf, "off");
2606 */
2607         Strcpy(buf, "\83I\83t");
2608 /*JP
2609     enl_msg("Autopickup ", "is ", "was ", buf, "");
2610 */
2611     enl_msg("\8e©\93®\8fE\82¢\90Ý\92è\82Í", "\82Å\82 \82é", "\82Å\82 \82Á\82½", buf, "");
2612 }
2613
2614 /* characteristics: expanded version of bottom line strength, dexterity, &c */
2615 STATIC_OVL void
2616 characteristics_enlightenment(mode, final)
2617 int mode;
2618 int final;
2619 {
2620     char buf[BUFSZ];
2621
2622     enlght_out("");
2623 /*JP
2624     Sprintf(buf, "%s Characteristics:", !final ? "Current" : "Final");
2625 */
2626     Sprintf(buf, "%s\93Á\90«\81F", !final ? "\8c»\8dÝ\82Ì" : "\8dÅ\8fI");
2627     enlght_out(buf);
2628
2629     /* bottom line order */
2630     one_characteristic(mode, final, A_STR); /* strength */
2631     one_characteristic(mode, final, A_DEX); /* dexterity */
2632     one_characteristic(mode, final, A_CON); /* constitution */
2633     one_characteristic(mode, final, A_INT); /* intelligence */
2634     one_characteristic(mode, final, A_WIS); /* wisdom */
2635     one_characteristic(mode, final, A_CHA); /* charisma */
2636 }
2637
2638 /* display one attribute value for characteristics_enlightenment() */
2639 STATIC_OVL void
2640 one_characteristic(mode, final, attrindx)
2641 int mode, final, attrindx;
2642 {
2643     extern const char *const attrname[]; /* attrib.c */
2644     boolean hide_innate_value = FALSE, interesting_alimit;
2645     int acurrent, abase, apeak, alimit;
2646     const char *paren_pfx;
2647     char subjbuf[BUFSZ], valubuf[BUFSZ], valstring[32];
2648
2649     /* being polymorphed or wearing certain cursed items prevents
2650        hero from reliably tracking changes to characteristics so
2651        we don't show base & peak values then; when the items aren't
2652        cursed, hero could take them off to check underlying values
2653        and we show those in such case so that player doesn't need
2654        to actually resort to doing that */
2655     if (Upolyd) {
2656         hide_innate_value = TRUE;
2657     } else if (Fixed_abil) {
2658         if (stuck_ring(uleft, RIN_SUSTAIN_ABILITY)
2659             || stuck_ring(uright, RIN_SUSTAIN_ABILITY))
2660             hide_innate_value = TRUE;
2661     }
2662     switch (attrindx) {
2663     case A_STR:
2664         if (uarmg && uarmg->otyp == GAUNTLETS_OF_POWER && uarmg->cursed)
2665             hide_innate_value = TRUE;
2666         break;
2667     case A_DEX:
2668         break;
2669     case A_CON:
2670         if (uwep && uwep->oartifact == ART_OGRESMASHER && uwep->cursed)
2671             hide_innate_value = TRUE;
2672         break;
2673     case A_INT:
2674         if (uarmh && uarmh->otyp == DUNCE_CAP && uarmh->cursed)
2675             hide_innate_value = TRUE;
2676         break;
2677     case A_WIS:
2678         if (uarmh && uarmh->otyp == DUNCE_CAP && uarmh->cursed)
2679             hide_innate_value = TRUE;
2680         break;
2681     case A_CHA:
2682         break;
2683     default:
2684         return; /* impossible */
2685     };
2686     /* note: final disclosure includes MAGICENLIGHTENTMENT */
2687     if ((mode & MAGICENLIGHTENMENT) && !Upolyd)
2688         hide_innate_value = FALSE;
2689
2690     acurrent = ACURR(attrindx);
2691     (void) attrval(attrindx, acurrent, valubuf); /* Sprintf(valubuf,"%d",) */
2692 /*JP
2693     Sprintf(subjbuf, "Your %s ", attrname[attrindx]);
2694 */
2695     Sprintf(subjbuf, "\82 \82È\82½\82Ì%s\82Í", attrname[attrindx]);
2696
2697     if (!hide_innate_value) {
2698         /* show abase, amax, and/or attrmax if acurr doesn't match abase
2699            (a magic bonus or penalty is in effect) or abase doesn't match
2700            amax (some points have been lost to poison or exercise abuse
2701            and are restorable) or attrmax is different from normal human
2702            (while game is in progress; trying to reduce dependency on
2703            spoilers to keep track of such stuff) or attrmax was different
2704            from abase (at end of game; this attribute wasn't maxed out) */
2705         abase = ABASE(attrindx);
2706         apeak = AMAX(attrindx);
2707         alimit = ATTRMAX(attrindx);
2708         /* criterium for whether the limit is interesting varies */
2709         interesting_alimit =
2710             final ? TRUE /* was originally `(abase != alimit)' */
2711                   : (alimit != (attrindx != A_STR ? 18 : STR18(100)));
2712 /*JP
2713         paren_pfx = final ? " (" : " (current; ";
2714 */
2715         paren_pfx = final ? " (" : " (\8c»\8dÝ; ";
2716         if (acurrent != abase) {
2717 #if 0 /*JP:T*/
2718             Sprintf(eos(valubuf), "%sbase:%s", paren_pfx,
2719                     attrval(attrindx, abase, valstring));
2720 #else
2721             Sprintf(eos(valubuf), "%s\8aî\96{:%s", paren_pfx,
2722                     attrval(attrindx, abase, valstring));
2723 #endif
2724             paren_pfx = ", ";
2725         }
2726         if (abase != apeak) {
2727 #if 0 /*JP:T*/
2728             Sprintf(eos(valubuf), "%speak:%s", paren_pfx,
2729                     attrval(attrindx, apeak, valstring));
2730 #else
2731             Sprintf(eos(valubuf), "%s\8dÅ\91å:%s", paren_pfx,
2732                     attrval(attrindx, apeak, valstring));
2733 #endif
2734             paren_pfx = ", ";
2735         }
2736         if (interesting_alimit) {
2737 #if 0 /*JP:T*/
2738             Sprintf(eos(valubuf), "%s%slimit:%s", paren_pfx,
2739                     /* more verbose if exceeding 'limit' due to magic bonus */
2740                     (acurrent > alimit) ? "innate " : "",
2741                     attrval(attrindx, alimit, valstring));
2742 #else
2743             Sprintf(eos(valubuf), "%s%s\8fã\8cÀ:%s", paren_pfx,
2744                     /* more verbose if exceeding 'limit' due to magic bonus */
2745                     (acurrent > alimit) ? "\96{\97\88\82Ì" : "",
2746                     attrval(attrindx, alimit, valstring));
2747 #endif
2748             /* paren_pfx = ", "; */
2749         }
2750         if (acurrent != abase || abase != apeak || interesting_alimit)
2751             Strcat(valubuf, ")");
2752     }
2753 /*JP
2754     enl_msg(subjbuf, "is ", "was ", valubuf, "");
2755 */
2756     enl_msg(subjbuf, "\82¾", "\82¾\82Á\82½", valubuf, "");
2757 }
2758
2759 /* status: selected obvious capabilities, assorted troubles */
2760 STATIC_OVL void
2761 status_enlightenment(mode, final)
2762 int mode;
2763 int final;
2764 {
2765     boolean magic = (mode & MAGICENLIGHTENMENT) ? TRUE : FALSE;
2766     int cap, wtype;
2767     char buf[BUFSZ], youtoo[BUFSZ];
2768     boolean Riding = (u.usteed
2769                       /* if hero dies while dismounting, u.usteed will still
2770                          be set; we want to ignore steed in that situation */
2771                       && !(final == ENL_GAMEOVERDEAD
2772 /*JP
2773                            && !strcmp(killer.name, "riding accident")));
2774 */
2775                            && !strcmp(killer.name, "\8bR\8fæ\8e\96\8cÌ\82Å")));
2776     const char *steedname = (!Riding ? (char *) 0
2777                       : x_monnam(u.usteed,
2778                                  u.usteed->mtame ? ARTICLE_YOUR : ARTICLE_THE,
2779                                  (char *) 0,
2780                                  (SUPPRESS_SADDLE | SUPPRESS_HALLUCINATION),
2781                                  FALSE));
2782
2783     /*\
2784      * Status (many are abbreviated on bottom line; others are or
2785      *     should be discernible to the hero hence to the player)
2786     \*/
2787     enlght_out(""); /* separator after title or characteristics */
2788 /*JP
2789     enlght_out(final ? "Final Status:" : "Current Status:");
2790 */
2791     enlght_out(final ? "\8dÅ\8fI\8fó\91Ô:" : "\8c»\8dÝ\82Ì\8fó\91Ô:");
2792
2793     Strcpy(youtoo, You_);
2794     /* not a traditional status but inherently obvious to player; more
2795        detail given below (attributes section) for magic enlightenment */
2796     if (Upolyd) {
2797 #if 0 /*JP*/
2798         Strcpy(buf, "transformed");
2799         if (ugenocided())
2800             Sprintf(eos(buf), " and %s %s inside",
2801                     final ? "felt" : "feel", udeadinside());
2802         you_are(buf, "");
2803 #else /*JP:TODO:\95Ï\89»+\8bs\8eE\83p\83^\81[\83\93*/
2804         you_are_ing("\95Ï\89»\82µ\82Ä", "");
2805 #endif
2806     }
2807     /* not a trouble, but we want to display riding status before maybe
2808        reporting steed as trapped or hero stuck to cursed saddle */
2809     if (Riding) {
2810 #if 0 /*JP:T*/
2811         Sprintf(buf, "riding %s", steedname);
2812         you_are(buf, "");
2813 #else
2814         Sprintf(buf, "%s\82É\8fæ\82Á\82Ä", steedname);
2815         you_are_ing(buf, "");
2816 #endif
2817 /*JP
2818         Sprintf(eos(youtoo), "and %s ", steedname);
2819 */
2820         Sprintf(youtoo, "\82 \82È\82½\82Æ%s\82Í", steedname);
2821     }
2822     /* other movement situations that hero should always know */
2823     if (Levitation) {
2824         if (Lev_at_will && magic)
2825 /*JP
2826             you_are("levitating, at will", "");
2827 */
2828             you_are_ing("\8e©\95ª\82Ì\88Ó\8eu\82Å\95\82\97V\82µ\82Ä", "");
2829         else
2830 /*JP
2831             enl_msg(youtoo, are, were, "levitating", from_what(LEVITATION));
2832 */
2833             enl_msg(youtoo, "\82¢\82é", "\82¢\82½", "\95\82\97V\82µ\82Ä", from_what(LEVITATION));
2834     } else if (Flying) { /* can only fly when not levitating */
2835 /*JP
2836         enl_msg(youtoo, are, were, "flying", from_what(FLYING));
2837 */
2838         enl_msg(youtoo, "\82¢\82é", "\82¢\82½", "\94ò\82ñ\82Å", from_what(FLYING));
2839     }
2840     if (Underwater) {
2841 /*JP
2842         you_are("underwater", "");
2843 */
2844         enl_msg(You_, "\82¢\82é", "\82¢\82½", "\90\85\96Ê\89º\82É", "");
2845     } else if (u.uinwater) {
2846 /*JP
2847         you_are(Swimming ? "swimming" : "in water", from_what(SWIMMING));
2848 */
2849         enl_msg(You_, Swimming ? "\89j\82¢\82Å" : "\90\85\92\86\82É", "\82¢\82é", "\82¢\82½", from_what(SWIMMING));
2850     } else if (walking_on_water()) {
2851         /* show active Wwalking here, potential Wwalking elsewhere */
2852 #if 0 /*JP*/
2853         Sprintf(buf, "walking on %s",
2854                 is_pool(u.ux, u.uy) ? "water"
2855                 : is_lava(u.ux, u.uy) ? "lava"
2856                   : surface(u.ux, u.uy)); /* catchall; shouldn't happen */
2857         you_are(buf, from_what(WWALKING));
2858 #else
2859         Sprintf(buf, "%s\82Ì\8fã\82ð\95à\82¢\82Ä",
2860                 is_pool(u.ux, u.uy) ? "\90\85"
2861                 : is_lava(u.ux, u.uy) ? "\97n\8aâ"
2862                   : surface(u.ux, u.uy)); /* catchall; shouldn't happen */
2863         you_are_ing(buf, from_what(WWALKING));
2864 #endif
2865     }
2866     if (Upolyd && (u.uundetected || U_AP_TYPE != M_AP_NOTHING))
2867         youhiding(TRUE, final);
2868
2869     /* internal troubles, mostly in the order that prayer ranks them */
2870     if (Stoned) {
2871         if (final && (Stoned & I_SPECIAL))
2872 /*JP
2873             enlght_out(" You turned into stone.");
2874 */
2875             enlght_out(" \82 \82È\82½\82Í\90Î\82É\82È\82Á\82½\81D");
2876         else
2877 /*JP
2878             you_are("turning to stone", "");
2879 */
2880             enl_msg("\82 \82È\82½\82Í", "\82È\82è\82Â\82Â\82 \82é", "\82È\82Á\82½", "\90Î\82É", "");
2881     }
2882     if (Slimed) {
2883         if (final && (Slimed & I_SPECIAL))
2884 /*JP
2885             enlght_out(" You turned into slime.");
2886 */
2887             enlght_out(" \82 \82È\82½\82Í\83X\83\89\83C\83\80\82É\82È\82Á\82½\81D");
2888         else
2889 /*JP
2890             you_are("turning into slime", "");
2891 */
2892             enl_msg("\82 \82È\82½\82Í", "\82È\82è\82Â\82Â\82 \82é", "\82È\82Á\82½", "\83X\83\89\83C\83\80\82É", "");
2893     }
2894     if (Strangled) {
2895         if (u.uburied) {
2896 /*JP
2897             you_are("buried", "");
2898 */
2899             you_are_ing("\92\82\91§\82µ\82Ä", "");
2900         } else {
2901             if (final && (Strangled & I_SPECIAL)) {
2902 /*JP
2903                 enlght_out(" You died from strangulation.");
2904 */
2905                 enlght_out(" \82 \82È\82½\82Í\92\82\91§\8e\80\82µ\82½\81D");
2906             } else {
2907 /*JP
2908                 Strcpy(buf, "being strangled");
2909 */
2910                 Strcpy(buf, "\8eñ\82ð\8di\82ß\82ç\82ê\82Ä");
2911                 if (wizard)
2912                     Sprintf(eos(buf), " (%ld)", (Strangled & TIMEOUT));
2913 /*JP
2914                 you_are(buf, from_what(STRANGLED));
2915 */
2916                 enl_msg("\82 \82È\82½\82Í", "\82¢\82é", "\82¢\82½", buf, from_what(STRANGLED));
2917             }
2918         }
2919     }
2920     if (Sick) {
2921         /* the two types of sickness are lumped together; hero can be
2922            afflicted by both but there is only one timeout; botl status
2923            puts TermIll before FoodPois and death due to timeout reports
2924            terminal illness if both are in effect, so do the same here */
2925         if (final && (Sick & I_SPECIAL)) {
2926 #if 0 /*JP:T*/
2927             Sprintf(buf, " %sdied from %s.", You_, /* has trailing space */
2928                     (u.usick_type & SICK_NONVOMITABLE)
2929                     ? "terminal illness" : "food poisoning");
2930 #else
2931             Sprintf(buf, " %s%s\82Å\8e\80\82ñ\82¾\81D", You_, /* has trailing space */
2932                     (u.usick_type & SICK_NONVOMITABLE)
2933                     ? "\95a\8bC" : "\90H\92\86\93Å");
2934 #endif
2935             enlght_out(buf);
2936         } else {
2937             /* unlike death due to sickness, report the two cases separately
2938                because it is possible to cure one without curing the other */
2939             if (u.usick_type & SICK_NONVOMITABLE)
2940 /*JP
2941                 you_are("terminally sick from illness", "");
2942 */
2943                 enl_msg("\82 \82È\82½\82Í\95a\8bC\82Å\92v\96½\93I\82É\8bC\95ª\82ª\88«", "\82¢", "\82©\82Á\82½", "", "");
2944             if (u.usick_type & SICK_VOMITABLE)
2945 /*JP
2946                 you_are("terminally sick from food poisoning", "");
2947 */
2948                 enl_msg("\82 \82È\82½\82Í\90H\92\86\93Å\82Å\92v\96½\93I\82É\8bC\95ª\82ª\88«", "\82¢", "\82©\82Á\82½", "", "");
2949         }
2950     }
2951     if (Vomiting)
2952 /*JP
2953         you_are("nauseated", "");
2954 */
2955         enl_msg(You_, "\93f\82«\8bC\82ª", "\82 \82é", "\82 \82Á\82½", "");
2956     if (Stunned)
2957 /*JP
2958         you_are("stunned", "");
2959 */
2960         you_are("\82­\82ç\82­\82ç\8fó\91Ô", "");
2961     if (Confusion)
2962 /*JP
2963         you_are("confused", "");
2964 */
2965         you_are("\8d¬\97\90\8fó\91Ô", "");
2966     if (Hallucination)
2967 /*JP
2968         you_are("hallucinating", "");
2969 */
2970         you_are("\8c\8ao\8fó\91Ô", "");
2971     if (Blind) {
2972         /* from_what() (currently wizard-mode only) checks !haseyes()
2973            before u.uroleplay.blind, so we should too */
2974 #if 0 /*JP:T*/
2975         Sprintf(buf, "%s blind",
2976                 !haseyes(youmonst.data) ? "innately"
2977                 : u.uroleplay.blind ? "permanently"
2978                   /* better phrasing desperately wanted... */
2979                   : Blindfolded_only ? "deliberately"
2980                     : "temporarily");
2981 #else
2982         Sprintf(buf, "%s\96Ó\96Ú",
2983                 !haseyes(youmonst.data) ? "\90\82Ü\82ê\82È\82ª\82ç\82É"
2984                 : u.uroleplay.blind ? "\8dP\8bv\93I\82É"
2985                   /* better phrasing desperately wanted... */
2986                   : Blindfolded_only ? "\8cÌ\88Ó\82É"
2987                     : "\88ê\8e\9e\93I\82É");
2988 #endif
2989         if (wizard && (Blinded & TIMEOUT) != 0L
2990             && !u.uroleplay.blind && haseyes(youmonst.data))
2991             Sprintf(eos(buf), " (%ld)", (Blinded & TIMEOUT));
2992         /* !haseyes: avoid "you are innately blind innately" */
2993         you_are(buf, !haseyes(youmonst.data) ? "" : from_what(BLINDED));
2994     }
2995     if (Deaf)
2996 /*JP
2997         you_are("deaf", from_what(DEAF));
2998 */
2999         you_are("\8e¨\82ª\95·\82±\82¦\82È\82¢\8fó\91Ô", from_what(DEAF));
3000
3001     /* external troubles, more or less */
3002     if (Punished) {
3003         if (uball) {
3004 /*JP
3005             Sprintf(buf, "chained to %s", ansimpleoname(uball));
3006 */
3007             Sprintf(buf, "%s\82É\82Â\82È\82ª\82ê\82Ä", ansimpleoname(uball));
3008         } else {
3009             impossible("Punished without uball?");
3010 /*JP
3011             Strcpy(buf, "punished");
3012 */
3013             Strcpy(buf, "\94±\82ð\8eó\82¯\82Ä");
3014         }
3015         you_are(buf, "");
3016     }
3017     if (u.utrap) {
3018         char predicament[BUFSZ];
3019         struct trap *t;
3020         boolean anchored = (u.utraptype == TT_BURIEDBALL);
3021
3022         if (anchored) {
3023 /*JP
3024             Strcpy(predicament, "tethered to something buried");
3025 */
3026             Strcpy(predicament, "\89½\82©\96\84\82Ü\82Á\82Ä\82¢\82é\82à\82Ì\82É\82Â\82È\82ª\82ê\82Ä");
3027         } else if (u.utraptype == TT_INFLOOR || u.utraptype == TT_LAVA) {
3028 /*JP
3029             Sprintf(predicament, "stuck in %s", the(surface(u.ux, u.uy)));
3030 */
3031             Sprintf(predicament, "%s\82É\96\84\82Ü\82Á\82Ä", surface(u.ux, u.uy));
3032         } else {
3033 #if 0 /*JP*/
3034             Strcpy(predicament, "trapped");
3035             if ((t = t_at(u.ux, u.uy)) != 0)
3036                 Sprintf(eos(predicament), " in %s",
3037                         an(defsyms[trap_to_defsym(t->ttyp)].explanation));
3038 #else
3039             predicament[0] = '\0';
3040             if ((t = t_at(u.ux, u.uy)) != 0)
3041                 Sprintf(predicament, "%s\82É",
3042                         defsyms[trap_to_defsym(t->ttyp)].explanation);
3043             Strcat(predicament, "\82Ð\82Á\82©\82©\82Á\82Ä");
3044 #endif
3045         }
3046         if (u.usteed) { /* not `Riding' here */
3047 #if 0 /*JP*/
3048             Sprintf(buf, "%s%s ", anchored ? "you and " : "", steedname);
3049             *buf = highc(*buf);
3050             enl_msg(buf, (anchored ? "are " : "is "),
3051                     (anchored ? "were " : "was "), predicament, "");
3052 #else
3053             Sprintf(buf, "%s%s\82Í", anchored ? "\82 \82È\82½\82Æ" : "", steedname);
3054             enl_msg(buf, "\82¢\82é", "\82¢\82½" , predicament, "");
3055 #endif
3056         } else
3057             you_are(predicament, "");
3058     } /* (u.utrap) */
3059     if (u.uswallow) {
3060 /*JP
3061         Sprintf(buf, "swallowed by %s", a_monnam(u.ustuck));
3062 */
3063         Sprintf(buf, "%s\82É\88ù\82Ý\8d\9e\82Ü\82ê\82Ä", a_monnam(u.ustuck));
3064         if (wizard)
3065             Sprintf(eos(buf), " (%u)", u.uswldtim);
3066         you_are(buf, "");
3067     } else if (u.ustuck) {
3068 #if 0 /*JP*/
3069         Sprintf(buf, "%s %s",
3070                 (Upolyd && sticks(youmonst.data)) ? "holding" : "held by",
3071                 a_monnam(u.ustuck));
3072         you_are(buf, "");
3073 #else
3074         Sprintf(buf, "%s%s",
3075                 a_monnam(u.ustuck),
3076                 (Upolyd && sticks(youmonst.data)) ? "\82ð\95ß\82Ü\82¦\82Ä" : "\82É\95ß\82Ü\82Á\82Ä");
3077         you_are_ing(buf, "");
3078 #endif
3079     }
3080     if (Riding) {
3081         struct obj *saddle = which_armor(u.usteed, W_SADDLE);
3082
3083         if (saddle && saddle->cursed) {
3084 #if 0 /*JP*/
3085             Sprintf(buf, "stuck to %s %s", s_suffix(steedname),
3086                     simpleonames(saddle));
3087             you_are(buf, "");
3088 #else
3089             Sprintf(buf, "%s\82Ì%s\82É\82Â\82©\82Ü\82Á\82Ä", steedname,
3090                     simpleonames(saddle));
3091             you_are_ing(buf, "");
3092 #endif
3093         }
3094     }
3095     if (Wounded_legs) {
3096         /* when mounted, Wounded_legs applies to steed rather than to
3097            hero; we only report steed's wounded legs in wizard mode */
3098         if (u.usteed) { /* not `Riding' here */
3099             if (wizard && steedname) {
3100 #if 0 /*JP*/
3101                 Strcpy(buf, steedname);
3102                 *buf = highc(*buf);
3103                 enl_msg(buf, " has", " had", " wounded legs", "");
3104 #else
3105                 enl_msg(buf, iru, ita, "\82Í\8e\88\82ð\89ö\89ä\82µ\82Ä", "");
3106 #endif
3107             }
3108         } else {
3109 #if 0 /*JP*/
3110             Sprintf(buf, "wounded %s", makeplural(body_part(LEG)));
3111             you_have(buf, "");
3112 #else
3113             Sprintf(buf, "%s\82ð\89ö\89ä\82µ\82Ä", makeplural(body_part(LEG)));
3114             you_are_ing(buf, "");
3115 #endif
3116         }
3117     }
3118     if (Glib) {
3119 #if 0 /*JP*/
3120         Sprintf(buf, "slippery %s", fingers_or_gloves(TRUE));
3121         if (wizard)
3122             Sprintf(eos(buf), " (%ld)", (Glib & TIMEOUT));
3123         you_have(buf, "");
3124 #else
3125         Sprintf(buf, "%s\82ª\82Ê\82é\82Ê\82é\82µ\82Ä", body_part(FINGER));
3126         if (wizard)
3127             Sprintf(eos(buf), " (%ld)", (Glib & TIMEOUT));
3128         enl_msg(buf, iru, ita, "", "");
3129 #endif
3130     }
3131     if (Fumbling) {
3132         if (magic || cause_known(FUMBLING))
3133 /*JP
3134             enl_msg(You_, "fumble", "fumbled", "", from_what(FUMBLING));
3135 */
3136             you_are_ing("\95s\8aí\97p\82É\82È\82Á\82Ä", from_what(FUMBLING));
3137     }
3138     if (Sleepy) {
3139         if (magic || cause_known(SLEEPY)) {
3140             Strcpy(buf, from_what(SLEEPY));
3141             if (wizard)
3142                 Sprintf(eos(buf), " (%ld)", (HSleepy & TIMEOUT));
3143 /*JP
3144             enl_msg("You ", "fall", "fell", " asleep uncontrollably", buf);
3145 */
3146             you_are_ing("\96°\82Á\82Ä", buf);
3147         }
3148     }
3149     /* hunger/nutrition */
3150     if (Hunger) {
3151         if (magic || cause_known(HUNGER))
3152 #if 0 /*JP*/
3153             enl_msg(You_, "hunger", "hungered", " rapidly",
3154                     from_what(HUNGER));
3155 #else
3156             enl_msg("\82 \82È\82½\82Í\82·\82®\82É\95 \82ª\8c¸\82é\8fó\91Ô", "\82Å\82 \82é", "\82¾\82Á\82½", "", "");
3157 #endif
3158     }
3159     Strcpy(buf, hu_stat[u.uhs]); /* hunger status; omitted if "normal" */
3160     mungspaces(buf);             /* strip trailing spaces */
3161     if (*buf) {
3162 #if 0 /*JP*/
3163         *buf = lowc(*buf); /* override capitalization */
3164         if (!strcmp(buf, "weak"))
3165             Strcat(buf, " from severe hunger");
3166         else if (!strncmp(buf, "faint", 5)) /* fainting, fainted */
3167             Strcat(buf, " due to starvation");
3168         you_are(buf, "");
3169 #else
3170         Strcat(buf, "\8fó\91Ô");
3171         you_are(buf, "");
3172 #endif
3173     }
3174     /* encumbrance */
3175     if ((cap = near_capacity()) > UNENCUMBERED) {
3176 #if 0 /*JP*/
3177         const char *adj = "?_?"; /* (should always get overridden) */
3178
3179         Strcpy(buf, enc_stat[cap]);
3180         *buf = lowc(*buf);
3181         switch (cap) {
3182         case SLT_ENCUMBER:
3183             adj = "slightly";
3184             break; /* burdened */
3185         case MOD_ENCUMBER:
3186             adj = "moderately";
3187             break; /* stressed */
3188         case HVY_ENCUMBER:
3189             adj = "very";
3190             break; /* strained */
3191         case EXT_ENCUMBER:
3192             adj = "extremely";
3193             break; /* overtaxed */
3194         case OVERLOADED:
3195             adj = "not possible";
3196             break;
3197         }
3198         Sprintf(eos(buf), "; movement %s %s%s", !final ? "is" : "was", adj,
3199                 (cap < OVERLOADED) ? " slowed" : "");
3200         you_are(buf, "");
3201 #else
3202         Sprintf(buf, "\89×\95¨\82É\82æ\82Á\82Ä%s\8fó\91Ô", enc_stat[cap]);
3203         you_are(buf, "");
3204 #endif
3205     } else {
3206         /* last resort entry, guarantees Status section is non-empty
3207            (no longer needed for that purpose since weapon status added;
3208            still useful though) */
3209 /*JP
3210         you_are("unencumbered", "");
3211 */
3212         you_are("\89×\95¨\82Í\8e×\96\82\82É\82È\82ç\82È\82¢\8fó\91Ô", "");
3213     }
3214
3215     /* report being weaponless; distinguish whether gloves are worn */
3216     if (!uwep) {
3217 #if 0 /*JP*/
3218         you_are(uarmg ? "empty handed" /* gloves imply hands */
3219                       : humanoid(youmonst.data)
3220                          /* hands but no weapon and no gloves */
3221                          ? "bare handed"
3222                          /* alternate phrasing for paws or lack of hands */
3223                          : "not wielding anything",
3224                 "");
3225 #else
3226         enl_msg(You_, "\82¢", "\82©\82Á\82½", "\95\90\8aí\82ð\91\95\94õ\82µ\82Ä\82¢\82È", "");
3227 #endif
3228     /* two-weaponing implies hands (can't be polymorphed) and
3229        a weapon or wep-tool (not other odd stuff) in each hand */
3230     } else if (u.twoweap) {
3231 /*JP
3232         you_are("wielding two weapons at once", "");
3233 */
3234         you_are("\93ñ\93\81\97¬", "");
3235     /* report most weapons by their skill class (so a katana will be
3236        described as a long sword, for instance; mattock and hook are
3237        exceptions), or wielded non-weapon item by its object class */
3238     } else {
3239         const char *what = weapon_descr(uwep);
3240
3241 #if 0 /*JP*/
3242         if (!strcmpi(what, "armor") || !strcmpi(what, "food")
3243             || !strcmpi(what, "venom"))
3244             Sprintf(buf, "wielding some %s", what);
3245         else
3246             Sprintf(buf, "wielding %s",
3247                     (uwep->quan == 1L) ? an(what) : makeplural(what));
3248         you_are(buf, "");
3249 #else
3250         Sprintf(buf, "%s\82ð\91\95\94õ\82µ\82Ä", what);
3251         enl_msg(You_, "\82¢\82é", "\82¢\82½", buf, "");
3252 #endif
3253     }
3254     /*
3255      * Skill with current weapon.  Might help players who've never
3256      * noticed #enhance or decided that it was pointless.
3257      *
3258      * TODO?  Maybe merge wielding line and skill line into one sentence.
3259      */
3260     if ((wtype = uwep_skill_type()) != P_NONE) {
3261         char sklvlbuf[20];
3262         int sklvl = P_SKILL(wtype);
3263         boolean hav = (sklvl != P_UNSKILLED && sklvl != P_SKILLED);
3264
3265         if (sklvl == P_ISRESTRICTED)
3266 /*JP
3267             Strcpy(sklvlbuf, "no");
3268 */
3269             Strcpy(sklvlbuf, "\90§\8cÀ");
3270         else
3271             (void) lcase(skill_level_name(wtype, sklvlbuf));
3272         /* "you have no/basic/expert/master/grand-master skill with <skill>"
3273            or "you are unskilled/skilled in <skill>" */
3274 #if 0 /*JP:T*/
3275         Sprintf(buf, "%s %s %s", sklvlbuf,
3276                 hav ? "skill with" : "in", skill_name(wtype));
3277 #else
3278         Sprintf(buf, "%s\82Ì%s\83X\83L\83\8b", skill_name(wtype), sklvlbuf);
3279 #endif
3280         if (can_advance(wtype, FALSE))
3281 #if 0 /*JP:T*/
3282             Sprintf(eos(buf), " and %s that",
3283                     !final ? "can enhance" : "could have enhanced");
3284 #else
3285             Sprintf(eos(buf), "(\8d\82\82ß\82é\82±\82Æ\82ª\82Å\82«%s)",
3286                     !final ? "\82é" : "\82½");
3287 #endif
3288         if (hav)
3289             you_have(buf, "");
3290         else
3291             you_are(buf, "");
3292     }
3293     /* report 'nudity' */
3294     if (!uarm && !uarmu && !uarmc && !uarms && !uarmg && !uarmf && !uarmh) {
3295         if (u.uroleplay.nudist)
3296 #if 0 /*JP:T*/
3297             enl_msg(You_, "do", "did", " not wear any armor", "");
3298 #else
3299             enl_msg(You_, "\82¢", "\82©\82Á\82½", "\89½\82Ì\8aZ\82à\91\95\94õ\82µ\82È", "");
3300 #endif
3301         else
3302 #if 0 /*JP:T*/
3303             you_are("not wearing any armor", "");
3304 #else
3305             enl_msg(You_, "\82¢", "\82©\82Á\82½", "\89½\82Ì\8aZ\82à\91\95\94õ\82µ\82Ä\82¢\82È", "");
3306 #endif
3307     }
3308 }
3309
3310 /* attributes: intrinsics and the like, other non-obvious capabilities */
3311 STATIC_OVL void
3312 attributes_enlightenment(unused_mode, final)
3313 int unused_mode UNUSED;
3314 int final;
3315 {
3316 #if 0 /*JP*/
3317     static NEARDATA const char if_surroundings_permitted[] =
3318         " if surroundings permitted";
3319 #endif
3320     int ltmp, armpro;
3321     char buf[BUFSZ];
3322
3323     /*\
3324      *  Attributes
3325     \*/
3326     enlght_out("");
3327 /*JP
3328     enlght_out(final ? "Final Attributes:" : "Current Attributes:");
3329 */
3330     enlght_out(final ? "\8dÅ\8fI\91®\90«:" : "\8c»\8dÝ\82Ì\91®\90«:");
3331
3332     if (u.uevent.uhand_of_elbereth) {
3333 #if 0 /*JP:T*/
3334         static const char *const hofe_titles[3] = { "the Hand of Elbereth",
3335                                                     "the Envoy of Balance",
3336                                                     "the Glory of Arioch" };
3337 #else
3338         static const char *const hofe_titles[3] = { "\83G\83\8b\83x\83\8c\83X\82Ì\8cä\8eè",
3339                                                     "\92²\98a\82Ì\8eg\8eÒ",
3340                                                     "\83A\83\8a\83I\83b\83`\82Ì\96¼\97_" };
3341 #endif
3342         you_are(hofe_titles[u.uevent.uhand_of_elbereth - 1], "");
3343     }
3344
3345 /*JP
3346     Sprintf(buf, "%s", piousness(TRUE, "aligned"));
3347 */
3348     Sprintf(buf, "%s", piousness(TRUE, "\90M\8bÂ\90S"));
3349     if (u.ualign.record >= 0)
3350         you_are(buf, "");
3351     else
3352         you_have(buf, "");
3353
3354     if (wizard) {
3355 #if 0 /*JP:T*/
3356         Sprintf(buf, " %d", u.ualign.record);
3357         enl_msg("Your alignment ", "is", "was", buf, "");
3358 #else
3359         Sprintf(buf, "\82 \82È\82½\82Ì\91®\90«\92l\82Í%d", u.ualign.record);
3360         enl_msg(buf, "\82Å\82 \82é", "\82¾\82Á\82½", "", "");
3361 #endif
3362     }
3363
3364     /*** Resistances to troubles ***/
3365     if (Invulnerable)
3366 /*JP
3367         you_are("invulnerable", from_what(INVULNERABLE));
3368 */
3369         you_are("\95s\8e\80\90g", from_what(INVULNERABLE));
3370     if (Antimagic)
3371 /*JP
3372         you_are("magic-protected", from_what(ANTIMAGIC));
3373 */
3374         you_have("\96\82\96@\96h\8cä\94\\97Í", from_what(ANTIMAGIC));
3375     if (Fire_resistance)
3376 /*JP
3377         you_are("fire resistant", from_what(FIRE_RES));
3378 */
3379         you_have("\89Î\82Ö\82Ì\91Ï\90«", from_what(FIRE_RES));
3380     if (Cold_resistance)
3381 /*JP
3382         you_are("cold resistant", from_what(COLD_RES));
3383 */
3384         you_have("\8a¦\82³\82Ö\82Ì\91Ï\90«", from_what(COLD_RES));
3385     if (Sleep_resistance)
3386 /*JP
3387         you_are("sleep resistant", from_what(SLEEP_RES));
3388 */
3389         you_have("\96°\82è\82Ö\82Ì\91Ï\90«", from_what(SLEEP_RES));
3390     if (Disint_resistance)
3391 /*JP
3392         you_are("disintegration-resistant", from_what(DISINT_RES));
3393 */
3394         you_have("\95²\8dÓ\82Ö\82Ì\91Ï\90«", from_what(DISINT_RES));
3395     if (Shock_resistance)
3396 /*JP
3397         you_are("shock resistant", from_what(SHOCK_RES));
3398 */
3399         you_have("\93d\8c\82\82Ö\82Ì\91Ï\90«", from_what(SHOCK_RES));
3400     if (Poison_resistance)
3401 /*JP
3402         you_are("poison resistant", from_what(POISON_RES));
3403 */
3404         you_have("\93Å\82Ö\82Ì\91Ï\90«", from_what(POISON_RES));
3405     if (Acid_resistance)
3406 /*JP
3407         you_are("acid resistant", from_what(ACID_RES));
3408 */
3409         you_have("\8e_\82Ö\82Ì\91Ï\90«", from_what(ACID_RES));
3410     if (Drain_resistance)
3411 /*JP
3412         you_are("level-drain resistant", from_what(DRAIN_RES));
3413 */
3414         you_have("\83\8c\83x\83\8b\83_\83E\83\93\82Ö\82Ì\91Ï\90«", from_what(DRAIN_RES));
3415     if (Sick_resistance)
3416 /*JP
3417         you_are("immune to sickness", from_what(SICK_RES));
3418 */
3419         you_have("\95a\8bC\82É\91Î\82·\82é\96Æ\89u", from_what(SICK_RES));
3420     if (Stone_resistance)
3421 /*JP
3422         you_are("petrification resistant", from_what(STONE_RES));
3423 */
3424         you_have("\90Î\89»\82Ö\82Ì\91Ï\90«", from_what(STONE_RES));
3425     if (Halluc_resistance)
3426 #if 0 /*JP:T*/
3427         enl_msg(You_, "resist", "resisted", " hallucinations",
3428                 from_what(HALLUC_RES));
3429 #else
3430         you_have("\8c\8ao\82Ö\82Ì\91Ï\90«", from_what(HALLUC_RES));
3431 #endif
3432     if (u.uedibility)
3433 /*JP
3434         you_can("recognize detrimental food", "");
3435 */
3436         you_can("\97L\8aQ\82È\90H\97¿\82ð\8e¯\95Ê", "");
3437
3438     /*** Vision and senses ***/
3439     if (!Blind && (Blinded || !haseyes(youmonst.data)))
3440 #if 0 /*JP*/
3441         you_can("see", from_what(-BLINDED)); /* Eyes of the Overworld */
3442 #else /*\81u\92´\90¢\8aE\82Ì\96Ú\82É\82æ\82Á\82Ä\8c©\82é\82±\82Æ\82ª\82Å\82«\82é\81v*/
3443         you_can("\8c©\82é\82±\82Æ\82ª", from_what(-BLINDED)); /* Eyes of the Overworld */
3444 #endif
3445     if (See_invisible) {
3446         if (!Blind)
3447 /*JP
3448             enl_msg(You_, "see", "saw", " invisible", from_what(SEE_INVIS));
3449 */
3450             enl_msg("\82 \82È\82½\82Í\93§\96¾\82È\82à\82Ì\82ð\8c©\82ç\82ê", "\82é", "\82½", "", from_what(SEE_INVIS));
3451         else
3452 #if 0 /*JP:T*/
3453             enl_msg(You_, "will see", "would have seen",
3454                     " invisible when not blind", from_what(SEE_INVIS));
3455 #else
3456             enl_msg(You_, "\82é", "\82½",
3457                     "\96Ó\96Ú\82Å\82È\82¢\82Æ\82«\82É\82Í\93§\96¾\82È\82à\82Ì\82ð\8c©\82ç\82ê", from_what(SEE_INVIS));
3458 #endif
3459     }
3460     if (Blind_telepat)
3461 /*JP
3462         you_are("telepathic", from_what(TELEPAT));
3463 */
3464         you_have("\83e\83\8c\83p\83V\81[", from_what(TELEPAT));
3465     if (Warning)
3466 /*JP
3467         you_are("warned", from_what(WARNING));
3468 */
3469         you_have("\8cx\89ú\94\\97Í", from_what(WARNING));
3470     if (Warn_of_mon && context.warntype.obj) {
3471 #if 0 /*JP:T*/
3472         Sprintf(buf, "aware of the presence of %s",
3473                 (context.warntype.obj & M2_ORC) ? "orcs"
3474                 : (context.warntype.obj & M2_ELF) ? "elves"
3475                 : (context.warntype.obj & M2_DEMON) ? "demons" : something);
3476         you_are(buf, from_what(WARN_OF_MON));
3477 #else
3478         Sprintf(buf, "%s\82Ì\91\8dÝ\82ð\8a´\82\82é\94\\97Í",
3479                 (context.warntype.obj & M2_ORC) ? "\83I\81[\83N"
3480                 : (context.warntype.obj & M2_ELF) ? "\83G\83\8b\83t"
3481                 : (context.warntype.obj & M2_DEMON) ? "\88«\96\82" : something);
3482         you_have(buf, "");
3483 #endif
3484     }
3485     if (Warn_of_mon && context.warntype.polyd) {
3486 #if 0 /*JP*/
3487         Sprintf(buf, "aware of the presence of %s",
3488                 ((context.warntype.polyd & (M2_HUMAN | M2_ELF))
3489                  == (M2_HUMAN | M2_ELF))
3490                     ? "humans and elves"
3491                     : (context.warntype.polyd & M2_HUMAN)
3492                           ? "humans"
3493                           : (context.warntype.polyd & M2_ELF)
3494                                 ? "elves"
3495                                 : (context.warntype.polyd & M2_ORC)
3496                                       ? "orcs"
3497                                       : (context.warntype.polyd & M2_DEMON)
3498                                             ? "demons"
3499                                             : "certain monsters");
3500         you_are(buf, "");
3501 #else
3502         Sprintf(buf, "%s\82Ì\91\8dÝ\82ð\8a´\82\82é\94\\97Í",
3503                 ((context.warntype.polyd & (M2_HUMAN | M2_ELF))
3504                  == (M2_HUMAN | M2_ELF))
3505                     ? "\90l\8aÔ\82Æ\83G\83\8b\83t"
3506                     : (context.warntype.polyd & M2_HUMAN)
3507                           ? "\90l\8aÔ"
3508                           : (context.warntype.polyd & M2_ELF)
3509                                 ? "\83G\83\8b\83t"
3510                                 : (context.warntype.polyd & M2_ORC)
3511                                       ? "\83I\81[\83N"
3512                                       : (context.warntype.polyd & M2_DEMON)
3513                                             ? "\88«\96\82"
3514                                             : "\82 \82é\8eí\82Ì\89ö\95¨");
3515         you_have(buf, "");
3516 #endif
3517     }
3518     if (Warn_of_mon && context.warntype.speciesidx >= LOW_PM) {
3519 #if 0 /*JP*/
3520         Sprintf(buf, "aware of the presence of %s",
3521                 makeplural(mons[context.warntype.speciesidx].mname));
3522         you_are(buf, from_what(WARN_OF_MON));
3523 #else
3524         Sprintf(buf, "%s\82Ì\91\8dÝ\82ð\8a´\82\82é\94\\97Í",
3525                 mons[context.warntype.speciesidx].mname);
3526         you_have(buf, from_what(WARN_OF_MON));
3527 #endif
3528     }
3529     if (Undead_warning)
3530 /*JP
3531         you_are("warned of undead", from_what(WARN_UNDEAD));
3532 */
3533         you_have("\95s\8e\80\82Ì\90\95¨\82Ö\82Ì\8cx\89ú\94\\97Í", from_what(WARN_UNDEAD));
3534     if (Searching)
3535 /*JP
3536         you_have("automatic searching", from_what(SEARCHING));
3537 */
3538         you_have("\92T\8d¸\94\\97Í", from_what(SEARCHING));
3539     if (Clairvoyant)
3540 /*JP
3541         you_are("clairvoyant", from_what(CLAIRVOYANT));
3542 */
3543         you_have("\90ç\97¢\8aá\94\\97Í", from_what(CLAIRVOYANT));
3544     else if ((HClairvoyant || EClairvoyant) && BClairvoyant) {
3545         Strcpy(buf, from_what(-CLAIRVOYANT));
3546 #if 0 /*JP*/
3547         if (!strncmp(buf, " because of ", 12))
3548             /* overwrite substring; strncpy doesn't add terminator */
3549             (void) strncpy(buf, " if not for ", 12);
3550         enl_msg(You_, "could be", "could have been", " clairvoyant", buf);
3551 #else
3552         /*JP:\81u\81c\82É\82æ\82Á\82Ä\81v*/
3553         if (!STRNCMP2(buf, "\82É\82æ\82Á\82Ä"))
3554             /*JP:\81u\81c\82ª\82È\82¯\82ê\82Î\81v\82É\8f\91\82«\8a·\82¦\82é*/
3555             strcpy(eos(buf) - strlen("\82É\82æ\82Á\82Ä"), "\82ª\82È\82¯\82ê\82Î");
3556         you_have("\90ç\97¢\8aá\94\\97Í", buf);
3557 #endif
3558     }
3559     if (Infravision)
3560 /*JP
3561         you_have("infravision", from_what(INFRAVISION));
3562 */
3563         you_have("\90Ô\8aO\90ü\82ª\8c©\82¦\82é\8e\8b\8ao", from_what(INFRAVISION));
3564     if (Detect_monsters)
3565 /*JP
3566         you_are("sensing the presence of monsters", "");
3567 */
3568         you_have("\89ö\95¨\82ð\92T\82·\94\\97Í", "");
3569     if (u.umconf)
3570 /*JP
3571         you_are("going to confuse monsters", "");
3572 */
3573         you_have("\89ö\95¨\82ð\8d¬\97\90\82³\82¹\82é\94\\97Í", "");
3574
3575     /*** Appearance and behavior ***/
3576     if (Adornment) {
3577         int adorn = 0;
3578
3579         if (uleft && uleft->otyp == RIN_ADORNMENT)
3580             adorn += uleft->spe;
3581         if (uright && uright->otyp == RIN_ADORNMENT)
3582             adorn += uright->spe;
3583         /* the sum might be 0 (+0 ring or two which negate each other);
3584            that yields "you are charismatic" (which isn't pointless
3585            because it potentially impacts seduction attacks) */
3586 #if 0 /*JP*/
3587         Sprintf(buf, "%scharismatic",
3588                 (adorn > 0) ? "more " : (adorn < 0) ? "less " : "");
3589         you_are(buf, from_what(ADORNED));
3590 #else
3591         Sprintf(buf, "\96£\97Í%s\82Ä",
3592                 (adorn > 0) ? "\82ª\91\9d\89Á\82µ" : (adorn < 0) ? "\82ª\8c¸\8f­\82µ" : "\93I\82É\82È\82Á");
3593         enl_msg(You_, "\82Ä\82¢\82é", "\82½", buf, "");
3594 #endif
3595     }
3596     if (Invisible)
3597 /*JP
3598         you_are("invisible", from_what(INVIS));
3599 */
3600         you_are("\93§\96¾", from_what(INVIS));
3601     else if (Invis)
3602 /*JP
3603         you_are("invisible to others", from_what(INVIS));
3604 */
3605         you_are("\91¼\90l\82É\91Î\82µ\82Ä\93§\96¾", from_what(INVIS));
3606     /* ordinarily "visible" is redundant; this is a special case for
3607        the situation when invisibility would be an expected attribute */
3608     else if ((HInvis || EInvis) && BInvis)
3609 /*JP
3610         you_are("visible", from_what(-INVIS));
3611 */
3612         you_are("\95s\93§\96¾", from_what(-INVIS));
3613     if (Displaced)
3614 /*JP
3615         you_are("displaced", from_what(DISPLACED));
3616 */
3617         you_have("\8c\89e\94\\97Í", from_what(DISPLACED));
3618     if (Stealth)
3619 /*JP
3620         you_are("stealthy", from_what(STEALTH));
3621 */
3622         you_have("\90l\96Ú\82ð\93\90\82Þ\94\\97Í", from_what(STEALTH));
3623     if (Aggravate_monster)
3624 #if 0 /*JP*/
3625         enl_msg("You aggravate", "", "d", " monsters",
3626                 from_what(AGGRAVATE_MONSTER));
3627 #else
3628         you_are_ing("\94½\8a´\82ð\82©\82Á\82Ä", from_what(AGGRAVATE_MONSTER));
3629 #endif
3630     if (Conflict)
3631 /*JP
3632         enl_msg("You cause", "", "d", " conflict", from_what(CONFLICT));
3633 */
3634         you_are_ing("\93¬\91\88\82ð\88ø\82«\8bN\82±\82µ\82Ä", from_what(CONFLICT));
3635
3636     /*** Transportation ***/
3637     if (Jumping)
3638 /*JP
3639         you_can("jump", from_what(JUMPING));
3640 */
3641         you_can("\92µ\96ô\82·\82é\82±\82Æ\82ª", from_what(JUMPING));
3642     if (Teleportation)
3643 /*JP
3644         you_can("teleport", from_what(TELEPORT));
3645 */
3646         you_can("\8fu\8aÔ\88Ú\93®\82ª", from_what(TELEPORT));
3647     if (Teleport_control)
3648 /*JP
3649         you_have("teleport control", from_what(TELEPORT_CONTROL));
3650 */
3651         you_have("\8fu\8aÔ\88Ú\93®\82Ì\90§\8cä\94\\97Í", from_what(TELEPORT_CONTROL));
3652     /* actively levitating handled earlier as a status condition */
3653     if (BLevitation) { /* levitation is blocked */
3654         long save_BLev = BLevitation;
3655
3656         BLevitation = 0L;
3657         if (Levitation) {
3658             /* either trapped in the floor or inside solid rock
3659                (or both if chained to buried iron ball and have
3660                moved one step into solid rock somehow) */
3661 #if 0 /*JP*/
3662             boolean trapped = (save_BLev & I_SPECIAL) != 0L,
3663                     terrain = (save_BLev & FROMOUTSIDE) != 0L;
3664
3665             Sprintf(buf, "%s%s%s",
3666                     trapped ? " if not trapped" : "",
3667                     (trapped && terrain) ? " and" : "",
3668                     terrain ? if_surroundings_permitted : "");
3669             enl_msg(You_, "would levitate", "would have levitated", buf, "");
3670 #else
3671             you_are("\8fó\8bµ\82ª\8b\96\82¹\82Î\95\82\97V\82·\82é\8fó\91Ô", "");
3672 #endif
3673         }
3674         BLevitation = save_BLev;
3675     }
3676     /* actively flying handled earlier as a status condition */
3677     if (BFlying) { /* flight is blocked */
3678         long save_BFly = BFlying;
3679
3680         BFlying = 0L;
3681         if (Flying) {
3682 #if 0 /*JP:T*/
3683             enl_msg(You_, "would fly", "would have flown",
3684                     /* wording quibble: for past tense, "hadn't been"
3685                        would sound better than "weren't" (and
3686                        "had permitted" better than "permitted"), but
3687                        "weren't" and "permitted" are adequate so the
3688                        extra complexity to handle that isn't worth it */
3689                     Levitation
3690                        ? " if you weren't levitating"
3691                        : (save_BFly == I_SPECIAL)
3692                           /* this is an oversimpliction; being trapped
3693                              might also be blocking levitation so flight
3694                              would still be blocked after escaping trap */
3695                           ? " if you weren't trapped"
3696                           : (save_BFly == FROMOUTSIDE)
3697                              ? if_surroundings_permitted
3698                              /* two or more of levitation, surroundings,
3699                                 and being trapped in the floor */
3700                              : " if circumstances permitted",
3701                     "");
3702 #else
3703             enl_msg(You_, "\94ò\82Ô\82±\82Æ\82ª\82Å\82«\82é", "\94ò\82Ô\82±\82Æ\82ª\82Å\82«\82½",
3704                     /* wording quibble: for past tense, "hadn't been"
3705                        would sound better than "weren't" (and
3706                        "had permitted" better than "permitted"), but
3707                        "weren't" and "permitted" are adequate so the
3708                        extra complexity to handle that isn't worth it */
3709                     Levitation
3710                        ? "\95\82\97V\82µ\82Ä\82¢\82È\82¯\82ê\82Î"
3711                        : (save_BFly == I_SPECIAL)
3712                           /* this is an oversimpliction; being trapped
3713                              might also be blocking levitation so flight
3714                              would still be blocked after escaping trap */
3715                           ? "\95ß\82Ü\82Á\82Ä\82¢\82È\82¯\82ê\82Î"
3716                           : (save_BFly == FROMOUTSIDE)
3717                              ? "\8fó\8bµ\82ª\8b\96\82¹\82Î"
3718                              /* two or more of levitation, surroundings,
3719                                 and being trapped in the floor */
3720                              : "\8e\96\8fî\82ª\8b\96\82¹\82Î",
3721                     "");
3722 #endif
3723         }
3724         BFlying = save_BFly;
3725     }
3726     /* actively walking on water handled earlier as a status condition */
3727     if (Wwalking && !walking_on_water())
3728 /*JP
3729         you_can("walk on water", from_what(WWALKING));
3730 */
3731         you_can("\90\85\82Ì\8fã\82ð\95à\82­\82±\82Æ\82ª", from_what(WWALKING));
3732     /* actively swimming (in water but not under it) handled earlier */
3733     if (Swimming && (Underwater || !u.uinwater))
3734 /*JP
3735         you_can("swim", from_what(SWIMMING));
3736 */
3737         you_can("\89j\82®\82±\82Æ\82ª", from_what(SWIMMING));
3738     if (Breathless)
3739 /*JP
3740         you_can("survive without air", from_what(MAGICAL_BREATHING));
3741 */
3742         you_can("\8bó\8bC\82È\82µ\82Å\90\82«\89\84\82Ñ\82é\82±\82Æ\82ª", from_what(MAGICAL_BREATHING));
3743     else if (Amphibious)
3744 /*JP
3745         you_can("breathe water", from_what(MAGICAL_BREATHING));
3746 */
3747         you_can("\90\85\92\86\82Å\8cÄ\8bz\82ª", from_what(MAGICAL_BREATHING));
3748     if (Passes_walls)
3749 /*JP
3750         you_can("walk through walls", from_what(PASSES_WALLS));
3751 */
3752         you_can("\95Ç\82ð\92Ê\82è\94²\82¯\82é\82±\82Æ\82ª", from_what(PASSES_WALLS));
3753
3754     /*** Physical attributes ***/
3755     if (Regeneration)
3756 /*JP
3757         enl_msg("You regenerate", "", "d", "", from_what(REGENERATION));
3758 */
3759         you_have("\8dÄ\90\94\\97Í", from_what(REGENERATION));
3760     if (Slow_digestion)
3761 /*JP
3762         you_have("slower digestion", from_what(SLOW_DIGESTION));
3763 */
3764         enl_msg("\90H\95¨\82Ì\8fÁ\89»\82ª\92x", "\82¢", "\82©\82Á\82½", "", from_what(SLOW_DIGESTION));
3765     if (u.uhitinc)
3766 /*JP
3767         you_have(enlght_combatinc("to hit", u.uhitinc, final, buf), "");
3768 */
3769         you_have(enlght_combatinc("\96½\92\86\97¦", u.uhitinc, final, buf), "");
3770     if (u.udaminc)
3771 /*JP
3772         you_have(enlght_combatinc("damage", u.udaminc, final, buf), "");
3773 */
3774         you_have(enlght_combatinc("\83_\83\81\81[\83W", u.udaminc, final, buf), "");
3775     if (u.uspellprot || Protection) {
3776         int prot = 0;
3777
3778         if (uleft && uleft->otyp == RIN_PROTECTION)
3779             prot += uleft->spe;
3780         if (uright && uright->otyp == RIN_PROTECTION)
3781             prot += uright->spe;
3782         if (HProtection & INTRINSIC)
3783             prot += u.ublessed;
3784         prot += u.uspellprot;
3785         if (prot)
3786 /*JP
3787             you_have(enlght_combatinc("defense", prot, final, buf), "");
3788 */
3789             you_have(enlght_combatinc("\96h\8cä", prot, final, buf), "");
3790     }
3791     if ((armpro = magic_negation(&youmonst)) > 0) {
3792         /* magic cancellation factor, conferred by worn armor */
3793         static const char *const mc_types[] = {
3794 #if 0 /*JP:T*/
3795             "" /*ordinary*/, "warded", "guarded", "protected",
3796 #else
3797             "" /*ordinary*/, "\89q\82ç\82ê\82Ä", "\8cì\82ç\82ê\82Ä", "\8eç\82ç\82ê\82Ä",
3798 #endif
3799         };
3800         /* sanity check */
3801         if (armpro >= SIZE(mc_types))
3802             armpro = SIZE(mc_types) - 1;
3803 /*JP
3804         you_are(mc_types[armpro], "");
3805 */
3806         you_are_ing(mc_types[armpro], "");
3807     }
3808     if (Half_physical_damage)
3809         enlght_halfdmg(HALF_PHDAM, final);
3810     if (Half_spell_damage)
3811         enlght_halfdmg(HALF_SPDAM, final);
3812     /* polymorph and other shape change */
3813     if (Protection_from_shape_changers)
3814 #if 0 /*JP*/
3815         you_are("protected from shape changers",
3816                 from_what(PROT_FROM_SHAPE_CHANGERS));
3817 #else
3818         you_have("\95Ï\89»\89ö\95¨\82Ö\82Ì\91Ï\90«", from_what(PROT_FROM_SHAPE_CHANGERS));
3819 #endif
3820     if (Unchanging) {
3821         const char *what = 0;
3822
3823         if (!Upolyd) /* Upolyd handled below after current form */
3824 /*JP
3825             you_can("not change from your current form",
3826 */
3827             you_are("\8c»\8dÝ\82Ì\8ep\82©\82ç\95Ï\89»\82Å\82«\82È\82¢\8fó\91Ô",
3828                     from_what(UNCHANGING));
3829         /* blocked shape changes */
3830         if (Polymorph)
3831 /*JP
3832             what = !final ? "polymorph" : "have polymorphed";
3833 */
3834             what = "\95Ï\89»\82µ\82Ä";
3835         else if (u.ulycn >= LOW_PM)
3836 /*JP
3837             what = !final ? "change shape" : "have changed shape";
3838 */
3839             what = "\8ep\82ð\95Ï\82¦\82Ä";
3840         if (what) {
3841 #if 0 /*JP*/
3842             Sprintf(buf, "would %s periodically", what);
3843             /* omit from_what(UNCHANGING); too verbose */
3844             enl_msg(You_, buf, buf, " if not locked into your current form",
3845                     "");
3846 #else
3847             Sprintf(buf, "\82à\82µ\8c»\8dÝ\82Ì\8ep\82É\8cÅ\92è\82³\82ê\82Ä\82¢\82È\82¯\82ê\82Î\92è\8aú\93I\82É%s", what);
3848             you_are_ing(buf, "");
3849 #endif
3850         }
3851     } else if (Polymorph) {
3852 /*JP
3853         you_are("polymorphing periodically", from_what(POLYMORPH));
3854 */
3855         you_are("\92è\8aú\93I\82É\95Ï\89»\82µ\82Ä", from_what(POLYMORPH));
3856     }
3857     if (Polymorph_control)
3858 /*JP
3859         you_have("polymorph control", from_what(POLYMORPH_CONTROL));
3860 */
3861         you_have("\95Ï\89»\82Ì\90§\8cä\94\\97Í", from_what(POLYMORPH_CONTROL));
3862     if (Upolyd && u.umonnum != u.ulycn
3863         /* if we've died from turning into slime, we're polymorphed
3864            right now but don't want to list it as a temporary attribute
3865            [we need a more reliable way to detect this situation] */
3866         && !(final == ENL_GAMEOVERDEAD
3867              && u.umonnum == PM_GREEN_SLIME && !Unchanging)) {
3868         /* foreign shape (except were-form which is handled below) */
3869 /*JP
3870         Sprintf(buf, "polymorphed into %s", an(youmonst.data->mname));
3871 */
3872         Sprintf(buf, "%s\82É\95Ï\89»\82µ\82Ä", youmonst.data->mname);
3873         if (wizard)
3874             Sprintf(eos(buf), " (%d)", u.mtimedone);
3875         you_are(buf, "");
3876     }
3877     if (lays_eggs(youmonst.data) && flags.female) /* Upolyd */
3878 /*JP
3879         you_can("lay eggs", "");
3880 */
3881         you_can("\97\91\82ð\8eY\82Þ\82±\82Æ\82ª", "");
3882     if (u.ulycn >= LOW_PM) {
3883 #if 0 /*JP*/
3884         /* "you are a werecreature [in beast form]" */
3885         Strcpy(buf, an(mons[u.ulycn].mname));
3886         if (u.umonnum == u.ulycn) {
3887             Strcat(buf, " in beast form");
3888             if (wizard)
3889                 Sprintf(eos(buf), " (%d)", u.mtimedone);
3890         }
3891 #else
3892         /*JP:\81u\82 \82È\82½\82Í[\8fb\82Ì\8ep\82Ì]\81\9b\81\9b\90l\8aÔ\82Å\82 \82é\81v*/
3893         buf[0] = '\0';
3894         if (u.umonnum == u.ulycn) {
3895             Strcpy(buf, "\8fb\82Ì\8ep\82Ì");
3896             if (wizard)
3897                 Sprintf(eos(buf), " (%d)", u.mtimedone);
3898         }
3899         Strcat(buf, mons[u.ulycn].mname);
3900 #endif
3901         you_are(buf, "");
3902     }
3903     if (Unchanging && Upolyd) /* !Upolyd handled above */
3904 /*JP
3905         you_can("not change from your current form", from_what(UNCHANGING));
3906 */
3907         enl_msg("\8d¡\82Ì\8ep\82©\82ç\95Ï\89»\82·\82é\82±\82Æ\82ª\82Å\82«\82È", "\82¢", "\82©\82Á\82½", "", from_what(UNCHANGING));
3908     if (Hate_silver)
3909 /*JP
3910         you_are("harmed by silver", "");
3911 */
3912         enl_msg("\82 \82È\82½\82Í\8bâ\82É\8eã", "\82¢", "\82©\82Á\82½", "", "");
3913     /* movement and non-armor-based protection */
3914     if (Fast)
3915 /*JP
3916         you_are(Very_fast ? "very fast" : "fast", from_what(FAST));
3917 */
3918         you_have(Very_fast ? "\82Æ\82Ä\82à\91f\91\81\82­\8ds\93®\82·\82é\94\\97Í" : "\91f\91\81\82­\8ds\93®\82·\82é\94\\97Í", from_what(FAST));
3919     if (Reflecting)
3920 /*JP
3921         you_have("reflection", from_what(REFLECTING));
3922 */
3923         you_have("\94½\8eË\94\\97Í", from_what(REFLECTING));
3924     if (Free_action)
3925 /*JP
3926         you_have("free action", from_what(FREE_ACTION));
3927 */
3928         you_have("\8dS\91©\82³\82ê\82È\82¢\94\\97Í", from_what(FREE_ACTION));
3929     if (Fixed_abil)
3930 /*JP
3931         you_have("fixed abilities", from_what(FIXED_ABIL));
3932 */
3933         enl_msg("\94\\97Í\82ª\95Ï\89»\82µ\82È", "\82¢", "\82©\82Á\82½", "", from_what(FIXED_ABIL));
3934     if (Lifesaved)
3935 /*JP
3936         enl_msg("Your life ", "will be", "would have been", " saved", "");
3937 */
3938         enl_msg("\82 \82È\82½\82Ì\90\96½\82Í\95Û\91\82³\82ê\82Ä", iru, ita, "", "");
3939
3940     /*** Miscellany ***/
3941     if (Luck) {
3942         ltmp = abs((int) Luck);
3943 #if 0 /*JP:T*/
3944         Sprintf(buf, "%s%slucky",
3945                 ltmp >= 10 ? "extremely " : ltmp >= 5 ? "very " : "",
3946                 Luck < 0 ? "un" : "");
3947 #else
3948         Sprintf(buf, "%s%s",
3949                 ltmp >= 10 ? "\96Ò\97ó\82É" : ltmp >= 5 ? "\82Æ\82Ä\82à" : "",
3950                 Luck < 0 ? "\95s\8dK" : "\8dK\95\9f");
3951 #endif
3952         if (wizard)
3953             Sprintf(eos(buf), " (%d)", Luck);
3954         you_are(buf, "");
3955     } else if (wizard)
3956 /*JP
3957         enl_msg("Your luck ", "is", "was", " zero", "");
3958 */
3959         enl_msg("\82 \82È\82½\82Ì\89^\82Í\83[\83\8d", "\82Å\82 \82é", "\82¾\82Á\82½", "", "");
3960     if (u.moreluck > 0)
3961 /*JP
3962         you_have("extra luck", "");
3963 */
3964         you_have("\82³\82ç\82È\82é\8dK\89^", "");
3965     else if (u.moreluck < 0)
3966 /*JP
3967         you_have("reduced luck", "");
3968 */
3969         you_have("\82³\82ç\82È\82é\95s\89^", "");
3970     if (carrying(LUCKSTONE) || stone_luck(TRUE)) {
3971         ltmp = stone_luck(FALSE);
3972         if (ltmp <= 0)
3973 /*JP
3974             enl_msg("Bad luck ", "does", "did", " not time out for you", "");
3975 */
3976             enl_msg("\95s\89^\82Í\8e\9e\8aÔ\90Ø\82ê\82É\82È\82ç\82È", "\82¢", "\82©\82Á\82½", "", "");
3977         if (ltmp >= 0)
3978 /*JP
3979             enl_msg("Good luck ", "does", "did", " not time out for you", "");
3980 */
3981             enl_msg("\8dK\89^\82Í\8e\9e\8aÔ\90Ø\82ê\82É\82È\82ç\82È", "\82¢", "\82©\82Á\82½", "", "");
3982     }
3983
3984     if (u.ugangr) {
3985 #if 0 /*JP*/
3986         Sprintf(buf, " %sangry with you",
3987                 u.ugangr > 6 ? "extremely " : u.ugangr > 3 ? "very " : "");
3988 #else
3989         Sprintf(buf, "%s\82Í%s\93{\82Á\82Ä%s", u_gname(),
3990                 u.ugangr > 6 ? "\96Ò\97ó\82É" : u.ugangr > 3 ? "\82Æ\82Ä\82à" : "", final ? ita : iru);
3991 #endif
3992         if (wizard)
3993             Sprintf(eos(buf), " (%d)", u.ugangr);
3994 #if 0 /*JP*/
3995         enl_msg(u_gname(), " is", " was", buf, "");
3996 #else
3997         enl_msg(buf, "", "", "", "");
3998 #endif
3999     } else {
4000         /*
4001          * We need to suppress this when the game is over, because death
4002          * can change the value calculated by can_pray(), potentially
4003          * resulting in a false claim that you could have prayed safely.
4004          */
4005         if (!final) {
4006 #if 0 /*JP*/
4007 #if 0
4008             /* "can [not] safely pray" vs "could [not] have safely prayed" */
4009             Sprintf(buf, "%s%ssafely pray%s", can_pray(FALSE) ? "" : "not ",
4010                     final ? "have " : "", final ? "ed" : "");
4011 #else
4012             Sprintf(buf, "%ssafely pray", can_pray(FALSE) ? "" : "not ");
4013 #endif
4014             if (wizard)
4015                 Sprintf(eos(buf), " (%d)", u.ublesscnt);
4016             you_can(buf, "");
4017 #else /*JP*/
4018             Sprintf(buf, "\82 \82È\82½\82Í\88À\91S\82É\8bF\82é\82±\82Æ\82ª");
4019             Strcat(buf, can_pray(FALSE) ? can : "\82Å\82«\82È\82¢");
4020             if (wizard)
4021               Sprintf(eos(buf), " (%d)", u.ublesscnt);
4022             enl_msg(buf, "", "", "", "");
4023 #endif
4024         }
4025     }
4026
4027 #ifdef DEBUG
4028     /* named fruit debugging (doesn't really belong here...); to enable,
4029        include 'fruit' in DEBUGFILES list (even though it isn't a file...) */
4030     if (wizard && explicitdebug("fruit")) {
4031         struct fruit *f;
4032
4033         reorder_fruit(TRUE); /* sort by fruit index, from low to high;
4034                               * this modifies the ffruit chain, so could
4035                               * possibly mask or even introduce a problem,
4036                               * but it does useful sanity checking */
4037         for (f = ffruit; f; f = f->nextf) {
4038 /*JP
4039             Sprintf(buf, "Fruit #%d ", f->fid);
4040 */
4041             Sprintf(buf, "fruit $%d \82Í", f->fid);
4042 /*JP
4043             enl_msg(buf, "is ", "was ", f->fname, "");
4044 */
4045             enl_msg(buf, "\82¾", "\82¾\82Á\82½", f->fname, "");
4046         }
4047 /*JP
4048         enl_msg("The current fruit ", "is ", "was ", pl_fruit, "");
4049 */
4050         enl_msg("\8c»\8dÝ\82Ì fruit \82Í", "\82¾", "\82¾\82Á\82½", pl_fruit, "");
4051         Sprintf(buf, "%d", flags.made_fruit);
4052 /*JP
4053         enl_msg("The made fruit flag ", "is ", "was ", buf, "");
4054 */
4055         enl_msg("made fruit flag \82Í", "\82¾", "\82¾\82Á\82½", buf, "");
4056     }
4057 #endif
4058
4059     {
4060         const char *p;
4061
4062         buf[0] = '\0';
4063         if (final < 2) { /* still in progress, or quit/escaped/ascended */
4064 /*JP
4065             p = "survived after being killed ";
4066 */
4067             p = "\8e\80\82ñ\82¾\8cã\95\9c\8a\88\82µ\82Ä\82¢\82½";
4068             switch (u.umortality) {
4069             case 0:
4070 /*JP
4071                 p = !final ? (char *) 0 : "survived";
4072 */
4073                 p = !final ? (char *)0 : "\90\82«\89\84\82Ñ\82½";
4074                 break;
4075             case 1:
4076 /*JP
4077                 Strcpy(buf, "once");
4078 */
4079                 Strcpy(buf, "\88ê\93x");
4080                 break;
4081             case 2:
4082 /*JP
4083                 Strcpy(buf, "twice");
4084 */
4085                 Strcpy(buf, "\93ñ\93x");
4086                 break;
4087             case 3:
4088 /*JP
4089                 Strcpy(buf, "thrice");
4090 */
4091                 Strcpy(buf, "\8eO\93x");
4092                 break;
4093             default:
4094 /*JP
4095                 Sprintf(buf, "%d times", u.umortality);
4096 */
4097                 Sprintf(buf, "%d\89ñ", u.umortality);
4098                 break;
4099             }
4100         } else { /* game ended in character's death */
4101 /*JP
4102             p = "are dead";
4103 */
4104             p = "\8e\80\82ñ\82Å\82¢\82é";
4105             switch (u.umortality) {
4106             case 0:
4107                 impossible("dead without dying?");
4108             case 1:
4109                 break; /* just "are dead" */
4110             default:
4111 #if 0 /*JP:T*/
4112                 Sprintf(buf, " (%d%s time!)", u.umortality,
4113                         ordin(u.umortality));
4114 #else
4115                  Sprintf(buf, "(%d\89ñ\81I)", u.umortality);
4116 #endif
4117                 break;
4118             }
4119         }
4120         if (p)
4121 /*JP
4122             enl_msg(You_, "have been killed ", p, buf, "");
4123 */
4124             enl_msg(You_, "\8e\80\82ñ\82Å\82¢\82é", p, buf, "");
4125     }
4126 }
4127
4128 #if 0  /* no longer used */
4129 STATIC_DCL boolean NDECL(minimal_enlightenment);
4130
4131 /*
4132  * Courtesy function for non-debug, non-explorer mode players
4133  * to help refresh them about who/what they are.
4134  * Returns FALSE if menu cancelled (dismissed with ESC), TRUE otherwise.
4135  */
4136 STATIC_OVL boolean
4137 minimal_enlightenment()
4138 {
4139     winid tmpwin;
4140     menu_item *selected;
4141     anything any;
4142     int genidx, n;
4143     char buf[BUFSZ], buf2[BUFSZ];
4144     static const char untabbed_fmtstr[] = "%-15s: %-12s";
4145     static const char untabbed_deity_fmtstr[] = "%-17s%s";
4146     static const char tabbed_fmtstr[] = "%s:\t%-12s";
4147     static const char tabbed_deity_fmtstr[] = "%s\t%s";
4148     static const char *fmtstr;
4149     static const char *deity_fmtstr;
4150
4151     fmtstr = iflags.menu_tab_sep ? tabbed_fmtstr : untabbed_fmtstr;
4152     deity_fmtstr = iflags.menu_tab_sep ? tabbed_deity_fmtstr
4153                                        : untabbed_deity_fmtstr;
4154     any = zeroany;
4155     buf[0] = buf2[0] = '\0';
4156     tmpwin = create_nhwindow(NHW_MENU);
4157     start_menu(tmpwin);
4158     add_menu(tmpwin, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
4159 /*JP
4160              "Starting", FALSE);
4161 */
4162              "\8aJ\8en", FALSE);
4163
4164     /* Starting name, race, role, gender */
4165 /*JP
4166     Sprintf(buf, fmtstr, "name", plname);
4167 */
4168     Sprintf(buf, fmtstr, "\96¼\91O", plname);
4169     add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4170 /*JP
4171     Sprintf(buf, fmtstr, "race", urace.noun);
4172 */
4173     Sprintf(buf, fmtstr, "\8eí\91°", urace.noun);
4174     add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4175 /*JP
4176     Sprintf(buf, fmtstr, "role",
4177 */
4178     Sprintf(buf, fmtstr, "\90E\8bÆ",
4179             (flags.initgend && urole.name.f) ? urole.name.f : urole.name.m);
4180     add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4181 /*JP
4182     Sprintf(buf, fmtstr, "gender", genders[flags.initgend].adj);
4183 */
4184     Sprintf(buf, fmtstr, "\90«\95Ê", genders[flags.initgend].adj);
4185     add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4186
4187     /* Starting alignment */
4188 /*JP
4189     Sprintf(buf, fmtstr, "alignment", align_str(u.ualignbase[A_ORIGINAL]));
4190 */
4191     Sprintf(buf, fmtstr, "\91®\90«", align_str(u.ualignbase[A_ORIGINAL]));
4192     add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4193
4194     /* Current name, race, role, gender */
4195     add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, "", FALSE);
4196     add_menu(tmpwin, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
4197 /*JP
4198              "Current", FALSE);
4199 */
4200              "\8c»\8dÝ", FALSE);
4201 /*JP
4202     Sprintf(buf, fmtstr, "race", Upolyd ? youmonst.data->mname : urace.noun);
4203 */
4204     Sprintf(buf, fmtstr, "\8eí\91°", Upolyd ? youmonst.data->mname : urace.noun);
4205     add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4206     if (Upolyd) {
4207 /*JP
4208         Sprintf(buf, fmtstr, "role (base)",
4209 */
4210         Sprintf(buf, fmtstr, "\90E\8bÆ(\8aî\96{)",
4211                 (u.mfemale && urole.name.f) ? urole.name.f
4212                                             : urole.name.m);
4213         add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4214     } else {
4215 /*JP
4216         Sprintf(buf, fmtstr, "role",
4217 */
4218         Sprintf(buf, fmtstr, "\90E\8bÆ",
4219                 (flags.female && urole.name.f) ? urole.name.f
4220                                                : urole.name.m);
4221         add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4222     }
4223     /* don't want poly_gender() here; it forces `2' for non-humanoids */
4224     genidx = is_neuter(youmonst.data) ? 2 : flags.female;
4225 /*JP
4226     Sprintf(buf, fmtstr, "gender", genders[genidx].adj);
4227 */
4228     Sprintf(buf, fmtstr, "\90«\95Ê", genders[genidx].adj);
4229     add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4230     if (Upolyd && (int) u.mfemale != genidx) {
4231 /*JP
4232         Sprintf(buf, fmtstr, "gender (base)", genders[u.mfemale].adj);
4233 */
4234         Sprintf(buf, fmtstr, "\90«\95Ê(\8aî\96{)", genders[u.mfemale].adj);
4235         add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4236     }
4237
4238     /* Current alignment */
4239 /*JP
4240     Sprintf(buf, fmtstr, "alignment", align_str(u.ualign.type));
4241 */
4242     Sprintf(buf, fmtstr, "\91®\90«", align_str(u.ualign.type));
4243     add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4244
4245     /* Deity list */
4246     add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, "", FALSE);
4247     add_menu(tmpwin, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
4248 /*JP
4249              "Deities", FALSE);
4250 */
4251              "\90_", FALSE);
4252 #if 0 /*JP:T*/
4253     Sprintf(buf2, deity_fmtstr, align_gname(A_CHAOTIC),
4254             (u.ualignbase[A_ORIGINAL] == u.ualign.type
4255              && u.ualign.type == A_CHAOTIC)               ? " (s,c)"
4256                 : (u.ualignbase[A_ORIGINAL] == A_CHAOTIC) ? " (s)"
4257                 : (u.ualign.type   == A_CHAOTIC)          ? " (c)" : "");
4258 #else
4259     Sprintf(buf2, deity_fmtstr, align_gname(A_CHAOTIC),
4260             (u.ualignbase[A_ORIGINAL] == u.ualign.type
4261              && u.ualign.type == A_CHAOTIC)               ? " (\8f\89\81C\8c»)"
4262                 : (u.ualignbase[A_ORIGINAL] == A_CHAOTIC) ? " (\8f\89)"
4263                 : (u.ualign.type   == A_CHAOTIC)          ? " (\8c»)" : "");
4264 #endif
4265 /*JP
4266     Sprintf(buf, fmtstr, "Chaotic", buf2);
4267 */
4268     Sprintf(buf, fmtstr, "\8d¬\93×", buf2);
4269     add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4270
4271 #if 0 /*JP:T*/
4272     Sprintf(buf2, deity_fmtstr, align_gname(A_NEUTRAL),
4273             (u.ualignbase[A_ORIGINAL] == u.ualign.type
4274              && u.ualign.type == A_NEUTRAL)               ? " (s,c)"
4275                 : (u.ualignbase[A_ORIGINAL] == A_NEUTRAL) ? " (s)"
4276                 : (u.ualign.type   == A_NEUTRAL)          ? " (c)" : "");
4277 #else
4278     Sprintf(buf2, deity_fmtstr, align_gname(A_NEUTRAL),
4279             (u.ualignbase[A_ORIGINAL] == u.ualign.type
4280              && u.ualign.type == A_NEUTRAL)               ? " (\8f\89\81C\8c»)"
4281                 : (u.ualignbase[A_ORIGINAL] == A_NEUTRAL) ? " (\8f\89)"
4282                 : (u.ualign.type   == A_NEUTRAL)          ? " (\8c»)" : "");
4283 #endif
4284 /*JP
4285     Sprintf(buf, fmtstr, "Neutral", buf2);
4286 */
4287     Sprintf(buf, fmtstr, "\92\86\97§", buf2);
4288     add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4289
4290 #if 0 /*JP:T*/
4291     Sprintf(buf2, deity_fmtstr, align_gname(A_LAWFUL),
4292             (u.ualignbase[A_ORIGINAL] == u.ualign.type
4293              && u.ualign.type == A_LAWFUL)                ? " (s,c)"
4294                 : (u.ualignbase[A_ORIGINAL] == A_LAWFUL)  ? " (s)"
4295                 : (u.ualign.type   == A_LAWFUL)           ? " (c)" : "");
4296 #else
4297     Sprintf(buf2, deity_fmtstr, align_gname(A_LAWFUL),
4298             (u.ualignbase[A_ORIGINAL] == u.ualign.type
4299              && u.ualign.type == A_LAWFUL)                ? " (\8f\89\81C\8c»)"
4300                 : (u.ualignbase[A_ORIGINAL] == A_LAWFUL)  ? " (\8f\89)"
4301                 : (u.ualign.type   == A_LAWFUL)           ? " (\8c»)" : "");
4302 #endif
4303 /*JP
4304     Sprintf(buf, fmtstr, "Lawful", buf2);
4305 */
4306     Sprintf(buf, fmtstr, "\92\81\8f\98", buf2);
4307     add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
4308
4309 /*JP
4310     end_menu(tmpwin, "Base Attributes");
4311 */
4312     end_menu(tmpwin, "\8aî\96{\91®\90«");
4313     n = select_menu(tmpwin, PICK_NONE, &selected);
4314     destroy_nhwindow(tmpwin);
4315     return (boolean) (n != -1);
4316 }
4317 #endif /*0*/
4318
4319 /* ^X command */
4320 STATIC_PTR int
4321 doattributes(VOID_ARGS)
4322 {
4323     int mode = BASICENLIGHTENMENT;
4324
4325     /* show more--as if final disclosure--for wizard and explore modes */
4326     if (wizard || discover)
4327         mode |= MAGICENLIGHTENMENT;
4328
4329     enlightenment(mode, ENL_GAMEINPROGRESS);
4330     return 0;
4331 }
4332
4333 void
4334 youhiding(via_enlghtmt, msgflag)
4335 boolean via_enlghtmt; /* englightment line vs topl message */
4336 int msgflag;          /* for variant message phrasing */
4337 {
4338     char *bp, buf[BUFSZ];
4339
4340 /*JP
4341     Strcpy(buf, "hiding");
4342 */
4343     Strcpy(buf, "\89B\82ê");
4344     if (U_AP_TYPE != M_AP_NOTHING) {
4345         /* mimic; hero is only able to mimic a strange object or gold
4346            or hallucinatory alternative to gold, so we skip the details
4347            for the hypothetical furniture and monster cases */
4348 #if 0 /*JP*//*\8cã\82ë\82É\89ñ\82·*//* not used */
4349         bp = eos(strcpy(buf, "mimicking"));
4350 #endif
4351         if (U_AP_TYPE == M_AP_OBJECT) {
4352 /*JP
4353             Sprintf(bp, " %s", an(simple_typename(youmonst.mappearance)));
4354 */
4355             Strcpy(buf, simple_typename(youmonst.mappearance));
4356         } else if (U_AP_TYPE == M_AP_FURNITURE) {
4357 /*JP
4358             Strcpy(bp, " something");
4359 */
4360             Strcpy(buf, "\89½\82©");
4361         } else if (U_AP_TYPE == M_AP_MONSTER) {
4362 /*JP
4363             Strcpy(bp, " someone");
4364 */
4365             Strcpy(buf, "\89½\8eÒ\82©");
4366         } else {
4367             ; /* something unexpected; leave 'buf' as-is */
4368         }
4369 #if 1 /*JP*//*\82±\82±\82Å\92Ç\89Á*/
4370         Strcat(buf, "\82Ì\82Ó\82è\82ð\82µ");
4371 #endif
4372     } else if (u.uundetected) {
4373         bp = eos(buf); /* points past "hiding" */
4374         if (youmonst.data->mlet == S_EEL) {
4375             if (is_pool(u.ux, u.uy))
4376 /*JP
4377                 Sprintf(bp, " in the %s", waterbody_name(u.ux, u.uy));
4378 */
4379                 Sprintf(bp, "%s\82Ì\92\86\82É", waterbody_name(u.ux, u.uy));
4380         } else if (hides_under(youmonst.data)) {
4381             struct obj *o = level.objects[u.ux][u.uy];
4382
4383             if (o)
4384 /*JP
4385                 Sprintf(bp, " underneath %s", ansimpleoname(o));
4386 */
4387                 Sprintf(bp, "%s\82Ì\89º\82É", ansimpleoname(o));
4388         } else if (is_clinger(youmonst.data) || Flying) {
4389             /* Flying: 'lurker above' hides on ceiling but doesn't cling */
4390 /*JP
4391             Sprintf(bp, " on the %s", ceiling(u.ux, u.uy));
4392 */
4393             Sprintf(bp, "%s\82É", ceiling(u.ux, u.uy));
4394         } else {
4395             /* on floor; is_hider() but otherwise not special: 'trapper' */
4396             if (u.utrap && u.utraptype == TT_PIT) {
4397                 struct trap *t = t_at(u.ux, u.uy);
4398
4399 #if 0 /*JP:T*/
4400                 Sprintf(bp, " in a %spit",
4401                         (t && t->ttyp == SPIKED_PIT) ? "spiked " : "");
4402 #else
4403                 Sprintf(bp, "%s\97\8e\82µ\8c\8a\82Ì\92\86\82É",
4404                         (t && t->ttyp == SPIKED_PIT) ? "\83g\83Q\82¾\82ç\82¯\82Ì" : "");
4405 #endif
4406             } else
4407 /*JP
4408                 Sprintf(bp, " on the %s", surface(u.ux, u.uy));
4409 */
4410                 Sprintf(bp, "%s\82É", surface(u.ux, u.uy));
4411         }
4412 #if 1 /*JP*//*\82±\82±\82Å\92Ç\89Á*/
4413         Strcat(buf, "\89B\82ê");
4414 #endif
4415     } else {
4416         ; /* shouldn't happen; will result in generic "you are hiding" */
4417     }
4418
4419     if (via_enlghtmt) {
4420         int final = msgflag; /* 'final' is used by you_are() macro */
4421
4422         you_are(buf, "");
4423     } else {
4424         /* for dohide(), when player uses '#monster' command */
4425 #if 0 /*JP*/
4426         You("are %s %s.", msgflag ? "already" : "now", buf);
4427 #else
4428         if (msgflag) {
4429             You("\82·\82Å\82É%s\82Ä\82¢\82é\81D", buf);
4430         } else {
4431             You("%s\82½\81D", buf);
4432         }
4433 #endif
4434     }
4435 }
4436
4437 /* KMH, #conduct
4438  * (shares enlightenment's tense handling)
4439  */
4440 int
4441 doconduct(VOID_ARGS)
4442 {
4443     show_conduct(0);
4444     return 0;
4445 }
4446
4447 void
4448 show_conduct(final)
4449 int final;
4450 {
4451     char buf[BUFSZ];
4452     int ngenocided;
4453
4454     /* Create the conduct window */
4455     en_win = create_nhwindow(NHW_MENU);
4456 /*JP
4457     putstr(en_win, 0, "Voluntary challenges:");
4458 */
4459     putstr(en_win, 0, "\8e©\94­\93I\92§\90í:");
4460
4461     if (u.uroleplay.blind)
4462 /*JP
4463         you_have_been("blind from birth");
4464 */
4465         you_have_been("\90\82Ü\82ê\82È\82ª\82ç\82É\96Ó\96Ú");
4466     if (u.uroleplay.nudist)
4467 /*JP
4468         you_have_been("faithfully nudist");
4469 */
4470         you_have_been("\92\89\8eÀ\82È\97\87\91°");
4471
4472     if (!u.uconduct.food)
4473 /*JP
4474         enl_msg(You_, "have gone", "went", " without food", "");
4475 */
4476         enl_msg("\82 \82È\82½\82Í\90H\8e\96\82ð\82µ", "\82Ä\82¢\82È\82¢", "\82È\82©\82Á\82½", "", "");
4477         /* but beverages are okay */
4478     else if (!u.uconduct.unvegan)
4479 /*JP
4480         you_have_X("followed a strict vegan diet");
4481 */
4482         you_have_been("\8cµ\8ai\82È\8dØ\90H\8eå\8b`\8eÒ");
4483     else if (!u.uconduct.unvegetarian)
4484 /*JP
4485         you_have_been("vegetarian");
4486 */
4487         you_have_been("\8dØ\90H\8eå\8b`\8eÒ");
4488
4489     if (!u.uconduct.gnostic)
4490 /*JP
4491         you_have_been("an atheist");
4492 */
4493         you_have_been("\96³\90_\98_\8eÒ");
4494
4495     if (!u.uconduct.weaphit) {
4496 /*JP
4497         you_have_never("hit with a wielded weapon");
4498 */
4499         you_have_never("\82 \82È\82½\82Í\91\95\94õ\82µ\82Ä\82¢\82é\95\90\8aí\82Å\8dU\8c\82\82µ");
4500     } else if (wizard) {
4501 #if 0 /*JP:T*/
4502         Sprintf(buf, "used a wielded weapon %ld time%s", u.uconduct.weaphit,
4503                 plur(u.uconduct.weaphit));
4504         you_have_X(buf);
4505 #else
4506         Sprintf(buf, "\82 \82È\82½\82Í%ld\89ñ\91\95\94õ\82µ\82½\95\90\8aí\82ð\8eg\97p\82µ", u.uconduct.weaphit);
4507         you_have_X(buf);
4508 #endif
4509     }
4510     if (!u.uconduct.killer)
4511 /*JP
4512         you_have_been("a pacifist");
4513 */
4514         you_have_been("\95½\98a\8eå\8b`\8eÒ");
4515
4516     if (!u.uconduct.literate) {
4517 /*JP
4518         you_have_been("illiterate");
4519 */
4520         you_have_never("\82 \82È\82½\82Í\93Ç\82Ý\8f\91\82«\82µ");
4521     } else if (wizard) {
4522 #if 0 /*JP:T*/
4523         Sprintf(buf, "read items or engraved %ld time%s", u.uconduct.literate,
4524                 plur(u.uconduct.literate));
4525         you_have_X(buf);
4526 #else
4527         Sprintf(buf, "%ld\89ñ\93Ç\82ñ\82¾\82è\8f\91\82¢\82½\82è\82µ", u.uconduct.literate);
4528         you_have_X(buf);
4529 #endif
4530     }
4531
4532     ngenocided = num_genocides();
4533     if (ngenocided == 0) {
4534 /*JP
4535         you_have_never("genocided any monsters");
4536 */
4537         you_have_never("\82 \82È\82½\82Í\89ö\95¨\82ð\8bs\8eE\82µ");
4538     } else {
4539 #if 0 /*JP:T*/
4540         Sprintf(buf, "genocided %d type%s of monster%s", ngenocided,
4541                 plur(ngenocided), plur(ngenocided));
4542         you_have_X(buf);
4543 #else
4544         Sprintf(buf, "%d\8eí\82Ì\89ö\95¨\82ð\8bs\8eE\82µ", ngenocided);
4545         you_have_X(buf);
4546 #endif
4547     }
4548
4549     if (!u.uconduct.polypiles) {
4550 /*JP
4551         you_have_never("polymorphed an object");
4552 */
4553         you_have_never("\82 \82È\82½\82Í\95¨\91Ì\82ð\95Ï\89»\82³\82¹");
4554     } else if (wizard) {
4555 #if 0 /*JP:T*/
4556         Sprintf(buf, "polymorphed %ld item%s", u.uconduct.polypiles,
4557                 plur(u.uconduct.polypiles));
4558         you_have_X(buf);
4559 #else
4560         Sprintf(buf, "%ld\8cÂ\82Ì\95¨\82ð\95Ï\89»\82³\82¹", u.uconduct.polypiles);
4561         you_have_X(buf);
4562 #endif
4563     }
4564
4565     if (!u.uconduct.polyselfs) {
4566 /*JP
4567         you_have_never("changed form");
4568 */
4569         you_have_never("\82 \82È\82½\82Í\95Ï\89»\82µ");
4570     } else if (wizard) {
4571 #if 0 /*JP:T*/
4572         Sprintf(buf, "changed form %ld time%s", u.uconduct.polyselfs,
4573                 plur(u.uconduct.polyselfs));
4574         you_have_X(buf);
4575 #else
4576         Sprintf(buf, "%ld\89ñ\8ep\82ð\95Ï\82¦", u.uconduct.polyselfs);
4577         you_have_X(buf);
4578 #endif
4579     }
4580
4581     if (!u.uconduct.wishes) {
4582 /*JP
4583         you_have_X("used no wishes");
4584 */
4585         you_have_never("\82 \82È\82½\82Í\8aè\82¢\8e\96\82ð\82µ");
4586     } else {
4587 #if 0 /*JP:T*/
4588         Sprintf(buf, "used %ld wish%s", u.uconduct.wishes,
4589                 (u.uconduct.wishes > 1L) ? "es" : "");
4590 #else
4591         Sprintf(buf, "%ld\89ñ\8aè\82¢\8e\96\82ð\82µ", u.uconduct.wishes);
4592 #endif
4593         if (u.uconduct.wisharti) {
4594             /* if wisharti == wishes
4595              *  1 wish (for an artifact)
4596              *  2 wishes (both for artifacts)
4597              *  N wishes (all for artifacts)
4598              * else (N is at least 2 in order to get here; M < N)
4599              *  N wishes (1 for an artifact)
4600              *  N wishes (M for artifacts)
4601              */
4602 #if 0 /*JP*/
4603             if (u.uconduct.wisharti == u.uconduct.wishes)
4604                 Sprintf(eos(buf), " (%s",
4605                         (u.uconduct.wisharti > 2L) ? "all "
4606                           : (u.uconduct.wisharti == 2L) ? "both " : "");
4607             else
4608                 Sprintf(eos(buf), " (%ld ", u.uconduct.wisharti);
4609
4610             Sprintf(eos(buf), "for %s)",
4611                     (u.uconduct.wisharti == 1L) ? "an artifact"
4612                                                 : "artifacts");
4613 #else
4614             Sprintf(eos(buf), " (\90¹\8aí\82Í%ld\89ñ)", u.uconduct.wisharti);
4615 #endif
4616         }
4617         you_have_X(buf);
4618
4619         if (!u.uconduct.wisharti)
4620 #if 0 /*JP*/
4621             enl_msg(You_, "have not wished", "did not wish",
4622                     " for any artifacts", "");
4623 #else
4624             enl_msg("\82 \82È\82½\82Í\90¹\8aí\82ð\8aè", "\82Á\82Ä\82¢\82È\82¢", "\82í\82È\82©\82Á\82½", "", "");
4625 #endif
4626     }
4627
4628     /* Pop up the window and wait for a key */
4629     display_nhwindow(en_win, TRUE);
4630     destroy_nhwindow(en_win);
4631     en_win = WIN_ERR;
4632 }
4633
4634 /* ordered by command name */
4635 struct ext_func_tab extcmdlist[] = {
4636 #if 0 /*JP:T*/
4637     { '#', "#", "perform an extended command",
4638 #else
4639     { '#', "#", "\8ag\92£\83R\83}\83\93\83h\82ð\8eÀ\8ds\82·\82é",
4640 #endif
4641             doextcmd, IFBURIED | GENERALCMD },
4642 #if 0 /*JP:T*/
4643     { M('?'), "?", "list all extended commands",
4644 #else
4645     { M('?'), "?", "\8ag\92£\83R\83}\83\93\83h\88ê\97\97\82ð\95\\8e¦\82·\82é",
4646 #endif
4647             doextlist, IFBURIED | AUTOCOMPLETE | GENERALCMD },
4648 #if 0 /*JP:T*/
4649     { M('a'), "adjust", "adjust inventory letters",
4650 #else
4651     { M('a'), "adjust", "\8e\9d\82¿\95¨\88ê\97\97\82Ì\92²\90®",
4652 #endif
4653             doorganize, IFBURIED | AUTOCOMPLETE },
4654 #if 0 /*JP:T*/
4655     { M('A'), "annotate", "name current level",
4656 #else
4657     { M('A'), "annotate", "\8c»\8dÝ\82Ì\8aK\82É\96¼\91O\82ð\82Â\82¯\82é",
4658 #endif
4659             donamelevel, IFBURIED | AUTOCOMPLETE },
4660 #if 0 /*JP:T*/
4661     { 'a', "apply", "apply (use) a tool (pick-axe, key, lamp...)",
4662 #else
4663     { 'a', "apply", "\93¹\8bï\82ð\8eg\82¤\81D(\82Â\82é\82Í\82µ, \8c®, \83\89\83\93\83v\81c)",
4664 #endif
4665             doapply },
4666 #if 0 /*JP:T*/
4667     { C('x'), "attributes", "show your attributes",
4668 #else
4669     { C('x'), "attributes", "\91®\90«\82ð\95\\8e¦\82·\82é",
4670 #endif
4671             doattributes, IFBURIED },
4672 #if 0 /*JP:T*/
4673     { '@', "autopickup", "toggle the pickup option on/off",
4674 #else
4675     { '@', "autopickup", "\8e©\93®\8fE\82¢\83I\83v\83V\83\87\83\93\82ð\90Ø\82è\91Ö\82¦\82é",
4676 #endif
4677             dotogglepickup, IFBURIED },
4678 #if 0 /*JP:T*/
4679     { 'C', "call", "call (name) something", docallcmd, IFBURIED },
4680 #else
4681     { 'C', "call", "\96¼\91O\82ð\82Â\82¯\82é", docallcmd, IFBURIED },
4682 #endif
4683 #if 0 /*JP:T*/
4684     { 'Z', "cast", "zap (cast) a spell", docast, IFBURIED },
4685 #else
4686     { 'Z', "cast", "\8eô\95\82ð\8f¥\82¦\82é", docast, IFBURIED },
4687 #endif
4688 #if 0 /*JP:T*/
4689     { M('c'), "chat", "talk to someone", dotalk, IFBURIED | AUTOCOMPLETE },
4690 #else
4691     { M('c'), "chat", "\92N\82©\82Æ\98b\82·", dotalk, IFBURIED | AUTOCOMPLETE },
4692 #endif
4693 #if 0 /*JP:T*/
4694     { 'c', "close", "close a door", doclose },
4695 #else
4696     { 'c', "close", "\83h\83A\82ð\95Â\82ß\82é", doclose },
4697 #endif
4698 #if 0 /*JP:T*/
4699     { M('C'), "conduct", "list voluntary challenges you have maintained",
4700 #else
4701     { M('C'), "conduct", "\82Ç\82¤\82¢\82¤\8ds\93®\82ð\82Æ\82Á\82½\82©\8c©\82é",
4702 #endif
4703             doconduct, IFBURIED | AUTOCOMPLETE },
4704 #if 0 /*JP:T*/
4705     { M('d'), "dip", "dip an object into something", dodip, AUTOCOMPLETE },
4706 #else
4707     { M('d'), "dip", "\89½\82©\82É\95¨\82ð\90Z\82·", dodip, AUTOCOMPLETE },
4708 #endif
4709 #if 0 /*JP:T*/
4710     { '>', "down", "go down a staircase", dodown },
4711 #else
4712     { '>', "down", "\8aK\92i\82ð\8d~\82è\82ée", dodown },
4713 #endif
4714 #if 0 /*JP:T*/
4715     { 'd', "drop", "drop an item", dodrop },
4716 #else
4717     { 'd', "drop", "\95¨\82ð\92u\82­", dodrop },
4718 #endif
4719 #if 0 /*JP:T*/
4720     { 'D', "droptype", "drop specific item types", doddrop },
4721 #else
4722     { 'D', "droptype", "\8ew\92è\82µ\82½\8eí\97Þ\82Ì\95¨\82ð\92u\82­", doddrop },
4723 #endif
4724 #if 0 /*JP:T*/
4725     { 'e', "eat", "eat something", doeat },
4726 #else
4727     { 'e', "eat", "\89½\82©\82ð\90H\82×\82é", doeat },
4728 #endif
4729 #if 0 /*JP:T*/
4730     { 'E', "engrave", "engrave writing on the floor", doengrave },
4731 #else
4732     { 'E', "engrave", "\8f°\82É\95\8e\9a\82ð\8f\91\82­", doengrave },
4733 #endif
4734 #if 0 /*JP:T*/
4735     { M('e'), "enhance", "advance or check weapon and spell skills",
4736 #else
4737     { M('e'), "enhance", "\95\90\8aí\8fn\97û\93x\82ð\8d\82\82ß\82é",
4738 #endif
4739             enhance_weapon_skill, IFBURIED | AUTOCOMPLETE },
4740 #if 0 /*JP:T*/
4741     { '\0', "exploremode", "enter explore (discovery) mode",
4742 #else
4743     { '\0', "exploremode", "\92T\8c\9f(\94­\8c©)\83\82\81[\83h\82É\93ü\82é",
4744 #endif
4745             enter_explore_mode, IFBURIED },
4746 #if 0 /*JP:T*/
4747     { 'f', "fire", "fire ammunition from quiver", dofire },
4748 #else
4749     { 'f', "fire", "\91\95\93U\82³\82ê\82½\95¨\82ð\8eË\82é", dofire },
4750 #endif
4751 #if 0 /*JP:T*/
4752     { M('f'), "force", "force a lock", doforce, AUTOCOMPLETE },
4753 #else
4754     { M('f'), "force", "\8c®\82ð\82±\82\82 \82¯\82é", doforce, AUTOCOMPLETE },
4755 #endif
4756 #if 0 /*JP:T*/
4757     { ';', "glance", "show what type of thing a map symbol corresponds to",
4758 #else
4759     { ';', "glance", "\92n\90}\8fã\82Ì\83V\83\93\83{\83\8b\82ª\89½\82É\91Î\89\9e\82·\82é\82©\82ð\8c©\82é",
4760 #endif
4761             doquickwhatis, IFBURIED | GENERALCMD },
4762 #if 0 /*JP:T*/
4763     { '?', "help", "give a help message", dohelp, IFBURIED | GENERALCMD },
4764 #else
4765     { '?', "help", "\83w\83\8b\83v\83\81\83b\83Z\81[\83W\82ð\95\\8e¦\82·\82é", dohelp, IFBURIED | GENERALCMD },
4766 #endif
4767 #if 0 /*JP:T*/
4768     { '\0', "herecmdmenu", "show menu of commands you can do here",
4769 #else
4770     { '\0', "herecmdmenu", "\82±\82±\82Å\8fo\97\88\82é\83R\83}\83\93\83h\82Ì\83\81\83j\83\85\81[\82ð\95\\8e¦\82·\82é",
4771 #endif
4772             doherecmdmenu, IFBURIED },
4773 #if 0 /*JP:T*/
4774     { 'V', "history", "show long version and game history",
4775 #else
4776     { 'V', "history", "\92·\82¢\83o\81[\83W\83\87\83\93\82Æ\83Q\81[\83\80\82Ì\97ð\8ej\82ð\95\\8e¦\82·\82é",
4777 #endif
4778             dohistory, IFBURIED | GENERALCMD },
4779 #if 0 /*JP:T*/
4780     { 'i', "inventory", "show your inventory", ddoinv, IFBURIED },
4781 #else
4782     { 'i', "inventory", "\8e\9d\95¨\82ð\95\\8e¦\82·\82é", ddoinv, IFBURIED },
4783 #endif
4784 #if 0 /*JP:T*/
4785     { 'I', "inventtype", "inventory specific item types",
4786 #else
4787     { 'I', "inventtype", "\8ew\92è\82µ\82½\8eí\97Þ\82Ì\8e\9d\95¨\82ð\8c©\82é",
4788 #endif
4789             dotypeinv, IFBURIED },
4790 #if 0 /*JP:T*/
4791     { M('i'), "invoke", "invoke an object's special powers",
4792 #else
4793     { M('i'), "invoke", "\95¨\82Ì\93Á\95Ê\82È\97Í\82ð\8eg\82¤",
4794 #endif
4795             doinvoke, IFBURIED | AUTOCOMPLETE },
4796 #if 0 /*JP:T*/
4797     { M('j'), "jump", "jump to another location", dojump, AUTOCOMPLETE },
4798 #else
4799     { M('j'), "jump", "\91¼\82Ì\88Ê\92u\82É\94ò\82Ñ\82¤\82Â\82é", dojump, AUTOCOMPLETE },
4800 #endif
4801 #if 0 /*JP:T*/
4802     { C('d'), "kick", "kick something", dokick },
4803 #else
4804     { C('d'), "kick", "\89½\82©\82ð\8fR\82é", dokick },
4805 #endif
4806 #if 0 /*JP:T*/
4807     { '\\', "known", "show what object types have been discovered",
4808 #else
4809     { '\\', "known", "\94­\8c©\82µ\82½\95¨\82Ì\8eí\97Þ\82ð\95\\8e¦\82·\82é",
4810 #endif
4811             dodiscovered, IFBURIED | GENERALCMD },
4812 #if 0 /*JP:T*/
4813     { '`', "knownclass", "show discovered types for one class of objects",
4814 #else
4815     { '`', "knownclass", "\88ê\82Â\82Ì\8eí\97Þ\82Ì\92\86\82Å\94­\8c©\82µ\82½\95¨\82ð\95\\8e¦\82·\82é",
4816 #endif
4817             doclassdisco, IFBURIED | GENERALCMD },
4818 #if 0 /*JP:T*/
4819     { '\0', "levelchange", "change experience level",
4820 #else
4821     { '\0', "levelchange", "\8co\8c±\83\8c\83x\83\8b\82ð\95Ï\82¦\82é",
4822 #endif
4823             wiz_level_change, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4824 #if 0 /*JP:T*/
4825     { '\0', "lightsources", "show mobile light sources",
4826 #else
4827     { '\0', "lightsources", "\88Ú\93®\8cõ\8c¹\82ð\8c©\82é",
4828 #endif
4829             wiz_light_sources, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4830 #if 0 /*JP:T*/
4831     { ':', "look", "look at what is here", dolook, IFBURIED },
4832 #else
4833     { ':', "look", "\82±\82±\82É\89½\82ª\82 \82é\82Ì\82©\8c©\82é", dolook, IFBURIED },
4834 #endif
4835 #if 0 /*JP:T*/
4836     { M('l'), "loot", "loot a box on the floor", doloot, AUTOCOMPLETE },
4837 #else
4838     { M('l'), "loot", "\8f°\82Ì\8fã\82Ì\94 \82ð\8aJ\82¯\82é", doloot, AUTOCOMPLETE },
4839 #endif
4840 #ifdef DEBUG_MIGRATING_MONS
4841 #if 0 /*JP:T*/
4842     { '\0', "migratemons", "migrate N random monsters",
4843 #else
4844     { '\0', "migratemons", "\83\89\83\93\83_\83\80\82È\89ö\95¨\82ð\89½\91Ì\82©\88Ú\8fZ\82³\82¹\82é",
4845 #endif
4846             wiz_migrate_mons, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4847 #endif
4848 #if 0 /*JP:T*/
4849     { M('m'), "monster", "use monster's special ability",
4850 #else
4851     { M('m'), "monster", "\89ö\95¨\82Ì\93Á\95Ê\94\\97Í\82ð\8eg\82¤",
4852 #endif
4853             domonability, IFBURIED | AUTOCOMPLETE },
4854 #if 0 /*JP:T*/
4855     { 'N', "name", "name a monster or an object",
4856 #else
4857     { 'N', "name", "\83A\83C\83e\83\80\82â\95¨\82É\96¼\91O\82ð\82Â\82¯\82é",
4858 #endif
4859             docallcmd, IFBURIED | AUTOCOMPLETE },
4860 #if 0 /*JP:T*/
4861     { M('o'), "offer", "offer a sacrifice to the gods",
4862 #else
4863     { M('o'), "offer", "\90_\82É\8b\9f\95¨\82ð\95ù\82°\82é",
4864 #endif
4865             dosacrifice, AUTOCOMPLETE },
4866 #if 0 /*JP:T*/
4867     { 'o', "open", "open a door", doopen },
4868 #else
4869     { 'o', "open", "\94à\82ð\8aJ\82¯\82é", doopen },
4870 #endif
4871 #if 0 /*JP:T*/
4872     { 'O', "options", "show option settings, possibly change them",
4873 #else
4874     { 'O', "options", "\8c»\8dÝ\82Ì\83I\83v\83V\83\87\83\93\90Ý\92è\82ð\95\\8e¦\82µ\89Â\94\\82È\82ç\95Ï\8dX\82·\82é",
4875 #endif
4876             doset, IFBURIED | GENERALCMD },
4877 #if 0 /*JP:T*/
4878     { C('o'), "overview", "show a summary of the explored dungeon",
4879 #else
4880     { C('o'), "overview", "\92T\8dõ\82µ\82½\96À\8b{\82Ì\8aT\97v\82ð\95\\8e¦\82·\82é",
4881 #endif
4882             dooverview, IFBURIED | AUTOCOMPLETE },
4883 #if 0 /*JP:T*/
4884     { '\0', "panic", "test panic routine (fatal to game)",
4885 #else
4886     { '\0', "panic", "\83p\83j\83b\83N\83\8b\81[\83`\83\93\82ð\83e\83X\83g\82·\82é(\92v\96½\93I)",
4887 #endif
4888             wiz_panic, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4889 #if 0 /*JP:T*/
4890     { 'p', "pay", "pay your shopping bill", dopay },
4891 #else
4892     { 'p', "pay", "\94\83\82¢\95¨\82Ì\8a¨\92è\82ð\95¥\82¤", dopay },
4893 #endif
4894 #if 0 /*JP:T*/
4895     { ',', "pickup", "pick up things at the current location", dopickup },
4896 #else
4897     { ',', "pickup", "\8c»\8dÝ\82Ì\88Ê\92u\82É\82 \82é\95¨\82ð\8fE\82¤", dopickup },
4898 #endif
4899 #if 0 /*JP:T*/
4900     { '\0', "polyself", "polymorph self",
4901 #else
4902     { '\0', "polyself", "\95Ï\89»\82·\82é",
4903 #endif
4904             wiz_polyself, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
4905 #if 0 /*JP:T*/
4906     { M('p'), "pray", "pray to the gods for help",
4907 #else
4908     { M('p'), "pray", "\90_\82É\8bF\82é",
4909 #endif
4910             dopray, IFBURIED | AUTOCOMPLETE },
4911 #if 0 /*JP:T*/
4912     { C('p'), "prevmsg", "view recent game messages",
4913 #else
4914     { C('p'), "prevmsg", "\8dÅ\8bß\82Ì\83\81\83b\83Z\81[\83W\82ð\8c©\82é",
4915 #endif
4916             doprev_message, IFBURIED | GENERALCMD },
4917 #if 0 /*JP:T*/
4918     { 'P', "puton", "put on an accessory (ring, amulet, etc)", doputon },
4919 #else
4920     { 'P', "puton", "\83A\83N\83Z\83T\83\8a\82ð\82Â\82¯\82é (\8ew\97Ö\81C\96\82\8f\9c\82¯\82È\82Ç)", doputon },
4921 #endif
4922 #if 0 /*JP:T*/
4923     { 'q', "quaff", "quaff (drink) something", dodrink },
4924 #else
4925     { 'q', "quaff", "\89½\82©\82ð\88ù\82Þ", dodrink },
4926 #endif
4927 #if 0 /*JP:T*/
4928     { M('q'), "quit", "exit without saving current game",
4929 #else
4930     { M('q'), "quit", "\83Z\81[\83u\82µ\82È\82¢\82Å\8fI\97¹",
4931 #endif
4932             done2, IFBURIED | AUTOCOMPLETE | GENERALCMD },
4933 #if 0 /*JP:T*/
4934     { 'Q', "quiver", "select ammunition for quiver", dowieldquiver },
4935 #else
4936     { 'Q', "quiver", "\91\95\93U\82·\82é\95¨\82ð\91I\91ð\82·\82é", dowieldquiver },
4937 #endif
4938 #if 0 /*JP:T*/
4939     { 'r', "read", "read a scroll or spellbook", doread },
4940 #else
4941     { 'r', "read", "\8aª\95¨\82â\96\82\96@\8f\91\82ð\93Ç\82Þ", doread },
4942 #endif
4943 #if 0 /*JP:T*/
4944     { C('r'), "redraw", "redraw screen", doredraw, IFBURIED | GENERALCMD },
4945 #else
4946     { C('r'), "redraw", "\89æ\96Ê\82ð\8dÄ\95\\8e¦\82·\82é", doredraw, IFBURIED | GENERALCMD },
4947 #endif
4948 #if 0 /*JP:T*/
4949     { 'R', "remove", "remove an accessory (ring, amulet, etc)", doremring },
4950 #else
4951     { 'R', "remove", "\83A\83N\83Z\83T\83\8a\82ð\82Í\82¸\82· (\8ew\97Ö\81C\96\82\8f\9c\82¯\82È\82Ç)", doremring },
4952 #endif
4953 #if 0 /*JP:T*/
4954     { M('R'), "ride", "mount or dismount a saddled steed",
4955 #else
4956     { M('R'), "ride", "\89ö\95¨\82É\8fæ\82é(\82Ü\82½\82Í\8d~\82è\82é)",
4957 #endif
4958             doride, AUTOCOMPLETE },
4959 #if 0 /*JP:T*/
4960     { M('r'), "rub", "rub a lamp or a stone", dorub, AUTOCOMPLETE },
4961 #else
4962     { M('r'), "rub", "\83\89\83\93\83v\82ð\82±\82·\82é", dorub, AUTOCOMPLETE },
4963 #endif
4964 #if 0 /*JP:T*/
4965     { 'S', "save", "save the game and exit", dosave, IFBURIED | GENERALCMD },
4966 #else
4967     { 'S', "save", "\83Q\81[\83\80\82ð\95Û\91\82µ\82Ä\8fI\97¹\82·\82é", dosave, IFBURIED | GENERALCMD },
4968 #endif
4969 #if 0 /*JP:T*/
4970     { 's', "search", "search for traps and secret doors",
4971             dosearch, IFBURIED, "searching" },
4972 #else
4973     { 's', "search", "ã©\82â\89B\82µ\94à\82ð\92T\82·",
4974             dosearch, IFBURIED, "\92T\82·" },
4975 #endif
4976 #if 0 /*JP:T*/
4977     { '*', "seeall", "show all equipment in use", doprinuse, IFBURIED },
4978 #else
4979     { '*', "seeall", "\8eg\97p\82µ\82Ä\82¢\82é\91S\82Ä\82Ì\91\95\94õ\97Þ\82ð\95\\8e¦\82·\82é", doprinuse, IFBURIED },
4980 #endif
4981 #if 0 /*JP:T*/
4982     { AMULET_SYM, "seeamulet", "show the amulet currently worn",
4983 #else
4984     { AMULET_SYM, "seeamulet", "\90g\82É\82Â\82¯\82Ä\82¢\82é\96\82\8f\9c\82¯\82ð\95\\8e¦\82·\82é",
4985 #endif
4986             dopramulet, IFBURIED },
4987 #if 0 /*JP:T*/
4988 #else
4989 #endif
4990     { ARMOR_SYM, "seearmor", "\8eg\82Á\82Ä\82¢\82é\96h\8bï\82ð\95\\8e¦\82·\82é",
4991             doprarm, IFBURIED },
4992 #if 0 /*JP:T*/
4993     { GOLD_SYM, "seegold", "count your gold", doprgold, IFBURIED },
4994 #else
4995     { GOLD_SYM, "seegold", "\8e\9d\82Á\82Ä\82¢\82é\8bà\89Ý\82Ì\90\94\82ð\90\94\82¦\82é", doprgold, IFBURIED },
4996 #endif
4997 #if 0 /*JP:T*/
4998     { '\0', "seenv", "show seen vectors",
4999 #else
5000     { '\0', "seenv", "\8e\8b\90ü\83x\83N\83g\83\8b\82ð\8c©\82é",
5001 #endif
5002             wiz_show_seenv, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
5003 #if 0 /*JP:T*/
5004     { RING_SYM, "seerings", "show the ring(s) currently worn",
5005 #else
5006     { RING_SYM, "seerings", "\82Í\82ß\82Ä\82¢\82é\8ew\97Ö\82ð\95\\8e¦\82·\82é",
5007 #endif
5008             doprring, IFBURIED },
5009 #if 0 /*JP:T*/
5010     { SPBOOK_SYM, "seespells", "list and reorder known spells",
5011 #else
5012     { SPBOOK_SYM, "seespells", "\92m\82Á\82Ä\82¢\82é\8eô\95\82ð\95\\8e¦\82µ\82Ä\95À\82×\91Ö\82¦\82é",
5013 #endif
5014             dovspell, IFBURIED },
5015 #if 0 /*JP:T*/
5016     { TOOL_SYM, "seetools", "show the tools currently in use",
5017 #else
5018     { TOOL_SYM, "seetools", "\8eg\82Á\82Ä\82¢\82é\93¹\8bï\82ð\95\\8e¦\82·\82é",
5019 #endif
5020             doprtool, IFBURIED },
5021 #if 0 /*JP:T*/
5022     { '^', "seetrap", "show the type of adjacent trap", doidtrap, IFBURIED },
5023 #else
5024     { '^', "seetrap", "\97×\82É\82 \82éã©\82Ì\8eí\97Þ\82ð\95\\8e¦\82·\82é", doidtrap, IFBURIED },
5025 #endif
5026 #if 0 /*JP:T*/
5027     { WEAPON_SYM, "seeweapon", "show the weapon currently wielded",
5028 #else
5029     { WEAPON_SYM, "seeweapon", "\8eg\82Á\82Ä\82¢\82é\95\90\8aí\82ð\95\\8e¦\82·\82é",
5030 #endif
5031             doprwep, IFBURIED },
5032 #if 0 /*JP:T*/
5033     { '!', "shell", "do a shell escape",
5034 #else
5035     { '!', "shell", "\83V\83F\83\8b\82É\94²\82¯\82é",
5036 #endif
5037             dosh_core, IFBURIED | GENERALCMD
5038 #ifndef SHELL
5039                        | CMD_NOT_AVAILABLE
5040 #endif /* SHELL */
5041     },
5042 #if 0 /*JP:T*/
5043     { M('s'), "sit", "sit down", dosit, AUTOCOMPLETE },
5044 #else
5045     { M('s'), "sit", "\8dÀ\82é", dosit, AUTOCOMPLETE },
5046 #endif
5047 #if 0 /*JP:T*/
5048     { '\0', "stats", "show memory statistics",
5049 #else
5050     { '\0', "stats", "\83\81\83\82\83\8a\8fó\91Ô\82ð\8c©\82é",
5051 #endif
5052             wiz_show_stats, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
5053 #if 0 /*JP:T*/
5054     { C('z'), "suspend", "suspend the game",
5055 #else
5056     { C('z'), "suspend", "\83Q\81[\83\80\82ð\92\86\92f\82·\82é",
5057 #endif
5058             dosuspend_core, IFBURIED | GENERALCMD
5059 #ifndef SUSPEND
5060                             | CMD_NOT_AVAILABLE
5061 #endif /* SUSPEND */
5062     },
5063 #if 0 /*JP:T*/
5064     { 'x', "swap", "swap wielded and secondary weapons", doswapweapon },
5065 #else
5066     { 'x', "swap", "\8d\89E\82Ì\95\90\8aí\82ð\8cð\8a·\82·\82é", doswapweapon },
5067 #endif
5068 #if 0 /*JP:T*/
5069     { 'T', "takeoff", "take off one piece of armor", dotakeoff },
5070 #else
5071     { 'T', "takeoff", "\96h\8bï\82ð\88ê\82Â\8aO\82·", dotakeoff },
5072 #endif
5073 #if 0 /*JP:T*/
5074     { 'A', "takeoffall", "remove all armor", doddoremarm },
5075 #else
5076     { 'A', "takeoffall", "\91S\82Ä\82Ì\96h\8bï\82ð\8aO\82·", doddoremarm },
5077 #endif
5078 #if 0 /*JP:T*/
5079     { C('t'), "teleport", "teleport around the level", dotelecmd, IFBURIED },
5080 #else
5081     { C('t'), "teleport", "\93¯\82\8aK\82Ì\92\86\82Å\8fu\8aÔ\88Ú\93®\82·\82é", dotelecmd, IFBURIED },
5082 #endif
5083 #if 0 /*JP:T*/
5084     { '\0', "terrain", "show map without obstructions",
5085 #else
5086     { '\0', "terrain", "\8e×\96\82\82³\82ê\82¸\82É\92n\90}\82ð\8c©\82é",
5087 #endif
5088             doterrain, IFBURIED | AUTOCOMPLETE },
5089 #if 0 /*JP:T*/
5090     { '\0', "therecmdmenu",
5091             "menu of commands you can do from here to adjacent spot",
5092 #else
5093     { '\0', "therecmdmenu",
5094             "\82±\82±\82©\82ç\97×\82Ì\83}\83X\82É\91Î\82µ\82Ä\8fo\97\88\82é\83R\83}\83\93\83h\82Ì\83\81\83j\83\85\81[",
5095 #endif
5096             dotherecmdmenu },
5097 #if 0 /*JP:T*/
5098     { 't', "throw", "throw something", dothrow },
5099 #else
5100     { 't', "throw", "\89½\82©\82ð\93\8a\82°\82é", dothrow },
5101 #endif
5102 #if 0 /*JP:T*/
5103     { '\0', "timeout", "look at timeout queue and hero's timed intrinsics",
5104 #else
5105     { '\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é",
5106 #endif
5107             wiz_timeout_queue, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
5108 #if 0 /*JP:T*/
5109     { M('T'), "tip", "empty a container", dotip, AUTOCOMPLETE },
5110 #else
5111     { M('T'), "tip", "\93ü\82ê\95¨\82ð\8bó\82É\82·\82é", dotip, AUTOCOMPLETE },
5112 #endif
5113 #if 0 /*JP:T*/
5114     { '_', "travel", "travel to a specific location on the map", dotravel },
5115 #else
5116     { '_', "travel", "\92n\90}\82Å\8ew\92è\82³\82ê\82½\88Ê\92u\82Ü\82Å\88Ú\93®\82·\82é", dotravel },
5117 #endif
5118 #if 0 /*JP:T*/
5119     { M('t'), "turn", "turn undead away", doturn, IFBURIED | AUTOCOMPLETE },
5120 #else
5121     { M('t'), "turn", "\83A\83\93\83f\83b\83g\82ð\93y\82É\95Ô\82·", doturn, IFBURIED | AUTOCOMPLETE },
5122 #endif
5123 #if 0 /*JP:T*/
5124     { 'X', "twoweapon", "toggle two-weapon combat",
5125 #else
5126     { 'X', "twoweapon", "\97¼\8eè\8e\9d\82¿\82Ì\90Ø\82è\91Ö\82¦",
5127 #endif
5128             dotwoweapon, AUTOCOMPLETE },
5129 #if 0 /*JP:T*/
5130     { M('u'), "untrap", "untrap something", dountrap, AUTOCOMPLETE },
5131 #else
5132     { M('u'), "untrap", "ã©\82ð\82Í\82¸\82·", dountrap, AUTOCOMPLETE },
5133 #endif
5134 #if 0 /*JP:T*/
5135     { '<', "up", "go up a staircase", doup },
5136 #else
5137     { '<', "up", "\8aK\92i\82ð\8fã\82é", doup },
5138 #endif
5139 #if 0 /*JP:T*/
5140     { '\0', "vanquished", "list vanquished monsters",
5141 #else
5142     { '\0', "vanquished", "\93|\82µ\82½\89ö\95¨\82Ì\88ê\97\97\82ð\8c©\82é",
5143 #endif
5144             dovanquished, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
5145     { M('v'), "version",
5146 #if 0 /*JP:T*/
5147             "list compile time options for this version of NetHack",
5148 #else
5149             "\83R\83\93\83p\83C\83\8b\8e\9e\82Ì\83I\83v\83V\83\87\83\93\82ð\95\\8e¦\82·\82é",
5150 #endif
5151             doextversion, IFBURIED | AUTOCOMPLETE | GENERALCMD },
5152 #if 0 /*JP:T*/
5153     { 'v', "versionshort", "show version", doversion, IFBURIED | GENERALCMD },
5154 #else
5155     { 'v', "versionshort", "\83o\81[\83W\83\87\83\93\82ð\95\\8e¦\82·\82é", doversion, IFBURIED | GENERALCMD },
5156 #endif
5157 #if 0 /*JP:T*/
5158     { '\0', "vision", "show vision array",
5159 #else
5160     { '\0', "vision", "\8e\8b\8aE\94z\97ñ\82ð\8c©\82é",
5161 #endif
5162             wiz_show_vision, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
5163 #if 0 /*JP:T*/
5164     { '.', "wait", "rest one move while doing nothing",
5165             donull, IFBURIED, "waiting" },
5166 #else
5167     { '.', "wait", "\88ê\95à\95ª\89½\82à\82µ\82È\82¢",
5168             donull, IFBURIED, "\8bx\8ce\82·\82é" },
5169 #endif
5170 #if 0 /*JP:T*/
5171     { 'W', "wear", "wear a piece of armor", dowear },
5172 #else
5173     { 'W', "wear", "\96h\8bï\82ð\88ê\82Â\82Â\82¯\82é", dowear },
5174 #endif
5175 #if 0 /*JP:T*/
5176     { '&', "whatdoes", "tell what a command does", dowhatdoes, IFBURIED },
5177 #else
5178     { '&', "whatdoes", "\83R\83}\83\93\83h\82Ì\88Ó\96¡\82ð\95\\8e¦\82·\82é", dowhatdoes, IFBURIED },
5179 #endif
5180 #if 0 /*JP:T*/
5181     { '/', "whatis", "show what type of thing a symbol corresponds to",
5182 #else
5183     { '/', "whatis", "\83V\83\93\83{\83\8b\82ª\89½\82ð\95\\82µ\82Ä\82¢\82é\82©\82ð\95\\8e¦\82·\82é",
5184 #endif
5185             dowhatis, IFBURIED | GENERALCMD },
5186 #if 0 /*JP:T*/
5187     { 'w', "wield", "wield (put in use) a weapon", dowield },
5188 #else
5189     { 'w', "wield", "\95\90\8aí\82ð\90g\82É\82Â\82¯\82é", dowield },
5190 #endif
5191 #if 0 /*JP:T*/
5192     { M('w'), "wipe", "wipe off your face", dowipe, AUTOCOMPLETE },
5193 #else
5194     { M('w'), "wipe", "\8aç\82ð\90@\82¤", dowipe, AUTOCOMPLETE },
5195 #endif
5196 #ifdef DEBUG
5197 #if 0 /*JP:T*/
5198     { '\0', "wizbury", "bury objs under and around you",
5199 #else
5200     { '\0', "wizbury", "\95¨\82ð\82 \82È\82½\82Ì\8eü\82è\82É\96\84\82ß\82é",
5201 #endif
5202             wiz_debug_cmd_bury, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
5203 #endif
5204     { C('e'), "wizdetect", "reveal hidden things within a small radius",
5205             wiz_detect, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
5206     { C('g'), "wizgenesis", "create a monster",
5207             wiz_genesis, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
5208     { C('i'), "wizidentify", "identify all items in inventory",
5209             wiz_identify, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
5210     { '\0', "wizintrinsic", "set an intrinsic",
5211             wiz_intrinsic, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
5212     { C('v'), "wizlevelport", "teleport to another level",
5213             wiz_level_tele, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
5214     { '\0', "wizmakemap", "recreate the current level",
5215             wiz_makemap, IFBURIED | WIZMODECMD },
5216     { C('f'), "wizmap", "map the level",
5217             wiz_map, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
5218 #if 0 /*JP:T*/
5219     { '\0', "wizrumorcheck", "verify rumor boundaries",
5220 #else
5221     { '\0', "wizrumorcheck", "\89\\82Ì\8b«\8aE\82ð\8c\9f\8fØ\82·\82é",
5222 #endif
5223             wiz_rumor_check, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
5224 #if 0 /*JP:T*/
5225     { '\0', "wizsmell", "smell monster",
5226 #else
5227     { '\0', "wizsmell", "\89ö\95¨\82Ì\93õ\82¢\82ð\9ak\82®",
5228 #endif
5229             wiz_smell, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
5230     { '\0', "wizwhere", "show locations of special levels",
5231             wiz_where, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
5232     { C('w'), "wizwish", "wish for something",
5233             wiz_wish, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
5234 #if 0 /*JP:T*/
5235     { '\0', "wmode", "show wall modes",
5236 #else
5237     { '\0', "wmode", "\95Ç\83\82\81[\83h\82ð\8c©\82é",
5238 #endif
5239             wiz_show_wmodes, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
5240 #if 0 /*JP:T*/
5241     { 'z', "zap", "zap a wand", dozap },
5242 #else
5243     { 'z', "zap", "\8fñ\82ð\90U\82é", dozap },
5244 #endif
5245     { '\0', (char *) 0, (char *) 0, donull, 0, (char *) 0 } /* sentinel */
5246 };
5247
5248 /* for key2extcmddesc() to support dowhatdoes() */
5249 struct movcmd {
5250     uchar k1, k2, k3, k4; /* 'normal', 'qwertz', 'numpad', 'phone' */
5251     const char *txt, *alt; /* compass direction, screen direction */
5252 };
5253 static const struct movcmd movtab[] = {
5254     { 'h', 'h', '4', '4', "west",      "left" },
5255     { 'j', 'j', '2', '8', "south",     "down" },
5256     { 'k', 'k', '8', '2', "north",     "up" },
5257     { 'l', 'l', '6', '6', "east",      "right" },
5258     { 'b', 'b', '1', '7', "southwest", "lower left" },
5259     { 'n', 'n', '3', '9', "southeast", "lower right" },
5260     { 'u', 'u', '9', '3', "northeast", "upper right" },
5261     { 'y', 'z', '7', '1', "northwest", "upper left" },
5262     {   0,   0,   0,   0,  (char *) 0, (char *) 0 }
5263 };
5264
5265 int extcmdlist_length = SIZE(extcmdlist) - 1;
5266
5267 const char *
5268 key2extcmddesc(key)
5269 uchar key;
5270 {
5271     static char key2cmdbuf[48];
5272     const struct movcmd *mov;
5273     int k, c;
5274     uchar M_5 = (uchar) M('5'), M_0 = (uchar) M('0');
5275
5276     /* need to check for movement commands before checking the extended
5277        commands table because it contains entries for number_pad commands
5278        that match !number_pad movement (like 'j' for "jump") */
5279     key2cmdbuf[0] = '\0';
5280     if (movecmd(k = key))
5281         Strcpy(key2cmdbuf, "move"); /* "move or attack"? */
5282     else if (movecmd(k = unctrl(key)))
5283         Strcpy(key2cmdbuf, "rush");
5284     else if (movecmd(k = (Cmd.num_pad ? unmeta(key) : lowc(key))))
5285         Strcpy(key2cmdbuf, "run");
5286     if (*key2cmdbuf) {
5287         for (mov = &movtab[0]; mov->k1; ++mov) {
5288             c = !Cmd.num_pad ? (!Cmd.swap_yz ? mov->k1 : mov->k2)
5289                              : (!Cmd.phone_layout ? mov->k3 : mov->k4);
5290             if (c == k) {
5291                 Sprintf(eos(key2cmdbuf), " %s (screen %s)",
5292                         mov->txt, mov->alt);
5293                 return key2cmdbuf;
5294             }
5295         }
5296     } else if (digit(key) || (Cmd.num_pad && digit(unmeta(key)))) {
5297         key2cmdbuf[0] = '\0';
5298         if (!Cmd.num_pad)
5299             Strcpy(key2cmdbuf, "start of, or continuation of, a count");
5300         else if (key == '5' || key == M_5)
5301             Sprintf(key2cmdbuf, "%s prefix",
5302                     (!!Cmd.pcHack_compat ^ (key == M_5)) ? "run" : "rush");
5303         else if (key == '0' || (Cmd.pcHack_compat && key == M_0))
5304             Strcpy(key2cmdbuf, "synonym for 'i'");
5305         if (*key2cmdbuf)
5306             return key2cmdbuf;
5307     }
5308     if (Cmd.commands[key]) {
5309         if (Cmd.commands[key]->ef_txt)
5310             return Cmd.commands[key]->ef_desc;
5311
5312     }
5313     return (char *) 0;
5314 }
5315
5316 boolean
5317 bind_key(key, command)
5318 uchar key;
5319 const char *command;
5320 {
5321     struct ext_func_tab *extcmd;
5322
5323     /* special case: "nothing" is reserved for unbinding */
5324     if (!strcmp(command, "nothing")) {
5325         Cmd.commands[key] = (struct ext_func_tab *) 0;
5326         return TRUE;
5327     }
5328
5329     for (extcmd = extcmdlist; extcmd->ef_txt; extcmd++) {
5330         if (strcmp(command, extcmd->ef_txt))
5331             continue;
5332         Cmd.commands[key] = extcmd;
5333 #if 0 /* silently accept key binding for unavailable command (!SHELL,&c) */
5334         if ((extcmd->flags & CMD_NOT_AVAILABLE) != 0) {
5335             char buf[BUFSZ];
5336
5337             Sprintf(buf, cmdnotavail, extcmd->ef_txt);
5338             config_error_add("%s", buf);
5339         }
5340 #endif
5341         return TRUE;
5342     }
5343
5344     return FALSE;
5345 }
5346
5347 /* initialize all keyboard commands */
5348 void
5349 commands_init()
5350 {
5351     struct ext_func_tab *extcmd;
5352
5353     for (extcmd = extcmdlist; extcmd->ef_txt; extcmd++)
5354         if (extcmd->key)
5355             Cmd.commands[extcmd->key] = extcmd;
5356
5357     (void) bind_key(C('l'), "redraw"); /* if number_pad is set */
5358     /*       'b', 'B' : go sw */
5359     /*       'F' : fight (one time) */
5360     /*       'g', 'G' : multiple go */
5361     /*       'h', 'H' : go west */
5362     (void) bind_key('h',    "help"); /* if number_pad is set */
5363     (void) bind_key('j',    "jump"); /* if number_pad is on */
5364     /*       'j', 'J', 'k', 'K', 'l', 'L', 'm', 'M', 'n', 'N' move commands */
5365     (void) bind_key('k',    "kick"); /* if number_pad is on */
5366     (void) bind_key('l',    "loot"); /* if number_pad is on */
5367     (void) bind_key(C('n'), "annotate"); /* if number_pad is on */
5368     (void) bind_key(M('n'), "name");
5369     (void) bind_key(M('N'), "name");
5370     (void) bind_key('u',    "untrap"); /* if number_pad is on */
5371
5372     /* alt keys: */
5373     (void) bind_key(M('O'), "overview");
5374     (void) bind_key(M('2'), "twoweapon");
5375
5376     /* wait_on_space */
5377     (void) bind_key(' ',    "wait");
5378 }
5379
5380 int
5381 dokeylist_putcmds(datawin, docount, cmdflags, exflags, keys_used)
5382 winid datawin;
5383 boolean docount;
5384 int cmdflags, exflags;
5385 boolean *keys_used; /* boolean keys_used[256] */
5386 {
5387     int i;
5388     char buf[BUFSZ];
5389     char buf2[QBUFSZ];
5390     int count = 0;
5391
5392     for (i = 0; i < 256; i++) {
5393         const struct ext_func_tab *extcmd;
5394         uchar key = (uchar) i;
5395
5396         if (keys_used[i])
5397             continue;
5398         if (key == ' ' && !flags.rest_on_space)
5399             continue;
5400         if ((extcmd = Cmd.commands[i]) != (struct ext_func_tab *) 0) {
5401             if ((cmdflags && !(extcmd->flags & cmdflags))
5402                 || (exflags && (extcmd->flags & exflags)))
5403                 continue;
5404             if (docount) {
5405                 count++;
5406                 continue;
5407             }
5408             Sprintf(buf, "%-8s %-12s %s", key2txt(key, buf2),
5409                     extcmd->ef_txt,
5410                     extcmd->ef_desc);
5411             putstr(datawin, 0, buf);
5412             keys_used[i] = TRUE;
5413         }
5414     }
5415     return count;
5416 }
5417
5418 /* list all keys and their bindings, like dat/hh but dynamic */
5419 void
5420 dokeylist(VOID_ARGS)
5421 {
5422     char buf[BUFSZ], buf2[BUFSZ];
5423     uchar key;
5424     boolean keys_used[256] = {0};
5425     winid datawin;
5426     int i;
5427     static const char
5428 #if 0 /*JP:T*/
5429         run_desc[] = "Prefix: run until something very interesting is seen",
5430 #else
5431         run_desc[] = "\90Ú\93ª\8e«: \89½\82©\82Æ\82Ä\82à\8b»\96¡\90[\82¢\82à\82Ì\82ª\8c©\82¦\82é\82Ü\82Å\91\96\82é",
5432 #endif
5433         forcefight_desc[] =
5434 #if 0 /*JP:T*/
5435                      "Prefix: force fight even if you don't see a monster";
5436 #else
5437                      "\90Ú\93ª\8e«: \82½\82Æ\82¦\89ö\95¨\82ª\8c©\82¦\82Ä\82¢\82È\82­\82Ä\82à\90í\82¤";
5438 #endif
5439     static const struct {
5440         int nhkf;
5441         const char *desc;
5442         boolean numpad;
5443     } misc_keys[] = {
5444 #if 0 /*JP:T*/
5445         { NHKF_ESC, "escape from the current query/action", FALSE },
5446 #else
5447         { NHKF_ESC, "\8c»\8dÝ\82Ì\8ds\93®\82ð\92\86\92f\82·\82é", FALSE },
5448 #endif
5449         { NHKF_RUSH,
5450 #if 0 /*JP:T*/
5451           "Prefix: rush until something interesting is seen", FALSE },
5452 #else
5453           "\90Ú\93ª\8e«: \89½\82©\8b»\96¡\90[\82¢\82à\82Ì\82ª\8c©\82¦\82é\82Ü\82Å\91\96\82é", FALSE },
5454 #endif
5455         { NHKF_RUN, run_desc, FALSE },
5456         { NHKF_RUN2, run_desc, TRUE },
5457         { NHKF_FIGHT, forcefight_desc, FALSE },
5458         { NHKF_FIGHT2, forcefight_desc, TRUE } ,
5459         { NHKF_NOPICKUP,
5460 #if 0 /*JP:T*/
5461           "Prefix: move without picking up objects/fighting", FALSE },
5462 #else
5463           "\90Ú\93ª\8e«: \95¨\82ð\8fE\82Á\82½\82è\90í\82Á\82½\82è\82¹\82¸\82É\88Ú\93®\82·\82é", FALSE },
5464 #endif
5465         { NHKF_RUN_NOPICKUP,
5466 #if 0 /*JP:T*/
5467           "Prefix: run without picking up objects/fighting", FALSE },
5468 #else
5469           "\90Ú\93ª\8e«: \95¨\82ð\8fE\82Á\82½\82è\90í\82Á\82½\82è\82¹\82¸\82É\91\96\82é", FALSE },
5470 #endif
5471 #if 0 /*JP:T*/
5472         { NHKF_DOINV, "view inventory", TRUE },
5473 #else
5474         { NHKF_DOINV, "\8e\9d\95¨\82ð\95\\8e¦\82·\82é", TRUE },
5475 #endif
5476 #if 0 /*JP:T*/
5477         { NHKF_REQMENU, "Prefix: request a menu", FALSE },
5478 #else
5479         { NHKF_REQMENU, "\90Ú\93ª\8e«: \83\81\83j\83\85\81[\82ð\97v\8b\81\82·\82é", FALSE },
5480 #endif
5481 #ifdef REDO
5482 #if 0 /*JP:T*/
5483         { NHKF_DOAGAIN , "re-do: perform the previous command again", FALSE },
5484 #else
5485         { NHKF_DOAGAIN , "\8dÄ\8eÀ\8ds: \91O\89ñ\82Ì\83R\83}\83\93\83h\82ð\82à\82¤\88ê\93x\8eÀ\8ds\82·\82é", FALSE },
5486 #endif
5487 #endif
5488         { 0, (const char *) 0, FALSE }
5489     };
5490
5491     datawin = create_nhwindow(NHW_TEXT);
5492     putstr(datawin, 0, "");
5493 /*JP
5494     putstr(datawin, 0, "            Full Current Key Bindings List");
5495 */
5496     putstr(datawin, 0, "             \8c»\8dÝ\82Ì\8a®\91S\82È\83L\81[\8a\84\82è\93\96\82Ä\88ê\97\97");
5497
5498     /* directional keys */
5499     putstr(datawin, 0, "");
5500 /*JP
5501     putstr(datawin, 0, "Directional keys:");
5502 */
5503     putstr(datawin, 0, "\95û\8cü\83L\81[:");
5504     show_direction_keys(datawin, '.', FALSE); /* '.'==self in direction grid */
5505
5506     keys_used[(uchar) Cmd.move_NW] = keys_used[(uchar) Cmd.move_N]
5507         = keys_used[(uchar) Cmd.move_NE] = keys_used[(uchar) Cmd.move_W]
5508         = keys_used[(uchar) Cmd.move_E] = keys_used[(uchar) Cmd.move_SW]
5509         = keys_used[(uchar) Cmd.move_S] = keys_used[(uchar) Cmd.move_SE]
5510         = TRUE;
5511
5512     if (!iflags.num_pad) {
5513         keys_used[(uchar) highc(Cmd.move_NW)]
5514             = keys_used[(uchar) highc(Cmd.move_N)]
5515             = keys_used[(uchar) highc(Cmd.move_NE)]
5516             = keys_used[(uchar) highc(Cmd.move_W)]
5517             = keys_used[(uchar) highc(Cmd.move_E)]
5518             = keys_used[(uchar) highc(Cmd.move_SW)]
5519             = keys_used[(uchar) highc(Cmd.move_S)]
5520             = keys_used[(uchar) highc(Cmd.move_SE)] = TRUE;
5521         keys_used[(uchar) C(Cmd.move_NW)]
5522             = keys_used[(uchar) C(Cmd.move_N)]
5523             = keys_used[(uchar) C(Cmd.move_NE)]
5524             = keys_used[(uchar) C(Cmd.move_W)]
5525             = keys_used[(uchar) C(Cmd.move_E)]
5526             = keys_used[(uchar) C(Cmd.move_SW)]
5527             = keys_used[(uchar) C(Cmd.move_S)]
5528             = keys_used[(uchar) C(Cmd.move_SE)] = TRUE;
5529         putstr(datawin, 0, "");
5530 #if 0 /*JP:T*/
5531         putstr(datawin, 0,
5532           "Shift-<direction> will move in specified direction until you hit");
5533         putstr(datawin, 0, "        a wall or run into something.");
5534 #else
5535         putstr(datawin, 0,
5536           "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É");
5537         putstr(datawin, 0, "        \88Ú\93®\82·\82é\81D");
5538 #endif
5539 #if 0 /*JP:T*/
5540         putstr(datawin, 0,
5541           "Ctrl-<direction> will run in specified direction until something");
5542         putstr(datawin, 0, "        very interesting is seen.");
5543 #else
5544         putstr(datawin, 0,
5545           "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É");
5546         putstr(datawin, 0, "        \88Ú\93®\82·\82é\81D");
5547 #endif
5548     }
5549
5550     putstr(datawin, 0, "");
5551 /*JP
5552     putstr(datawin, 0, "Miscellaneous keys:");
5553 */
5554     putstr(datawin, 0, "\97l\81X\82È\83L\81[:");
5555     for (i = 0; misc_keys[i].desc; i++) {
5556         key = Cmd.spkeys[misc_keys[i].nhkf];
5557         if (key && ((misc_keys[i].numpad && iflags.num_pad)
5558                     || !misc_keys[i].numpad)) {
5559             keys_used[(uchar) key] = TRUE;
5560             Sprintf(buf, "%-8s %s", key2txt(key, buf2), misc_keys[i].desc);
5561             putstr(datawin, 0, buf);
5562         }
5563     }
5564 #ifndef NO_SIGNAL
5565     putstr(datawin, 0, "^c       break out of NetHack (SIGINT)");
5566     keys_used[(uchar) C('c')] = TRUE;
5567 #endif
5568
5569     putstr(datawin, 0, "");
5570     show_menu_controls(datawin, TRUE);
5571
5572     if (dokeylist_putcmds(datawin, TRUE, GENERALCMD, WIZMODECMD, keys_used)) {
5573         putstr(datawin, 0, "");
5574 /*JP
5575         putstr(datawin, 0, "General commands:");
5576 */
5577         putstr(datawin, 0, "\88ê\94Ê\83R\83}\83\93\83h:");
5578         (void) dokeylist_putcmds(datawin, FALSE, GENERALCMD, WIZMODECMD,
5579                                  keys_used);
5580     }
5581
5582     if (dokeylist_putcmds(datawin, TRUE, 0, WIZMODECMD, keys_used)) {
5583         putstr(datawin, 0, "");
5584 /*JP
5585         putstr(datawin, 0, "Game commands:");
5586 */
5587         putstr(datawin, 0, "\83Q\81[\83\80\83R\83}\83\93\83h:");
5588         (void) dokeylist_putcmds(datawin, FALSE, 0, WIZMODECMD, keys_used);
5589     }
5590
5591     if (wizard
5592         && dokeylist_putcmds(datawin, TRUE, WIZMODECMD, 0, keys_used)) {
5593         putstr(datawin, 0, "");
5594 /*JP
5595         putstr(datawin, 0, "Wizard-mode commands:");
5596 */
5597         putstr(datawin, 0, "\83E\83B\83U\81[\83h\83\82\81[\83h\83R\83}\83\93\83h:");
5598         (void) dokeylist_putcmds(datawin, FALSE, WIZMODECMD, 0, keys_used);
5599     }
5600
5601     display_nhwindow(datawin, FALSE);
5602     destroy_nhwindow(datawin);
5603 }
5604
5605 char
5606 cmd_from_func(fn)
5607 int NDECL((*fn));
5608 {
5609     int i;
5610
5611     for (i = 0; i < 256; ++i)
5612         if (Cmd.commands[i] && Cmd.commands[i]->ef_funct == fn)
5613             return (char) i;
5614     return '\0';
5615 }
5616
5617 /*
5618  * wizard mode sanity_check code
5619  */
5620
5621 static const char template[] = "%-27s  %4ld  %6ld";
5622 static const char stats_hdr[] = "                             count  bytes";
5623 static const char stats_sep[] = "---------------------------  ----- -------";
5624
5625 STATIC_OVL int
5626 size_obj(otmp)
5627 struct obj *otmp;
5628 {
5629     int sz = (int) sizeof (struct obj);
5630
5631     if (otmp->oextra) {
5632         sz += (int) sizeof (struct oextra);
5633         if (ONAME(otmp))
5634             sz += (int) strlen(ONAME(otmp)) + 1;
5635         if (OMONST(otmp))
5636             sz += size_monst(OMONST(otmp), FALSE);
5637         if (OMID(otmp))
5638             sz += (int) sizeof (unsigned);
5639         if (OLONG(otmp))
5640             sz += (int) sizeof (long);
5641         if (OMAILCMD(otmp))
5642             sz += (int) strlen(OMAILCMD(otmp)) + 1;
5643     }
5644     return sz;
5645 }
5646
5647 STATIC_OVL void
5648 count_obj(chain, total_count, total_size, top, recurse)
5649 struct obj *chain;
5650 long *total_count;
5651 long *total_size;
5652 boolean top;
5653 boolean recurse;
5654 {
5655     long count, size;
5656     struct obj *obj;
5657
5658     for (count = size = 0, obj = chain; obj; obj = obj->nobj) {
5659         if (top) {
5660             count++;
5661             size += size_obj(obj);
5662         }
5663         if (recurse && obj->cobj)
5664             count_obj(obj->cobj, total_count, total_size, TRUE, TRUE);
5665     }
5666     *total_count += count;
5667     *total_size += size;
5668 }
5669
5670 STATIC_OVL void
5671 obj_chain(win, src, chain, force, total_count, total_size)
5672 winid win;
5673 const char *src;
5674 struct obj *chain;
5675 boolean force;
5676 long *total_count;
5677 long *total_size;
5678 {
5679     char buf[BUFSZ];
5680     long count = 0L, size = 0L;
5681
5682     count_obj(chain, &count, &size, TRUE, FALSE);
5683
5684     if (count || size || force) {
5685         *total_count += count;
5686         *total_size += size;
5687         Sprintf(buf, template, src, count, size);
5688         putstr(win, 0, buf);
5689     }
5690 }
5691
5692 STATIC_OVL void
5693 mon_invent_chain(win, src, chain, total_count, total_size)
5694 winid win;
5695 const char *src;
5696 struct monst *chain;
5697 long *total_count;
5698 long *total_size;
5699 {
5700     char buf[BUFSZ];
5701     long count = 0, size = 0;
5702     struct monst *mon;
5703
5704     for (mon = chain; mon; mon = mon->nmon)
5705         count_obj(mon->minvent, &count, &size, TRUE, FALSE);
5706
5707     if (count || size) {
5708         *total_count += count;
5709         *total_size += size;
5710         Sprintf(buf, template, src, count, size);
5711         putstr(win, 0, buf);
5712     }
5713 }
5714
5715 STATIC_OVL void
5716 contained_stats(win, src, total_count, total_size)
5717 winid win;
5718 const char *src;
5719 long *total_count;
5720 long *total_size;
5721 {
5722     char buf[BUFSZ];
5723     long count = 0, size = 0;
5724     struct monst *mon;
5725
5726     count_obj(invent, &count, &size, FALSE, TRUE);
5727     count_obj(fobj, &count, &size, FALSE, TRUE);
5728     count_obj(level.buriedobjlist, &count, &size, FALSE, TRUE);
5729     count_obj(migrating_objs, &count, &size, FALSE, TRUE);
5730     /* DEADMONSTER check not required in this loop since they have no
5731      * inventory */
5732     for (mon = fmon; mon; mon = mon->nmon)
5733         count_obj(mon->minvent, &count, &size, FALSE, TRUE);
5734     for (mon = migrating_mons; mon; mon = mon->nmon)
5735         count_obj(mon->minvent, &count, &size, FALSE, TRUE);
5736
5737     if (count || size) {
5738         *total_count += count;
5739         *total_size += size;
5740         Sprintf(buf, template, src, count, size);
5741         putstr(win, 0, buf);
5742     }
5743 }
5744
5745 STATIC_OVL int
5746 size_monst(mtmp, incl_wsegs)
5747 struct monst *mtmp;
5748 boolean incl_wsegs;
5749 {
5750     int sz = (int) sizeof (struct monst);
5751
5752     if (mtmp->wormno && incl_wsegs)
5753         sz += size_wseg(mtmp);
5754
5755     if (mtmp->mextra) {
5756         sz += (int) sizeof (struct mextra);
5757         if (MNAME(mtmp))
5758             sz += (int) strlen(MNAME(mtmp)) + 1;
5759         if (EGD(mtmp))
5760             sz += (int) sizeof (struct egd);
5761         if (EPRI(mtmp))
5762             sz += (int) sizeof (struct epri);
5763         if (ESHK(mtmp))
5764             sz += (int) sizeof (struct eshk);
5765         if (EMIN(mtmp))
5766             sz += (int) sizeof (struct emin);
5767         if (EDOG(mtmp))
5768             sz += (int) sizeof (struct edog);
5769         /* mextra->mcorpsenm doesn't point to more memory */
5770     }
5771     return sz;
5772 }
5773
5774 STATIC_OVL void
5775 mon_chain(win, src, chain, force, total_count, total_size)
5776 winid win;
5777 const char *src;
5778 struct monst *chain;
5779 boolean force;
5780 long *total_count;
5781 long *total_size;
5782 {
5783     char buf[BUFSZ];
5784     long count, size;
5785     struct monst *mon;
5786     /* mon->wormno means something different for migrating_mons and mydogs */
5787     boolean incl_wsegs = !strcmpi(src, "fmon");
5788
5789     count = size = 0L;
5790     for (mon = chain; mon; mon = mon->nmon) {
5791         count++;
5792         size += size_monst(mon, incl_wsegs);
5793     }
5794     if (count || size || force) {
5795         *total_count += count;
5796         *total_size += size;
5797         Sprintf(buf, template, src, count, size);
5798         putstr(win, 0, buf);
5799     }
5800 }
5801
5802 STATIC_OVL void
5803 misc_stats(win, total_count, total_size)
5804 winid win;
5805 long *total_count;
5806 long *total_size;
5807 {
5808     char buf[BUFSZ], hdrbuf[QBUFSZ];
5809     long count, size;
5810     int idx;
5811     struct trap *tt;
5812     struct damage *sd; /* shop damage */
5813     struct kinfo *k; /* delayed killer */
5814     struct cemetery *bi; /* bones info */
5815
5816     /* traps and engravings are output unconditionally;
5817      * others only if nonzero
5818      */
5819     count = size = 0L;
5820     for (tt = ftrap; tt; tt = tt->ntrap) {
5821         ++count;
5822         size += (long) sizeof *tt;
5823     }
5824     *total_count += count;
5825     *total_size += size;
5826     Sprintf(hdrbuf, "traps, size %ld", (long) sizeof (struct trap));
5827     Sprintf(buf, template, hdrbuf, count, size);
5828     putstr(win, 0, buf);
5829
5830     count = size = 0L;
5831     engr_stats("engravings, size %ld+text", hdrbuf, &count, &size);
5832     *total_count += count;
5833     *total_size += size;
5834     Sprintf(buf, template, hdrbuf, count, size);
5835     putstr(win, 0, buf);
5836
5837     count = size = 0L;
5838     light_stats("light sources, size %ld", hdrbuf, &count, &size);
5839     if (count || size) {
5840         *total_count += count;
5841         *total_size += size;
5842         Sprintf(buf, template, hdrbuf, count, size);
5843         putstr(win, 0, buf);
5844     }
5845
5846     count = size = 0L;
5847     timer_stats("timers, size %ld", hdrbuf, &count, &size);
5848     if (count || size) {
5849         *total_count += count;
5850         *total_size += size;
5851         Sprintf(buf, template, hdrbuf, count, size);
5852         putstr(win, 0, buf);
5853     }
5854
5855     count = size = 0L;
5856     for (sd = level.damagelist; sd; sd = sd->next) {
5857         ++count;
5858         size += (long) sizeof *sd;
5859     }
5860     if (count || size) {
5861         *total_count += count;
5862         *total_size += size;
5863         Sprintf(hdrbuf, "shop damage, size %ld",
5864                 (long) sizeof (struct damage));
5865         Sprintf(buf, template, hdrbuf, count, size);
5866         putstr(win, 0, buf);
5867     }
5868
5869     count = size = 0L;
5870     region_stats("regions, size %ld+%ld*rect+N", hdrbuf, &count, &size);
5871     if (count || size) {
5872         *total_count += count;
5873         *total_size += size;
5874         Sprintf(buf, template, hdrbuf, count, size);
5875         putstr(win, 0, buf);
5876     }
5877
5878     count = size = 0L;
5879     for (k = killer.next; k; k = k->next) {
5880         ++count;
5881         size += (long) sizeof *k;
5882     }
5883     if (count || size) {
5884         *total_count += count;
5885         *total_size += size;
5886         Sprintf(hdrbuf, "delayed killer%s, size %ld",
5887                 plur(count), (long) sizeof (struct kinfo));
5888         Sprintf(buf, template, hdrbuf, count, size);
5889         putstr(win, 0, buf);
5890     }
5891
5892     count = size = 0L;
5893     for (bi = level.bonesinfo; bi; bi = bi->next) {
5894         ++count;
5895         size += (long) sizeof *bi;
5896     }
5897     if (count || size) {
5898         *total_count += count;
5899         *total_size += size;
5900         Sprintf(hdrbuf, "bones history, size %ld",
5901                 (long) sizeof (struct cemetery));
5902         Sprintf(buf, template, hdrbuf, count, size);
5903         putstr(win, 0, buf);
5904     }
5905
5906     count = size = 0L;
5907     for (idx = 0; idx < NUM_OBJECTS; ++idx)
5908         if (objects[idx].oc_uname) {
5909             ++count;
5910             size += (long) (strlen(objects[idx].oc_uname) + 1);
5911         }
5912     if (count || size) {
5913         *total_count += count;
5914         *total_size += size;
5915         Strcpy(hdrbuf, "object type names, text");
5916         Sprintf(buf, template, hdrbuf, count, size);
5917         putstr(win, 0, buf);
5918     }
5919 }
5920
5921 /*
5922  * Display memory usage of all monsters and objects on the level.
5923  */
5924 static int
5925 wiz_show_stats()
5926 {
5927     char buf[BUFSZ];
5928     winid win;
5929     long total_obj_size, total_obj_count,
5930          total_mon_size, total_mon_count,
5931          total_ovr_size, total_ovr_count,
5932          total_misc_size, total_misc_count;
5933
5934     win = create_nhwindow(NHW_TEXT);
5935     putstr(win, 0, "Current memory statistics:");
5936
5937     total_obj_count = total_obj_size = 0L;
5938     putstr(win, 0, stats_hdr);
5939     Sprintf(buf, "  Objects, base size %ld", (long) sizeof (struct obj));
5940     putstr(win, 0, buf);
5941     obj_chain(win, "invent", invent, TRUE, &total_obj_count, &total_obj_size);
5942     obj_chain(win, "fobj", fobj, TRUE, &total_obj_count, &total_obj_size);
5943     obj_chain(win, "buried", level.buriedobjlist, FALSE,
5944               &total_obj_count, &total_obj_size);
5945     obj_chain(win, "migrating obj", migrating_objs, FALSE,
5946               &total_obj_count, &total_obj_size);
5947     obj_chain(win, "billobjs", billobjs, FALSE,
5948               &total_obj_count, &total_obj_size);
5949     mon_invent_chain(win, "minvent", fmon, &total_obj_count, &total_obj_size);
5950     mon_invent_chain(win, "migrating minvent", migrating_mons,
5951                      &total_obj_count, &total_obj_size);
5952     contained_stats(win, "contained", &total_obj_count, &total_obj_size);
5953     putstr(win, 0, stats_sep);
5954     Sprintf(buf, template, "  Obj total", total_obj_count, total_obj_size);
5955     putstr(win, 0, buf);
5956
5957     total_mon_count = total_mon_size = 0L;
5958     putstr(win, 0, "");
5959     Sprintf(buf, "  Monsters, base size %ld", (long) sizeof (struct monst));
5960     putstr(win, 0, buf);
5961     mon_chain(win, "fmon", fmon, TRUE, &total_mon_count, &total_mon_size);
5962     mon_chain(win, "migrating", migrating_mons, FALSE,
5963               &total_mon_count, &total_mon_size);
5964     /* 'mydogs' is only valid during level change or end of game disclosure,
5965        but conceivably we've been called from within debugger at such time */
5966     if (mydogs) /* monsters accompanying hero */
5967         mon_chain(win, "mydogs", mydogs, FALSE,
5968                   &total_mon_count, &total_mon_size);
5969     putstr(win, 0, stats_sep);
5970     Sprintf(buf, template, "  Mon total", total_mon_count, total_mon_size);
5971     putstr(win, 0, buf);
5972
5973     total_ovr_count = total_ovr_size = 0L;
5974     putstr(win, 0, "");
5975     putstr(win, 0, "  Overview");
5976     overview_stats(win, template, &total_ovr_count, &total_ovr_size);
5977     putstr(win, 0, stats_sep);
5978     Sprintf(buf, template, "  Over total", total_ovr_count, total_ovr_size);
5979     putstr(win, 0, buf);
5980
5981     total_misc_count = total_misc_size = 0L;
5982     putstr(win, 0, "");
5983     putstr(win, 0, "  Miscellaneous");
5984     misc_stats(win, &total_misc_count, &total_misc_size);
5985     putstr(win, 0, stats_sep);
5986     Sprintf(buf, template, "  Misc total", total_misc_count, total_misc_size);
5987     putstr(win, 0, buf);
5988
5989     putstr(win, 0, "");
5990     putstr(win, 0, stats_sep);
5991     Sprintf(buf, template, "  Grand total",
5992             (total_obj_count + total_mon_count
5993              + total_ovr_count + total_misc_count),
5994             (total_obj_size + total_mon_size
5995              + total_ovr_size + total_misc_size));
5996     putstr(win, 0, buf);
5997
5998 #if defined(__BORLANDC__) && !defined(_WIN32)
5999     show_borlandc_stats(win);
6000 #endif
6001
6002     display_nhwindow(win, FALSE);
6003     destroy_nhwindow(win);
6004     return 0;
6005 }
6006
6007 void
6008 sanity_check()
6009 {
6010     obj_sanity_check();
6011     timer_sanity_check();
6012     mon_sanity_check();
6013     light_sources_sanity_check();
6014     bc_sanity_check();
6015 }
6016
6017 #ifdef DEBUG_MIGRATING_MONS
6018 static int
6019 wiz_migrate_mons()
6020 {
6021     int mcount = 0;
6022     char inbuf[BUFSZ] = DUMMY;
6023     struct permonst *ptr;
6024     struct monst *mtmp;
6025     d_level tolevel;
6026
6027     getlin("How many random monsters to migrate? [0]", inbuf);
6028     if (*inbuf == '\033')
6029         return 0;
6030     mcount = atoi(inbuf);
6031     if (mcount < 0 || mcount > (COLNO * ROWNO) || Is_botlevel(&u.uz))
6032         return 0;
6033     while (mcount > 0) {
6034         if (Is_stronghold(&u.uz))
6035             assign_level(&tolevel, &valley_level);
6036         else
6037             get_level(&tolevel, depth(&u.uz) + 1);
6038         ptr = rndmonst();
6039         mtmp = makemon(ptr, 0, 0, NO_MM_FLAGS);
6040         if (mtmp)
6041             migrate_to_level(mtmp, ledger_no(&tolevel), MIGR_RANDOM,
6042                              (coord *) 0);
6043         mcount--;
6044     }
6045     return 0;
6046 }
6047 #endif
6048
6049 struct {
6050     int nhkf;
6051     char key;
6052     const char *name;
6053 } const spkeys_binds[] = {
6054     { NHKF_ESC,              '\033', (char *) 0 }, /* no binding */
6055     { NHKF_DOAGAIN,          DOAGAIN, "repeat" },
6056     { NHKF_REQMENU,          'm', "reqmenu" },
6057     { NHKF_RUN,              'G', "run" },
6058     { NHKF_RUN2,             '5', "run.numpad" },
6059     { NHKF_RUSH,             'g', "rush" },
6060     { NHKF_FIGHT,            'F', "fight" },
6061     { NHKF_FIGHT2,           '-', "fight.numpad" },
6062     { NHKF_NOPICKUP,         'm', "nopickup" },
6063     { NHKF_RUN_NOPICKUP,     'M', "run.nopickup" },
6064     { NHKF_DOINV,            '0', "doinv" },
6065     { NHKF_TRAVEL,           CMD_TRAVEL, (char *) 0 }, /* no binding */
6066     { NHKF_CLICKLOOK,        CMD_CLICKLOOK, (char *) 0 }, /* no binding */
6067     { NHKF_REDRAW,           C('r'), "redraw" },
6068     { NHKF_REDRAW2,          C('l'), "redraw.numpad" },
6069     { NHKF_GETDIR_SELF,      '.', "getdir.self" },
6070     { NHKF_GETDIR_SELF2,     's', "getdir.self2" },
6071     { NHKF_GETDIR_HELP,      '?', "getdir.help" },
6072     { NHKF_COUNT,            'n', "count" },
6073     { NHKF_GETPOS_SELF,      '@', "getpos.self" },
6074     { NHKF_GETPOS_PICK,      '.', "getpos.pick" },
6075     { NHKF_GETPOS_PICK_Q,    ',', "getpos.pick.quick" },
6076     { NHKF_GETPOS_PICK_O,    ';', "getpos.pick.once" },
6077     { NHKF_GETPOS_PICK_V,    ':', "getpos.pick.verbose" },
6078     { NHKF_GETPOS_SHOWVALID, '$', "getpos.valid" },
6079     { NHKF_GETPOS_AUTODESC,  '#', "getpos.autodescribe" },
6080     { NHKF_GETPOS_MON_NEXT,  'm', "getpos.mon.next" },
6081     { NHKF_GETPOS_MON_PREV,  'M', "getpos.mon.prev" },
6082     { NHKF_GETPOS_OBJ_NEXT,  'o', "getpos.obj.next" },
6083     { NHKF_GETPOS_OBJ_PREV,  'O', "getpos.obj.prev" },
6084     { NHKF_GETPOS_DOOR_NEXT, 'd', "getpos.door.next" },
6085     { NHKF_GETPOS_DOOR_PREV, 'D', "getpos.door.prev" },
6086     { NHKF_GETPOS_UNEX_NEXT, 'x', "getpos.unexplored.next" },
6087     { NHKF_GETPOS_UNEX_PREV, 'X', "getpos.unexplored.prev" },
6088     { NHKF_GETPOS_VALID_NEXT, 'z', "getpos.valid.next" },
6089     { NHKF_GETPOS_VALID_PREV, 'Z', "getpos.valid.prev" },
6090     { NHKF_GETPOS_INTERESTING_NEXT, 'a', "getpos.all.next" },
6091     { NHKF_GETPOS_INTERESTING_PREV, 'A', "getpos.all.prev" },
6092     { NHKF_GETPOS_HELP,      '?', "getpos.help" },
6093     { NHKF_GETPOS_LIMITVIEW, '"', "getpos.filter" },
6094     { NHKF_GETPOS_MOVESKIP,  '*', "getpos.moveskip" },
6095     { NHKF_GETPOS_MENU,      '!', "getpos.menu" }
6096 };
6097
6098 boolean
6099 bind_specialkey(key, command)
6100 uchar key;
6101 const char *command;
6102 {
6103     int i;
6104     for (i = 0; i < SIZE(spkeys_binds); i++) {
6105         if (!spkeys_binds[i].name || strcmp(command, spkeys_binds[i].name))
6106             continue;
6107         Cmd.spkeys[spkeys_binds[i].nhkf] = key;
6108         return TRUE;
6109     }
6110     return FALSE;
6111 }
6112
6113 /* returns a one-byte character from the text (it may massacre the txt
6114  * buffer) */
6115 char
6116 txt2key(txt)
6117 char *txt;
6118 {
6119     txt = trimspaces(txt);
6120     if (!*txt)
6121         return '\0';
6122
6123     /* simple character */
6124     if (!txt[1])
6125         return txt[0];
6126
6127     /* a few special entries */
6128     if (!strcmp(txt, "<enter>"))
6129         return '\n';
6130     if (!strcmp(txt, "<space>"))
6131         return ' ';
6132     if (!strcmp(txt, "<esc>"))
6133         return '\033';
6134
6135     /* control and meta keys */
6136     switch (*txt) {
6137     case 'm': /* can be mx, Mx, m-x, M-x */
6138     case 'M':
6139         txt++;
6140         if (*txt == '-' && txt[1])
6141             txt++;
6142         if (txt[1])
6143             return '\0';
6144         return M(*txt);
6145     case 'c': /* can be cx, Cx, ^x, c-x, C-x, ^-x */
6146     case 'C':
6147     case '^':
6148         txt++;
6149         if (*txt == '-' && txt[1])
6150             txt++;
6151         if (txt[1])
6152             return '\0';
6153         return C(*txt);
6154     }
6155
6156     /* ascii codes: must be three-digit decimal */
6157     if (*txt >= '0' && *txt <= '9') {
6158         uchar key = 0;
6159         int i;
6160
6161         for (i = 0; i < 3; i++) {
6162             if (txt[i] < '0' || txt[i] > '9')
6163                 return '\0';
6164             key = 10 * key + txt[i] - '0';
6165         }
6166         return key;
6167     }
6168
6169     return '\0';
6170 }
6171
6172 /* returns the text for a one-byte encoding;
6173  * must be shorter than a tab for proper formatting */
6174 char *
6175 key2txt(c, txt)
6176 uchar c;
6177 char *txt; /* sufficiently long buffer */
6178 {
6179     /* should probably switch to "SPC", "ESC", "RET"
6180        since nethack's documentation uses ESC for <escape> */
6181     if (c == ' ')
6182         Sprintf(txt, "<space>");
6183     else if (c == '\033')
6184         Sprintf(txt, "<esc>");
6185     else if (c == '\n')
6186         Sprintf(txt, "<enter>");
6187     else if (c == '\177')
6188         Sprintf(txt, "<del>"); /* "<delete>" won't fit */
6189     else
6190         Strcpy(txt, visctrl((char) c));
6191     return txt;
6192 }
6193
6194
6195 void
6196 parseautocomplete(autocomplete, condition)
6197 char *autocomplete;
6198 boolean condition;
6199 {
6200     struct ext_func_tab *efp;
6201     register char *autoc;
6202
6203     /* break off first autocomplete from the rest; parse the rest */
6204     if ((autoc = index(autocomplete, ',')) != 0
6205         || (autoc = index(autocomplete, ':')) != 0) {
6206         *autoc++ = '\0';
6207         parseautocomplete(autoc, condition);
6208     }
6209
6210     /* strip leading and trailing white space */
6211     autocomplete = trimspaces(autocomplete);
6212
6213     if (!*autocomplete)
6214         return;
6215
6216     /* take off negation */
6217     if (*autocomplete == '!') {
6218         /* unlike most options, a leading "no" might actually be a part of
6219          * the extended command.  Thus you have to use ! */
6220         autocomplete++;
6221         autocomplete = trimspaces(autocomplete);
6222         condition = !condition;
6223     }
6224
6225     /* find and modify the extended command */
6226     for (efp = extcmdlist; efp->ef_txt; efp++) {
6227         if (!strcmp(autocomplete, efp->ef_txt)) {
6228             if (condition)
6229                 efp->flags |= AUTOCOMPLETE;
6230             else
6231                 efp->flags &= ~AUTOCOMPLETE;
6232             return;
6233         }
6234     }
6235
6236     /* not a real extended command */
6237     raw_printf("Bad autocomplete: invalid extended command '%s'.",
6238                autocomplete);
6239     wait_synch();
6240 }
6241
6242 /* called at startup and after number_pad is twiddled */
6243 void
6244 reset_commands(initial)
6245 boolean initial;
6246 {
6247     static const char sdir[] = "hykulnjb><",
6248                       sdir_swap_yz[] = "hzkulnjb><",
6249                       ndir[] = "47896321><",
6250                       ndir_phone_layout[] = "41236987><";
6251     static const int ylist[] = {
6252         'y', 'Y', C('y'), M('y'), M('Y'), M(C('y'))
6253     };
6254     static struct ext_func_tab *back_dir_cmd[8];
6255     const struct ext_func_tab *cmdtmp;
6256     boolean flagtemp;
6257     int c, i, updated = 0;
6258     static boolean backed_dir_cmd = FALSE;
6259
6260     if (initial) {
6261         updated = 1;
6262         Cmd.num_pad = FALSE;
6263         Cmd.pcHack_compat = Cmd.phone_layout = Cmd.swap_yz = FALSE;
6264         for (i = 0; i < SIZE(spkeys_binds); i++)
6265             Cmd.spkeys[spkeys_binds[i].nhkf] = spkeys_binds[i].key;
6266         commands_init();
6267     } else {
6268
6269         if (backed_dir_cmd) {
6270             for (i = 0; i < 8; i++) {
6271                 Cmd.commands[(uchar) Cmd.dirchars[i]] = back_dir_cmd[i];
6272             }
6273         }
6274
6275         /* basic num_pad */
6276         flagtemp = iflags.num_pad;
6277         if (flagtemp != Cmd.num_pad) {
6278             Cmd.num_pad = flagtemp;
6279             ++updated;
6280         }
6281         /* swap_yz mode (only applicable for !num_pad); intended for
6282            QWERTZ keyboard used in Central Europe, particularly Germany */
6283         flagtemp = (iflags.num_pad_mode & 1) ? !Cmd.num_pad : FALSE;
6284         if (flagtemp != Cmd.swap_yz) {
6285             Cmd.swap_yz = flagtemp;
6286             ++updated;
6287             /* Cmd.swap_yz has been toggled;
6288                perform the swap (or reverse previous one) */
6289             for (i = 0; i < SIZE(ylist); i++) {
6290                 c = ylist[i] & 0xff;
6291                 cmdtmp = Cmd.commands[c];              /* tmp = [y] */
6292                 Cmd.commands[c] = Cmd.commands[c + 1]; /* [y] = [z] */
6293                 Cmd.commands[c + 1] = cmdtmp;          /* [z] = tmp */
6294             }
6295         }
6296         /* MSDOS compatibility mode (only applicable for num_pad) */
6297         flagtemp = (iflags.num_pad_mode & 1) ? Cmd.num_pad : FALSE;
6298         if (flagtemp != Cmd.pcHack_compat) {
6299             Cmd.pcHack_compat = flagtemp;
6300             ++updated;
6301             /* pcHack_compat has been toggled */
6302             c = M('5') & 0xff;
6303             cmdtmp = Cmd.commands['5'];
6304             Cmd.commands['5'] = Cmd.commands[c];
6305             Cmd.commands[c] = cmdtmp;
6306             c = M('0') & 0xff;
6307             Cmd.commands[c] = Cmd.pcHack_compat ? Cmd.commands['I'] : 0;
6308         }
6309         /* phone keypad layout (only applicable for num_pad) */
6310         flagtemp = (iflags.num_pad_mode & 2) ? Cmd.num_pad : FALSE;
6311         if (flagtemp != Cmd.phone_layout) {
6312             Cmd.phone_layout = flagtemp;
6313             ++updated;
6314             /* phone_layout has been toggled */
6315             for (i = 0; i < 3; i++) {
6316                 c = '1' + i;             /* 1,2,3 <-> 7,8,9 */
6317                 cmdtmp = Cmd.commands[c];              /* tmp = [1] */
6318                 Cmd.commands[c] = Cmd.commands[c + 6]; /* [1] = [7] */
6319                 Cmd.commands[c + 6] = cmdtmp;          /* [7] = tmp */
6320                 c = (M('1') & 0xff) + i; /* M-1,M-2,M-3 <-> M-7,M-8,M-9 */
6321                 cmdtmp = Cmd.commands[c];              /* tmp = [M-1] */
6322                 Cmd.commands[c] = Cmd.commands[c + 6]; /* [M-1] = [M-7] */
6323                 Cmd.commands[c + 6] = cmdtmp;          /* [M-7] = tmp */
6324             }
6325         }
6326     } /*?initial*/
6327
6328     if (updated)
6329         Cmd.serialno++;
6330     Cmd.dirchars = !Cmd.num_pad
6331                        ? (!Cmd.swap_yz ? sdir : sdir_swap_yz)
6332                        : (!Cmd.phone_layout ? ndir : ndir_phone_layout);
6333     Cmd.alphadirchars = !Cmd.num_pad ? Cmd.dirchars : sdir;
6334
6335     Cmd.move_W = Cmd.dirchars[0];
6336     Cmd.move_NW = Cmd.dirchars[1];
6337     Cmd.move_N = Cmd.dirchars[2];
6338     Cmd.move_NE = Cmd.dirchars[3];
6339     Cmd.move_E = Cmd.dirchars[4];
6340     Cmd.move_SE = Cmd.dirchars[5];
6341     Cmd.move_S = Cmd.dirchars[6];
6342     Cmd.move_SW = Cmd.dirchars[7];
6343
6344     if (!initial) {
6345         for (i = 0; i < 8; i++) {
6346             back_dir_cmd[i] =
6347                 (struct ext_func_tab *) Cmd.commands[(uchar) Cmd.dirchars[i]];
6348             Cmd.commands[(uchar) Cmd.dirchars[i]] = (struct ext_func_tab *) 0;
6349         }
6350         backed_dir_cmd = TRUE;
6351         for (i = 0; i < 8; i++)
6352             (void) bind_key(Cmd.dirchars[i], "nothing");
6353     }
6354 }
6355
6356 /* non-movement commands which accept 'm' prefix to request menu operation */
6357 STATIC_OVL boolean
6358 accept_menu_prefix(cmd_func)
6359 int NDECL((*cmd_func));
6360 {
6361     if (cmd_func == dopickup || cmd_func == dotip
6362         /* eat, #offer, and apply tinning-kit all use floorfood() to pick
6363            an item on floor or in invent; 'm' skips picking from floor
6364            (ie, inventory only) rather than request use of menu operation */
6365         || cmd_func == doeat || cmd_func == dosacrifice || cmd_func == doapply
6366         /* 'm' for removing saddle from adjacent monster without checking
6367            for containers at <u.ux,u.uy> */
6368         || cmd_func == doloot
6369         /* travel: pop up a menu of interesting targets in view */
6370         || cmd_func == dotravel
6371         /* wizard mode ^V and ^T */
6372         || cmd_func == wiz_level_tele || cmd_func == dotelecmd
6373         /* 'm' prefix allowed for some extended commands */
6374         || cmd_func == doextcmd || cmd_func == doextlist)
6375         return TRUE;
6376     return FALSE;
6377 }
6378
6379 char
6380 randomkey()
6381 {
6382     static unsigned i = 0;
6383     char c;
6384
6385     switch (rn2(16)) {
6386     default:
6387         c = '\033';
6388         break;
6389     case 0:
6390         c = '\n';
6391         break;
6392     case 1:
6393     case 2:
6394     case 3:
6395     case 4:
6396         c = (char) rn1('~' - ' ' + 1, ' ');
6397         break;
6398     case 5:
6399         c = (char) (rn2(2) ? '\t' : ' ');
6400         break;
6401     case 6:
6402         c = (char) rn1('z' - 'a' + 1, 'a');
6403         break;
6404     case 7:
6405         c = (char) rn1('Z' - 'A' + 1, 'A');
6406         break;
6407     case 8:
6408         c = extcmdlist[i++ % SIZE(extcmdlist)].key;
6409         break;
6410     case 9:
6411         c = '#';
6412         break;
6413     case 10:
6414     case 11:
6415     case 12:
6416         c = Cmd.dirchars[rn2(8)];
6417         if (!rn2(7))
6418             c = !Cmd.num_pad ? (!rn2(3) ? C(c) : (c + 'A' - 'a')) : M(c);
6419         break;
6420     case 13:
6421         c = (char) rn1('9' - '0' + 1, '0');
6422         break;
6423     case 14:
6424         /* any char, but avoid '\0' because it's used for mouse click */
6425         c = (char) rnd(iflags.wc_eight_bit_input ? 255 : 127);
6426         break;
6427     }
6428
6429     return c;
6430 }
6431
6432 void
6433 random_response(buf, sz)
6434 char *buf;
6435 int sz;
6436 {
6437     char c;
6438     int count = 0;
6439
6440     for (;;) {
6441         c = randomkey();
6442         if (c == '\n')
6443             break;
6444         if (c == '\033') {
6445             count = 0;
6446             break;
6447         }
6448         if (count < sz - 1)
6449             buf[count++] = c;
6450     }
6451     buf[count] = '\0';
6452 }
6453
6454 int
6455 rnd_extcmd_idx(VOID_ARGS)
6456 {
6457     return rn2(extcmdlist_length + 1) - 1;
6458 }
6459
6460 int
6461 ch2spkeys(c, start, end)
6462 char c;
6463 int start,end;
6464 {
6465     int i;
6466
6467     for (i = start; i <= end; i++)
6468         if (Cmd.spkeys[i] == c)
6469             return i;
6470     return NHKF_ESC;
6471 }
6472
6473 void
6474 rhack(cmd)
6475 register char *cmd;
6476 {
6477     int spkey;
6478     boolean prefix_seen, bad_command,
6479         firsttime = (cmd == 0);
6480
6481     iflags.menu_requested = FALSE;
6482 #ifdef SAFERHANGUP
6483     if (program_state.done_hup)
6484         end_of_input();
6485 #endif
6486     if (firsttime) {
6487         context.nopick = 0;
6488         cmd = parse();
6489     }
6490     if (*cmd == Cmd.spkeys[NHKF_ESC]) {
6491         context.move = FALSE;
6492         return;
6493     }
6494     if (*cmd == DOAGAIN && !in_doagain && saveq[0]) {
6495         in_doagain = TRUE;
6496         stail = 0;
6497         rhack((char *) 0); /* read and execute command */
6498         in_doagain = FALSE;
6499         return;
6500     }
6501     /* Special case of *cmd == ' ' handled better below */
6502     if (!*cmd || *cmd == (char) 0377) {
6503         nhbell();
6504         context.move = FALSE;
6505         return; /* probably we just had an interrupt */
6506     }
6507
6508     /* handle most movement commands */
6509     prefix_seen = FALSE;
6510     context.travel = context.travel1 = 0;
6511     spkey = ch2spkeys(*cmd, NHKF_RUN, NHKF_CLICKLOOK);
6512
6513     switch (spkey) {
6514     case NHKF_RUSH:
6515         if (movecmd(cmd[1])) {
6516             context.run = 2;
6517             domove_attempting |= DOMOVE_RUSH;
6518         } else
6519             prefix_seen = TRUE;
6520         break;
6521     case NHKF_RUN2:
6522         if (!Cmd.num_pad)
6523             break;
6524         /*FALLTHRU*/
6525     case NHKF_RUN:
6526         if (movecmd(lowc(cmd[1]))) {
6527             context.run = 3;
6528             domove_attempting |= DOMOVE_RUSH;
6529         } else
6530             prefix_seen = TRUE;
6531         break;
6532     case NHKF_FIGHT2:
6533         if (!Cmd.num_pad)
6534             break;
6535         /*FALLTHRU*/
6536     /* Effects of movement commands and invisible monsters:
6537      * m: always move onto space (even if 'I' remembered)
6538      * F: always attack space (even if 'I' not remembered)
6539      * normal movement: attack if 'I', move otherwise.
6540      */
6541     case NHKF_FIGHT:
6542         if (movecmd(cmd[1])) {
6543             context.forcefight = 1;
6544             domove_attempting |= DOMOVE_WALK;
6545         } else
6546             prefix_seen = TRUE;
6547         break;
6548     case NHKF_NOPICKUP:
6549         if (movecmd(cmd[1]) || u.dz) {
6550             context.run = 0;
6551             context.nopick = 1;
6552             if (!u.dz)
6553                 domove_attempting |= DOMOVE_WALK;
6554             else
6555                 cmd[0] = cmd[1]; /* "m<" or "m>" */
6556         } else
6557             prefix_seen = TRUE;
6558         break;
6559     case NHKF_RUN_NOPICKUP:
6560         if (movecmd(lowc(cmd[1]))) {
6561             context.run = 1;
6562             context.nopick = 1;
6563             domove_attempting |= DOMOVE_RUSH;
6564         } else
6565             prefix_seen = TRUE;
6566         break;
6567     case NHKF_DOINV:
6568         if (!Cmd.num_pad)
6569             break;
6570         (void) ddoinv(); /* a convenience borrowed from the PC */
6571         context.move = FALSE;
6572         multi = 0;
6573         return;
6574     case NHKF_CLICKLOOK:
6575         if (iflags.clicklook) {
6576             context.move = FALSE;
6577             do_look(2, &clicklook_cc);
6578         }
6579         return;
6580     case NHKF_TRAVEL:
6581         if (flags.travelcmd) {
6582             context.travel = 1;
6583             context.travel1 = 1;
6584             context.run = 8;
6585             context.nopick = 1;
6586             domove_attempting |= DOMOVE_RUSH;
6587             break;
6588         }
6589         /*FALLTHRU*/
6590     default:
6591         if (movecmd(*cmd)) { /* ordinary movement */
6592             context.run = 0; /* only matters here if it was 8 */
6593             domove_attempting |= DOMOVE_WALK;
6594         } else if (movecmd(Cmd.num_pad ? unmeta(*cmd) : lowc(*cmd))) {
6595             context.run = 1;
6596             domove_attempting |= DOMOVE_RUSH;
6597         } else if (movecmd(unctrl(*cmd))) {
6598             context.run = 3;
6599             domove_attempting |= DOMOVE_RUSH;
6600         }
6601         break;
6602     }
6603
6604     /* some special prefix handling */
6605     /* overload 'm' prefix to mean "request a menu" */
6606     if (prefix_seen && cmd[0] == Cmd.spkeys[NHKF_REQMENU]) {
6607         /* (for func_tab cast, see below) */
6608         const struct ext_func_tab *ft = Cmd.commands[cmd[1] & 0xff];
6609         int NDECL((*func)) = ft ? ((struct ext_func_tab *) ft)->ef_funct : 0;
6610
6611         if (func && accept_menu_prefix(func)) {
6612             iflags.menu_requested = TRUE;
6613             ++cmd;
6614         }
6615     }
6616
6617     if (((domove_attempting & (DOMOVE_RUSH | DOMOVE_WALK)) != 0L)
6618                             && !context.travel && !dxdy_moveok()) {
6619         /* trying to move diagonally as a grid bug;
6620            this used to be treated by movecmd() as not being
6621            a movement attempt, but that didn't provide for any
6622            feedback and led to strangeness if the key pressed
6623            ('u' in particular) was overloaded for num_pad use */
6624 /*JP
6625         You_cant("get there from here...");
6626 */
6627         You_cant("\82±\82±\82©\82ç\82»\82±\82Ö\82Í\8ds\82¯\82Ü\82¹\82ñ\81D\81D\81D");
6628         context.run = 0;
6629         context.nopick = context.forcefight = FALSE;
6630         context.move = context.mv = FALSE;
6631         multi = 0;
6632         return;
6633     }
6634
6635     if ((domove_attempting & DOMOVE_WALK) != 0L) {
6636         if (multi)
6637             context.mv = TRUE;
6638         domove();
6639         context.forcefight = 0;
6640         return;
6641     } else if ((domove_attempting & DOMOVE_RUSH) != 0L) {
6642         if (firsttime) {
6643             if (!multi)
6644                 multi = max(COLNO, ROWNO);
6645             u.last_str_turn = 0;
6646         }
6647         context.mv = TRUE;
6648         domove();
6649         return;
6650     } else if (prefix_seen && cmd[1] == Cmd.spkeys[NHKF_ESC]) {
6651         /* <prefix><escape> */
6652         /* don't report "unknown command" for change of heart... */
6653         bad_command = FALSE;
6654     } else if (*cmd == ' ' && !flags.rest_on_space) {
6655         bad_command = TRUE; /* skip cmdlist[] loop */
6656
6657     /* handle all other commands */
6658     } else {
6659         register const struct ext_func_tab *tlist;
6660         int res, NDECL((*func));
6661
6662         /* current - use *cmd to directly index cmdlist array */
6663         if ((tlist = Cmd.commands[*cmd & 0xff]) != 0) {
6664             if (!wizard && (tlist->flags & WIZMODECMD)) {
6665 /*JP
6666                 You_cant("do that!");
6667 */
6668                 pline("\82»\82ê\82Í\82Å\82«\82Ü\82¹\82ñ\81I");
6669                 res = 0;
6670             } else if (u.uburied && !(tlist->flags & IFBURIED)) {
6671 /*JP
6672                 You_cant("do that while you are buried!");
6673 */
6674                 You("\96\84\82Ü\82Á\82Ä\82¢\82é\8e\9e\82É\82»\82ñ\82È\82±\82Æ\82Í\82Å\82«\82È\82¢\81I");
6675                 res = 0;
6676             } else {
6677                 /* we discard 'const' because some compilers seem to have
6678                    trouble with the pointer passed to set_occupation() */
6679                 func = ((struct ext_func_tab *) tlist)->ef_funct;
6680                 if (tlist->f_text && !occupation && multi)
6681                     set_occupation(func, tlist->f_text, multi);
6682                 res = (*func)(); /* perform the command */
6683             }
6684             if (!res) {
6685                 context.move = FALSE;
6686                 multi = 0;
6687             }
6688             return;
6689         }
6690         /* if we reach here, cmd wasn't found in cmdlist[] */
6691         bad_command = TRUE;
6692     }
6693
6694     if (bad_command) {
6695         char expcmd[20]; /* we expect 'cmd' to point to 1 or 2 chars */
6696         char c, c1 = cmd[1];
6697
6698         expcmd[0] = '\0';
6699         while ((c = *cmd++) != '\0')
6700             Strcat(expcmd, visctrl(c)); /* add 1..4 chars plus terminator */
6701
6702 /*JP
6703         if (!prefix_seen || !help_dir(c1, spkey, "Invalid direction key!"))
6704 */
6705         if (!prefix_seen || !help_dir(c1, spkey, "\96³\8cø\82È\95û\8cü\8ew\92è\82Å\82·\81I"))
6706 /*JP
6707             Norep("Unknown command '%s'.", expcmd);
6708 */
6709             Norep("'%s'\83R\83}\83\93\83h\81H", expcmd);
6710     }
6711     /* didn't move */
6712     context.move = FALSE;
6713     multi = 0;
6714     return;
6715 }
6716
6717 /* convert an x,y pair into a direction code */
6718 int
6719 xytod(x, y)
6720 schar x, y;
6721 {
6722     register int dd;
6723
6724     for (dd = 0; dd < 8; dd++)
6725         if (x == xdir[dd] && y == ydir[dd])
6726             return dd;
6727     return -1;
6728 }
6729
6730 /* convert a direction code into an x,y pair */
6731 void
6732 dtoxy(cc, dd)
6733 coord *cc;
6734 register int dd;
6735 {
6736     cc->x = xdir[dd];
6737     cc->y = ydir[dd];
6738     return;
6739 }
6740
6741 /* also sets u.dz, but returns false for <> */
6742 int
6743 movecmd(sym)
6744 char sym;
6745 {
6746     register const char *dp = index(Cmd.dirchars, sym);
6747
6748     u.dz = 0;
6749     if (!dp || !*dp)
6750         return 0;
6751     u.dx = xdir[dp - Cmd.dirchars];
6752     u.dy = ydir[dp - Cmd.dirchars];
6753     u.dz = zdir[dp - Cmd.dirchars];
6754 #if 0 /* now handled elsewhere */
6755     if (u.dx && u.dy && NODIAG(u.umonnum)) {
6756         u.dx = u.dy = 0;
6757         return 0;
6758     }
6759 #endif
6760     return !u.dz;
6761 }
6762
6763 /* grid bug handling which used to be in movecmd() */
6764 int
6765 dxdy_moveok()
6766 {
6767     if (u.dx && u.dy && NODIAG(u.umonnum))
6768         u.dx = u.dy = 0;
6769     return u.dx || u.dy;
6770 }
6771
6772 /* decide whether a character (user input keystroke) requests screen repaint */
6773 boolean
6774 redraw_cmd(c)
6775 char c;
6776 {
6777     return (boolean) (c == Cmd.spkeys[NHKF_REDRAW]
6778                       || (Cmd.num_pad && c == Cmd.spkeys[NHKF_REDRAW2]));
6779 }
6780
6781 boolean
6782 prefix_cmd(c)
6783 char c;
6784 {
6785     return (c == Cmd.spkeys[NHKF_RUSH]
6786             || c == Cmd.spkeys[NHKF_RUN]
6787             || c == Cmd.spkeys[NHKF_NOPICKUP]
6788             || c == Cmd.spkeys[NHKF_RUN_NOPICKUP]
6789             || c == Cmd.spkeys[NHKF_FIGHT]
6790             || (Cmd.num_pad && (c == Cmd.spkeys[NHKF_RUN2]
6791                                 || c == Cmd.spkeys[NHKF_FIGHT2])));
6792 }
6793
6794 /*
6795  * uses getdir() but unlike getdir() it specifically
6796  * produces coordinates using the direction from getdir()
6797  * and verifies that those coordinates are ok.
6798  *
6799  * If the call to getdir() returns 0, Never_mind is displayed.
6800  * If the resulting coordinates are not okay, emsg is displayed.
6801  *
6802  * Returns non-zero if coordinates in cc are valid.
6803  */
6804 int
6805 get_adjacent_loc(prompt, emsg, x, y, cc)
6806 const char *prompt, *emsg;
6807 xchar x, y;
6808 coord *cc;
6809 {
6810     xchar new_x, new_y;
6811     if (!getdir(prompt)) {
6812         pline1(Never_mind);
6813         return 0;
6814     }
6815     new_x = x + u.dx;
6816     new_y = y + u.dy;
6817     if (cc && isok(new_x, new_y)) {
6818         cc->x = new_x;
6819         cc->y = new_y;
6820     } else {
6821         if (emsg)
6822             pline1(emsg);
6823         return 0;
6824     }
6825     return 1;
6826 }
6827
6828 int
6829 getdir(s)
6830 const char *s;
6831 {
6832     char dirsym;
6833     int is_mov;
6834
6835  retry:
6836     if (in_doagain || *readchar_queue)
6837         dirsym = readchar();
6838     else
6839 /*JP
6840         dirsym = yn_function((s && *s != '^') ? s : "In what direction?",
6841 */
6842         dirsym = yn_function((s && *s != '^') ? s : "\82Ç\82Ì\95û\8cü\81H",
6843                              (char *) 0, '\0');
6844     /* remove the prompt string so caller won't have to */
6845     clear_nhwindow(WIN_MESSAGE);
6846
6847     if (redraw_cmd(dirsym)) { /* ^R */
6848         docrt();              /* redraw */
6849         goto retry;
6850     }
6851     savech(dirsym);
6852
6853     if (dirsym == Cmd.spkeys[NHKF_GETDIR_SELF]
6854         || dirsym == Cmd.spkeys[NHKF_GETDIR_SELF2]) {
6855         u.dx = u.dy = u.dz = 0;
6856     } else if (!(is_mov = movecmd(dirsym)) && !u.dz) {
6857         boolean did_help = FALSE, help_requested;
6858
6859         if (!index(quitchars, dirsym)) {
6860             help_requested = (dirsym == Cmd.spkeys[NHKF_GETDIR_HELP]);
6861             if (help_requested || iflags.cmdassist) {
6862                 did_help = help_dir((s && *s == '^') ? dirsym : '\0',
6863                                     NHKF_ESC,
6864                                     help_requested ? (const char *) 0
6865 /*JP
6866                                                   : "Invalid direction key!");
6867 */
6868                                                   : "\96³\8cø\82È\95û\8cü\8ew\92è\82Å\82·\81I");
6869                 if (help_requested)
6870                     goto retry;
6871             }
6872             if (!did_help)
6873 /*JP
6874                 pline("What a strange direction!");
6875 */
6876                 pline("\82¸\82¢\82Ô\82ñ\82Æ\8aï\96­\82È\95û\8cü\82¾\81I");
6877         }
6878         return 0;
6879     } else if (is_mov && !dxdy_moveok()) {
6880 /*JP
6881         You_cant("orient yourself that direction.");
6882 */
6883         You_cant("\8cü\82«\82É\8e©\95ª\8e©\90g\82ð\8ew\92è\82Å\82«\82È\82¢\81D");
6884         return 0;
6885     }
6886     if (!u.dz && (Stunned || (Confusion && !rn2(5))))
6887         confdir();
6888     return 1;
6889 }
6890
6891 STATIC_OVL void
6892 show_direction_keys(win, centerchar, nodiag)
6893 winid win; /* should specify a window which is using a fixed-width font... */
6894 char centerchar; /* '.' or '@' or ' ' */
6895 boolean nodiag;
6896 {
6897     char buf[BUFSZ];
6898
6899     if (!centerchar)
6900         centerchar = ' ';
6901
6902     if (nodiag) {
6903         Sprintf(buf, "             %c   ", Cmd.move_N);
6904         putstr(win, 0, buf);
6905         putstr(win, 0, "             |   ");
6906         Sprintf(buf, "          %c- %c -%c",
6907                 Cmd.move_W, centerchar, Cmd.move_E);
6908         putstr(win, 0, buf);
6909         putstr(win, 0, "             |   ");
6910         Sprintf(buf, "             %c   ", Cmd.move_S);
6911         putstr(win, 0, buf);
6912     } else {
6913         Sprintf(buf, "          %c  %c  %c",
6914                 Cmd.move_NW, Cmd.move_N, Cmd.move_NE);
6915         putstr(win, 0, buf);
6916         putstr(win, 0, "           \\ | / ");
6917         Sprintf(buf, "          %c- %c -%c",
6918                 Cmd.move_W, centerchar, Cmd.move_E);
6919         putstr(win, 0, buf);
6920         putstr(win, 0, "           / | \\ ");
6921         Sprintf(buf, "          %c  %c  %c",
6922                 Cmd.move_SW, Cmd.move_S, Cmd.move_SE);
6923         putstr(win, 0, buf);
6924     };
6925 }
6926
6927 /* explain choices if player has asked for getdir() help or has given
6928    an invalid direction after a prefix key ('F', 'g', 'm', &c), which
6929    might be bogus but could be up, down, or self when not applicable */
6930 STATIC_OVL boolean
6931 help_dir(sym, spkey, msg)
6932 char sym;
6933 int spkey; /* NHKF_ code for prefix key, if one was used, or for ESC */
6934 const char *msg;
6935 {
6936     static const char wiz_only_list[] = "EFGIVW";
6937     char ctrl;
6938     winid win;
6939     char buf[BUFSZ], buf2[BUFSZ], *explain;
6940     const char *dothat, *how;
6941     boolean prefixhandling, viawindow;
6942
6943     /* NHKF_ESC indicates that player asked for help at getdir prompt */
6944     viawindow = (spkey == NHKF_ESC || iflags.cmdassist);
6945     prefixhandling = (spkey != NHKF_ESC);
6946     /*
6947      * Handling for prefix keys that don't want special directions.
6948      * Delivered via pline if 'cmdassist' is off, or instead of the
6949      * general message if it's on.
6950      */
6951     dothat = "do that";
6952 #if 0 /*JP*/
6953     how = " at"; /* for "<action> at yourself"; not used for up/down */
6954 #else
6955     how = "";
6956 #endif
6957     switch (spkey) {
6958     case NHKF_NOPICKUP:
6959 #if 0 /*JP*/
6960         dothat = "move";
6961 #else
6962         dothat = "\88Ú\93®\82·\82é";
6963 #endif
6964         break;
6965     case NHKF_RUSH:
6966 #if 0 /*JP*/
6967         dothat = "rush";
6968 #else
6969         dothat = "\93Ë\90i\82·\82é";
6970 #endif
6971         break;
6972     case NHKF_RUN2:
6973         if (!Cmd.num_pad)
6974             break;
6975         /*FALLTHRU*/
6976     case NHKF_RUN:
6977     case NHKF_RUN_NOPICKUP:
6978 #if 0 /*JP*/
6979         dothat = "run";
6980 #else
6981         dothat = "\91\96\82é";
6982 #endif
6983         break;
6984     case NHKF_FIGHT2:
6985         if (!Cmd.num_pad)
6986             break;
6987         /*FALLTHRU*/
6988     case NHKF_FIGHT:
6989 #if 0 /*JP*/
6990         dothat = "fight";
6991 #else
6992         dothat = "\90í\82¤";
6993 #endif
6994         how = ""; /* avoid "fight at yourself" */
6995         break;
6996     default:
6997         prefixhandling = FALSE;
6998         break;
6999     }
7000
7001     buf[0] = '\0';
7002     /* for movement prefix followed by '.' or (numpad && 's') to mean 'self';
7003        note: '-' for hands (inventory form of 'self') is not handled here */
7004     if (prefixhandling
7005         && (sym == Cmd.spkeys[NHKF_GETDIR_SELF]
7006             || (Cmd.num_pad && sym == Cmd.spkeys[NHKF_GETDIR_SELF2]))) {
7007 /*JP
7008         Sprintf(buf, "You can't %s%s yourself.", dothat, how);
7009 */
7010         Sprintf(buf, "\8e©\95ª\8e©\90g\82É%s%s\82±\82Æ\82Í\82Å\82«\82È\82¢\81D", dothat, how);
7011     /* for movement prefix followed by up or down */
7012     } else if (prefixhandling && (sym == '<' || sym == '>')) {
7013 #if 0 /*JP*/
7014         Sprintf(buf, "You can't %s %s.", dothat,
7015                 /* was "upwards" and "downwards", but they're considered
7016                    to be variants of canonical "upward" and "downward" */
7017                 (sym == '<') ? "upward" : "downward");
7018 #else
7019         Sprintf(buf, "%s%s\82±\82Æ\82Í\82Å\82«\82È\82¢\81D",
7020                 (sym == '<') ? "\8fã\95û\8cü\82É" : "\89º\95û\8cü\82É", dothat);
7021 #endif
7022     }
7023
7024     /* if '!cmdassist', display via pline() and we're done (note: asking
7025        for help at getdir() prompt forces cmdassist for this operation) */
7026     if (!viawindow) {
7027         if (prefixhandling) {
7028             if (!*buf)
7029 #if 0 /*JP*/
7030                 Sprintf(buf, "Invalid direction for '%s' prefix.",
7031                         visctrl(Cmd.spkeys[spkey]));
7032 #else
7033                 Sprintf(buf, "'%s'\90Ú\93ª\8e«\82É\82Í\95s\90³\82È\95û\8cü\81D",
7034                         visctrl(Cmd.spkeys[spkey]));
7035 #endif
7036             pline("%s", buf);
7037             return TRUE;
7038         }
7039         /* when 'cmdassist' is off and caller doesn't insist, do nothing */
7040         return FALSE;
7041     }
7042
7043     win = create_nhwindow(NHW_TEXT);
7044     if (!win)
7045         return FALSE;
7046
7047     if (*buf) {
7048         /* show bad-prefix message instead of general invalid-direction one */
7049         putstr(win, 0, buf);
7050         putstr(win, 0, "");
7051     } else if (msg) {
7052         Sprintf(buf, "cmdassist: %s", msg);
7053         putstr(win, 0, buf);
7054         putstr(win, 0, "");
7055     }
7056
7057     if (!prefixhandling && (letter(sym) || sym == '[')) {
7058         /* '[': old 'cmdhelp' showed ESC as ^[ */
7059         sym = highc(sym); /* @A-Z[ (note: letter() accepts '@') */
7060         ctrl = (sym - 'A') + 1; /* 0-27 (note: 28-31 aren't applicable) */
7061         if ((explain = dowhatdoes_core(ctrl, buf2)) != 0
7062             && (!index(wiz_only_list, sym) || wizard)) {
7063             Sprintf(buf, "Are you trying to use ^%c%s?", sym,
7064                     index(wiz_only_list, sym) ? ""
7065                         : " as specified in the Guidebook");
7066             putstr(win, 0, buf);
7067             putstr(win, 0, "");
7068             putstr(win, 0, explain);
7069             putstr(win, 0, "");
7070             putstr(win, 0,
7071                   "To use that command, hold down the <Ctrl> key as a shift");
7072             Sprintf(buf, "and press the <%c> key.", sym);
7073             putstr(win, 0, buf);
7074             putstr(win, 0, "");
7075         }
7076     }
7077
7078 #if 0 /*JP:T*/
7079     Sprintf(buf, "Valid direction keys%s%s%s are:",
7080             prefixhandling ? " to " : "", prefixhandling ? dothat : "",
7081             NODIAG(u.umonnum) ? " in your current form" : "");
7082 #else
7083     Sprintf(buf, "%s%s%s\97L\8cø\82È\95û\8cü\8ew\92è\82Í:",
7084             prefixhandling ? dothat : "", prefixhandling ? "\82½\82ß\82Ì" : "",
7085             NODIAG(u.umonnum) ? " \8c»\8dÝ\82Ì\8ep\82Å\82Ì" : "");
7086 #endif
7087     putstr(win, 0, buf);
7088     show_direction_keys(win, !prefixhandling ? '.' : ' ', NODIAG(u.umonnum));
7089
7090     if (!prefixhandling || spkey == NHKF_NOPICKUP) {
7091         /* NOPICKUP: unlike the other prefix keys, 'm' allows up/down for
7092            stair traversal; we won't get here when "m<" or "m>" has been
7093            given but we include up and down for 'm'+invalid_direction;
7094            self is excluded as a viable direction for every prefix */
7095         putstr(win, 0, "");
7096 /*JP
7097         putstr(win, 0, "          <  up");
7098 */
7099         putstr(win, 0, "          <  \8fã");
7100 /*JP
7101         putstr(win, 0, "          >  down");
7102 */
7103         putstr(win, 0, "          >  \89º");
7104         if (!prefixhandling) {
7105             int selfi = Cmd.num_pad ? NHKF_GETDIR_SELF2 : NHKF_GETDIR_SELF;
7106
7107 #if 0 /*JP:T*/
7108             Sprintf(buf,   "       %4s  direct at yourself",
7109                     visctrl(Cmd.spkeys[selfi]));
7110 #else
7111             Sprintf(buf,   "       %4s  \8e©\95ª\82É\8cü\82¯\82é",
7112                     visctrl(Cmd.spkeys[selfi]));
7113 #endif
7114             putstr(win, 0, buf);
7115         }
7116     }
7117
7118     if (msg) {
7119         /* non-null msg means that this wasn't an explicit user request */
7120         putstr(win, 0, "");
7121         putstr(win, 0,
7122 /*JP
7123                "(Suppress this message with !cmdassist in config file.)");
7124 */
7125                "(\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)");
7126     }
7127     display_nhwindow(win, FALSE);
7128     destroy_nhwindow(win);
7129     return TRUE;
7130 }
7131
7132 void
7133 confdir()
7134 {
7135     register int x = NODIAG(u.umonnum) ? 2 * rn2(4) : rn2(8);
7136
7137     u.dx = xdir[x];
7138     u.dy = ydir[x];
7139     return;
7140 }
7141
7142 const char *
7143 directionname(dir)
7144 int dir;
7145 {
7146     static NEARDATA const char *const dirnames[] = {
7147         "west",      "northwest", "north",     "northeast", "east",
7148         "southeast", "south",     "southwest", "down",      "up",
7149     };
7150
7151     if (dir < 0 || dir >= SIZE(dirnames))
7152         return "invalid";
7153     return dirnames[dir];
7154 }
7155
7156 int
7157 isok(x, y)
7158 register int x, y;
7159 {
7160     /* x corresponds to curx, so x==1 is the first column. Ach. %% */
7161     return x >= 1 && x <= COLNO - 1 && y >= 0 && y <= ROWNO - 1;
7162 }
7163
7164 /* #herecmdmenu command */
7165 STATIC_PTR int
7166 doherecmdmenu(VOID_ARGS)
7167 {
7168     char ch = here_cmd_menu(TRUE);
7169
7170     return ch ? 1 : 0;
7171 }
7172
7173 /* #therecmdmenu command, a way to test there_cmd_menu without mouse */
7174 STATIC_PTR int
7175 dotherecmdmenu(VOID_ARGS)
7176 {
7177     char ch;
7178
7179     if (!getdir((const char *) 0) || !isok(u.ux + u.dx, u.uy + u.dy))
7180         return 0;
7181
7182     if (u.dx || u.dy)
7183         ch = there_cmd_menu(TRUE, u.ux + u.dx, u.uy + u.dy);
7184     else
7185         ch = here_cmd_menu(TRUE);
7186
7187     return ch ? 1 : 0;
7188 }
7189
7190 STATIC_OVL void
7191 add_herecmd_menuitem(win, func, text)
7192 winid win;
7193 int NDECL((*func));
7194 const char *text;
7195 {
7196     char ch;
7197     anything any;
7198
7199     if ((ch = cmd_from_func(func)) != '\0') {
7200         any = zeroany;
7201         any.a_nfunc = func;
7202         add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, text, MENU_UNSELECTED);
7203     }
7204 }
7205
7206 STATIC_OVL char
7207 there_cmd_menu(doit, x, y)
7208 boolean doit;
7209 int x, y;
7210 {
7211     winid win;
7212     char ch;
7213     char buf[BUFSZ];
7214     schar typ = levl[x][y].typ;
7215     int npick, K = 0;
7216     menu_item *picks = (menu_item *) 0;
7217     struct trap *ttmp;
7218     struct monst *mtmp;
7219
7220     win = create_nhwindow(NHW_MENU);
7221     start_menu(win);
7222
7223     if (IS_DOOR(typ)) {
7224         boolean key_or_pick, card;
7225         int dm = levl[x][y].doormask;
7226
7227         if ((dm & (D_CLOSED | D_LOCKED))) {
7228             add_herecmd_menuitem(win, doopen, "Open the door"), ++K;
7229             /* unfortunately there's no lknown flag for doors to
7230                remember the locked/unlocked state */
7231             key_or_pick = (carrying(SKELETON_KEY) || carrying(LOCK_PICK));
7232             card = (carrying(CREDIT_CARD) != 0);
7233             if (key_or_pick || card) {
7234                 Sprintf(buf, "%sunlock the door",
7235                         key_or_pick ? "lock or " : "");
7236                 add_herecmd_menuitem(win, doapply, upstart(buf)), ++K;
7237             }
7238             /* unfortunately there's no tknown flag for doors (or chests)
7239                to remember whether a trap had been found */
7240             add_herecmd_menuitem(win, dountrap,
7241                                  "Search the door for a trap"), ++K;
7242             /* [what about #force?] */
7243             add_herecmd_menuitem(win, dokick, "Kick the door"), ++K;
7244         } else if ((dm & D_ISOPEN)) {
7245             add_herecmd_menuitem(win, doclose, "Close the door"), ++K;
7246         }
7247     }
7248
7249     if (typ <= SCORR)
7250         add_herecmd_menuitem(win, dosearch, "Search for secret doors"), ++K;
7251
7252     if ((ttmp = t_at(x, y)) != 0 && ttmp->tseen) {
7253         add_herecmd_menuitem(win, doidtrap, "Examine trap"), ++K;
7254         if (ttmp->ttyp != VIBRATING_SQUARE)
7255             add_herecmd_menuitem(win, dountrap, "Attempt to disarm trap"), ++K;
7256     }
7257
7258     mtmp = m_at(x, y);
7259     if (mtmp && !canspotmon(mtmp))
7260         mtmp = 0;
7261     if (mtmp && which_armor(mtmp, W_SADDLE)) {
7262         char *mnam = x_monnam(mtmp, ARTICLE_THE, (char *) 0,
7263                               SUPPRESS_SADDLE, FALSE);
7264
7265         if (!u.usteed) {
7266             Sprintf(buf, "Ride %s", mnam);
7267             add_herecmd_menuitem(win, doride, buf), ++K;
7268         }
7269         Sprintf(buf, "Remove saddle from %s", mnam);
7270         add_herecmd_menuitem(win, doloot, buf), ++K;
7271     }
7272     if (mtmp && can_saddle(mtmp) && !which_armor(mtmp, W_SADDLE)
7273         && carrying(SADDLE)) {
7274         Sprintf(buf, "Put saddle on %s", mon_nam(mtmp)), ++K;
7275         add_herecmd_menuitem(win, doapply, buf);
7276     }
7277 #if 0
7278     if (mtmp || glyph_is_invisible(glyph_at(x, y))) {
7279         /* "Attack %s", mtmp ? mon_nam(mtmp) : "unseen creature" */
7280     } else {
7281         /* "Move %s", direction */
7282     }
7283 #endif
7284
7285     if (K) {
7286         end_menu(win, "What do you want to do?");
7287         npick = select_menu(win, PICK_ONE, &picks);
7288     } else {
7289         pline("No applicable actions.");
7290         npick = 0;
7291     }
7292     destroy_nhwindow(win);
7293     ch = '\0';
7294     if (npick > 0) {
7295         int NDECL((*func)) = picks->item.a_nfunc;
7296         free((genericptr_t) picks);
7297
7298         if (doit) {
7299             int ret = (*func)();
7300
7301             ch = (char) ret;
7302         } else {
7303             ch = cmd_from_func(func);
7304         }
7305     }
7306     return ch;
7307 }
7308
7309 STATIC_OVL char
7310 here_cmd_menu(doit)
7311 boolean doit;
7312 {
7313     winid win;
7314     char ch;
7315     char buf[BUFSZ];
7316     schar typ = levl[u.ux][u.uy].typ;
7317     int npick;
7318     menu_item *picks = (menu_item *) 0;
7319
7320     win = create_nhwindow(NHW_MENU);
7321     start_menu(win);
7322
7323     if (IS_FOUNTAIN(typ) || IS_SINK(typ)) {
7324         Sprintf(buf, "Drink from the %s",
7325                 defsyms[IS_FOUNTAIN(typ) ? S_fountain : S_sink].explanation);
7326         add_herecmd_menuitem(win, dodrink, buf);
7327     }
7328     if (IS_FOUNTAIN(typ))
7329         add_herecmd_menuitem(win, dodip,
7330                              "Dip something into the fountain");
7331     if (IS_THRONE(typ))
7332         add_herecmd_menuitem(win, dosit,
7333                              "Sit on the throne");
7334
7335     if ((u.ux == xupstair && u.uy == yupstair)
7336         || (u.ux == sstairs.sx && u.uy == sstairs.sy && sstairs.up)
7337         || (u.ux == xupladder && u.uy == yupladder)) {
7338         Sprintf(buf, "Go up the %s",
7339                 (u.ux == xupladder && u.uy == yupladder)
7340                 ? "ladder" : "stairs");
7341         add_herecmd_menuitem(win, doup, buf);
7342     }
7343     if ((u.ux == xdnstair && u.uy == ydnstair)
7344         || (u.ux == sstairs.sx && u.uy == sstairs.sy && !sstairs.up)
7345         || (u.ux == xdnladder && u.uy == ydnladder)) {
7346         Sprintf(buf, "Go down the %s",
7347                 (u.ux == xupladder && u.uy == yupladder)
7348                 ? "ladder" : "stairs");
7349         add_herecmd_menuitem(win, dodown, buf);
7350     }
7351     if (u.usteed) { /* another movement choice */
7352         Sprintf(buf, "Dismount %s",
7353                 x_monnam(u.usteed, ARTICLE_THE, (char *) 0,
7354                          SUPPRESS_SADDLE, FALSE));
7355         add_herecmd_menuitem(win, doride, buf);
7356     }
7357
7358 #if 0
7359     if (Upolyd) { /* before objects */
7360         Sprintf(buf, "Use %s special ability",
7361                 s_suffix(mons[u.umonnum].mname));
7362         add_herecmd_menuitem(win, domonability, buf);
7363     }
7364 #endif
7365
7366     if (OBJ_AT(u.ux, u.uy)) {
7367         struct obj *otmp = level.objects[u.ux][u.uy];
7368
7369         Sprintf(buf, "Pick up %s", otmp->nexthere ? "items" : doname(otmp));
7370         add_herecmd_menuitem(win, dopickup, buf);
7371
7372         if (Is_container(otmp)) {
7373             Sprintf(buf, "Loot %s", doname(otmp));
7374             add_herecmd_menuitem(win, doloot, buf);
7375         }
7376         if (otmp->oclass == FOOD_CLASS) {
7377             Sprintf(buf, "Eat %s", doname(otmp));
7378             add_herecmd_menuitem(win, doeat, buf);
7379         }
7380     }
7381
7382     if (invent)
7383         add_herecmd_menuitem(win, dodrop, "Drop items");
7384
7385     add_herecmd_menuitem(win, donull, "Rest one turn");
7386     add_herecmd_menuitem(win, dosearch, "Search around you");
7387     add_herecmd_menuitem(win, dolook, "Look at what is here");
7388
7389     end_menu(win, "What do you want to do?");
7390     npick = select_menu(win, PICK_ONE, &picks);
7391     destroy_nhwindow(win);
7392     ch = '\0';
7393     if (npick > 0) {
7394         int NDECL((*func)) = picks->item.a_nfunc;
7395         free((genericptr_t) picks);
7396
7397         if (doit) {
7398             int ret = (*func)();
7399
7400             ch = (char) ret;
7401         } else {
7402             ch = cmd_from_func(func);
7403         }
7404     }
7405     return ch;
7406 }
7407
7408
7409 static NEARDATA int last_multi;
7410
7411 /*
7412  * convert a MAP window position into a movecmd
7413  */
7414 const char *
7415 click_to_cmd(x, y, mod)
7416 int x, y, mod;
7417 {
7418     int dir;
7419     static char cmd[4];
7420     cmd[1] = 0;
7421
7422     if (iflags.clicklook && mod == CLICK_2) {
7423         clicklook_cc.x = x;
7424         clicklook_cc.y = y;
7425         cmd[0] = Cmd.spkeys[NHKF_CLICKLOOK];
7426         return cmd;
7427     }
7428
7429     x -= u.ux;
7430     y -= u.uy;
7431
7432     if (flags.travelcmd) {
7433         if (abs(x) <= 1 && abs(y) <= 1) {
7434             x = sgn(x), y = sgn(y);
7435         } else {
7436             u.tx = u.ux + x;
7437             u.ty = u.uy + y;
7438             cmd[0] = Cmd.spkeys[NHKF_TRAVEL];
7439             return cmd;
7440         }
7441
7442         if (x == 0 && y == 0) {
7443             if (iflags.herecmd_menu) {
7444                 cmd[0] = here_cmd_menu(FALSE);
7445                 return cmd;
7446             }
7447
7448             /* here */
7449             if (IS_FOUNTAIN(levl[u.ux][u.uy].typ)
7450                 || IS_SINK(levl[u.ux][u.uy].typ)) {
7451                 cmd[0] = cmd_from_func(mod == CLICK_1 ? dodrink : dodip);
7452                 return cmd;
7453             } else if (IS_THRONE(levl[u.ux][u.uy].typ)) {
7454                 cmd[0] = cmd_from_func(dosit);
7455                 return cmd;
7456             } else if ((u.ux == xupstair && u.uy == yupstair)
7457                        || (u.ux == sstairs.sx && u.uy == sstairs.sy
7458                            && sstairs.up)
7459                        || (u.ux == xupladder && u.uy == yupladder)) {
7460                 cmd[0] = cmd_from_func(doup);
7461                 return cmd;
7462             } else if ((u.ux == xdnstair && u.uy == ydnstair)
7463                        || (u.ux == sstairs.sx && u.uy == sstairs.sy
7464                            && !sstairs.up)
7465                        || (u.ux == xdnladder && u.uy == ydnladder)) {
7466                 cmd[0] = cmd_from_func(dodown);
7467                 return cmd;
7468             } else if (OBJ_AT(u.ux, u.uy)) {
7469                 cmd[0] = cmd_from_func(Is_container(level.objects[u.ux][u.uy])
7470                                        ? doloot : dopickup);
7471                 return cmd;
7472             } else {
7473                 cmd[0] = cmd_from_func(donull); /* just rest */
7474                 return cmd;
7475             }
7476         }
7477
7478         /* directional commands */
7479
7480         dir = xytod(x, y);
7481
7482         if (!m_at(u.ux + x, u.uy + y)
7483             && !test_move(u.ux, u.uy, x, y, TEST_MOVE)) {
7484             cmd[1] = Cmd.dirchars[dir];
7485             cmd[2] = '\0';
7486             if (iflags.herecmd_menu) {
7487                 cmd[0] = there_cmd_menu(FALSE, u.ux + x, u.uy + y);
7488                 if (cmd[0] == '\0')
7489                     cmd[1] = '\0';
7490                 return cmd;
7491             }
7492
7493             if (IS_DOOR(levl[u.ux + x][u.uy + y].typ)) {
7494                 /* slight assistance to the player: choose kick/open for them
7495                  */
7496                 if (levl[u.ux + x][u.uy + y].doormask & D_LOCKED) {
7497                     cmd[0] = cmd_from_func(dokick);
7498                     return cmd;
7499                 }
7500                 if (levl[u.ux + x][u.uy + y].doormask & D_CLOSED) {
7501                     cmd[0] = cmd_from_func(doopen);
7502                     return cmd;
7503                 }
7504             }
7505             if (levl[u.ux + x][u.uy + y].typ <= SCORR) {
7506                 cmd[0] = cmd_from_func(dosearch);
7507                 cmd[1] = 0;
7508                 return cmd;
7509             }
7510         }
7511     } else {
7512         /* convert without using floating point, allowing sloppy clicking */
7513         if (x > 2 * abs(y))
7514             x = 1, y = 0;
7515         else if (y > 2 * abs(x))
7516             x = 0, y = 1;
7517         else if (x < -2 * abs(y))
7518             x = -1, y = 0;
7519         else if (y < -2 * abs(x))
7520             x = 0, y = -1;
7521         else
7522             x = sgn(x), y = sgn(y);
7523
7524         if (x == 0 && y == 0) {
7525             /* map click on player to "rest" command */
7526             cmd[0] = cmd_from_func(donull);
7527             return cmd;
7528         }
7529         dir = xytod(x, y);
7530     }
7531
7532     /* move, attack, etc. */
7533     cmd[1] = 0;
7534     if (mod == CLICK_1) {
7535         cmd[0] = Cmd.dirchars[dir];
7536     } else {
7537         cmd[0] = (Cmd.num_pad
7538                      ? M(Cmd.dirchars[dir])
7539                      : (Cmd.dirchars[dir] - 'a' + 'A')); /* run command */
7540     }
7541
7542     return cmd;
7543 }
7544
7545 char
7546 get_count(allowchars, inkey, maxcount, count, historical)
7547 char *allowchars;
7548 char inkey;
7549 long maxcount;
7550 long *count;
7551 boolean historical; /* whether to include in message history: True => yes */
7552 {
7553     char qbuf[QBUFSZ];
7554     int key;
7555     long cnt = 0L;
7556     boolean backspaced = FALSE;
7557     /* this should be done in port code so that we have erase_char
7558        and kill_char available; we can at least fake erase_char */
7559 #define STANDBY_erase_char '\177'
7560
7561     for (;;) {
7562         if (inkey) {
7563             key = inkey;
7564             inkey = '\0';
7565         } else
7566             key = readchar();
7567
7568         if (digit(key)) {
7569             cnt = 10L * cnt + (long) (key - '0');
7570             if (cnt < 0)
7571                 cnt = 0;
7572             else if (maxcount > 0 && cnt > maxcount)
7573                 cnt = maxcount;
7574         } else if (cnt && (key == '\b' || key == STANDBY_erase_char)) {
7575             cnt = cnt / 10;
7576             backspaced = TRUE;
7577         } else if (key == Cmd.spkeys[NHKF_ESC]) {
7578             break;
7579         } else if (!allowchars || index(allowchars, key)) {
7580             *count = cnt;
7581             break;
7582         }
7583
7584         if (cnt > 9 || backspaced) {
7585             clear_nhwindow(WIN_MESSAGE);
7586             if (backspaced && !cnt) {
7587 /*JP
7588                 Sprintf(qbuf, "Count: ");
7589 */
7590                 Sprintf(qbuf, "\90\94: ");
7591             } else {
7592 /*JP
7593                 Sprintf(qbuf, "Count: %ld", cnt);
7594 */
7595                 Sprintf(qbuf, "\90\94: %ld", cnt);
7596                 backspaced = FALSE;
7597             }
7598             custompline(SUPPRESS_HISTORY, "%s", qbuf);
7599             mark_synch();
7600         }
7601     }
7602
7603     if (historical) {
7604 /*JP
7605         Sprintf(qbuf, "Count: %ld ", *count);
7606 */
7607         Sprintf(qbuf, "\90\94: %ld ", *count);
7608         (void) key2txt((uchar) key, eos(qbuf));
7609         putmsghistory(qbuf, FALSE);
7610     }
7611
7612     return key;
7613 }
7614
7615
7616 STATIC_OVL char *
7617 parse()
7618 {
7619 #ifdef LINT /* static char in_line[COLNO]; */
7620     char in_line[COLNO];
7621 #else
7622     static char in_line[COLNO];
7623 #endif
7624     register int foo;
7625
7626     iflags.in_parse = TRUE;
7627     multi = 0;
7628     context.move = 1;
7629     flush_screen(1); /* Flush screen buffer. Put the cursor on the hero. */
7630
7631 #ifdef ALTMETA
7632     alt_esc = iflags.altmeta; /* readchar() hack */
7633 #endif
7634     if (!Cmd.num_pad || (foo = readchar()) == Cmd.spkeys[NHKF_COUNT]) {
7635         long tmpmulti = multi;
7636
7637         foo = get_count((char *) 0, '\0', LARGEST_INT, &tmpmulti, FALSE);
7638         last_multi = multi = tmpmulti;
7639     }
7640 #ifdef ALTMETA
7641     alt_esc = FALSE; /* readchar() reset */
7642 #endif
7643
7644     if (iflags.debug_fuzzer /* if fuzzing, override '!' and ^Z */
7645         && (Cmd.commands[foo & 0x0ff]
7646             && (Cmd.commands[foo & 0x0ff]->ef_funct == dosuspend_core
7647                 || Cmd.commands[foo & 0x0ff]->ef_funct == dosh_core)))
7648         foo = Cmd.spkeys[NHKF_ESC];
7649
7650     if (foo == Cmd.spkeys[NHKF_ESC]) { /* esc cancels count (TH) */
7651         clear_nhwindow(WIN_MESSAGE);
7652         multi = last_multi = 0;
7653     } else if (foo == Cmd.spkeys[NHKF_DOAGAIN] || in_doagain) {
7654         multi = last_multi;
7655     } else {
7656         last_multi = multi;
7657         savech(0); /* reset input queue */
7658         savech((char) foo);
7659     }
7660
7661     if (multi) {
7662         multi--;
7663         save_cm = in_line;
7664     } else {
7665         save_cm = (char *) 0;
7666     }
7667     /* in 3.4.3 this was in rhack(), where it was too late to handle M-5 */
7668     if (Cmd.pcHack_compat) {
7669         /* This handles very old inconsistent DOS/Windows behaviour
7670            in a different way: earlier, the keyboard handler mapped
7671            these, which caused counts to be strange when entered
7672            from the number pad. Now do not map them until here. */
7673         switch (foo) {
7674         case '5':
7675             foo = Cmd.spkeys[NHKF_RUSH];
7676             break;
7677         case M('5'):
7678             foo = Cmd.spkeys[NHKF_RUN];
7679             break;
7680         case M('0'):
7681             foo = Cmd.spkeys[NHKF_DOINV];
7682             break;
7683         default:
7684             break; /* as is */
7685         }
7686     }
7687
7688     in_line[0] = foo;
7689     in_line[1] = '\0';
7690     if (prefix_cmd(foo)) {
7691         foo = readchar();
7692         savech((char) foo);
7693         in_line[1] = foo;
7694         in_line[2] = 0;
7695     }
7696     clear_nhwindow(WIN_MESSAGE);
7697
7698     iflags.in_parse = FALSE;
7699     return in_line;
7700 }
7701
7702 #ifdef HANGUPHANDLING
7703 /* some very old systems, or descendents of such systems, expect signal
7704    handlers to have return type `int', but they don't actually inspect
7705    the return value so we should be safe using `void' unconditionally */
7706 /*ARGUSED*/
7707 void
7708 hangup(sig_unused) /* called as signal() handler, so sent at least one arg */
7709 int sig_unused UNUSED;
7710 {
7711     if (program_state.exiting)
7712         program_state.in_moveloop = 0;
7713     nhwindows_hangup();
7714 #ifdef SAFERHANGUP
7715     /* When using SAFERHANGUP, the done_hup flag it tested in rhack
7716        and a couple of other places; actual hangup handling occurs then.
7717        This is 'safer' because it disallows certain cheats and also
7718        protects against losing objects in the process of being thrown,
7719        but also potentially riskier because the disconnected program
7720        must continue running longer before attempting a hangup save. */
7721     program_state.done_hup++;
7722     /* defer hangup iff game appears to be in progress */
7723     if (program_state.in_moveloop && program_state.something_worth_saving)
7724         return;
7725 #endif /* SAFERHANGUP */
7726     end_of_input();
7727 }
7728
7729 void
7730 end_of_input()
7731 {
7732 #ifdef NOSAVEONHANGUP
7733 #ifdef INSURANCE
7734     if (flags.ins_chkpt && program_state.something_worth_saving)
7735         program_state.preserve_locks = 1; /* keep files for recovery */
7736 #endif
7737     program_state.something_worth_saving = 0; /* don't save */
7738 #endif
7739
7740 #ifndef SAFERHANGUP
7741     if (!program_state.done_hup++)
7742 #endif
7743         if (program_state.something_worth_saving)
7744             (void) dosave0();
7745     if (iflags.window_inited)
7746         exit_nhwindows((char *) 0);
7747     clearlocks();
7748     nh_terminate(EXIT_SUCCESS);
7749     /*NOTREACHED*/ /* not necessarily true for vms... */
7750     return;
7751 }
7752 #endif /* HANGUPHANDLING */
7753
7754 char
7755 readchar()
7756 {
7757     register int sym;
7758     int x = u.ux, y = u.uy, mod = 0;
7759
7760     if (iflags.debug_fuzzer)
7761         return randomkey();
7762     if (*readchar_queue)
7763         sym = *readchar_queue++;
7764     else
7765         sym = in_doagain ? pgetchar() : nh_poskey(&x, &y, &mod);
7766
7767 #ifdef NR_OF_EOFS
7768     if (sym == EOF) {
7769         register int cnt = NR_OF_EOFS;
7770         /*
7771          * Some SYSV systems seem to return EOFs for various reasons
7772          * (?like when one hits break or for interrupted systemcalls?),
7773          * and we must see several before we quit.
7774          */
7775         do {
7776             clearerr(stdin); /* omit if clearerr is undefined */
7777             sym = pgetchar();
7778         } while (--cnt && sym == EOF);
7779     }
7780 #endif /* NR_OF_EOFS */
7781
7782     if (sym == EOF) {
7783 #ifdef HANGUPHANDLING
7784         hangup(0); /* call end_of_input() or set program_state.done_hup */
7785 #endif
7786         sym = '\033';
7787 #ifdef ALTMETA
7788     } else if (sym == '\033' && alt_esc) {
7789         /* iflags.altmeta: treat two character ``ESC c'' as single `M-c' */
7790         sym = *readchar_queue ? *readchar_queue++ : pgetchar();
7791         if (sym == EOF || sym == 0)
7792             sym = '\033';
7793         else if (sym != '\033')
7794             sym |= 0200; /* force 8th bit on */
7795 #endif /*ALTMETA*/
7796     } else if (sym == 0) {
7797         /* click event */
7798         readchar_queue = click_to_cmd(x, y, mod);
7799         sym = *readchar_queue++;
7800     }
7801     return (char) sym;
7802 }
7803
7804 /* '_' command, #travel, via keyboard rather than mouse click */
7805 STATIC_PTR int
7806 dotravel(VOID_ARGS)
7807 {
7808     static char cmd[2];
7809     coord cc;
7810
7811     /* [FIXME?  Supporting the ability to disable traveling via mouse
7812        click makes some sense, depending upon overall mouse usage.
7813        Disabling '_' on a user by user basis makes no sense at all since
7814        even if it is typed by accident, aborting when picking a target
7815        destination is trivial.  Travel via mouse predates travel via '_',
7816        and this use of OPTION=!travel is probably just a mistake....] */
7817     if (!flags.travelcmd)
7818         return 0;
7819
7820     cmd[1] = 0;
7821     cc.x = iflags.travelcc.x;
7822     cc.y = iflags.travelcc.y;
7823     if (cc.x == 0 && cc.y == 0) {
7824         /* No cached destination, start attempt from current position */
7825         cc.x = u.ux;
7826         cc.y = u.uy;
7827     }
7828     iflags.getloc_travelmode = TRUE;
7829     if (iflags.menu_requested) {
7830         int gf = iflags.getloc_filter;
7831         iflags.getloc_filter = GFILTER_VIEW;
7832         if (!getpos_menu(&cc, GLOC_INTERESTING)) {
7833             iflags.getloc_filter = gf;
7834             iflags.getloc_travelmode = FALSE;
7835             return 0;
7836         }
7837         iflags.getloc_filter = gf;
7838     } else {
7839 /*JP
7840         pline("Where do you want to travel to?");
7841 */
7842         pline("\82Ç\82±\82É\88Ú\93®\82·\82é\81H");
7843 /*JP
7844         if (getpos(&cc, TRUE, "the desired destination") < 0) {
7845 */
7846         if (getpos(&cc, TRUE, "\88Ú\93®\90æ") < 0) {
7847             /* user pressed ESC */
7848             iflags.getloc_travelmode = FALSE;
7849             return 0;
7850         }
7851     }
7852     iflags.getloc_travelmode = FALSE;
7853     iflags.travelcc.x = u.tx = cc.x;
7854     iflags.travelcc.y = u.ty = cc.y;
7855     cmd[0] = Cmd.spkeys[NHKF_TRAVEL];
7856     readchar_queue = cmd;
7857     return 0;
7858 }
7859
7860 /*
7861  *   Parameter validator for generic yes/no function to prevent
7862  *   the core from sending too long a prompt string to the
7863  *   window port causing a buffer overflow there.
7864  */
7865 char
7866 yn_function(query, resp, def)
7867 const char *query, *resp;
7868 char def;
7869 {
7870     char res, qbuf[QBUFSZ];
7871 #ifdef DUMPLOG
7872     extern unsigned saved_pline_index; /* pline.c */
7873     unsigned idx = saved_pline_index;
7874     /* buffer to hold query+space+formatted_single_char_response */
7875     char dumplog_buf[QBUFSZ + 1 + 15]; /* [QBUFSZ+1+7] should suffice */
7876 #endif
7877
7878     iflags.last_msg = PLNMSG_UNKNOWN; /* most recent pline is clobbered */
7879
7880     /* maximum acceptable length is QBUFSZ-1 */
7881     if (strlen(query) >= QBUFSZ) {
7882         /* caller shouldn't have passed anything this long */
7883         paniclog("Query truncated: ", query);
7884         (void) strncpy(qbuf, query, QBUFSZ - 1 - 3);
7885         Strcpy(&qbuf[QBUFSZ - 1 - 3], "...");
7886         query = qbuf;
7887     }
7888     res = (*windowprocs.win_yn_function)(query, resp, def);
7889 #ifdef DUMPLOG
7890     if (idx == saved_pline_index) {
7891         /* when idx is still the same as saved_pline_index, the interface
7892            didn't put the prompt into saved_plines[]; we put a simplified
7893            version in there now (without response choices or default) */
7894         Sprintf(dumplog_buf, "%s ", query);
7895         (void) key2txt((uchar) res, eos(dumplog_buf));
7896         dumplogmsg(dumplog_buf);
7897     }
7898 #endif
7899     return res;
7900 }
7901
7902 /* for paranoid_confirm:quit,die,attack prompting */
7903 boolean
7904 paranoid_query(be_paranoid, prompt)
7905 boolean be_paranoid;
7906 const char *prompt;
7907 {
7908     boolean confirmed_ok;
7909
7910     /* when paranoid, player must respond with "yes" rather than just 'y'
7911        to give the go-ahead for this query; default is "no" unless the
7912        ParanoidConfirm flag is set in which case there's no default */
7913     if (be_paranoid) {
7914         char pbuf[BUFSZ], qbuf[QBUFSZ], ans[BUFSZ];
7915         const char *promptprefix = "",
7916                 *responsetype = ParanoidConfirm ? "(yes|no)" : "(yes) [no]";
7917         int k, trylimit = 6; /* 1 normal, 5 more with "Yes or No:" prefix */
7918
7919         copynchars(pbuf, prompt, BUFSZ - 1);
7920         /* in addition to being paranoid about this particular
7921            query, we might be even more paranoid about all paranoia
7922            responses (ie, ParanoidConfirm is set) in which case we
7923            require "no" to reject in addition to "yes" to confirm
7924            (except we won't loop if response is ESC; it means no) */
7925         do {
7926             /* make sure we won't overflow a QBUFSZ sized buffer */
7927             k = (int) (strlen(promptprefix) + 1 + strlen(responsetype));
7928             if ((int) strlen(pbuf) + k > QBUFSZ - 1) {
7929                 /* chop off some at the end */
7930                 Strcpy(pbuf + (QBUFSZ - 1) - k - 4, "...?"); /* -4: "...?" */
7931             }
7932
7933             Sprintf(qbuf, "%s%s %s", promptprefix, pbuf, responsetype);
7934             *ans = '\0';
7935             getlin(qbuf, ans);
7936             (void) mungspaces(ans);
7937             confirmed_ok = !strcmpi(ans, "yes");
7938             if (confirmed_ok || *ans == '\033')
7939                 break;
7940             promptprefix = "\"Yes\" or \"No\": ";
7941         } while (ParanoidConfirm && strcmpi(ans, "no") && --trylimit);
7942     } else
7943         confirmed_ok = (yn(prompt) == 'y');
7944
7945     return confirmed_ok;
7946 }
7947
7948 /* ^Z command, #suspend */
7949 STATIC_PTR int
7950 dosuspend_core(VOID_ARGS)
7951 {
7952 #ifdef SUSPEND
7953     /* Does current window system support suspend? */
7954     if ((*windowprocs.win_can_suspend)()) {
7955         /* NB: SYSCF SHELLERS handled in port code. */
7956         dosuspend();
7957     } else
7958 #endif
7959         Norep(cmdnotavail, "#suspend");
7960     return 0;
7961 }
7962
7963 /* '!' command, #shell */
7964 STATIC_PTR int
7965 dosh_core(VOID_ARGS)
7966 {
7967 #ifdef SHELL
7968     /* access restrictions, if any, are handled in port code */
7969     dosh();
7970 #else
7971     Norep(cmdnotavail, "#shell");
7972 #endif
7973     return 0;
7974 }
7975
7976 /*cmd.c*/