OSDN Git Service

unused
[jnethack/source.git] / src / cmd.c
index 8fd20ef..f7efef2 100644 (file)
--- a/src/cmd.c
+++ b/src/cmd.c
@@ -1,10 +1,33 @@
-/* NetHack 3.6 cmd.c   $NHDT-Date: 1446975462 2015/11/08 09:37:42 $  $NHDT-Branch: master $:$NHDT-Revision: 1.206 $ */
+/* NetHack 3.6 cmd.c   $NHDT-Date: 1557088405 2019/05/05 20:33:25 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.333 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/*-Copyright (c) Robert Patrick Rankin, 2013. */
 /* NetHack may be freely redistributed.  See license for details. */
 
+/* JNetHack Copyright */
+/* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000  */
+/* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2019            */
+/* JNetHack may be freely redistributed.  See license for details. */
+
 #include "hack.h"
+#include "lev.h"
 #include "func_tab.h"
 
+/* Macros for meta and ctrl modifiers:
+ *   M and C return the meta/ctrl code for the given character;
+ *     e.g., (C('c') is ctrl-c
+ */
+#ifndef M
+#ifndef NHSTDC
+#define M(c) (0x80 | (c))
+#else
+#define M(c) ((c) - 128)
+#endif /* NHSTDC */
+#endif
+
+#ifndef C
+#define C(c) (0x1f & (c))
+#endif
+
 #ifdef ALTMETA
 STATIC_VAR boolean alt_esc = FALSE;
 #endif
@@ -29,7 +52,6 @@ extern const char *enc_stat[]; /* encumbrance status from botl.c */
 
 #ifdef DEBUG
 extern int NDECL(wiz_debug_cmd_bury);
-extern int NDECL(wiz_debug_cmd_traveldisplay);
 #endif
 
 #ifdef DUMB /* stuff commented out in extern.h, but needed here */
@@ -98,7 +120,7 @@ extern int NDECL(dosit);              /**/
 extern int NDECL(dotalk);             /**/
 extern int NDECL(docast);             /**/
 extern int NDECL(dovspell);           /**/
-extern int NDECL(dotele);             /**/
+extern int NDECL(dotelecmd);          /**/
 extern int NDECL(dountrap);           /**/
 extern int NDECL(doversion);          /**/
 extern int NDECL(doextversion);       /**/
@@ -107,22 +129,24 @@ extern int NDECL(dowield);            /**/
 extern int NDECL(dowieldquiver);      /**/
 extern int NDECL(dozap);              /**/
 extern int NDECL(doorganize);         /**/
-#endif                                /* DUMB */
-
-static int NDECL(dosuspend_core); /**/
+#endif /* DUMB */
 
 static int NDECL((*timed_occ_fn));
 
+STATIC_PTR int NDECL(dosuspend_core);
+STATIC_PTR int NDECL(dosh_core);
+STATIC_PTR int NDECL(doherecmdmenu);
+STATIC_PTR int NDECL(dotherecmdmenu);
 STATIC_PTR int NDECL(doprev_message);
 STATIC_PTR int NDECL(timed_occupation);
 STATIC_PTR int NDECL(doextcmd);
-STATIC_PTR int NDECL(domonability);
-STATIC_PTR int NDECL(dooverview_or_wiz_where);
 STATIC_PTR int NDECL(dotravel);
 STATIC_PTR int NDECL(doterrain);
 STATIC_PTR int NDECL(wiz_wish);
 STATIC_PTR int NDECL(wiz_identify);
+STATIC_PTR int NDECL(wiz_intrinsic);
 STATIC_PTR int NDECL(wiz_map);
+STATIC_PTR int NDECL(wiz_makemap);
 STATIC_PTR int NDECL(wiz_genesis);
 STATIC_PTR int NDECL(wiz_where);
 STATIC_PTR int NDECL(wiz_detect);
@@ -133,7 +157,7 @@ STATIC_PTR int NDECL(wiz_level_change);
 STATIC_PTR int NDECL(wiz_show_seenv);
 STATIC_PTR int NDECL(wiz_show_vision);
 STATIC_PTR int NDECL(wiz_smell);
-STATIC_PTR int NDECL(wiz_mon_polycontrol);
+STATIC_PTR int NDECL(wiz_intrinsic);
 STATIC_PTR int NDECL(wiz_show_wmodes);
 STATIC_DCL void NDECL(wiz_map_levltyp);
 STATIC_DCL void NDECL(wiz_levltyp_legend);
@@ -143,27 +167,24 @@ extern void FDECL(show_borlandc_stats, (winid));
 #ifdef DEBUG_MIGRATING_MONS
 STATIC_PTR int NDECL(wiz_migrate_mons);
 #endif
-STATIC_DCL int FDECL(size_monst, (struct monst *));
+STATIC_DCL int FDECL(size_monst, (struct monst *, BOOLEAN_P));
 STATIC_DCL int FDECL(size_obj, (struct obj *));
 STATIC_DCL void FDECL(count_obj, (struct obj *, long *, long *,
                                   BOOLEAN_P, BOOLEAN_P));
 STATIC_DCL void FDECL(obj_chain, (winid, const char *, struct obj *,
-                                  long *, long *));
+                                  BOOLEAN_P, long *, long *));
 STATIC_DCL void FDECL(mon_invent_chain, (winid, const char *, struct monst *,
                                          long *, long *));
 STATIC_DCL void FDECL(mon_chain, (winid, const char *, struct monst *,
-                                  long *, long *));
-STATIC_DCL void FDECL(contained, (winid, const char *, long *, long *));
+                                  BOOLEAN_P, long *, long *));
+STATIC_DCL void FDECL(contained_stats, (winid, const char *, long *, long *));
+STATIC_DCL void FDECL(misc_stats, (winid, long *, long *));
 STATIC_PTR int NDECL(wiz_show_stats);
 STATIC_DCL boolean FDECL(accept_menu_prefix, (int NDECL((*))));
-#ifdef PORT_DEBUG
-STATIC_DCL int NDECL(wiz_port_debug);
-#endif
 STATIC_PTR int NDECL(wiz_rumor_check);
-STATIC_DCL char FDECL(cmd_from_func, (int NDECL((*))));
 STATIC_PTR int NDECL(doattributes);
-STATIC_PTR int NDECL(doconduct); /**/
 
+STATIC_DCL void FDECL(enlght_out, (const char *));
 STATIC_DCL void FDECL(enlght_line, (const char *, const char *, const char *,
                                     const char *));
 STATIC_DCL char *FDECL(enlght_combatinc, (const char *, int, int, char *));
@@ -172,16 +193,32 @@ STATIC_DCL boolean NDECL(walking_on_water);
 STATIC_DCL boolean FDECL(cause_known, (int));
 STATIC_DCL char *FDECL(attrval, (int, int, char *));
 STATIC_DCL void FDECL(background_enlightenment, (int, int));
+STATIC_DCL void FDECL(basics_enlightenment, (int, int));
 STATIC_DCL void FDECL(characteristics_enlightenment, (int, int));
 STATIC_DCL void FDECL(one_characteristic, (int, int, int));
 STATIC_DCL void FDECL(status_enlightenment, (int, int));
 STATIC_DCL void FDECL(attributes_enlightenment, (int, int));
 
+STATIC_DCL void FDECL(add_herecmd_menuitem, (winid, int NDECL((*)),
+                                             const char *));
+STATIC_DCL char FDECL(here_cmd_menu, (BOOLEAN_P));
+STATIC_DCL char FDECL(there_cmd_menu, (BOOLEAN_P, int, int));
+STATIC_DCL char *NDECL(parse);
+STATIC_DCL void FDECL(show_direction_keys, (winid, CHAR_P, BOOLEAN_P));
+STATIC_DCL boolean FDECL(help_dir, (CHAR_P, int, const char *));
+
 static const char *readchar_queue = "";
 static coord clicklook_cc;
-
-STATIC_DCL char *NDECL(parse);
-STATIC_DCL boolean FDECL(help_dir, (CHAR_P, const char *));
+/* for rejecting attempts to use wizard mode commands */
+/*JP
+static const char unavailcmd[] = "Unavailable command '%s'.";
+*/
+static const char unavailcmd[] = "'%s'\83R\83}\83\93\83h\82Í\8eg\82¦\82È\82¢\81D";
+/* for rejecting #if !SHELL, !SUSPEND */
+/*JP
+static const char cmdnotavail[] = "'%s' command not available.";
+*/
+static const char cmdnotavail[] = "'%s'\83R\83}\83\93\83h\82Í\97\98\97p\82Å\82«\82Ü\82¹\82ñ\81D";
 
 STATIC_PTR int
 doprev_message(VOID_ARGS)
@@ -273,6 +310,8 @@ pgetchar() /* courtesy of aeb@cwi.nl */
 {
     register int ch;
 
+    if (iflags.debug_fuzzer)
+        return randomkey();
     if (!(ch = popch()))
         ch = nhgetch();
     return (char) ch;
@@ -320,8 +359,23 @@ doextcmd(VOID_ARGS)
             return 0; /* quit */
 
         func = extcmdlist[idx].ef_funct;
+        if (!wizard && (extcmdlist[idx].flags & WIZMODECMD)) {
+/*JP
+            You("can't do that.");
+*/
+            pline("\82»\82ê\82Í\82Å\82«\82Ü\82¹\82ñ\81D");
+            return 0;
+        }
         if (iflags.menu_requested && !accept_menu_prefix(func)) {
-            pline("'m' prefix has no effect for this command.");
+#if 0 /*JP*/
+            pline("'%s' prefix has no effect for the %s command.",
+                  visctrl(Cmd.spkeys[NHKF_REQMENU]),
+                  extcmdlist[idx].ef_txt);
+#else
+            pline("'%s'\90Ú\93ª\8e«\82Í%s\83R\83}\83\93\83h\82É\82Í\96³\8cø\81D",
+                  visctrl(Cmd.spkeys[NHKF_REQMENU]),
+                  extcmdlist[idx].ef_txt);
+#endif
             iflags.menu_requested = FALSE;
         }
         retval = (*func)();
@@ -330,36 +384,196 @@ doextcmd(VOID_ARGS)
     return retval;
 }
 
-/* here after #? - now list all full-word commands */
+/* here after #? - now list all full-word commands and provid
+   some navigation capability through the long list */
 int
 doextlist(VOID_ARGS)
 {
     register const struct ext_func_tab *efp;
-    char buf[BUFSZ];
-    winid datawin;
+    char buf[BUFSZ], searchbuf[BUFSZ], promptbuf[QBUFSZ];
+    winid menuwin;
+    anything any;
+    menu_item *selected;
+    int n, pass;
+    int menumode = 0, menushown[2], onelist = 0;
+    boolean redisplay = TRUE, search = FALSE;
+#if 0 /*JP*/
+    static const char *headings[] = { "Extended commands",
+                                      "Debugging Extended Commands" };
+#else
+    static const char *headings[] = { "\8ag\92£\83R\83}\83\93\83h",
+                                      "\83f\83o\83b\83O\8ag\92£\83R\83}\83\93\83h" };
+#endif
 
-    datawin = create_nhwindow(NHW_TEXT);
-    putstr(datawin, 0, "");
-    putstr(datawin, 0, "            Extended Commands List");
-    putstr(datawin, 0, "");
-    putstr(datawin, 0, "    Press '#', then type:");
-    putstr(datawin, 0, "");
+    searchbuf[0] = '\0';
+    menuwin = create_nhwindow(NHW_MENU);
 
-    for (efp = extcmdlist; efp->ef_txt; efp++) {
-        Sprintf(buf, "    %-15s - %s.", efp->ef_txt, efp->ef_desc);
-        putstr(datawin, 0, buf);
+    while (redisplay) {
+        redisplay = FALSE;
+        any = zeroany;
+        start_menu(menuwin);
+#if 0 /*JP*/
+        add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
+                 "Extended Commands List", MENU_UNSELECTED);
+#else
+        add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
+                 "\8ag\92£\83R\83}\83\93\83h\88ê\97\97", MENU_UNSELECTED);
+#endif
+        add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
+                 "", MENU_UNSELECTED);
+
+        Strcpy(buf, menumode ? "Show" : "Hide");
+        Strcat(buf, " commands that don't autocomplete");
+        if (!menumode)
+            Strcat(buf, " (those not marked with [A])");
+        any.a_int = 1;
+        add_menu(menuwin, NO_GLYPH, &any, 'a', 0, ATR_NONE, buf,
+                 MENU_UNSELECTED);
+
+        if (!*searchbuf) {
+            any.a_int = 2;
+            /* was 's', but then using ':' handling within the interface
+               would only examine the two or three meta entries, not the
+               actual list of extended commands shown via separator lines;
+               having ':' as an explicit selector overrides the default
+               menu behavior for it; we retain 's' as a group accelerator */
+            add_menu(menuwin, NO_GLYPH, &any, ':', 's', ATR_NONE,
+                     "Search extended commands", MENU_UNSELECTED);
+        } else {
+            Strcpy(buf, "Show all, clear search");
+            if (strlen(buf) + strlen(searchbuf) + strlen(" (\"\")") < QBUFSZ)
+                Sprintf(eos(buf), " (\"%s\")", searchbuf);
+            any.a_int = 3;
+            /* specifying ':' as a group accelerator here is mostly a
+               statement of intent (we'd like to accept it as a synonym but
+               also want to hide it from general menu use) because it won't
+               work for interfaces which support ':' to search; use as a
+               general menu command takes precedence over group accelerator */
+            add_menu(menuwin, NO_GLYPH, &any, 's', ':', ATR_NONE,
+                     buf, MENU_UNSELECTED);
+        }
+        if (wizard) {
+            any.a_int = 4;
+            add_menu(menuwin, NO_GLYPH, &any, 'z', 0, ATR_NONE,
+                     onelist ? "Show debugging commands in separate section"
+                     : "Show all alphabetically, including debugging commands",
+                     MENU_UNSELECTED);
+        }
+        any = zeroany;
+        add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
+                 "", MENU_UNSELECTED);
+        menushown[0] = menushown[1] = 0;
+        n = 0;
+        for (pass = 0; pass <= 1; ++pass) {
+            /* skip second pass if not in wizard mode or wizard mode
+               commands are being integrated into a single list */
+            if (pass == 1 && (onelist || !wizard))
+                break;
+            for (efp = extcmdlist; efp->ef_txt; efp++) {
+                int wizc;
+
+                if ((efp->flags & CMD_NOT_AVAILABLE) != 0)
+                    continue;
+                /* if hiding non-autocomplete commands, skip such */
+                if (menumode == 1 && (efp->flags & AUTOCOMPLETE) == 0)
+                    continue;
+                /* if searching, skip this command if it doesn't match */
+                if (*searchbuf
+                    /* first try case-insensitive substring match */
+                    && !strstri(efp->ef_txt, searchbuf)
+                    && !strstri(efp->ef_desc, searchbuf)
+                    /* wildcard support; most interfaces use case-insensitve
+                       pmatch rather than regexp for menu searching */
+                    && !pmatchi(searchbuf, efp->ef_txt)
+                    && !pmatchi(searchbuf, efp->ef_desc))
+                    continue;
+                /* skip wizard mode commands if not in wizard mode;
+                   when showing two sections, skip wizard mode commands
+                   in pass==0 and skip other commands in pass==1 */
+                wizc = (efp->flags & WIZMODECMD) != 0;
+                if (wizc && !wizard)
+                    continue;
+                if (!onelist && pass != wizc)
+                    continue;
+
+                /* We're about to show an item, have we shown the menu yet?
+                   Doing menu in inner loop like this on demand avoids a
+                   heading with no subordinate entries on the search
+                   results menu. */
+                if (!menushown[pass]) {
+                    Strcpy(buf, headings[pass]);
+                    add_menu(menuwin, NO_GLYPH, &any, 0, 0,
+                             iflags.menu_headings, buf, MENU_UNSELECTED);
+                    menushown[pass] = 1;
+                }
+                Sprintf(buf, " %-14s %-3s %s",
+                        efp->ef_txt,
+                        (efp->flags & AUTOCOMPLETE) ? "[A]" : " ",
+                        efp->ef_desc);
+                add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
+                         buf, MENU_UNSELECTED);
+                ++n;
+            }
+            if (n)
+                add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
+                         "", MENU_UNSELECTED);
+        }
+        if (*searchbuf && !n)
+            add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
+                     "no matches", MENU_UNSELECTED);
+
+        end_menu(menuwin, (char *) 0);
+        n = select_menu(menuwin, PICK_ONE, &selected);
+        if (n > 0) {
+            switch (selected[0].item.a_int) {
+            case 1: /* 'a': toggle show/hide non-autocomplete */
+                menumode = 1 - menumode;  /* toggle 0 -> 1, 1 -> 0 */
+                redisplay = TRUE;
+                break;
+            case 2: /* ':' when not searching yet: enable search */
+                search = TRUE;
+                break;
+            case 3: /* 's' when already searching: disable search */
+                search = FALSE;
+                searchbuf[0] = '\0';
+                redisplay = TRUE;
+                break;
+            case 4: /* 'z': toggle showing wizard mode commands separately */
+                search = FALSE;
+                searchbuf[0] = '\0';
+                onelist = 1 - onelist;  /* toggle 0 -> 1, 1 -> 0 */
+                redisplay = TRUE;
+                break;
+            }
+            free((genericptr_t) selected);
+        } else {
+            search = FALSE;
+            searchbuf[0] = '\0';
+        }
+        if (search) {
+            Strcpy(promptbuf, "Extended command list search phrase");
+            Strcat(promptbuf, "?");
+            getlin(promptbuf, searchbuf);
+            (void) mungspaces(searchbuf);
+            if (searchbuf[0] == '\033')
+                searchbuf[0] = '\0';
+            if (*searchbuf)
+                redisplay = TRUE;
+            search = FALSE;
+        }
     }
-    display_nhwindow(datawin, FALSE);
-    destroy_nhwindow(datawin);
+    destroy_nhwindow(menuwin);
     return 0;
 }
 
-#ifdef TTY_GRAPHICS
-#define MAX_EXT_CMD 50 /* Change if we ever have > 50 ext cmds */
+#if defined(TTY_GRAPHICS) || defined(CURSES_GRAPHICS)
+#define MAX_EXT_CMD 200 /* Change if we ever have more ext cmds */
 
 /*
- * This is currently used only by the tty port and is
- * controlled via runtime option 'extmenu'.
+ * This is currently used only by the tty interface and is
+ * controlled via runtime option 'extmenu'.  (Most other interfaces
+ * already use a menu all the time for extended commands.)
+ *
  * ``# ?'' is counted towards the limit of the number of commands,
  * so we actually support MAX_EXT_CMD-1 "real" extended commands.
  *
@@ -376,9 +590,10 @@ extcmd_via_menu()
     char buf[BUFSZ];
     char cbuf[QBUFSZ], prompt[QBUFSZ], fmtstr[20];
     int i, n, nchoices, acount;
-    int ret, biggest;
+    int ret, len, biggest;
     int accelerator, prevaccelerator;
     int matchlevel = 0;
+    boolean wastoolong, one_per_line;
 
     ret = 0;
     cbuf[0] = '\0';
@@ -388,12 +603,14 @@ extcmd_via_menu()
         any = zeroany;
         /* populate choices */
         for (efp = extcmdlist; efp->ef_txt; efp++) {
+            if ((efp->flags & CMD_NOT_AVAILABLE)
+                || !(efp->flags & AUTOCOMPLETE)
+                || (!wizard && (efp->flags & WIZMODECMD)))
+                continue;
             if (!matchlevel || !strncmp(efp->ef_txt, cbuf, matchlevel)) {
                 choices[i] = efp;
-                if ((int) strlen(efp->ef_desc) > biggest) {
-                    biggest = strlen(efp->ef_desc);
-                    Sprintf(fmtstr, "%%-%ds", biggest + 15);
-                }
+                if ((len = (int) strlen(efp->ef_desc)) > biggest)
+                    biggest = len;
                 if (++i > MAX_EXT_CMD) {
 #if defined(BETA)
                     impossible(
@@ -408,23 +625,33 @@ extcmd_via_menu()
         choices[i] = (struct ext_func_tab *) 0;
         nchoices = i;
         /* if we're down to one, we have our selection so get out of here */
-        if (nchoices == 1) {
-            for (i = 0; extcmdlist[i].ef_txt != (char *) 0; i++)
-                if (!strncmpi(extcmdlist[i].ef_txt, cbuf, matchlevel)) {
-                    ret = i;
-                    break;
-                }
+        if (nchoices  <= 1) {
+            ret = (nchoices == 1) ? (int) (choices[0] - extcmdlist) : -1;
             break;
         }
 
         /* otherwise... */
         win = create_nhwindow(NHW_MENU);
         start_menu(win);
+        Sprintf(fmtstr, "%%-%ds", biggest + 15);
+        prompt[0] = '\0';
+        wastoolong = FALSE; /* True => had to wrap due to line width
+                             * ('w' in wizard mode) */
+        /* -3: two line menu header, 1 line menu footer (for prompt) */
+        one_per_line = (nchoices < ROWNO - 3);
         accelerator = prevaccelerator = 0;
         acount = 0;
         for (i = 0; choices[i]; ++i) {
             accelerator = choices[i]->ef_txt[matchlevel];
-            if (accelerator != prevaccelerator || nchoices < (ROWNO - 3)) {
+            if (accelerator != prevaccelerator || one_per_line)
+                wastoolong = FALSE;
+            if (accelerator != prevaccelerator || one_per_line
+                || (acount >= 2
+                    /* +4: + sizeof " or " - sizeof "" */
+                    && (strlen(prompt) + 4 + strlen(choices[i]->ef_txt)
+                        /* -6: enough room for 1 space left margin
+                         *   + "%c - " menu selector + 1 space right margin */
+                        >= min(sizeof prompt, COLNO - 6)))) {
                 if (acount) {
                     /* flush extended cmds for that letter already in buf */
                     Sprintf(buf, fmtstr, prompt);
@@ -432,17 +659,32 @@ extcmd_via_menu()
                     add_menu(win, NO_GLYPH, &any, any.a_char, 0, ATR_NONE,
                              buf, FALSE);
                     acount = 0;
+                    if (!(accelerator != prevaccelerator || one_per_line))
+                        wastoolong = TRUE;
                 }
             }
             prevaccelerator = accelerator;
-            if (!acount || nchoices < (ROWNO - 3)) {
-                Sprintf(prompt, "%s [%s]", choices[i]->ef_txt,
-                        choices[i]->ef_desc);
+            if (!acount || one_per_line) {
+#if 0 /*JP:T*/
+                Sprintf(prompt, "%s%s [%s]", wastoolong ? "or " : "",
+                        choices[i]->ef_txt, choices[i]->ef_desc);
+#else
+                Sprintf(prompt, "%s%s [%s]", wastoolong ? "\82Ü\82½\82Í" : "",
+                        choices[i]->ef_txt, choices[i]->ef_desc);
+#endif
             } else if (acount == 1) {
-                Sprintf(prompt, "%s or %s", choices[i - 1]->ef_txt,
-                        choices[i]->ef_txt);
+#if 0 /*JP:T*/
+                Sprintf(prompt, "%s%s or %s", wastoolong ? "or " : "",
+                        choices[i - 1]->ef_txt, choices[i]->ef_txt);
+#else
+                Sprintf(prompt, "%s%s\82Ü\82½\82Í%s", wastoolong ? "\82Ü\82½\82Í" : "",
+                        choices[i - 1]->ef_txt, choices[i]->ef_txt);
+#endif
             } else {
+/*JP
                 Strcat(prompt, " or ");
+*/
+                Strcat(prompt," \82Ü\82½\82Í ");
                 Strcat(prompt, choices[i]->ef_txt);
             }
             ++acount;
@@ -454,7 +696,10 @@ extcmd_via_menu()
             add_menu(win, NO_GLYPH, &any, any.a_char, 0, ATR_NONE, buf,
                      FALSE);
         }
+/*JP
         Sprintf(prompt, "Extended Command: %s", cbuf);
+*/
+        Sprintf(prompt, "\8ag\92£\83R\83}\83\93\83h: %s", cbuf);
         end_menu(win, prompt);
         n = select_menu(win, PICK_ONE, &pick_list);
         destroy_nhwindow(win);
@@ -484,7 +729,7 @@ extcmd_via_menu()
 #endif /* TTY_GRAPHICS */
 
 /* #monster command - use special monster ability while polymorphed */
-STATIC_PTR int
+int
 domonability(VOID_ARGS)
 {
     if (can_breathe(youmonst.data))
@@ -508,22 +753,37 @@ domonability(VOID_ARGS)
             if (split_mon(&youmonst, (struct monst *) 0))
                 dryup(u.ux, u.uy, TRUE);
         } else
+/*JP
             There("is no fountain here.");
+*/
+            pline("\82±\82±\82É\82Í\90ò\82Í\82È\82¢\81D");
     } else if (is_unicorn(youmonst.data)) {
         use_unicorn_horn((struct obj *) 0);
         return 1;
     } else if (youmonst.data->msound == MS_SHRIEK) {
+/*JP
         You("shriek.");
+*/
+        You("\8bà\90Ø\82è\90º\82ð\82 \82°\82½\81D");
         if (u.uburied)
+/*JP
             pline("Unfortunately sound does not carry well through rock.");
+*/
+            pline("\8ec\94O\82È\82ª\82ç\89¹\82Í\8aâ\82ð\82¤\82Ü\82­\93`\82í\82ç\82È\82¢\81D");
         else
             aggravate();
     } else if (youmonst.data->mlet == S_VAMPIRE)
         return dopoly();
     else if (Upolyd)
+/*JP
         pline("Any special ability you may have is purely reflexive.");
+*/
+        pline("\82 \82È\82½\82Ì\8e\9d\82Á\82Ä\82¢\82é\93Á\8eê\94\\97Í\82Í\82Ç\82ê\82à\8eó\93®\93I\82¾\81D");
     else
+/*JP
         You("don't have a special ability in your normal form!");
+*/
+        You("\95\81\92i\82Ì\8ep\82Å\82Ì\93Á\8eê\94\\97Í\82ð\8e\9d\82Á\82Ä\82¢\82È\82¢\81I");
     return 0;
 }
 
@@ -531,44 +791,55 @@ int
 enter_explore_mode(VOID_ARGS)
 {
     if (wizard) {
+/*JP
         You("are in debug mode.");
+*/
+        You("\82·\82Å\82É\83f\83o\83b\83O\83\82\81[\83h\82¾\81D");
     } else if (discover) {
+/*JP
         You("are already in explore mode.");
+*/
+        You("\82·\82Å\82É\92T\8c\9f\83\82\81[\83h\82¾\81D");
     } else {
 #ifdef SYSCF
 #if defined(UNIX)
         if (!sysopt.explorers || !sysopt.explorers[0]
             || !check_user_string(sysopt.explorers)) {
+/*JP
             You("cannot access explore mode.");
+*/
+            You("\92T\8c\9f\83\82\81[\83h\82É\83A\83N\83Z\83X\82Å\82«\82È\82¢\81D");
             return 0;
         }
 #endif
 #endif
         pline(
+/*JP
         "Beware!  From explore mode there will be no return to normal game.");
+*/
+        "\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");
         if (paranoid_query(ParanoidQuit,
+/*JP
                            "Do you want to enter explore mode?")) {
+*/
+                           "\94­\8c©\83\82\81[\83h\82É\88Ú\82è\82Ü\82·\82©\81H")) {
             clear_nhwindow(WIN_MESSAGE);
+/*JP
             You("are now in non-scoring explore mode.");
+*/
+            You("\83X\83R\83A\82ª\82Ì\82ç\82È\82¢\94­\8c©\83\82\81[\83h\82É\88Ú\8ds\82µ\82½\81D");
             discover = TRUE;
         } else {
             clear_nhwindow(WIN_MESSAGE);
+/*JP
             pline("Resuming normal game.");
+*/
+            pline("\92Ê\8fí\83\82\81[\83h\82ð\91±\82¯\82é\81D");
         }
     }
     return 0;
 }
 
-STATIC_PTR int
-dooverview_or_wiz_where(VOID_ARGS)
-{
-    if (wizard)
-        return wiz_where();
-    else
-        dooverview();
-    return 0;
-}
-
 /* ^W command - wish for something */
 STATIC_PTR int
 wiz_wish(VOID_ARGS) /* Unlimited wishes for debug mode by Paul Polderman */
@@ -581,8 +852,7 @@ wiz_wish(VOID_ARGS) /* Unlimited wishes for debug mode by Paul Polderman */
         flags.verbose = save_verbose;
         (void) encumber_msg();
     } else
-        pline("Unavailable command '%s'.",
-              visctrl((int) cmd_from_func(wiz_wish)));
+        pline(unavailcmd, visctrl((int) cmd_from_func(wiz_wish)));
     return 0;
 }
 
@@ -592,12 +862,104 @@ wiz_identify(VOID_ARGS)
 {
     if (wizard) {
         iflags.override_ID = (int) cmd_from_func(wiz_identify);
-        if (display_inventory((char *) 0, TRUE) == -1)
-            identify_pack(0, FALSE);
+        /* command remapping might leave #wizidentify as the only way
+           to invoke us, in which case cmd_from_func() will yield NUL;
+           it won't matter to display_inventory()/display_pickinv()
+           if ^I invokes some other command--what matters is that
+           display_pickinv() and xname() see override_ID as nonzero */
+        if (!iflags.override_ID)
+            iflags.override_ID = C('I');
+        (void) display_inventory((char *) 0, FALSE);
         iflags.override_ID = 0;
     } else
-        pline("Unavailable command '%s'.",
-              visctrl((int) cmd_from_func(wiz_identify)));
+        pline(unavailcmd, visctrl((int) cmd_from_func(wiz_identify)));
+    return 0;
+}
+
+/* #wizmakemap - discard current dungeon level and replace with a new one */
+STATIC_PTR int
+wiz_makemap(VOID_ARGS)
+{
+    if (wizard) {
+        struct monst *mtmp;
+        boolean was_in_W_tower = In_W_tower(u.ux, u.uy, &u.uz);
+
+        rm_mapseen(ledger_no(&u.uz));
+        for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
+            if (mtmp->isgd) { /* vault is going away; get rid of guard */
+                mtmp->isgd = 0;
+                mongone(mtmp);
+            }
+            if (DEADMONSTER(mtmp))
+                continue;
+            if (mtmp->isshk)
+                setpaid(mtmp);
+            /* TODO?
+             *  Reduce 'born' tally for each monster about to be discarded
+             *  by savelev(), otherwise replacing heavily populated levels
+             *  tends to make their inhabitants become extinct.
+             */
+        }
+        if (Punished) {
+            ballrelease(FALSE);
+            unplacebc();
+        }
+        /* reset lock picking unless it's for a carried container */
+        maybe_reset_pick((struct obj *) 0);
+        /* reset interrupted digging if it was taking place on this level */
+        if (on_level(&context.digging.level, &u.uz))
+            (void) memset((genericptr_t) &context.digging, 0,
+                          sizeof (struct dig_info));
+        /* reset cached targets */
+        iflags.travelcc.x = iflags.travelcc.y = 0; /* travel destination */
+        context.polearm.hitmon = (struct monst *) 0; /* polearm target */
+        /* escape from trap */
+        reset_utrap(FALSE);
+        check_special_room(TRUE); /* room exit */
+        u.ustuck = (struct monst *) 0;
+        u.uswallow = 0;
+        u.uinwater = 0;
+        u.uundetected = 0; /* not hidden, even if means are available */
+        dmonsfree(); /* purge dead monsters from 'fmon' */
+        /* keep steed and other adjacent pets after releasing them
+           from traps, stopping eating, &c as if hero were ascending */
+        keepdogs(TRUE); /* (pets-only; normally we'd be using 'FALSE' here) */
+
+        /* discard current level; "saving" is used to release dynamic data */
+        savelev(-1, ledger_no(&u.uz), FREE_SAVE);
+        /* create a new level; various things like bestowing a guardian
+           angel on Astral or setting off alarm on Ft.Ludios are handled
+           by goto_level(do.c) so won't occur for replacement levels */
+        mklev();
+
+        vision_reset();
+        vision_full_recalc = 1;
+        cls();
+        /* was using safe_teleds() but that doesn't honor arrival region
+           on levels which have such; we don't force stairs, just area */
+        u_on_rndspot((u.uhave.amulet ? 1 : 0) /* 'going up' flag */
+                     | (was_in_W_tower ? 2 : 0));
+        losedogs();
+        /* u_on_rndspot() might pick a spot that has a monster, or losedogs()
+           might pick the hero's spot (only if there isn't already a monster
+           there), so we might have to move hero or the co-located monster */
+        if ((mtmp = m_at(u.ux, u.uy)) != 0)
+            u_collide_m(mtmp);
+        initrack();
+        if (Punished) {
+            unplacebc();
+            placebc();
+        }
+        docrt();
+        flush_screen(1);
+        deliver_splev_message(); /* level entry */
+        check_special_room(FALSE); /* room entry */
+#ifdef INSURANCE
+        save_currentstate();
+#endif
+    } else {
+        pline(unavailcmd, "#wizmakemap");
+    }
     return 0;
 }
 
@@ -618,8 +980,7 @@ wiz_map(VOID_ARGS)
         HConfusion = save_Hconf;
         HHallucination = save_Hhallu;
     } else
-        pline("Unavailable command '%s'.",
-              visctrl((int) cmd_from_func(wiz_map)));
+        pline(unavailcmd, visctrl((int) cmd_from_func(wiz_map)));
     return 0;
 }
 
@@ -630,8 +991,7 @@ wiz_genesis(VOID_ARGS)
     if (wizard)
         (void) create_particular();
     else
-        pline("Unavailable command '%s'.",
-              visctrl((int) cmd_from_func(wiz_genesis)));
+        pline(unavailcmd, visctrl((int) cmd_from_func(wiz_genesis)));
     return 0;
 }
 
@@ -642,8 +1002,7 @@ wiz_where(VOID_ARGS)
     if (wizard)
         (void) print_dungeon(FALSE, (schar *) 0, (xchar *) 0);
     else
-        pline("Unavailable command '%s'.",
-              visctrl((int) cmd_from_func(wiz_where)));
+        pline(unavailcmd, visctrl((int) cmd_from_func(wiz_where)));
     return 0;
 }
 
@@ -654,8 +1013,7 @@ wiz_detect(VOID_ARGS)
     if (wizard)
         (void) findit();
     else
-        pline("Unavailable command '%s'.",
-              visctrl((int) cmd_from_func(wiz_detect)));
+        pline(unavailcmd, visctrl((int) cmd_from_func(wiz_detect)));
     return 0;
 }
 
@@ -666,18 +1024,7 @@ wiz_level_tele(VOID_ARGS)
     if (wizard)
         level_tele();
     else
