]> granicus.if.org Git - nethack/commitdiff
Unify ad_heal
authorPasi Kallinen <paxed@alt.org>
Tue, 1 Dec 2020 08:58:51 +0000 (10:58 +0200)
committerPasi Kallinen <paxed@alt.org>
Fri, 4 Dec 2020 07:30:19 +0000 (09:30 +0200)
include/extern.h
src/mhitm.c
src/mhitu.c
src/uhitm.c

index 70d8298d95481af413bf6d9ebcf7b14c40befa66..94f3d8a0dea90b9732d29ebfc3b6ec4da47efdae 100644 (file)
@@ -2788,6 +2788,7 @@ E void FDECL(mhitm_ad_halu, (struct monst *, struct attack *, struct monst *, st
 E void FDECL(mhitm_ad_phys, (struct monst *, struct attack *, struct monst *, struct mhitm_data *));
 E void FDECL(mhitm_ad_ston, (struct monst *, struct attack *, struct monst *, struct mhitm_data *));
 E void FDECL(mhitm_ad_were, (struct monst *, struct attack *, struct monst *, struct mhitm_data *));
+E void FDECL(mhitm_ad_heal, (struct monst *, struct attack *, struct monst *, struct mhitm_data *));
 E boolean FDECL(do_stone_u, (struct monst *));
 E void FDECL(do_stone_mon, (struct monst *, struct attack *, struct monst *, struct mhitm_data *));
 E int FDECL(damageum, (struct monst *, struct attack *, int));
index b743a2fe39820ad451e2eb0eaf27d8068bf2cc98..e638a97b0c06c698f68d8cc3fc7dfdc2725259e9 100644 (file)
@@ -969,6 +969,10 @@ int dieroll;
             return mhm.hitflags;
         break;
     case AD_HEAL:
+        mhitm_ad_heal(magr, mattk, mdef, &mhm);
+        if (mhm.done)
+            return mhm.hitflags;
+        break;
     case AD_PHYS:
  physical:
         mhitm_ad_phys(magr, mattk, mdef, &mhm);
index 8000454e39bf7e5579b2d838c626bc5ce4158a01..1e630dfd690f98eefb7583d6c9b9a0f03b6a89aa 100644 (file)
@@ -1229,66 +1229,9 @@ register struct attack *mattk;
             return mhm.hitflags;
         break;
     case AD_HEAL:
-        /* a cancelled nurse is just an ordinary monster,
-         * nurses don't heal those that cause petrification */
-        if (mtmp->mcan || (Upolyd && touch_petrifies(g.youmonst.data))) {
-            hitmsg(mtmp, mattk);
-            break;
-        }
-        /* weapon check should match the one in sounds.c for MS_NURSE */
-        if (!(uwep && (uwep->oclass == WEAPON_CLASS || is_weptool(uwep)))
-            && !uarmu && !uarm && !uarmc
-            && !uarms && !uarmg && !uarmf && !uarmh) {
-            boolean goaway = FALSE;
-
-            pline("%s hits!  (I hope you don't mind.)", Monnam(mtmp));
-            if (Upolyd) {
-                u.mh += rnd(7);
-                if (!rn2(7)) {
-                    /* no upper limit necessary; effect is temporary */
-                    u.mhmax++;
-                    if (!rn2(13))
-                        goaway = TRUE;
-                }
-                if (u.mh > u.mhmax)
-                    u.mh = u.mhmax;
-            } else {
-                u.uhp += rnd(7);
-                if (!rn2(7)) {
-                    /* hard upper limit via nurse care: 25 * ulevel */
-                    if (u.uhpmax < 5 * u.ulevel + d(2 * u.ulevel, 10))
-                        u.uhpmax++;
-                    if (!rn2(13))
-                        goaway = TRUE;
-                }
-                if (u.uhp > u.uhpmax)
-                    u.uhp = u.uhpmax;
-            }
-            if (!rn2(3))
-                exercise(A_STR, TRUE);
-            if (!rn2(3))
-                exercise(A_CON, TRUE);
-            if (Sick)
-                make_sick(0L, (char *) 0, FALSE, SICK_ALL);
-            g.context.botl = 1;
-            if (goaway) {
-                mongone(mtmp);
-                return 2;
-            } else if (!rn2(33)) {
-                if (!tele_restrict(mtmp))
-                    (void) rloc(mtmp, TRUE);
-                monflee(mtmp, d(3, 6), TRUE, FALSE);
-                return 3;
-            }
-            mhm.damage = 0;
-        } else {
-            if (Role_if(PM_HEALER)) {
-                if (!Deaf && !(g.moves % 5))
-                    verbalize("Doc, I can't help you unless you cooperate.");
-                mhm.damage = 0;
-            } else
-                hitmsg(mtmp, mattk);
-        }
+        mhitm_ad_heal(mtmp, mattk, &g.youmonst, &mhm);
+        if (mhm.done)
+            return mhm.hitflags;
         break;
     case AD_CURS:
         mhitm_ad_curs(mtmp, mattk, &g.youmonst, &mhm);
index d4281ac2fc9fffa7d60bfec6bda2c6633cbaac87..56e6bc2c5319f007d4b1908c62ea3654d56bfd98 100644 (file)
@@ -3656,7 +3656,7 @@ struct mhitm_data *mhm;
 
     if (magr == &g.youmonst) {
         /* uhitm */
-        mhitm_ad_phys(&g.youmonst, mattk, mdef, mhm);
+        mhitm_ad_phys(magr, mattk, mdef, mhm);
         if (mhm->done)
             return;
     } else if (mdef == &g.youmonst) {
@@ -3674,7 +3674,98 @@ struct mhitm_data *mhm;
         }
     } else {
         /* mhitm */
-        mhitm_ad_phys(&g.youmonst, mattk, mdef, mhm);
+        mhitm_ad_phys(magr, mattk, mdef, mhm);
+        if (mhm->done)
+            return;
+    }
+}
+
+void
+mhitm_ad_heal(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 */
+        mhitm_ad_phys(magr, mattk, mdef, mhm);
+        if (mhm->done)
+            return;
+    } else if (mdef == &g.youmonst) {
+        /* mhitu */
+        int armpro = magic_negation(mdef);
+        boolean uncancelled = !magr->mcan && (rn2(10) >= 3 * armpro);
+
+        /* a cancelled nurse is just an ordinary monster,
+         * nurses don't heal those that cause petrification */
+        if (magr->mcan || (Upolyd && touch_petrifies(pd))) {
+            hitmsg(magr, mattk);
+            return;
+        }
+        /* weapon check should match the one in sounds.c for MS_NURSE */
+        if (!(uwep && (uwep->oclass == WEAPON_CLASS || is_weptool(uwep)))
+            && !uarmu && !uarm && !uarmc
+            && !uarms && !uarmg && !uarmf && !uarmh) {
+            boolean goaway = FALSE;
+
+            pline("%s hits!  (I hope you don't mind.)", Monnam(magr));
+            if (Upolyd) {
+                u.mh += rnd(7);
+                if (!rn2(7)) {
+                    /* no upper limit necessary; effect is temporary */
+                    u.mhmax++;
+                    if (!rn2(13))
+                        goaway = TRUE;
+                }
+                if (u.mh > u.mhmax)
+                    u.mh = u.mhmax;
+            } else {
+                u.uhp += rnd(7);
+                if (!rn2(7)) {
+                    /* hard upper limit via nurse care: 25 * ulevel */
+                    if (u.uhpmax < 5 * u.ulevel + d(2 * u.ulevel, 10))
+                        u.uhpmax++;
+                    if (!rn2(13))
+                        goaway = TRUE;
+                }
+                if (u.uhp > u.uhpmax)
+                    u.uhp = u.uhpmax;
+            }
+            if (!rn2(3))
+                exercise(A_STR, TRUE);
+            if (!rn2(3))
+                exercise(A_CON, TRUE);
+            if (Sick)
+                make_sick(0L, (char *) 0, FALSE, SICK_ALL);
+            g.context.botl = 1;
+            if (goaway) {
+                mongone(magr);
+                mhm->done = TRUE;
+                mhm->hitflags = MM_DEF_DIED; /* return 2??? */
+                return;
+            } else if (!rn2(33)) {
+                if (!tele_restrict(magr))
+                    (void) rloc(magr, TRUE);
+                monflee(magr, d(3, 6), TRUE, FALSE);
+                mhm->done = TRUE;
+                mhm->hitflags = MM_HIT | MM_DEF_DIED; /* return 3??? */
+                return;
+            }
+            mhm->damage = 0;
+        } else {
+            if (Role_if(PM_HEALER)) {
+                if (!Deaf && !(g.moves % 5))
+                    verbalize("Doc, I can't help you unless you cooperate.");
+                mhm->damage = 0;
+            } else
+                hitmsg(magr, mattk);
+        }
+    } else {
+        /* mhitm */
+        mhitm_ad_phys(magr, mattk, mdef, mhm);
         if (mhm->done)
             return;
     }
@@ -3760,7 +3851,11 @@ int specialdmg; /* blessed and/or silver bonus against various things */
         if (mhm.done)
             return mhm.hitflags;
         break;
-    case AD_HEAL: /* likewise */
+    case AD_HEAL:
+        mhitm_ad_heal(&g.youmonst, mattk, mdef, &mhm);
+        if (mhm.done)
+            return mhm.hitflags;
+        break;
     case AD_PHYS:
  physical:
         mhitm_ad_phys(&g.youmonst, mattk, mdef, &mhm);