]> granicus.if.org Git - nethack/commitdiff
Apply dest. limit to monster trap door usage
authorMichael Meyer <me@entrez.cc>
Thu, 22 Sep 2022 00:19:33 +0000 (20:19 -0400)
committerPasi Kallinen <paxed@alt.org>
Thu, 22 Sep 2022 08:36:48 +0000 (11:36 +0300)
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
src/teleport.c
src/trap.c

index d92650bfb6a45dc9c536754b26556206c1c2b458..9f6e39191bdd0320b5e076042a01baa8c71f587d 100644 (file)
@@ -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,
index 8d35e7f900cbb4e850ea2ca4273eb693d4bab302..30b51b66ccd0db3b2dc6a2557a979b229abe3b7f 100644 (file)
@@ -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)
index 97cc712bc66cef6093c9910114805663c3efd26e..3f4abb7c67f847440f7bf4f0758dfb71227e5a16 100644 (file)
@@ -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 " : "");