]> granicus.if.org Git - nethack/commitdiff
level drain while polymorphed (trunk only)
authornethack.rankin <nethack.rankin>
Thu, 22 Sep 2005 06:02:08 +0000 (06:02 +0000)
committernethack.rankin <nethack.rankin>
Thu, 22 Sep 2005 06:02:08 +0000 (06:02 +0000)
     Noticed when incorporating the "vampire dancing" patch:  losing a level
while polymorphed would subtract from your normal hit points but didn't
affect your monster hit points.  Now they'll lose d8 from max and current,
similar to the amount they increase when gaining a level.

     This also addresses an issue from the newsgroup a few weeks back:
someone mentioned an assumption that Stormbringer drained an amount other
than d8 for monsters who use some other formula for their hit points.  It
wasn't true, but now it will be (approximately).  Most monsters with unusual
hit points aren't subject to level drain, so it shouldn't have much impact.

doc/fixes35.0
include/extern.h
src/artifact.c
src/exper.c
src/makemon.c
src/zap.c

index dcc66ec72f342d893ca8d603450525735680d65f..a8ca82367aeb70d8607fc2e5b4c7223eaba4f595 100644 (file)
@@ -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
index 1584fea30fe8393ef7d202c10a453350b56cfbe4..934ef429f18b0f1166049431be377b3a190c50a3 100644 (file)
@@ -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 *));
index 2d9cbb71951ec469e0bbec380202beb16346d439..c8950b1e56d3ebb59887e8bf4416fb35df22864b 100644 (file)
@@ -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--;
index ec276c4da35baeb7cf9a8d2a7428ec747baeffd1..523a72e370952707479a49603b0b5d0a2a3b80e7 100644 (file)
@@ -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;
        }
index 23177d7e0826015096bdf32377f69983dd2122d2..05945ab6c76d1e160902b3d0dd1a8be36c325ab4 100644 (file)
@@ -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
index 8e78c3bc919a3f22a1c7d7981428828cd519348e..95297223c3c820281edf0a6c54517d7578985e38 100644 (file)
--- 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();