]> granicus.if.org Git - nethack/commitdiff
Give gremlin the property it stole, if possible
authorPasi Kallinen <paxed@alt.org>
Wed, 25 Jan 2023 19:52:05 +0000 (21:52 +0200)
committerPasi Kallinen <paxed@alt.org>
Wed, 25 Jan 2023 19:55:11 +0000 (21:55 +0200)
doc/fixes3-7-0.txt
include/extern.h
src/eat.c
src/mon.c
src/sit.c
src/uhitm.c

index 5c03167fc2cca508fa2cbbf80598a3c1b75b8322..167e34fbc37ca1a0dfe24bad07b406425197ef30 100644 (file)
@@ -1099,6 +1099,7 @@ if a grave is created with the corpse lying on top (bones), don't find a
 kicking a headstone might summon a ghoul
 eating garlic makes nearby monsters flee
 giants occasionally get a battle axe or a two-handed sword
+give gremlin the property it stole, if possible
 
 
 Fixes to 3.7.0-x Problems that Were Exposed Via git Repository
index 240db51906bf624d6560a8e7bce0a44f71cadbec..bfa8e36171951a16da0b49f8f6465d9748b9c98b 100644 (file)
@@ -1548,6 +1548,7 @@ extern void m_consume_obj(struct monst *, struct obj *);
 extern int meatmetal(struct monst *);
 extern int meatobj(struct monst *);
 extern int meatcorpse(struct monst *);
+extern void mon_give_prop(struct monst *, int);
 extern void mon_givit(struct monst *, struct permonst *);
 extern void mpickgold(struct monst *);
 extern boolean mpickstuff(struct monst *, const char *);
@@ -2581,7 +2582,7 @@ extern boolean is_izchak(struct monst *, boolean);
 extern void take_gold(void);
 extern int dosit(void);
 extern void rndcurse(void);
-extern void attrcurse(void);
+extern int attrcurse(void);
 
 /* ### sounds.c ### */
 
index e58b930026da3479cfd581f93a9fd56f131ef52c..6b4086cfbb3faaa96375a4759c74fd055a82e556 100644 (file)
--- a/src/eat.c
+++ b/src/eat.c
@@ -1220,7 +1220,7 @@ cpostfx(int pm)
         /* picks an intrinsic at random and removes it; there's
            no feedback if hero already lacks the chosen ability */
         debugpline0("using attrcurse to strip an intrinsic");
-        attrcurse();
+        (void) attrcurse();
         break;
     case PM_DEATH:
     case PM_PESTILENCE:
index 92523333f30dc213c1e0fefa5e5c57859c92dc54..a7f45c4f6fc7cea0b421cc141dcc7e3d1b431de1 100644 (file)
--- a/src/mon.c
+++ b/src/mon.c
@@ -1453,54 +1453,13 @@ meatcorpse(
     return 0;
 }
 
-DISABLE_WARNING_FORMAT_NONLITERAL
-
-/* Maybe give an intrinsic to monster from eating corpse that confers it. */
+/* give monster property prop */
 void
