diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index 8a37c1f5c..d19a70a6e 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -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 diff --git a/include/decl.h b/include/decl.h index d5186158b..72f85eb90 100644 --- a/include/decl.h +++ b/include/decl.h @@ -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; diff --git a/src/decl.c b/src/decl.c index 7d0a47cb4..a7e52dd80 100644 --- a/src/decl.c +++ b/src/decl.c @@ -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 */ diff --git a/src/mhitm.c b/src/mhitm.c index 078b7596c..322b65b22 100644 --- a/src/mhitm.c +++ b/src/mhitm.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)) { diff --git a/src/mhitu.c b/src/mhitu.c index ff32445e8..d6332c18d 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -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(); diff --git a/src/mon.c b/src/mon.c index 40a005440..dce75521c 100644 --- a/src/mon.c +++ b/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; } diff --git a/src/uhitm.c b/src/uhitm.c index cb85c63e3..cbf797e8e 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -5005,6 +5005,7 @@ gulpum(struct monst *mdef, struct attack *mattk) "you totally digest " 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: