OSDN Git Service

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