-mon_givit(struct monst *mtmp, struct permonst *ptr)
+mon_give_prop(struct monst *mtmp, int prop)
 {
-    int prop = corpse_intrinsic(ptr);
-    boolean vis = canseemon(mtmp);
     const char *msg = NULL;
     unsigned short intrinsic = 0; /* MR_* constant */
 
-    if (ptr == &mons[PM_STALKER]) {
-        /*
-         * Invisible stalker isn't flagged as conferring invisibility
-         * so prop is 0.  For hero, eating a stalker corpse confers
-         * temporary invisibility if hero is visible.  When already
-         * invisible, if confers permanent invisibilty and also
-         * permanent see invisible.  For monsters, only permanent
-         * invisibility is possible; temporary invisibility and see
-         * invisible aren't implemented for them.
-         *
-         * A monster being invisible gains no benefit against other
-         * monsters, and an invisible pet when hero can't see invisible
-         * is a nuisance at best, so this is probably detrimental.
-         * Players will just have to live with it if they want to be
-         * able to have pets gain intrinsics from eating corpses.
-         */
-        if (!mtmp->perminvis || mtmp->invis_blkd) {
-            char mtmpbuf[BUFSZ];
-
-            Strcpy(mtmpbuf, Monnam(mtmp));
-            mon_set_minvis(mtmp);
-            if (vis)
-                pline("%s %s.", mtmpbuf,
-                      !canspotmon(mtmp) ? "vanishes"
-                      : mtmp->invis_blkd ? "seems to flicker"
-                        : "becomes invisible");
-        }
-        mtmp->mstun = 1; /* no timeout but will eventually wear off */
-        return;
-    }
-
-    if (prop == 0)
-        return; /* no intrinsic from this corpse */
-
-    if (!should_givit(prop, ptr))
-        return; /* failed die roll */
-
     /* Pets don't have all the fields that the hero does, so they can't get all
        the same intrinsics. If it happens to choose strength gain or teleport
        control or whatever, ignore it. */
@@ -1530,6 +1489,7 @@ mon_givit(struct monst *mtmp, struct permonst *ptr)
         msg = "%s looks healthy.";
         break;
     default:
+        return; /* can't give it */
         break;
     }
 
@@ -1543,11 +1503,59 @@ mon_givit(struct monst *mtmp, struct permonst *ptr)
     if (intrinsic)
         mtmp->mintrinsics |= intrinsic;
 
-    if (vis && msg)
+    if (canseemon(mtmp) && msg) {
+        DISABLE_WARNING_FORMAT_NONLITERAL
         pline(msg, Monnam(mtmp));
+        RESTORE_WARNING_FORMAT_NONLITERAL
+    }
 }
 
-RESTORE_WARNING_FORMAT_NONLITERAL
+/* Maybe give an intrinsic to monster from eating corpse that confers it. */
+void
+mon_givit(struct monst *mtmp, struct permonst *ptr)
+{
+    int prop = corpse_intrinsic(ptr);
+    boolean vis = canseemon(mtmp);
+
+    if (ptr == &mons[PM_STALKER]) {
+        /*
+         * Invisible stalker isn't flagged as conferring invisibility
+         * so prop is 0.  For hero, eating a stalker corpse confers
+         * temporary invisibility if hero is visible.  When already
+         * invisible, if confers permanent invisibilty and also
+         * permanent see invisible.  For monsters, only permanent
+         * invisibility is possible; temporary invisibility and see
+         * invisible aren't implemented for them.
+         *
+         * A monster being invisible gains no benefit against other
+         * monsters, and an invisible pet when hero can't see invisible
+         * is a nuisance at best, so this is probably detrimental.
+         * Players will just have to live with it if they want to be
+         * able to have pets gain intrinsics from eating corpses.
+         */
+        if (!mtmp->perminvis || mtmp->invis_blkd) {
+            char mtmpbuf[BUFSZ];
+
+            Strcpy(mtmpbuf, Monnam(mtmp));
+            mon_set_minvis(mtmp);
+            if (vis)
+                pline("%s %s.", mtmpbuf,
+                      !canspotmon(mtmp) ? "vanishes"
+                      : mtmp->invis_blkd ? "seems to flicker"
+                        : "becomes invisible");
+        }
+        mtmp->mstun = 1; /* no timeout but will eventually wear off */
+        return;
+    }
+
+    if (prop == 0)
+        return; /* no intrinsic from this corpse */
+
+    if (!should_givit(prop, ptr))
+        return; /* failed die roll */
+
+    mon_give_prop(mtmp, prop);
+}
 
 void
 mpickgold(register struct monst* mtmp)
index f835014d33422a3b9ab5c71e2ee6b4b11777abda..876f03444ce60a95fbe1c9bb47030ee14c563c32 100644 (file)
--- a/src/sit.c
+++ b/src/sit.c
@@ -447,15 +447,20 @@ rndcurse(void)
     }
 }
 
