mhpmax of life-drained monsters
The report about problems after stone-to-flesh on a petrified long worm included stethoscope feedback of 0(-1) hit points, after life-draining. I was unable to reproduce a maximum hp of -1 and hope that it was a side-effect of the [already fixed] stale mon->wormno value used when resurrecting the long worm. Anyway, this changes life-draining to never take mon->hpmax below mon->m_lev + 1 (the +1 is needed to cope with m_lev==0 monsters). The same limit is also applied to monster life-saving but more to avoid replicating the arbitrary minimum of 10 (four instances) then because it might be less than m_lev+1 somehow. Sanity checking now tests whether a monster's max HP is less than its level + 1 so if there are ways other than life-drain attacks for it to drop that low, the fuzzer will choke. The new check also tests whether a monster's current HP is greater than max HP. Polymophred hero killing a golem or vortex by vampire bite reported "<Mon> dies." Give an alternate message since those aren't alive.
This commit is contained in:
31
src/uhitm.c
31
src/uhitm.c
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 uhitm.c $NHDT-Date: 1591017421 2020/06/01 13:17:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.236 $ */
|
||||
/* NetHack 3.6 uhitm.c $NHDT-Date: 1593306911 2020/06/28 01:15:11 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.237 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Robert Patrick Rankin, 2012. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -1845,21 +1845,32 @@ int specialdmg; /* blessed and/or silver bonus against various things */
|
||||
}
|
||||
tmp = 0;
|
||||
break;
|
||||
case AD_DRLI:
|
||||
case AD_DRLI: /* drain life */
|
||||
if (!negated && !rn2(3) && !resists_drli(mdef)) {
|
||||
int xtmp = d(2, 6);
|
||||
|
||||
pline("%s suddenly seems weaker!", Monnam(mdef));
|
||||
mdef->mhpmax -= xtmp;
|
||||
mdef->mhp -= xtmp;
|
||||
tmp = d(2, 6); /* Stormbringer uses monhp_per_lvl(usually 1d8) */
|
||||
pline("%s becomes weaker!", Monnam(mdef));
|
||||
if (mdef->mhpmax - tmp > (int) mdef->m_lev) {
|
||||
mdef->mhpmax -= tmp;
|
||||
} else {
|
||||
/* limit floor of mhpmax reduction to current m_lev + 1;
|
||||
avoid increasing it if somehow already less than that */
|
||||
if (mdef->mhpmax > (int) mdef->m_lev)
|
||||
mdef->mhpmax = (int) mdef->m_lev + 1;
|
||||
}
|
||||
mdef->mhp -= tmp;
|
||||
/* !m_lev: level 0 monster is killed regardless of hit points
|
||||
rather than drop to level -1 */
|
||||
rather than drop to level -1; note: some non-living creatures
|
||||
(golems, vortices) are subject to life-drain */
|
||||
if (DEADMONSTER(mdef) || !mdef->m_lev) {
|
||||
pline("%s dies!", Monnam(mdef));
|
||||
pline("%s %s!", Monnam(mdef),
|
||||
nonliving(mdef->data) ? "expires" : "dies");
|
||||
xkilled(mdef, XKILL_NOMSG);
|
||||
} else
|
||||
mdef->m_lev--;
|
||||
tmp = 0;
|
||||
tmp = 0; /* damage has already been inflicted */
|
||||
|
||||
/* unlike hitting with Stormbringer, wounded hero doesn't
|
||||
heal any from the drained life */
|
||||
}
|
||||
break;
|
||||
case AD_RUST:
|
||||
|
||||
Reference in New Issue
Block a user