From: PatR Date: Thu, 29 Jul 2021 10:32:58 +0000 (-0700) Subject: concealing unknown branch stairs X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f2019e2ec6c71437a3361fee62b56a4a50992a3a;p=nethack concealing unknown branch stairs 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. --- diff --git a/include/extern.h b/include/extern.h index f0d3292e0..07aa255b4 100644 --- a/include/extern.h +++ b/include/extern.h @@ -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); diff --git a/src/display.c b/src/display.c index 2824ebd36..bbcd32960 100644 --- a/src/display.c +++ b/src/display.c @@ -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; diff --git a/src/dungeon.c b/src/dungeon.c index 9bf9343e6..ccd92335e 100644 --- a/src/dungeon.c +++ b/src/dungeon.c @@ -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) diff --git a/src/invent.c b/src/invent.c index e0876dff3..a76bec579 100644 --- a/src/invent.c +++ b/src/invent.c @@ -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" */