fix pull request #468 - scroll of earth panic

If a monster read a scroll of earth and got killed in the process,
there would be an "dealloc_obj: obj not free" panic when trying to
use up the scroll.  It was dropped to the ground with any other
possessions and no longer in the monster's inventory at the time
m_useup() was called.  Use up the scroll before performing its
effects.

The patch does something similar for potion of polymorph, but if
newcham() can kill the monster then there are other problems
besides trying to use up the potion.  I kept that in anyway.

Fixes #468
This commit is contained in:
PatR
2021-03-16 11:20:16 -07:00
parent 0cca010ff1
commit c6e6d65e43
2 changed files with 9 additions and 7 deletions

View File

@@ -412,7 +412,7 @@ remove superfluous "All" from "All foos are already nonexistent." when blessed
You mime dip <item> intoing something.
mounted hero falling out of saddle shouldn't hit ground and take damage when
levitating or flying (if done without steed's help)
avoid "obj not free" panic if monster kills itself by reading scroll of earth
Fixes to 3.7.0-x Problems that Were Exposed Via git Repository
------------------------------------------------------------------

View File

@@ -1577,7 +1577,7 @@ use_offensive(struct monst* mtmp)
/* don't use monster fields after killing it */
boolean confused = (mtmp->mconf ? TRUE : FALSE);
int mmx = mtmp->mx, mmy = mtmp->my;
boolean is_cursed = otmp->cursed;
boolean is_cursed = otmp->cursed, is_blessed = otmp->blessed;
mreadmsg(mtmp, otmp);
/* Identify the scroll */
@@ -1595,27 +1595,29 @@ use_offensive(struct monst* mtmp)
makeknown(otmp->otyp);
}
/* could be fatal to monster, so use up the scroll before
there's a chance that monster's inventory will be dropped */
m_useup(mtmp, otmp);
/* Loop through the surrounding squares */
for (x = mmx - 1; x <= mmx + 1; x++) {
for (y = mmy - 1; y <= mmy + 1; y++) {
/* Is this a suitable spot? */
if (isok(x, y) && !closed_door(x, y)
&& !IS_ROCK(levl[x][y].typ) && !IS_AIR(levl[x][y].typ)
&& (((x == mmx) && (y == mmy)) ? !otmp->blessed
: !otmp->cursed)
&& (((x == mmx) && (y == mmy)) ? !is_blessed : !is_cursed)
&& (x != u.ux || y != u.uy)) {
(void) drop_boulder_on_monster(x, y, confused, FALSE);
}
}
}
m_useup(mtmp, otmp);
/* Attack the player */
if (distmin(mmx, mmy, u.ux, u.uy) == 1 && !is_cursed) {
drop_boulder_on_player(confused, !is_cursed, FALSE, TRUE);
}
return (DEADMONSTER(mtmp)) ? 1 : 2;
}
} /* case MUSE_SCR_EARTH */
#if 0
case MUSE_SCR_FIRE: {
boolean vis = cansee(mtmp->mx, mtmp->my);
@@ -2136,12 +2138,12 @@ use_misc(struct monst* mtmp)
return 2;
case MUSE_POT_POLYMORPH:
mquaffmsg(mtmp, otmp);
m_useup(mtmp, otmp);
if (vismon)
pline("%s suddenly mutates!", Monnam(mtmp));
(void) newcham(mtmp, muse_newcham_mon(mtmp), FALSE, FALSE);
if (oseen)
makeknown(POT_POLYMORPH);
m_useup(mtmp, otmp);
return 2;
case MUSE_BAG:
return mloot_container(mtmp, otmp, vismon);