From 81285b661e7c8393cc95750b35f794f35ddac100 Mon Sep 17 00:00:00 2001 From: Michael Meyer Date: Wed, 21 Sep 2022 20:19:33 -0400 Subject: [PATCH] Apply dest. limit to monster trap door usage To prevent monsters from falling past the bottom level or into the sanctum early, and to maintain consistency between monster and hero hole usage. --- include/extern.h | 1 + src/teleport.c | 1 + src/trap.c | 25 +++++++++++++++++-------- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/include/extern.h b/include/extern.h index d92650bfb..9f6e39191 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2796,6 +2796,7 @@ extern boolean burnarmor(struct monst *); extern int erode_obj(struct obj *, const char *, int, int); extern boolean grease_protect(struct obj *, const char *, struct monst *); extern struct trap *maketrap(coordxy, coordxy, int); +extern d_level *clamp_hole_destination(d_level *); extern void fall_through(boolean, unsigned); extern struct monst *animate_statue(struct obj *, coordxy, coordxy, int, int *); extern struct monst *activate_statue_trap(struct trap *, coordxy, coordxy, diff --git a/src/teleport.c b/src/teleport.c index 8d35e7f90..30b51b66c 100644 --- a/src/teleport.c +++ b/src/teleport.c @@ -1540,6 +1540,7 @@ mlevel_tele_trap( return Trap_Effect_Finished; } else { assign_level(&tolevel, &trap->dst); + (void) clamp_hole_destination(&tolevel); } } else if (tt == MAGIC_PORTAL) { if (In_endgame(&u.uz) && (mon_has_amulet(mtmp) diff --git a/src/trap.c b/src/trap.c index 97cc712bc..3f4abb7c6 100644 --- a/src/trap.c +++ b/src/trap.c @@ -512,6 +512,20 @@ maketrap(coordxy x, coordxy y, int typ) return ttmp; } +/* limit the destination of a hole or trapdoor to the furthest level you + should be able to fall to */ +d_level * +clamp_hole_destination(d_level *dlev) +{ + int bottom = dng_bottom(dlev); + dlev->dlevel = min(dlev->dlevel, bottom); + if (In_hell(dlev) && !u.uevent.invoked + && dlev->dlevel == bottom) + dlev->dlevel--; + + return dlev; +} + void fall_through( boolean td, /* td == TRUE : trap door or hole */ @@ -585,20 +599,15 @@ fall_through( int dist; if (t) { - dtmp.dnum = t->dst.dnum; + assign_level(&dtmp, &t->dst); /* don't fall beyond the bottom, in case this came from a bones file with different dungeon size */ - bottom = dng_bottom(&t->dst); - dtmp.dlevel = min(t->dst.dlevel, bottom); - if (In_hell(&t->dst) && !u.uevent.invoked - && dtmp.dlevel == bottom) - dtmp.dlevel--; + (void) clamp_hole_destination(&dtmp); } else { dtmp.dnum = u.uz.dnum; dtmp.dlevel = newlevel; } - /* XXX: dist won't be accurate if dtmp.dnum may not match u.uz.dnum */ - dist = dtmp.dlevel - dunlev(&u.uz); + dist = depth(&dtmp) - depth(&u.uz); if (dist > 1) You("fall down a %s%sshaft!", dist > 3 ? "very " : "", dist > 2 ? "deep " : "");