-        pline("Unavailable command '%s'.",
-              visctrl((int) cmd_from_func(wiz_level_tele)));
-    return 0;
-}
-
-/* #monpolycontrol command - choose new form for shapechangers, polymorphees */
-STATIC_PTR int
-wiz_mon_polycontrol(VOID_ARGS)
-{
-    iflags.mon_polycontrol = !iflags.mon_polycontrol;
-    pline("Monster polymorph control is %s.",
-          iflags.mon_polycontrol ? "on" : "off");
+        pline(unavailcmd, visctrl((int) cmd_from_func(wiz_level_tele)));
     return 0;
 }
 
@@ -685,11 +1032,14 @@ wiz_mon_polycontrol(VOID_ARGS)
 STATIC_PTR int
 wiz_level_change(VOID_ARGS)
 {
-    char buf[BUFSZ];
-    int newlevel;
+    char buf[BUFSZ] = DUMMY;
+    int newlevel = 0;
     int ret;
 
+/*JP
     getlin("To what experience level do you want to be set?", buf);
+*/
+    getlin("\8co\8c±\83\8c\83x\83\8b\82ð\82¢\82­\82Â\82É\90Ý\92è\82µ\82Ü\82·\82©\81H", buf);
     (void) mungspaces(buf);
     if (buf[0] == '\033' || buf[0] == '\0')
         ret = 0;
@@ -701,19 +1051,31 @@ wiz_level_change(VOID_ARGS)
         return 0;
     }
     if (newlevel == u.ulevel) {
+/*JP
         You("are already that experienced.");
+*/
+        You("\82·\82Å\82É\82»\82Ì\8co\8c±\83\8c\83x\83\8b\82¾\81D");
     } else if (newlevel < u.ulevel) {
         if (u.ulevel == 1) {
+/*JP
             You("are already as inexperienced as you can get.");
+*/
+            You("\82·\82Å\82É\89Â\94\\82È\8cÀ\82è\82Ì\8dÅ\92á\82Ì\8co\8c±\83\8c\83x\83\8b\82¾\81D");
             return 0;
         }
         if (newlevel < 1)
             newlevel = 1;
         while (u.ulevel > newlevel)
+/*JP
             losexp("#levelchange");
+*/
+            losexp("#levelchange\83R\83}\83\93\83h\82Å");
     } else {
         if (u.ulevel >= MAXULEV) {
+/*JP
             You("are already as experienced as you can get.");
+*/
+            You("\82·\82Å\82É\89Â\94\\82È\8cÀ\82è\82Ì\8dÅ\91å\82Ì\8co\8c±\83\8c\83x\83\8b\82¾\81D");
             return 0;
         }
         if (newlevel > MAXULEV)
@@ -729,7 +1091,15 @@ wiz_level_change(VOID_ARGS)
 STATIC_PTR int
 wiz_panic(VOID_ARGS)
 {
+    if (iflags.debug_fuzzer) {
+        u.uhp = u.uhpmax = 1000;
+        u.uen = u.uenmax = 1000;
+        return 0;
+    }
+/*JP
     if (yn("Do you want to call panic() and end your game?") == 'y')
+*/
+    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')
         panic("Crash test.");
     return 0;
 }
@@ -832,7 +1202,7 @@ wiz_show_wmodes(VOID_ARGS)
     int x, y;
     char row[COLNO + 1];
     struct rm *lev;
-    boolean istty = !strcmp(windowprocs.name, "tty");
+    boolean istty = WINDOWPORT("tty");
 
     win = create_nhwindow(NHW_TEXT);
     if (istty)
@@ -879,7 +1249,7 @@ wiz_map_levltyp(VOID_ARGS)
         for (x = 1; x < COLNO; x++) {
             terrain = levl[x][y].typ;
             /* assumes there aren't more than 10+26+26 terrain types */
-            row[x - 1] = (char) ((terrain == 0 && !may_dig(x, y))
+            row[x - 1] = (char) ((terrain == STONE && !may_dig(x, y))
                                     ? '*'
                                     : (terrain < 10)
                                        ? '0' + terrain
@@ -887,7 +1257,8 @@ wiz_map_levltyp(VOID_ARGS)
                                           ? 'a' + terrain - 10
                                           : 'A' + terrain - 36);
         }
-        if (levl[0][y].typ != 0 || may_dig(0, y))
+        x--;
+        if (levl[0][y].typ != STONE || may_dig(0, y))
             row[x++] = '!';
         row[x] = '\0';
         putstr(win, 0, row);
@@ -1102,6 +1473,134 @@ wiz_smell(VOID_ARGS)
     return 0;
 }
 
+/* #wizinstrinsic command to set some intrinsics for testing */
+STATIC_PTR int
+wiz_intrinsic(VOID_ARGS)
+{
+    if (wizard) {
+        extern const struct propname {
+            int prop_num;
+            const char *prop_name;
+        } propertynames[]; /* timeout.c */
+        static const char wizintrinsic[] = "#wizintrinsic";
+        static const char fmt[] = "You are%s %s.";
+        winid win;
+        anything any;
+        char buf[BUFSZ];
+        int i, j, n, p, amt, typ;
+        long oldtimeout, newtimeout;
+        const char *propname;
+        menu_item *pick_list = (menu_item *) 0;
+
+        any = zeroany;
+        win = create_nhwindow(NHW_MENU);
+        start_menu(win);
+        for (i = 0; (propname = propertynames[i].prop_name) != 0; ++i) {
+            p = propertynames[i].prop_num;
+            if (p == HALLUC_RES) {
+                /* Grayswandir vs hallucination; ought to be redone to
+                   use u.uprops[HALLUC].blocked instead of being treated
+                   as a separate property; letting in be manually toggled
+                   even only in wizard mode would be asking for trouble... */
+                continue;
+            }
+            if (p == FIRE_RES) {
+                any.a_int = 0;
+                add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, "--", FALSE);
+            }
+            any.a_int = i + 1; /* +1: avoid 0 */
+            oldtimeout = u.uprops[p].intrinsic & TIMEOUT;
+            if (oldtimeout)
+                Sprintf(buf, "%-27s [%li]", propname, oldtimeout);
+            else
+                Sprintf(buf, "%s", propname);
+            add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
+        }
+        end_menu(win, "Which intrinsics?");
+        n = select_menu(win, PICK_ANY, &pick_list);
+        destroy_nhwindow(win);
+
+        amt = 30; /* TODO: prompt for duration */
+        for (j = 0; j < n; ++j) {
+            i = pick_list[j].item.a_int - 1; /* -1: reverse +1 above */
+            p = propertynames[i].prop_num;
+            oldtimeout = u.uprops[p].intrinsic & TIMEOUT;
+            newtimeout = oldtimeout + (long) amt;
+            switch (p) {
+            case SICK:
+            case SLIMED:
+            case STONED:
+                if (oldtimeout > 0L && newtimeout > oldtimeout)
+                    newtimeout = oldtimeout;
+                break;
+            }
+
+            switch (p) {
+            case BLINDED:
+                make_blinded(newtimeout, TRUE);
+                break;
+#if 0       /* make_confused() only gives feedback when confusion is
+             * ending so use the 'default' case for it instead */
+            case CONFUSION:
+                make_confused(newtimeout, TRUE);
+                break;
+#endif /*0*/
+            case DEAF:
+                make_deaf(newtimeout, TRUE);
+                break;
+            case HALLUC:
+                make_hallucinated(newtimeout, TRUE, 0L);
+                break;
+            case SICK:
+                typ = !rn2(2) ? SICK_VOMITABLE : SICK_NONVOMITABLE;
+                make_sick(newtimeout, wizintrinsic, TRUE, typ);
+                break;
+            case SLIMED:
+                Sprintf(buf, fmt,
+                        !Slimed ? "" : " still", "turning into slime");
+                make_slimed(newtimeout, buf);
+                break;
+            case STONED:
+                Sprintf(buf, fmt,
+                        !Stoned ? "" : " still", "turning into stone");
+                make_stoned(newtimeout, buf, KILLED_BY, wizintrinsic);
+                break;
+            case STUNNED:
+                make_stunned(newtimeout, TRUE);
+                break;
+            case VOMITING:
+                Sprintf(buf, fmt, !Vomiting ? "" : " still", "vomiting");
+                make_vomiting(newtimeout, FALSE);
+                pline1(buf);
+                break;
+            case WARN_OF_MON:
+                if (!Warn_of_mon) {
+                    context.warntype.speciesidx = PM_GRID_BUG;
+                    context.warntype.species
+                                         = &mons[context.warntype.speciesidx];
+                }
+                goto def_feedback;
+            case LEVITATION:
+            case FLYING:
+                float_vs_flight();
+                /*FALLTHRU*/
+            default:
+            def_feedback:
+                pline("Timeout for %s %s %d.", propertynames[i].prop_name,
+                      oldtimeout ? "increased by" : "set to", amt);
+                incr_itimeout(&u.uprops[p].intrinsic, amt);
+                break;
+            }
+            context.botl = 1; /* probably not necessary... */
+        }
+        if (n >= 1)
+            free((genericptr_t) pick_list);
+        doredraw();
+    } else
+        pline(unavailcmd, visctrl((int) cmd_from_func(wiz_intrinsic)));
+    return 0;
+}
+
 /* #wizrumorcheck command - verify each rumor access */
 STATIC_PTR int
 wiz_rumor_check(VOID_ARGS)
@@ -1131,23 +1630,36 @@ doterrain(VOID_ARGS)
      *  a legend for the levl[][].typ codes dump
      */
     men = create_nhwindow(NHW_MENU);
+    start_menu(men);
     any = zeroany;
     any.a_int = 1;
     add_menu(men, NO_GLYPH, &any, 0, 0, ATR_NONE,
+/*JP
              "known map without monsters, objects, and traps",
+*/
+             "\89ö\95¨\81C\95¨\81Cã©\82È\82µ\82Ì\92n\90}",
              MENU_SELECTED);
     any.a_int = 2;
     add_menu(men, NO_GLYPH, &any, 0, 0, ATR_NONE,
+/*JP
              "known map without monsters and objects",
+*/
+             "\89ö\95¨\81C\95¨\82È\82µ\82Ì\92n\90}",
              MENU_UNSELECTED);
     any.a_int = 3;
     add_menu(men, NO_GLYPH, &any, 0, 0, ATR_NONE,
+/*JP
              "known map without monsters",
+*/
+             "\89ö\95¨\82È\82µ\82Ì\92n\90}",
              MENU_UNSELECTED);
     if (discover || wizard) {
         any.a_int = 4;
         add_menu(men, NO_GLYPH, &any, 0, 0, ATR_NONE,
+/*JP
                  "full map without monsters, objects, and traps",
+*/
+                 "\89ö\95¨\81C\95¨\81Cã©\82È\82µ\82Ì\8a®\91S\82È\92n\90}",
                  MENU_UNSELECTED);
         if (wizard) {
             any.a_int = 5;
@@ -1160,7 +1672,10 @@ doterrain(VOID_ARGS)
                      MENU_UNSELECTED);
         }
     }
+/*JP
     end_menu(men, "View which?");
+*/
+    end_menu(men, "\82Ç\82ê\82ð\8c©\82é\81H");
 
     n = select_menu(men, PICK_ONE, &sel);
     destroy_nhwindow(men);
@@ -1177,35 +1692,93 @@ doterrain(VOID_ARGS)
         free((genericptr_t) sel);
 
     switch (which) {
-    case 1: reveal_terrain(0, 0);   break; /* known map */
-    case 2: reveal_terrain(0, 1);   break; /* known map with traps */
-    case 3: reveal_terrain(0, 1|2); break; /* known map w/ traps & objs */
-    case 4: reveal_terrain(1, 0);   break; /* full map */
-    case 5: wiz_map_levltyp();      break; /* map internals */
-    case 6: wiz_levltyp_legend();   break; /* internal details */
-    default: break;
+    case 1: /* known map */
+        reveal_terrain(0, TER_MAP);
+        break;
+    case 2: /* known map with known traps */
+        reveal_terrain(0, TER_MAP | TER_TRP);
+        break;
+    case 3: /* known map with known traps and objects */
+        reveal_terrain(0, TER_MAP | TER_TRP | TER_OBJ);
+        break;
+    case 4: /* full map */
+        reveal_terrain(1, TER_MAP);
+        break;
+    case 5: /* map internals */
+        wiz_map_levltyp();
+        break;
+    case 6: /* internal details */
+        wiz_levltyp_legend();
+        break;
+    default:
+        break;
     }
     return 0; /* no time elapses */
 }
 
 /* -enlightenment and conduct- */
 static winid en_win = WIN_ERR;
+static boolean en_via_menu = FALSE;
+#if 0 /*JP*/
 static const char You_[] = "You ", are[] = "are ", were[] = "were ",
                   have[] = "have ", had[] = "had ", can[] = "can ",
                   could[] = "could ";
+#else
+static const char You_[] = "\82 \82È\82½\82Í", 
+                  are[]  = "\82Å\82 \82é",       were[]  = "\82Å\82 \82Á\82½",
+                  have[] = "\82ð\82à\82Á\82Ä\82¢\82é", had[]   = "\82ð\82à\82Á\82Ä\82¢\82½",
+                  can[]  = "\82Å\82«\82é",       could[] = "\82Å\82«\82½",
+                  iru[]  = "\82¢\82é",         ita[]   = "\82¢\82½";
+#endif
+#if 0 /*JP*//* not used */
 static const char have_been[] = "have been ", have_never[] = "have never ",
                   never[] = "never ";
+#endif
 
+#if 0 /*JP*/
 #define enl_msg(prefix, present, past, suffix, ps) \
     enlght_line(prefix, final ? past : present, suffix, ps)
+#else
+#define enl_msg(prefix, present, past, suffix, ps) \
+    enlght_line(prefix, ps, suffix, final ? past : present)
+#endif
 #define you_are(attr, ps) enl_msg(You_, are, were, attr, ps)
 #define you_have(attr, ps) enl_msg(You_, have, had, attr, ps)
 #define you_can(attr, ps) enl_msg(You_, can, could, attr, ps)
+/*JP
 #define you_have_been(goodthing) enl_msg(You_, have_been, were, goodthing, "")
+*/
+#define you_have_been(goodthing) enl_msg(You_, are, were, goodthing, "")
+#if 0 /*JP*/
 #define you_have_never(badthing) \
     enl_msg(You_, have_never, never, badthing, "")
+#else
+#define you_have_never(badthing) \
+    enl_msg(badthing, "\82Ä\82¢\82È\82¢", "\82È\82©\82Á\82½", "", "")
+#endif
+#if 0 /*JP*/
 #define you_have_X(something) \
     enl_msg(You_, have, (const char *) "", something, "")
+#else
+#define you_have_X(something) \
+    enl_msg(something, "\82Ä\82¢\82é", "\82½", "", "")
+#endif
+#if 1 /*JP*/
+#define you_are_ing(goodthing, ps) enl_msg(You_, iru, ita, goodthing, ps)
+#endif
+
+static void
+enlght_out(buf)
+const char *buf;
+{
+    if (en_via_menu) {
+        anything any;
+
+        any = zeroany;
+        add_menu(en_win, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
+    } else
+        putstr(en_win, 0, buf);
+}
 
 static void
 enlght_line(start, middle, end, ps)
@@ -1213,8 +1786,11 @@ const char *start, *middle, *end, *ps;
 {
     char buf[BUFSZ];
 
+/*JP
     Sprintf(buf, " %s%s%s%s.", start, middle, end, ps);
-    putstr(en_win, 0, buf);
+*/
+    Sprintf(buf, "%s%s%s%s\81D", start, middle, end, ps);
+    enlght_out(buf);
 }
 
 /* format increased chance to hit or damage or defense (Protection) */
@@ -1225,32 +1801,61 @@ int incamt, final;
 char *outbuf;
 {
     const char *modif, *bonus;
+#if 0 /*JP*/
     boolean invrt;
+#endif
     int absamt;
 
     absamt = abs(incamt);
     /* Protection amount is typically larger than damage or to-hit;
        reduce magnitude by a third in order to stretch modifier ranges
        (small:1..5, moderate:6..10, large:11..19, huge:20+) */
+#if 0 /*JP*/
     if (!strcmp(inctyp, "defense"))
+#else
+    if (!strcmp(inctyp, "\96h\8cä"))
+#endif
         absamt = (absamt * 2) / 3;
 
     if (absamt <= 3)
+/*JP
         modif = "small";
+*/
+        modif = "\8bÍ\82©\82È";
     else if (absamt <= 6)
+/*JP
         modif = "moderate";
+*/
+        modif = "\92\86\92ö\93x\82Ì";
     else if (absamt <= 12)
+/*JP
         modif = "large";
+*/
+        modif = "\91å\82«\82È";
     else
+/*JP
         modif = "huge";
+*/
+        modif = "\8b­\91å\82È";
 
+#if 0 /*JP*/
     modif = !incamt ? "no" : an(modif); /* ("no" case shouldn't happen) */
+#endif
+/*JP
     bonus = (incamt >= 0) ? "bonus" : "penalty";
+*/
+    bonus = (incamt > 0) ? "\83{\81[\83i\83X" : "\83y\83i\83\8b\83e\83B";
     /* "bonus <foo>" (to hit) vs "<bar> bonus" (damage, defense) */
+#if 0 /*JP*/
     invrt = strcmp(inctyp, "to hit") ? TRUE : FALSE;
+#endif
 
+#if 0 /*JP*/
     Sprintf(outbuf, "%s %s %s", modif, invrt ? inctyp : bonus,
             invrt ? bonus : inctyp);
+#else
+    Sprintf(outbuf, "%s\82É%s%s", inctyp, modif, bonus);
+#endif
     if (final || wizard)
         Sprintf(eos(outbuf), " (%s%d)", (incamt > 0) ? "+" : "", incamt);
 
@@ -1268,18 +1873,33 @@ int final;
 
     switch (category) {
     case HALF_PHDAM:
+/*JP
         category_name = "physical";
+*/
+        category_name = "\95¨\97\9d";
         break;
     case HALF_SPDAM:
+/*JP
         category_name = "spell";
+*/
+        category_name = "\8eô\95¶";
         break;
     default:
+/*JP
         category_name = "unknown";
+*/
+        category_name = "\95s\96¾";
         break;
     }
+#if 0 /*JP*/
     Sprintf(buf, " %s %s damage", (final || wizard) ? "half" : "reduced",
             category_name);
     enl_msg(You_, "take", "took", buf, from_what(category));
+#else
+    Sprintf(buf, " %s\83_\83\81\81[\83W\82ð%s", (final || wizard) ? "\94¼\8c¸" : "\8c¸\8f­",
+            category_name);
+    enl_msg(You_, "\82µ\82Ä\82¢\82é", "\82µ\82Ä\82¢\82½", buf, from_what(category));
+#endif
 }
 
 /* is hero actively using water walking capability on water (or lava)? */
@@ -1336,22 +1956,36 @@ int final; /* ENL_GAMEINPROGRESS:0, ENL_GAMEOVERALIVE, ENL_GAMEOVERDEAD */
 {
     char buf[BUFSZ], tmpbuf[BUFSZ];
 
+    en_win = create_nhwindow(NHW_MENU);
+    en_via_menu = !final;
+    if (en_via_menu)
+        start_menu(en_win);
+
     Strcpy(tmpbuf, plname);
     *tmpbuf = highc(*tmpbuf); /* same adjustment as bottom line */
     /* as in background_enlightenment, when poly'd we need to use the saved
        gender in u.mfemale rather than the current you-as-monster gender */
+#if 0 /*JP*/
     Sprintf(buf, "%s the %s's attributes:", tmpbuf,
             ((Upolyd ? u.mfemale : flags.female) && urole.name.f)
                 ? urole.name.f
                 : urole.name.m);
+#else
+    Sprintf(buf, "%s\82Ì%s\82Ì\91®\90«:",
+            ((Upolyd ? u.mfemale : flags.female) && urole.name.f)
+                ? urole.name.f
+                : urole.name.m,
+             tmpbuf);
+#endif
 
-    en_win = create_nhwindow(NHW_MENU);
     /* title */
-    putstr(en_win, 0, buf); /* "Conan the Archeologist's attributes:" */
+    enlght_out(buf); /* "Conan the Archeologist's attributes:" */
     /* background and characteristics; ^X or end-of-game disclosure */
     if (mode & BASICENLIGHTENMENT) {
-        /* role, race, alignment, deities */
+        /* role, race, alignment, deities, dungeon level, time, experience */
         background_enlightenment(mode, final);
+        /* hit points, energy points, armor class, gold */
+        basics_enlightenment(mode, final);
         /* strength, dexterity, &c */
         characteristics_enlightenment(mode, final);
     }
@@ -1367,7 +2001,17 @@ int final; /* ENL_GAMEINPROGRESS:0, ENL_GAMEOVERALIVE, ENL_GAMEOVERDEAD */
         /* intrinsics and other traditional enlightenment feedback */
         attributes_enlightenment(mode, final);
     }
-    display_nhwindow(en_win, TRUE);
+
+    if (!en_via_menu) {
+        display_nhwindow(en_win, TRUE);
+    } else {
+        menu_item *selected = 0;
+
+        end_menu(en_win, (char *) 0);
+        if (select_menu(en_win, PICK_NONE, &selected) > 0)
+            free((genericptr_t) selected);
+        en_via_menu = FALSE;
+    }
     destroy_nhwindow(en_win);
     en_win = WIN_ERR;
 }
@@ -1389,8 +2033,11 @@ int final;
     role_titl = (innategend && urole.name.f) ? urole.name.f : urole.name.m;
     rank_titl = rank_of(u.ulevel, Role_switch, innategend);
 
-    putstr(en_win, 0, ""); /* separator after title */
-    putstr(en_win, 0, "Background:");
+    enlght_out(""); /* separator after title */
+/*JP
+    enlght_out("Background:");
+*/
+    enlght_out("\94w\8ci\8fî\95ñ:");
 
     /* if polymorphed, report current shape before underlying role;
        will be repeated as first status: "you are transformed" and also
@@ -1404,10 +2051,21 @@ int final;
         tmpbuf[0] = '\0';
         /* here we always use current gender, not saved role gender */
         if (!is_male(uasmon) && !is_female(uasmon) && !is_neuter(uasmon))
+/*JP
             Sprintf(tmpbuf, "%s ", genders[flags.female ? 1 : 0].adj);
+*/
+            Sprintf(tmpbuf, "%s\82Ì", genders[flags.female ? 1 : 0].adj);
+#if 0 /*JP*/
         Sprintf(buf, "%sin %s%s form", !final ? "currently " : "", tmpbuf,
                 uasmon->mname);
+#else
+        Sprintf(buf, "%s%s%s\82Ì\8ep", !final ? "\8d¡\82Ì\82Æ\82±\82ë" : "", tmpbuf,
+                uasmon->mname);
+#endif
+/*JP
         you_are(buf, "");
+*/
+        you_are_ing(buf, "");
     }
 
     /* report role; omit gender if it's redundant (eg, "female priestess") */
@@ -1415,50 +2073,116 @@ int final;
     if (!urole.name.f
         && ((urole.allow & ROLE_GENDMASK) == (ROLE_MALE | ROLE_FEMALE)
             || innategend != flags.initgend))
+/*JP
         Sprintf(tmpbuf, "%s ", genders[innategend].adj);
+*/
+        Sprintf(tmpbuf, "%s", genders[innategend].adj);
     buf[0] = '\0';
     if (Upolyd)
+#if 0 /*JP*/
         Strcpy(buf, "actually "); /* "You are actually a ..." */
+#else
+        Strcpy(buf, "\8eÀ\8dÛ\82É\82Í"); /* "\82 \82È\82½\82Í\8eÀ\8dÛ\82É\82Í..." */
+#endif
     if (!strcmpi(rank_titl, role_titl)) {
         /* omit role when rank title matches it */
+#if 0 /*JP*/
         Sprintf(eos(buf), "%s, level %d %s%s", an(rank_titl), u.ulevel,
                 tmpbuf, urace.noun);
+#else
+        Sprintf(eos(buf), "\83\8c\83x\83\8b%d\82Ì%s\82Ì%s%s", u.ulevel,
+                tmpbuf, urace.adj, role_titl);
+#endif
     } else {
+#if 0 /*JP*/
         Sprintf(eos(buf), "%s, a level %d %s%s %s", an(rank_titl), u.ulevel,
                 tmpbuf, urace.adj, role_titl);
+#else
+        Sprintf(eos(buf), "\83\8c\83x\83\8b%d\82Ì%s\82Ì%s%s\82Ì%s", u.ulevel,
+                tmpbuf, urace.adj, role_titl, rank_titl);
+#endif
     }
     you_are(buf, "");
 
-    /* report alignment (bypass you_are() in order to omit ending period) */
+    /* report alignment (bypass you_are() in order to omit ending period);
+       adverb is used to distinguish between temporary change (helm of opp.
+       alignment), permanent change (one-time conversion), and original */
+#if 0 /*JP*/
     Sprintf(buf, " %s%s%s, %son a mission for %s",
             You_, !final ? are : were,
             align_str(u.ualign.type),
             /* helm of opposite alignment (might hide conversion) */
-            (u.ualign.type != u.ualignbase[A_CURRENT]) ? "temporarily "
+            (u.ualign.type != u.ualignbase[A_CURRENT])
+               /* what's the past tense of "currently"? if we used "formerly"
+                  it would sound like a reference to the original alignment */
+               ? (!final ? "currently " : "temporarily ")
                /* permanent conversion */
-               : (u.ualign.type != u.ualignbase[A_ORIGINAL]) ? "now "
+               : (u.ualign.type != u.ualignbase[A_ORIGINAL])
+                  /* and what's the past tense of "now"? certainly not "then"
+                     in a context like this...; "belatedly" == weren't that
+                     way sooner (in other words, didn't start that way) */
+                  ? (!final ? "now " : "belatedly ")
                   /* atheist (ignored in very early game) */
-                  : (!u.uconduct.gnostic && moves > 1000L) ? "nominally "
+                  : (!u.uconduct.gnostic && moves > 1000L)
+                     ? "nominally "
                      /* lastly, normal case */
                      : "",
             u_gname());
-    putstr(en_win, 0, buf);
+#else
+    Sprintf(buf, "\82 \82È\82½\82Í%s\82Å, %s%s\82Ì\82½\82ß\82Ì\94C\96±\82ð\8ds\82Á\82Ä%s\81D",
+            align_str(u.ualign.type),
+            /* helm of opposite alignment (might hide conversion) */
+            (u.ualign.type != u.ualignbase[A_CURRENT]) ? "\88ê\8e\9e\93I\82É"
+               /* permanent conversion */
+               : (u.ualign.type != u.ualignbase[A_ORIGINAL]) ? "\8c»\8dÝ"
+                  /* atheist (ignored in very early game) */
+                  : (!u.uconduct.gnostic && moves > 1000L) ? "\96¼\8b`\8fã"
+                     /* lastly, normal case */
+                     : "",
+            u_gname(), !final ? iru : ita);
+#endif
+    enlght_out(buf);
     /* show the rest of this game's pantheon (finishes previous sentence)
        [appending "also Moloch" at the end would allow for straightforward
        trailing "and" on all three aligned entries but looks too verbose] */
+#if 0 /*JP*/
     Sprintf(buf, " who %s opposed by", !final ? "is" : "was");
+#else
+    Strcpy(buf, "\82 \82È\82½\82Í");
+#endif
     if (u.ualign.type != A_LAWFUL)
+#if 0 /*JP*/
         Sprintf(eos(buf), " %s (%s) and", align_gname(A_LAWFUL),
                 align_str(A_LAWFUL));
+#else
+        Sprintf(eos(buf), "%s(%s)\82¨\82æ\82Ñ", align_gname(A_LAWFUL),
+                align_str(A_LAWFUL));
+#endif
     if (u.ualign.type != A_NEUTRAL)
+#if 0 /*JP*/
         Sprintf(eos(buf), " %s (%s)%s", align_gname(A_NEUTRAL),
                 align_str(A_NEUTRAL),
                 (u.ualign.type != A_CHAOTIC) ? " and" : "");
+#else
+        Sprintf(eos(buf), "%s(%s)%s", align_gname(A_NEUTRAL),
+                align_str(A_NEUTRAL),
+                (u.ualign.type != A_CHAOTIC) ? "\82¨\82æ\82Ñ" : "");
+#endif
     if (u.ualign.type != A_CHAOTIC)
+#if 0 /*JP*/
         Sprintf(eos(buf), " %s (%s)", align_gname(A_CHAOTIC),
                 align_str(A_CHAOTIC));
+#else
+    if (u.ualign.type != A_CHAOTIC)
+        Sprintf(eos(buf), "%s(%s)", align_gname(A_CHAOTIC),
+                align_str(A_CHAOTIC));
+#endif
+#if 0 /*JP*/
     Strcat(buf, "."); /* terminate sentence */
-    putstr(en_win, 0, buf);
+#else
+    Sprintf(eos(buf), "\82Æ\91Î\97§\82µ\82Ä%s\81D", !final ? iru : ita);
+#endif
+    enlght_out(buf);
 
     /* show original alignment,gender,race,role if any have been changed;
        giving separate message for temporary alignment change bypasses need
@@ -1469,46 +2193,299 @@ int final;
                + ((u.ualignbase[A_CURRENT] != u.ualignbase[A_ORIGINAL])
                   ? 2 : 0));
     if (difalgn & 1) { /* have temporary alignment so report permanent one */
+/*JP
         Sprintf(buf, "actually %s", align_str(u.ualignbase[A_CURRENT]));
+*/
+        Sprintf(buf, "\8eÀ\8dÛ\82É\82Í%s", align_str(u.ualignbase[A_CURRENT]));
+#if 0 /*JP*/
         you_are(buf, "");
+#else
+        enl_msg(buf, "\82Ä\82¢\82é", "\82Ä\82¢\82½", "", "");
+#endif
         difalgn &= ~1; /* suppress helm from "started out <foo>" message */
     }
     if (difgend || difalgn) { /* sex change or perm align change or both */
+#if 0 /*JP:T*/
         Sprintf(buf, " You started out %s%s%s.",
                 difgend ? genders[flags.initgend].adj : "",
                 (difgend && difalgn) ? " and " : "",
                 difalgn ? align_str(u.ualignbase[A_ORIGINAL]) : "");
-        putstr(en_win, 0, buf);
+#else
+        Sprintf(buf, "\82 \82È\82½\82Í%s%s%s\82Å\8aJ\8en\82µ\82½\81D",
+                difgend ? genders[flags.initgend].adj : "",
+                (difgend && difalgn) ? "\82©\82Â" : "",
+                difalgn ? align_str(u.ualignbase[A_ORIGINAL]) : "");
+#endif
+        enlght_out(buf);
     }
-}
 
-/* characteristics: expanded version of bottom line strength, dexterity, &c */
-STATIC_OVL void
-characteristics_enlightenment(mode, final)
-int mode;
-int final;
-{
-    putstr(en_win, 0, ""); /* separator after background */
-    putstr(en_win, 0,
-           final ? "Final Characteristics:" : "Current Characteristics:");
+    /* 3.6.2: dungeon level, so that ^X really has all status info as
+       claimed by the comment below; this reveals more information than
+       the basic status display, but that's one of the purposes of ^X;
+       similar information is revealed by #overview; the "You died in
+       <location>" given by really_done() is more rudimentary than this */
+    *buf = *tmpbuf = '\0';
+    if (In_endgame(&u.uz)) {
+        int egdepth = observable_depth(&u.uz);
+
+        (void) endgamelevelname(tmpbuf, egdepth);
+        Sprintf(buf, "in the endgame, on the %s%s",
+                !strncmp(tmpbuf, "Plane", 5) ? "Elemental " : "", tmpbuf);
+    } else if (Is_knox(&u.uz)) {
+        /* this gives away the fact that the knox branch is only 1 level */
+/*JP
+        Sprintf(buf, "on the %s level", dungeons[u.uz.dnum].dname);
+*/
+        Sprintf(buf, "%s", dungeons[u.uz.dnum].dname);
+        /* TODO? maybe phrase it differently when actually inside the fort,
+           if we're able to determine that (not trivial) */
+    } else {
+        char dgnbuf[QBUFSZ];
 
-    /* bottom line order */
-    one_characteristic(mode, final, A_STR); /* strength */
-    one_characteristic(mode, final, A_DEX); /* dexterity */
-    one_characteristic(mode, final, A_CON); /* constitution */
-    one_characteristic(mode, final, A_INT); /* intelligence */
-    one_characteristic(mode, final, A_WIS); /* wisdom */
-    one_characteristic(mode, final, A_CHA); /* charisma */
-}
+        Strcpy(dgnbuf, dungeons[u.uz.dnum].dname);
+#if 0 /*JP*/
+        if (!strncmpi(dgnbuf, "The ", 4))
+            *dgnbuf = lowc(*dgnbuf);
+#endif
+#if 0 /*JP*/
+        Sprintf(tmpbuf, "level %d",
+                In_quest(&u.uz) ? dunlev(&u.uz) : depth(&u.uz));
+#else
+        if (In_quest(&u.uz)) {
+            Sprintf(tmpbuf, "\91æ%d\8aK\91w", dunlev(&u.uz));
+        } else {
+            Sprintf(tmpbuf, "\92n\89º%d\8aK", depth(&u.uz));
+        }
+#endif
+        /* TODO? maybe extend this bit to include various other automatic
+           annotations from the dungeon overview code */
+        if (Is_rogue_level(&u.uz))
+            Strcat(tmpbuf, ", a primitive area");
+        else if (Is_bigroom(&u.uz) && !Blind)
+            Strcat(tmpbuf, ", a very big room");
+#if 0 /*JP*/
+        Sprintf(buf, "in %s, on %s", dgnbuf, tmpbuf);
+#else
+        Sprintf(buf, "%s\82Ì%s", dgnbuf, tmpbuf);
+#endif
+    }
+    you_are(buf, "");
 
