]> granicus.if.org Git - nethack/commitdiff
mon->mhp manipulation
authorPatR <rankin@nethack.org>
Sun, 22 May 2016 01:25:16 +0000 (18:25 -0700)
committerPatR <rankin@nethack.org>
Sun, 22 May 2016 01:25:16 +0000 (18:25 -0700)
I've hunted for other instances where monster hit points were set
to zero or less without calling the routine that kills off the
monster (see recent mon_unslime() vs zhitm()) and didn't find any
for mhp subtraction.  I haven't checked for direct assignment yet.

For a while I thought I'd found several cases where a monster was
intended to be killed but got left with positive hit points, but
it turned out that lifesaved_monster(), of all places, was setting
them to zero.  I've moved that to its callers so that it isn't so
well hidden.  And changed several ''if ((mon->mhp -= dmg) <= 0)''
into separate subtraction and 'if' just so the mhp manipulation is
a bit more visible.

I think the only actual change here is the message for monster
being killed by lava, where glass golems now melt instead of burn.

src/makemon.c
src/mon.c
src/muse.c
src/music.c
src/trap.c
src/uhitm.c
src/zap.c

index 73a1138d49f7b9a4d9d8d4b2f83b4b2754a8d8d8..e9b56f9c90a1ef591c9abc2334cf8bd0022e3e83 100644 (file)
@@ -770,6 +770,7 @@ xchar x, y; /* clone's preferred location or 0 (near mon) */
     /* Max HP the same, but current HP halved for both.  The caller
      * might want to override this by halving the max HP also.
      * When current HP is odd, the original keeps the extra point.
+     * We know original has more than 1 HP, so both end up with at least 1.
      */
     m2->mhpmax = mon->mhpmax;
     m2->mhp = mon->mhp / 2;
index aadc3c6a407d261dd7e91d2ee750799421c889e4..b8f201bbf193658d2bfa1d91745052455e69afef 100644 (file)
--- a/src/mon.c
+++ b/src/mon.c
@@ -514,14 +514,19 @@ register struct monst *mtmp;
          */
         if (!is_clinger(mtmp->data) && !likes_lava(mtmp->data)) {
             if (!resists_fire(mtmp)) {
-                if (cansee(mtmp->mx, mtmp->my))
+                if (cansee(mtmp->mx, mtmp->my)) {
+                    struct attack *dummy = &mtmp->data->mattk[0];
+                    const char *how = on_fire(mtmp->data, dummy);
+
                     pline("%s %s.", Monnam(mtmp),
-                          mtmp->data == &mons[PM_WATER_ELEMENTAL]
-                              ? "boils away"
-                              : "burns to a crisp");
+                          !strcmp(how, "boiling") ? "boils away"
+                             : !strcmp(how, "melting") ? "melts away"
+                                : "burns to a crisp");
+                }
                 mondead(mtmp);
             } else {
-                if (--mtmp->mhp < 1) {
+                mtmp->mhp -= 1;
+                if (mtmp->mhp < 1) {
                     if (cansee(mtmp->mx, mtmp->my))
                         pline("%s surrenders to the fire.", Monnam(mtmp));
                     mondead(mtmp);
@@ -1775,8 +1780,8 @@ struct monst *mtmp;
         /* genocided monster can't be life-saved */
         if (cansee(mtmp->mx, mtmp->my))
             pline("Unfortunately, %s is still genocided...", mon_nam(mtmp));
+        mtmp->mhp = 0;
     }
-    mtmp->mhp = 0;
 }
 
 void
@@ -1786,6 +1791,7 @@ register struct monst *mtmp;
     struct permonst *mptr;
     int tmp;
 
+    mtmp->mhp = 0; /* in case caller hasn't done this */
     lifesaved_monster(mtmp);
     if (mtmp->mhp > 0)
         return;
@@ -2028,6 +2034,7 @@ struct monst *mdef;
      * put inventory in it, and we have to check for lifesaving before
      * making the statue....
      */
+    mdef->mhp = 0; /* in case caller hasn't done this */
     lifesaved_monster(mdef);
     if (mdef->mhp > 0)
         return;
@@ -2167,6 +2174,7 @@ int xkill_flags; /* 1: suppress message, 2: suppress corpse, 4: pacifist */
             nocorpse = (xkill_flags & XKILL_NOCORPSE) != 0,
             noconduct = (xkill_flags & XKILL_NOCONDUCT) != 0;
 
+    mtmp->mhp = 0; /* caller will usually have already done this */
     if (!noconduct) /* KMH, conduct */
         u.uconduct.killer++;
 
index f64f8dc32e956d363858ab7bc2e1c666dbfbf54d..0b8c3ded1c05aa2207b5762ffe35b7b61d89ff41 100644 (file)
@@ -140,7 +140,7 @@ struct obj *obj;
         int dam = d(obj->spe + 2, 6);
 
         /* 3.6.1: no Deaf filter; 'if' message doesn't warrant it, 'else'
-           message doesn't need it since Your_hear() has one of its own */
+           message doesn't need it since You_hear() has one of its own */
         if (vis) {
             pline("%s zaps %s, which suddenly explodes!", Monnam(mon),
                   an(xname(obj)));
@@ -154,11 +154,11 @@ struct obj *obj;
                         ? "nearby" : "in the distance");
         }
         m_useup(mon, obj);
