fix github issue #1029 - erroneous death feedback

for monsters that haven't died, when being removed from play to keep
them out of bones.

Reported by copperwater:  if the quest nemesis was present on a level
being saved as bones, it was removed from the map to keep it out of
the bones level but the quest feedback for nemesis death was given
in the process.  Would happen for blessed genocide of "*" too.  (It
didn't happen for #wizmakemap and I'm not sure why.)

This was an unintended side-effect of moving some common stuff from
mondead() and mongone() into m_detach().  The quest feedback isn't
actually common to both.  Instead of moving that back, pass a flag
that m_detach() can use to determine which routine called it.

Fixes #1029
This commit is contained in:
PatR
2023-05-20 16:44:18 -07:00
parent 9052bd5099
commit 92a993a0b6
2 changed files with 28 additions and 19 deletions

View File

@@ -1584,6 +1584,8 @@ the fuzzer could get stuck in a loop if hero died in a way where life-saving
where life-saving teleports you out of it; if the level is full, the
teleport will fail and you'll immediately burn up again)
fix unicorn horn's ability to repair blindness
quest nemesis and a few other special monsters are suppressed from bones;
their death feedback could be given when they were removed
Fixes to 3.7.0-x Platform and/or Interface Problems Exposed Via git Repository

View File

@@ -16,7 +16,7 @@ static long mm_2way_aggression(struct monst *, struct monst *);
static long mm_aggression(struct monst *, struct monst *);
static long mm_displacement(struct monst *, struct monst *);
static void mon_leaving_level(struct monst *);
static void m_detach(struct monst *, struct permonst *);
static void m_detach(struct monst *, struct permonst *, boolean);
static void set_mon_min_mhpmax(struct monst *, int);
static void lifesaved_monster(struct monst *);
static boolean ok_to_obliterate(struct monst *);
@@ -2465,7 +2465,8 @@ mon_leaving_level(struct monst *mon)
static void
m_detach(
struct monst *mtmp,
struct permonst *mptr) /* reflects mtmp->data _prior_ to mtmp's death */
struct permonst *mptr, /* reflects mtmp->data _prior_ to mtmp's death */
boolean due_to_death)
{
coordxy mx = mtmp->mx, my = mtmp->my;
@@ -2487,23 +2488,29 @@ m_detach(
mon_leaving_level(mtmp);
mtmp->mhp = 0; /* simplify some tests: force mhp to 0 */
if (mtmp->iswiz)
wizdead();
if (mtmp->data->msound == MS_NEMESIS) {
nemdead();
/* The Archeologist, Caveman, and Priest quest texts describe
the nemesis's body creating noxious fumes/gas when killed. */
if (stinky_nemesis(mtmp))
create_gas_cloud(mx, my, 5, 8);
/* foodead() might give quest feedback for foo having died; skip that
if we're called for mongone() rather than mondead(); saving bones
or wizard mode genocide of "*" can result in special monsters going
away without having been killed */
if (due_to_death) {
if (mtmp->iswiz)
wizdead();
if (mtmp->data->msound == MS_NEMESIS) {
nemdead();
/* The Archeologist, Caveman, and Priest quest texts describe
the nemesis's body creating noxious fumes/gas when killed. */
if (stinky_nemesis(mtmp))
create_gas_cloud(mx, my, 5, 8);
}
if (mtmp->data->msound == MS_LEADER)
leaddead();
/* release (drop onto map) all objects carried by mtmp; assumes that
mtmp->mx,my contains the appropriate location */
relobj(mtmp, 1, FALSE); /* drop mtmp->minvent, issue newsym(mx,my) */
}
if (mtmp->data->msound == MS_LEADER)
leaddead();
if (mtmp->m_id == gs.stealmid)
thiefdead();
/* release (drop onto map) all objects carried by mtmp; assumes that
mtmp->mx,my contains the appropriate location */
relobj(mtmp, 1, FALSE); /* drop mtmp->minvent, then issue newsym(mx,my) */
if (mtmp->m_id == gs.stealmid)
thiefdead(); /* reset theft-in-progress data */
if (mtmp->isshk)
shkgone(mtmp);
if (mtmp->wormno)
@@ -2795,7 +2802,7 @@ mondead(struct monst *mtmp)
if (glyph_is_invisible(levl[mtmp->mx][mtmp->my].glyph))
unmap_object(mtmp->mx, mtmp->my);
m_detach(mtmp, mptr);
m_detach(mtmp, mptr, TRUE);
return;
}
@@ -2898,7 +2905,7 @@ mongone(struct monst* mdef)
mdrop_special_objs(mdef);
/* release rest of monster's inventory--it is removed from game */
discard_minvent(mdef, FALSE);
m_detach(mdef, mdef->data);
m_detach(mdef, mdef->data, FALSE);
}
/* drop a statue or rock and remove monster */