OSDN Git Service

fix #38569
[jnethack/source.git] / src / dungeon.c
index 96b9959..700ede6 100644 (file)
@@ -1,5 +1,6 @@
-/* NetHack 3.6 dungeon.c       $NHDT-Date: 1448862377 2015/11/30 05:46:17 $  $NHDT-Branch: master $:$NHDT-Revision: 1.69 $ */
+/* NetHack 3.6 dungeon.c       $NHDT-Date: 1523308357 2018/04/09 21:12:37 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.87 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/*-Copyright (c) Robert Patrick Rankin, 2012. */
 /* NetHack may be freely redistributed.  See license for details. */
 
 #include "hack.h"
@@ -57,11 +58,13 @@ STATIC_DCL boolean FDECL(unreachable_level, (d_level *, BOOLEAN_P));
 STATIC_DCL void FDECL(tport_menu, (winid, char *, struct lchoice *, d_level *,
                                    BOOLEAN_P));
 STATIC_DCL const char *FDECL(br_string, (int));
+STATIC_DCL char FDECL(chr_u_on_lvl, (d_level *));
 STATIC_DCL void FDECL(print_branch, (winid, int, int, int, BOOLEAN_P,
                                      struct lchoice *));
 STATIC_DCL mapseen *FDECL(load_mapseen, (int));
 STATIC_DCL void FDECL(save_mapseen, (int, mapseen *));
 STATIC_DCL mapseen *FDECL(find_mapseen, (d_level *));
+STATIC_DCL mapseen *FDECL(find_mapseen_by_str, (const char *));
 STATIC_DCL void FDECL(print_mapseen, (winid, mapseen *, int, int, BOOLEAN_P));
 STATIC_DCL boolean FDECL(interest_mapseen, (mapseen *));
 STATIC_DCL void FDECL(traverse_mapseenchn, (BOOLEAN_P, winid,
@@ -246,7 +249,7 @@ dlb *stream;
         panic(
   "Premature EOF on dungeon description file!\r\nExpected %d bytes - got %d.",
               (size * nitems), (size * cnt));
-        terminate(EXIT_FAILURE);
+        nh_terminate(EXIT_FAILURE);
     }
 }
 
@@ -490,6 +493,7 @@ struct proto_dungeon *pd;
 
     branch_num = find_branch(dungeons[dgn].dname, pd);
     new_branch = (branch *) alloc(sizeof(branch));
+    (void) memset((genericptr_t)new_branch, 0, sizeof(branch));
     new_branch->next = (branch *) 0;
     new_branch->id = branch_id++;
     new_branch->type = correct_branch_type(&pd->tmpbranch[branch_num]);
@@ -545,6 +549,7 @@ struct proto_dungeon *pd;
 
     pd->final_lev[proto_index] = new_level =
         (s_level *) alloc(sizeof(s_level));
+    (void) memset((genericptr_t)new_level, 0, sizeof(s_level));
     /* load new level with data */
     Strcpy(new_level->proto, tlevel->name);
     new_level->boneid = tlevel->boneschar;
@@ -852,7 +857,7 @@ init_dungeons()
              * its branch.  First, the depth of the entry point:
              *
              *  depth of branch from "parent" dungeon
-             *  + -1 or 1 depending on a up or down stair or
+             *  + -1 or 1 depending on an up or down stair or
              *    0 if portal
              *
              * Followed by the depth of the top of the dungeon:
@@ -948,10 +953,22 @@ init_dungeons()
     /*
      *  I hate hardwiring these names. :-(
      */
+/*JP
     quest_dnum = dname_to_dnum("The Quest");
+*/
+    quest_dnum = dname_to_dnum("\83N\83G\83X\83g");
+/*JP
     sokoban_dnum = dname_to_dnum("Sokoban");
+*/
+    sokoban_dnum = dname_to_dnum("\91q\8cÉ\94Ô");
+/*JP
     mines_dnum = dname_to_dnum("The Gnomish Mines");
+*/
+    mines_dnum = dname_to_dnum("\83m\81[\83\80\82Ì\8dz\8eR");
+/*JP
     tower_dnum = dname_to_dnum("Vlad's Tower");
+*/
+    tower_dnum = dname_to_dnum("\83\94\83\89\83h\8cò\82Ì\93\83");
 
     /* one special fixup for dummy surface level */
     if ((x = find_level("dummy")) != 0) {
@@ -962,7 +979,7 @@ init_dungeons()
            instead of 0, so adjust the start point to shift endgame up */
         if (dunlevs_in_dungeon(&x->dlevel) > 1 - dungeons[i].depth_start)
             dungeons[i].depth_start -= 1;
-        /* TO DO: strip "dummy" out all the way here,
+        /* TODO: strip "dummy" out all the way here,
            so that it's hidden from <ctrl/O> feedback. */
     }
 
@@ -1216,16 +1233,16 @@ int upflag;
            destination instead of its enclosing region.
            Note: up vs down doesn't matter in this case
            because both specify the same exclusion area. */
-        place_lregion(dndest.nlx, dndest.nly, dndest.nhx, dndest.nhy, 0, 0, 0,
-                      0, LR_DOWNTELE, (d_level *) 0);
+        place_lregion(dndest.nlx, dndest.nly, dndest.nhx, dndest.nhy,
+                      0, 0, 0, 0, LR_DOWNTELE, (d_level *) 0);
     else if (up)
-        place_lregion(updest.lx, updest.ly, updest.hx, updest.hy, updest.nlx,
-                      updest.nly, updest.nhx, updest.nhy, LR_UPTELE,
-                      (d_level *) 0);
+        place_lregion(updest.lx, updest.ly, updest.hx, updest.hy,
+                      updest.nlx, updest.nly, updest.nhx, updest.nhy,
+                      LR_UPTELE, (d_level *) 0);
     else
