extern boolean can_touch_safely(struct monst *, struct obj *);
extern int can_carry(struct monst *, struct obj *);
extern long mon_allowflags(struct monst *);
+extern boolean m_in_air(struct monst *);
extern int mfndpos(struct monst *, coord *, long *, long);
extern boolean monnear(struct monst *, coordxy, coordxy);
extern void dmonsfree(void);
if (ceiling_hider(mptr)
/* normally !accessible would be overridable with passes_walls,
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)",
!has_ceiling(&u.uz) ? "without ceiling"
: "in solid stone",
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 */
int
mfndpos(
nodiag = NODIAG(mdat - mons);
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));
/* note: floating eye is the only is_floater() so this could be
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 */
lavaok = FALSE;
thrudoor = ((flag & (ALLOW_WALL | BUSTDOOR)) != 0L);
return (is_swimmer(mdat)
|| (!Is_waterlevel(&u.uz)
&& !is_waterwall(x, y)
- && !grounded(mdat)));
+ && m_in_air(mtmp)));
} else if (mdat->mlet == S_EEL && rn2(13) && !ignorewater) {
return FALSE;
} else if (is_lava(x, y) && !ignorelava) {
&& uarmf->oerodeproof)
|| (Upolyd && likes_lava(gy.youmonst.data)));
else
- return (is_floater(mdat) || is_flyer(mdat)
- || likes_lava(mdat));
+ return (m_in_air(mtmp) || likes_lava(mdat));
}
if (passes_walls(mdat) && may_passwall(x, y))
return TRUE;