]> granicus.if.org Git - nethack/commitdiff
fix #H9118 - stoning a sandestin
authorPatR <rankin@nethack.org>
Thu, 15 Aug 2019 01:49:16 +0000 (18:49 -0700)
committerPatR <rankin@nethack.org>
Thu, 15 Aug 2019 01:49:16 +0000 (18:49 -0700)
causes "dmonsfree: N removed doesn't match N+1 pending" warning.  The
sandestin monster definition flags it as MR_STONE, immune to being
turned to stone.  If the hero hit it with a cockatrice while it was
shape-changed into something which isn't MR_STONE, it had its mon->mhp
set to 0, so died, and its form (mon->data) was set back to sandestin.
known_hitum() decided that it didn't turn to stone because of MR_STONE
for that form so proceeded to kill it off due to lack of hit points,
causing it to die twice.

I started to change that so that it didn't kill off the critter a
second time, bit it really shouldn't be able to kill it by stoning in
the first place.  So sandestin how shares some vampire code to revert
to innate form and not turn to stone when "killed" by stoning.  It
only yields the normal visible polymorph message:  "the <foo> turns
into a <bar>" without any attempt to explain why.  Once in sandestin
form, smacking it with a cockatrice corpse doesn't do anything special
(due to MR_STONE now being unambiguously in effect).  It will soon
shape-change to some other form and then become subject to being
forced back to innate shape by stoning again.

doc/fixes36.3
src/mon.c

index ea02fdf3960892445a83580d27b7414f6dffcc5b..5f8b0815a43cc51f332b3724b63b2cf4e8837e18 100644 (file)
@@ -1,4 +1,4 @@
-$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.102 $ $NHDT-Date: 1565574993 2019/08/12 01:56:33 $
+$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.103 $ $NHDT-Date: 1565833748 2019/08/15 01:49:08 $
 
 This fixes36.3 file is here to capture information about updates in the 3.6.x
 lineage following the release of 3.6.2 in May 2019. Please note, however,
@@ -120,6 +120,11 @@ fix typo in end_of_input() present since 3.6.0 that would prevent compilation
        for NOSAVEONHANGUP+INSURANCE configuration
 when a status condition becomes fatal, keep it listed as an active condition
        during disclosure and/or dumplog rather than having it already reset
+when a shape-shifted sandestin was turned to stone, it died and reverted to
+       sandestin form with 0 HP; that confused known_hitum() because
+       sandestins are immune to stoning; net result was monster dying twice,
+       triggering "dmonsfree: N removed doesn't match N+1 pending" warning;
+       instead of dying, make it revert to sandestin form with full health
 
 
 Fixes to Post-3.6.2 Problems that Were Exposed Via git Repository
index 862125289764f1e69dd6971f3eed1d4964e806ef..ca2e1927654cd97ce64ff7dd0b84a6ece3148661 100644 (file)
--- a/src/mon.c
+++ b/src/mon.c
@@ -1,4 +1,4 @@
-/* NetHack 3.6 mon.c   $NHDT-Date: 1560791350 2019/06/17 17:09:10 $  $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.294 $ */
+/* NetHack 3.6 mon.c   $NHDT-Date: 1565833749 2019/08/15 01:49:09 $  $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.296 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Derek S. Ray, 2015. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -1363,8 +1363,8 @@ long flag;
             thrudoor = TRUE;
     }
 
-nexttry: /* eels prefer the water, but if there is no water nearby,
-            they will crawl over land */
+ nexttry: /* eels prefer the water, but if there is no water nearby,
+             they will crawl over land */
     if (mon->mconf) {
         flag |= ALLOW_ALL;
         flag &= ~NOTONL;
@@ -2185,7 +2185,9 @@ struct monst *mdef;
     xchar x = mdef->mx, y = mdef->my;
     boolean wasinside = FALSE;
 
-    if (!vamp_stone(mdef)) /* vampshifter reverts to vampire */
+    /* vampshifter reverts to vampire;
+       3.6.3: also used to unshift shape-changed sandestin */
+    if (!vamp_stone(mdef))
         return;
 
     /* we have to make the statue before calling mondead, to be able to
@@ -2454,7 +2456,7 @@ int xkill_flags; /* 1: suppress message, 2: suppress corpse, 4: pacifist */
     /* monster is gone, corpse or other object might now be visible */
     newsym(x, y);
 
-cleanup:
+ cleanup:
     /* punish bad behaviour */
     if (is_human(mdat)
         && (!always_hostile(mdat) && mtmp->malign <= 0)
@@ -2588,6 +2590,18 @@ struct monst *mtmp;
             newsym(mtmp->mx, mtmp->my);
             return FALSE;   /* didn't petrify */
         }
+    } else if (mtmp->cham >= LOW_PM
+               && (mons[mtmp->cham].mresists & MR_STONE)) {
+        /* sandestins are stoning-immune so if hit by stoning damage
+           they revert to innate shape rather than become a statue */
+        mtmp->mcanmove = 1;
+        mtmp->mfrozen = 0;
+        if (mtmp->mhpmax <= 0)
+            mtmp->mhpmax = 10;
+        mtmp->mhp = mtmp->mhpmax;
+        (void) newcham(mtmp, &mons[mtmp->cham], FALSE, TRUE);
+        newsym(mtmp->mx, mtmp->my);
+        return FALSE;   /* didn't petrify */
     }
     return TRUE;
 }
@@ -2688,7 +2702,7 @@ struct monst *mon;
             mtmp->mstate |= MON_OBLITERATE;
             mongone(mtmp);
             /* places in the code might still reference mtmp->mx, mtmp->my */
-            /* mtmp->mx = mtmp->my = 0; */ 
+            /* mtmp->mx = mtmp->my = 0; */
             rloc_to(mon, mx, my);           /* note: mon, not mtmp */
 
         /* last resort - migrate mon to the next plane */