Fix ceiling hiders on pools
While fuzzing, I saw a sanity checking error complaining about a ceiling hider being on top of a pool; the rock piercer was teleported on top of the pool while it was hiding in the ceiling. Try to be a bit more consistent when a monster is hiding in ceiling, and if it's valid for it to be on a pool.
This commit is contained in:
@@ -1559,6 +1559,7 @@ extern int max_mon_load(struct monst *);
|
|||||||
extern boolean can_touch_safely(struct monst *, struct obj *);
|
extern boolean can_touch_safely(struct monst *, struct obj *);
|
||||||
extern int can_carry(struct monst *, struct obj *);
|
extern int can_carry(struct monst *, struct obj *);
|
||||||
extern long mon_allowflags(struct monst *);
|
extern long mon_allowflags(struct monst *);
|
||||||
|
extern boolean m_in_air(struct monst *);
|
||||||
extern int mfndpos(struct monst *, coord *, long *, long);
|
extern int mfndpos(struct monst *, coord *, long *, long);
|
||||||
extern boolean monnear(struct monst *, coordxy, coordxy);
|
extern boolean monnear(struct monst *, coordxy, coordxy);
|
||||||
extern void dmonsfree(void);
|
extern void dmonsfree(void);
|
||||||
|
|||||||
19
src/mon.c
19
src/mon.c
@@ -153,7 +153,10 @@ sanity_check_single_mon(
|
|||||||
if (ceiling_hider(mptr)
|
if (ceiling_hider(mptr)
|
||||||
/* normally !accessible would be overridable with passes_walls,
|
/* normally !accessible would be overridable with passes_walls,
|
||||||
but not for hiding on the ceiling */
|
but not for hiding on the ceiling */
|
||||||
&& (!has_ceiling(&u.uz) || !accessible(mx, my)))
|
&& (!has_ceiling(&u.uz) ||
|
||||||
|
!(levl[mx][my].typ == POOL
|
||||||
|
|| levl[mx][my].typ == MOAT
|
||||||
|
|| accessible(mx, my))))
|
||||||
impossible("ceiling hider hiding %s (%s)",
|
impossible("ceiling hider hiding %s (%s)",
|
||||||
!has_ceiling(&u.uz) ? "without ceiling"
|
!has_ceiling(&u.uz) ? "without ceiling"
|
||||||
: "in solid stone",
|
: "in solid stone",
|
||||||
@@ -1854,6 +1857,16 @@ mon_allowflags(struct monst* mtmp)
|
|||||||
return allowflags;
|
return allowflags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* return TRUE if monster is up in the air/on the ceiling */
|
||||||
|
boolean
|
||||||
|
m_in_air(struct monst *mtmp)
|
||||||
|
{
|
||||||
|
return (is_flyer(mtmp->data)
|
||||||
|
|| is_floater(mtmp->data)
|
||||||
|
|| (is_clinger(mtmp->data)
|
||||||
|
&& has_ceiling(&u.uz) && mtmp->mundetected));
|
||||||
|
}
|
||||||
|
|
||||||
/* return number of acceptable neighbour positions */
|
/* return number of acceptable neighbour positions */
|
||||||
int
|
int
|
||||||
mfndpos(
|
mfndpos(
|
||||||
@@ -1881,11 +1894,11 @@ mfndpos(
|
|||||||
|
|
||||||
nodiag = NODIAG(mdat - mons);
|
nodiag = NODIAG(mdat - mons);
|
||||||
wantpool = (mdat->mlet == S_EEL);
|
wantpool = (mdat->mlet == S_EEL);
|
||||||
poolok = ((!Is_waterlevel(&u.uz) && !grounded(mdat))
|
poolok = ((!Is_waterlevel(&u.uz) && m_in_air(mon))
|
||||||
|| (is_swimmer(mdat) && !wantpool));
|
|| (is_swimmer(mdat) && !wantpool));
|
||||||
/* note: floating eye is the only is_floater() so this could be
|
/* note: floating eye is the only is_floater() so this could be
|
||||||
simplified, but then adding another floater would be error prone */
|
simplified, but then adding another floater would be error prone */
|
||||||
lavaok = (!grounded(mdat) || likes_lava(mdat));
|
lavaok = (m_in_air(mon) || likes_lava(mdat));
|
||||||
if (mdat == &mons[PM_FLOATING_EYE]) /* prefers to avoid heat */
|
if (mdat == &mons[PM_FLOATING_EYE]) /* prefers to avoid heat */
|
||||||
lavaok = FALSE;
|
lavaok = FALSE;
|
||||||
thrudoor = ((flag & (ALLOW_WALL | BUSTDOOR)) != 0L);
|
thrudoor = ((flag & (ALLOW_WALL | BUSTDOOR)) != 0L);
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ goodpos(
|
|||||||
return (is_swimmer(mdat)
|
return (is_swimmer(mdat)
|
||||||
|| (!Is_waterlevel(&u.uz)
|
|| (!Is_waterlevel(&u.uz)
|
||||||
&& !is_waterwall(x, y)
|
&& !is_waterwall(x, y)
|
||||||
&& !grounded(mdat)));
|
&& m_in_air(mtmp)));
|
||||||
} else if (mdat->mlet == S_EEL && rn2(13) && !ignorewater) {
|
} else if (mdat->mlet == S_EEL && rn2(13) && !ignorewater) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
} else if (is_lava(x, y) && !ignorelava) {
|
} else if (is_lava(x, y) && !ignorelava) {
|
||||||
@@ -147,8 +147,7 @@ goodpos(
|
|||||||
&& uarmf->oerodeproof)
|
&& uarmf->oerodeproof)
|
||||||
|| (Upolyd && likes_lava(gy.youmonst.data)));
|
|| (Upolyd && likes_lava(gy.youmonst.data)));
|
||||||
else
|
else
|
||||||
return (is_floater(mdat) || is_flyer(mdat)
|
return (m_in_air(mtmp) || likes_lava(mdat));
|
||||||
|| likes_lava(mdat));
|
|
||||||
}
|
}
|
||||||
if (passes_walls(mdat) && may_passwall(x, y))
|
if (passes_walls(mdat) && may_passwall(x, y))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|||||||
Reference in New Issue
Block a user