OSDN Git Service

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