-        place_lregion(dndest.lx, dndest.ly, dndest.hx, dndest.hy, dndest.nlx,
-                      dndest.nly, dndest.nhx, dndest.nhy, LR_DOWNTELE,
-                      (d_level *) 0);
+        place_lregion(dndest.lx, dndest.ly, dndest.hx, dndest.hy,
+                      dndest.nlx, dndest.nly, dndest.nhx, dndest.nhy,
+                      LR_DOWNTELE, (d_level *) 0);
 }
 
 /* place you on the special staircase */
@@ -1604,6 +1621,25 @@ level_difficulty()
              * The same applies to Vlad's Tower, although the increment
              * there is inconsequential compared to overall depth.
              */
+#if 0
+        /*
+         * The inside of the Wizard's Tower is also effectively a
+         * builds-up area, reached from a portal an arbitrary distance
+         * below rather than stairs 1 level beneath the entry level.
+         */
+        else if (On_W_tower_level(&u.uz) && In_W_tower(some_X, some_Y, &u.uz))
+            res += (fakewiz1.dlev - u.uz.dlev);
+            /*
+             * Handling this properly would need more information here:
+             * an inside/outside flag, or coordinates to calculate it.
+             * Unfortunately level difficulty may be wanted before
+             * coordinates have been chosen so simply extending this
+             * routine to take extra arguments is not sufficient to cope.
+             * The difference beyond naive depth-from-surface is small
+             * relative to the overall depth, so just ignore complications
+             * posed by W_tower.
+             */
+#endif /*0*/
     }
     return (xchar) res;
 }
