From a345fc8dfbe7378c5e2cab7b16bd166385bf502d Mon Sep 17 00:00:00 2001 From: Michael Meyer Date: Fri, 19 Aug 2022 17:10:09 -0400 Subject: [PATCH] Fix: levelport by name to unconnected branch (unconnected to the current dungeon branch, that is) Level teleporting allows you to type in the name of a level instead of its number. This normally only works for levels within your current dungeon branch (main dungeon <-> Gehennom levelports are the exception): entering "medusa" as a destination won't work while the hero is in the Gnomish Mines, but it will work fine to get to the Medusa level from elsewhere in the main dungeon. Teleporting to a particular branch entrance didn't apply the same restriction. The teleport would still happen even if the destination branch was unreachable from the current branch, and in such a case the game would just try to get the hero to the depth of the branch entrance, within the current branch. For example, entering "quest" as a destination within the Gnomish Mines would bring the hero to Mines' End, since that's the closest depth-wise it's possible to get to the quest portal level. Apply the same rules to branch entrances as exist for named levels, excluding destinations that are unreachable from the current branch. --- src/dungeon.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/dungeon.c b/src/dungeon.c index 0f15f8b20..95e40bfe8 100644 --- a/src/dungeon.c +++ b/src/dungeon.c @@ -1975,6 +1975,14 @@ level_difficulty(void) return res; } +/* within same branch, or else main dungeon <-> gehennom */ +#define dlev_in_current_branch(dlev) \ + (dlev.dnum == u.uz.dnum \ + || (u.uz.dnum == valley_level.dnum \ + && dlev.dnum == medusa_level.dnum) \ + || (u.uz.dnum == medusa_level.dnum \ + && dlev.dnum == valley_level.dnum)) + /* Take one word and try to match it to a level. * Recognized levels are as shown by print_dungeon(). */ @@ -1982,7 +1990,7 @@ schar lev_by_name(const char *nam) { schar lev = 0; - s_level *slev = (s_level *)0; + s_level *slev = (s_level *) 0; d_level dlev; const char *p; int idx, idxtoo; @@ -2017,12 +2025,7 @@ lev_by_name(const char *nam) if (mseen || slev) { idx = ledger_no(&dlev); - if ((dlev.dnum == u.uz.dnum - /* within same branch, or else main dungeon <-> gehennom */ - || (u.uz.dnum == valley_level.dnum - && dlev.dnum == medusa_level.dnum) - || (u.uz.dnum == medusa_level.dnum - && dlev.dnum == valley_level.dnum)) + if (dlev_in_current_branch(dlev) && (/* either wizard mode or else seen and not forgotten */ wizard || (g.level_info[idx].flags & (VISITED)) @@ -2048,13 +2051,16 @@ lev_by_name(const char *nam) idx = idxtoo; dlev.dnum = ledger_to_dnum(idx); dlev.dlevel = ledger_to_dlev(idx); - lev = depth(&dlev); + if (dlev_in_current_branch(dlev)) + lev = depth(&dlev); } } } return lev; } +#undef dlev_in_current_branch + static boolean unplaced_floater(struct dungeon *dptr) {