Refine attempt to clamp trap door fall destination
This should prevent anyone from exploiting falling into the sanctum (by taking advantage of a trap door in a bones file from a differently laid-out dungeon, as described in the previous commit) to bypass the invocation, in addition to falling past the actual end of the dungeon.
This commit is contained in:
committed by
Pasi Kallinen
parent
1830b206c7
commit
9f5b362601
26
src/trap.c
26
src/trap.c
@@ -8,7 +8,7 @@
|
||||
extern const char *const destroy_strings[][3]; /* from zap.c */
|
||||
|
||||
static void mk_trap_statue(coordxy, coordxy);
|
||||
static int dng_bottom(void);
|
||||
static int dng_bottom(d_level *lev);
|
||||
static void hole_destination(d_level *);
|
||||
static boolean keep_saddle_with_steedcorpse(unsigned, struct obj *,
|
||||
struct obj *);
|
||||
@@ -375,19 +375,19 @@ mk_trap_statue(coordxy x, coordxy y)
|
||||
mongone(mtmp);
|
||||
}
|
||||
|
||||
/* find "bottom" level of current dungeon, stopping at quest locate */
|
||||
/* find "bottom" level of specified dungeon, stopping at quest locate */
|
||||
static int
|
||||
dng_bottom(void)
|
||||
dng_bottom(d_level *lev)
|
||||
{
|
||||
int bottom = dunlevs_in_dungeon(&u.uz);
|
||||
int bottom = dunlevs_in_dungeon(lev);
|
||||
|
||||
/* 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)) {
|
||||
if (In_quest(lev)) {
|
||||
int qlocate_depth = qlocate_level.dlevel;
|
||||
|
||||
/* deepest reached < qlocate implies current < qlocate */
|
||||
if (dunlev_reached(&u.uz) < qlocate_depth)
|
||||
if (dunlev_reached(lev) < qlocate_depth)
|
||||
bottom = qlocate_depth; /* early cut-off */
|
||||
}
|
||||
return bottom;
|
||||
@@ -397,7 +397,7 @@ dng_bottom(void)
|
||||
static void
|
||||
hole_destination(d_level *dst)
|
||||
{
|
||||
int bottom = dng_bottom();
|
||||
int bottom = dng_bottom(&u.uz);
|
||||
|
||||
dst->dnum = u.uz.dnum;
|
||||
dst->dlevel = dunlev(&u.uz);
|
||||
@@ -520,7 +520,7 @@ fall_through(
|
||||
d_level dtmp;
|
||||
char msgbuf[BUFSZ];
|
||||
const char *dont_fall = 0;
|
||||
int newlevel, bottom = dng_bottom();
|
||||
int newlevel, bottom = dng_bottom(&u.uz);
|
||||
struct trap *t = (struct trap *) 0;
|
||||
|
||||
/* we'll fall even while levitating in Sokoban; otherwise, if we
|
||||
@@ -550,6 +550,8 @@ fall_through(
|
||||
|| ((Flying || is_clinger(g.youmonst.data)
|
||||
|| (ceiling_hider(g.youmonst.data) && u.uundetected))
|
||||
&& !(ftflags & TOOKPLUNGE))
|
||||
/* this is no longer a very useful test because newlevel isn't
|
||||
the real destination we're aiming for, if t != 0 */
|
||||
|| (Inhell && !u.uevent.invoked && newlevel == bottom)) {
|
||||
dont_fall = "don't fall in.";
|
||||
} else if (g.youmonst.data->msize >= MZ_HUGE) {
|
||||
@@ -586,13 +588,17 @@ fall_through(
|
||||
dtmp.dnum = t->dst.dnum;
|
||||
/* 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);
|
||||
dist = dtmp.dlevel - dunlev(&u.uz);
|
||||
if (In_hell(&t->dst) && !u.uevent.invoked
|
||||
&& dtmp.dlevel == bottom)
|
||||
dtmp.dlevel--;
|
||||
} else {
|
||||
dtmp.dnum = u.uz.dnum;
|
||||
dtmp.dlevel = newlevel;
|
||||
dist = newlevel - dunlev(&u.uz);
|
||||
}
|
||||
/* XXX: dist won't be accurate if dtmp.dnum may not match u.uz.dnum */
|
||||
dist = dtmp.dlevel - dunlev(&u.uz);
|
||||
if (dist > 1)
|
||||
You("fall down a %s%sshaft!", dist > 3 ? "very " : "",
|
||||
dist > 2 ? "deep " : "");
|
||||
|
||||
Reference in New Issue
Block a user