-        if (mon->mhp <= dam) {
+        mon->mhp -= dam;
+        if (mon->mhp <= 0) {
             monkilled(mon, "", AD_RBRE);
             return 1;
-        } else
-            mon->mhp -= dam;
+        }
         m.has_defense = m.has_offense = m.has_misc = 0;
         /* Only one needed to be set to 0 but the others are harmless */
     }
@@ -1498,10 +1498,13 @@ struct monst *mtmp;
             else
                 losehp(num, "scroll of fire", KILLED_BY_AN);
             for (mtmp2 = fmon; mtmp2; mtmp2 = mtmp2->nmon) {
-                if (DEADMONSTER(mtmp2)) continue;
-                if (mtmp == mtmp2) continue;
+                if (DEADMONSTER(mtmp2))
+                    continue;
+                if (mtmp == mtmp2)
+                    continue;
                 if (dist2(mtmp2->mx, mtmp2->my, mtmp->mx, mtmp->my) < 3) {
-                    if (resists_fire(mtmp2)) continue;
+                    if (resists_fire(mtmp2))
+                        continue;
                     mtmp2->mhp -= num;
                     if (resists_cold(mtmp2))
                         mtmp2->mhp -= 3 * num;
index b765b67223b9568907c3f2d526a0c5e4afd58d40..58cc4b0f0d7a93860956a27592ad9348a0e1402b 100644 (file)
@@ -352,12 +352,12 @@ int force;
                             /* Falling is okay for falling down
                                 within a pit from jostling too */
                             mselftouch(mtmp, "Falling, ", TRUE);
-                            if (mtmp->mhp > 0)
-                                if ((mtmp->mhp -=
-                                     rnd(m_already_trapped ? 4 : 6)) <= 0) {
-                                    if (!cansee(x, y))
+                            if (mtmp->mhp > 0) {
+                                mtmp->mhp -= rnd(m_already_trapped ? 4 : 6);
+                                if (mtmp->mhp <= 0) {
+                                    if (!cansee(x, y)) {
                                         pline("It is destroyed!");
-                                    else {
+                                    else {
                                         You("destroy %s!",
                                             mtmp->mtame
                                               ? x_monnam(mtmp, ARTICLE_THE,
@@ -370,6 +370,7 @@ int force;
                                     }
                                     xkilled(mtmp, XKILL_NOMSG);
                                 }
+                            }
                         }
                     } else if (x == u.ux && y == u.uy) {
                         if (Levitation || Flying
index 92d2dfd6dcb61226af5317d63e396af517ee3c8b..6d52dce3e2d6dcd801f14a69066593ab711bef12 100644 (file)
@@ -2531,7 +2531,8 @@ register struct monst *mtmp;
 
                 if (in_sight)
                     seetrap(trap);
-                if ((mtmp->mhp -= dmgval2) <= 0)
+                mtmp->mhp -= dmgval2;
+                if (mtmp->mhp <= 0)
                     monkilled(mtmp,
                               in_sight
                                   ? "compression from an anti-magic field"
@@ -3885,7 +3886,8 @@ boolean force_failure;
                 if (ttype == BEAR_TRAP) {
                     if (mtmp->mtame)
                         abuse_dog(mtmp);
-                    if ((mtmp->mhp -= rnd(4)) <= 0)
+                    mtmp->mhp -= rnd(4);
+                    if (mtmp->mhp <= 0)
                         killed(mtmp);
                 } else if (ttype == WEB) {
                     if (!webmaker(youmonst.data)) {
@@ -4941,9 +4943,9 @@ boolean nocorpse;
             if (dam < 1)
                 dam = 1;
         }
-        if ((mon->mhp -= dam) <= 0) {
-            int xx = mon->mx;
-            int yy = mon->my;
+        mon->mhp -= dam;
+        if (mon->mhp <= 0) {
+            int xx = mon->mx, yy = mon->my;
 
             monkilled(mon, "", nocorpse ? -AD_RBRE : AD_PHYS);
             if (mon->mhp <= 0) {
index a91c48c4973912ba1ad93d0e39bc1610087a0b73..0ca149785013329d723be53c14deb7f4b553a908 100644 (file)
@@ -1604,7 +1604,9 @@ register struct attack *mattk;
 
             pline("%s suddenly seems weaker!", Monnam(mdef));
             mdef->mhpmax -= xtmp;
-            if ((mdef->mhp -= xtmp) <= 0 || !mdef->m_lev) {
+            mdef->mhp -= xtmp;
+            /* !m_lev: level 0 monster is killed rather than drop to -1 */
+            if (mdef->mhp <= 0 && !mdef->m_lev) {
                 pline("%s dies!", Monnam(mdef));
                 xkilled(mdef, XKILL_NOMSG);
             } else
@@ -1767,7 +1769,8 @@ register struct attack *mattk;
     }
 
     mdef->mstrategy &= ~STRAT_WAITFORU; /* in case player is very fast */
-    if ((mdef->mhp -= tmp) < 1) {
+    mdef->mhp -= tmp;
+    if (mdef->mhp < 1) {
         if (mdef->mtame && !cansee(mdef->mx, mdef->my)) {
             You_feel("embarrassed for a moment.");
             if (tmp)
@@ -2043,7 +2046,8 @@ register struct attack *mattk;
                 break;
             }
             end_engulf();
-            if ((mdef->mhp -= dam) <= 0) {
+            mdef->mhp -= dam;
+            if (mdef->mhp <= 0) {
                 killed(mdef);
                 if (mdef->mhp <= 0) /* not lifesaved */
                     return 2;
@@ -2690,7 +2694,8 @@ int dmg;
 {
     pline("%s %s!", Monnam(mon),
           (dmg > mon->mhp / 2) ? "wails in agony" : "cries out in pain");
-    if ((mon->mhp -= dmg) <= 0) {
+    mon->mhp -= dmg;
+    if (mon->mhp <= 0) {
         if (context.mon_moving)
             monkilled(mon, (char *) 0, AD_BLND);
         else
index 6bc482278f2b2efd254faef5898f428e08a7d12c..161959ffb88a10add5419ca7fd112d9745cdbf89 100644 (file)
--- a/src/zap.c
+++ b/src/zap.c
@@ -3432,7 +3432,8 @@ int dx, dy;
     return (struct monst *) 0;
 }
 
-/* used by buzz(); also used by munslime(muse.c); returns damage to mon */
+/* used by buzz(); also used by munslime(muse.c); returns damage applied
+   to mon; note: caller is responsible for killing mon if damage is fatal */
 int
 zhitm(mon, type, nd, ootmp)
 register struct monst *mon;