]> granicus.if.org Git - nethack/commitdiff
Unify ad_drli
authorPasi Kallinen <paxed@alt.org>
Mon, 30 Nov 2020 17:43:16 +0000 (19:43 +0200)
committerPasi Kallinen <paxed@alt.org>
Fri, 4 Dec 2020 07:30:14 +0000 (09:30 +0200)
include/extern.h
src/mhitm.c
src/mhitu.c
src/uhitm.c

index cf5f18597efde67e09150126658577ba47d47be8..2607c69b0274f24447d1a12d485b869532f66c76 100644 (file)
@@ -2759,6 +2759,7 @@ E void FDECL(mhitm_ad_rust, (struct monst *, struct attack *, struct monst *, st
 E void FDECL(mhitm_ad_corr, (struct monst *, struct attack *, struct monst *, struct mhitm_data *));
 E void FDECL(mhitm_ad_dcay, (struct monst *, struct attack *, struct monst *, struct mhitm_data *));
 E void FDECL(mhitm_ad_dren, (struct monst *, struct attack *, struct monst *, struct mhitm_data *));
+E void FDECL(mhitm_ad_drli, (struct monst *, struct attack *, struct monst *, struct mhitm_data *));
 E int FDECL(damageum, (struct monst *, struct attack *, int));
 E void FDECL(missum, (struct monst *, struct attack *, BOOLEAN_P));
 E int FDECL(passive, (struct monst *, struct obj *, BOOLEAN_P, int,
index 90cf855e8dfae7b8d36b070ba1f2761d19dea69d..4850e31951494b625a3f2fb3da21837e85778661 100644 (file)
@@ -1286,26 +1286,9 @@ int dieroll;
         }
         break;
     case AD_DRLI: /* drain life */
-        if (!cancelled && !rn2(3) && !resists_drli(mdef)) {
-            mhm.damage = d(2, 6); /* Stormbringer uses monhp_per_lvl(usually 1d8) */
-            if (g.vis && canspotmon(mdef))
-                pline("%s becomes weaker!", Monnam(mdef));
-            if (mdef->mhpmax - mhm.damage > (int) mdef->m_lev) {
-                mdef->mhpmax -= mhm.damage;
-            } 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;
-            }
-            if (mdef->m_lev == 0) /* automatic kill if drained past level 0 */
-                mhm.damage = mdef->mhp;
-            else
-                mdef->m_lev--;
-
-            /* unlike hitting with Stormbringer, wounded attacker doesn't
-               heal any from the drained life */
-        }
+        mhitm_ad_drli(magr, mattk, mdef, &mhm);
+        if (mhm.done)
+            return mhm.hitflags;
         break;
     case AD_SSEX:
     case AD_SITM: /* for now these are the same */
index c8567e1142c35bcd548a416f148946da1a66c88a..0c4dde8850fd447db0e1e77ab314637fb84f7524 100644 (file)
@@ -1242,13 +1242,9 @@ register struct attack *mattk;
         }
         break;
     case AD_DRLI: /* drain life */
-        hitmsg(mtmp, mattk);
-        if (uncancelled && !rn2(3) && !Drain_resistance) {
-            losexp("life drainage");
-
-            /* unlike hitting with Stormbringer, wounded attacker doesn't
-               heal any from the drained life */
-        }
+        mhitm_ad_drli(mtmp, mattk, &g.youmonst, &mhm);
+        if (mhm.done)
+            return mhm.hitflags;
         break;
     case AD_LEGS: {
         long side = rn2(2) ? RIGHT_SIDE : LEFT_SIDE;
index 7bd27ee0a0b8c19ad5c28eb8a600c0339b1e5822..88ce1958b584435ada5c8c7b65bcd510b51799f1 100644 (file)
@@ -1852,10 +1852,6 @@ struct mhitm_data *mhm;
         mhm->damage = 0;
     } else if (mdef == &g.youmonst) {
         /* mhitu */
-        /*  Next a cancellation factor.
-         *  Use uncancelled when cancellation factor takes into account certain
-         *  armor's special magic protection.  Otherwise just use !mtmp->mcan.
-         */
         int armpro = magic_negation(mdef);
         boolean uncancelled = !magr->mcan && (rn2(10) >= 3 * armpro);
 
@@ -1876,6 +1872,87 @@ struct mhitm_data *mhm;
     }
 }
 