-/* display one attribute value for characteristics_enlightenment() */
-STATIC_OVL void
+    /* this is shown even if the 'time' option is off */
+    if (moves == 1L) {
+#if 0 /*JP*/
+        you_have("just started your adventure", "");
+#else
+        enlght_line(You_, "", "\96`\8c¯\82ð\8aJ\8en\82µ\82½\82Æ\82±\82ë\82¾", "");
+#endif
+    } else {
+        /* 'turns' grates on the nerves in this context... */
+/*JP
+    Sprintf(buf, "the dungeon %ld turn%s ago", moves, plur(moves));
+*/
+    Sprintf(buf, "%ld\83^\81[\83\93\91O\82É\96À\8b{\82É\93ü\82Á\82½", moves);
+        /* same phrasing for current and final: "entered" is unconditional */
+#if 0 /*JP*/
+        enlght_line(You_, "entered ", buf, "");
+#else
+        enlght_line(You_, "", buf, "");
+#endif
+    }
+    if (!Upolyd) {
+        /* flags.showexp does not matter */
+        /* experience level is already shown above */
+#if 0 /*JP*/
+        Sprintf(buf, "%-1ld experience point%s", u.uexp, plur(u.uexp));
+#else
+        Sprintf(buf, "\8co\8c±\92l%-1ld\83|\83C\83\93\83g", u.uexp);
+#endif
+        if (wizard) {
+            if (u.ulevel < 30) {
+                int ulvl = (int) u.ulevel;
+                long nxtlvl = newuexp(ulvl);
+                /* long oldlvl = (ulvl > 1) ? newuexp(ulvl - 1) : 0; */
+
+                Sprintf(eos(buf), ", %ld %s%sneeded to attain level %d",
+                        (nxtlvl - u.uexp), (u.uexp > 0) ? "more " : "",
+                        !final ? "" : "were ", (ulvl + 1));
+            }
+        }
+        you_have(buf, "");
+    }
+#ifdef SCORE_ON_BOTL
+    if (flags.showscore) {
+        /* describes what's shown on status line, which is an approximation;
+           only show it here if player has the 'showscore' option enabled */
+#if 0 /*JP*/
+        Sprintf(buf, "%ld%s", botl_score(),
+                !final ? "" : " before end-of-game adjustments");
+        enl_msg("Your score ", "is ", "was ", buf, "");
+#else
+        Sprintf(buf, "%s%ld", botl_score(),
+                !final ? "" : "\83Q\81[\83\80\8fI\97¹\8e\9e\82Ì\92²\90®\91O\82Í");
+        enl_msg("\82 \82È\82½\82Ì\83X\83R\83A\82Í", "\82Å\82 \82é", "\82Å\82 \82Á\82½", buf, "");
+#endif
+    }
+#endif
+}
+
+/* hit points, energy points, armor class -- essential information which
+   doesn't fit very well in other categories */
+/*ARGSUSED*/
+STATIC_OVL void
+basics_enlightenment(mode, final)
+int mode UNUSED;
+int final;
+{
+    static char Power[] = "energy points (spell power)";
+    char buf[BUFSZ];
+    int pw = u.uen, hp = (Upolyd ? u.mh : u.uhp),
+        pwmax = u.uenmax, hpmax = (Upolyd ? u.mhmax : u.uhpmax);
+
+    enlght_out(""); /* separator after background */
+/*JP
+    enlght_out("Basics:");
+*/
+    enlght_out("\8aî\96{:");
+
+    if (hp < 0)
+        hp = 0;
+    /* "1 out of 1" rather than "all" if max is only 1; should never happen */
+#if 0 /*JP*/
+    if (hp == hpmax && hpmax > 1)
+        Sprintf(buf, "all %d hit points", hpmax);
+    else
+        Sprintf(buf, "%d out of %d hit point%s", hp, hpmax, plur(hpmax));
+#else
+    Sprintf(buf, "%d\83q\83b\83g\83|\83C\83\93\83g(\8dÅ\91å:%d)", hp, hpmax);
+#endif
+    you_have(buf, "");
+
+    /* low max energy is feasible, so handle couple of extra special cases */
+#if 0 /*JP*/
+    if (pwmax == 0 || (pw == pwmax && pwmax == 2)) /* both: "all 2" is silly */
+        Sprintf(buf, "%s %s", !pwmax ? "no" : "both", Power);
+    else if (pw == pwmax && pwmax > 2)
+        Sprintf(buf, "all %d %s", pwmax, Power);
+    else
+        Sprintf(buf, "%d out of %d %s", pw, pwmax, Power);
+#else
+    Sprintf(buf, "%d\96\82\97Í\83|\83C\83\93\83g(\8dÅ\91å:%d)", pw, pwmax);
+#endif
+    you_have(buf, "");
+
+    if (Upolyd) {
+        switch (mons[u.umonnum].mlevel) {
+        case 0:
+            /* status line currently being explained shows "HD:0" */
+/*JP
+            Strcpy(buf, "0 hit dice (actually 1/2)");
+*/
+            Strcpy(buf, "HD0(\8eÀ\8dÛ\82É\82Í1/2)");
+            break;
+        case 1:
+/*JP
+            Strcpy(buf, "1 hit die");
+*/
+            Strcpy(buf, "HD1");
+            break;
+        default:
+/*JP
+            Sprintf(buf, "%d hit dice", mons[u.umonnum].mlevel);
+*/
+            Sprintf(buf, "HD%d", mons[u.umonnum].mlevel);
+            break;
+        }
+        you_have(buf, "");
+    }
+
+    Sprintf(buf, "%d", u.uac);
+/*JP
+    enl_msg("Your armor class ", "is ", "was ", buf, "");
+*/
+    enl_msg("\82 \82È\82½\82Ì\96h\8cä\92l\82Í", "\82Å\82 \82é", "\82Å\82 \82Á\82½", buf, "");
+
+    /* gold; similar to doprgold(#seegold) but without shop billing info;
+       same amount as shown on status line which ignores container contents */
+    {
+/*JP
+        static const char Your_wallet[] = "Your wallet ";
+*/
+        static const char Your_wallet[] = "\82 \82È\82½\82Ì\8dà\95z";
+        long umoney = money_cnt(invent);
+
+        if (!umoney) {
+/*JP
+            enl_msg(Your_wallet, "is ", "was ", "empty", "");
+*/
+            enl_msg(Your_wallet, "\82Å\82 \82é", "\82Å\82¾\82Á\82½", "\82Í\8bó", "");
+        } else {
+#if 0 /*JP:T*/
+            Sprintf(buf, "%ld %s", umoney, currency(umoney));
+            enl_msg(Your_wallet, "contains ", "contained ", buf, "");
+#else
+            Sprintf(buf, "\82É\82Í%ld%s", umoney, currency(umoney));
+            enl_msg(Your_wallet, "\93ü\82Á\82Ä\82¢\82é", "\93ü\82Á\82Ä\82¢\82½", buf, "");
+#endif
+        }
+    }
+
+    if (flags.pickup) {
+        char ocl[MAXOCLASSES + 1];
+
+        Strcpy(buf, "on");
+        oc_to_str(flags.pickup_types, ocl);
+        Sprintf(eos(buf), " for %s%s%s",
+                *ocl ? "'" : "", *ocl ? ocl : "all types", *ocl ? "'" : "");
+        if (flags.pickup_thrown && *ocl) /* *ocl: don't show if 'all types' */
+            Strcat(buf, " plus thrown");
+        if (iflags.autopickup_exceptions[AP_GRAB]
+            || iflags.autopickup_exceptions[AP_LEAVE])
+            Strcat(buf, ", with exceptions");
+    } else
+/*JP
+        Strcpy(buf, "off");
+*/
+        Strcpy(buf, "\83I\83t");
+/*JP
+    enl_msg("Autopickup ", "is ", "was ", buf, "");
+*/
+    enl_msg("\8e©\93®\8fE\82¢\90Ý\92è\82Í", "\82Å\82 \82é", "\82Å\82 \82Á\82½", buf, "");
+}
+
+/* characteristics: expanded version of bottom line strength, dexterity, &c */
+STATIC_OVL void
+characteristics_enlightenment(mode, final)
+int mode;
+int final;
+{
+    char buf[BUFSZ];
+
+    enlght_out("");
+/*JP
+    Sprintf(buf, "%s Characteristics:", !final ? "Current" : "Final");
+*/
+    Sprintf(buf, "%s\91®\90«\81F", !final ? "\8c»\8dÝ\82Ì" : "\8dÅ\8fI");
+    enlght_out(buf);
+
+    /* bottom line order */
+    one_characteristic(mode, final, A_STR); /* strength */
+    one_characteristic(mode, final, A_DEX); /* dexterity */
+    one_characteristic(mode, final, A_CON); /* constitution */
+    one_characteristic(mode, final, A_INT); /* intelligence */
+    one_characteristic(mode, final, A_WIS); /* wisdom */
+    one_characteristic(mode, final, A_CHA); /* charisma */
+}
+
+/* display one attribute value for characteristics_enlightenment() */
+STATIC_OVL void
 one_characteristic(mode, final, attrindx)
 int mode, final, attrindx;
 {
+    extern const char *const attrname[]; /* attrib.c */
     boolean hide_innate_value = FALSE, interesting_alimit;
     int acurrent, abase, apeak, alimit;
-    const char *attrname, *paren_pfx;
+    const char *paren_pfx;
     char subjbuf[BUFSZ], valubuf[BUFSZ], valstring[32];
 
     /* being polymorphed or wearing certain cursed items prevents
@@ -1526,28 +2503,24 @@ int mode, final, attrindx;
     }
     switch (attrindx) {
     case A_STR:
-        attrname = "strength";
         if (uarmg && uarmg->otyp == GAUNTLETS_OF_POWER && uarmg->cursed)
             hide_innate_value = TRUE;
         break;
     case A_DEX:
-        attrname = "dexterity";
         break;
     case A_CON:
-        attrname = "constitution";
+        if (uwep && uwep->oartifact == ART_OGRESMASHER && uwep->cursed)
+            hide_innate_value = TRUE;
         break;
     case A_INT:
-        attrname = "intelligence";
         if (uarmh && uarmh->otyp == DUNCE_CAP && uarmh->cursed)
             hide_innate_value = TRUE;
         break;
     case A_WIS:
-        attrname = "wisdom";
         if (uarmh && uarmh->otyp == DUNCE_CAP && uarmh->cursed)
             hide_innate_value = TRUE;
         break;
     case A_CHA:
-        attrname = "charisma";
         break;
     default:
         return; /* impossible */
@@ -1558,7 +2531,10 @@ int mode, final, attrindx;
 
     acurrent = ACURR(attrindx);
     (void) attrval(attrindx, acurrent, valubuf); /* Sprintf(valubuf,"%d",) */
-    Sprintf(subjbuf, "Your %s ", attrname);
+/*JP
+    Sprintf(subjbuf, "Your %s ", attrname[attrindx]);
+*/
+    Sprintf(subjbuf, "\82 \82È\82½\82Ì%s\82Í", attrname[attrindx]);
 
     if (!hide_innate_value) {
         /* show abase, amax, and/or attrmax if acurr doesn't match abase
@@ -1575,28 +2551,51 @@ int mode, final, attrindx;
         interesting_alimit =
             final ? TRUE /* was originally `(abase != alimit)' */
                   : (alimit != (attrindx != A_STR ? 18 : STR18(100)));
+/*JP
         paren_pfx = final ? " (" : " (current; ";
+*/
+        paren_pfx = final ? " (" : " (\8c»\8dÝ; ";
         if (acurrent != abase) {
+#if 0 /*JP*/
             Sprintf(eos(valubuf), "%sbase:%s", paren_pfx,
                     attrval(attrindx, abase, valstring));
+#else
+            Sprintf(eos(valubuf), "%s\8aî\96{:%s", paren_pfx,
+                    attrval(attrindx, abase, valstring));
+#endif
             paren_pfx = ", ";
         }
         if (abase != apeak) {
+#if 0 /*JP*/
             Sprintf(eos(valubuf), "%speak:%s", paren_pfx,
                     attrval(attrindx, apeak, valstring));
+#else
+            Sprintf(eos(valubuf), "%s\8dÅ\91å:%s", paren_pfx,
+                    attrval(attrindx, apeak, valstring));
+#endif
             paren_pfx = ", ";
         }
         if (interesting_alimit) {
+#if 0 /*JP*/
             Sprintf(eos(valubuf), "%s%slimit:%s", paren_pfx,
                     /* more verbose if exceeding 'limit' due to magic bonus */
                     (acurrent > alimit) ? "innate " : "",
                     attrval(attrindx, alimit, valstring));
+#else
+            Sprintf(eos(valubuf), "%s%s\8fã\8cÀ:%s", paren_pfx,
+                    /* more verbose if exceeding 'limit' due to magic bonus */
+                    (acurrent > alimit) ? "\96{\97\88\82Ì" : "",
+                    attrval(attrindx, alimit, valstring));
+#endif
             /* paren_pfx = ", "; */
         }
         if (acurrent != abase || abase != apeak || interesting_alimit)
             Strcat(valubuf, ")");
     }
+/*JP
     enl_msg(subjbuf, "is ", "was ", valubuf, "");
+*/
+    enl_msg(subjbuf, "\82¾", "\82¾\82Á\82½", valubuf, "");
 }
 
 /* status: selected obvious capabilities, assorted troubles */
