]> granicus.if.org Git - nethack/commitdiff
concealing unknown branch stairs
authorPatR <rankin@nethack.org>
Thu, 29 Jul 2021 10:32:58 +0000 (03:32 -0700)
committerPatR <rankin@nethack.org>
Thu, 29 Jul 2021 10:32:58 +0000 (03:32 -0700)
First cut at displaying branch stairs/ladder up/down as ordinary
stairs/ladder up/down if the destination hasn't been visited yet.

Stepping on stairs with 'mention_decor' enabled, or using ':' when
already on them, will report regular stairs' destination level.
Probably not very useful since it's just N+1 for downstairs or N-1
for upstairs when currently on level N.

It's based on whether the destination level has been visited, not
on whether the stairs have been traversed, so reaching a level via
trap or level teleporation can make the level's stairs known when
their destination really shouldn't be discovered yet.

include/extern.h
src/display.c
src/dungeon.c
src/invent.c

index f0d3292e0dcd5fb762f50a298006c1d9b4ce662b..07aa255b445680743d28e8d59037c4fb81ab3842 100644 (file)
@@ -634,6 +634,7 @@ extern unsigned int induced_align(int);
 extern boolean Invocation_lev(d_level *);
 extern xchar level_difficulty(void);
 extern schar lev_by_name(const char *);
+extern boolean known_branch_stairs(stairway *, char *, boolean);
 extern schar print_dungeon(boolean, schar *, xchar *);
 extern char *get_annotation(d_level *);
 extern int donamelevel(void);
index 2824ebd3638f228292c15a07c34fd17d4a6fdad2..bbcd3296074751669b92608e2549eb6da28fe211 100644 (file)
@@ -1856,14 +1856,14 @@ back_to_glyph(xchar x, xchar y)
         break;
     case STAIRS:
         sway = stairway_at(x, y);
-        if (sway && (sway->tolev.dnum != u.uz.dnum))
+        if (known_branch_stairs(sway, (char *) 0, FALSE))
             idx = (ptr->ladder & LA_DOWN) ? S_brdnstair : S_brupstair;
         else
             idx = (ptr->ladder & LA_DOWN) ? S_dnstair : S_upstair;
         break;
     case LADDER:
         sway = stairway_at(x, y);
-        if (sway && (sway->tolev.dnum != u.uz.dnum))
+        if (known_branch_stairs(sway, (char *) 0, FALSE))
             idx = (ptr->ladder & LA_DOWN) ? S_brdnladder : S_brupladder;
         else
             idx = (ptr->ladder & LA_DOWN) ? S_dnladder : S_upladder;
index 9bf9343e6c15890705f5f19f328ed120c0e3cc49..ccd92335e8df53b2fe13ebd173fd3dcb2f6c8bfd 100644 (file)
@@ -1279,7 +1279,8 @@ ledger_to_dnum(xchar ledgerno)
     /* find i such that (i->base + 1) <= ledgerno <= (i->base + i->count) */
     for (i = 0; i < g.n_dgns; i++)
         if (g.dungeons[i].ledger_start < ledgerno
-            && ledgerno <= g.dungeons[i].ledger_start + g.dungeons[i].num_dunlevs)
+            && (ledgerno
+                <= g.dungeons[i].ledger_start + g.dungeons[i].num_dunlevs))
             return (xchar) i;
 
     panic("level number out of range [ledger_to_dnum(%d)]", (int) ledgerno);
@@ -1950,7 +1951,7 @@ level_difficulty(void)
          * 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);
+            res += (fakewiz1.dlevel - u.uz.dlevel);
             /*
              * Handling this properly would need more information here:
              * an inside/outside flag, or coordinates to calculate it.
@@ -2105,6 +2106,50 @@ tport_menu(winid win, char *entry, struct lchoice *lchoices,
     return;
 }
 
+/* this is only an approximation; to make it accurate, the stair list
+   should track which stairs have been traversed */
+boolean
+known_branch_stairs(stairway *sway, char *outbuf, boolean stcase)
+{
+    d_level tolev;
+    const char *stairs, *updown;
+    int ledgr, dest_visited;
+
+    if (outbuf)
+        *outbuf = '\0';
+    if (!sway)
+        return FALSE;
+
+    tolev = sway->tolev;
+    stairs = sway->isladder ? "ladder" : stcase ? "staircase" : "stairs";
+    updown = sway->up ? "up" : "down";
+    ledgr = ledger_no(&tolev);
+    dest_visited = (g.level_info[ledgr].flags & VISITED) != 0;
+
+    if (tolev.dnum == u.uz.dnum || !dest_visited) {
+        if (outbuf) {
+            Sprintf(outbuf, "%s %s", stairs, updown);
+            if (dest_visited) {
+                boolean specialdepth = (tolev.dnum == quest_dnum
+                                        || tolev.dnum == knox_level.dnum);
+                int to_dlev = specialdepth ? dunlev(&tolev) : depth(&tolev);
+
+                Sprintf(eos(outbuf), " to level %d", to_dlev);
+            }
+        }
+        /* might actually be branch stairs but if the branch hasn't been
+           visited yet, the hero won't know that */
+        return FALSE;
+    }
+    if (outbuf) {
+        Sprintf(outbuf, "branch %s %s to %s",
+                stairs, updown, g.dungeons[tolev.dnum].dname);
+        (void) strsubst(outbuf, "The ", "the ");
+    }
+    /* branch stairs and hero knows it */
+    return TRUE;
+}
+
 /* Convert a branch type to a string usable by print_dungeon(). */
 static const char *
 br_string(int type)
index e0876dff368755abbd8d471e44a539032866d039..a76bec57975452b65de71c9537be296125ac0279 100644 (file)
@@ -3283,7 +3283,7 @@ dfeature_at(int x, int y, char *buf)
     int ltyp = lev->typ, cmap = -1;
     const char *dfeature = 0;
     static char altbuf[BUFSZ];
-    stairway *stway = stairway_at(x,y);
+    stairway *stway = stairway_at(x, y);
 
     if (IS_DOOR(ltyp)) {
         switch (lev->doormask) {
@@ -3324,15 +3324,20 @@ dfeature_at(int x, int y, char *buf)
                 a_gname(),
                 align_str(Amask2align(lev->altarmask & ~AM_SHRINE)));
         dfeature = altbuf;
-    } else if (stway && !stway->isladder && stway->up)
-        cmap = S_upstair; /* "staircase up" */
-    else if (stway && !stway->isladder && !stway->up)
-        cmap = S_dnstair; /* "staircase down" */
-    else if (stway && stway->isladder && stway->up)
-        cmap = S_upladder; /* "ladder up" */
-    else if (stway && stway->isladder && !stway->up)
-        cmap = S_dnladder; /* "ladder down" */
-    else if (ltyp == DRAWBRIDGE_DOWN)
+    } else if (stway) {
+        (void) known_branch_stairs(stway, altbuf, TRUE);
+        dfeature = altbuf;
+#if 0
+        if (!stway->isladder && stway->up)
+            cmap = S_upstair; /* "staircase up" */
+        else if (!stway->isladder && !stway->up)
+            cmap = S_dnstair; /* "staircase down" */
+        else if (stway->isladder && stway->up)
+            cmap = S_upladder; /* "ladder up" */
+        else if (stway->isladder && !stway->up)
+            cmap = S_dnladder; /* "ladder down" */
+#endif
+    } else if (ltyp == DRAWBRIDGE_DOWN)
         cmap = S_vodbridge; /* "lowered drawbridge" */
     else if (ltyp == DBWALL)
         cmap = S_vcdbridge; /* "raised drawbridge" */