-/* remove a random INTRINSIC ability */
-void
+/* remove a random INTRINSIC ability from hero.
+   returns the intrinsic property which was removed,
+   or 0 if nothing was removed. */
+int
 attrcurse(void)
 {
+    int ret = 0;
+
     switch (rnd(11)) {
     case 1:
         if (HFire_resistance & INTRINSIC) {
             HFire_resistance &= ~INTRINSIC;
             You_feel("warmer.");
+            ret = FIRE_RES;
             break;
         }
         /*FALLTHRU*/
@@ -463,6 +468,7 @@ attrcurse(void)
         if (HTeleportation & INTRINSIC) {
             HTeleportation &= ~INTRINSIC;
             You_feel("less jumpy.");
+            ret = TELEPORT;
             break;
         }
         /*FALLTHRU*/
@@ -470,6 +476,7 @@ attrcurse(void)
         if (HPoison_resistance & INTRINSIC) {
             HPoison_resistance &= ~INTRINSIC;
             You_feel("a little sick!");
+            ret = POISON_RES;
             break;
         }
         /*FALLTHRU*/
@@ -479,6 +486,7 @@ attrcurse(void)
             if (Blind && !Blind_telepat)
                 see_monsters(); /* Can't sense mons anymore! */
             Your("senses fail!");
+            ret = TELEPAT;
             break;
         }
         /*FALLTHRU*/
@@ -486,6 +494,7 @@ attrcurse(void)
         if (HCold_resistance & INTRINSIC) {
             HCold_resistance &= ~INTRINSIC;
             You_feel("cooler.");
+            ret = COLD_RES;
             break;
         }
         /*FALLTHRU*/
@@ -493,6 +502,7 @@ attrcurse(void)
         if (HInvis & INTRINSIC) {
             HInvis &= ~INTRINSIC;
             You_feel("paranoid.");
+            ret = INVIS;
             break;
         }
         /*FALLTHRU*/
@@ -507,6 +517,7 @@ attrcurse(void)
             }
             You("%s!", Hallucination ? "tawt you taw a puttie tat"
                                      : "thought you saw something");
+            ret = SEE_INVIS;
             break;
         }
         /*FALLTHRU*/
@@ -514,6 +525,7 @@ attrcurse(void)
         if (HFast & INTRINSIC) {
             HFast &= ~INTRINSIC;
             You_feel("slower.");
+            ret = FAST;
             break;
         }
         /*FALLTHRU*/
@@ -521,6 +533,7 @@ attrcurse(void)
         if (HStealth & INTRINSIC) {
             HStealth &= ~INTRINSIC;
             You_feel("clumsy.");
+            ret = STEALTH;
             break;
         }
         /*FALLTHRU*/
@@ -529,6 +542,7 @@ attrcurse(void)
         if (HProtection & INTRINSIC) {
             HProtection &= ~INTRINSIC;
             You_feel("vulnerable.");
+            ret = PROTECTION;
             break;
         }
         /*FALLTHRU*/
@@ -536,12 +550,14 @@ attrcurse(void)
         if (HAggravate_monster & INTRINSIC) {
             HAggravate_monster &= ~INTRINSIC;
             You_feel("less attractive.");
+            ret = AGGRAVATE_MONSTER;
             break;
         }
         /*FALLTHRU*/
     default:
         break;
     }
+    return ret;
 }
 
 /*sit.c*/
index 02a44bfbfd0b79b632f2791d561f8db1ef7a631a..7f09598b58602e55805799c7e23d0147ba31b336 100644 (file)
@@ -2773,7 +2773,7 @@ mhitm_ad_curs(struct monst *magr, struct attack *mattk, struct monst *mdef,
                 rehumanize();
                 return;
             }
-            attrcurse();
+            mon_give_prop(magr, attrcurse());
         }
     } else {
         /* mhitm */