]> granicus.if.org Git - nethack/commitdiff
fix pull request #468 - scroll of earth panic
authorPatR <rankin@nethack.org>
Tue, 16 Mar 2021 18:20:16 +0000 (11:20 -0700)
committerPatR <rankin@nethack.org>
Tue, 16 Mar 2021 18:20:16 +0000 (11:20 -0700)
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

doc/fixes37.0
src/muse.c

index 5ffc200a9820ad23494b2414f72302a8b904d912..61bf23a2fb45a02a2d1c5ff86c10a64a96ca7fb7 100644 (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
 ------------------------------------------------------------------
index f2008ff6df180cfef31d1f85f7a740ebd1f0c072..a4eea23cb38d0476e991adfc1281272ef5dc0ad3 100644 (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);