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
+16
-10
@@ -8,7 +8,7 @@
|
|||||||
extern const char *const destroy_strings[][3]; /* from zap.c */
|
extern const char *const destroy_strings[][3]; /* from zap.c */
|
||||||
|
|
||||||
static void mk_trap_statue(coordxy, coordxy);
|
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 void hole_destination(d_level *);
|
||||||
static boolean keep_saddle_with_steedcorpse(unsigned, struct obj *,
|
static boolean keep_saddle_with_steedcorpse(unsigned, struct obj *,
|
||||||
struct obj *);
|
struct obj *);
|
||||||
@@ -375,19 +375,19 @@ mk_trap_statue(coordxy x, coordxy y)
|
|||||||
mongone(mtmp);
|
mongone(mtmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* find "bottom" level of current dungeon, stopping at quest locate */
|
/* find "bottom" level of specified dungeon, stopping at quest locate */
|
||||||
static int
|
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
|
/* when in the upper half of the quest, don't fall past the
|
||||||
middle "quest locate" level if hero hasn't been there yet */
|
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;
|
int qlocate_depth = qlocate_level.dlevel;
|
||||||
|
|
||||||
/* deepest reached < qlocate implies current < qlocate */
|
/* 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 */
|
bottom = qlocate_depth; /* early cut-off */
|
||||||
}
|
}
|
||||||
return bottom;
|
return bottom;
|
||||||
@@ -397,7 +397,7 @@ dng_bottom(void)
|
|||||||
static void
|
static void
|
||||||
hole_destination(d_level *dst)
|
hole_destination(d_level *dst)
|
||||||
{
|
{
|
||||||
int bottom = dng_bottom();
|
int bottom = dng_bottom(&u.uz);
|
||||||
|
|
||||||
dst->dnum = u.uz.dnum;
|
dst->dnum = u.uz.dnum;
|
||||||
dst->dlevel = dunlev(&u.uz);
|
dst->dlevel = dunlev(&u.uz);
|
||||||
@@ -520,7 +520,7 @@ fall_through(
|
|||||||
d_level dtmp;
|
d_level dtmp;
|
||||||
char msgbuf[BUFSZ];
|
char msgbuf[BUFSZ];
|
||||||
const char *dont_fall = 0;
|
const char *dont_fall = 0;
|
||||||
int newlevel, bottom = dng_bottom();
|
int newlevel, bottom = dng_bottom(&u.uz);
|
||||||
struct trap *t = (struct trap *) 0;
|
struct trap *t = (struct trap *) 0;
|
||||||
|
|
||||||
/* we'll fall even while levitating in Sokoban; otherwise, if we
|
/* we'll fall even while levitating in Sokoban; otherwise, if we
|
||||||
@@ -550,6 +550,8 @@ fall_through(
|
|||||||
|| ((Flying || is_clinger(g.youmonst.data)
|
|| ((Flying || is_clinger(g.youmonst.data)
|
||||||
|| (ceiling_hider(g.youmonst.data) && u.uundetected))
|
|| (ceiling_hider(g.youmonst.data) && u.uundetected))
|
||||||
&& !(ftflags & TOOKPLUNGE))
|
&& !(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)) {
|
|| (Inhell && !u.uevent.invoked && newlevel == bottom)) {
|
||||||
dont_fall = "don't fall in.";
|
dont_fall = "don't fall in.";
|
||||||
} else if (g.youmonst.data->msize >= MZ_HUGE) {
|
} else if (g.youmonst.data->msize >= MZ_HUGE) {
|
||||||
@@ -586,13 +588,17 @@ fall_through(
|
|||||||
dtmp.dnum = t->dst.dnum;
|
dtmp.dnum = t->dst.dnum;
|
||||||
/* don't fall beyond the bottom, in case this came from a bones
|
/* don't fall beyond the bottom, in case this came from a bones
|
||||||
file with different dungeon size */
|
file with different dungeon size */
|
||||||
|
bottom = dng_bottom(&t->dst);
|
||||||
dtmp.dlevel = min(t->dst.dlevel, bottom);
|
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 {
|
} else {
|
||||||
dtmp.dnum = u.uz.dnum;
|
dtmp.dnum = u.uz.dnum;
|
||||||
dtmp.dlevel = newlevel;
|
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)
|
if (dist > 1)
|
||||||
You("fall down a %s%sshaft!", dist > 3 ? "very " : "",
|
You("fall down a %s%sshaft!", dist > 3 ? "very " : "",
|
||||||
dist > 2 ? "deep " : "");
|
dist > 2 ? "deep " : "");
|
||||||
|
|||||||
Reference in New Issue
Block a user