]> granicus.if.org Git - nethack/commitdiff
fix #K3378 - quaffing lit potion of oil
authorPatR <rankin@nethack.org>
Thu, 1 Jul 2021 00:33:18 +0000 (17:33 -0700)
committerPatR <rankin@nethack.org>
Thu, 1 Jul 2021 00:33:18 +0000 (17:33 -0700)
should cure sliming.  Implement the suggestion that quaffing a
burning potion of oil while turning into green slime will cure the
latter.

It's somewhat iffy since the slime is on the outside moving in and
the burning oil ends up on the inside, but the message sequence is
|You burn your face.
|The slime that covers you is burned away!
and it could be that igniting part of the slime quickly spreads to
the rest.

Implemented for monsters as well as for the hero.  They will light
and drink the oil in a single turn in the extremely rare situation
where they actually have a potion of oil and need to use it.

doc/fixes37.0
src/muse.c
src/potion.c

index c470dd77266aee6a8883e49147d6632934b790e3..700efcd76b3caa4cc798a111792527a4b6d96fd2 100644 (file)
@@ -1053,6 +1053,7 @@ monsters can gain resistances by eating corpses
 menu for what-is command supports /^ and /" to view a list of nearby or whole
        level visible and remembered traps
 spiders will occasionally spin webs when moving around
+drinking a burning potion of oil will cure being turned into slime
 
 
 Platform- and/or Interface-Specific New Features
index e57c2bdb1a821c3c889a670f830a30e3942d9744..2d7f0542c6ae57f7928f6ba13329644c01613239 100644 (file)
@@ -300,7 +300,8 @@ mquaffmsg(struct monst* mtmp, struct obj* otmp)
 static boolean
 m_use_healing(struct monst* mtmp)
 {
-    struct obj *obj = 0;
+    struct obj *obj;
+
     if ((obj = m_carrying(mtmp, POT_FULL_HEALING)) != 0) {
         g.m.defensive = obj;
         g.m.has_defense = MUSE_POT_FULL_HEALING;
@@ -2795,6 +2796,38 @@ muse_unslime(
                     by_you ? -EXPL_FIERY : EXPL_FIERY);
             dmg = 0; /* damage has been applied by explode() */
         }
+    } else if (otyp == POT_OIL) {
+        char Pronoun[40];
+        boolean was_lit = obj->lamplit ? TRUE : FALSE, saw_lit = FALSE;
+        /*
+         * If not already lit, requires two actions.  We cheat and let
+         * monster do both rather than render the potion unuseable.
+         *
+         * Monsters don't start with oil and don't actively pick up oil
+         * so this may never occur in a real game.  (Possible though;
+         * nymph can steal potions of oil; shapechanger could take on
+         * nymph form or vacuum up stuff as a g.cube and then eventually
+         * engage with a green slime.)
+         */
+
+        if (obj->quan > 1L)
+            obj = splitobj(obj, 1L);
+        if (vis && !was_lit) {
+            pline("%s ignites %s.", Monnam(mon), ansimpleoname(obj));
+            saw_lit = TRUE;
+        }
+        begin_burn(obj, was_lit);
+        vis |= canseemon(mon); /* burning potion may improve visibility */
+        if (vis) {
+            if (!Unaware)
+                obj->dknown = 1; /* hero is watching mon drink obj */
+            pline("%s quaffs a burning %s",
+                  saw_lit ? upstart(strcpy(Pronoun, mhe(mon))) : Monnam(mon),
+                  simpleonames(obj));
+            makeknown(POT_OIL);
+        }
+        dmg = d(3, 4); /* [**TEMP** (different from hero)] */
+        m_useup(mon, obj);
     } else { /* wand/horn of fire w/ positive charge count */
         mplayhorn(mon, obj, TRUE);
         /* -1 => monster's wand of fire; 2 => # of damage dice */
@@ -2837,12 +2870,18 @@ muse_unslime(
 
 /* decide whether obj can be used to cure green slime */
 static int
-cures_sliming(struct monst* mon, struct obj* obj)
+cures_sliming(struct monst *mon, struct obj *obj)
 {
-    /* scroll of fire, non-empty wand or horn of fire */
+    /* scroll of fire */
     if (obj->otyp == SCR_FIRE)
-        return (haseyes(mon->data) && mon->mcansee);
-    /* hero doesn't need hands or even limbs to zap, so mon doesn't either */
+        return (haseyes(mon->data) && mon->mcansee && !nohands(mon->data));
+
+    /* potion of oil; will be set burning if not already */
+    if (obj->otyp == POT_OIL)
+        return !nohands(mon->data);
+
+    /* non-empty wand or horn of fire;
+       hero doesn't need hands or even limbs to zap, so mon doesn't either */
     return ((obj->otyp == WAN_FIRE
              || (obj->otyp == FIRE_HORN && can_blow(mon)))
             && obj->spe > 0);
index e23aa96f86329e2e315c971f4000dd2a837a7dfc..d9abc90a7ae6943d3de2c82b495dcb87a8a45c1e 100644 (file)
@@ -1102,22 +1102,37 @@ peffects(struct obj *otmp)
         break;
     }
     case POT_OIL: { /* P. Winner */
-        boolean good_for_you = FALSE;
+        boolean good_for_you = FALSE, vulnerable;
 
         if (otmp->lamplit) {
             if (likes_fire(g.youmonst.data)) {
                 pline("Ahh, a refreshing drink.");
                 good_for_you = TRUE;
             } else {
+                /*
+                 * Note: if poly'd into green slime, hero ought to take
+                 * extra damage, but drinking potions in that form isn't
+                 * possible so there's no need to try to handle that.
+                 */
                 You("burn your %s.", body_part(FACE));
                 /* fire damage */
-                losehp(d(Fire_resistance ? 1 : 3, 4), "burning potion of oil",
-                       KILLED_BY_AN);
+                vulnerable = !Fire_resistance || Cold_resistance;
+                losehp(d(vulnerable ? 4 : 2, 4),
+                       "quaffing a burning potion of oil",
+                       KILLED_BY);
             }
-        } else if (otmp->cursed)
+            /*
+             * This is slightly iffy because the burning isn't being
+             * spread across the body.  But the message is "the slime
+             * that covers you burns away" and having that follow
+             * "you burn your face" seems consistent enough.
+             */
+            burn_away_slime();
+        } else if (otmp->cursed) {
             pline("This tastes like castor oil.");
-        else
+        } else {
             pline("That was smooth!");
+        }
         exercise(A_WIS, good_for_you);
         break;
     }