@@ -1606,13 +2605,16 @@ int mode;
 int final;
 {
     boolean magic = (mode & MAGICENLIGHTENMENT) ? TRUE : FALSE;
-    int cap;
+    int cap, wtype;
     char buf[BUFSZ], youtoo[BUFSZ];
     boolean Riding = (u.usteed
                       /* if hero dies while dismounting, u.usteed will still
                          be set; we want to ignore steed in that situation */
                       && !(final == ENL_GAMEOVERDEAD
+/*JP
                            && !strcmp(killer.name, "riding accident")));
+*/
+                           && !strcmp(killer.name, "\8bR\8fæ\8e\96\8cÌ\82Å")));
     const char *steedname = (!Riding ? (char *) 0
                       : x_monnam(u.usteed,
                                  u.usteed->mtame ? ARTICLE_YOUR : ARTICLE_THE,
@@ -1624,84 +2626,169 @@ int final;
      * Status (many are abbreviated on bottom line; others are or
      *     should be discernible to the hero hence to the player)
     \*/
-    putstr(en_win, 0, ""); /* separator after title or characteristics */
-    putstr(en_win, 0, final ? "Final Status:" : "Current Status:");
+    enlght_out(""); /* separator after title or characteristics */
+/*JP
+    enlght_out(final ? "Final Status:" : "Current Status:");
+*/
+    enlght_out(final ? "\8dÅ\8fI\8fó\91Ô:" : "\8c»\8dÝ\82Ì\8fó\91Ô:");
 
     Strcpy(youtoo, You_);
     /* not a traditional status but inherently obvious to player; more
        detail given below (attributes section) for magic enlightenment */
-    if (Upolyd)
-        you_are("transformed", "");
+    if (Upolyd) {
+#if 0 /*JP*/
+        Strcpy(buf, "transformed");
+        if (ugenocided())
+            Sprintf(eos(buf), " and %s %s inside",
+                    final ? "felt" : "feel", udeadinside());
+        you_are(buf, "");
+#else /*JP:TODO:\95Ï\89»+\8bs\8eE\83p\83^\81[\83\93*/
+        you_are_ing("\95Ï\89»\82µ\82Ä", "");
+#endif
+    }
     /* not a trouble, but we want to display riding status before maybe
        reporting steed as trapped or hero stuck to cursed saddle */
     if (Riding) {
+#if 0 /*JP*/
         Sprintf(buf, "riding %s", steedname);
         you_are(buf, "");
+#else
+        Sprintf(buf, "%s\82É\8fæ\82Á\82Ä", steedname);
+        you_are_ing(buf, "");
+#endif
+/*JP
         Sprintf(eos(youtoo), "and %s ", steedname);
+*/
+        Sprintf(youtoo, "\82 \82È\82½\82Æ%s\82Í", steedname);
     }
     /* other movement situations that hero should always know */
     if (Levitation) {
         if (Lev_at_will && magic)
+/*JP
             you_are("levitating, at will", "");
+*/
+            you_are_ing("\8e©\95ª\82Ì\88Ó\8eu\82Å\95\82\97V\82µ\82Ä", "");
         else
+/*JP
             enl_msg(youtoo, are, were, "levitating", from_what(LEVITATION));
+*/
+            enl_msg(youtoo, "\82¢\82é", "\82¢\82½", "\95\82\97V\82µ\82Ä", from_what(LEVITATION));
     } else if (Flying) { /* can only fly when not levitating */
+/*JP
         enl_msg(youtoo, are, were, "flying", from_what(FLYING));
+*/
+        enl_msg(youtoo, "\82¢\82é", "\82¢\82½", "\94ò\82ñ\82Å", from_what(FLYING));
     }
     if (Underwater) {
+/*JP
         you_are("underwater", "");
+*/
+        enl_msg(You_, "\82¢\82é", "\82¢\82½", "\90\85\96Ê\89º\82É", "");
     } else if (u.uinwater) {
+/*JP
         you_are(Swimming ? "swimming" : "in water", from_what(SWIMMING));
+*/
+        enl_msg(You_, Swimming ? "\89j\82¢\82Å" : "\90\85\92\86\82É", "\82¢\82é", "\82¢\82½", from_what(SWIMMING));
     } else if (walking_on_water()) {
         /* show active Wwalking here, potential Wwalking elsewhere */
+#if 0 /*JP*/
         Sprintf(buf, "walking on %s",
                 is_pool(u.ux, u.uy) ? "water"
                 : is_lava(u.ux, u.uy) ? "lava"
                   : surface(u.ux, u.uy)); /* catchall; shouldn't happen */
         you_are(buf, from_what(WWALKING));
+#else
+        Sprintf(buf, "%s\82Ì\8fã\82ð\95à\82¢\82Ä",
+                is_pool(u.ux, u.uy) ? "\90\85"
+                : is_lava(u.ux, u.uy) ? "\97n\8aâ"
+                  : surface(u.ux, u.uy)); /* catchall; shouldn't happen */
+        you_are_ing(buf, from_what(WWALKING));
+#endif
     }
-    if (Upolyd && (u.uundetected || youmonst.m_ap_type != M_AP_NOTHING))
+    if (Upolyd && (u.uundetected || U_AP_TYPE != M_AP_NOTHING))
         youhiding(TRUE, final);
 
     /* internal troubles, mostly in the order that prayer ranks them */
     if (Stoned)
+/*JP
         you_are("turning to stone", "");
+*/
+        enl_msg("\82 \82È\82½\82Í", "\82È\82è\82Â\82Â\82 \82é", "\82È\82Á\82½", "\90Î\82É", "");
     if (Slimed)
+/*JP
         you_are("turning into slime", "");
+*/
+        enl_msg("\82 \82È\82½\82Í", "\82È\82è\82Â\82Â\82 \82é", "\82È\82Á\82½", "\83X\83\89\83C\83\80\82É", "");
     if (Strangled) {
         if (u.uburied) {
+/*JP
             you_are("buried", "");
+*/
+            you_are_ing("\92\82\91§\82µ\82Ä", "");
         } else {
+/*JP
             Strcpy(buf, "being strangled");
+*/
+            Strcpy(buf, "\8eñ\82ð\8di\82ß\82ç\82ê\82Ä");
             if (wizard)
                 Sprintf(eos(buf), " (%ld)", (Strangled & TIMEOUT));
+/*JP
             you_are(buf, from_what(STRANGLED));
+*/
+            enl_msg("\82 \82È\82½\82Í", "\82¢\82é", "\82¢\82½", buf, from_what(STRANGLED));
         }
     }
     if (Sick) {
         /* prayer lumps these together; botl puts Ill before FoodPois */
         if (u.usick_type & SICK_NONVOMITABLE)
+/*JP
             you_are("terminally sick from illness", "");
+*/
+            enl_msg("\82 \82È\82½\82Í\95a\8bC\82Å\92v\96½\93I\82É\8bC\95ª\82ª\88«", "\82¢", "\82©\82Á\82½", "", "");
         if (u.usick_type & SICK_VOMITABLE)
+/*JP
             you_are("terminally sick from food poisoning", "");
+*/
+            enl_msg("\82 \82È\82½\82Í\90H\92\86\93Å\82Å\92v\96½\93I\82É\8bC\95ª\82ª\88«", "\82¢", "\82©\82Á\82½", "", "");
     }
     if (Vomiting)
+/*JP
         you_are("nauseated", "");
+*/
+        enl_msg(You_, "\93f\82«\8bC\82ª", "\82 \82é", "\82 \82Á\82½", "");
     if (Stunned)
+/*JP
         you_are("stunned", "");
+*/
+        you_are("\82­\82ç\82­\82ç\8fó\91Ô", "");
     if (Confusion)
+/*JP
         you_are("confused", "");
+*/
+        you_are("\8d¬\97\90\8fó\91Ô", "");
     if (Hallucination)
+/*JP
         you_are("hallucinating", "");
+*/
+        you_are("\8c\8ao\8fó\91Ô", "");
     if (Blind) {
         /* from_what() (currently wizard-mode only) checks !haseyes()
            before u.uroleplay.blind, so we should too */
+#if 0 /*JP*/
         Sprintf(buf, "%s blind",
                 !haseyes(youmonst.data) ? "innately"
                 : u.uroleplay.blind ? "permanently"
                   /* better phrasing desperately wanted... */
                   : Blindfolded_only ? "deliberately"
                     : "temporarily");
+#else
+        Sprintf(buf, "%s\96Ó\96Ú",
+                !haseyes(youmonst.data) ? "\90\82Ü\82ê\82È\82ª\82ç\82É"
+                : u.uroleplay.blind ? "\8dP\8bv\93I\82É"
+                  /* better phrasing desperately wanted... */
+                  : Blindfolded_only ? "\8cÌ\88Ó\82É"
+                    : "\88ê\8e\9e\93I\82É");
+#endif
         if (wizard && (Blinded & TIMEOUT) != 0L
             && !u.uroleplay.blind && haseyes(youmonst.data))
             Sprintf(eos(buf), " (%ld)", (Blinded & TIMEOUT));
@@ -1709,15 +2796,24 @@ int final;
         you_are(buf, !haseyes(youmonst.data) ? "" : from_what(BLINDED));
     }
     if (Deaf)
+/*JP
         you_are("deaf", from_what(DEAF));
+*/
+        you_are("\8e¨\82ª\95·\82±\82¦\82È\82¢\8fó\91Ô", from_what(DEAF));
 
     /* external troubles, more or less */
     if (Punished) {
         if (uball) {
+/*JP
             Sprintf(buf, "chained to %s", ansimpleoname(uball));
+*/
+            Sprintf(buf, "%s\82É\82Â\82È\82ª\82ê\82Ä", ansimpleoname(uball));
         } else {
             impossible("Punished without uball?");
+/*JP
             Strcpy(buf, "punished");
+*/
+            Strcpy(buf, "\94±\82ð\8eó\82¯\82Ä");
         }
         you_are(buf, "");
     }
@@ -1727,41 +2823,76 @@ int final;
         boolean anchored = (u.utraptype == TT_BURIEDBALL);
 
         if (anchored) {
+/*JP
             Strcpy(predicament, "tethered to something buried");
+*/
+            Strcpy(predicament, "\89½\82©\96\84\82Ü\82Á\82Ä\82¢\82é\82à\82Ì\82É\82Â\82È\82ª\82ê\82Ä");
         } else if (u.utraptype == TT_INFLOOR || u.utraptype == TT_LAVA) {
+/*JP
             Sprintf(predicament, "stuck in %s", the(surface(u.ux, u.uy)));
+*/
+            Sprintf(predicament, "%s\82É\96\84\82Ü\82Á\82Ä", surface(u.ux, u.uy));
         } else {
+#if 0 /*JP*/
             Strcpy(predicament, "trapped");
             if ((t = t_at(u.ux, u.uy)) != 0)
                 Sprintf(eos(predicament), " in %s",
                         an(defsyms[trap_to_defsym(t->ttyp)].explanation));
+#else
+            predicament[0] = '\0';
+            if ((t = t_at(u.ux, u.uy)) != 0)
+                Sprintf(predicament, "%s\82É",
+                        defsyms[trap_to_defsym(t->ttyp)].explanation);
+            Strcat(predicament, "\82Ð\82Á\82©\82©\82Á\82Ä");
+#endif
         }
         if (u.usteed) { /* not `Riding' here */
+#if 0 /*JP*/
             Sprintf(buf, "%s%s ", anchored ? "you and " : "", steedname);
             *buf = highc(*buf);
             enl_msg(buf, (anchored ? "are " : "is "),
                     (anchored ? "were " : "was "), predicament, "");
+#else
+            Sprintf(buf, "%s%s\82Í", anchored ? "\82 \82È\82½\82Æ" : "", steedname);
+            enl_msg(buf, "\82¢\82é", "\82¢\82½" , predicament, "");
+#endif
         } else
             you_are(predicament, "");
     } /* (u.utrap) */
     if (u.uswallow) {
+/*JP
         Sprintf(buf, "swallowed by %s", a_monnam(u.ustuck));
+*/
+        Sprintf(buf, "%s\82É\88ù\82Ý\8d\9e\82Ü\82ê\82Ä", a_monnam(u.ustuck));
         if (wizard)
             Sprintf(eos(buf), " (%u)", u.uswldtim);
         you_are(buf, "");
     } else if (u.ustuck) {
+#if 0 /*JP*/
         Sprintf(buf, "%s %s",
                 (Upolyd && sticks(youmonst.data)) ? "holding" : "held by",
                 a_monnam(u.ustuck));
         you_are(buf, "");
+#else
+        Sprintf(buf, "%s%s",
+                a_monnam(u.ustuck),
+                (Upolyd && sticks(youmonst.data)) ? "\82ð\95ß\82Ü\82¦\82Ä" : "\82É\95ß\82Ü\82Á\82Ä");
+        you_are_ing(buf, "");
+#endif
     }
     if (Riding) {
         struct obj *saddle = which_armor(u.usteed, W_SADDLE);
 
         if (saddle && saddle->cursed) {
+#if 0 /*JP*/
             Sprintf(buf, "stuck to %s %s", s_suffix(steedname),
                     simpleonames(saddle));
             you_are(buf, "");
+#else
+            Sprintf(buf, "%s\82Ì%s\82É\82Â\82©\82Ü\82Á\82Ä", steedname,
+                    simpleonames(saddle));
+            you_are_ing(buf, "");
+#endif
         }
     }
     if (Wounded_legs) {
@@ -1769,49 +2900,79 @@ int final;
            hero; we only report steed's wounded legs in wizard mode */
         if (u.usteed) { /* not `Riding' here */
             if (wizard && steedname) {
+#if 0 /*JP*/
                 Strcpy(buf, steedname);
                 *buf = highc(*buf);
                 enl_msg(buf, " has", " had", " wounded legs", "");
+#else
+                enl_msg(buf, iru, ita, "\82Í\8e\88\82ð\89ö\89ä\82µ\82Ä", "");
+#endif
             }
         } else {
+#if 0 /*JP*/
             Sprintf(buf, "wounded %s", makeplural(body_part(LEG)));
             you_have(buf, "");
+#else
+            Sprintf(buf, "%s\82ð\89ö\89ä\82µ\82Ä", makeplural(body_part(LEG)));
+            you_are_ing(buf, "");
+#endif
         }
     }
     if (Glib) {
+#if 0 /*JP*/
         Sprintf(buf, "slippery %s", makeplural(body_part(FINGER)));
         you_have(buf, "");
+#else
+        Sprintf(buf, "%s\82ª\82Ê\82é\82Ê\82é\82µ\82Ä", body_part(FINGER));
+        enl_msg(buf, iru, ita, "", "");
+#endif
     }
     if (Fumbling) {
         if (magic || cause_known(FUMBLING))
+/*JP
             enl_msg(You_, "fumble", "fumbled", "", from_what(FUMBLING));
+*/
+            you_are_ing("\95s\8aí\97p\82É\82È\82Á\82Ä", from_what(FUMBLING));
     }
     if (Sleepy) {
         if (magic || cause_known(SLEEPY)) {
             Strcpy(buf, from_what(SLEEPY));
             if (wizard)
                 Sprintf(eos(buf), " (%ld)", (HSleepy & TIMEOUT));
+/*JP
             enl_msg("You ", "fall", "fell", " asleep uncontrollably", buf);
+*/
+            you_are_ing("\96°\82Á\82Ä", buf);
         }
     }
     /* hunger/nutrition */
     if (Hunger) {
         if (magic || cause_known(HUNGER))
+#if 0 /*JP*/
             enl_msg(You_, "hunger", "hungered", " rapidly",
                     from_what(HUNGER));
+#else
+            enl_msg("\82 \82È\82½\82Í\82·\82®\82É\95 \82ª\8c¸\82é\8fó\91Ô", "\82Å\82 \82é", "\82¾\82Á\82½", "", "");
+#endif
     }
     Strcpy(buf, hu_stat[u.uhs]); /* hunger status; omitted if "normal" */
     mungspaces(buf);             /* strip trailing spaces */
     if (*buf) {
+#if 0 /*JP*/
         *buf = lowc(*buf); /* override capitalization */
         if (!strcmp(buf, "weak"))
             Strcat(buf, " from severe hunger");
         else if (!strncmp(buf, "faint", 5)) /* fainting, fainted */
             Strcat(buf, " due to starvation");
         you_are(buf, "");
+#else
+        Strcat(buf, "\8fó\91Ô");
+        you_are(buf, "");
+#endif
     }
     /* encumbrance */
     if ((cap = near_capacity()) > UNENCUMBERED) {
+#if 0 /*JP*/
         const char *adj = "?_?"; /* (should always get overridden) */
 
         Strcpy(buf, enc_stat[cap]);
@@ -1836,14 +2997,23 @@ int final;
         Sprintf(eos(buf), "; movement %s %s%s", !final ? "is" : "was", adj,
                 (cap < OVERLOADED) ? " slowed" : "");
         you_are(buf, "");
+#else
+        Sprintf(buf, "\89×\95¨\82É\82æ\82Á\82Ä%s\8fó\91Ô", enc_stat[cap]);
+        you_are(buf, "");
+#endif
     } else {
         /* last resort entry, guarantees Status section is non-empty
            (no longer needed for that purpose since weapon status added;
            still useful though) */
+/*JP
         you_are("unencumbered", "");
+*/
+        you_are("\89×\95¨\82Í\8e×\96\82\82É\82È\82ç\82È\82¢\8fó\91Ô", "");
     }
+
     /* report being weaponless; distinguish whether gloves are worn */
     if (!uwep) {
+#if 0 /*JP*/
         you_are(uarmg ? "empty handed" /* gloves imply hands */
                       : humanoid(youmonst.data)
                          /* hands but no weapon and no gloves */
@@ -1851,15 +3021,23 @@ int final;
                          /* alternate phrasing for paws or lack of hands */
                          : "not wielding anything",
                 "");
-    /* two-weaponing implies a weapon (not other odd stuff) in each hand */
+#else
+        enl_msg(You_, "\82¢", "\82©\82Á\82½", "\95\90\8aí\82ð\91\95\94õ\82µ\82Ä\82¢\82È", "");
+#endif
+    /* two-weaponing implies hands (can't be polymorphed) and
+       a weapon or wep-tool (not other odd stuff) in each hand */
     } else if (u.twoweap) {
+/*JP
         you_are("wielding two weapons at once", "");
+*/
+        you_are("\93ñ\93\81\97¬", "");
     /* report most weapons by their skill class (so a katana will be
        described as a long sword, for instance; mattock and hook are
        exceptions), or wielded non-weapon item by its object class */
     } else {
         const char *what = weapon_descr(uwep);
 
+#if 0 /*JP*/
         if (!strcmpi(what, "armor") || !strcmpi(what, "food")
             || !strcmpi(what, "venom"))
             Sprintf(buf, "wielding some %s", what);
@@ -1867,13 +3045,56 @@ int final;
             Sprintf(buf, "wielding %s",
                     (uwep->quan == 1L) ? an(what) : makeplural(what));
         you_are(buf, "");
+#else
+        Sprintf(buf, "%s\82ð\91\95\94õ\82µ\82Ä", what);
+        enl_msg(You_, "\82¢\82é", "\82¢\82½", buf, "");
+#endif
+    }
+    /*
+     * Skill with current weapon.  Might help players who've never
+     * noticed #enhance or decided that it was pointless.
+     *
+     * TODO?  Maybe merge wielding line and skill line into one sentence.
+     */
+    if ((wtype = uwep_skill_type()) != P_NONE) {
+        char sklvlbuf[20];
+        int sklvl = P_SKILL(wtype);
+        boolean hav = (sklvl != P_UNSKILLED && sklvl != P_SKILLED);
+
+        if (sklvl == P_ISRESTRICTED)
+            Strcpy(sklvlbuf, "no");
+        else
+            (void) lcase(skill_level_name(wtype, sklvlbuf));
+        /* "you have no/basic/expert/master/grand-master skill with <skill>"
+           or "you are unskilled/skilled in <skill>" */
+#if 0 /*JP*/
+        Sprintf(buf, "%s %s %s", sklvlbuf,
+                hav ? "skill with" : "in", skill_name(wtype));
+#else
+        Sprintf(buf, "%s\82Ì%s\83X\83L\83\8b", skill_name(wtype), sklvlbuf);
+#endif
+        if (can_advance(wtype, FALSE))
+            Sprintf(eos(buf), " and %s that",
+                    !final ? "can enhance" : "could have enhanced");
+        if (hav)
+            you_have(buf, "");
+        else
+            you_are(buf, "");
     }
     /* report 'nudity' */
-    if (!uarm && !uarmu && !uarmc && !uarmg && !uarmf && !uarmh) {
+    if (!uarm && !uarmu && !uarmc && !uarms && !uarmg && !uarmf && !uarmh) {
         if (u.uroleplay.nudist)
+#if 0 /*JP*/
             enl_msg(You_, "do", "did", " not wear any armor", "");
+#else
+            enl_msg(You_, "\82¢", "\82©\82Á\82½", "\89½\82Ì\8aZ\82à\91\95\94õ\82µ\82È", "");
+#endif
         else
+#if 0 /*JP*/
             you_are("not wearing any armor", "");
+#else
+            enl_msg(You_, "\82¢", "\82©\82Á\82½", "\89½\82Ì\8aZ\82à\91\95\94õ\82µ\82Ä\82¢\82È", "");
+#endif
     }
 }
 
@@ -1883,103 +3104,173 @@ attributes_enlightenment(unused_mode, final)
 int unused_mode UNUSED;
 int final;
 {
+#if 0 /*JP*/
     static NEARDATA const char if_surroundings_permitted[] =
         " if surroundings permitted";
+#endif
     int ltmp, armpro;
     char buf[BUFSZ];
 
     /*\
      *  Attributes
     \*/
-    putstr(en_win, 0, "");
-    putstr(en_win, 0, final ? "Final Attributes:" : "Current Attributes:");
+    enlght_out("");
+/*JP
+    enlght_out(final ? "Final Attributes:" : "Current Attributes:");
+*/
+    enlght_out(final ? "\8dÅ\8fI\91®\90«:" : "\8c»\8dÝ\82Ì\91®\90«:");
 
     if (u.uevent.uhand_of_elbereth) {
+#if 0 /*JP*/
         static const char *const hofe_titles[3] = { "the Hand of Elbereth",
                                                     "the Envoy of Balance",
                                                     "the Glory of Arioch" };
+#else
+        static const char *const hofe_titles[3] = { "\83G\83\8b\83x\83\8c\83X\82Ì\8cä\8eè",
+                                                    "\92²\98a\82Ì\8eg\8eÒ",
+                                                    "\83A\83\8a\83I\83b\83`\82Ì\96¼\97_" };
+#endif
         you_are(hofe_titles[u.uevent.uhand_of_elbereth - 1], "");
     }
 
-    /* note: piousness 20 matches MIN_QUEST_ALIGN (quest.h) */
-    if (u.ualign.record >= 20)
-        you_are("piously aligned", "");
-    else if (u.ualign.record > 13)
-        you_are("devoutly aligned", "");
-    else if (u.ualign.record > 8)
-        you_are("fervently aligned", "");
-    else if (u.ualign.record > 3)
-        you_are("stridently aligned", "");
-    else if (u.ualign.record == 3)
-        you_are("aligned", "");
-    else if (u.ualign.record > 0)
-        you_are("haltingly aligned", "");
-    else if (u.ualign.record == 0)
-        you_are("nominally aligned", "");
-    else if (u.ualign.record >= -3)
-        you_have("strayed", "");
-    else if (u.ualign.record >= -8)
-        you_have("sinned", "");
+/*JP
+    Sprintf(buf, "%s", piousness(TRUE, "aligned"));
+*/
+    Sprintf(buf, "%s", piousness(TRUE, "\90M\8bÂ\90S"));
+    if (u.ualign.record >= 0)
+        you_are(buf, "");
     else
-        you_have("transgressed", "");
+        you_have(buf, "");
+
     if (wizard) {
+#if 0 /*JP*/
         Sprintf(buf, " %d", u.ualign.record);
         enl_msg("Your alignment ", "is", "was", buf, "");
+#else
+        Sprintf(buf, "\82 \82È\82½\82Ì\91®\90«\92l\82Í%d", u.ualign.record);
+        enl_msg(buf, "\82Å\82 \82é", "\82¾\82Á\82½", "", "");
+#endif
     }
 
     /*** Resistances to troubles ***/
     if (Invulnerable)
+/*JP
         you_are("invulnerable", from_what(INVULNERABLE));
+*/
+        you_are("\95s\8e\80\90g", from_what(INVULNERABLE));
     if (Antimagic)
+/*JP
         you_are("magic-protected", from_what(ANTIMAGIC));
+*/
+        you_have("\96\82\96@\96h\8cä\94\\97Í", from_what(ANTIMAGIC));
     if (Fire_resistance)
+/*JP
         you_are("fire resistant", from_what(FIRE_RES));
+*/
+        you_have("\89Î\82Ö\82Ì\91Ï\90«", from_what(FIRE_RES));
     if (Cold_resistance)
+/*JP
         you_are("cold resistant", from_what(COLD_RES));
+*/
+        you_have("\8a¦\82³\82Ö\82Ì\91Ï\90«", from_what(COLD_RES));
     if (Sleep_resistance)
+/*JP
         you_are("sleep resistant", from_what(SLEEP_RES));
+*/
+        you_have("\96°\82è\82Ö\82Ì\91Ï\90«", from_what(SLEEP_RES));
     if (Disint_resistance)
+/*JP
         you_are("disintegration-resistant", from_what(DISINT_RES));
+*/
+        you_have("\95²\8dÓ\82Ö\82Ì\91Ï\90«", from_what(DISINT_RES));
     if (Shock_resistance)
+/*JP
         you_are("shock resistant", from_what(SHOCK_RES));
+*/
+        you_have("\93d\8c\82\82Ö\82Ì\91Ï\90«", from_what(SHOCK_RES));
     if (Poison_resistance)
+/*JP
         you_are("poison resistant", from_what(POISON_RES));
+*/
+        you_have("\93Å\82Ö\82Ì\91Ï\90«", from_what(POISON_RES));
     if (Acid_resistance)
+/*JP
         you_are("acid resistant", from_what(ACID_RES));
+*/
+        you_have("\8e_\82Ö\82Ì\91Ï\90«", from_what(ACID_RES));
     if (Drain_resistance)
+/*JP
         you_are("level-drain resistant", from_what(DRAIN_RES));
+*/
+        you_have("\83\8c\83x\83\8b\83_\83E\83\93\82Ö\82Ì\91Ï\90«", from_what(DRAIN_RES));
     if (Sick_resistance)
+/*JP
         you_are("immune to sickness", from_what(SICK_RES));
+*/
+        you_have("\95a\8bC\82É\91Î\82·\82é\96Æ\89u", from_what(SICK_RES));
     if (Stone_resistance)
+/*JP
         you_are("petrification resistant", from_what(STONE_RES));
+*/
+        you_have("\90Î\89»\82Ö\82Ì\91Ï\90«", from_what(STONE_RES));
     if (Halluc_resistance)
+#if 0 /*JP*/
         enl_msg(You_, "resist", "resisted", " hallucinations",
                 from_what(HALLUC_RES));
+#else
+        you_have("\8c\8ao\82Ö\82Ì\91Ï\90«", from_what(HALLUC_RES));
+#endif
     if (u.uedibility)
+/*JP
         you_can("recognize detrimental food", "");
+*/
+        you_can("\97L\8aQ\82È\90H\97¿\82ð\8e¯\95Ê", "");
 
     /*** Vision and senses ***/
     if (!Blind && (Blinded || !haseyes(youmonst.data)))
         you_can("see", from_what(-BLINDED)); /* Eyes of the Overworld */
     if (See_invisible) {
         if (!Blind)
+/*JP
             enl_msg(You_, "see", "saw", " invisible", from_what(SEE_INVIS));
+*/
+            enl_msg("\82 \82È\82½\82Í\93§\96¾\82È\82à\82Ì\82ð\8c©\82ç\82ê", "\82é", "\82½", "", from_what(SEE_INVIS));
         else
+#if 0 /*JP*/
             enl_msg(You_, "will see", "would have seen",
                     " invisible when not blind", from_what(SEE_INVIS));
+#else
+            enl_msg(You_, "\82é", "\82½",
+                    "\96Ó\96Ú\82Å\82È\82¢\82Æ\82«\82É\82Í\93§\96¾\82È\82à\82Ì\82ð\8c©\82ç\82ê", from_what(SEE_INVIS));
+#endif
     }
     if (Blind_telepat)
+/*JP
         you_are("telepathic", from_what(TELEPAT));
+*/
+        you_have("\83e\83\8c\83p\83V\81[", from_what(TELEPAT));
     if (Warning)
+/*JP
         you_are("warned", from_what(WARNING));
+*/
+        you_have("\8cx\89ú\94\\97Í", from_what(WARNING));
     if (Warn_of_mon && context.warntype.obj) {
+#if 0 /*JP*/
         Sprintf(buf, "aware of the presence of %s",
                 (context.warntype.obj & M2_ORC) ? "orcs"
                 : (context.warntype.obj & M2_ELF) ? "elves"
                 : (context.warntype.obj & M2_DEMON) ? "demons" : something);
         you_are(buf, from_what(WARN_OF_MON));
+#else
+        Sprintf(buf, "%s\82Ì\91\8dÝ\82ð\8a´\82\82é\94\\97Í",
+                (context.warntype.obj & M2_ORC) ? "\83I\81[\83N"
+                : (context.warntype.obj & M2_ELF) ? "\83G\83\8b\83t"
+                : (context.warntype.obj & M2_DEMON) ? "\88«\96\82" : something);
+        you_have(buf, "");
+#endif
     }
     if (Warn_of_mon && context.warntype.polyd) {
+#if 0 /*JP*/
         Sprintf(buf, "aware of the presence of %s",
                 ((context.warntype.polyd & (M2_HUMAN | M2_ELF))
                  == (M2_HUMAN | M2_ELF))
@@ -1994,31 +3285,79 @@ int final;
                                             ? "demons"
                                             : "certain monsters");
         you_are(buf, "");
+#else
+        Sprintf(buf, "%s\82Ì\91\8dÝ\82ð\8a´\82\82é\94\\97Í",
+                ((context.warntype.polyd & (M2_HUMAN | M2_ELF))
+                 == (M2_HUMAN | M2_ELF))
+                    ? "\90l\8aÔ\82Æ\83G\83\8b\83t"
+                    : (context.warntype.polyd & M2_HUMAN)
+                          ? "\90l\8aÔ"
+                          : (context.warntype.polyd & M2_ELF)
+                                ? "\83G\83\8b\83t"
+                                : (context.warntype.polyd & M2_ORC)
+                                      ? "\83I\81[\83N"
+                                      : (context.warntype.polyd & M2_DEMON)
+                                            ? "\88«\96\82"
+                                            : "\82 \82é\8eí\82Ì\89ö\95¨");
+        you_have(buf, "");
+#endif
     }
-    if (Warn_of_mon && context.warntype.speciesidx) {
+    if (Warn_of_mon && context.warntype.speciesidx >= LOW_PM) {
+#if 0 /*JP*/
         Sprintf(buf, "aware of the presence of %s",
                 makeplural(mons[context.warntype.speciesidx].mname));
         you_are(buf, from_what(WARN_OF_MON));
+#else
+        Sprintf(buf, "%s\82Ì\91\8dÝ\82ð\8a´\82\82é\94\\97Í",
+                mons[context.warntype.speciesidx].mname);
+        you_have(buf, from_what(WARN_OF_MON));
+#endif
     }
     if (Undead_warning)
+/*JP
         you_are("warned of undead", from_what(WARN_UNDEAD));
+*/
+        you_have("\95s\8e\80\82Ì\90\95¨\82Ö\82Ì\8cx\89ú\94\\97Í", from_what(WARN_UNDEAD));
     if (Searching)
+/*JP
         you_have("automatic searching", from_what(SEARCHING));
+*/
+        you_have("\92T\8d¸\94\\97Í", from_what(SEARCHING));
     if (Clairvoyant)
+/*JP
         you_are("clairvoyant", from_what(CLAIRVOYANT));
+*/
+        you_have("\90ç\97¢\8aá\94\\97Í", from_what(CLAIRVOYANT));
     else if ((HClairvoyant || EClairvoyant) && BClairvoyant) {
         Strcpy(buf, from_what(-CLAIRVOYANT));
+#if 0 /*JP*/
         if (!strncmp(buf, " because of ", 12))
             /* overwrite substring; strncpy doesn't add terminator */
             (void) strncpy(buf, " if not for ", 12);
         enl_msg(You_, "could be", "could have been", " clairvoyant", buf);
+#else
+        /*JP:\81u\81c\82É\82æ\82Á\82Ä\81v*/
+        if (!strncmp(buf, "\82É\82æ\82Á\82Ä", 8))
+            /*JP:\81u\81c\82ª\82È\82¯\82ê\82Î\81v\82É\8f\91\82«\8a·\82¦\82é*/
+            strcpy(eos(buf) - 8, "\82ª\82È\82¯\82ê\82Î");
+        you_have("\90ç\97¢\8aá\94\\97Í", buf);
+#endif
     }
     if (Infravision)
+/*JP
         you_have("infravision", from_what(INFRAVISION));
+*/
+        you_have("\90Ô\8aO\90ü\82ª\8c©\82¦\82é\8e\8b\8ao", from_what(INFRAVISION));
     if (Detect_monsters)
+/*JP
         you_are("sensing the presence of monsters", "");
+*/
+        you_have("\89ö\95¨\82ð\92T\82·\94\\97Í", "");
     if (u.umconf)
+/*JP
         you_are("going to confuse monsters", "");
+*/
+        you_have("\89ö\95¨\82ð\8d¬\97\90\82³\82¹\82é\94\\97Í", "");
 
     /*** Appearance and behavior ***/
     if (Adornment) {
@@ -2031,43 +3370,94 @@ int final;
         /* the sum might be 0 (+0 ring or two which negate each other);
            that yields "you are charismatic" (which isn't pointless
            because it potentially impacts seduction attacks) */
+#if 0 /*JP*/
         Sprintf(buf, "%scharismatic",
                 (adorn > 0) ? "more " : (adorn < 0) ? "less " : "");
         you_are(buf, from_what(ADORNED));
+#else
+        Sprintf(buf, "\96£\97Í%s\82Ä",
+                (adorn > 0) ? "\82ª\91\9d\89Á\82µ" : (adorn < 0) ? "\82ª\8c¸\8f­\82µ" : "\93I\82É\82È\82Á");
+        enl_msg(You_, "\82Ä\82¢\82é", "\82½", buf, "");
+#endif
     }
     if (Invisible)
+/*JP
         you_are("invisible", from_what(INVIS));
+*/
+        you_are("\93§\96¾", from_what(INVIS));
     else if (Invis)
+/*JP
         you_are("invisible to others", from_what(INVIS));
+*/
+        you_are("\91¼\90l\82É\91Î\82µ\82Ä\93§\96¾", from_what(INVIS));
     /* ordinarily "visible" is redundant; this is a special case for
        the situation when invisibility would be an expected attribute */
     else if ((HInvis || EInvis) && BInvis)
+/*JP
         you_are("visible", from_what(-INVIS));
+*/
+        you_are("\95s\93§\96¾", from_what(-INVIS));
     if (Displaced)
+/*JP
         you_are("displaced", from_what(DISPLACED));
+*/
+        you_have("\8c\89e\94\\97Í", from_what(DISPLACED));
     if (Stealth)
+/*JP
         you_are("stealthy", from_what(STEALTH));
+*/
+        you_have("\90l\96Ú\82ð\93\90\82Þ\94\\97Í", from_what(STEALTH));
     if (Aggravate_monster)
+#if 0 /*JP*/
         enl_msg("You aggravate", "", "d", " monsters",
                 from_what(AGGRAVATE_MONSTER));
+#else
+        you_are_ing("\94½\8a´\82ð\82©\82Á\82Ä", from_what(AGGRAVATE_MONSTER));
+#endif
     if (Conflict)
+/*JP
         enl_msg("You cause", "", "d", " conflict", from_what(CONFLICT));
+*/
+        you_are_ing("\93¬\91\88\82ð\88ø\82«\8bN\82±\82µ\82Ä", from_what(CONFLICT));
 
     /*** Transportation ***/
     if (Jumping)
+/*JP
         you_can("jump", from_what(JUMPING));
+*/
+        you_can("\92µ\96ô\82·\82é\82±\82Æ\82ª", from_what(JUMPING));
     if (Teleportation)
+/*JP
         you_can("teleport", from_what(TELEPORT));
+*/
+        you_can("\8fu\8aÔ\88Ú\93®\82ª", from_what(TELEPORT));
     if (Teleport_control)
+/*JP
         you_have("teleport control", from_what(TELEPORT_CONTROL));
+*/
+        you_have("\8fu\8aÔ\88Ú\93®\82Ì\90§\8cä\94\\97Í", from_what(TELEPORT_CONTROL));
     /* actively levitating handled earlier as a status condition */
     if (BLevitation) { /* levitation is blocked */
         long save_BLev = BLevitation;
 
         BLevitation = 0L;
-        if (Levitation)
-            enl_msg(You_, "would levitate", "would have levitated",
-                    if_surroundings_permitted, "");
+        if (Levitation) {
+            /* either trapped in the floor or inside solid rock
+               (or both if chained to buried iron ball and have
+               moved one step into solid rock somehow) */
+#if 0 /*JP*/
+            boolean trapped = (save_BLev & I_SPECIAL) != 0L,
+                    terrain = (save_BLev & FROMOUTSIDE) != 0L;
+
+            Sprintf(buf, "%s%s%s",
+                    trapped ? " if not trapped" : "",
+                    (trapped && terrain) ? " and" : "",
+                    terrain ? if_surroundings_permitted : "");
+            enl_msg(You_, "would levitate", "would have levitated", buf, "");
+#else
+            you_are("\8fó\8bµ\82ª\8b\96\82¹\82Î\95\82\97V\82·\82é\8fó\91Ô", "");
+#endif
+        }
         BLevitation = save_BLev;
     }
     /* actively flying handled earlier as a status condition */
@@ -2075,39 +3465,100 @@ int final;
         long save_BFly = BFlying;
 
         BFlying = 0L;
-        if (Flying)
+        if (Flying) {
+#if 0 /*JP*/
             enl_msg(You_, "would fly", "would have flown",
+                    /* wording quibble: for past tense, "hadn't been"
+                       would sound better than "weren't" (and
+                       "had permitted" better than "permitted"), but
+                       "weren't" and "permitted" are adequate so the
+                       extra complexity to handle that isn't worth it */
+                    Levitation
+                       ? " if you weren't levitating"
+                       : (save_BFly == I_SPECIAL)
+                          /* this is an oversimpliction; being trapped
+                             might also be blocking levitation so flight
+                             would still be blocked after escaping trap */
+                          ? " if you weren't trapped"
+                          : (save_BFly == FROMOUTSIDE)
+                             ? if_surroundings_permitted
+                             /* two or more of levitation, surroundings,
+                                and being trapped in the floor */
+                             : " if circumstances permitted",
+                    "");
+#else
+            enl_msg(You_, "\94ò\82Ô\82±\82Æ\82ª\82Å\82«\82é", "\94ò\82Ô\82±\82Æ\82ª\82Å\82«\82½",
+                    /* wording quibble: for past tense, "hadn't been"
+                       would sound better than "weren't" (and
+                       "had permitted" better than "permitted"), but
+                       "weren't" and "permitted" are adequate so the
+                       extra complexity to handle that isn't worth it */
                     Levitation
-                       ? "if you weren't levitating"
-                       : (save_BFly == FROMOUTSIDE)
-                          ? if_surroundings_permitted
-                          /* both surroundings and [latent] levitation */
-                          : " if circumstances permitted",
+                       ? "\95\82\97V\82µ\82Ä\82¢\82È\82¯\82ê\82Î"
+                       : (save_BFly == I_SPECIAL)
+                          /* this is an oversimpliction; being trapped
+                             might also be blocking levitation so flight
+                             would still be blocked after escaping trap */
+                          ? "\95ß\82Ü\82Á\82Ä\82¢\82È\82¯\82ê\82Î"
+                          : (save_BFly == FROMOUTSIDE)
+                             ? "\8fó\8bµ\82ª\8b\96\82¹\82Î"
+                             /* two or more of levitation, surroundings,
+                                and being trapped in the floor */
+                             : "\8e\96\8fî\82ª\8b\96\82¹\82Î",
                     "");
+#endif
+        }
         BFlying = save_BFly;
     }
     /* actively walking on water handled earlier as a status condition */
     if (Wwalking && !walking_on_water())
+/*JP
         you_can("walk on water", from_what(WWALKING));
+*/
+        you_can("\90\85\82Ì\8fã\82ð\95à\82­\82±\82Æ\82ª", from_what(WWALKING));
     /* actively swimming (in water but not under it) handled earlier */
     if (Swimming && (Underwater || !u.uinwater))
+/*JP
         you_can("swim", from_what(SWIMMING));
+*/
+        you_can("\89j\82®\82±\82Æ\82ª", from_what(SWIMMING));
     if (Breathless)
+/*JP
         you_can("survive without air", from_what(MAGICAL_BREATHING));
+*/
+        you_can("\8bó\8bC\82È\82µ\82Å\90\82«\89\84\82Ñ\82é\82±\82Æ\82ª", from_what(MAGICAL_BREATHING));
     else if (Amphibious)
+/*JP
         you_can("breathe water", from_what(MAGICAL_BREATHING));
+*/
+        you_can("\90\85\92\86\82Å\8cÄ\8bz\82ª", from_what(MAGICAL_BREATHING));
     if (Passes_walls)
+/*JP
         you_can("walk through walls", from_what(PASSES_WALLS));
+*/
+        you_can("\95Ç\82ð\92Ê\82è\94²\82¯\82é\82±\82Æ\82ª", from_what(PASSES_WALLS));
 
     /*** Physical attributes ***/
     if (Regeneration)
+/*JP
         enl_msg("You regenerate", "", "d", "", from_what(REGENERATION));
+*/
+        you_have("\8dÄ\90\94\\97Í", from_what(REGENERATION));
     if (Slow_digestion)
+/*JP
         you_have("slower digestion", from_what(SLOW_DIGESTION));
+*/
+        enl_msg("\90H\95¨\82Ì\8fÁ\89»\82ª\92x", "\82¢", "\82©\82Á\82½", "", from_what(SLOW_DIGESTION));
     if (u.uhitinc)
+/*JP
         you_have(enlght_combatinc("to hit", u.uhitinc, final, buf), "");
+*/
+        you_have(enlght_combatinc("\96½\92\86\97¦", u.uhitinc, final, buf), "");
     if (u.udaminc)
+/*JP
         you_have(enlght_combatinc("damage", u.udaminc, final, buf), "");
+*/
+        you_have(enlght_combatinc("\83_\83\81\81[\83W", u.udaminc, final, buf), "");
     if (u.uspellprot || Protection) {
         int prot = 0;
 
@@ -2119,17 +3570,27 @@ int final;
             prot += u.ublessed;
         prot += u.uspellprot;
         if (prot)
+/*JP
             you_have(enlght_combatinc("defense", prot, final, buf), "");
+*/
+            you_have(enlght_combatinc("\96h\8cä", prot, final, buf), "");
     }
     if ((armpro = magic_negation(&youmonst)) > 0) {
         /* magic cancellation factor, conferred by worn armor */
         static const char *const mc_types[] = {
+#if 0 /*JP*/
             "" /*ordinary*/, "warded", "guarded", "protected",
+#else
+            "" /*ordinary*/, "\89q\82ç\82ê\82Ä", "\8cì\82ç\82ê\82Ä", "\8eç\82ç\82ê\82Ä",
+#endif
         };
         /* sanity check */
         if (armpro >= SIZE(mc_types))
             armpro = SIZE(mc_types) - 1;
+/*JP
         you_are(mc_types[armpro], "");
+*/
+        you_are_ing(mc_types[armpro], "");
     }
     if (Half_physical_damage)
         enlght_halfdmg(HALF_PHDAM, final);
@@ -2137,40 +3598,76 @@ int final;
         enlght_halfdmg(HALF_SPDAM, final);
     /* polymorph and other shape change */
     if (Protection_from_shape_changers)
+#if 0 /*JP*/
         you_are("protected from shape changers",
                 from_what(PROT_FROM_SHAPE_CHANGERS));
+#else
+        you_have("\95Ï\89»\89ö\95¨\82Ö\82Ì\91Ï\90«", from_what(PROT_FROM_SHAPE_CHANGERS));
+#endif
     if (Unchanging) {
         const char *what = 0;
 
         if (!Upolyd) /* Upolyd handled below after current form */
+/*JP
             you_can("not change from your current form",
+*/
+            you_are("\8c»\8dÝ\82Ì\8ep\82©\82ç\95Ï\89»\82Å\82«\82È\82¢\8fó\91Ô",
                     from_what(UNCHANGING));
         /* blocked shape changes */
         if (Polymorph)
+/*JP
             what = !final ? "polymorph" : "have polymorphed";
+*/
+            what = "\95Ï\89»\82µ\82Ä";
         else if (u.ulycn >= LOW_PM)
+/*JP
             what = !final ? "change shape" : "have changed shape";
+*/
+            what = "\8ep\82ð\95Ï\82¦\82Ä";
         if (what) {
+#if 0 /*JP*/
             Sprintf(buf, "would %s periodically", what);
             /* omit from_what(UNCHANGING); too verbose */
             enl_msg(You_, buf, buf, " if not locked into your current form",
                     "");
+#else
+            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);
+            you_are_ing(buf, "");
+#endif
         }
     } else if (Polymorph) {
+/*JP
         you_are("polymorphing periodically", from_what(POLYMORPH));
+*/
+        you_are("\92è\8aú\93I\82É\95Ï\89»\82µ\82Ä", from_what(POLYMORPH));
     }
     if (Polymorph_control)
+/*JP
         you_have("polymorph control", from_what(POLYMORPH_CONTROL));
-    if (Upolyd && u.umonnum != u.ulycn) {
+*/
+        you_have("\95Ï\89»\82Ì\90§\8cä\94\\97Í", from_what(POLYMORPH_CONTROL));
+    if (Upolyd && u.umonnum != u.ulycn
+        /* if we've died from turning into slime, we're polymorphed
+           right now but don't want to list it as a temporary attribute
+           [we need a more reliable way to detect this situation] */
+        && !(final == ENL_GAMEOVERDEAD
+             && u.umonnum == PM_GREEN_SLIME && !Unchanging)) {
         /* foreign shape (except were-form which is handled below) */
+/*JP
         Sprintf(buf, "polymorphed into %s", an(youmonst.data->mname));
+*/
+        Sprintf(buf, "%s\82É\95Ï\89»\82µ\82Ä", youmonst.data->mname);
         if (wizard)
             Sprintf(eos(buf), " (%d)", u.mtimedone);
         you_are(buf, "");
     }
     if (lays_eggs(youmonst.data) && flags.female) /* Upolyd */
+/*JP
         you_can("lay eggs", "");
+*/
+        you_can("\97\91\82ð\8eY\82Þ\82±\82Æ\82ª", "");
     if (u.ulycn >= LOW_PM) {
+#if 0 /*JP*/
         /* "you are a werecreature [in beast form]" */
         Strcpy(buf, an(mons[u.ulycn].mname));
         if (u.umonnum == u.ulycn) {
@@ -2178,53 +3675,114 @@ int final;
             if (wizard)
                 Sprintf(eos(buf), " (%d)", u.mtimedone);
         }
+#else
+        /*JP:\81u\82 \82È\82½\82Í[\8fb\82Ì\8ep\82Ì]\81\9b\81\9b\90l\8aÔ\82Å\82 \82é\81v*/
+        buf[0] = '\0';
+        if (u.umonnum == u.ulycn) {
+            Strcpy(buf, "\8fb\82Ì\8ep\82Ì");
+            if (wizard)
+                Sprintf(eos(buf), " (%d)", u.mtimedone);
+        }
+        Strcat(buf, mons[u.ulycn].mname);
+#endif
         you_are(buf, "");
     }
     if (Unchanging && Upolyd) /* !Upolyd handled above */
+/*JP
         you_can("not change from your current form", from_what(UNCHANGING));
+*/
+        enl_msg("\8d¡\82Ì\8ep\82©\82ç\95Ï\89»\82·\82é\82±\82Æ\82ª\82Å\82«\82È", "\82¢", "\82©\82Á\82½", "", from_what(UNCHANGING));
     if (Hate_silver)
+/*JP
         you_are("harmed by silver", "");
+*/
+        enl_msg("\82 \82È\82½\82Í\8bâ\82É\8eã", "\82¢", "\82©\82Á\82½", "", "");
     /* movement and non-armor-based protection */
     if (Fast)
+/*JP
         you_are(Very_fast ? "very fast" : "fast", from_what(FAST));
+*/
+        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));
     if (Reflecting)
+/*JP
         you_have("reflection", from_what(REFLECTING));
+*/
+        you_have("\94½\8eË\94\\97Í", from_what(REFLECTING));
     if (Free_action)
+/*JP
         you_have("free action", from_what(FREE_ACTION));
+*/
+        you_have("\8dS\91©\82³\82ê\82È\82¢\94\\97Í", from_what(FREE_ACTION));
     if (Fixed_abil)
+/*JP
         you_have("fixed abilities", from_what(FIXED_ABIL));
+*/
+        enl_msg("\94\\97Í\82ª\95Ï\89»\82µ\82È", "\82¢", "\82©\82Á\82½", "", from_what(FIXED_ABIL));
     if (Lifesaved)
+/*JP
         enl_msg("Your life ", "will be", "would have been", " saved", "");
+*/
+        enl_msg("\82 \82È\82½\82Ì\90\96½\82Í\95Û\91\82³\82ê\82Ä", iru, ita, "", "");
 
     /*** Miscellany ***/
     if (Luck) {
         ltmp = abs((int) Luck);
+#if 0 /*JP*/
         Sprintf(buf, "%s%slucky",
                 ltmp >= 10 ? "extremely " : ltmp >= 5 ? "very " : "",
                 Luck < 0 ? "un" : "");
+#else
+        Sprintf(buf, "%s%s",
+                ltmp >= 10 ? "\96Ò\97ó\82É" : ltmp >= 5 ? "\82Æ\82Ä\82à" : "",
+                Luck < 0 ? "\95s\8dK" : "\8dK\95\9f");
+#endif
         if (wizard)
             Sprintf(eos(buf), " (%d)", Luck);
         you_are(buf, "");
     } else if (wizard)
+/*JP
         enl_msg("Your luck ", "is", "was", " zero", "");
+*/
+        enl_msg("\82 \82È\82½\82Ì\89^\82Í\83[\83\8d", "\82Å\82 \82é", "\82¾\82Á\82½", "", "");
     if (u.moreluck > 0)
+/*JP
         you_have("extra luck", "");
+*/
+        you_have("\82³\82ç\82È\82é\8dK\89^", "");
     else if (u.moreluck < 0)
+/*JP
         you_have("reduced luck", "");
+*/
+        you_have("\82³\82ç\82È\82é\95s\89^", "");
     if (carrying(LUCKSTONE) || stone_luck(TRUE)) {
-        ltmp = stone_luck(0);
+        ltmp = stone_luck(FALSE);
         if (ltmp <= 0)
+/*JP
             enl_msg("Bad luck ", "does", "did", " not time out for you", "");
+*/
+            enl_msg("\95s\89^\82Í\8e\9e\8aÔ\90Ø\82ê\82É\82È\82ç\82È", "\82¢", "\82©\82Á\82½", "", "");
         if (ltmp >= 0)
+/*JP
             enl_msg("Good luck ", "does", "did", " not time out for you", "");
+*/
+            enl_msg("\8dK\89^\82Í\8e\9e\8aÔ\90Ø\82ê\82É\82È\82ç\82È", "\82¢", "\82©\82Á\82½", "", "");
     }
 
     if (u.ugangr) {
+#if 0 /*JP*/
         Sprintf(buf, " %sangry with you",
                 u.ugangr > 6 ? "extremely " : u.ugangr > 3 ? "very " : "");
+#else
+        Sprintf(buf, "%s\82Í%s\93{\82Á\82Ä%s", u_gname(),
+                u.ugangr > 6 ? "\96Ò\97ó\82É" : u.ugangr > 3 ? "\82Æ\82Ä\82à" : "", final ? ita : iru);
+#endif
         if (wizard)
             Sprintf(eos(buf), " (%d)", u.ugangr);
+#if 0 /*JP*/
         enl_msg(u_gname(), " is", " was", buf, "");
+#else
+        enl_msg(buf, "", "", "", "");
+#endif
     } else {
         /*
          * We need to suppress this when the game is over, because death
@@ -2232,6 +3790,7 @@ int final;
          * resulting in a false claim that you could have prayed safely.
          */
         if (!final) {
+#if 0 /*JP*/
 #if 0
             /* "can [not] safely pray" vs "could [not] have safely prayed" */
             Sprintf(buf, "%s%ssafely pray%s", can_pray(FALSE) ? "" : "not ",
@@ -2242,63 +3801,114 @@ int final;
             if (wizard)
                 Sprintf(eos(buf), " (%d)", u.ublesscnt);
             you_can(buf, "");
+#else /*JP*/
+            Sprintf(buf, "\82 \82È\82½\82Í\88À\91S\82É\8bF\82é\82±\82Æ\82ª");
+            Strcat(buf, can_pray(FALSE) ? can : "\82Å\82«\82È\82¢");
+            if (wizard)
+              Sprintf(eos(buf), " (%d)", u.ublesscnt);
+            enl_msg(buf, "", "", "", "");
+#endif
         }
     }
 
-    /* named fruit debugging (doesn't really belong here...) */
-    if (wizard) {
-        int fcount = 0;
+#ifdef DEBUG
+    /* named fruit debugging (doesn't really belong here...); to enable,
+       include 'fruit' in DEBUGFILES list (even though it isn't a file...) */
+    if (wizard && explicitdebug("fruit")) {
         struct fruit *f;
-        char buf2[BUFSZ];
 
+        reorder_fruit(TRUE); /* sort by fruit index, from low to high;
+                              * this modifies the ffruit chain, so could
+                              * possibly mask or even introduce a problem,
+                              * but it does useful sanity checking */
         for (f = ffruit; f; f = f->nextf) {
-            Sprintf(buf, "Fruit %d ", ++fcount);
-            Sprintf(buf2, "%s (id %d)", f->fname, f->fid);
-            enl_msg(buf, "is ", "was ", buf2, "");
+/*JP
+            Sprintf(buf, "Fruit #%d ", f->fid);
+*/
+            Sprintf(buf, "fruit $%d \82Í", f->fid);
+/*JP
+            enl_msg(buf, "is ", "was ", f->fname, "");
+*/
+            enl_msg(buf, "\82¾", "\82¾\82Á\82½", f->fname, "");
         }
+/*JP
         enl_msg("The current fruit ", "is ", "was ", pl_fruit, "");
+*/
+        enl_msg("\8c»\8dÝ\82Ì fruit \82Í", "\82¾", "\82¾\82Á\82½", pl_fruit, "");
         Sprintf(buf, "%d", flags.made_fruit);
+/*JP
         enl_msg("The made fruit flag ", "is ", "was ", buf, "");
+*/
+        enl_msg("made fruit flag \82Í", "\82¾", "\82¾\82Á\82½", buf, "");
     }
+#endif
 
     {
         const char *p;
 
         buf[0] = '\0';
         if (final < 2) { /* still in progress, or quit/escaped/ascended */
+/*JP
             p = "survived after being killed ";
+*/
+            p = "\8e\80\82ñ\82¾\8cã\95\9c\8a\88\82µ\82Ä\82¢\82½";
             switch (u.umortality) {
             case 0:
+/*JP
                 p = !final ? (char *) 0 : "survived";
+*/
+                p = !final ? (char *)0 : "\90\82«\89\84\82Ñ\82½";
                 break;
             case 1:
+/*JP
                 Strcpy(buf, "once");
+*/
+                Strcpy(buf, "\88ê\93x");
                 break;
             case 2:
+/*JP
                 Strcpy(buf, "twice");
+*/
+                Strcpy(buf, "\93ñ\93x");
                 break;
             case 3:
+/*JP
                 Strcpy(buf, "thrice");
+*/
+                Strcpy(buf, "\8eO\93x");
                 break;
             default:
+/*JP
                 Sprintf(buf, "%d times", u.umortality);
+*/
+                Sprintf(buf, "%d\89ñ", u.umortality);
                 break;
             }
         } else { /* game ended in character's death */
+/*JP
             p = "are dead";
+*/
+            p = "\8e\80\82ñ\82Å\82¢\82é";
             switch (u.umortality) {
             case 0:
                 impossible("dead without dying?");
             case 1:
                 break; /* just "are dead" */
             default:
+#if 0 /*JP*/
                 Sprintf(buf, " (%d%s time!)", u.umortality,
                         ordin(u.umortality));
+#else
+                 Sprintf(buf, "(%d\89ñ\81I)", u.umortality);
+#endif
                 break;
             }
         }
         if (p)
+/*JP
             enl_msg(You_, "have been killed ", p, buf, "");
+*/
+            enl_msg(You_, "\8e\80\82ñ\82Å\82¢\82é", p, buf, "");
     }
 }
 
@@ -2333,82 +3943,160 @@ minimal_enlightenment()
     tmpwin = create_nhwindow(NHW_MENU);
     start_menu(tmpwin);
     add_menu(tmpwin, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
+/*JP
              "Starting", FALSE);
+*/
+             "\8aJ\8en", FALSE);
 
     /* Starting name, race, role, gender */
+/*JP
     Sprintf(buf, fmtstr, "name", plname);
+*/
+    Sprintf(buf, fmtstr, "\96¼\91O", plname);
     add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
+/*JP
     Sprintf(buf, fmtstr, "race", urace.noun);
+*/
+    Sprintf(buf, fmtstr, "\8eí\91°", urace.noun);
     add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
+/*JP
     Sprintf(buf, fmtstr, "role",
+*/
+    Sprintf(buf, fmtstr, "\90E\8bÆ",
             (flags.initgend && urole.name.f) ? urole.name.f : urole.name.m);
     add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
+/*JP
     Sprintf(buf, fmtstr, "gender", genders[flags.initgend].adj);
+*/
+    Sprintf(buf, fmtstr, "\90«\95Ê", genders[flags.initgend].adj);
     add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
 
     /* Starting alignment */
+/*JP
     Sprintf(buf, fmtstr, "alignment", align_str(u.ualignbase[A_ORIGINAL]));
+*/
+    Sprintf(buf, fmtstr, "\91®\90«", align_str(u.ualignbase[A_ORIGINAL]));
     add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
 
     /* Current name, race, role, gender */
     add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, "", FALSE);
     add_menu(tmpwin, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
+/*JP
              "Current", FALSE);
+*/
+             "\8c»\8dÝ", FALSE);
+/*JP
     Sprintf(buf, fmtstr, "race", Upolyd ? youmonst.data->mname : urace.noun);
+*/
+    Sprintf(buf, fmtstr, "\8eí\91°", Upolyd ? youmonst.data->mname : urace.noun);
     add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
     if (Upolyd) {
+/*JP
         Sprintf(buf, fmtstr, "role (base)",
+*/
+        Sprintf(buf, fmtstr, "\90E\8bÆ(\8aî\96{)",
                 (u.mfemale && urole.name.f) ? urole.name.f
                                             : urole.name.m);
         add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
     } else {
+/*JP
         Sprintf(buf, fmtstr, "role",
+*/
+        Sprintf(buf, fmtstr, "\90E\8bÆ",
                 (flags.female && urole.name.f) ? urole.name.f
                                                : urole.name.m);
         add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
     }
     /* don't want poly_gender() here; it forces `2' for non-humanoids */
     genidx = is_neuter(youmonst.data) ? 2 : flags.female;
