diff --git a/doc/fixes35.0 b/doc/fixes35.0 index dcc66ec72..a8ca82367 100644 --- a/doc/fixes35.0 +++ b/doc/fixes35.0 @@ -86,6 +86,8 @@ various actions--such as enchanting--performed on an unpaid shop object adjust health threshold where wounded hero will be healed by successful prayer prevent lose-level+regain-level cycle from arbritrarily boosting HP and Pw prevent polymorphing into "new man" at low level from magnifying HP and Pw +losing a level while polymorphed affects hero's current monster HP as well as + underlying normal HP Platform- and/or Interface-Specific Fixes diff --git a/include/extern.h b/include/extern.h index 1584fea30..934ef429f 100644 --- a/include/extern.h +++ b/include/extern.h @@ -960,6 +960,7 @@ E void FDECL(readmail, (struct obj *)); E boolean FDECL(is_home_elemental, (struct permonst *)); E struct monst *FDECL(clone_mon, (struct monst *,XCHAR_P,XCHAR_P)); +E int FDECL(monhp_per_lvl, (struct monst *)); E void FDECL(newmonhp, (struct monst *,int)); E struct monst *FDECL(makemon, (struct permonst *,int,int,int)); E boolean FDECL(create_critters, (int,struct permonst *)); diff --git a/src/artifact.c b/src/artifact.c index 2d9cbb719..c8950b1e5 100644 --- a/src/artifact.c +++ b/src/artifact.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)artifact.c 3.5 2005/04/15 */ +/* SCCS Id: @(#)artifact.c 3.5 2005/09/20 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1133,7 +1133,7 @@ int dieroll; /* needed for Magicbane and vorpal blades */ if (mdef->m_lev == 0) { *dmgptr = 2 * mdef->mhp + FATAL_DAMAGE_MODIFIER; } else { - int drain = rnd(8); + int drain = monhp_per_lvl(mdef); *dmgptr += drain; mdef->mhpmax -= drain; mdef->m_lev--; diff --git a/src/exper.c b/src/exper.c index ec276c4da..523a72e37 100644 --- a/src/exper.c +++ b/src/exper.c @@ -190,6 +190,14 @@ const char *drainer; /* cause of death, if drain should be fatal */ if (u.uexp > 0) u.uexp = newuexp(u.ulevel) - 1; + + if (Upolyd) { + num = monhp_per_lvl(&youmonst); + u.mhmax -= num; + u.mh -= num; + if (u.mh <= 0) rehumanize(); + } + context.botl = 1; } @@ -217,7 +225,7 @@ boolean incr; /* true iff via incremental experience growth */ /* increase hit points (when polymorphed, do monster form first in order to retain normal human/whatever increase for later) */ if (Upolyd) { - hpinc = rnd(8); + hpinc = monhp_per_lvl(&youmonst); u.mhmax += hpinc; u.mh += hpinc; } diff --git a/src/makemon.c b/src/makemon.c index 23177d7e0..05945ab6c 100644 --- a/src/makemon.c +++ b/src/makemon.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)makemon.c 3.5 2005/07/13 */ +/* SCCS Id: @(#)makemon.c 3.5 2005/09/20 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -803,6 +803,31 @@ boolean ghostly; return result; } +/* amount of HP to lose from level drain (or gain from Stormbringer) */ +int +monhp_per_lvl(mon) +struct monst *mon; +{ + struct permonst *ptr = mon->data; + int hp = rnd(8); /* default is d8 */ + + /* like newmonhp, but home elementals are ignored, riders use normal d8 */ + if (is_golem(ptr)) { + /* draining usually won't be applicable for these critters */ + hp = golemhp(monsndx(ptr)) / (int)ptr->mlevel; + } else if (ptr->mlevel > 49) { + /* arbitrary; such monsters won't be involved in draining anyway */ + hp = 4 + rnd(4); /* 5..8 */ + } else if (ptr->mlet == S_DRAGON && monsndx(ptr) >= PM_GRAY_DRAGON) { + /* adult dragons; newmonhp() uses In_endgame(&u.uz) ? 8 : 4 + rnd(4) */ + hp = 4 + rn2(5); /* 4..8 */ + } else if (!mon->m_lev) { + /* level 0 monsters use 1d4 instead of Nd8 */ + hp = rnd(4); + } + return hp; +} + /* set up a new monster's initial level and hit points; used by newcham() as well as by makemon() */ void diff --git a/src/zap.c b/src/zap.c index 8e78c3bc9..95297223c 100644 --- a/src/zap.c +++ b/src/zap.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)zap.c 3.5 2005/06/22 */ +/* SCCS Id: @(#)zap.c 3.5 2005/09/20 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -311,7 +311,7 @@ struct obj *otmp; wake = FALSE; break; case SPE_DRAIN_LIFE: - dmg = rnd(8); + dmg = monhp_per_lvl(mtmp); if(dbldam) dmg *= 2; if (otyp == SPE_DRAIN_LIFE) dmg += spell_damage_bonus();