fix issue #1434 - engulfed gas spore explosion
Issue reported by Umbire: a gas spore that got swallowed and killed didn't die but exploded anyway, with the explosion affecting the map instead of being contained in the swallower. There was code to handle that but it wasn't being executed. This fix feels unclean but seems to work. I couldn't reproduce the survival of the gas spore but since that isn't wanted I won't worry about it. Fixes #1434
This commit is contained in:
@@ -1523,6 +1523,8 @@ monsters trapped in pits cannot kick
|
||||
create familiar spell can create harder creatures
|
||||
a vampire lord could choose to take on wolf form while flying over water or
|
||||
lava, then revert to vampire lord form and teleport unnecessarily
|
||||
a gas spore that was killed when an engulfer swallowed it produced an explosion
|
||||
on the map rather than inside the engulfer
|
||||
|
||||
|
||||
Fixes to 3.7.0-x General Problems Exposed Via git Repository
|
||||
|
||||
@@ -604,6 +604,9 @@ struct instance_globals_m {
|
||||
/* dokick.c */
|
||||
struct rm *maploc;
|
||||
|
||||
/* mhitm.c */
|
||||
struct monst *mswallower; /* for gas spore explosion when it's swallowed*/
|
||||
|
||||
/* mhitu.c */
|
||||
int mhitu_dieroll;
|
||||
|
||||
|
||||
@@ -508,6 +508,8 @@ static const struct instance_globals_m g_init_m = {
|
||||
UNDEFINED_PTR, /* migrating_mons */
|
||||
/* dokick.c */
|
||||
UNDEFINED_PTR, /* maploc */
|
||||
/* mhitm.c */
|
||||
UNDEFINED_PTR, /* mswallower */
|
||||
/* mhitu.c */
|
||||
UNDEFINED_VALUE, /* mhitu_dieroll */
|
||||
/* mklev.c */
|
||||
|
||||
@@ -906,7 +906,9 @@ gulpmm(
|
||||
newsym(ax, ay); /* erase old position */
|
||||
newsym(dx, dy); /* update new position */
|
||||
|
||||
gm.mswallower = magr; /* corpse_chance() wants this */
|
||||
status = mdamagem(magr, mdef, mattk, (struct obj *) 0, 0);
|
||||
gm.mswallower = (struct monst *) 0; /* reset */
|
||||
|
||||
if ((status & (M_ATTK_AGR_DIED | M_ATTK_DEF_DIED))
|
||||
== (M_ATTK_AGR_DIED | M_ATTK_DEF_DIED)) {
|
||||
|
||||
@@ -1271,7 +1271,7 @@ gulp_blnd_check(void)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* monster swallows you, or damage if u.uswallow */
|
||||
/* monster swallows you, or damage if already swallowed (u.uswallow != 0) */
|
||||
staticfn int
|
||||
gulpmu(struct monst *mtmp, struct attack *mattk)
|
||||
{
|
||||
@@ -1537,7 +1537,9 @@ gulpmu(struct monst *mtmp, struct attack *mattk)
|
||||
if (physical_damage)
|
||||
tmp = Maybe_Half_Phys(tmp);
|
||||
|
||||
gm.mswallower = mtmp; /* match gulpmm() */
|
||||
mdamageu(mtmp, tmp);
|
||||
gm.mswallower = 0;
|
||||
if (tmp)
|
||||
stop_occupation();
|
||||
|
||||
|
||||
32
src/mon.c
32
src/mon.c
@@ -2204,8 +2204,7 @@ mfndpos(
|
||||
if (IS_DOOR(ntyp)
|
||||
/* an amorphous creature can only move under/through a
|
||||
closed door if it doesn't currently have hero engulfed */
|
||||
&& !((amorphous(mdat) || can_fog(mon))
|
||||
&& (mon != u.ustuck || !u.uswallow))
|
||||
&& !((amorphous(mdat) || can_fog(mon)) && !engulfing_u(mon))
|
||||
&& (((levl[nx][ny].doormask & D_CLOSED) && !(flag & OPENDOOR))
|
||||
|| ((levl[nx][ny].doormask & D_LOCKED)
|
||||
&& !(flag & UNLOCKDOOR))) && !thrudoor)
|
||||
@@ -2670,11 +2669,25 @@ mon_leaving_level(struct monst *mon)
|
||||
remove_monster(mx, my);
|
||||
|
||||
#if 0 /* mustn't do this; too many places assume that the stale
|
||||
monst->mx,my values are still valid */
|
||||
* monst->mx,my values are still valid */
|
||||
mon->mx = mon->my = 0; /* off normal map */
|
||||
#endif
|
||||
}
|
||||
if (onmap) {
|
||||
/* gulpmm() tries to deal with this, but without this extra
|
||||
place_monster() the messages for exploding engulfed gas spore
|
||||
are delivered without the engulfer being shown on the map */
|
||||
if (gm.mswallower && gm.mswallower != mon) {
|
||||
if (gm.mswallower != &gy.youmonst) {
|
||||
place_monster(gm.mswallower,
|
||||
gm.mswallower->mx, gm.mswallower->my);
|
||||
} else {
|
||||
u_on_newpos(u.ux, u.uy);
|
||||
if (canspotself())
|
||||
display_self();
|
||||
}
|
||||
}
|
||||
|
||||
mon->mundetected = 0; /* for migration; doesn't matter for death */
|
||||
/* unhide mimic in case its shape has been blocking line of sight
|
||||
or it is accompanying the hero to another level */
|
||||
@@ -3146,6 +3159,9 @@ corpse_chance(
|
||||
struct permonst *mdat = mon->data;
|
||||
int i, tmp;
|
||||
|
||||
if (!magr && gm.mswallower && attacktype(gm.mswallower->data, AT_ENGL))
|
||||
magr = gm.mswallower, was_swallowed = TRUE; /* for gas spore boom */
|
||||
|
||||
if (mdat == &mons[PM_VLAD_THE_IMPALER] || mdat->mlet == S_LICH) {
|
||||
if (cansee(mon->mx, mon->my) && !was_swallowed)
|
||||
pline_mon(mon, "%s body crumbles into dust.",
|
||||
@@ -3162,7 +3178,10 @@ corpse_chance(
|
||||
tmp = d((int) mdat->mlevel + 1, (int) mdat->mattk[i].damd);
|
||||
else
|
||||
tmp = 0;
|
||||
|
||||
if (was_swallowed && magr) {
|
||||
/* mdef is a gas spore (AT_BOOM) that is exploding inside an
|
||||
engulfer; suppress usual explosion since it's contained */
|
||||
if (magr == &gy.youmonst) {
|
||||
There("is an explosion in your %s!", body_part(STOMACH));
|
||||
Sprintf(svk.killer.name, "%s explosion",
|
||||
@@ -3176,14 +3195,11 @@ corpse_chance(
|
||||
mondied(magr);
|
||||
if (DEADMONSTER(magr)) { /* maybe lifesaved */
|
||||
if (canspotmon(magr))
|
||||
pline_mon(magr, "%s rips open!",
|
||||
Monnam(magr));
|
||||
pline_mon(magr, "%s rips open!", Monnam(magr));
|
||||
} else if (canseemon(magr))
|
||||
pline_mon(magr,
|
||||
"%s seems to have indigestion.",
|
||||
pline_mon(magr, "%s seems to have indigestion.",
|
||||
Monnam(magr));
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
@@ -5005,6 +5005,7 @@ gulpum(struct monst *mdef, struct attack *mattk)
|
||||
"you totally digest <mdef>" will be coming soon (after
|
||||
several turns) but the level-gain message seems out of
|
||||
order if the kill message is left implicit */
|
||||
gm.mswallower = &gy.youmonst;
|
||||
xkilled(mdef, XKILL_GIVEMSG | XKILL_NOCORPSE);
|
||||
if (!DEADMONSTER(mdef)) { /* monster lifesaved */
|
||||
You("hurriedly regurgitate the sizzling in your %s.",
|
||||
@@ -5045,6 +5046,7 @@ gulpum(struct monst *mdef, struct attack *mattk)
|
||||
} else
|
||||
exercise(A_CON, TRUE);
|
||||
}
|
||||
gm.mswallower = (struct monst *) 0;
|
||||
end_engulf();
|
||||
return M_ATTK_DEF_DIED;
|
||||
case AD_PHYS:
|
||||
|
||||
Reference in New Issue
Block a user