+/*JP
     Sprintf(buf, fmtstr, "gender", genders[genidx].adj);
+*/
+    Sprintf(buf, fmtstr, "\90«\95Ê", genders[genidx].adj);
     add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
     if (Upolyd && (int) u.mfemale != genidx) {
+/*JP
         Sprintf(buf, fmtstr, "gender (base)", genders[u.mfemale].adj);
+*/
+        Sprintf(buf, fmtstr, "\90«\95Ê(\8aî\96{)", genders[u.mfemale].adj);
         add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
     }
 
     /* Current alignment */
+/*JP
     Sprintf(buf, fmtstr, "alignment", align_str(u.ualign.type));
+*/
+    Sprintf(buf, fmtstr, "\91®\90«", align_str(u.ualign.type));
     add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
 
     /* Deity list */
     add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, "", FALSE);
     add_menu(tmpwin, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
+/*JP
              "Deities", FALSE);
+*/
+             "\90_", FALSE);
+#if 0 /*JP*/
     Sprintf(buf2, deity_fmtstr, align_gname(A_CHAOTIC),
             (u.ualignbase[A_ORIGINAL] == u.ualign.type
              && u.ualign.type == A_CHAOTIC)               ? " (s,c)"
                 : (u.ualignbase[A_ORIGINAL] == A_CHAOTIC) ? " (s)"
                 : (u.ualign.type   == A_CHAOTIC)          ? " (c)" : "");
+#else
+    Sprintf(buf2, deity_fmtstr, align_gname(A_CHAOTIC),
+            (u.ualignbase[A_ORIGINAL] == u.ualign.type
+             && u.ualign.type == A_CHAOTIC)               ? " (\8f\89\81C\8c»)"
+                : (u.ualignbase[A_ORIGINAL] == A_CHAOTIC) ? " (\8f\89)"
+                : (u.ualign.type   == A_CHAOTIC)          ? " (\8c»)" : "");
+#endif
+/*JP
     Sprintf(buf, fmtstr, "Chaotic", buf2);
+*/
+    Sprintf(buf, fmtstr, "\8d¬\93×", buf2);
     add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
 
+#if 0 /*JP*/
     Sprintf(buf2, deity_fmtstr, align_gname(A_NEUTRAL),
             (u.ualignbase[A_ORIGINAL] == u.ualign.type
              && u.ualign.type == A_NEUTRAL)               ? " (s,c)"
                 : (u.ualignbase[A_ORIGINAL] == A_NEUTRAL) ? " (s)"
                 : (u.ualign.type   == A_NEUTRAL)          ? " (c)" : "");
+#else
+    Sprintf(buf2, deity_fmtstr, align_gname(A_NEUTRAL),
+            (u.ualignbase[A_ORIGINAL] == u.ualign.type
+             && u.ualign.type == A_NEUTRAL)               ? " (\8f\89\81C\8c»)"
+                : (u.ualignbase[A_ORIGINAL] == A_NEUTRAL) ? " (\8f\89)"
+                : (u.ualign.type   == A_NEUTRAL)          ? " (\8c»)" : "");
+#endif
+/*JP
     Sprintf(buf, fmtstr, "Neutral", buf2);
+*/
+    Sprintf(buf, fmtstr, "\92\86\97§", buf2);
     add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
 
+#if 0 /*JP*/
     Sprintf(buf2, deity_fmtstr, align_gname(A_LAWFUL),
             (u.ualignbase[A_ORIGINAL] == u.ualign.type
              && u.ualign.type == A_LAWFUL)                ? " (s,c)"
                 : (u.ualignbase[A_ORIGINAL] == A_LAWFUL)  ? " (s)"
                 : (u.ualign.type   == A_LAWFUL)           ? " (c)" : "");
+#else
+    Sprintf(buf2, deity_fmtstr, align_gname(A_LAWFUL),
+            (u.ualignbase[A_ORIGINAL] == u.ualign.type
+             && u.ualign.type == A_LAWFUL)                ? " (\8f\89\81C\8c»)"
+                : (u.ualignbase[A_ORIGINAL] == A_LAWFUL)  ? " (\8f\89)"
+                : (u.ualign.type   == A_LAWFUL)           ? " (\8c»)" : "");
+#endif
+/*JP
     Sprintf(buf, fmtstr, "Lawful", buf2);
+*/
+    Sprintf(buf, fmtstr, "\92\81\8f\98", buf2);
     add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
 
+/*JP
     end_menu(tmpwin, "Base Attributes");
+*/
+    end_menu(tmpwin, "\8aî\96{\91®\90«");
     n = select_menu(tmpwin, PICK_NONE, &selected);
     destroy_nhwindow(tmpwin);
     return (boolean) (n != -1);
@@ -2436,44 +4124,81 @@ int msgflag;          /* for variant message phrasing */
 {
     char *bp, buf[BUFSZ];
 
+/*JP
     Strcpy(buf, "hiding");
-    if (youmonst.m_ap_type != M_AP_NOTHING) {
+*/
+    Strcpy(buf, "\89B\82ê");
+    if (U_AP_TYPE != M_AP_NOTHING) {
         /* mimic; hero is only able to mimic a strange object or gold
            or hallucinatory alternative to gold, so we skip the details
            for the hypothetical furniture and monster cases */
+#if 0 /*JP*//*\8cã\82ë\82É\89ñ\82·*//* not used */
         bp = eos(strcpy(buf, "mimicking"));
-        if (youmonst.m_ap_type == M_AP_OBJECT) {
+#endif
+        if (U_AP_TYPE == M_AP_OBJECT) {
+/*JP
             Sprintf(bp, " %s", an(simple_typename(youmonst.mappearance)));
-        } else if (youmonst.m_ap_type == M_AP_FURNITURE) {
+*/
+            Strcpy(buf, simple_typename(youmonst.mappearance));
+        } else if (U_AP_TYPE == M_AP_FURNITURE) {
+/*JP
             Strcpy(bp, " something");
-        } else if (youmonst.m_ap_type == M_AP_MONSTER) {
+*/
+            Strcpy(buf, "\89½\82©");
+        } else if (U_AP_TYPE == M_AP_MONSTER) {
+/*JP
             Strcpy(bp, " someone");
+*/
+            Strcpy(buf, "\89½\8eÒ\82©");
         } else {
             ; /* something unexpected; leave 'buf' as-is */
         }
+#if 1 /*JP*//*\82±\82±\82Å\92Ç\89Á*/
+        Strcat(buf, "\82Ì\82Ó\82è\82ð\82µ");
+#endif
     } else if (u.uundetected) {
         bp = eos(buf); /* points past "hiding" */
         if (youmonst.data->mlet == S_EEL) {
             if (is_pool(u.ux, u.uy))
+/*JP
                 Sprintf(bp, " in the %s", waterbody_name(u.ux, u.uy));
+*/
+                Sprintf(bp, "%s\82Ì\92\86\82É", waterbody_name(u.ux, u.uy));
         } else if (hides_under(youmonst.data)) {
             struct obj *o = level.objects[u.ux][u.uy];
 
             if (o)
+/*JP
                 Sprintf(bp, " underneath %s", ansimpleoname(o));
+*/
+                Sprintf(bp, "%s\82Ì\89º\82É", ansimpleoname(o));
         } else if (is_clinger(youmonst.data) || Flying) {
             /* Flying: 'lurker above' hides on ceiling but doesn't cling */
+/*JP
             Sprintf(bp, " on the %s", ceiling(u.ux, u.uy));
+*/
+            Sprintf(bp, "%s\82É", ceiling(u.ux, u.uy));
         } else {
             /* on floor; is_hider() but otherwise not special: 'trapper' */
             if (u.utrap && u.utraptype == TT_PIT) {
                 struct trap *t = t_at(u.ux, u.uy);
 
+#if 0 /*JP*/
                 Sprintf(bp, " in a %spit",
                         (t && t->ttyp == SPIKED_PIT) ? "spiked " : "");
+#else
+                Sprintf(bp, "%s\97\8e\82µ\8c\8a\82Ì\92\86\82É",
+                        (t && t->ttyp == SPIKED_PIT) ? "\83g\83Q\82¾\82ç\82¯\82Ì" : "");
+#endif
             } else
+/*JP
                 Sprintf(bp, " on the %s", surface(u.ux, u.uy));
+*/
+                Sprintf(bp, "%s\82É", surface(u.ux, u.uy));
         }
+#if 1 /*JP*//*\82±\82±\82Å\92Ç\89Á*/
+        Strcat(buf, "\89B\82ê");
+#endif
     } else {
         ; /* shouldn't happen; will result in generic "you are hiding" */
     }
@@ -2484,14 +4209,22 @@ int msgflag;          /* for variant message phrasing */
         you_are(buf, "");
     } else {
         /* for dohide(), when player uses '#monster' command */
+#if 0 /*JP*/
         You("are %s %s.", msgflag ? "already" : "now", buf);
+#else
+        if (msgflag) {
+            You("\82·\82Å\82É%s\82Ä\82¢\82é\81D", buf);
+        } else {
+            You("%s\82½\81D", buf);
+        }
+#endif
     }
 }
 
 /* KMH, #conduct
  * (shares enlightenment's tense handling)
  */
-STATIC_PTR int
+int
 doconduct(VOID_ARGS)
 {
     show_conduct(0);
@@ -2507,77 +4240,172 @@ int final;
 
     /* Create the conduct window */
     en_win = create_nhwindow(NHW_MENU);
+/*JP
     putstr(en_win, 0, "Voluntary challenges:");
+*/
+    putstr(en_win, 0, "\8e©\94­\93I\92§\90í:");
 
     if (u.uroleplay.blind)
+/*JP
         you_have_been("blind from birth");
+*/
+        you_have_been("\90\82Ü\82ê\82È\82ª\82ç\82É\96Ó\96Ú");
     if (u.uroleplay.nudist)
+/*JP
         you_have_been("faithfully nudist");
+*/
+        you_have_been("\92\89\8eÀ\82È\97\87\91°");
 
     if (!u.uconduct.food)
+/*JP
         enl_msg(You_, "have gone", "went", " without food", "");
-    /* But beverages are okay */
+*/
+        enl_msg("\82 \82È\82½\82Í\90H\8e\96\82ð\82µ", "\82Ä\82¢\82È\82¢", "\82È\82©\82Á\82½", "", "");
+        /* but beverages are okay */
     else if (!u.uconduct.unvegan)
+/*JP
         you_have_X("followed a strict vegan diet");
+*/
+        you_have_been("\8cµ\8ai\82È\8dØ\90H\8eå\8b`\8eÒ");
     else if (!u.uconduct.unvegetarian)
+/*JP
         you_have_been("vegetarian");
+*/
+        you_have_been("\8dØ\90H\8eå\8b`\8eÒ");
 
     if (!u.uconduct.gnostic)
+/*JP
         you_have_been("an atheist");
+*/
+        you_have_been("\96³\90_\98_\8eÒ");
 
     if (!u.uconduct.weaphit) {
+/*JP
         you_have_never("hit with a wielded weapon");
+*/
+        you_have_never("\82 \82È\82½\82Í\91\95\94õ\82µ\82Ä\82¢\82é\95\90\8aí\82Å\8dU\8c\82\82µ");
     } else if (wizard) {
+#if 0 /*JP*/
         Sprintf(buf, "used a wielded weapon %ld time%s", u.uconduct.weaphit,
                 plur(u.uconduct.weaphit));
         you_have_X(buf);
+#else
+        Sprintf(buf, "\82 \82È\82½\82Í%ld\89ñ\91\95\94õ\82µ\82½\95\90\8aí\82ð\8eg\97p\82µ", u.uconduct.weaphit);
+        you_have_X(buf);
+#endif
     }
     if (!u.uconduct.killer)
+/*JP
         you_have_been("a pacifist");
+*/
+        you_have_been("\95½\98a\8eå\8b`\8eÒ");
 
     if (!u.uconduct.literate) {
+/*JP
         you_have_been("illiterate");
+*/
+        you_have_never("\82 \82È\82½\82Í\93Ç\82Ý\8f\91\82«\82µ");
     } else if (wizard) {
+#if 0 /*JP:T*/
         Sprintf(buf, "read items or engraved %ld time%s", u.uconduct.literate,
                 plur(u.uconduct.literate));
         you_have_X(buf);
+#else
+        Sprintf(buf, "%ld\89ñ\93Ç\82ñ\82¾\82è\8f\91\82¢\82½\82è\82µ", u.uconduct.literate);
+        you_have_X(buf);
+#endif
     }
 
     ngenocided = num_genocides();
     if (ngenocided == 0) {
+/*JP
         you_have_never("genocided any monsters");
+*/
+        you_have_never("\82 \82È\82½\82Í\89ö\95¨\82ð\8bs\8eE\82µ");
     } else {
+#if 0 /*JP:T*/
         Sprintf(buf, "genocided %d type%s of monster%s", ngenocided,
                 plur(ngenocided), plur(ngenocided));
         you_have_X(buf);
+#else
+        Sprintf(buf, "%d\8eí\82Ì\89ö\95¨\82ð\8bs\8eE\82µ", ngenocided);
+        you_have_X(buf);
+#endif
     }
 
     if (!u.uconduct.polypiles) {
+/*JP
         you_have_never("polymorphed an object");
+*/
+        you_have_never("\82 \82È\82½\82Í\95¨\91Ì\82ð\95Ï\89»\82³\82¹");
     } else if (wizard) {
+#if 0 /*JP:T*/
         Sprintf(buf, "polymorphed %ld item%s", u.uconduct.polypiles,
                 plur(u.uconduct.polypiles));
         you_have_X(buf);
+#else
+        Sprintf(buf, "%ld\8cÂ\82Ì\95¨\82ð\95Ï\89»\82³\82¹", u.uconduct.polypiles);
+        you_have_X(buf);
+#endif
     }
 
     if (!u.uconduct.polyselfs) {
+/*JP
         you_have_never("changed form");
+*/
+        you_have_never("\82 \82È\82½\82Í\95Ï\89»\82µ");
     } else if (wizard) {
+#if 0 /*JP:T*/
         Sprintf(buf, "changed form %ld time%s", u.uconduct.polyselfs,
                 plur(u.uconduct.polyselfs));
         you_have_X(buf);
+#else
+        Sprintf(buf, "%ld\89ñ\8ep\82ð\95Ï\82¦", u.uconduct.polyselfs);
+        you_have_X(buf);
+#endif
     }
 
     if (!u.uconduct.wishes) {
+/*JP
         you_have_X("used no wishes");
+*/
+        you_have_never("\82 \82È\82½\82Í\8aè\82¢\8e\96\82ð\82µ");
     } else {
+#if 0 /*JP*/
         Sprintf(buf, "used %ld wish%s", u.uconduct.wishes,
                 (u.uconduct.wishes > 1L) ? "es" : "");
+#else
+        Sprintf(buf, "%ld\89ñ\8aè\82¢\8e\96\82ð\82µ", u.uconduct.wishes);
+#endif
+        if (u.uconduct.wisharti) {
+            /* if wisharti == wishes
+             *  1 wish (for an artifact)
+             *  2 wishes (both for artifacts)
+             *  N wishes (all for artifacts)
+             * else (N is at least 2 in order to get here; M < N)
+             *  N wishes (1 for an artifact)
+             *  N wishes (M for artifacts)
+             */
+            if (u.uconduct.wisharti == u.uconduct.wishes)
+                Sprintf(eos(buf), " (%s",
+                        (u.uconduct.wisharti > 2L) ? "all "
+                          : (u.uconduct.wisharti == 2L) ? "both " : "");
+            else
+                Sprintf(eos(buf), " (%ld ", u.uconduct.wisharti);
+
+            Sprintf(eos(buf), "for %s)",
+                    (u.uconduct.wisharti == 1L) ? "an artifact"
+                                                : "artifacts");
+        }
         you_have_X(buf);
 
         if (!u.uconduct.wisharti)
+#if 0 /*JP*/
             enl_msg(You_, "have not wished", "did not wish",
                     " for any artifacts", "");
+#else
+            enl_msg("\82 \82È\82½\82Í\90¹\8aí\82ð\8aè", "\82Á\82Ä\82¢\82È\82¢", "\82í\82È\82©\82Á\82½", "", "");
+#endif
     }
 
     /* Pop up the window and wait for a key */
@@ -2586,291 +4414,650 @@ int final;
     en_win = WIN_ERR;
 }
 
