sanity check: avoid "you over monster" impossible
I did this several months ago to avoid a sanity check warning (and consequent fuzzer panic) when an engulfer expels the hero on a full level. I was hoping to refine it but never went back; install it now before forgetting about it entirely. If a chameleon changes from wall-phazer to engulfer while in a spot the hero can't move onto and engulfs him/her, expelling the hero after the engulfer has taken the hero's spot might be forced to put the hero on top of the engulfer or another monster when unable to use the engulfer's former spot. Rather than try to figure out all the possible ways this might happen and attempt to deal with each of them, just prevent an engulf attack from succeeding if the hero wouldn't be able to move to the engulfer's spot. (Does not prevent an air elemental over water from engulfing the hero.)
This commit is contained in:
@@ -1713,6 +1713,10 @@ applying a wielded lump of royal jelly but not picking something to rub it on
|
||||
"addinv: null obj after quiver merge" (like applying lit potion of oil)
|
||||
ceiling hider could become hidden when there was no ceiling, triggering a
|
||||
warning if sanity_check was On
|
||||
hero could be forced onto a monster's location if a level was full and an
|
||||
engulfer was occupying an adjacent but inaccessible spot, engulfed
|
||||
hero, then expelled hero while now occupying hero's accessible spot,
|
||||
triggering sanity_check warning "you over monster"
|
||||
experimental #saveoptions wasn't saving the set of cond_xyz options correctly;
|
||||
if player viewed the 'm O' submenu for status conditions, they would
|
||||
get saved even if not changed; otherwise, ones that came in from the
|
||||
|
||||
38
src/mhitm.c
38
src/mhitm.c
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.7 mhitm.c $NHDT-Date: 1627412283 2021/07/27 18:58:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.199 $ */
|
||||
/* NetHack 3.7 mhitm.c $NHDT-Date: 1698939796 2023/11/02 15:43:16 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.244 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Robert Patrick Rankin, 2011. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -797,7 +797,9 @@ boolean
|
||||
engulf_target(struct monst *magr, struct monst *mdef)
|
||||
{
|
||||
struct rm *lev;
|
||||
int dx, dy;
|
||||
int ax, ay, dx, dy;
|
||||
boolean uatk = (magr == &gy.youmonst),
|
||||
udef = (mdef == &gy.youmonst);
|
||||
|
||||
/* can't swallow something that's too big */
|
||||
if (mdef->data->msize >= MZ_HUGE
|
||||
@@ -808,21 +810,25 @@ engulf_target(struct monst *magr, struct monst *mdef)
|
||||
if (mdef->mtrapped || magr->mtrapped)
|
||||
return FALSE;
|
||||
|
||||
/* (hypothetical) engulfers who can pass through walls aren't
|
||||
limited by rock|trees|bars */
|
||||
if ((magr == &gy.youmonst) ? Passes_walls : passes_walls(magr->data))
|
||||
return TRUE;
|
||||
|
||||
/* don't swallow something in a spot where attacker wouldn't
|
||||
otherwise be able to move onto; we don't want to engulf
|
||||
a wall-phaser and end up with a non-phaser inside a wall */
|
||||
dx = mdef->mx, dy = mdef->my;
|
||||
if (mdef == &gy.youmonst)
|
||||
dx = u.ux, dy = u.uy;
|
||||
/* if attacker is phasing in solid rock and defender can't move there,
|
||||
or vice versa, don't allow engulf to succeeed; otherwise expelling
|
||||
might not be able to place attacker and defender both back on map;
|
||||
when defender is the hero, a sanity_check complaint about placing
|
||||
the hero on top of a monster can occur */
|
||||
dx = (mdef == &gy.youmonst) ? u.ux : mdef->mx;
|
||||
dy = (mdef == &gy.youmonst) ? u.uy : mdef->my;
|
||||
lev = &levl[dx][dy];
|
||||
if (IS_ROCK(lev->typ) || closed_door(dx, dy) || IS_TREE(lev->typ)
|
||||
/* not passes_bars(); engulfer isn't squeezing through */
|
||||
|| (lev->typ == IRONBARS && !is_whirly(magr->data)))
|
||||
if (!(udef ? Passes_walls : passes_walls(mdef->data))
|
||||
&& (IS_ROCK(lev->typ) || closed_door(dx, dy) || IS_TREE(lev->typ)
|
||||
/* not passes_bars(); engulfer isn't squeezing through */
|
||||
|| (lev->typ == IRONBARS && !is_whirly(magr->data))))
|
||||
return FALSE;
|
||||
ax = (magr == &gy.youmonst) ? u.ux : magr->mx;
|
||||
ay = (magr == &gy.youmonst) ? u.uy : magr->my;
|
||||
lev = &levl[ax][ay];
|
||||
if (!(uatk ? Passes_walls : passes_walls(magr->data))
|
||||
&& (IS_ROCK(lev->typ) || closed_door(ax, ay) || IS_TREE(lev->typ)
|
||||
|| (lev->typ == IRONBARS && !is_whirly(mdef->data))))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
|
||||
Reference in New Issue
Block a user