From: PatR Date: Thu, 1 Jul 2021 00:33:18 +0000 (-0700) Subject: fix #K3378 - quaffing lit potion of oil X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4c7734ebbd22b09139490c6af2b55178b7bb036c;p=nethack fix #K3378 - quaffing lit potion of oil 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. --- diff --git a/doc/fixes37.0 b/doc/fixes37.0 index c470dd772..700efcd76 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -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 diff --git a/src/muse.c b/src/muse.c index e57c2bdb1..2d7f0542c 100644 --- a/src/muse.c +++ b/src/muse.c @@ -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); diff --git a/src/potion.c b/src/potion.c index e23aa96f8..d9abc90a7 100644 --- a/src/potion.c +++ b/src/potion.c @@ -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; }