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.
This commit is contained in:
@@ -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
|
/* Max HP the same, but current HP halved for both. The caller
|
||||||
* might want to override this by halving the max HP also.
|
* might want to override this by halving the max HP also.
|
||||||
* When current HP is odd, the original keeps the extra point.
|
* 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->mhpmax = mon->mhpmax;
|
||||||
m2->mhp = mon->mhp / 2;
|
m2->mhp = mon->mhp / 2;
|
||||||
|
|||||||
20
src/mon.c
20
src/mon.c
@@ -514,14 +514,19 @@ register struct monst *mtmp;
|
|||||||
*/
|
*/
|
||||||
if (!is_clinger(mtmp->data) && !likes_lava(mtmp->data)) {
|
if (!is_clinger(mtmp->data) && !likes_lava(mtmp->data)) {
|
||||||
if (!resists_fire(mtmp)) {
|
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),
|
pline("%s %s.", Monnam(mtmp),
|
||||||
mtmp->data == &mons[PM_WATER_ELEMENTAL]
|
!strcmp(how, "boiling") ? "boils away"
|
||||||
? "boils away"
|
: !strcmp(how, "melting") ? "melts away"
|
||||||
: "burns to a crisp");
|
: "burns to a crisp");
|
||||||
|
}
|
||||||
mondead(mtmp);
|
mondead(mtmp);
|
||||||
} else {
|
} else {
|
||||||
if (--mtmp->mhp < 1) {
|
mtmp->mhp -= 1;
|
||||||
|
if (mtmp->mhp < 1) {
|
||||||
if (cansee(mtmp->mx, mtmp->my))
|
if (cansee(mtmp->mx, mtmp->my))
|
||||||
pline("%s surrenders to the fire.", Monnam(mtmp));
|
pline("%s surrenders to the fire.", Monnam(mtmp));
|
||||||
mondead(mtmp);
|
mondead(mtmp);
|
||||||
@@ -1775,8 +1780,8 @@ struct monst *mtmp;
|
|||||||
/* genocided monster can't be life-saved */
|
/* genocided monster can't be life-saved */
|
||||||
if (cansee(mtmp->mx, mtmp->my))
|
if (cansee(mtmp->mx, mtmp->my))
|
||||||
pline("Unfortunately, %s is still genocided...", mon_nam(mtmp));
|
pline("Unfortunately, %s is still genocided...", mon_nam(mtmp));
|
||||||
|
mtmp->mhp = 0;
|
||||||
}
|
}
|
||||||
mtmp->mhp = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -1786,6 +1791,7 @@ register struct monst *mtmp;
|
|||||||
struct permonst *mptr;
|
struct permonst *mptr;
|
||||||
int tmp;
|
int tmp;
|
||||||
|
|
||||||
|
mtmp->mhp = 0; /* in case caller hasn't done this */
|
||||||
lifesaved_monster(mtmp);
|
lifesaved_monster(mtmp);
|
||||||
if (mtmp->mhp > 0)
|
if (mtmp->mhp > 0)
|
||||||
return;
|
return;
|
||||||
@@ -2028,6 +2034,7 @@ struct monst *mdef;
|
|||||||
* put inventory in it, and we have to check for lifesaving before
|
* put inventory in it, and we have to check for lifesaving before
|
||||||
* making the statue....
|
* making the statue....
|
||||||
*/
|
*/
|
||||||
|
mdef->mhp = 0; /* in case caller hasn't done this */
|
||||||
lifesaved_monster(mdef);
|
lifesaved_monster(mdef);
|
||||||
if (mdef->mhp > 0)
|
if (mdef->mhp > 0)
|
||||||
return;
|
return;
|
||||||
@@ -2167,6 +2174,7 @@ int xkill_flags; /* 1: suppress message, 2: suppress corpse, 4: pacifist */
|
|||||||
nocorpse = (xkill_flags & XKILL_NOCORPSE) != 0,
|
nocorpse = (xkill_flags & XKILL_NOCORPSE) != 0,
|
||||||
noconduct = (xkill_flags & XKILL_NOCONDUCT) != 0;
|
noconduct = (xkill_flags & XKILL_NOCONDUCT) != 0;
|
||||||
|
|
||||||
|
mtmp->mhp = 0; /* caller will usually have already done this */
|
||||||
if (!noconduct) /* KMH, conduct */
|
if (!noconduct) /* KMH, conduct */
|
||||||
u.uconduct.killer++;
|
u.uconduct.killer++;
|
||||||
|
|
||||||
|
|||||||
17
src/muse.c
17
src/muse.c
@@ -140,7 +140,7 @@ struct obj *obj;
|
|||||||
int dam = d(obj->spe + 2, 6);
|
int dam = d(obj->spe + 2, 6);
|
||||||
|
|
||||||
/* 3.6.1: no Deaf filter; 'if' message doesn't warrant it, 'else'
|
/* 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) {
|
if (vis) {
|
||||||
pline("%s zaps %s, which suddenly explodes!", Monnam(mon),
|
pline("%s zaps %s, which suddenly explodes!", Monnam(mon),
|
||||||
an(xname(obj)));
|
an(xname(obj)));
|
||||||
@@ -154,11 +154,11 @@ struct obj *obj;
|
|||||||
? "nearby" : "in the distance");
|
? "nearby" : "in the distance");
|
||||||
}
|
}
|
||||||
m_useup(mon, obj);
|
m_useup(mon, obj);
|
||||||
if (mon->mhp <= dam) {
|
mon->mhp -= dam;
|
||||||
|
if (mon->mhp <= 0) {
|
||||||
monkilled(mon, "", AD_RBRE);
|
monkilled(mon, "", AD_RBRE);
|
||||||
return 1;
|
return 1;
|
||||||
} else
|
}
|
||||||
mon->mhp -= dam;
|
|
||||||
m.has_defense = m.has_offense = m.has_misc = 0;
|
m.has_defense = m.has_offense = m.has_misc = 0;
|
||||||
/* Only one needed to be set to 0 but the others are harmless */
|
/* Only one needed to be set to 0 but the others are harmless */
|
||||||
}
|
}
|
||||||
@@ -1498,10 +1498,13 @@ struct monst *mtmp;
|
|||||||
else
|
else
|
||||||
losehp(num, "scroll of fire", KILLED_BY_AN);
|
losehp(num, "scroll of fire", KILLED_BY_AN);
|
||||||
for (mtmp2 = fmon; mtmp2; mtmp2 = mtmp2->nmon) {
|
for (mtmp2 = fmon; mtmp2; mtmp2 = mtmp2->nmon) {
|
||||||
if (DEADMONSTER(mtmp2)) continue;
|
if (DEADMONSTER(mtmp2))
|
||||||
if (mtmp == mtmp2) continue;
|
continue;
|
||||||
|
if (mtmp == mtmp2)
|
||||||
|
continue;
|
||||||
if (dist2(mtmp2->mx, mtmp2->my, mtmp->mx, mtmp->my) < 3) {
|
if (dist2(mtmp2->mx, mtmp2->my, mtmp->mx, mtmp->my) < 3) {
|
||||||
if (resists_fire(mtmp2)) continue;
|
if (resists_fire(mtmp2))
|
||||||
|
continue;
|
||||||
mtmp2->mhp -= num;
|
mtmp2->mhp -= num;
|
||||||
if (resists_cold(mtmp2))
|
if (resists_cold(mtmp2))
|
||||||
mtmp2->mhp -= 3 * num;
|
mtmp2->mhp -= 3 * num;
|
||||||
|
|||||||
11
src/music.c
11
src/music.c
@@ -352,12 +352,12 @@ int force;
|
|||||||
/* Falling is okay for falling down
|
/* Falling is okay for falling down
|
||||||
within a pit from jostling too */
|
within a pit from jostling too */
|
||||||
mselftouch(mtmp, "Falling, ", TRUE);
|
mselftouch(mtmp, "Falling, ", TRUE);
|
||||||
if (mtmp->mhp > 0)
|
if (mtmp->mhp > 0) {
|
||||||
if ((mtmp->mhp -=
|
mtmp->mhp -= rnd(m_already_trapped ? 4 : 6);
|
||||||
rnd(m_already_trapped ? 4 : 6)) <= 0) {
|
if (mtmp->mhp <= 0) {
|
||||||
if (!cansee(x, y))
|
if (!cansee(x, y)) {
|
||||||
pline("It is destroyed!");
|
pline("It is destroyed!");
|
||||||
else {
|
} else {
|
||||||
You("destroy %s!",
|
You("destroy %s!",
|
||||||
mtmp->mtame
|
mtmp->mtame
|
||||||
? x_monnam(mtmp, ARTICLE_THE,
|
? x_monnam(mtmp, ARTICLE_THE,
|
||||||
@@ -370,6 +370,7 @@ int force;
|
|||||||
}
|
}
|
||||||
xkilled(mtmp, XKILL_NOMSG);
|
xkilled(mtmp, XKILL_NOMSG);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (x == u.ux && y == u.uy) {
|
} else if (x == u.ux && y == u.uy) {
|
||||||
if (Levitation || Flying
|
if (Levitation || Flying
|
||||||
|
|||||||
12
src/trap.c
12
src/trap.c
@@ -2531,7 +2531,8 @@ register struct monst *mtmp;
|
|||||||
|
|
||||||
if (in_sight)
|
if (in_sight)
|
||||||
seetrap(trap);
|
seetrap(trap);
|
||||||
if ((mtmp->mhp -= dmgval2) <= 0)
|
mtmp->mhp -= dmgval2;
|
||||||
|
if (mtmp->mhp <= 0)
|
||||||
monkilled(mtmp,
|
monkilled(mtmp,
|
||||||
in_sight
|
in_sight
|
||||||
? "compression from an anti-magic field"
|
? "compression from an anti-magic field"
|
||||||
@@ -3885,7 +3886,8 @@ boolean force_failure;
|
|||||||
if (ttype == BEAR_TRAP) {
|
if (ttype == BEAR_TRAP) {
|
||||||
if (mtmp->mtame)
|
if (mtmp->mtame)
|
||||||
abuse_dog(mtmp);
|
abuse_dog(mtmp);
|
||||||
if ((mtmp->mhp -= rnd(4)) <= 0)
|
mtmp->mhp -= rnd(4);
|
||||||
|
if (mtmp->mhp <= 0)
|
||||||
killed(mtmp);
|
killed(mtmp);
|
||||||
} else if (ttype == WEB) {
|
} else if (ttype == WEB) {
|
||||||
if (!webmaker(youmonst.data)) {
|
if (!webmaker(youmonst.data)) {
|
||||||
@@ -4941,9 +4943,9 @@ boolean nocorpse;
|
|||||||
if (dam < 1)
|
if (dam < 1)
|
||||||
dam = 1;
|
dam = 1;
|
||||||
}
|
}
|
||||||
if ((mon->mhp -= dam) <= 0) {
|
mon->mhp -= dam;
|
||||||
int xx = mon->mx;
|
if (mon->mhp <= 0) {
|
||||||
int yy = mon->my;
|
int xx = mon->mx, yy = mon->my;
|
||||||
|
|
||||||
monkilled(mon, "", nocorpse ? -AD_RBRE : AD_PHYS);
|
monkilled(mon, "", nocorpse ? -AD_RBRE : AD_PHYS);
|
||||||
if (mon->mhp <= 0) {
|
if (mon->mhp <= 0) {
|
||||||
|
|||||||
13
src/uhitm.c
13
src/uhitm.c
@@ -1604,7 +1604,9 @@ register struct attack *mattk;
|
|||||||
|
|
||||||
pline("%s suddenly seems weaker!", Monnam(mdef));
|
pline("%s suddenly seems weaker!", Monnam(mdef));
|
||||||
mdef->mhpmax -= xtmp;
|
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));
|
pline("%s dies!", Monnam(mdef));
|
||||||
xkilled(mdef, XKILL_NOMSG);
|
xkilled(mdef, XKILL_NOMSG);
|
||||||
} else
|
} else
|
||||||
@@ -1767,7 +1769,8 @@ register struct attack *mattk;
|
|||||||
}
|
}
|
||||||
|
|
||||||
mdef->mstrategy &= ~STRAT_WAITFORU; /* in case player is very fast */
|
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)) {
|
if (mdef->mtame && !cansee(mdef->mx, mdef->my)) {
|
||||||
You_feel("embarrassed for a moment.");
|
You_feel("embarrassed for a moment.");
|
||||||
if (tmp)
|
if (tmp)
|
||||||
@@ -2043,7 +2046,8 @@ register struct attack *mattk;
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
end_engulf();
|
end_engulf();
|
||||||
if ((mdef->mhp -= dam) <= 0) {
|
mdef->mhp -= dam;
|
||||||
|
if (mdef->mhp <= 0) {
|
||||||
killed(mdef);
|
killed(mdef);
|
||||||
if (mdef->mhp <= 0) /* not lifesaved */
|
if (mdef->mhp <= 0) /* not lifesaved */
|
||||||
return 2;
|
return 2;
|
||||||
@@ -2690,7 +2694,8 @@ int dmg;
|
|||||||
{
|
{
|
||||||
pline("%s %s!", Monnam(mon),
|
pline("%s %s!", Monnam(mon),
|
||||||
(dmg > mon->mhp / 2) ? "wails in agony" : "cries out in pain");
|
(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)
|
if (context.mon_moving)
|
||||||
monkilled(mon, (char *) 0, AD_BLND);
|
monkilled(mon, (char *) 0, AD_BLND);
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -3432,7 +3432,8 @@ int dx, dy;
|
|||||||
return (struct monst *) 0;
|
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
|
int
|
||||||
zhitm(mon, type, nd, ootmp)
|
zhitm(mon, type, nd, ootmp)
|
||||||
register struct monst *mon;
|
register struct monst *mon;
|
||||||
|
|||||||
Reference in New Issue
Block a user