OSDN Git Service

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