@@ -1616,30 +1652,42 @@ lev_by_name(nam)
 const char *nam;
 {
     schar lev = 0;
-    s_level *slev;
+    s_level *slev = (s_level *)0;
     d_level dlev;
     const char *p;
     int idx, idxtoo;
     char buf[BUFSZ];
+    mapseen *mseen;
 
-    /* allow strings like "the oracle level" to find "oracle" */
-    if (!strncmpi(nam, "the ", 4))
-        nam += 4;
-    if ((p = strstri(nam, " level")) != 0 && p == eos((char *) nam) - 6) {
-        nam = strcpy(buf, nam);
-        *(eos(buf) - 6) = '\0';
-    }
-    /* hell is the old name, and wouldn't match; gehennom would match its
-       branch, yielding the castle level instead of the valley of the dead */
-    if (!strcmpi(nam, "gehennom") || !strcmpi(nam, "hell")) {
-        if (In_V_tower(&u.uz))
-            nam = " to Vlad's tower"; /* branch to... */
-        else
-            nam = "valley";
+    /* look at the player's custom level annotations first */
+    if ((mseen = find_mapseen_by_str(nam)) != 0) {
+        dlev = mseen->lev;
+    } else {
+        /* no matching annotation, check whether they used a name we know */
+
+#if 0 /*JP*//*\93ú\96{\8cê\82Å\82Í\8f\88\97\9d\82µ\82È\82¢*/
+        /* allow strings like "the oracle level" to find "oracle" */
+        if (!strncmpi(nam, "the ", 4))
+            nam += 4;
+        if ((p = strstri(nam, " level")) != 0 && p == eos((char *) nam) - 6) {
+            nam = strcpy(buf, nam);
+            *(eos(buf) - 6) = '\0';
+        }
+        /* hell is the old name, and wouldn't match; gehennom would match its
+           branch, yielding the castle level instead of the valley of the dead */
+        if (!strcmpi(nam, "gehennom") || !strcmpi(nam, "hell")) {
+            if (In_V_tower(&u.uz))
+                nam = " to Vlad's tower"; /* branch to... */
+            else
+                nam = "valley";
+        }
+#endif
+
+        if ((slev = find_level(nam)) != 0)
+            dlev = slev->dlevel;
     }
 
-    if ((slev = find_level(nam)) != 0) {
-        dlev = slev->dlevel;
+    if (mseen || slev) {
         idx = ledger_no(&dlev);
         if ((dlev.dnum == u.uz.dnum
              /* within same branch, or else main dungeon <-> gehennom */
@@ -1651,7 +1699,7 @@ const char *nam;
                 wizard
                 || (level_info[idx].flags & (FORGOTTEN | VISITED))
                        == VISITED)) {
-            lev = depth(&slev->dlevel);
+            lev = depth(&dlev);
         }
     } else { /* not a specific level; try branch names */
         idx = find_branch(nam, (struct proto_dungeon *) 0);
@@ -1751,15 +1799,37 @@ int type;
 {
     switch (type) {
     case BR_PORTAL:
+/*JP
         return "Portal";
+*/
+        return "\96\82\96@\82Ì\93ü\82è\8cû";
     case BR_NO_END1:
+/*JP
         return "Connection";
+*/
+        return "\90Ú\91±\95\94";
     case BR_NO_END2:
+/*JP
         return "One way stair";
+*/
+        return "\88ê\95û\92Ê\8ds\82Ì\8aK\92i";
     case BR_STAIR:
+/*JP
         return "Stair";
+*/
+        return "\8aK\92i";
     }
+/*JP
     return " (unknown)";
+*/
+    return " (\95s\96¾)";
+}
+
+STATIC_OVL char
+chr_u_on_lvl(dlev)
+d_level *dlev;
+{
+    return u.uz.dnum == dlev->dnum && u.uz.dlevel == dlev->dlevel ? '*' : ' ';
 }
 
 /* Print all child branches between the lower and upper bounds. */
@@ -1779,8 +1849,17 @@ struct lchoice *lchoices_p;
     for (br = branches; br; br = br->next) {
         if (br->end1.dnum == dnum && lower_bound < br->end1.dlevel
             && br->end1.dlevel <= upper_bound) {
-            Sprintf(buf, "   %s to %s: %d", br_string(br->type),
+#if 0 /*JP*/
+            Sprintf(buf, "%c %s to %s: %d",
+                    bymenu ? chr_u_on_lvl(&br->end1) : ' ',
+                    br_string(br->type),
                     dungeons[br->end2.dnum].dname, depth(&br->end1));
+#else
+            Sprintf(buf, "%c %s\82©\82ç%s: %d",
+                    bymenu ? chr_u_on_lvl(&br->end1) : ' ',
+                    br_string(br->type),
+                    dungeons[br->end2.dnum].dname, depth(&br->end1));
+#endif
             if (bymenu)
                 tport_menu(win, buf, lchoices_p, &br->end1,
                            unreachable_level(&br->end1, FALSE));
@@ -1806,8 +1885,8 @@ xchar *rdgn;
     branch *br;
     anything any;
     struct lchoice lchoices;
-
     winid win = create_nhwindow(NHW_MENU);
+
     if (bymenu) {
         start_menu(win);
         lchoices.idx = 0;
@@ -1818,21 +1897,37 @@ xchar *rdgn;
         if (bymenu && In_endgame(&u.uz) && i != astral_level.dnum)
             continue;
         unplaced = unplaced_floater(dptr);
+/*JP
         descr = unplaced ? "depth" : "level";
+*/
+        descr = unplaced ? "\92n\89º" : "\83\8c\83x\83\8b";
         nlev = dptr->num_dunlevs;
         if (nlev > 1)
+#if 0 /*JP*/
             Sprintf(buf, "%s: %s %d to %d", dptr->dname, makeplural(descr),
                     dptr->depth_start, dptr->depth_start + nlev - 1);
+#else
+            Sprintf(buf, "%s: %s%d\82©\82ç%d", dptr->dname, descr,
+                    dptr->depth_start, dptr->depth_start + nlev - 1);
+#endif
         else
             Sprintf(buf, "%s: %s %d", dptr->dname, descr, dptr->depth_start);
 
         /* Most entrances are uninteresting. */
         if (dptr->entry_lev != 1) {
             if (dptr->entry_lev == nlev)
+/*JP
                 Strcat(buf, ", entrance from below");
+*/
+                Strcat(buf, ", \89º\82©\82ç\82Ì\93ü\82è\8cû");
             else
+#if 0 /*JP*/
                 Sprintf(eos(buf), ", entrance on %d",
                         dptr->depth_start + dptr->entry_lev - 1);
+#else
+                Sprintf(eos(buf), ", %d\82Ì\93ü\82è\8cû",
+                        dptr->depth_start + dptr->entry_lev - 1);
+#endif
         }
         if (bymenu) {
             any = zeroany;
@@ -1853,7 +1948,9 @@ xchar *rdgn;
             print_branch(win, i, last_level, slev->dlevel.dlevel, bymenu,
                          &lchoices);
 
-            Sprintf(buf, "   %s: %d", slev->proto, depth(&slev->dlevel));
+            Sprintf(buf, "%c %s: %d",
+                    chr_u_on_lvl(&slev->dlevel),
+                    slev->proto, depth(&slev->dlevel));
             if (Is_stronghold(&slev->dlevel))
                 Sprintf(eos(buf), " (tune %s)", tune);
             if (bymenu)
@@ -1873,7 +1970,10 @@ xchar *rdgn;
         menu_item *selected;
         int idx;
 
+/*JP
         end_menu(win, "Level teleport to where:");
+*/
+        end_menu(win, "\82Ç\82±\82É\8fu\8aÔ\88Ú\93®\82·\82é\81F");
         n = select_menu(win, PICK_ONE, &selected);
         destroy_nhwindow(win);
         if (n > 0) {
@@ -1893,11 +1993,19 @@ xchar *rdgn;
         if (br->end1.dnum == n_dgns) {
             if (first) {
                 putstr(win, 0, "");
+/*JP
                 putstr(win, 0, "Floating branches");
+*/
+                putstr(win, 0, "\95\82\93®\95ª\8aò");
                 first = FALSE;
             }
+#if 0 /*JP*/
             Sprintf(buf, "   %s to %s", br_string(br->type),
                     dungeons[br->end2.dnum].dname);
+#else
+            Sprintf(buf, "   %s\82©\82ç%s", br_string(br->type),
+                    dungeons[br->end2.dnum].dname);
+#endif
             putstr(win, 0, buf);
         }
     }
@@ -1905,29 +2013,50 @@ xchar *rdgn;
     /* I hate searching for the invocation pos while debugging. -dean */
     if (Invocation_lev(&u.uz)) {
         putstr(win, 0, "");
+#if 0 /*JP*/
         Sprintf(buf, "Invocation position @ (%d,%d), hero @ (%d,%d)",
                 inv_pos.x, inv_pos.y, u.ux, u.uy);
+#else
+        Sprintf(buf, "\94­\93®\88Ê\92u @ (%d,%d), \83v\83\8c\83C\83\84\81[ @ (%d,%d)",
+                inv_pos.x, inv_pos.y, u.ux, u.uy);
+#endif
         putstr(win, 0, buf);
-    }
-    /*
-     * The following is based on the assumption that the inter-level portals
-     * created by the level compiler (not the dungeon compiler) only exist
-     * one per level (currently true, of course).
-     */
-    else if (Is_earthlevel(&u.uz) || Is_waterlevel(&u.uz)
-             || Is_firelevel(&u.uz) || Is_airlevel(&u.uz)) {
+    } else {
         struct trap *trap;
+
+        /* if current level has a magic portal, report its location;
+           this assumes that there is at most one magic portal on any
+           given level; quest and ft.ludios have pairs (one in main
+           dungeon matched with one in the corresponding branch), the
+           elemental planes have singletons (connection to next plane) */
+        *buf = '\0';
         for (trap = ftrap; trap; trap = trap->ntrap)
             if (trap->ttyp == MAGIC_PORTAL)
                 break;
 
-        putstr(win, 0, "");
         if (trap)
-            Sprintf(buf, "Portal @ (%d,%d), hero @ (%d,%d)", trap->tx,
-                    trap->ty, u.ux, u.uy);
-        else
-            Sprintf(buf, "No portal found.");
-        putstr(win, 0, buf);
+            Sprintf(buf, "Portal @ (%d,%d), hero @ (%d,%d)",
+                    trap->tx, trap->ty, u.ux, u.uy);
+
+        /* only report "no portal found" when actually expecting a portal */
+#if 0 /*JP*/
+        else if (Is_earthlevel(&u.uz) || Is_waterlevel(&u.uz)
+                 || Is_firelevel(&u.uz) || Is_airlevel(&u.uz)
+                 || Is_qstart(&u.uz) || at_dgn_entrance("The Quest")
+                 || Is_knox(&u.uz))
+#else
+        else if (Is_earthlevel(&u.uz) || Is_waterlevel(&u.uz)
+                 || Is_firelevel(&u.uz) || Is_airlevel(&u.uz)
+                 || Is_qstart(&u.uz) || at_dgn_entrance("\83N\83G\83X\83g")
+                 || Is_knox(&u.uz))
+#endif
+            Strcpy(buf, "No portal found.");
+
+        /* only give output if we found a portal or expected one and didn't */
+        if (*buf) {
+            putstr(win, 0, "");
+            putstr(win, 0, buf);
+        }
     }
 
     display_nhwindow(win, TRUE);
@@ -1995,15 +2124,36 @@ donamelevel()
     if (!(mptr = find_mapseen(&u.uz)))
         return 0;
 
+    nbuf[0] = '\0';
+#ifdef EDIT_GETLIN
+    if (mptr->custom) {
+        (void) strncpy(nbuf, mptr->custom, BUFSZ);
+        nbuf[BUFSZ - 1] = '\0';
+    }
+#else
     if (mptr->custom) {
         char tmpbuf[BUFSZ];
+
+#if 0 /*JP*/
         Sprintf(tmpbuf, "Replace annotation \"%.30s%s\" with?", mptr->custom,
+                (strlen(mptr->custom) > 30) ? "..." : "");
+#else
+        Sprintf(tmpbuf, "\8c»\8dÝ\82Ì\83\81\83\82\81u%.30s%s\81v\82ð\89½\82É\8f\91\82«\8a·\82¦\82é\81H", mptr->custom,
                 strlen(mptr->custom) > 30 ? "..." : "");
+#endif
         getlin(tmpbuf, nbuf);
     } else
+#endif
+/*JP
         getlin("What do you want to call this dungeon level?", nbuf);
-    if (index(nbuf, '\033'))
+*/
+        getlin("\82±\82Ì\8aK\82ð\89½\82Æ\8cÄ\82Ô\81H", nbuf);
+
+    /* empty input or ESC means don't add or change annotation;
+       space-only means discard current annotation without adding new one */
+    if (!*nbuf || *nbuf == '\033')
         return 0;
+    /* strip leading and trailing spaces, compress out consecutive spaces */
     (void) mungspaces(nbuf);
 
     /* discard old annotation, if any */
@@ -2012,7 +2162,8 @@ donamelevel()
         mptr->custom = (char *) 0;
         mptr->custom_lth = 0;
     }
-    /* add new annotation, unless it's empty or a single space */
+    /* add new annotation, unless it's all spaces (which will be an
+       empty string after mungspaces() above) */
     if (*nbuf && strcmp(nbuf, " ")) {
         mptr->custom = dupstr(nbuf);
         mptr->custom_lth = strlen(mptr->custom);
@@ -2034,6 +2185,20 @@ d_level *lev;
     return mptr;
 }
 
+STATIC_OVL mapseen *
+find_mapseen_by_str(s)
+const char *s;
+{
+    mapseen *mptr;
+
+    for (mptr = mapseenchn; mptr; mptr = mptr->next)
+        if (mptr->custom && !strcmpi(s, mptr->custom))
+            break;
+
+    return mptr;
+}
+
+
 void
 forget_mapseen(ledger_num)
 int ledger_num;
@@ -2063,6 +2228,39 @@ int ledger_num;
     }
 }
 
+void
+rm_mapseen(ledger_num)
+int ledger_num;
+{
+    mapseen *mptr, *mprev = (mapseen *)0;
+    struct cemetery *bp, *bpnext;
+
+    for (mptr = mapseenchn; mptr; mprev = mptr, mptr = mptr->next)
+        if (dungeons[mptr->lev.dnum].ledger_start + mptr->lev.dlevel == ledger_num)
+            break;
+
+    if (!mptr)
+        return;
+
+    if (mptr->custom)
+        free((genericptr_t) mptr->custom);
+
+    bp = mptr->final_resting_place;
+    while (bp) {
+        bpnext = bp->next;
+        free(bp);
+        bp = bpnext;
+    }
+
+    if (mprev) {
+        mprev->next = mptr->next;
+        free(mptr);
+    } else {
+        mapseenchn = mptr->next;
+        free(mptr);
+    }
+}
+
 STATIC_OVL void
 save_mapseen(fd, mptr)
 int fd;
@@ -2119,6 +2317,50 @@ int fd;
     return load;
 }
 
+/* to support '#stats' wizard-mode command */
+void
+overview_stats(win, statsfmt, total_count, total_size)
+winid win;
+const char *statsfmt;
+long *total_count, *total_size;
+{
+    char buf[BUFSZ], hdrbuf[QBUFSZ];
+    long ocount, osize, bcount, bsize, acount, asize;
+    struct cemetery *ce;
+    mapseen *mptr = find_mapseen(&u.uz);
+
+    ocount = bcount = acount = osize = bsize = asize = 0L;
+    for (mptr = mapseenchn; mptr; mptr = mptr->next) {
+        ++ocount;
+        osize += (long) sizeof *mptr;
+        for (ce = mptr->final_resting_place; ce; ce = ce->next) {
+            ++bcount;
+            bsize += (long) sizeof *ce;
+        }
+        if (mptr->custom_lth) {
+            ++acount;
+            asize += (long) (mptr->custom_lth + 1);
+        }
+    }
+
+    Sprintf(hdrbuf, "general, size %ld", (long) sizeof (mapseen));
+    Sprintf(buf, statsfmt, hdrbuf, ocount, osize);
+    putstr(win, 0, buf);
+    if (bcount) {
+        Sprintf(hdrbuf, "cemetery, size %ld",
+                (long) sizeof (struct cemetery));
+        Sprintf(buf, statsfmt, hdrbuf, bcount, bsize);
+        putstr(win, 0, buf);
+    }
+    if (acount) {
+        Sprintf(hdrbuf, "annotations, text");
+        Sprintf(buf, statsfmt, hdrbuf, acount, asize);
+        putstr(win, 0, buf);
+    }
+    *total_count += ocount + bcount + acount;
+    *total_size += osize + bsize + asize;
+}
+
 /* Remove all mapseen objects for a particular dnum.
  * Useful during quest expulsion to remove quest levels.
  * [No longer deleted, just marked as unreachable.  #overview will
@@ -2280,7 +2522,10 @@ recalc_mapseen()
     /* flags.castle, flags.valley, flags.msanctum retain previous value */
     mptr->flags.forgot = 0;
     /* flags.quest_summons disabled once quest finished */
+/*JP
     mptr->flags.quest_summons = (at_dgn_entrance("The Quest")
+*/
+    mptr->flags.quest_summons = (at_dgn_entrance("\83N\83G\83X\83g")
                                  && u.uevent.qcalled
                                  && !(u.uevent.qcompleted
                                       || u.uevent.qexpelled
@@ -2421,6 +2666,9 @@ recalc_mapseen()
             /*  An automatic annotation is added to the Castle and
              *  to Fort Ludios once their structure's main entrance
              *  has been seen (in person or via magic mapping).
+             *  For the Fort, that entrance is just a secret door
+             *  which will be converted into a regular one when
+             *  located (or destroyed).
              * DOOR: possibly a lowered drawbridge's open portcullis;
              * DBWALL: a raised drawbridge's "closed door";
              * DRAWBRIDGE_DOWN: the span provided by lowered bridge,
@@ -2430,15 +2678,33 @@ recalc_mapseen()
              *  the adjacent DBWALL has been seen.
              */
             case DOOR:
+                if (Is_knox(&u.uz)) {
+                    int ty, tx = x - 4;
+
+                    /* Throne is four columns left, either directly in
+                     * line or one row higher or lower, and doesn't have
+                     * to have been seen yet.
+                     *   ......|}}}.
+                     *   ..\...S}...
+                     *   ..\...S}...
+                     *   ......|}}}.
+                     * For 3.6.0 and earlier, it was always in direct line:
+                     * both throne and door on the lower of the two rows.
+                     */
+                    for (ty = y - 1; ty <= y + 1; ++ty)
+                        if (isok(tx, ty) && IS_THRONE(levl[tx][ty].typ)) {
+                            mptr->flags.ludios = 1;
+                            break;
+                        }
+                    break;
+                }
                 if (is_drawbridge_wall(x, y) < 0)
                     break;
-            /* else FALLTHRU */
+                /*FALLTHRU*/
             case DBWALL:
             case DRAWBRIDGE_DOWN:
                 if (Is_stronghold(&u.uz))
                     mptr->flags.castle = 1, mptr->flags.castletune = 1;
-                else if (Is_knox(&u.uz))
-                    mptr->flags.ludios = 1;
                 break;
             default:
                 break;
@@ -2558,14 +2824,24 @@ const char *obj;
     /* players are computer scientists: 0, 1, 2, n */
     switch (x) {
     case 0:
+/*JP:\82±\82±\82É\82Í\97\88\82È\82¢\82Í\82¸*/
         return "no";
     /* an() returns too much.  index is ok in this case */
     case 1:
+/*JP
         return index(vowels, *obj) ? "an" : "a";
+*/
+       return "";
     case 2:
+/*JP
         return "some";
+*/
+        return "\93ñ\82Â\82Ì";
     case 3:
+/*JP
         return "many";
+*/
+        return "\91½\82­\82Ì";
     }
 
     return "(unknown)";
@@ -2582,13 +2858,22 @@ branch *br;
 
     switch (br->type) {
     case BR_PORTAL:
+/*JP
         return closed_portal ? "Sealed portal" : "Portal";
+*/
+        return closed_portal ? "\95\95\88ó\82³\82ê\82½\96\82\96@\82Ì\93ü\8cû" : "\96\82\96@\82Ì\93ü\8cû";
     case BR_NO_END1:
         return "Connection";
     case BR_NO_END2:
+/*JP
         return br->end1_up ? "One way stairs up" : "One way stairs down";
+*/
+        return br->end1_up ? "\8fã\82è\95Ð\93¹\8aK\92i" : "\89º\82è\95Ð\93¹\8aK\92i";
     case BR_STAIR:
+/*JP
         return br->end1_up ? "Stairs up" : "Stairs down";
+*/
+        return br->end1_up ? "\8fã\82è\8aK\92i" : "\89º\82è\8aK\92i";
     }
 
     return "(unknown)";
@@ -2605,23 +2890,41 @@ int indx;
     *outbuf = '\0';
     switch (indx) {
     case -5:
+/*JP
         Strcpy(outbuf, "Astral Plane");
+*/
+        Strcpy(outbuf, "\93V\8fã\8aE");
         break;
     case -4:
+/*JP
         planename = "Water";
+*/
+        planename = "\90\85";
         break;
     case -3:
+/*JP
         planename = "Fire";
+*/
+        planename = "\89Î";
         break;
     case -2:
+/*JP
         planename = "Air";
+*/
+        planename = "\95\97";
         break;
     case -1:
+/*JP
         planename = "Earth";
+*/
+        planename = "\93y";
         break;
     }
     if (planename)
+/*JP
         Sprintf(outbuf, "Plane of %s", planename);
+*/
+        Sprintf(outbuf, "%s\82Ì\90¸\97ì\8aE", planename);
     else if (!*outbuf)
         Sprintf(outbuf, "unknown plane #%d", indx);
     return outbuf;
@@ -2631,45 +2934,85 @@ STATIC_OVL const char *
 shop_string(rtype)
 int rtype;
 {
+#if 0 /*JP*/
     const char *str = "shop"; /* catchall */
+#else
+    const char *str = "\93X"; /* catchall */
+#endif
 
     /* Yuck, redundancy...but shclass.name doesn't cut it as a noun */
     switch (rtype) {
     case SHOPBASE - 1:
+/*JP
         str = "untended shop";
+*/
+        str = "\95ú\8aü\82³\82ê\82½\93X";
         break; /* see recalc_mapseen */
     case SHOPBASE:
+/*JP
         str = "general store";
+*/
+        str = "\8eG\89Ý\93X";
         break;
     case ARMORSHOP:
+/*JP
         str = "armor shop";
+*/
+        str = "\96h\8bï\93X";
         break;
     case SCROLLSHOP:
+/*JP
         str = "scroll shop";
+*/
+        str = "\8aª\95¨\93X";
         break;
     case POTIONSHOP:
+/*JP
         str = "potion shop";
+*/
+        str = "\96ò\93X";
         break;
     case WEAPONSHOP:
+/*JP
         str = "weapon shop";
+*/
+        str = "\95\90\8aí\93X";
         break;
     case FOODSHOP:
+/*JP
         str = "delicatessen";
+*/
+        str = "\90H\97¿\95i\93X";
         break;
     case RINGSHOP:
+/*JP
         str = "jewelers";
+*/
+        str = "\95ó\90Î\93X";
         break;
     case WANDSHOP:
+/*JP
         str = "wand shop";
+*/
+        str = "\8fñ\93X";
         break;
     case BOOKSHOP:
+/*JP
         str = "bookstore";
+*/
+        str = "\8f\91\93X";
         break;
     case FODDERSHOP:
+/*JP
         str = "health food store";
+*/
+        str = "\8c\92\8dN\90H\95i\93X";
         break;
     case CANDLESHOP:
+/*JP
         str = "lighting shop";
+*/
+        str = "\8fÆ\96¾\93X";
         break;
     default:
         break;
@@ -2708,12 +3051,21 @@ char *outbuf;
 #endif
 #define COMMA (i++ > 0 ? ", " : PREFIX)
 /* "iterate" once; safe to use as ``if (cond) ADDTOBUF(); else whatever;'' */
+#if 0 /*JP*/
 #define ADDNTOBUF(nam, var)                                                  \
     do {                                                                     \
         if (var)                                                             \
             Sprintf(eos(buf), "%s%s %s%s", COMMA, seen_string((var), (nam)), \
                     (nam), plur(var));                                       \
     } while (0)
+#else
+#define ADDNTOBUF(nam, var)                                                  \
+    do {                                                                     \
+        if (var)                                                             \
+            Sprintf(eos(buf), "%s%s%s", COMMA, seen_string((var), (nam)),    \
+                    (nam));                                                  \
+    } while (0)
+#endif
 #define ADDTOBUF(nam, var)                           \
     do {                                             \
         if (var)                                     \
@@ -2748,12 +3100,18 @@ boolean printdun;
             || In_endgame(&mptr->lev))
             Sprintf(buf, "%s:", dungeons[dnum].dname);
         else if (builds_up(&mptr->lev))
+/*JP
             Sprintf(buf, "%s: levels %d up to %d",
+*/
+            Sprintf(buf, "%s: %d\8aK\82©\82ç%d\8aK",
                     dungeons[dnum].dname,
                     depthstart + dungeons[dnum].entry_lev - 1,
                     depthstart + dungeons[dnum].dunlev_ureached - 1);
         else
+/*JP
             Sprintf(buf, "%s: levels %d to %d",
+*/
+            Sprintf(buf, "%s: %d\8aK\82©\82ç%d\8aK",
                     dungeons[dnum].dname, depthstart,
                     depthstart + dungeons[dnum].dunlev_ureached - 1);
         putstr(win, !final ? ATR_INVERSE : 0, buf);
@@ -2764,11 +3122,10 @@ boolean printdun;
     if (In_endgame(&mptr->lev))
         Sprintf(buf, "%s%s:", TAB, endgamelevelname(tmpbuf, i));
     else
-        /* FIXME: when this branch has only one level (Ft.Ludios),
-         * listing "Level 1:" for it might confuse inexperienced
-         * players into thinking there's more than one.
-         */
+/*JP
         Sprintf(buf, "%sLevel %d:", TAB, i);
+*/
+        Sprintf(buf, "%s%d\8aK:", TAB, i);
 
     /* wizmode prints out proto dungeon names for clarity */
     if (wizard) {
@@ -2779,10 +3136,19 @@ boolean printdun;
     }
     /* [perhaps print custom annotation on its own line when it's long] */
     if (mptr->custom)
-        Sprintf(eos(buf), " (%s)", mptr->custom);
+        Sprintf(eos(buf), " \"%s\"", mptr->custom);
     if (on_level(&u.uz, &mptr->lev))
+#if 0 /*JP*/
         Sprintf(eos(buf), " <- You %s here.",
-                (!final || (final == 1 && how == ASCENDED)) ? "are" : "were");
+                (!final || (final == 1 && how == ASCENDED)) ? "are"
+                  : (final == 1 && how == ESCAPED) ? "left from"
+                    : "were");
+#else
+        Sprintf(eos(buf), " <- \82±\82±%s\81D",
+                (!final || (final == 1 && how == ASCENDED)) ? "\82É\82¢\82é"
+                  : (final == 1 && how == ESCAPED) ? "\82©\82ç\94²\82¯\82½"
+                    : "\82É\82¢\82½");
+#endif
     putstr(win, !final ? ATR_BOLD : 0, buf);
 
     if (mptr->flags.forgot)
@@ -2797,7 +3163,10 @@ boolean printdun;
          */
         if (mptr->feat.nshop > 0) {
             if (mptr->feat.nshop > 1)
+/*JP
                 ADDNTOBUF("shop", mptr->feat.nshop);
+*/
+                ADDNTOBUF("\93X", mptr->feat.nshop);
             else
                 Sprintf(eos(buf), "%s%s", COMMA,
                         an(shop_string(mptr->feat.shoptype)));
@@ -2805,19 +3174,43 @@ boolean printdun;
         if (mptr->feat.naltar > 0) {
             /* Temples + non-temple altars get munged into just "altars" */
             if (mptr->feat.ntemple != mptr->feat.naltar)
+/*JP
                 ADDNTOBUF("altar", mptr->feat.naltar);
+*/
+                ADDNTOBUF("\8dÕ\92d", mptr->feat.naltar);
             else
+/*JP
                 ADDNTOBUF("temple", mptr->feat.ntemple);
+*/
+                ADDNTOBUF("\8e\9b\89@", mptr->feat.ntemple);
 
             /* only print out altar's god if they are all to your god */
             if (Amask2align(Msa2amask(mptr->feat.msalign)) == u.ualign.type)
+/*JP
                 Sprintf(eos(buf), " to %s", align_gname(u.ualign.type));
+*/
+                Sprintf(eos(buf), "(%s)", align_gname(u.ualign.type));
         }
+/*JP
         ADDNTOBUF("throne", mptr->feat.nthrone);
+*/
+        ADDNTOBUF("\8bÊ\8dÀ", mptr->feat.nthrone);
+/*JP
         ADDNTOBUF("fountain", mptr->feat.nfount);
+*/
+        ADDNTOBUF("\90ò", mptr->feat.nfount);
+/*JP
         ADDNTOBUF("sink", mptr->feat.nsink);
+*/
+        ADDNTOBUF("\97¬\82µ\91ä", mptr->feat.nsink);
+/*JP
         ADDNTOBUF("grave", mptr->feat.ngrave);
+*/
+        ADDNTOBUF("\95æ", mptr->feat.ngrave);
+/*JP
         ADDNTOBUF("tree", mptr->feat.ntree);
+*/
+        ADDNTOBUF("\96Ø", mptr->feat.ntree);
 #if 0
         ADDTOBUF("water", mptr->feat.water);
         ADDTOBUF("lava", mptr->feat.lava);
@@ -2834,49 +3227,100 @@ boolean printdun;
     /* we assume that these are mutually exclusive */
     *buf = '\0';
     if (mptr->flags.oracle) {
+/*JP
         Sprintf(buf, "%sOracle of Delphi.", PREFIX);
+*/
+        Sprintf(buf, "%s\83f\83\8b\83t\83@\83C\82Ì\90_\93a\81D", PREFIX);
     } else if (In_sokoban(&mptr->lev)) {
+#if 0 /*JP*/
         Sprintf(buf, "%s%s.", PREFIX,
                 mptr->flags.sokosolved ? "Solved" : "Unsolved");
+#else
+        Sprintf(buf, "%s%s.", PREFIX,
+                mptr->flags.sokosolved ? "\83N\83\8a\83A\8dÏ" : "\96¢\83N\83\8a\83A");
+#endif
     } else if (mptr->flags.bigroom) {
+/*JP
         Sprintf(buf, "%sA very big room.", PREFIX);
+*/
+        Sprintf(buf, "%s\82Æ\82Ä\82à\91å\82«\82¢\95\94\89®\81D", PREFIX);
     } else if (mptr->flags.roguelevel) {
+/*JP
         Sprintf(buf, "%sA primitive area.", PREFIX);
-    } else if (mptr->flags.quest_summons) {
-        Sprintf(buf, "%sSummoned by %s.", PREFIX, ldrname());
+*/
+        Sprintf(buf, "%s\92P\8f\83\82È\95\94\89®\81D", PREFIX);
     } else if (on_level(&mptr->lev, &qstart_level)) {
+#if 0 /*JP*/
         Sprintf(buf, "%sHome%s.", PREFIX,
                 mptr->flags.unreachable ? " (no way back...)" : "");
+#else
+        Sprintf(buf, "%s\8cÌ\8b½%s\81D", PREFIX,
+                mptr->flags.unreachable ? "(\96ß\82ê\82È\82¢\81D\81D\81D)" : "");
+#endif
         if (u.uevent.qcompleted)
+/*JP
             Sprintf(buf, "%sCompleted quest for %s.", PREFIX, ldrname());
+*/
+            Sprintf(buf, "%s%s\82Ì\82½\82ß\82É\83N\83G\83X\83g\82ð\8a®\90\8b\82µ\82½\81D", PREFIX, ldrname());
         else if (mptr->flags.questing)
+/*JP
             Sprintf(buf, "%sGiven quest by %s.", PREFIX, ldrname());
+*/
+            Sprintf(buf, "%s%s\82©\82ç\83N\83G\83X\83g\82ð\97^\82¦\82ç\82ê\82½\81D", PREFIX, ldrname());
     } else if (mptr->flags.ludios) {
         /* presence of the ludios branch in #overview output indicates that
            the player has made it onto the level; presence of this annotation
            indicates that the fort's entrance has been seen (or mapped) */
+/*JP
         Sprintf(buf, "%sFort Ludios.", PREFIX);
+*/
+        Sprintf(buf, "%s\83\8d\81[\83f\83B\83I\83X\8dÔ\81D", PREFIX);
     } else if (mptr->flags.castle) {
+/*JP
         Sprintf(buf, "%sThe castle%s.", PREFIX, tunesuffix(mptr, tmpbuf));
+*/
+        Sprintf(buf, "%s\8fé%s\81D", PREFIX, tunesuffix(mptr, tmpbuf));
     } else if (mptr->flags.valley) {
+/*JP
         Sprintf(buf, "%sValley of the Dead.", PREFIX);
+*/
+        Sprintf(buf, "%s\8e\80\82Ì\92J\81D", PREFIX);
     } else if (mptr->flags.msanctum) {
+/*JP
         Sprintf(buf, "%sMoloch's Sanctum.", PREFIX);
+*/
+        Sprintf(buf, "%s\83\82\81[\83\8d\83b\83N\82Ì\90¹\88æ\81D", PREFIX);
     }
     if (*buf)
         putstr(win, 0, buf);
+    /* quest entrance is not mutually-exclusive with bigroom or rogue level */
+    if (mptr->flags.quest_summons) {
+/*JP
+        Sprintf(buf, "%sSummoned by %s.", PREFIX, ldrname());
+*/
+        Sprintf(buf, "%s%s\82©\82ç\8cÄ\82Ñ\8fo\82³\82ê\82½\81D", PREFIX, ldrname());
+        putstr(win, 0, buf);
+    }
 
     /* print out branches */
     if (mptr->br) {
+#if 0 /*JP*/
         Sprintf(buf, "%s%s to %s", PREFIX, br_string2(mptr->br),
                 dungeons[mptr->br->end2.dnum].dname);
+#else
+        Sprintf(buf, "%s%s\82Ö\82Ì%s", PREFIX, dungeons[mptr->br->end2.dnum].dname,
+               br_string2(mptr->br));
+#endif
 
         /* Since mapseen objects are printed out in increasing order
          * of dlevel, clarify which level this branch is going to
          * if the branch goes upwards.  Unless it's the end game.
          */
         if (mptr->br->end1_up && !In_endgame(&(mptr->br->end2)))
+/*JP
             Sprintf(eos(buf), ", level %d", depth(&(mptr->br->end2)));
+*/
+            Sprintf(eos(buf), ", %d\8aK", depth(&(mptr->br->end2)));
         Strcat(buf, ".");
         putstr(win, 0, buf);
     }
@@ -2890,19 +3334,29 @@ boolean printdun;
             if (bp->bonesknown || wizard || final)
                 ++kncnt;
         if (kncnt) {
+/*JP
             Sprintf(buf, "%s%s", PREFIX, "Final resting place for");
+*/
+            Sprintf(buf, "%s%s", PREFIX, "\8dÅ\8aú\82Ì\92n:");
             putstr(win, 0, buf);
             if (died_here) {
                 /* disclosure occurs before bones creation, so listing dead
                    hero here doesn't give away whether bones are produced */
-                formatkiller(tmpbuf, sizeof tmpbuf, how);
+                formatkiller(tmpbuf, sizeof tmpbuf, how, TRUE);
+#if 0 /*JP*/
                 /* rephrase a few death reasons to work with "you" */
                 (void) strsubst(tmpbuf, " himself", " yourself");
                 (void) strsubst(tmpbuf, " herself", " yourself");
                 (void) strsubst(tmpbuf, " his ", " your ");
                 (void) strsubst(tmpbuf, " her ", " your ");
+#endif
+#if 0 /*JP*/
                 Sprintf(buf, "%s%syou, %s%c", PREFIX, TAB, tmpbuf,
                         --kncnt ? ',' : '.');
+#else
+                Sprintf(buf, "%s%s     %s%c", PREFIX, TAB, tmpbuf,
+                        --kncnt ? ',' : '.');
+#endif
                 putstr(win, 0, buf);
             }
             for (bp = mptr->final_resting_place; bp; bp = bp->next) {