+void
+mhitm_ad_drli(magr, mattk, mdef, mhm)
+struct monst *magr;
+struct attack *mattk;
+struct monst *mdef;
+struct mhitm_data *mhm;
+{
+    struct permonst *pd = mdef->data;
+
+    if (magr == &g.youmonst) {
+        /* uhitm */
+        int armpro = magic_negation(mdef);
+        /* since hero can't be cancelled, only defender's armor applies */
+        boolean negated = !(rn2(10) >= 3 * armpro);
+
+        if (!negated && !rn2(3) && !resists_drli(mdef)) {
+            mhm->damage = d(2, 6); /* Stormbringer uses monhp_per_lvl(usually 1d8) */
+            pline("%s becomes weaker!", Monnam(mdef));
+            if (mdef->mhpmax - mhm->damage > (int) mdef->m_lev) {
+                mdef->mhpmax -= mhm->damage;
+            } 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 -= mhm->damage;
+            /* !m_lev: level 0 monster is killed regardless of hit points
+               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 %s!", Monnam(mdef),
+                      nonliving(mdef->data) ? "expires" : "dies");
+                xkilled(mdef, XKILL_NOMSG);
+            } else
+                mdef->m_lev--;
+            mhm->damage = 0; /* damage has already been inflicted */
+
+            /* unlike hitting with Stormbringer, wounded hero doesn't
+               heal any from the drained life */
+        }
+    } else if (mdef == &g.youmonst) {
+        /* mhitu */
+        int armpro = magic_negation(mdef);
+        boolean uncancelled = !magr->mcan && (rn2(10) >= 3 * armpro);
+
+        hitmsg(magr, mattk);
+        if (uncancelled && !rn2(3) && !Drain_resistance) {
+            losexp("life drainage");
+
+            /* unlike hitting with Stormbringer, wounded attacker doesn't
+               heal any from the drained life */
+        }
+    } else {
+        /* mhitm */
+        int armpro = magic_negation(mdef);
+        boolean cancelled = magr->mcan || !(rn2(10) >= 3 * armpro);
+
+        if (!cancelled && !rn2(3) && !resists_drli(mdef)) {
+            mhm->damage = d(2, 6); /* Stormbringer uses monhp_per_lvl(usually 1d8) */
+            if (g.vis && canspotmon(mdef))
+                pline("%s becomes weaker!", Monnam(mdef));
+            if (mdef->mhpmax - mhm->damage > (int) mdef->m_lev) {
+                mdef->mhpmax -= mhm->damage;
+            } 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;
+            }
+            if (mdef->m_lev == 0) /* automatic kill if drained past level 0 */
+                mhm->damage = mdef->mhp;
+            else
+                mdef->m_lev--;
+
+            /* unlike hitting with Stormbringer, wounded attacker doesn't
+               heal any from the drained life */
+        }
+    }
+}
+
 /* Template for monster hits monster for AD_FOO.
    - replace "break" with return
    - replace "return" with mhm->done = TRUE
@@ -2126,32 +2203,9 @@ int specialdmg; /* blessed and/or silver bonus against various things */
         mhm.damage = 0;
         break;
     case AD_DRLI: /* drain life */
-        if (!negated && !rn2(3) && !resists_drli(mdef)) {
-            mhm.damage = d(2, 6); /* Stormbringer uses monhp_per_lvl(usually 1d8) */
-            pline("%s becomes weaker!", Monnam(mdef));
-            if (mdef->mhpmax - mhm.damage > (int) mdef->m_lev) {
-                mdef->mhpmax -= mhm.damage;
-            } 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 -= mhm.damage;
-            /* !m_lev: level 0 monster is killed regardless of hit points
-               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 %s!", Monnam(mdef),
-                      nonliving(mdef->data) ? "expires" : "dies");
-                xkilled(mdef, XKILL_NOMSG);
-            } else
-                mdef->m_lev--;
-            mhm.damage = 0; /* damage has already been inflicted */
-
-            /* unlike hitting with Stormbringer, wounded hero doesn't
-               heal any from the drained life */
-        }
+        mhitm_ad_drli(&g.youmonst, mattk, mdef, &mhm);
+        if (mhm.done)
+            return mhm.hitflags;
         break;
     case AD_RUST:
         mhitm_ad_rust(&g.youmonst, mattk, mdef, &mhm);