OSDN Git Service

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