From: PatR Date: Sun, 22 May 2016 01:25:16 +0000 (-0700) Subject: mon->mhp manipulation X-Git-Tag: NetHack-3.6.1_RC01~749 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c1bfa1360fb037ad51b555d3cacaee5972de00a6;p=nethack mon->mhp manipulation 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. --- diff --git a/src/makemon.c b/src/makemon.c index 73a1138d4..e9b56f9c9 100644 --- a/src/makemon.c +++ b/src/makemon.c @@ -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; diff --git a/src/mon.c b/src/mon.c index aadc3c6a4..b8f201bbf 100644 --- 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++; diff --git a/src/muse.c b/src/muse.c index f64f8dc32..0b8c3ded1 100644 --- a/src/muse.c +++ b/src/muse.c @@ -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; diff --git a/src/music.c b/src/music.c index b765b6722..58cc4b0f0 100644 --- a/src/music.c +++ b/src/music.c @@ -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 diff --git a/src/trap.c b/src/trap.c index 92d2dfd6d..6d52dce3e 100644 --- a/src/trap.c +++ b/src/trap.c @@ -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) { diff --git a/src/uhitm.c b/src/uhitm.c index a91c48c49..0ca149785 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -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 diff --git a/src/zap.c b/src/zap.c index 6bc482278..161959ffb 100644 --- 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;