-#ifndef M
-#ifndef NHSTDC
-#define M(c) (0x80 | (c))
+/* ordered by command name */
+struct ext_func_tab extcmdlist[] = {
+    { '#', "#", "perform an extended command",
+            doextcmd, IFBURIED | GENERALCMD },
+#if 0 /*JP*/
+    { M('?'), "?", "list all extended commands",
 #else
-#define M(c) ((c) -128)
-#endif /* NHSTDC */
+    { M('?'), "?", "\82±\82Ì\8ag\92£\83R\83}\83\93\83h\88ê\97\97\82ð\95\\8e¦\82·\82é",
 #endif
-#ifndef C
-#define C(c) (0x1f & (c))
+            doextlist, IFBURIED | AUTOCOMPLETE | GENERALCMD },
+#if 0 /*JP*/
+    { M('a'), "adjust", "adjust inventory letters",
+#else
+    { M('a'), "adjust", "\8e\9d\82¿\95¨\88ê\97\97\82Ì\92²\90®",
+#endif
+            doorganize, IFBURIED | AUTOCOMPLETE },
+#if 0 /*JP*/
+    { M('A'), "annotate", "name current level",
+#else
+    { M('A'), "annotate", "\8c»\8dÝ\82Ì\8aK\82É\96¼\91O\82ð\82Â\82¯\82é",
+#endif
+            donamelevel, IFBURIED | AUTOCOMPLETE },
+    { 'a', "apply", "apply (use) a tool (pick-axe, key, lamp...)",
+            doapply },
+    { C('x'), "attributes", "show your attributes",
+            doattributes, IFBURIED },
+    { '@', "autopickup", "toggle the pickup option on/off",
+            dotogglepickup, IFBURIED },
+    { 'C', "call", "call (name) something", docallcmd, IFBURIED },
+    { 'Z', "cast", "zap (cast) a spell", docast, IFBURIED },
+#if 0 /*JP*/
+    { M('c'), "chat", "talk to someone", dotalk, IFBURIED | AUTOCOMPLETE },
+#else
+    { M('c'), "chat", "\92N\82©\82Æ\98b\82·", dotalk, IFBURIED | AUTOCOMPLETE },
+#endif
+    { 'c', "close", "close a door", doclose },
+#if 0 /*JP*/
+    { M('C'), "conduct", "list voluntary challenges you have maintained",
+#else
+    { M('C'), "conduct", "\82Ç\82¤\82¢\82¤\8ds\93®\82ð\82Æ\82Á\82½\82©\8c©\82é",
+#endif
+            doconduct, IFBURIED | AUTOCOMPLETE },
+#if 0 /*JP*/
+    { M('d'), "dip", "dip an object into something", dodip, AUTOCOMPLETE },
+#else
+    { M('d'), "dip", "\89½\82©\82É\95¨\82ð\90Z\82·", dodip, AUTOCOMPLETE },
+#endif
+    { '>', "down", "go down a staircase", dodown },
+    { 'd', "drop", "drop an item", dodrop },
+    { 'D', "droptype", "drop specific item types", doddrop },
+    { 'e', "eat", "eat something", doeat },
+    { 'E', "engrave", "engrave writing on the floor", doengrave },
+#if 0 /*JP*/
+    { M('e'), "enhance", "advance or check weapon and spell skills",
+#else
+    { M('e'), "enhance", "\95\90\8aí\8fn\97û\93x\82ð\8d\82\82ß\82é",
+#endif
+            enhance_weapon_skill, IFBURIED | AUTOCOMPLETE },
+#if 0 /*JP*/
+    { '\0', "exploremode", "enter explore (discovery) mode",
+#else
+    { '\0', "exploremode", "\92T\8c\9f(\94­\8c©)\83\82\81[\83h\82É\93ü\82é",
+#endif
+            enter_explore_mode, IFBURIED },
+    { 'f', "fire", "fire ammunition from quiver", dofire },
+#if 0 /*JP*/
+    { M('f'), "force", "force a lock", doforce, AUTOCOMPLETE },
+#else
+    { M('f'), "force", "\8c®\82ð\82±\82\82 \82¯\82é", doforce, AUTOCOMPLETE },
+#endif
+    { ';', "glance", "show what type of thing a map symbol corresponds to",
+            doquickwhatis, IFBURIED | GENERALCMD },
+    { '?', "help", "give a help message", dohelp, IFBURIED | GENERALCMD },
+    { '\0', "herecmdmenu", "show menu of commands you can do here",
+            doherecmdmenu, IFBURIED },
+    { 'V', "history", "show long version and game history",
+            dohistory, IFBURIED | GENERALCMD },
+    { 'i', "inventory", "show your inventory", ddoinv, IFBURIED },
+    { 'I', "inventtype", "inventory specific item types",
+            dotypeinv, IFBURIED },
+#if 0 /*JP*/
+    { M('i'), "invoke", "invoke an object's special powers",
+#else
+    { M('i'), "invoke", "\95¨\82Ì\93Á\95Ê\82È\97Í\82ð\8eg\82¤",
+#endif
+            doinvoke, IFBURIED | AUTOCOMPLETE },
+#if 0 /*JP*/
+    { M('j'), "jump", "jump to another location", dojump, AUTOCOMPLETE },
+#else
+    { M('j'), "jump", "\91¼\82Ì\88Ê\92u\82É\94ò\82Ñ\82¤\82Â\82é", dojump, AUTOCOMPLETE },
+#endif
+    { C('d'), "kick", "kick something", dokick },
+    { '\\', "known", "show what object types have been discovered",
+            dodiscovered, IFBURIED | GENERALCMD },
+    { '`', "knownclass", "show discovered types for one class of objects",
+            doclassdisco, IFBURIED | GENERALCMD },
+#if 0 /*JP*/
+    { '\0', "levelchange", "change experience level",
+#else
+    { '\0', "levelchange", "\8co\8c±\83\8c\83x\83\8b\82ð\95Ï\82¦\82é",
+#endif
+            wiz_level_change, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
+#if 0 /*JP*/
+    { '\0', "lightsources", "show mobile light sources",
+#else
+    { '\0', "lightsources", "\88Ú\93®\8cõ\8c¹\82ð\8c©\82é",
+#endif
+            wiz_light_sources, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
+    { ':', "look", "look at what is here", dolook, IFBURIED },
+#if 0 /*JP*/
+    { M('l'), "loot", "loot a box on the floor", doloot, AUTOCOMPLETE },
+#else
+    { M('l'), "loot", "\8f°\82Ì\8fã\82Ì\94 \82ð\8aJ\82¯\82é", doloot, AUTOCOMPLETE },
 #endif
-
-static const struct func_tab cmdlist[] = {
-    { C('d'), FALSE, dokick }, /* "D" is for door!...?  Msg is in dokick.c */
-    { C('e'), TRUE, wiz_detect },
-    { C('f'), TRUE, wiz_map },
-    { C('g'), TRUE, wiz_genesis },
-    { C('i'), TRUE, wiz_identify },
-    { C('l'), TRUE, doredraw },    /* if number_pad is set */
-    { C('n'), TRUE, donamelevel }, /* if number_pad is set */
-    { C('o'), TRUE, dooverview_or_wiz_where }, /* depends on wizard status */
-    { C('p'), TRUE, doprev_message },
-    { C('r'), TRUE, doredraw },
-    { C('t'), TRUE, dotele },
-    { C('v'), TRUE, wiz_level_tele },
-    { C('w'), TRUE, wiz_wish },
-    { C('x'), TRUE, doattributes },
-    { C('z'), TRUE, dosuspend_core },
-    { 'a', FALSE, doapply },
-    { 'A', FALSE, doddoremarm },
-    { M('a'), TRUE, doorganize },
-    { M('A'), TRUE, donamelevel }, /* #annotate */
-    /*  'b', 'B' : go sw */
-    { 'c', FALSE, doclose },
-    { 'C', TRUE, docallcmd },
-    { M('c'), TRUE, dotalk },
-    { M('C'), TRUE, doconduct }, /* #conduct */
-    { 'd', FALSE, dodrop },
-    { 'D', FALSE, doddrop },
-    { M('d'), FALSE, dodip },
-    { 'e', FALSE, doeat },
-    { 'E', FALSE, doengrave },
-    { M('e'), TRUE, enhance_weapon_skill },
-    { 'f', FALSE, dofire },
-    /*  'F' : fight (one time) */
-    { M('f'), FALSE, doforce },
-    /*  'g', 'G' : multiple go */
-    /*  'h', 'H' : go west */
-    { 'h', TRUE, dohelp }, /* if number_pad is set */
-    { 'i', TRUE, ddoinv },
-    { 'I', TRUE, dotypeinv }, /* Robert Viduya */
-    { M('i'), TRUE, doinvoke },
-    /*  'j', 'J', 'k', 'K', 'l', 'L', 'm', 'M', 'n', 'N' : move commands */
-    { 'j', FALSE, dojump }, /* if number_pad is on */
-    { M('j'), FALSE, dojump },
-    { 'k', FALSE, dokick }, /* if number_pad is on */
-    { 'l', FALSE, doloot }, /* if number_pad is on */
-    { M('l'), FALSE, doloot },
-    /*  'n' prefixes a count if number_pad is on */
-    { M('m'), TRUE, domonability },
-    { 'N', TRUE, docallcmd }, /* if number_pad is on */
-    { M('n'), TRUE, docallcmd },
-    { M('N'), TRUE, docallcmd },
-    { 'o', FALSE, doopen },
-    { 'O', TRUE, doset },
-    { M('o'), FALSE, dosacrifice },
-    { M('O'), TRUE, dooverview }, /* #overview */
-    { 'p', FALSE, dopay },
-    { 'P', FALSE, doputon },
-    { M('p'), TRUE, dopray },
-    { 'q', FALSE, dodrink },
-    { 'Q', FALSE, dowieldquiver },
-    { M('q'), TRUE, done2 },
-    { 'r', FALSE, doread },
-    { 'R', FALSE, doremring },
-    { M('r'), FALSE, dorub },
-    { M('R'), FALSE, doride }, /* #ride */
-    { 's', TRUE, dosearch, "searching" },
-    { 'S', TRUE, dosave },
-    { M('s'), FALSE, dosit },
-    { 't', FALSE, dothrow },
-    { 'T', FALSE, dotakeoff },
-    { M('t'), TRUE, doturn },
-    { M('T'), FALSE, dotip }, /* #tip */
-    /*  'u', 'U' : go ne */
-    { 'u', FALSE, dountrap }, /* if number_pad is on */
-    { M('u'), FALSE, dountrap },
-    { 'v', TRUE, doversion },
-    { 'V', TRUE, dohistory },
-    { M('v'), TRUE, doextversion },
-    { 'w', FALSE, dowield },
-    { 'W', FALSE, dowear },
-    { M('w'), FALSE, dowipe },
-    { 'x', FALSE, doswapweapon },
-    { 'X', FALSE, dotwoweapon },
-    /*  'y', 'Y' : go nw */
-    { 'z', FALSE, dozap },
-    { 'Z', TRUE, docast },
-    { '<', FALSE, doup },
-    { '>', FALSE, dodown },
-    { '/', TRUE, dowhatis },
-    { '&', TRUE, dowhatdoes },
-    { '?', TRUE, dohelp },
-    { M('?'), TRUE, doextlist },
-#ifdef SHELL
-    { '!', TRUE, dosh },
-#endif
-    { '.', TRUE, donull, "waiting" },
-    { ' ', TRUE, donull, "waiting" },
-    { ',', FALSE, dopickup },
-    { ':', TRUE, dolook },
-    { ';', TRUE, doquickwhatis },
-    { '^', TRUE, doidtrap },
-    { '\\', TRUE, dodiscovered }, /* Robert Viduya */
-    { '`', TRUE, doclassdisco },
-    { '@', TRUE, dotogglepickup },
-    { M('2'), FALSE, dotwoweapon },
-    { WEAPON_SYM, TRUE, doprwep },
-    { ARMOR_SYM, TRUE, doprarm },
-    { RING_SYM, TRUE, doprring },
-    { AMULET_SYM, TRUE, dopramulet },
-    { TOOL_SYM, TRUE, doprtool },
-    { '*', TRUE, doprinuse }, /* inventory of all equipment in use */
-    { GOLD_SYM, TRUE, doprgold },
-    { SPBOOK_SYM, TRUE, dovspell }, /* Mike Stephenson */
-    { '#', TRUE, doextcmd },
-    { '_', TRUE, dotravel },
-    { 0, 0, 0, 0 }
-};
-
-struct ext_func_tab extcmdlist[] = {
-    { "adjust", "adjust inventory letters", doorganize, TRUE },
-    { "annotate", "name current level", donamelevel, TRUE },
-    { "chat", "talk to someone", dotalk, TRUE }, /* converse? */
-    { "conduct", "list voluntary challenges you have maintained", doconduct,
-      TRUE },
-    { "dip", "dip an object into something", dodip, FALSE },
-    { "enhance", "advance or check weapon and spell skills",
-      enhance_weapon_skill, TRUE },
-    { "exploremode", "enter explore mode", enter_explore_mode, TRUE },
-    { "force", "force a lock", doforce, FALSE },
-    { "invoke", "invoke an object's powers", doinvoke, TRUE },
-    { "jump", "jump to a location", dojump, FALSE },
-    { "loot", "loot a box on the floor", doloot, FALSE },
-    { "monster", "use a monster's special ability", domonability, TRUE },
-    { "name", "name a monster or an object", docallcmd, TRUE },
-    { "offer", "offer a sacrifice to the gods", dosacrifice, FALSE },
-    { "overview", "show an overview of the dungeon", dooverview, TRUE },
-    { "pray", "pray to the gods for help", dopray, TRUE },
-    { "quit", "exit without saving current game", done2, TRUE },
-    { "ride", "ride (or stop riding) a monster", doride, FALSE },
-    { "rub", "rub a lamp or a stone", dorub, FALSE },
-    { "sit", "sit down", dosit, FALSE },
-    { "terrain", "show map without obstructions", doterrain, TRUE },
-    { "tip", "empty a container", dotip, FALSE },
-    { "turn", "turn undead", doturn, TRUE },
-    { "twoweapon", "toggle two-weapon combat", dotwoweapon, FALSE },
-    { "untrap", "untrap something", dountrap, FALSE },
-    { "version", "list compile time options for this version of NetHack",
-      doextversion, TRUE },
-    { "wipe", "wipe off your face", dowipe, FALSE },
-    { "?", "get this list of extended commands", doextlist, TRUE },
-    /*
-     * There must be a blank entry here for every entry in the table
-     * below.
-     */
-    { (char *) 0, (char *) 0, donull, TRUE }, /* levelchange */
-    { (char *) 0, (char *) 0, donull, TRUE }, /* lightsources */
 #ifdef DEBUG_MIGRATING_MONS
-    { (char *) 0, (char *) 0, donull, TRUE }, /* migratemons */
-#endif
-    { (char *) 0, (char *) 0, donull, TRUE }, /* monpolycontrol */
-    { (char *) 0, (char *) 0, donull, TRUE }, /* panic */
-    { (char *) 0, (char *) 0, donull, TRUE }, /* polyself */
-#ifdef PORT_DEBUG
-    { (char *) 0, (char *) 0, donull, TRUE }, /* portdebug */
-#endif
-    { (char *) 0, (char *) 0, donull, TRUE }, /* seenv */
-    { (char *) 0, (char *) 0, donull, TRUE }, /* stats */
-    { (char *) 0, (char *) 0, donull, TRUE }, /* timeout */
-    { (char *) 0, (char *) 0, donull, TRUE }, /* vanquished */
-    { (char *) 0, (char *) 0, donull, TRUE }, /* vision */
-    { (char *) 0, (char *) 0, donull, TRUE }, /* wizsmell */
+#if 0 /*JP*/
+    { '\0', "migratemons", "migrate N random monsters",
+#else
+    { '\0', "migratemons", "\83\89\83\93\83_\83\80\82È\89ö\95¨\82ð\89½\91Ì\82©\88Ú\8fZ\82³\82¹\82é",
+#endif
+            wiz_migrate_mons, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
+#endif
+#if 0 /*JP*/
+    { M('m'), "monster", "use monster's special ability",
+#else
+    { M('m'), "monster", "\89ö\95¨\82Ì\93Á\95Ê\94\\97Í\82ð\8eg\82¤",
+#endif
+            domonability, IFBURIED | AUTOCOMPLETE },
+#if 0 /*JP*/
+    { 'N', "name", "name a monster or an object",
+#else
+    { 'N', "name", "\83A\83C\83e\83\80\82â\95¨\82É\96¼\91O\82ð\82Â\82¯\82é",
+#endif
+            docallcmd, IFBURIED | AUTOCOMPLETE },
+#if 0 /*JP*/
+    { M('o'), "offer", "offer a sacrifice to the gods",
+#else
+    { M('o'), "offer", "\90_\82É\8b\9f\95¨\82ð\95ù\82°\82é",
+#endif
+            dosacrifice, AUTOCOMPLETE },
+    { 'o', "open", "open a door", doopen },
+    { 'O', "options", "show option settings, possibly change them",
+            doset, IFBURIED | GENERALCMD },
+#if 0 /*JP*/
+    { C('o'), "overview", "show a summary of the explored dungeon",
+#else
+    { C('o'), "overview", "\92T\8dõ\82µ\82½\96À\8b{\82Ì\8aT\97v\82ð\95\\8e¦\82·\82é",
+#endif
+            dooverview, IFBURIED | AUTOCOMPLETE },
+#if 0 /*JP*/
+    { '\0', "panic", "test panic routine (fatal to game)",
+#else
+    { '\0', "panic", "\83p\83j\83b\83N\83\8b\81[\83`\83\93\82ð\83e\83X\83g\82·\82é(\92v\96½\93I)",
+#endif
+            wiz_panic, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
+    { 'p', "pay", "pay your shopping bill", dopay },
+    { ',', "pickup", "pick up things at the current location", dopickup },
+#if 0 /*JP*/
+    { '\0', "polyself", "polymorph self",
+#else
+    { '\0', "polyself", "\95Ï\89»\82·\82é",
+#endif
+            wiz_polyself, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
+#if 0 /*JP*/
+    { M('p'), "pray", "pray to the gods for help",
+#else
+    { M('p'), "pray", "\90_\82É\8bF\82é",
+#endif
+            dopray, IFBURIED | AUTOCOMPLETE },
+    { C('p'), "prevmsg", "view recent game messages",
+            doprev_message, IFBURIED | GENERALCMD },
+    { 'P', "puton", "put on an accessory (ring, amulet, etc)", doputon },
+    { 'q', "quaff", "quaff (drink) something", dodrink },
+#if 0 /*JP*/
+    { M('q'), "quit", "exit without saving current game",
+#else
+    { M('q'), "quit", "\83Z\81[\83u\82µ\82È\82¢\82Å\8fI\97¹",
+#endif
+            done2, IFBURIED | AUTOCOMPLETE | GENERALCMD },
+    { 'Q', "quiver", "select ammunition for quiver", dowieldquiver },
+    { 'r', "read", "read a scroll or spellbook", doread },
+    { C('r'), "redraw", "redraw screen", doredraw, IFBURIED | GENERALCMD },
+    { 'R', "remove", "remove an accessory (ring, amulet, etc)", doremring },
+#if 0 /*JP*/
+    { M('R'), "ride", "mount or dismount a saddled steed",
+#else
+    { M('R'), "ride", "\89ö\95¨\82É\8fæ\82é(\82Ü\82½\82Í\8d~\82è\82é)",
+#endif
+            doride, AUTOCOMPLETE },
+#if 0 /*JP*/
+    { M('r'), "rub", "rub a lamp or a stone", dorub, AUTOCOMPLETE },
+#else
+    { M('r'), "rub", "\83\89\83\93\83v\82ð\82±\82·\82é", dorub, AUTOCOMPLETE },
+#endif
+    { 'S', "save", "save the game and exit", dosave, IFBURIED | GENERALCMD },
+#if 0 /*JP*/
+    { 's', "search", "search for traps and secret doors",
+            dosearch, IFBURIED, "searching" },
+#else
+    { 's', "search", "ã©\82â\89B\82µ\94à\82ð\92T\82·",
+            dosearch, IFBURIED, "\92T\82·" },
+#endif
+    { '*', "seeall", "show all equipment in use", doprinuse, IFBURIED },
+    { AMULET_SYM, "seeamulet", "show the amulet currently worn",
+            dopramulet, IFBURIED },
+    { ARMOR_SYM, "seearmor", "show the armor currently worn",
+            doprarm, IFBURIED },
+    { GOLD_SYM, "seegold", "count your gold", doprgold, IFBURIED },
+#if 0 /*JP*/
+    { '\0', "seenv", "show seen vectors",
+#else
+    { '\0', "seenv", "\8e\8b\90ü\83x\83N\83g\83\8b\82ð\8c©\82é",
+#endif
+            wiz_show_seenv, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
+    { RING_SYM, "seerings", "show the ring(s) currently worn",
+            doprring, IFBURIED },
+    { SPBOOK_SYM, "seespells", "list and reorder known spells",
+            dovspell, IFBURIED },
+    { TOOL_SYM, "seetools", "show the tools currently in use",
+            doprtool, IFBURIED },
+    { '^', "seetrap", "show the type of adjacent trap", doidtrap, IFBURIED },
+    { WEAPON_SYM, "seeweapon", "show the weapon currently wielded",
+            doprwep, IFBURIED },
+    { '!', "shell", "do a shell escape",
+            dosh_core, IFBURIED | GENERALCMD
+#ifndef SHELL
+                       | CMD_NOT_AVAILABLE
+#endif /* SHELL */
+    },
+#if 0 /*JP*/
+    { M('s'), "sit", "sit down", dosit, AUTOCOMPLETE },
+#else
+    { M('s'), "sit", "\8dÀ\82é", dosit, AUTOCOMPLETE },
+#endif
+#if 0 /*JP*/
+    { '\0', "stats", "show memory statistics",
+#else
+    { '\0', "stats", "\83\81\83\82\83\8a\8fó\91Ô\82ð\8c©\82é",
+#endif
+            wiz_show_stats, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
+    { C('z'), "suspend", "suspend the game",
+            dosuspend_core, IFBURIED | GENERALCMD
+#ifndef SUSPEND
+                            | CMD_NOT_AVAILABLE
+#endif /* SUSPEND */
+    },
+    { 'x', "swap", "swap wielded and secondary weapons", doswapweapon },
+    { 'T', "takeoff", "take off one piece of armor", dotakeoff },
+    { 'A', "takeoffall", "remove all armor", doddoremarm },
+    { C('t'), "teleport", "teleport around the level", dotelecmd, IFBURIED },
+#if 0 /*JP*/
+    { '\0', "terrain", "show map without obstructions",
+#else
+    { '\0', "terrain", "\8e×\96\82\82³\82ê\82¸\82É\92n\90}\82ð\8c©\82é",
+#endif
+            doterrain, IFBURIED | AUTOCOMPLETE },
+    { '\0', "therecmdmenu",
+            "menu of commands you can do from here to adjacent spot",
+            dotherecmdmenu },
+    { 't', "throw", "throw something", dothrow },
+#if 0 /*JP*/
+    { '\0', "timeout", "look at timeout queue and hero's timed intrinsics",
+#else
+    { '\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é",
+#endif
+            wiz_timeout_queue, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
+#if 0 /*JP*/
+    { M('T'), "tip", "empty a container", dotip, AUTOCOMPLETE },
+#else
+    { M('T'), "tip", "\93ü\82ê\95¨\82ð\8bó\82É\82·\82é", dotip, AUTOCOMPLETE },
+#endif
+    { '_', "travel", "travel to a specific location on the map", dotravel },
+#if 0 /*JP*/
+    { M('t'), "turn", "turn undead away", doturn, IFBURIED | AUTOCOMPLETE },
+#else
+    { M('t'), "turn", "\83A\83\93\83f\83b\83g\82ð\93y\82É\95Ô\82·", doturn, IFBURIED | AUTOCOMPLETE },
+#endif
+#if 0 /*JP*/
+    { 'X', "twoweapon", "toggle two-weapon combat",
+#else
+    { 'X', "twoweapon", "\97¼\8eè\8e\9d\82¿\82Ì\90Ø\82è\91Ö\82¦",
+#endif
+            dotwoweapon, AUTOCOMPLETE },
+#if 0 /*JP*/
+    { M('u'), "untrap", "untrap something", dountrap, AUTOCOMPLETE },
+#else
+    { M('u'), "untrap", "ã©\82ð\82Í\82¸\82·", dountrap, AUTOCOMPLETE },
+#endif
+    { '<', "up", "go up a staircase", doup },
+#if 0 /*JP*/
+    { '\0', "vanquished", "list vanquished monsters",
+#else
+    { '\0', "vanquished", "\93|\82µ\82½\89ö\95¨\82Ì\88ê\97\97\82ð\8c©\82é",
+#endif
+            dovanquished, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
+    { M('v'), "version",
+#if 0 /*JP*/
+            "list compile time options for this version of NetHack",
+#else
+            "\83R\83\93\83p\83C\83\8b\8e\9e\82Ì\83I\83v\83V\83\87\83\93\82ð\95\\8e¦\82·\82é",
+#endif
+            doextversion, IFBURIED | AUTOCOMPLETE | GENERALCMD },
+    { 'v', "versionshort", "show version", doversion, IFBURIED | GENERALCMD },
+#if 0 /*JP*/
+    { '\0', "vision", "show vision array",
+#else
+    { '\0', "vision", "\8e\8b\8aE\94z\97ñ\82ð\8c©\82é",
+#endif
+            wiz_show_vision, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
+#if 0 /*JP*/
+    { '.', "wait", "rest one move while doing nothing",
+            donull, IFBURIED, "waiting" },
+#else
+    { '.', "wait", "\88ê\95à\95ª\89½\82à\82µ\82È\82¢",
+            donull, IFBURIED, "\8bx\8ce\82·\82é" },
+#endif
+    { 'W', "wear", "wear a piece of armor", dowear },
+    { '&', "whatdoes", "tell what a command does", dowhatdoes, IFBURIED },
+    { '/', "whatis", "show what type of thing a symbol corresponds to",
+            dowhatis, IFBURIED | GENERALCMD },
+    { 'w', "wield", "wield (put in use) a weapon", dowield },
+#if 0 /*JP*/
+    { M('w'), "wipe", "wipe off your face", dowipe, AUTOCOMPLETE },
+#else
+    { M('w'), "wipe", "\8aç\82ð\90@\82¤", dowipe, AUTOCOMPLETE },
+#endif
 #ifdef DEBUG
-    { (char *) 0, (char *) 0, donull, TRUE }, /* wizdebug_traveldisplay */
-    { (char *) 0, (char *) 0, donull, TRUE }, /* wizdebug_bury */
+#if 0 /*JP*/
+    { '\0', "wizbury", "bury objs under and around you",
+#else
+    { '\0', "wizbury", "\95¨\82ð\82 \82È\82½\82Ì\8eü\82è\82É\96\84\82ß\82é",
+#endif
+            wiz_debug_cmd_bury, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
+#endif
+    { C('e'), "wizdetect", "reveal hidden things within a small radius",
+            wiz_detect, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
+    { C('g'), "wizgenesis", "create a monster",
+            wiz_genesis, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
+    { C('i'), "wizidentify", "identify all items in inventory",
+            wiz_identify, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
+    { '\0', "wizintrinsic", "set an intrinsic",
+            wiz_intrinsic, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
+    { C('v'), "wizlevelport", "teleport to another level",
+            wiz_level_tele, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
+    { '\0', "wizmakemap", "recreate the current level",
+            wiz_makemap, IFBURIED | WIZMODECMD },
+    { C('f'), "wizmap", "map the level",
+            wiz_map, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
+#if 0 /*JP*/
+    { '\0', "wizrumorcheck", "verify rumor boundaries",
+#else
+    { '\0', "wizrumorcheck", "\89\\82Ì\8b«\8aE\82ð\8c\9f\8fØ\82·\82é",
 #endif
-    { (char *) 0, (char *) 0, donull, TRUE }, /* wizrumorcheck */
-    { (char *) 0, (char *) 0, donull, TRUE }, /* wmode */
-    { (char *) 0, (char *) 0, donull, TRUE }  /* sentinel */
+            wiz_rumor_check, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
+#if 0 /*JP*/
+    { '\0', "wizsmell", "smell monster",
+#else
+    { '\0', "wizsmell", "\89ö\95¨\82Ì\93õ\82¢\82ð\9ak\82®",
+#endif
+            wiz_smell, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
+    { '\0', "wizwhere", "show locations of special levels",
+            wiz_where, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
+    { C('w'), "wizwish", "wish for something",
+            wiz_wish, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
+#if 0 /*JP*/
+    { '\0', "wmode", "show wall modes",
+#else
+    { '\0', "wmode", "\95Ç\83\82\81[\83h\82ð\8c©\82é",
+#endif
+            wiz_show_wmodes, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
+    { 'z', "zap", "zap a wand", dozap },
+    { '\0', (char *) 0, (char *) 0, donull, 0, (char *) 0 } /* sentinel */
 };
 
-/* there must be a placeholder in the table above for every entry here */
-static const struct ext_func_tab debug_extcmdlist[] = {
-    { "levelchange", "change experience level", wiz_level_change, TRUE },
-    { "lightsources", "show mobile light sources", wiz_light_sources, TRUE },
-#ifdef DEBUG_MIGRATING_MONS
-    { "migratemons", "migrate n random monsters", wiz_migrate_mons, TRUE },
-#endif
-    { "monpolycontrol", "control monster polymorphs", wiz_mon_polycontrol,
-      TRUE },
-    { "panic", "test panic routine (fatal to game)", wiz_panic, TRUE },
-    { "polyself", "polymorph self", wiz_polyself, TRUE },
-#ifdef PORT_DEBUG
-    { "portdebug", "wizard port debug command", wiz_port_debug, TRUE },
-#endif
-    { "seenv", "show seen vectors", wiz_show_seenv, TRUE },
-    { "stats", "show memory statistics", wiz_show_stats, TRUE },
-    { "timeout", "look at timeout queue", wiz_timeout_queue, TRUE },
-    { "vanquished", "list vanquished monsters", dovanquished, TRUE },
-    { "vision", "show vision array", wiz_show_vision, TRUE },
-    { "wizsmell", "smell monster", wiz_smell, TRUE },
-#ifdef DEBUG
-    { "wizdebug_traveldisplay", "wizard debug: toggle travel display",
-      wiz_debug_cmd_traveldisplay, TRUE },
-    { "wizdebug_bury", "wizard debug: bury objs under and around you",
-      wiz_debug_cmd_bury, TRUE },
-#endif
-    { "wizrumorcheck", "verify rumor boundaries", wiz_rumor_check, TRUE },
-    { "wmode", "show wall modes", wiz_show_wmodes, TRUE },
-    { (char *) 0, (char *) 0, donull, TRUE }
-};
+int extcmdlist_length = SIZE(extcmdlist) - 1;
 
-/*
- * Insert debug commands into the extended command list.  This function
- * assumes that the last entry will be the help entry.
- *
- * You must add entries in ext_func_tab every time you add one to the
- * debug_extcmdlist().
- */
+const char *
+key2extcmddesc(key)
+uchar key;
+{
+    if (Cmd.commands[key] && Cmd.commands[key]->ef_txt)
+        return Cmd.commands[key]->ef_desc;
+    return (char *) 0;
+}
+
+boolean
+bind_key(key, command)
+uchar key;
+const char *command;
+{
+    struct ext_func_tab *extcmd;
+
+    /* special case: "nothing" is reserved for unbinding */
+    if (!strcmp(command, "nothing")) {
+        Cmd.commands[key] = (struct ext_func_tab *) 0;
+        return TRUE;
+    }
+
+    for (extcmd = extcmdlist; extcmd->ef_txt; extcmd++) {
+        if (strcmp(command, extcmd->ef_txt))
+            continue;
+        Cmd.commands[key] = extcmd;
+#if 0 /* silently accept key binding for unavailable command (!SHELL,&c) */
+        if ((extcmd->flags & CMD_NOT_AVAILABLE) != 0) {
+            char buf[BUFSZ];
+
+            Sprintf(buf, cmdnotavail, extcmd->ef_txt);
+            config_error_add("%s", buf);
+        }
+#endif
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+/* initialize all keyboard commands */
 void
-add_debug_extended_commands()
+commands_init()
 {
-    int i, j, k, n;
-
-    /* count the # of help entries */
-    for (n = 0; extcmdlist[n].ef_txt[0] != '?'; n++)
-        ;
-
-    for (i = 0; debug_extcmdlist[i].ef_txt; i++) {
-        /* need enough room for "?" entry plus terminator */
-        if (n + 2 >= SIZE(extcmdlist))
-            panic("Too many debugging commands!");
-        for (j = 0; j < n; j++)
-            if (strcmp(debug_extcmdlist[i].ef_txt, extcmdlist[j].ef_txt) < 0)
-                break;
+    struct ext_func_tab *extcmd;
+
+    for (extcmd = extcmdlist; extcmd->ef_txt; extcmd++)
+        if (extcmd->key)
+            Cmd.commands[extcmd->key] = extcmd;
+
+    (void) bind_key(C('l'), "redraw"); /* if number_pad is set */
+    /*       'b', 'B' : go sw */
+    /*       'F' : fight (one time) */
+    /*       'g', 'G' : multiple go */
+    /*       'h', 'H' : go west */
+    (void) bind_key('h',    "help"); /* if number_pad is set */
+    (void) bind_key('j',    "jump"); /* if number_pad is on */
+    /*       'j', 'J', 'k', 'K', 'l', 'L', 'm', 'M', 'n', 'N' move commands */
+    (void) bind_key('k',    "kick"); /* if number_pad is on */
+    (void) bind_key('l',    "loot"); /* if number_pad is on */
+    (void) bind_key(C('n'), "annotate"); /* if number_pad is on */
+    (void) bind_key(M('n'), "name");
+    (void) bind_key(M('N'), "name");
+    (void) bind_key('u',    "untrap"); /* if number_pad is on */
+
+    /* alt keys: */
+    (void) bind_key(M('O'), "overview");
+    (void) bind_key(M('2'), "twoweapon");
+
+    /* wait_on_space */
+    (void) bind_key(' ',    "wait");
+}
+
+int
+dokeylist_putcmds(datawin, docount, cmdflags, exflags, keys_used)
+winid datawin;
+boolean docount;
+int cmdflags, exflags;
+boolean *keys_used; /* boolean keys_used[256] */
+{
+    int i;
+    char buf[BUFSZ];
+    char buf2[QBUFSZ];
+    int count = 0;
+
+    for (i = 0; i < 256; i++) {
+        const struct ext_func_tab *extcmd;
+        uchar key = (uchar) i;
 
-        /* insert i'th debug entry into extcmdlist[j], pushing down  */
-        for (k = n; k >= j; --k)
-            extcmdlist[k + 1] = extcmdlist[k];
-        extcmdlist[j] = debug_extcmdlist[i];
-        n++; /* now an extra entry */
+        if (keys_used[i])
+            continue;
+        if (key == ' ' && !flags.rest_on_space)
+            continue;
+        if ((extcmd = Cmd.commands[i]) != (struct ext_func_tab *) 0) {
+            if ((cmdflags && !(extcmd->flags & cmdflags))
+                || (exflags && (extcmd->flags & exflags)))
+                continue;
+            if (docount) {
+                count++;
+                continue;
+            }
+            Sprintf(buf, "%-8s %-12s %s", key2txt(key, buf2),
+                    extcmd->ef_txt,
+                    extcmd->ef_desc);
+            putstr(datawin, 0, buf);
+            keys_used[i] = TRUE;
+        }
     }
+    return count;
 }
 
-STATIC_OVL char
+/* list all keys and their bindings, like dat/hh but dynamic */
+void
+dokeylist(VOID_ARGS)
+{
+    char buf[BUFSZ], buf2[BUFSZ];
+    uchar key;
+    boolean keys_used[256] = {0};
+    winid datawin;
+    int i;
+    static const char
+        run_desc[] = "Prefix: run until something very interesting is seen",
+        forcefight_desc[] =
+                     "Prefix: force fight even if you don't see a monster";
+    static const struct {
+        int nhkf;
+        const char *desc;
+        boolean numpad;
+    } misc_keys[] = {
+        { NHKF_ESC, "escape from the current query/action", FALSE },
+        { NHKF_RUSH,
+          "Prefix: rush until something interesting is seen", FALSE },
+        { NHKF_RUN, run_desc, FALSE },
+        { NHKF_RUN2, run_desc, TRUE },
+        { NHKF_FIGHT, forcefight_desc, FALSE },
+        { NHKF_FIGHT2, forcefight_desc, TRUE } ,
+        { NHKF_NOPICKUP,
+          "Prefix: move without picking up objects/fighting", FALSE },
+        { NHKF_RUN_NOPICKUP,
+          "Prefix: run without picking up objects/fighting", FALSE },
+        { NHKF_DOINV, "view inventory", TRUE },
+        { NHKF_REQMENU, "Prefix: request a menu", FALSE },
+#ifdef REDO
+        { NHKF_DOAGAIN , "re-do: perform the previous command again", FALSE },
+#endif
+        { 0, (const char *) 0, FALSE }
+    };
+
+    datawin = create_nhwindow(NHW_TEXT);
+    putstr(datawin, 0, "");
+    putstr(datawin, 0, "            Full Current Key Bindings List");
+
+    /* directional keys */
+    putstr(datawin, 0, "");
+    putstr(datawin, 0, "Directional keys:");
+    show_direction_keys(datawin, '.', FALSE); /* '.'==self in direction grid */
+
+    keys_used[(uchar) Cmd.move_NW] = keys_used[(uchar) Cmd.move_N]
+        = keys_used[(uchar) Cmd.move_NE] = keys_used[(uchar) Cmd.move_W]
+        = keys_used[(uchar) Cmd.move_E] = keys_used[(uchar) Cmd.move_SW]
+        = keys_used[(uchar) Cmd.move_S] = keys_used[(uchar) Cmd.move_SE]
+        = TRUE;
+
+    if (!iflags.num_pad) {
+        keys_used[(uchar) highc(Cmd.move_NW)]
+            = keys_used[(uchar) highc(Cmd.move_N)]
+            = keys_used[(uchar) highc(Cmd.move_NE)]
+            = keys_used[(uchar) highc(Cmd.move_W)]
+            = keys_used[(uchar) highc(Cmd.move_E)]
+            = keys_used[(uchar) highc(Cmd.move_SW)]
+            = keys_used[(uchar) highc(Cmd.move_S)]
+            = keys_used[(uchar) highc(Cmd.move_SE)] = TRUE;
+        keys_used[(uchar) C(Cmd.move_NW)]
+            = keys_used[(uchar) C(Cmd.move_N)]
+            = keys_used[(uchar) C(Cmd.move_NE)]
+            = keys_used[(uchar) C(Cmd.move_W)]
+            = keys_used[(uchar) C(Cmd.move_E)]
+            = keys_used[(uchar) C(Cmd.move_SW)]
+            = keys_used[(uchar) C(Cmd.move_S)]
+            = keys_used[(uchar) C(Cmd.move_SE)] = TRUE;
+        putstr(datawin, 0, "");
+        putstr(datawin, 0,
+          "Shift-<direction> will move in specified direction until you hit");
+        putstr(datawin, 0, "        a wall or run into something.");
+        putstr(datawin, 0,
+          "Ctrl-<direction> will run in specified direction until something");
+        putstr(datawin, 0, "        very interesting is seen.");
+    }
+
+    putstr(datawin, 0, "");
+    putstr(datawin, 0, "Miscellaneous keys:");
+    for (i = 0; misc_keys[i].desc; i++) {
+        key = Cmd.spkeys[misc_keys[i].nhkf];
+        if (key && ((misc_keys[i].numpad && iflags.num_pad)
+                    || !misc_keys[i].numpad)) {
+            keys_used[(uchar) key] = TRUE;
+            Sprintf(buf, "%-8s %s", key2txt(key, buf2), misc_keys[i].desc);
+            putstr(datawin, 0, buf);
+        }
+    }
+#ifndef NO_SIGNAL
+    putstr(datawin, 0, "^c       break out of NetHack (SIGINT)");
+    keys_used[(uchar) C('c')] = TRUE;
+#endif
+
+    putstr(datawin, 0, "");
+    show_menu_controls(datawin, TRUE);
+
+    if (dokeylist_putcmds(datawin, TRUE, GENERALCMD, WIZMODECMD, keys_used)) {
+        putstr(datawin, 0, "");
+        putstr(datawin, 0, "General commands:");
+        (void) dokeylist_putcmds(datawin, FALSE, GENERALCMD, WIZMODECMD,
+                                 keys_used);
+    }
+
+    if (dokeylist_putcmds(datawin, TRUE, 0, WIZMODECMD, keys_used)) {
+        putstr(datawin, 0, "");
+        putstr(datawin, 0, "Game commands:");
+        (void) dokeylist_putcmds(datawin, FALSE, 0, WIZMODECMD, keys_used);
+    }
+
+    if (wizard
+        && dokeylist_putcmds(datawin, TRUE, WIZMODECMD, 0, keys_used)) {
+        putstr(datawin, 0, "");
+        putstr(datawin, 0, "Wizard-mode commands:");
+        (void) dokeylist_putcmds(datawin, FALSE, WIZMODECMD, 0, keys_used);
+    }
+
+    display_nhwindow(datawin, FALSE);
+    destroy_nhwindow(datawin);
+}
+
+char
 cmd_from_func(fn)
 int NDECL((*fn));
 {
     int i;
-    for (i = 0; i < SIZE(cmdlist); ++i)
-        if (cmdlist[i].f_funct == fn)
-            return cmdlist[i].f_char;
-    return 0;
+
+    for (i = 0; i < 256; ++i)
+        if (Cmd.commands[i] && Cmd.commands[i]->ef_funct == fn)
+            return (char) i;
+    return '\0';
 }
 
-static const char template[] = "%-18s %4ld  %6ld";
-static const char count_str[] = "                   count  bytes";
-static const char separator[] = "------------------ -----  ------";
+/*
+ * wizard mode sanity_check code
+ */
+
+static const char template[] = "%-27s  %4ld  %6ld";
+static const char stats_hdr[] = "                             count  bytes";
+static const char stats_sep[] = "---------------------------  ----- -------";
 
 STATIC_OVL int
 size_obj(otmp)
 struct obj *otmp;
 {
-    int sz = (int) sizeof(struct obj);
+    int sz = (int) sizeof (struct obj);
 
     if (otmp->oextra) {
-        sz += (int) sizeof(struct oextra);
+        sz += (int) sizeof (struct oextra);
         if (ONAME(otmp))
             sz += (int) strlen(ONAME(otmp)) + 1;
         if (OMONST(otmp))
-            sz += (int) sizeof(struct monst);
+            sz += size_monst(OMONST(otmp), FALSE);
         if (OMID(otmp))
-            sz += (int) sizeof(unsigned);
+            sz += (int) sizeof (unsigned);
         if (OLONG(otmp))
-            sz += (int) sizeof(long);
+            sz += (int) sizeof (long);
         if (OMAILCMD(otmp))
             sz += (int) strlen(OMAILCMD(otmp)) + 1;
     }
@@ -2901,21 +5088,25 @@ boolean recurse;
 }
 
 STATIC_OVL void
-obj_chain(win, src, chain, total_count, total_size)
+obj_chain(win, src, chain, force, total_count, total_size)
 winid win;
 const char *src;
 struct obj *chain;
+boolean force;
 long *total_count;
 long *total_size;
 {
     char buf[BUFSZ];
-    long count = 0, size = 0;
+    long count = 0L, size = 0L;
 
     count_obj(chain, &count, &size, TRUE, FALSE);
-    *total_count += count;
-    *total_size += size;
-    Sprintf(buf, template, src, count, size);
-    putstr(win, 0, buf);
+
+    if (count || size || force) {
+        *total_count += count;
+        *total_size += size;
+        Sprintf(buf, template, src, count, size);
+        putstr(win, 0, buf);
+    }
 }
 
 STATIC_OVL void
@@ -2932,14 +5123,17 @@ long *total_size;
 
     for (mon = chain; mon; mon = mon->nmon)
         count_obj(mon->minvent, &count, &size, TRUE, FALSE);
-    *total_count += count;
-    *total_size += size;
-    Sprintf(buf, template, src, count, size);
-    putstr(win, 0, buf);
+
+    if (count || size) {
+        *total_count += count;
+        *total_size += size;
+        Sprintf(buf, template, src, count, size);
+        putstr(win, 0, buf);
+    }
 }
 
 STATIC_OVL void
-contained(win, src, total_count, total_size)
+contained_stats(win, src, total_count, total_size)
 winid win;
 const char *src;
 long *total_count;
@@ -2960,58 +5154,188 @@ long *total_size;
     for (mon = migrating_mons; mon; mon = mon->nmon)
         count_obj(mon->minvent, &count, &size, FALSE, TRUE);
 
-    *total_count += count;
-    *total_size += size;
-
-    Sprintf(buf, template, src, count, size);
-    putstr(win, 0, buf);
+    if (count || size) {
+        *total_count += count;
+        *total_size += size;
+        Sprintf(buf, template, src, count, size);
+        putstr(win, 0, buf);
+    }
 }
 
 STATIC_OVL int
-size_monst(mtmp)
+size_monst(mtmp, incl_wsegs)
 struct monst *mtmp;
+boolean incl_wsegs;
 {
-    int sz = (int) sizeof(struct monst);
+    int sz = (int) sizeof (struct monst);
+
+    if (mtmp->wormno && incl_wsegs)
+        sz += size_wseg(mtmp);
 
     if (mtmp->mextra) {
-        sz += (int) sizeof(struct mextra);
+        sz += (int) sizeof (struct mextra);
         if (MNAME(mtmp))
             sz += (int) strlen(MNAME(mtmp)) + 1;
         if (EGD(mtmp))
-            sz += (int) sizeof(struct egd);
+            sz += (int) sizeof (struct egd);
         if (EPRI(mtmp))
-            sz += (int) sizeof(struct epri);
+            sz += (int) sizeof (struct epri);
         if (ESHK(mtmp))
-            sz += (int) sizeof(struct eshk);
+            sz += (int) sizeof (struct eshk);
         if (EMIN(mtmp))
-            sz += (int) sizeof(struct emin);
+            sz += (int) sizeof (struct emin);
         if (EDOG(mtmp))
-            sz += (int) sizeof(struct edog);
+            sz += (int) sizeof (struct edog);
         /* mextra->mcorpsenm doesn't point to more memory */
     }
     return sz;
 }
 
 STATIC_OVL void
-mon_chain(win, src, chain, total_count, total_size)
+mon_chain(win, src, chain, force, total_count, total_size)
 winid win;
 const char *src;
 struct monst *chain;
+boolean force;
 long *total_count;
 long *total_size;
 {
     char buf[BUFSZ];
     long count, size;
     struct monst *mon;
+    /* mon->wormno means something different for migrating_mons and mydogs */
+    boolean incl_wsegs = !strcmpi(src, "fmon");
 
-    for (count = size = 0, mon = chain; mon; mon = mon->nmon) {
+    count = size = 0L;
+    for (mon = chain; mon; mon = mon->nmon) {
         count++;
-        size += size_monst(mon);
+        size += size_monst(mon, incl_wsegs);
+    }
+    if (count || size || force) {
+        *total_count += count;
+        *total_size += size;
+        Sprintf(buf, template, src, count, size);
+        putstr(win, 0, buf);
+    }
+}
+
+STATIC_OVL void
+misc_stats(win, total_count, total_size)
+winid win;
+long *total_count;
+long *total_size;
+{
+    char buf[BUFSZ], hdrbuf[QBUFSZ];
+    long count, size;
+    int idx;
+    struct trap *tt;
+    struct damage *sd; /* shop damage */
+    struct kinfo *k; /* delayed killer */
+    struct cemetery *bi; /* bones info */
+
+    /* traps and engravings are output unconditionally;
+     * others only if nonzero
+     */
+    count = size = 0L;
+    for (tt = ftrap; tt; tt = tt->ntrap) {
+        ++count;
+        size += (long) sizeof *tt;
     }
     *total_count += count;
     *total_size += size;
-    Sprintf(buf, template, src, count, size);
+    Sprintf(hdrbuf, "traps, size %ld", (long) sizeof (struct trap));
+    Sprintf(buf, template, hdrbuf, count, size);
+    putstr(win, 0, buf);
+
+    count = size = 0L;
+    engr_stats("engravings, size %ld+text", hdrbuf, &count, &size);
+    *total_count += count;
+    *total_size += size;
+    Sprintf(buf, template, hdrbuf, count, size);
     putstr(win, 0, buf);
+
+    count = size = 0L;
+    light_stats("light sources, size %ld", hdrbuf, &count, &size);
+    if (count || size) {
+        *total_count += count;
+        *total_size += size;
+        Sprintf(buf, template, hdrbuf, count, size);
+        putstr(win, 0, buf);
+    }
+
+    count = size = 0L;
+    timer_stats("timers, size %ld", hdrbuf, &count, &size);
+    if (count || size) {
+        *total_count += count;
+        *total_size += size;
+        Sprintf(buf, template, hdrbuf, count, size);
+        putstr(win, 0, buf);
+    }
+
+    count = size = 0L;
+    for (sd = level.damagelist; sd; sd = sd->next) {
+        ++count;
+        size += (long) sizeof *sd;
+    }
+    if (count || size) {
+        *total_count += count;
+        *total_size += size;
+        Sprintf(hdrbuf, "shop damage, size %ld",
+                (long) sizeof (struct damage));
+        Sprintf(buf, template, hdrbuf, count, size);
+        putstr(win, 0, buf);
+    }
+
+    count = size = 0L;
+    region_stats("regions, size %ld+%ld*rect+N", hdrbuf, &count, &size);
+    if (count || size) {
+        *total_count += count;
+        *total_size += size;
+        Sprintf(buf, template, hdrbuf, count, size);
+        putstr(win, 0, buf);
+    }
+
+    count = size = 0L;
+    for (k = killer.next; k; k = k->next) {
+        ++count;
+        size += (long) sizeof *k;
+    }
+    if (count || size) {
+        *total_count += count;
+        *total_size += size;
+        Sprintf(hdrbuf, "delayed killer%s, size %ld",
+                plur(count), (long) sizeof (struct kinfo));
+        Sprintf(buf, template, hdrbuf, count, size);
+        putstr(win, 0, buf);
+    }
+
+    count = size = 0L;
+    for (bi = level.bonesinfo; bi; bi = bi->next) {
+        ++count;
+        size += (long) sizeof *bi;
+    }
+    if (count || size) {
+        *total_count += count;
+        *total_size += size;
+        Sprintf(hdrbuf, "bones history, size %ld",
+                (long) sizeof (struct cemetery));
+        Sprintf(buf, template, hdrbuf, count, size);
+        putstr(win, 0, buf);
+    }
+
+    count = size = 0L;
+    for (idx = 0; idx < NUM_OBJECTS; ++idx)
+        if (objects[idx].oc_uname) {
+            ++count;
+            size += (long) (strlen(objects[idx].oc_uname) + 1);
+        }
+    if (count || size) {
+        *total_count += count;
+        *total_size += size;
+        Strcpy(hdrbuf, "object type names, text");
+        Sprintf(buf, template, hdrbuf, count, size);
+        putstr(win, 0, buf);
+    }
 }
 
 /*
@@ -3022,45 +5346,73 @@ wiz_show_stats()
 {
     char buf[BUFSZ];
     winid win;
-    long total_obj_size = 0, total_obj_count = 0;
-    long total_mon_size = 0, total_mon_count = 0;
+    long total_obj_size, total_obj_count,
+         total_mon_size, total_mon_count,
+         total_ovr_size, total_ovr_count,
+         total_misc_size, total_misc_count;
 
     win = create_nhwindow(NHW_TEXT);
     putstr(win, 0, "Current memory statistics:");
-    putstr(win, 0, "");
-    Sprintf(buf, "Objects, size %d", (int) sizeof(struct obj));
+
+    total_obj_count = total_obj_size = 0L;
+    putstr(win, 0, stats_hdr);
+    Sprintf(buf, "  Objects, base size %ld", (long) sizeof (struct obj));
     putstr(win, 0, buf);
-    putstr(win, 0, "");
-    putstr(win, 0, count_str);
-
-    obj_chain(win, "invent", invent, &total_obj_count, &total_obj_size);
-    obj_chain(win, "fobj", fobj, &total_obj_count, &total_obj_size);
-    obj_chain(win, "buried", level.buriedobjlist, &total_obj_count,
-              &total_obj_size);
-    obj_chain(win, "migrating obj", migrating_objs, &total_obj_count,
-              &total_obj_size);
+    obj_chain(win, "invent", invent, TRUE, &total_obj_count, &total_obj_size);
+    obj_chain(win, "fobj", fobj, TRUE, &total_obj_count, &total_obj_size);
+    obj_chain(win, "buried", level.buriedobjlist, FALSE,
+              &total_obj_count, &total_obj_size);
+    obj_chain(win, "migrating obj", migrating_objs, FALSE,
+              &total_obj_count, &total_obj_size);
+    obj_chain(win, "billobjs", billobjs, FALSE,
+              &total_obj_count, &total_obj_size);
     mon_invent_chain(win, "minvent", fmon, &total_obj_count, &total_obj_size);
     mon_invent_chain(win, "migrating minvent", migrating_mons,
                      &total_obj_count, &total_obj_size);
-
-    contained(win, "contained", &total_obj_count, &total_obj_size);
-
-    putstr(win, 0, separator);
-    Sprintf(buf, template, "Total", total_obj_count, total_obj_size);
+    contained_stats(win, "contained", &total_obj_count, &total_obj_size);
+    putstr(win, 0, stats_sep);
+    Sprintf(buf, template, "  Obj total", total_obj_count, total_obj_size);
     putstr(win, 0, buf);
 
+    total_mon_count = total_mon_size = 0L;
     putstr(win, 0, "");
-    putstr(win, 0, "");
-    Sprintf(buf, "Monsters, size %d", (int) sizeof(struct monst));
+    Sprintf(buf, "  Monsters, base size %ld", (long) sizeof (struct monst));
+    putstr(win, 0, buf);
+    mon_chain(win, "fmon", fmon, TRUE, &total_mon_count, &total_mon_size);
+    mon_chain(win, "migrating", migrating_mons, FALSE,
+              &total_mon_count, &total_mon_size);
+    /* 'mydogs' is only valid during level change or end of game disclosure,
+       but conceivably we've been called from within debugger at such time */
+    if (mydogs) /* monsters accompanying hero */
+        mon_chain(win, "mydogs", mydogs, FALSE,
+                  &total_mon_count, &total_mon_size);
+    putstr(win, 0, stats_sep);
+    Sprintf(buf, template, "  Mon total", total_mon_count, total_mon_size);
     putstr(win, 0, buf);
+
+    total_ovr_count = total_ovr_size = 0L;
     putstr(win, 0, "");
+    putstr(win, 0, "  Overview");
+    overview_stats(win, template, &total_ovr_count, &total_ovr_size);
+    putstr(win, 0, stats_sep);
+    Sprintf(buf, template, "  Over total", total_ovr_count, total_ovr_size);
+    putstr(win, 0, buf);
 
-    mon_chain(win, "fmon", fmon, &total_mon_count, &total_mon_size);
-    mon_chain(win, "migrating", migrating_mons, &total_mon_count,
-              &total_mon_size);
+    total_misc_count = total_misc_size = 0L;
+    putstr(win, 0, "");
+    putstr(win, 0, "  Miscellaneous");
+    misc_stats(win, &total_misc_count, &total_misc_size);
+    putstr(win, 0, stats_sep);
+    Sprintf(buf, template, "  Misc total", total_misc_count, total_misc_size);
+    putstr(win, 0, buf);
 
-    putstr(win, 0, separator);
-    Sprintf(buf, template, "Total", total_mon_count, total_mon_size);
+    putstr(win, 0, "");
+    putstr(win, 0, stats_sep);
+    Sprintf(buf, template, "  Grand total",
+            (total_obj_count + total_mon_count
+             + total_ovr_count + total_misc_count),
+            (total_obj_size + total_mon_size
+             + total_ovr_size + total_misc_size));
     putstr(win, 0, buf);
 
 #if defined(__BORLANDC__) && !defined(_WIN32)
@@ -3079,6 +5431,7 @@ sanity_check()
     timer_sanity_check();
     mon_sanity_check();
     light_sources_sanity_check();
+    bc_sanity_check();
 }
 
 #ifdef DEBUG_MIGRATING_MONS
@@ -3086,7 +5439,7 @@ static int
 wiz_migrate_mons()
 {
     int mcount = 0;
-    char inbuf[BUFSZ];
+    char inbuf[BUFSZ] = DUMMY;
     struct permonst *ptr;
     struct monst *mtmp;
     d_level tolevel;
@@ -3116,6 +5469,199 @@ wiz_migrate_mons()
 #define unctrl(c) ((c) <= C('z') ? (0x60 | (c)) : (c))
 #define unmeta(c) (0x7f & (c))
 
+struct {
+    int nhkf;
+    char key;
+    const char *name;
+} const spkeys_binds[] = {
+    { NHKF_ESC,              '\033', (char *) 0 }, /* no binding */
+    { NHKF_DOAGAIN,          DOAGAIN, "repeat" },
+    { NHKF_REQMENU,          'm', "reqmenu" },
+    { NHKF_RUN,              'G', "run" },
+    { NHKF_RUN2,             '5', "run.numpad" },
+    { NHKF_RUSH,             'g', "rush" },
+    { NHKF_FIGHT,            'F', "fight" },
+    { NHKF_FIGHT2,           '-', "fight.numpad" },
+    { NHKF_NOPICKUP,         'm', "nopickup" },
+    { NHKF_RUN_NOPICKUP,     'M', "run.nopickup" },
+    { NHKF_DOINV,            '0', "doinv" },
+    { NHKF_TRAVEL,           CMD_TRAVEL, (char *) 0 }, /* no binding */
+    { NHKF_CLICKLOOK,        CMD_CLICKLOOK, (char *) 0 }, /* no binding */
+    { NHKF_REDRAW,           C('r'), "redraw" },
+    { NHKF_REDRAW2,          C('l'), "redraw.numpad" },
+    { NHKF_GETDIR_SELF,      '.', "getdir.self" },
+    { NHKF_GETDIR_SELF2,     's', "getdir.self2" },
+    { NHKF_GETDIR_HELP,      '?', "getdir.help" },
+    { NHKF_COUNT,            'n', "count" },
+    { NHKF_GETPOS_SELF,      '@', "getpos.self" },
+    { NHKF_GETPOS_PICK,      '.', "getpos.pick" },
+    { NHKF_GETPOS_PICK_Q,    ',', "getpos.pick.quick" },
+    { NHKF_GETPOS_PICK_O,    ';', "getpos.pick.once" },
+    { NHKF_GETPOS_PICK_V,    ':', "getpos.pick.verbose" },
+    { NHKF_GETPOS_SHOWVALID, '$', "getpos.valid" },
+    { NHKF_GETPOS_AUTODESC,  '#', "getpos.autodescribe" },
+    { NHKF_GETPOS_MON_NEXT,  'm', "getpos.mon.next" },
+    { NHKF_GETPOS_MON_PREV,  'M', "getpos.mon.prev" },
+    { NHKF_GETPOS_OBJ_NEXT,  'o', "getpos.obj.next" },
+    { NHKF_GETPOS_OBJ_PREV,  'O', "getpos.obj.prev" },
+    { NHKF_GETPOS_DOOR_NEXT, 'd', "getpos.door.next" },
+    { NHKF_GETPOS_DOOR_PREV, 'D', "getpos.door.prev" },
+    { NHKF_GETPOS_UNEX_NEXT, 'x', "getpos.unexplored.next" },
+    { NHKF_GETPOS_UNEX_PREV, 'X', "getpos.unexplored.prev" },
+    { NHKF_GETPOS_VALID_NEXT, 'z', "getpos.valid.next" },
+    { NHKF_GETPOS_VALID_PREV, 'Z', "getpos.valid.prev" },
+    { NHKF_GETPOS_INTERESTING_NEXT, 'a', "getpos.all.next" },
+    { NHKF_GETPOS_INTERESTING_PREV, 'A', "getpos.all.prev" },
+    { NHKF_GETPOS_HELP,      '?', "getpos.help" },
+    { NHKF_GETPOS_LIMITVIEW, '"', "getpos.filter" },
+    { NHKF_GETPOS_MOVESKIP,  '*', "getpos.moveskip" },
+    { NHKF_GETPOS_MENU,      '!', "getpos.menu" }
+};
+
+boolean
+bind_specialkey(key, command)
+uchar key;
+const char *command;
+{
+    int i;
+    for (i = 0; i < SIZE(spkeys_binds); i++) {
+        if (!spkeys_binds[i].name || strcmp(command, spkeys_binds[i].name))
+            continue;
+        Cmd.spkeys[spkeys_binds[i].nhkf] = key;
+        return TRUE;
+    }
+    return FALSE;
+}
+
+/* returns a one-byte character from the text (it may massacre the txt
+ * buffer) */
+char
+txt2key(txt)
+char *txt;
+{
+    txt = trimspaces(txt);
+    if (!*txt)
+        return '\0';
+
+    /* simple character */
+    if (!txt[1])
+        return txt[0];
+
+    /* a few special entries */
+    if (!strcmp(txt, "<enter>"))
+        return '\n';
+    if (!strcmp(txt, "<space>"))
+        return ' ';
+    if (!strcmp(txt, "<esc>"))
+        return '\033';
+
+    /* control and meta keys */
+    switch (*txt) {
+    case 'm': /* can be mx, Mx, m-x, M-x */
+    case 'M':
+        txt++;
+        if (*txt == '-' && txt[1])
+            txt++;
+        if (txt[1])
+            return '\0';
+        return M(*txt);
+    case 'c': /* can be cx, Cx, ^x, c-x, C-x, ^-x */
+    case 'C':
+    case '^':
+        txt++;
+        if (*txt == '-' && txt[1])
+            txt++;
+        if (txt[1])
+            return '\0';
+        return C(*txt);
+    }
+
+    /* ascii codes: must be three-digit decimal */
+    if (*txt >= '0' && *txt <= '9') {
+        uchar key = 0;
+        int i;
+
+        for (i = 0; i < 3; i++) {
+            if (txt[i] < '0' || txt[i] > '9')
+                return '\0';
+            key = 10 * key + txt[i] - '0';
+        }
+        return key;
+    }
+
+    return '\0';
+}
+
+/* returns the text for a one-byte encoding;
+ * must be shorter than a tab for proper formatting */
+char *
+key2txt(c, txt)
+uchar c;
+char *txt; /* sufficiently long buffer */
+{
+    /* should probably switch to "SPC", "ESC", "RET"
+       since nethack's documentation uses ESC for <escape> */
+    if (c == ' ')
+        Sprintf(txt, "<space>");
+    else if (c == '\033')
+        Sprintf(txt, "<esc>");
+    else if (c == '\n')
+        Sprintf(txt, "<enter>");
+    else if (c == '\177')
+        Sprintf(txt, "<del>"); /* "<delete>" won't fit */
+    else
+        Strcpy(txt, visctrl((char) c));
+    return txt;
+}
+
+
+void
+parseautocomplete(autocomplete, condition)
+char *autocomplete;
+boolean condition;
+{
+    struct ext_func_tab *efp;
+    register char *autoc;
+
+    /* break off first autocomplete from the rest; parse the rest */
+    if ((autoc = index(autocomplete, ',')) != 0
+        || (autoc = index(autocomplete, ':')) != 0) {
+        *autoc++ = '\0';
+        parseautocomplete(autoc, condition);
+    }
+
+    /* strip leading and trailing white space */
+    autocomplete = trimspaces(autocomplete);
+
+    if (!*autocomplete)
+        return;
+
+    /* take off negation */
+    if (*autocomplete == '!') {
+        /* unlike most options, a leading "no" might actually be a part of
+         * the extended command.  Thus you have to use ! */
+        autocomplete++;
+        autocomplete = trimspaces(autocomplete);
+        condition = !condition;
+    }
+
+    /* find and modify the extended command */
+    for (efp = extcmdlist; efp->ef_txt; efp++) {
+        if (!strcmp(autocomplete, efp->ef_txt)) {
+            if (condition)
+                efp->flags |= AUTOCOMPLETE;
+            else
+                efp->flags &= ~AUTOCOMPLETE;
+            return;
+        }
+    }
+
+    /* not a real extended command */
+    raw_printf("Bad autocomplete: invalid extended command '%s'.",
+               autocomplete);
+    wait_synch();
+}
+
 /* called at startup and after number_pad is twiddled */
 void
 reset_commands(initial)
@@ -3128,26 +5674,35 @@ boolean initial;
     static const int ylist[] = {
         'y', 'Y', C('y'), M('y'), M('Y'), M(C('y'))
     };
-    const struct func_tab *cmdtmp;
+    static struct ext_func_tab *back_dir_cmd[8];
+    const struct ext_func_tab *cmdtmp;
     boolean flagtemp;
     int c, i, updated = 0;
+    static boolean backed_dir_cmd = FALSE;
 
     if (initial) {
         updated = 1;
-        for (i = 0; i < SIZE(cmdlist); i++) {
-            c = cmdlist[i].f_char & 0xff;
-            Cmd.commands[c] = &cmdlist[i];
-        }
         Cmd.num_pad = FALSE;
         Cmd.pcHack_compat = Cmd.phone_layout = Cmd.swap_yz = FALSE;
+        for (i = 0; i < SIZE(spkeys_binds); i++)
+            Cmd.spkeys[spkeys_binds[i].nhkf] = spkeys_binds[i].key;
+        commands_init();
     } else {
+
+        if (backed_dir_cmd) {
+            for (i = 0; i < 8; i++) {
+                Cmd.commands[(uchar) Cmd.dirchars[i]] = back_dir_cmd[i];
+            }
+        }
+
         /* basic num_pad */
         flagtemp = iflags.num_pad;
         if (flagtemp != Cmd.num_pad) {
             Cmd.num_pad = flagtemp;
             ++updated;
         }
-        /* swap_yz mode (only applicable for !num_pad) */
+        /* swap_yz mode (only applicable for !num_pad); intended for
+           QWERTZ keyboard used in Central Europe, particularly Germany */
         flagtemp = (iflags.num_pad_mode & 1) ? !Cmd.num_pad : FALSE;
         if (flagtemp != Cmd.swap_yz) {
             Cmd.swap_yz = flagtemp;
@@ -3181,12 +5736,12 @@ boolean initial;
             ++updated;
             /* phone_layout has been toggled */
             for (i = 0; i < 3; i++) {
-                c = '1' + i;                           /* 1,2,3 <-> 7,8,9 */
+                c = '1' + i;             /* 1,2,3 <-> 7,8,9 */
                 cmdtmp = Cmd.commands[c];              /* tmp = [1] */
                 Cmd.commands[c] = Cmd.commands[c + 6]; /* [1] = [7] */
                 Cmd.commands[c + 6] = cmdtmp;          /* [7] = tmp */
-                c = (M('1') & 0xff) + i;  /* M-1,M-2,M-3 <-> M-7,M-8,M-9 */
-                cmdtmp = Cmd.commands[c]; /* tmp = [M-1] */
+                c = (M('1') & 0xff) + i; /* M-1,M-2,M-3 <-> M-7,M-8,M-9 */
+                cmdtmp = Cmd.commands[c];              /* tmp = [M-1] */
                 Cmd.commands[c] = Cmd.commands[c + 6]; /* [M-1] = [M-7] */
                 Cmd.commands[c + 6] = cmdtmp;          /* [M-7] = tmp */
             }
@@ -3208,23 +5763,112 @@ boolean initial;
     Cmd.move_SE = Cmd.dirchars[5];
     Cmd.move_S = Cmd.dirchars[6];
     Cmd.move_SW = Cmd.dirchars[7];
+
+    if (!initial) {
+        for (i = 0; i < 8; i++) {
+            back_dir_cmd[i] =
+                (struct ext_func_tab *) Cmd.commands[(uchar) Cmd.dirchars[i]];
+            Cmd.commands[(uchar) Cmd.dirchars[i]] = (struct ext_func_tab *) 0;
+        }
+        backed_dir_cmd = TRUE;
+        for (i = 0; i < 8; i++)
+            (void) bind_key(Cmd.dirchars[i], "nothing");
+    }
 }
 
+/* non-movement commands which accept 'm' prefix to request menu operation */
 STATIC_OVL boolean
 accept_menu_prefix(cmd_func)
 int NDECL((*cmd_func));
 {
     if (cmd_func == dopickup || cmd_func == dotip
+        /* eat, #offer, and apply tinning-kit all use floorfood() to pick
+           an item on floor or in invent; 'm' skips picking from floor
+           (ie, inventory only) rather than request use of menu operation */
+        || cmd_func == doeat || cmd_func == dosacrifice || cmd_func == doapply
+        /* 'm' for removing saddle from adjacent monster without checking
+           for containers at <u.ux,u.uy> */
+        || cmd_func == doloot
+        /* travel: pop up a menu of interesting targets in view */
+        || cmd_func == dotravel
+        /* wizard mode ^V and ^T */
+        || cmd_func == wiz_level_tele || cmd_func == dotelecmd
+        /* 'm' prefix allowed for some extended commands */
         || cmd_func == doextcmd || cmd_func == doextlist)
         return TRUE;
     return FALSE;
 }
 
+char
+randomkey()
+{
+    static int i = 0;
+    char c;
+
+    switch (rn2(12)) {
+    default: c = '\033'; break;
+    case 0: c = '\n'; break;
+    case 1:
+    case 2:
+    case 3:
+    case 4: c = (char)(' ' + rn2((int)('~' - ' '))); break;
+    case 5: c = '\t'; break;
+    case 6: c = (char)('a' + rn2((int)('z' - 'a'))); break;
+    case 7: c = (char)('A' + rn2((int)('Z' - 'A'))); break;
+    case 8: c = extcmdlist[(i++) % SIZE(extcmdlist)].key; break;
+    case 9: c = '#'; break;
+    }
+
+    return c;
+}
+
+void
+random_response(buf, sz)
+char *buf;
+int sz;
+{
+    char c;
+    int count = 0;
+
+    for (;;) {
+        c = randomkey();
+        if (c == '\n')
+            break;
+        if (c == '\033') {
+            count = 0;
+            break;
+        }
+        if (count < sz - 1)
+            buf[count++] = c;
+    }
+    buf[count] = '\0';
+}
+
+int
+rnd_extcmd_idx(VOID_ARGS)
+{
+    return rn2(extcmdlist_length + 1) - 1;
+}
+
+int
+ch2spkeys(c, start, end)
+char c;
+int start,end;
+{
+    int i;
+
+    for (i = start; i <= end; i++)
+        if (Cmd.spkeys[i] == c)
+            return i;
+    return NHKF_ESC;
+}
+
 void
 rhack(cmd)
 register char *cmd;
 {
-    boolean do_walk, do_rush, prefix_seen, bad_command,
+    int spkey;
+    boolean prefix_seen, bad_command,
         firsttime = (cmd == 0);
 
     iflags.menu_requested = FALSE;
@@ -3236,7 +5880,7 @@ register char *cmd;
         context.nopick = 0;
         cmd = parse();
     }
-    if (*cmd == '\033') {
+    if (*cmd == Cmd.spkeys[NHKF_ESC]) {
         context.move = FALSE;
         return;
     }
@@ -3255,103 +5899,107 @@ register char *cmd;
     }
 
     /* handle most movement commands */
-    do_walk = do_rush = prefix_seen = FALSE;
+    prefix_seen = FALSE;
     context.travel = context.travel1 = 0;
-    switch (*cmd) {
-    case 'g':
+    spkey = ch2spkeys(*cmd, NHKF_RUN, NHKF_CLICKLOOK);
+
+    switch (spkey) {
+    case NHKF_RUSH:
         if (movecmd(cmd[1])) {
             context.run = 2;
-            do_rush = TRUE;
+            domove_attempting |= DOMOVE_RUSH;
         } else
             prefix_seen = TRUE;
         break;
-    case '5':
+    case NHKF_RUN2:
         if (!Cmd.num_pad)
-            break; /* else FALLTHRU */
-    case 'G':
+            break;
+        /*FALLTHRU*/
+    case NHKF_RUN:
         if (movecmd(lowc(cmd[1]))) {
             context.run = 3;
-            do_rush = TRUE;
+            domove_attempting |= DOMOVE_RUSH;
         } else
             prefix_seen = TRUE;
         break;
-    case '-':
+    case NHKF_FIGHT2:
         if (!Cmd.num_pad)
-            break; /* else FALLTHRU */
+            break;
+        /*FALLTHRU*/
     /* Effects of movement commands and invisible monsters:
      * m: always move onto space (even if 'I' remembered)
      * F: always attack space (even if 'I' not remembered)
      * normal movement: attack if 'I', move otherwise.
      */
-    case 'F':
+    case NHKF_FIGHT:
         if (movecmd(cmd[1])) {
             context.forcefight = 1;
-            do_walk = TRUE;
+            domove_attempting |= DOMOVE_WALK;
         } else
             prefix_seen = TRUE;
         break;
-    case 'm':
+    case NHKF_NOPICKUP:
         if (movecmd(cmd[1]) || u.dz) {
             context.run = 0;
             context.nopick = 1;
             if (!u.dz)
-                do_walk = TRUE;
+                domove_attempting |= DOMOVE_WALK;
             else
                 cmd[0] = cmd[1]; /* "m<" or "m>" */
         } else
             prefix_seen = TRUE;
         break;
-    case 'M':
+    case NHKF_RUN_NOPICKUP:
         if (movecmd(lowc(cmd[1]))) {
             context.run = 1;
             context.nopick = 1;
-            do_rush = TRUE;
+            domove_attempting |= DOMOVE_RUSH;
         } else
             prefix_seen = TRUE;
         break;
-    case '0':
+    case NHKF_DOINV:
         if (!Cmd.num_pad)
             break;
         (void) ddoinv(); /* a convenience borrowed from the PC */
         context.move = FALSE;
         multi = 0;
         return;
-    case CMD_CLICKLOOK:
+    case NHKF_CLICKLOOK:
         if (iflags.clicklook) {
             context.move = FALSE;
             do_look(2, &clicklook_cc);
         }
         return;
-    case CMD_TRAVEL:
+    case NHKF_TRAVEL:
         if (flags.travelcmd) {
             context.travel = 1;
             context.travel1 = 1;
             context.run = 8;
             context.nopick = 1;
-            do_rush = TRUE;
+            domove_attempting |= DOMOVE_RUSH;
             break;
         }
         /*FALLTHRU*/
     default:
         if (movecmd(*cmd)) { /* ordinary movement */
             context.run = 0; /* only matters here if it was 8 */
-            do_walk = TRUE;
+            domove_attempting |= DOMOVE_WALK;
         } else if (movecmd(Cmd.num_pad ? unmeta(*cmd) : lowc(*cmd))) {
             context.run = 1;
-            do_rush = TRUE;
+            domove_attempting |= DOMOVE_RUSH;
         } else if (movecmd(unctrl(*cmd))) {
             context.run = 3;
-            do_rush = TRUE;
+            domove_attempting |= DOMOVE_RUSH;
         }
         break;
     }
 
     /* some special prefix handling */
     /* overload 'm' prefix to mean "request a menu" */
-    if (prefix_seen && cmd[0] == 'm') {
+    if (prefix_seen && cmd[0] == Cmd.spkeys[NHKF_REQMENU]) {
         /* (for func_tab cast, see below) */
-        const struct func_tab *ft = Cmd.commands[cmd[1] & 0xff];
-        int NDECL((*func)) = ft ? ((struct func_tab *) ft)->f_funct : 0;
+        const struct ext_func_tab *ft = Cmd.commands[cmd[1] & 0xff];
+        int NDECL((*func)) = ft ? ((struct ext_func_tab *) ft)->ef_funct : 0;
 
         if (func && accept_menu_prefix(func)) {
             iflags.menu_requested = TRUE;
@@ -3359,13 +6007,17 @@ register char *cmd;
         }
     }
 
-    if ((do_walk || do_rush) && !context.travel && !dxdy_moveok()) {
+    if (((domove_attempting & (DOMOVE_RUSH | DOMOVE_WALK)) != 0L)
+                            && !context.travel && !dxdy_moveok()) {
         /* trying to move diagonally as a grid bug;
            this used to be treated by movecmd() as not being
            a movement attempt, but that didn't provide for any
            feedback and led to strangeness if the key pressed
            ('u' in particular) was overloaded for num_pad use */
+/*JP
         You_cant("get there from here...");
+*/
+        You_cant("\82±\82±\82©\82ç\82»\82±\82Ö\82Í\8ds\82¯\82Ü\82¹\82ñ\81D\81D\81D");
         context.run = 0;
         context.nopick = context.forcefight = FALSE;
         context.move = context.mv = FALSE;
@@ -3373,13 +6025,13 @@ register char *cmd;
         return;
     }
 
-    if (do_walk) {
+    if ((domove_attempting & DOMOVE_WALK) != 0L) {
         if (multi)
             context.mv = TRUE;
         domove();
         context.forcefight = 0;
         return;
-    } else if (do_rush) {
+    } else if ((domove_attempting & DOMOVE_RUSH) != 0L) {
         if (firsttime) {
             if (!multi)
                 multi = max(COLNO, ROWNO);
@@ -3388,33 +6040,36 @@ register char *cmd;
         context.mv = TRUE;
         domove();
         return;
-    } else if (prefix_seen && cmd[1] == '\033') { /* <prefix><escape> */
+    } else if (prefix_seen && cmd[1] == Cmd.spkeys[NHKF_ESC]) {
+        /* <prefix><escape> */
         /* don't report "unknown command" for change of heart... */
         bad_command = FALSE;
     } else if (*cmd == ' ' && !flags.rest_on_space) {
         bad_command = TRUE; /* skip cmdlist[] loop */
 
-        /* handle all other commands */
+    /* handle all other commands */
     } else {
-        register const struct func_tab *tlist;
+        register const struct ext_func_tab *tlist;
         int res, NDECL((*func));
 
-#if 0
-        /* obsolete - scan through the cmdlist array looking for *cmd */
-        for (tlist = cmdlist; tlist->f_char; tlist++) {
-            if ((*cmd & 0xff) != (tlist->f_char & 0xff))
-                continue;
-#else
         /* current - use *cmd to directly index cmdlist array */
         if ((tlist = Cmd.commands[*cmd & 0xff]) != 0) {
-#endif
-            if (u.uburied && !tlist->can_if_buried) {
+            if (!wizard && (tlist->flags & WIZMODECMD)) {
+/*JP
+                You_cant("do that!");
+*/
+                pline("\82»\82ê\82Í\82Å\82«\82Ü\82¹\82ñ\81I");
+                res = 0;
+            } else if (u.uburied && !(tlist->flags & IFBURIED)) {
+/*JP
                 You_cant("do that while you are buried!");
+*/
+                You("\96\84\82Ü\82Á\82Ä\82¢\82é\8e\9e\82É\82»\82ñ\82È\82±\82Æ\82Í\82Å\82«\82È\82¢\81I");
                 res = 0;
             } else {
                 /* we discard 'const' because some compilers seem to have
                    trouble with the pointer passed to set_occupation() */
-                func = ((struct func_tab *) tlist)->f_funct;
+                func = ((struct ext_func_tab *) tlist)->ef_funct;
                 if (tlist->f_text && !occupation && multi)
                     set_occupation(func, tlist->f_text, multi);
                 res = (*func)(); /* perform the command */
@@ -3430,26 +6085,21 @@ register char *cmd;
     }
 
     if (bad_command) {
-        char expcmd[10];
-        register char c, *cp = expcmd;
-
-        while ((c = *cmd++) != '\0'
-               && (int) (cp - expcmd) < (int) (sizeof expcmd - 3)) {
-            if (c >= 040 && c < 0177) {
-                *cp++ = c;
-            } else if (c & 0200) {
-                *cp++ = 'M';
-                *cp++ = '-';
-                *cp++ = c & ~0200;
-            } else {
-                *cp++ = '^';
-                *cp++ = c ^ 0100;
-            }
-        }
-        *cp = '\0';
-        if (!prefix_seen || !iflags.cmdassist
-            || !help_dir(0, "Invalid direction key!"))
+        char expcmd[20]; /* we expect 'cmd' to point to 1 or 2 chars */
+        char c, c1 = cmd[1];
+
+        expcmd[0] = '\0';
+        while ((c = *cmd++) != '\0')
+            Strcat(expcmd, visctrl(c)); /* add 1..4 chars plus terminator */
+
+/*JP
+        if (!prefix_seen || !help_dir(c1, spkey, "Invalid direction key!"))
+*/
+        if (!prefix_seen || !help_dir(c1, spkey, "\96³\8cø\82È\95û\8cü\8ew\92è\82Å\82·\81I"))
+/*JP
             Norep("Unknown command '%s'.", expcmd);
+*/
+            Norep("'%s'\83R\83}\83\93\83h\81H", expcmd);
     }
     /* didn't move */
     context.move = FALSE;
@@ -3517,7 +6167,21 @@ boolean
 redraw_cmd(c)
 char c;
 {
-    return (boolean) (c == C('r') || (Cmd.num_pad && c == C('l')));
+    return (boolean) (c == Cmd.spkeys[NHKF_REDRAW]
+                      || (Cmd.num_pad && c == Cmd.spkeys[NHKF_REDRAW2]));
+}
+
+boolean
+prefix_cmd(c)
+char c;
+{
+    return (c == Cmd.spkeys[NHKF_RUSH]
+            || c == Cmd.spkeys[NHKF_RUN]
+            || c == Cmd.spkeys[NHKF_NOPICKUP]
+            || c == Cmd.spkeys[NHKF_RUN_NOPICKUP]
+            || c == Cmd.spkeys[NHKF_FIGHT]
+            || (Cmd.num_pad && (c == Cmd.spkeys[NHKF_RUN2]
+                                || c == Cmd.spkeys[NHKF_FIGHT2])));
 }
 
 /*
@@ -3565,7 +6229,10 @@ retry:
     if (in_doagain || *readchar_queue)
         dirsym = readchar();
     else
+/*JP
         dirsym = yn_function((s && *s != '^') ? s : "In what direction?",
+*/
+        dirsym = yn_function((s && *s != '^') ? s : "\82Ç\82Ì\95û\8cü\81H",
                              (char *) 0, '\0');
     /* remove the prompt string so caller won't have to */
     clear_nhwindow(WIN_MESSAGE);
@@ -3576,27 +6243,37 @@ retry:
     }
     savech(dirsym);
 
-    if (dirsym == '.' || dirsym == 's') {
+    if (dirsym == Cmd.spkeys[NHKF_GETDIR_SELF]
+        || dirsym == Cmd.spkeys[NHKF_GETDIR_SELF2]) {
         u.dx = u.dy = u.dz = 0;
     } else if (!(is_mov = movecmd(dirsym)) && !u.dz) {
         boolean did_help = FALSE, help_requested;
 
         if (!index(quitchars, dirsym)) {
-            help_requested = (dirsym == '?');
+            help_requested = (dirsym == Cmd.spkeys[NHKF_GETDIR_HELP]);
             if (help_requested || iflags.cmdassist) {
-                did_help =
-                    help_dir((s && *s == '^') ? dirsym : 0,
-                             help_requested ? (const char *) 0
+                did_help = help_dir((s && *s == '^') ? dirsym : '\0',
+                                    NHKF_ESC,
+                                    help_requested ? (const char *) 0
+/*JP
                                             : "Invalid direction key!");
+*/
+                                            : "\96³\8cø\82È\95û\8cü\8ew\92è\82Å\82·\81I");
                 if (help_requested)
                     goto retry;
             }
             if (!did_help)
+/*JP
                 pline("What a strange direction!");
+*/
+                pline("\82¸\82¢\82Ô\82ñ\82Æ\8aï\96­\82È\95û\8cü\82¾\81I");
         }
         return 0;
     } else if (is_mov && !dxdy_moveok()) {
+/*JP
         You_cant("orient yourself that direction.");
+*/
+        You_cant("\8cü\82«\82É\8e©\95ª\8e©\90g\82ð\8ew\92è\82Å\82«\82È\82¢\81D");
         return 0;
     }
     if (!u.dz && (Stunned || (Confusion && !rn2(5))))
@@ -3604,76 +6281,191 @@ retry:
     return 1;
 }
 
+STATIC_OVL void
+show_direction_keys(win, centerchar, nodiag)
+winid win; /* should specify a window which is using a fixed-width font... */
+char centerchar; /* '.' or '@' or ' ' */
+boolean nodiag;
+{
+    char buf[BUFSZ];
+
+    if (!centerchar)
+        centerchar = ' ';
+
+    if (nodiag) {
+        Sprintf(buf, "             %c   ", Cmd.move_N);
+        putstr(win, 0, buf);
+        putstr(win, 0, "             |   ");
+        Sprintf(buf, "          %c- %c -%c",
+                Cmd.move_W, centerchar, Cmd.move_E);
+        putstr(win, 0, buf);
+        putstr(win, 0, "             |   ");
+        Sprintf(buf, "             %c   ", Cmd.move_S);
+        putstr(win, 0, buf);
+    } else {
+        Sprintf(buf, "          %c  %c  %c",
+                Cmd.move_NW, Cmd.move_N, Cmd.move_NE);
+        putstr(win, 0, buf);
+        putstr(win, 0, "           \\ | / ");
+        Sprintf(buf, "          %c- %c -%c",
+                Cmd.move_W, centerchar, Cmd.move_E);
+        putstr(win, 0, buf);
+        putstr(win, 0, "           / | \\ ");
+        Sprintf(buf, "          %c  %c  %c",
+                Cmd.move_SW, Cmd.move_S, Cmd.move_SE);
+        putstr(win, 0, buf);
+    };
+}
+
+/* explain choices if player has asked for getdir() help or has given
+   an invalid direction after a prefix key ('F', 'g', 'm', &c), which
+   might be bogus but could be up, down, or self when not applicable */
 STATIC_OVL boolean
-help_dir(sym, msg)
+help_dir(sym, spkey, msg)
 char sym;
+int spkey; /* NHKF_ code for prefix key, if one was used, or for ESC */
 const char *msg;
 {
+    static const char wiz_only_list[] = "EFGIVW";
     char ctrl;
     winid win;
-    static const char wiz_only_list[] = "EFGIOVW";
     char buf[BUFSZ], buf2[BUFSZ], *explain;
+    const char *dothat, *how;
+    boolean prefixhandling, viawindow;
+
+    /* NHKF_ESC indicates that player asked for help at getdir prompt */
+    viawindow = (spkey == NHKF_ESC || iflags.cmdassist);
+    prefixhandling = (spkey != NHKF_ESC);
+    /*
+     * Handling for prefix keys that don't want special directions.
+     * Delivered via pline if 'cmdassist' is off, or instead of the
+     * general message if it's on.
+     */
+    dothat = "do that";
+    how = " at"; /* for "<action> at yourself"; not used for up/down */
+    switch (spkey) {
+    case NHKF_NOPICKUP:
+        dothat = "move";
+        break;
+    case NHKF_RUSH:
+        dothat = "rush";
+        break;
+    case NHKF_RUN2:
+        if (!Cmd.num_pad)
+            break;
+        /*FALLTHRU*/
+    case NHKF_RUN:
+    case NHKF_RUN_NOPICKUP:
+        dothat = "run";
+        break;
+    case NHKF_FIGHT2:
+        if (!Cmd.num_pad)
+            break;
+        /*FALLTHRU*/
+    case NHKF_FIGHT:
+        dothat = "fight";
+        how = ""; /* avoid "fight at yourself" */
+        break;
+    default:
+        prefixhandling = FALSE;
+        break;
+    }
+
+    buf[0] = '\0';
+    /* for movement prefix followed by '.' or (numpad && 's') to mean 'self';
+       note: '-' for hands (inventory form of 'self') is not handled here */
+    if (prefixhandling
+        && (sym == Cmd.spkeys[NHKF_GETDIR_SELF]
+            || (Cmd.num_pad && sym == Cmd.spkeys[NHKF_GETDIR_SELF2]))) {
+        Sprintf(buf, "You can't %s%s yourself.", dothat, how);
+    /* for movement prefix followed by up or down */
+    } else if (prefixhandling && (sym == '<' || sym == '>')) {
+        Sprintf(buf, "You can't %s %s.", dothat,
+                /* was "upwards" and "downwards", but they're considered
+                   to be variants of canonical "upward" and "downward" */
+                (sym == '<') ? "upward" : "downward");
+    }
+
+    /* if '!cmdassist', display via pline() and we're done (note: asking
+       for help at getdir() prompt forces cmdassist for this operation) */
+    if (!viawindow) {
+        if (prefixhandling) {
+            if (!*buf)
+                Sprintf(buf, "Invalid direction for '%s' prefix.",
+                        visctrl(Cmd.spkeys[spkey]));
+            pline("%s", buf);
+            return TRUE;
+        }
+        /* when 'cmdassist' is off and caller doesn't insist, do nothing */
+        return FALSE;
+    }
 
     win = create_nhwindow(NHW_TEXT);
     if (!win)
         return FALSE;
-    if (msg) {
+
+    if (*buf) {
+        /* show bad-prefix message instead of general invalid-direction one */
+        putstr(win, 0, buf);
+        putstr(win, 0, "");
+    } else if (msg) {
         Sprintf(buf, "cmdassist: %s", msg);
         putstr(win, 0, buf);
         putstr(win, 0, "");
     }
-    if (letter(sym)) {
-        sym = highc(sym);
-        ctrl = (sym - 'A') + 1;
-        if ((explain = dowhatdoes_core(ctrl, buf2))
+
+    if (!prefixhandling && (letter(sym) || sym == '[')) {
+        /* '[': old 'cmdhelp' showed ESC as ^[ */
+        sym = highc(sym); /* @A-Z[ (note: letter() accepts '@') */
+        ctrl = (sym - 'A') + 1; /* 0-27 (note: 28-31 aren't applicable) */
+        if ((explain = dowhatdoes_core(ctrl, buf2)) != 0
             && (!index(wiz_only_list, sym) || wizard)) {
             Sprintf(buf, "Are you trying to use ^%c%s?", sym,
-                    index(wiz_only_list, sym)
-                        ? ""
+                    index(wiz_only_list, sym) ? ""
                         : " as specified in the Guidebook");
             putstr(win, 0, buf);
             putstr(win, 0, "");
             putstr(win, 0, explain);
             putstr(win, 0, "");
-            putstr(win, 0, "To use that command, you press");
-            Sprintf(buf, "the <Ctrl> key, and the <%c> key at the same time.",
-                    sym);
+            putstr(win, 0,
+                  "To use that command, hold down the <Ctrl> key as a shift");
+            Sprintf(buf, "and press the <%c> key.", sym);
             putstr(win, 0, buf);
             putstr(win, 0, "");
         }
     }
-    if (NODIAG(u.umonnum)) {
-        putstr(win, 0, "Valid direction keys in your current form are:");
-        Sprintf(buf, "             %c   ", Cmd.move_N);
-        putstr(win, 0, buf);
-        putstr(win, 0, "             |   ");
-        Sprintf(buf, "          %c- . -%c", Cmd.move_W, Cmd.move_E);
-        putstr(win, 0, buf);
-        putstr(win, 0, "             |   ");
-        Sprintf(buf, "             %c   ", Cmd.move_S);
-        putstr(win, 0, buf);
-    } else {
-        putstr(win, 0, "Valid direction keys are:");
-        Sprintf(buf, "          %c  %c  %c", Cmd.move_NW, Cmd.move_N,
-                Cmd.move_NE);
-        putstr(win, 0, buf);
-        putstr(win, 0, "           \\ | / ");
-        Sprintf(buf, "          %c- . -%c", Cmd.move_W, Cmd.move_E);
-        putstr(win, 0, buf);
-        putstr(win, 0, "           / | \\ ");
-        Sprintf(buf, "          %c  %c  %c", Cmd.move_SW, Cmd.move_S,
-                Cmd.move_SE);
-        putstr(win, 0, buf);
-    };
-    putstr(win, 0, "");
-    putstr(win, 0, "          <  up");
-    putstr(win, 0, "          >  down");
-    putstr(win, 0, "          .  direct at yourself");
+
+    Sprintf(buf, "Valid direction keys%s%s%s are:",
+            prefixhandling ? " to " : "", prefixhandling ? dothat : "",
+            NODIAG(u.umonnum) ? " in your current form" : "");
+    putstr(win, 0, buf);
+    show_direction_keys(win, !prefixhandling ? '.' : ' ', NODIAG(u.umonnum));
+
+    if (!prefixhandling || spkey == NHKF_NOPICKUP) {
+        /* NOPICKUP: unlike the other prefix keys, 'm' allows up/down for
+           stair traversal; we won't get here when "m<" or "m>" has been
+           given but we include up and down for 'm'+invalid_direction;
+           self is excluded as a viable direction for every prefix */
+        putstr(win, 0, "");
+        putstr(win, 0, "          <  up");
+        putstr(win, 0, "          >  down");
+        if (!prefixhandling) {
+            int selfi = Cmd.num_pad ? NHKF_GETDIR_SELF2 : NHKF_GETDIR_SELF;
+
+            Sprintf(buf,   "       %4s  direct at yourself",
+                    visctrl(Cmd.spkeys[selfi]));
+            putstr(win, 0, buf);
+        }
+    }
+
     if (msg) {
         /* non-null msg means that this wasn't an explicit user request */
         putstr(win, 0, "");
         putstr(win, 0,
+/*JP
                "(Suppress this message with !cmdassist in config file.)");
+*/
+               "(\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)");
     }
     display_nhwindow(win, FALSE);
     destroy_nhwindow(win);
@@ -3712,6 +6504,251 @@ register int x, y;
     return x >= 1 && x <= COLNO - 1 && y >= 0 && y <= ROWNO - 1;
 }
 
+/* #herecmdmenu command */
+STATIC_PTR int
+doherecmdmenu(VOID_ARGS)
+{
+    char ch = here_cmd_menu(TRUE);
+
+    return ch ? 1 : 0;
+}
+
+/* #therecmdmenu command, a way to test there_cmd_menu without mouse */
+STATIC_PTR int
+dotherecmdmenu(VOID_ARGS)
+{
+    char ch;
+
+    if (!getdir((const char *) 0) || !isok(u.ux + u.dx, u.uy + u.dy))
+        return 0;
+
+    if (u.dx || u.dy)
+        ch = there_cmd_menu(TRUE, u.ux + u.dx, u.uy + u.dy);
+    else
+        ch = here_cmd_menu(TRUE);
+
+    return ch ? 1 : 0;
+}
+
+STATIC_OVL void
+add_herecmd_menuitem(win, func, text)
+winid win;
+int NDECL((*func));
+const char *text;
+{
+    char ch;
+    anything any;
+
+    if ((ch = cmd_from_func(func)) != '\0') {
+        any = zeroany;
+        any.a_nfunc = func;
+        add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, text, MENU_UNSELECTED);
+    }
+}
+
+STATIC_OVL char
+there_cmd_menu(doit, x, y)
+boolean doit;
+int x, y;
+{
+    winid win;
+    char ch;
+    char buf[BUFSZ];
+    schar typ = levl[x][y].typ;
+    int npick, K = 0;
+    menu_item *picks = (menu_item *) 0;
+    struct trap *ttmp;
+    struct monst *mtmp;
+
+    win = create_nhwindow(NHW_MENU);
+    start_menu(win);
+
+    if (IS_DOOR(typ)) {
+        boolean key_or_pick, card;
+        int dm = levl[x][y].doormask;
+
+        if ((dm & (D_CLOSED | D_LOCKED))) {
+            add_herecmd_menuitem(win, doopen, "Open the door"), ++K;
+            /* unfortunately there's no lknown flag for doors to
+               remember the locked/unlocked state */
+            key_or_pick = (carrying(SKELETON_KEY) || carrying(LOCK_PICK));
+            card = (carrying(CREDIT_CARD) != 0);
+            if (key_or_pick || card) {
+                Sprintf(buf, "%sunlock the door",
+                        key_or_pick ? "lock or " : "");
+                add_herecmd_menuitem(win, doapply, upstart(buf)), ++K;
+            }
+            /* unfortunately there's no tknown flag for doors (or chests)
+               to remember whether a trap had been found */
+            add_herecmd_menuitem(win, dountrap,
+                                 "Search the door for a trap"), ++K;
+            /* [what about #force?] */
+            add_herecmd_menuitem(win, dokick, "Kick the door"), ++K;
+        } else if ((dm & D_ISOPEN)) {
+            add_herecmd_menuitem(win, doclose, "Close the door"), ++K;
+        }
+    }
+
+    if (typ <= SCORR)
+        add_herecmd_menuitem(win, dosearch, "Search for secret doors"), ++K;
+
+    if ((ttmp = t_at(x, y)) != 0 && ttmp->tseen) {
+        add_herecmd_menuitem(win, doidtrap, "Examine trap"), ++K;
+        if (ttmp->ttyp != VIBRATING_SQUARE)
+            add_herecmd_menuitem(win, dountrap, "Attempt to disarm trap"), ++K;
+    }
+
+    mtmp = m_at(x, y);
+    if (mtmp && !canspotmon(mtmp))
+        mtmp = 0;
+    if (mtmp && which_armor(mtmp, W_SADDLE)) {
+        char *mnam = x_monnam(mtmp, ARTICLE_THE, (char *) 0,
+                              SUPPRESS_SADDLE, FALSE);
+
+        if (!u.usteed) {
+            Sprintf(buf, "Ride %s", mnam);
+            add_herecmd_menuitem(win, doride, buf), ++K;
+        }
+        Sprintf(buf, "Remove saddle from %s", mnam);
+        add_herecmd_menuitem(win, doloot, buf), ++K;
+    }
+    if (mtmp && can_saddle(mtmp) && !which_armor(mtmp, W_SADDLE)
+        && carrying(SADDLE)) {
+        Sprintf(buf, "Put saddle on %s", mon_nam(mtmp)), ++K;
+        add_herecmd_menuitem(win, doapply, buf);
+    }
+#if 0
+    if (mtmp || glyph_is_invisible(glyph_at(x, y))) {
+        /* "Attack %s", mtmp ? mon_nam(mtmp) : "unseen creature" */
+    } else {
+        /* "Move %s", direction */
+    }
+#endif
+
+    if (K) {
+        end_menu(win, "What do you want to do?");
+        npick = select_menu(win, PICK_ONE, &picks);
+    } else {
+        pline("No applicable actions.");
+        npick = 0;
+    }
+    destroy_nhwindow(win);
+    ch = '\0';
+    if (npick > 0) {
+        int NDECL((*func)) = picks->item.a_nfunc;
+        free((genericptr_t) picks);
+
+        if (doit) {
+            int ret = (*func)();
+
+            ch = (char) ret;
+        } else {
+            ch = cmd_from_func(func);
+        }
+    }
+    return ch;
+}
+
+STATIC_OVL char
+here_cmd_menu(doit)
+boolean doit;
+{
+    winid win;
+    char ch;
+    char buf[BUFSZ];
+    schar typ = levl[u.ux][u.uy].typ;
+    int npick;
+    menu_item *picks = (menu_item *) 0;
+
+    win = create_nhwindow(NHW_MENU);
+    start_menu(win);
+
+    if (IS_FOUNTAIN(typ) || IS_SINK(typ)) {
+        Sprintf(buf, "Drink from the %s",
+                defsyms[IS_FOUNTAIN(typ) ? S_fountain : S_sink].explanation);
+        add_herecmd_menuitem(win, dodrink, buf);
+    }
+    if (IS_FOUNTAIN(typ))
+        add_herecmd_menuitem(win, dodip,
+                             "Dip something into the fountain");
+    if (IS_THRONE(typ))
+        add_herecmd_menuitem(win, dosit,
+                             "Sit on the throne");
+
+    if ((u.ux == xupstair && u.uy == yupstair)
+        || (u.ux == sstairs.sx && u.uy == sstairs.sy && sstairs.up)
+        || (u.ux == xupladder && u.uy == yupladder)) {
+        Sprintf(buf, "Go up the %s",
+                (u.ux == xupladder && u.uy == yupladder)
+                ? "ladder" : "stairs");
+        add_herecmd_menuitem(win, doup, buf);
+    }
+    if ((u.ux == xdnstair && u.uy == ydnstair)
+        || (u.ux == sstairs.sx && u.uy == sstairs.sy && !sstairs.up)
+        || (u.ux == xdnladder && u.uy == ydnladder)) {
+        Sprintf(buf, "Go down the %s",
+                (u.ux == xupladder && u.uy == yupladder)
+                ? "ladder" : "stairs");
+        add_herecmd_menuitem(win, dodown, buf);
+    }
+    if (u.usteed) { /* another movement choice */
+        Sprintf(buf, "Dismount %s",
+                x_monnam(u.usteed, ARTICLE_THE, (char *) 0,
+                         SUPPRESS_SADDLE, FALSE));
+        add_herecmd_menuitem(win, doride, buf);
+    }
+
+#if 0
+    if (Upolyd) { /* before objects */
+        Sprintf(buf, "Use %s special ability",
+                s_suffix(mons[u.umonnum].mname));
+        add_herecmd_menuitem(win, domonability, buf);
+    }
+#endif
+
+    if (OBJ_AT(u.ux, u.uy)) {
+        struct obj *otmp = level.objects[u.ux][u.uy];
+
+        Sprintf(buf, "Pick up %s", otmp->nexthere ? "items" : doname(otmp));
+        add_herecmd_menuitem(win, dopickup, buf);
+
+        if (Is_container(otmp)) {
+            Sprintf(buf, "Loot %s", doname(otmp));
+            add_herecmd_menuitem(win, doloot, buf);
+        }
+        if (otmp->oclass == FOOD_CLASS) {
+            Sprintf(buf, "Eat %s", doname(otmp));
+            add_herecmd_menuitem(win, doeat, buf);
+        }
+    }
+
+    if (invent)
+        add_herecmd_menuitem(win, dodrop, "Drop items");
+
+    add_herecmd_menuitem(win, donull, "Rest one turn");
+    add_herecmd_menuitem(win, dosearch, "Search around you");
+    add_herecmd_menuitem(win, dolook, "Look at what is here");
+
+    end_menu(win, "What do you want to do?");
+    npick = select_menu(win, PICK_ONE, &picks);
+    destroy_nhwindow(win);
+    ch = '\0';
+    if (npick > 0) {
+        int NDECL((*func)) = picks->item.a_nfunc;
+        free((genericptr_t) picks);
+
+        if (doit) {
+            int ret = (*func)();
+
+            ch = (char) ret;
+        } else {
+            ch = cmd_from_func(func);
+        }
+    }
+    return ch;
+}
+
+
 static NEARDATA int last_multi;
 
 /*
@@ -3728,7 +6765,7 @@ int x, y, mod;
     if (iflags.clicklook && mod == CLICK_2) {
         clicklook_cc.x = x;
         clicklook_cc.y = y;
-        cmd[0] = CMD_CLICKLOOK;
+        cmd[0] = Cmd.spkeys[NHKF_CLICKLOOK];
         return cmd;
     }
 
@@ -3741,35 +6778,43 @@ int x, y, mod;
         } else {
             u.tx = u.ux + x;
             u.ty = u.uy + y;
-            cmd[0] = CMD_TRAVEL;
+            cmd[0] = Cmd.spkeys[NHKF_TRAVEL];
             return cmd;
         }
 
         if (x == 0 && y == 0) {
+            if (iflags.herecmd_menu) {
+                cmd[0] = here_cmd_menu(FALSE);
+                return cmd;
+            }
+
             /* here */
             if (IS_FOUNTAIN(levl[u.ux][u.uy].typ)
                 || IS_SINK(levl[u.ux][u.uy].typ)) {
-                cmd[0] = mod == CLICK_1 ? 'q' : M('d');
+                cmd[0] = cmd_from_func(mod == CLICK_1 ? dodrink : dodip);
                 return cmd;
             } else if (IS_THRONE(levl[u.ux][u.uy].typ)) {
-                cmd[0] = M('s');
+                cmd[0] = cmd_from_func(dosit);
                 return cmd;
             } else if ((u.ux == xupstair && u.uy == yupstair)
                        || (u.ux == sstairs.sx && u.uy == sstairs.sy
                            && sstairs.up)
                        || (u.ux == xupladder && u.uy == yupladder)) {
-                return "<";
+                cmd[0] = cmd_from_func(doup);
+                return cmd;
             } else if ((u.ux == xdnstair && u.uy == ydnstair)
                        || (u.ux == sstairs.sx && u.uy == sstairs.sy
                            && !sstairs.up)
                        || (u.ux == xdnladder && u.uy == ydnladder)) {
-                return ">";
+                cmd[0] = cmd_from_func(dodown);
+                return cmd;
             } else if (OBJ_AT(u.ux, u.uy)) {
-                cmd[0] =
-                    Is_container(level.objects[u.ux][u.uy]) ? M('l') : ',';
+                cmd[0] = cmd_from_func(Is_container(level.objects[u.ux][u.uy])
+                                       ? doloot : dopickup);
                 return cmd;
             } else {
-                return "."; /* just rest */
+                cmd[0] = cmd_from_func(donull); /* just rest */
+                return cmd;
             }
         }
 
@@ -3781,20 +6826,27 @@ int x, y, mod;
             && !test_move(u.ux, u.uy, x, y, TEST_MOVE)) {
             cmd[1] = Cmd.dirchars[dir];
             cmd[2] = '\0';
+            if (iflags.herecmd_menu) {
+                cmd[0] = there_cmd_menu(FALSE, u.ux + x, u.uy + y);
+                if (cmd[0] == '\0')
+                    cmd[1] = '\0';
+                return cmd;
+            }
+
             if (IS_DOOR(levl[u.ux + x][u.uy + y].typ)) {
                 /* slight assistance to the player: choose kick/open for them
                  */
                 if (levl[u.ux + x][u.uy + y].doormask & D_LOCKED) {
-                    cmd[0] = C('d');
+                    cmd[0] = cmd_from_func(dokick);
                     return cmd;
                 }
                 if (levl[u.ux + x][u.uy + y].doormask & D_CLOSED) {
-                    cmd[0] = 'o';
+                    cmd[0] = cmd_from_func(doopen);
                     return cmd;
                 }
             }
             if (levl[u.ux + x][u.uy + y].typ <= SCORR) {
-                cmd[0] = 's';
+                cmd[0] = cmd_from_func(dosearch);
                 cmd[1] = 0;
                 return cmd;
             }
@@ -3812,9 +6864,11 @@ int x, y, mod;
         else
             x = sgn(x), y = sgn(y);
 
-        if (x == 0 && y == 0) /* map click on player to "rest" command */
-            return ".";
-
+        if (x == 0 && y == 0) {
+            /* map click on player to "rest" command */
+            cmd[0] = cmd_from_func(donull);
+            return cmd;
+        }
         dir = xytod(x, y);
     }
 
@@ -3831,6 +6885,77 @@ int x, y, mod;
     return cmd;
 }
 
+char
+get_count(allowchars, inkey, maxcount, count, historical)
+char *allowchars;
+char inkey;
+long maxcount;
+long *count;
+boolean historical; /* whether to include in message history: True => yes */
+{
+    char qbuf[QBUFSZ];
+    int key;
+    long cnt = 0L;
+    boolean backspaced = FALSE;
+    /* this should be done in port code so that we have erase_char
+       and kill_char available; we can at least fake erase_char */
+#define STANDBY_erase_char '\177'
+
+    for (;;) {
+        if (inkey) {
+            key = inkey;
+            inkey = '\0';
+        } else
+            key = readchar();
+
+        if (digit(key)) {
+            cnt = 10L * cnt + (long) (key - '0');
+            if (cnt < 0)
+                cnt = 0;
+            else if (maxcount > 0 && cnt > maxcount)
+                cnt = maxcount;
+        } else if (cnt && (key == '\b' || key == STANDBY_erase_char)) {
+            cnt = cnt / 10;
+            backspaced = TRUE;
+        } else if (key == Cmd.spkeys[NHKF_ESC]) {
+            break;
+        } else if (!allowchars || index(allowchars, key)) {
+            *count = cnt;
+            break;
+        }
+
+        if (cnt > 9 || backspaced) {
+            clear_nhwindow(WIN_MESSAGE);
+            if (backspaced && !cnt) {
+/*JP
+                Sprintf(qbuf, "Count: ");
+*/
+                Sprintf(qbuf, "\90\94: ");
+            } else {
+/*JP
+                Sprintf(qbuf, "Count: %ld", cnt);
+*/
+                Sprintf(qbuf, "\90\94: %ld", cnt);
+                backspaced = FALSE;
+            }
+            custompline(SUPPRESS_HISTORY, "%s", qbuf);
+            mark_synch();
+        }
+    }
+
+    if (historical) {
+/*JP
+        Sprintf(qbuf, "Count: %ld ", *count);
+*/
+        Sprintf(qbuf, "\90\94: %ld ", *count);
+        (void) key2txt((uchar) key, eos(qbuf));
+        putmsghistory(qbuf, FALSE);
+    }
+
+    return key;
+}
+
+
 STATIC_OVL char *
 parse()
 {
@@ -3840,8 +6965,8 @@ parse()
     static char in_line[COLNO];
 #endif
     register int foo;
-    boolean prezero = FALSE;
 
+    iflags.in_parse = TRUE;
     multi = 0;
     context.move = 1;
     flush_screen(1); /* Flush screen buffer. Put the cursor on the hero. */
@@ -3849,33 +6974,26 @@ parse()
 #ifdef ALTMETA
     alt_esc = iflags.altmeta; /* readchar() hack */
 #endif
-    if (!Cmd.num_pad || (foo = readchar()) == 'n')
-        for (;;) {
-            foo = readchar();
-            if (foo >= '0' && foo <= '9') {
-                multi = 10 * multi + foo - '0';
-                if (multi < 0 || multi >= LARGEST_INT)
-                    multi = LARGEST_INT;
-                if (multi > 9) {
-                    clear_nhwindow(WIN_MESSAGE);
-                    Sprintf(in_line, "Count: %d", multi);
-                    pline1(in_line);
-                    mark_synch();
-                }
-                last_multi = multi;
-                if (!multi && foo == '0')
-                    prezero = TRUE;
-            } else
-                break; /* not a digit */
-        }
+    if (!Cmd.num_pad || (foo = readchar()) == Cmd.spkeys[NHKF_COUNT]) {
+        long tmpmulti = multi;
+
+        foo = get_count((char *) 0, '\0', LARGEST_INT, &tmpmulti, FALSE);
+        last_multi = multi = tmpmulti;
+    }
 #ifdef ALTMETA
     alt_esc = FALSE; /* readchar() reset */
 #endif
 
-    if (foo == '\033') { /* esc cancels count (TH) */
+    if (iflags.debug_fuzzer /* if fuzzing, override '!' and ^Z */
+        && (Cmd.commands[foo & 0x0ff]
+            && (Cmd.commands[foo & 0x0ff]->ef_funct == dosuspend_core
+                || Cmd.commands[foo & 0x0ff]->ef_funct == dosh_core)))
+        foo = Cmd.spkeys[NHKF_ESC];
+
+    if (foo == Cmd.spkeys[NHKF_ESC]) { /* esc cancels count (TH) */
         clear_nhwindow(WIN_MESSAGE);
         multi = last_multi = 0;
-    } else if (foo == DOAGAIN || in_doagain) {
+    } else if (foo == Cmd.spkeys[NHKF_DOAGAIN] || in_doagain) {
         multi = last_multi;
     } else {
         last_multi = multi;
@@ -3897,13 +7015,13 @@ parse()
            from the number pad. Now do not map them until here. */
         switch (foo) {
         case '5':
-            foo = 'g';
+            foo = Cmd.spkeys[NHKF_RUSH];
             break;
         case M('5'):
-            foo = 'G';
+            foo = Cmd.spkeys[NHKF_RUN];
             break;
         case M('0'):
-            foo = 'I';
+            foo = Cmd.spkeys[NHKF_DOINV];
             break;
         default:
             break; /* as is */
@@ -3912,16 +7030,15 @@ parse()
 
     in_line[0] = foo;
     in_line[1] = '\0';
-    if (foo == 'g' || foo == 'G' || foo == 'm' || foo == 'M' || foo == 'F'
-        || (Cmd.num_pad && (foo == '5' || foo == '-'))) {
+    if (prefix_cmd(foo)) {
         foo = readchar();
         savech((char) foo);
         in_line[1] = foo;
         in_line[2] = 0;
     }
     clear_nhwindow(WIN_MESSAGE);
-    if (prezero)
-        in_line[0] = '\033';
+
+    iflags.in_parse = FALSE;
     return in_line;
 }
 
@@ -3971,7 +7088,7 @@ end_of_input()
     if (iflags.window_inited)
         exit_nhwindows((char *) 0);
     clearlocks();
-    terminate(EXIT_SUCCESS);
+    nh_terminate(EXIT_SUCCESS);
     /*NOTREACHED*/ /* not necessarily true for vms... */
     return;
 }
@@ -3983,6 +7100,8 @@ readchar()
     register int sym;
     int x = u.ux, y = u.uy, mod = 0;
 
+    if (iflags.debug_fuzzer)
+        return randomkey();
     if (*readchar_queue)
         sym = *readchar_queue++;
     else
@@ -4016,7 +7135,7 @@ readchar()
             sym = '\033';
         else if (sym != '\033')
             sym |= 0200; /* force 8th bit on */
-#endif                   /*ALTMETA*/
+#endif /*ALTMETA*/
     } else if (sym == 0) {
         /* click event */
         readchar_queue = click_to_cmd(x, y, mod);
@@ -4025,84 +7144,62 @@ readchar()
     return (char) sym;
 }
 
+/* '_' command, #travel, via keyboard rather than mouse click */
 STATIC_PTR int
 dotravel(VOID_ARGS)
 {
-    /* Keyboard travel command */
     static char cmd[2];
     coord cc;
 
+    /* [FIXME?  Supporting the ability to disable traveling via mouse
+       click makes some sense, depending upon overall mouse usage.
+       Disabling '_' on a user by user basis makes no sense at all since
+       even if it is typed by accident, aborting when picking a target
+       destination is trivial.  Travel via mouse predates travel via '_',
+       and this use of OPTION=!travel is probably just a mistake....] */
     if (!flags.travelcmd)
         return 0;
+
     cmd[1] = 0;
     cc.x = iflags.travelcc.x;
     cc.y = iflags.travelcc.y;
-    if (cc.x == -1 && cc.y == -1) {
+    if (cc.x == 0 && cc.y == 0) {
         /* No cached destination, start attempt from current position */
         cc.x = u.ux;
         cc.y = u.uy;
     }
+    iflags.getloc_travelmode = TRUE;
+    if (iflags.menu_requested) {
+        int gf = iflags.getloc_filter;
+        iflags.getloc_filter = GFILTER_VIEW;
+        if (!getpos_menu(&cc, GLOC_INTERESTING)) {
+            iflags.getloc_filter = gf;
+            iflags.getloc_travelmode = FALSE;
+            return 0;
+        }
+        iflags.getloc_filter = gf;
+    } else {
+/*JP
     pline("Where do you want to travel to?");
+*/
+    pline("\82Ç\82±\82É\88Ú\93®\82·\82é\81H");
+/*JP
     if (getpos(&cc, TRUE, "the desired destination") < 0) {
-        /* user pressed ESC */
-        return 0;
+*/
+    if (getpos(&cc, TRUE, "\88Ú\93®\90æ") < 0) {
+            /* user pressed ESC */
+            iflags.getloc_travelmode = FALSE;
+            return 0;
+        }
     }
+    iflags.getloc_travelmode = FALSE;
     iflags.travelcc.x = u.tx = cc.x;
     iflags.travelcc.y = u.ty = cc.y;
-    cmd[0] = CMD_TRAVEL;
+    cmd[0] = Cmd.spkeys[NHKF_TRAVEL];
     readchar_queue = cmd;
     return 0;
 }
 
-#ifdef PORT_DEBUG
-extern void NDECL(win32con_debug_keystrokes);
-extern void NDECL(win32con_handler_info);
-
-int
-wiz_port_debug()
-{
-    int n, k;
-    winid win;
-    anything any;
-    int item = 'a';
-    int num_menu_selections;
-    struct menu_selection_struct {
-        char *menutext;
-        void NDECL((*fn));
-    } menu_selections[] = {
-#ifdef WIN32
-        { "test win32 keystrokes (tty only)", win32con_debug_keystrokes },
-        { "show keystroke handler information (tty only)",
-          win32con_handler_info },
-#endif
-        { (char *) 0, (void NDECL((*) )) 0 } /* array terminator */
-    };
-
-    num_menu_selections = SIZE(menu_selections) - 1;
-    if (num_menu_selections > 0) {
-        menu_item *pick_list;
-        win = create_nhwindow(NHW_MENU);
-        start_menu(win);
-        for (k = 0; k < num_menu_selections; ++k) {
-            any.a_int = k + 1;
-            add_menu(win, NO_GLYPH, &any, item++, 0, ATR_NONE,
-                     menu_selections[k].menutext, MENU_UNSELECTED);
-        }
-        end_menu(win, "Which port debugging feature?");
-        n = select_menu(win, PICK_ONE, &pick_list);
-        destroy_nhwindow(win);
-        if (n > 0) {
-            n = pick_list[0].item.a_int - 1;
-            free((genericptr_t) pick_list);
-            /* execute the function */
-            (*menu_selections[n].fn)();
-        }
-    } else
-        pline("No port-specific debug capability defined.");
-    return 0;
-}
-#endif /*PORT_DEBUG*/
-
 /*
  *   Parameter validator for generic yes/no function to prevent
  *   the core from sending too long a prompt string to the
@@ -4113,19 +7210,36 @@ yn_function(query, resp, def)
 const char *query, *resp;
 char def;
 {
-    char qbuf[QBUFSZ];
+    char res, qbuf[QBUFSZ];
+#ifdef DUMPLOG
+    extern unsigned saved_pline_index; /* pline.c */
+    unsigned idx = saved_pline_index;
+    /* buffer to hold query+space+formatted_single_char_response */
+    char dumplog_buf[QBUFSZ + 1 + 15]; /* [QBUFSZ+1+7] should suffice */
+#endif
 
     iflags.last_msg = PLNMSG_UNKNOWN; /* most recent pline is clobbered */
 
     /* maximum acceptable length is QBUFSZ-1 */
-    if (strlen(query) < QBUFSZ)
-        return (*windowprocs.win_yn_function)(query, resp, def);
-
-    /* caller shouldn't have passed anything this long */
-    paniclog("Query truncated: ", query);
-    (void) strncpy(qbuf, query, QBUFSZ - 1 - 3);
-    Strcpy(&qbuf[QBUFSZ - 1 - 3], "...");
-    return (*windowprocs.win_yn_function)(qbuf, resp, def);
+    if (strlen(query) >= QBUFSZ) {
+        /* caller shouldn't have passed anything this long */
+        paniclog("Query truncated: ", query);
+        (void) strncpy(qbuf, query, QBUFSZ - 1 - 3);
+        Strcpy(&qbuf[QBUFSZ - 1 - 3], "...");
+        query = qbuf;
+    }
+    res = (*windowprocs.win_yn_function)(query, resp, def);
+#ifdef DUMPLOG
+    if (idx == saved_pline_index) {
+        /* when idx is still the same as saved_pline_index, the interface
+           didn't put the prompt into saved_plines[]; we put a simplified
+           version in there now (without response choices or default) */
+        Sprintf(dumplog_buf, "%s ", query);
+        (void) key2txt((uchar) res, eos(dumplog_buf));
+        dumplogmsg(dumplog_buf);
+    }
+#endif
+    return res;
 }
 
 /* for paranoid_confirm:quit,die,attack prompting */
@@ -4140,7 +7254,7 @@ const char *prompt;
        to give the go-ahead for this query; default is "no" unless the
        ParanoidConfirm flag is set in which case there's no default */
     if (be_paranoid) {
-        char qbuf[QBUFSZ], ans[BUFSZ];
+        char qbuf[QBUFSZ], ans[BUFSZ] = DUMMY;
         const char *promptprefix = "", *responsetype = ParanoidConfirm
                                                            ? "(yes|no)"
                                                            : "(yes) [no]";
@@ -4166,8 +7280,9 @@ const char *prompt;
     return confirmed_ok;
 }
 
-int
-dosuspend_core()
+/* ^Z command, #suspend */
+STATIC_PTR int
+dosuspend_core(VOID_ARGS)
 {
 #ifdef SUSPEND
     /* Does current window system support suspend? */
@@ -4176,7 +7291,20 @@ dosuspend_core()
         dosuspend();
     } else
 #endif
-        Norep("Suspend command not available.");
+        Norep(cmdnotavail, "#suspend");
+    return 0;
+}
+
+/* '!' command, #shell */
+STATIC_PTR int
+dosh_core(VOID_ARGS)
+{
+#ifdef SHELL
+    /* access restrictions, if any, are handled in port code */
+    dosh();
+#else
+    Norep(cmdnotavail, "#shell");
+#endif
     return 0;
 }