From: Pasi Kallinen Date: Wed, 27 Jul 2022 19:51:13 +0000 (+0300) Subject: Holes and trapdoors have predetermined exit level X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=05761bada6e87d22315256e56c43fc58f667d46b;p=nethack Holes and trapdoors have predetermined exit level Same hole/trapdoor will always take you to the same level. --- diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index 12d9f538a..a19f030a2 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -978,6 +978,7 @@ wielding Giantslayer prevents knockback from larger monsters scared hostile monster which cannot move away will attack prevent a fog cloud that has engulfed the hero from moving under closed doors allow cutting a known spider web with wielded weapon by force-fighting the web +holes and trapdoors have a fixed exit level Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/include/trap.h b/include/trap.h index 18adfb2a2..e54aa9052 100644 --- a/include/trap.h +++ b/include/trap.h @@ -18,7 +18,7 @@ union vlaunchinfo { struct trap { struct trap *ntrap; coordxy tx, ty; - d_level dst; /* destination for portals */ + d_level dst; /* destination for portals/holes/trapdoors */ coord launch; Bitfield(ttyp, 5); Bitfield(tseen, 1); diff --git a/src/do.c b/src/do.c index 4d3547d2e..8bb2aab5b 100644 --- a/src/do.c +++ b/src/do.c @@ -1133,6 +1133,8 @@ dodown(void) } if (trap && Is_stronghold(&u.uz)) { goto_hell(FALSE, TRUE); + } else if (trap) { + goto_level(&(trap->dst), FALSE, FALSE, FALSE); } else { g.at_ladder = (boolean) (levl[u.ux][u.uy].typ == LADDER); next_level(!trap); diff --git a/src/trap.c b/src/trap.c index 524d9d471..5901eeb7a 100644 --- a/src/trap.c +++ b/src/trap.c @@ -8,6 +8,8 @@ extern const char *const destroy_strings[][3]; /* from zap.c */ static void mk_trap_statue(coordxy, coordxy); +static int dng_bottom(void); +static void hole_destination(d_level *); static boolean keep_saddle_with_steedcorpse(unsigned, struct obj *, struct obj *); static boolean mu_maybe_destroy_web(struct monst *, boolean, struct trap *); @@ -373,6 +375,37 @@ mk_trap_statue(coordxy x, coordxy y) mongone(mtmp); } +/* find "bottom" level of current dungeon, stopping at quest locate */ +static int +dng_bottom(void) +{ + int bottom = dunlevs_in_dungeon(&u.uz); + + /* when in the upper half of the quest, don't fall past the + middle "quest locate" level if hero hasn't been there yet */ + if (In_quest(&u.uz)) { + int qlocate_depth = qlocate_level.dlevel; + + /* deepest reached < qlocate implies current < qlocate */ + if (dunlev_reached(&u.uz) < qlocate_depth) + bottom = qlocate_depth; /* early cut-off */ + } + return bottom; +} + +/* destination dlevel for holes or trapdoors */ +static void +hole_destination(d_level *dst) +{ + int bottom = dng_bottom(); + + dst->dnum = u.uz.dnum; + dst->dlevel = dunlev(&u.uz); + do { + dst->dlevel++; + } while (!rn2(4) && dst->dlevel < bottom); +} + struct trap * maketrap(coordxy x, coordxy y, int typ) { @@ -435,6 +468,8 @@ maketrap(coordxy x, coordxy y, int typ) /*FALLTHRU*/ case HOLE: case TRAPDOOR: + if (is_hole(typ)) + hole_destination(&(ttmp->dst)); if (*in_rooms(x, y, SHOPBASE) && (is_hole(typ) || IS_DOOR(lev->typ) || IS_WALL(lev->typ))) add_damage(x, y, /* schedule repair */ @@ -481,7 +516,7 @@ fall_through( d_level dtmp; char msgbuf[BUFSZ]; const char *dont_fall = 0; - int newlevel, bottom; + int newlevel, bottom = dng_bottom(); struct trap *t = (struct trap *) 0; /* we'll fall even while levitating in Sokoban; otherwise, if we @@ -489,20 +524,8 @@ fall_through( if (Blind && Levitation && !Sokoban) return; - bottom = dunlevs_in_dungeon(&u.uz); - /* when in the upper half of the quest, don't fall past the - middle "quest locate" level if hero hasn't been there yet */ - if (In_quest(&u.uz)) { - int qlocate_depth = qlocate_level.dlevel; - - /* deepest reached < qlocate implies current < qlocate */ - if (dunlev_reached(&u.uz) < qlocate_depth) - bottom = qlocate_depth; /* early cut-off */ - } newlevel = dunlev(&u.uz); /* current level */ - do { - newlevel++; - } while (!rn2(4) && newlevel < bottom); + newlevel++; if (td) { t = t_at(u.ux, u.uy); @@ -555,8 +578,14 @@ fall_through( } else { int dist = newlevel - dunlev(&u.uz); - dtmp.dnum = u.uz.dnum; - dtmp.dlevel = newlevel; + if (t) { + dtmp.dnum = t->dst.dnum; + dtmp.dlevel = t->dst.dlevel; + dist = dtmp.dlevel - dunlev(&u.uz); + } else { + dtmp.dnum = u.uz.dnum; + dtmp.dlevel = newlevel; + } if (dist > 1) You("fall down a %s%sshaft!", dist > 3 ? "very " : "", dist > 2 ? "deep " : "");