purple worms in wall (trunk only)

From a bug report, a purple worm
could swallow a ghost or xorn and end up inside solid rock.  It took a
bunch of tries to reproduce this, but I eventually did.  (I'm not sure
why it didn't happen every time a worm swallowed a target which was in
rock; the code for positioning an engulfer after it digests a target
always puts the engulfer in the target's former spot.)  After this
patch, worms can still swallow ghosts and xorns, but only when they're
in locations the worm could walk onto.
This commit is contained in:
nethack.rankin
2011-01-11 02:21:10 +00:00
parent 3b6c59c7fc
commit 72ca745646
5 changed files with 37 additions and 6 deletions
+1
View File
@@ -342,6 +342,7 @@ when reading an unknown scroll and learning it, discovery of teleporation was
too late if hero happened to land on another scroll of teleportation too late if hero happened to land on another scroll of teleportation
using an unlocking tool on a closed door which was actually a mimic reported using an unlocking tool on a closed door which was actually a mimic reported
that there was no door to unlock instead of exposing the mimic that there was no door to unlock instead of exposing the mimic
purple worm could end up in wall or solid rock when swallowing ghost or xorn
Platform- and/or Interface-Specific Fixes Platform- and/or Interface-Specific Fixes
+1
View File
@@ -1106,6 +1106,7 @@ E int FDECL(buzzmu, (struct monst *,struct attack *));
E int FDECL(fightm, (struct monst *)); E int FDECL(fightm, (struct monst *));
E int FDECL(mattackm, (struct monst *,struct monst *)); E int FDECL(mattackm, (struct monst *,struct monst *));
E boolean FDECL(engulf_target, (struct monst *,struct monst *));
#ifdef BARGETHROUGH #ifdef BARGETHROUGH
E int FDECL(mdisplacem, (struct monst *,struct monst *,BOOLEAN_P)); E int FDECL(mdisplacem, (struct monst *,struct monst *,BOOLEAN_P));
#endif #endif
+33 -3
View File
@@ -1,5 +1,4 @@
/* NetHack 3.5 mhitm.c $Date$ $Revision$ */ /* NetHack 3.5 mhitm.c $Date$ $Revision$ */
/* SCCS Id: @(#)mhitm.c 3.5 2007/12/19 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -550,6 +549,37 @@ gazemm(magr, mdef, mattk)
return(mdamagem(magr, mdef, mattk)); return(mdamagem(magr, mdef, mattk));
} }
/* return True if magr is allowed to swallow mdef, False otherwise */
boolean
engulf_target(magr, mdef)
struct monst *magr, *mdef;
{
struct rm *lev;
int dx, dy;
/* can't swallow something that's too big */
if (mdef->data->msize >= MZ_HUGE)
return FALSE;
/* (hypothetical) engulfers who can pass through walls aren't
limited by rock|trees|bars */
if ((magr == &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 == &youmonst) dx = u.ux, dy = u.uy;
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)))
return FALSE;
return TRUE;
}
/* Returns the same values as mattackm(). */ /* Returns the same values as mattackm(). */
STATIC_OVL int STATIC_OVL int
gulpmm(magr, mdef, mattk) gulpmm(magr, mdef, mattk)
@@ -561,7 +591,7 @@ gulpmm(magr, mdef, mattk)
char buf[BUFSZ]; char buf[BUFSZ];
struct obj *obj; struct obj *obj;
if (mdef->data->msize >= MZ_HUGE) return MM_MISS; if (!engulf_target(magr, mdef)) return MM_MISS;
if (vis) { if (vis) {
Sprintf(buf,"%s swallows", Monnam(magr)); Sprintf(buf,"%s swallows", Monnam(magr));
@@ -777,7 +807,7 @@ mdamagem(magr, mdef, mattk)
worm's bite attack to kill a shrieker because then it worm's bite attack to kill a shrieker because then it
won't swallow the corpse; but if the target survives, won't swallow the corpse; but if the target survives,
the subsequent engulf attack should accomplish that */ the subsequent engulf attack should accomplish that */
if (tmp >= mdef->mhp) tmp = mdef->mhp - 1; if (tmp >= mdef->mhp && mdef->mhp > 1) tmp = mdef->mhp - 1;
} }
break; break;
case AD_FIRE: case AD_FIRE:
+1 -2
View File
@@ -1,5 +1,4 @@
/* NetHack 3.5 mhitu.c $Date$ $Revision$ */ /* NetHack 3.5 mhitu.c $Date$ $Revision$ */
/* SCCS Id: @(#)mhitu.c 3.5 2009/02/17 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -1636,7 +1635,7 @@ gulpmu(mtmp, mattk) /* monster swallows you, or damage if u.uswallow */
if (!u.uswallow) { /* swallows you */ if (!u.uswallow) { /* swallows you */
int omx = mtmp->mx, omy = mtmp->my; int omx = mtmp->mx, omy = mtmp->my;
if (youmonst.data->msize >= MZ_HUGE) return(0); if (!engulf_target(mtmp, &youmonst)) return 0;
if ((t && ((t->ttyp == PIT) || (t->ttyp == SPIKED_PIT))) && if ((t && ((t->ttyp == PIT) || (t->ttyp == SPIKED_PIT))) &&
sobj_at(BOULDER, u.ux, u.uy)) sobj_at(BOULDER, u.ux, u.uy))
return(0); return(0);
+1 -1
View File
@@ -1832,7 +1832,7 @@ register struct attack *mattk;
* after exactly 1 round of attack otherwise. -KAA * after exactly 1 round of attack otherwise. -KAA
*/ */
if (pd->msize >= MZ_HUGE) return 0; if (!engulf_target(&youmonst, mdef)) return 0;
if(u.uhunger < 1500 && !u.uswallow) { if(u.uhunger < 1500 && !u.uswallow) {
for (otmp = mdef->minvent; otmp; otmp = otmp->nobj) for (otmp = mdef->minvent; otmp; otmp = otmp->nobj)