From c6897bf33181b38a1528c796aa5122ef96cd318a Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 3 Jan 2024 13:29:15 -0800 Subject: [PATCH] fix github issue #1191 - obj->age of oil potions Issue reported by AmyBSOD: several actions change the object type of a potion rather than force creation of a replacement one, and if/when the type was changed to oil, the age wasn't converted from absolute to relative. Relative age is the amount available and/or the number of turns it will burn if applied. The later in a game a potion got converted into oil, the longer it would burn. Not mentioned: reverse situation was also the case, although that didn't have any noticeable effect since incorrect absolute age of former oil doesn't matter. Not thoroughly tested. I got a potion of oil from a horn of plenty and it burned for 400 turns, but it might have been created directly rather than be a rejected magic potion that was converted into oil. Closes #1191 --- doc/fixes3-7-0.txt | 8 +++++++- include/extern.h | 3 ++- src/mkobj.c | 36 ++++++++++++++++++++++++++++++++++-- src/potion.c | 5 ++++- src/zap.c | 5 ++++- 5 files changed, 51 insertions(+), 6 deletions(-) diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index 2b54f748f..d2423a075 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -1,4 +1,4 @@ -$NHDT-Branch: (unknown) $:$NHDT-Revision: 1.1339 $ $NHDT-Date: 1702264272 2023/12/11 03:11:12 $ +$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1353 $ $NHDT-Date: 1704316439 2024/01/03 21:13:59 $ General Fixes and Modified Features ----------------------------------- @@ -1340,6 +1340,12 @@ wishing for a "lit candle" provided one, but the feedback as it was added into don't fall off steed because of Fumbling if saddle is cursed cursed welded quarterstaff doesn't prevent spellcasting wielded quarterstaff gives a small spellcasting bonus +if polymorphing a potion turned it into oil, dipping potions produced oil + randomly, or a horn of plenty produced a magic potion and converted + it into oil, the resulting potion of oil had its age (amount left) + set of the original potion's age (turn it was created) and could burn + for an arbitrarily long time if applied; conversely, polymophing oil + into non-oil kept its relative age (no noticeable effect though) Fixes to 3.7.0-x General Problems Exposed Via git Repository diff --git a/include/extern.h b/include/extern.h index 0c40114c0..2ff78fe73 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 extern.h $NHDT-Date: 1703716146 2023/12/27 22:29:06 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1356 $ */ +/* NetHack 3.7 extern.h $NHDT-Date: 1704316439 2024/01/03 21:13:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1359 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1595,6 +1595,7 @@ extern struct obj *mksobj(int, boolean, boolean) NONNULL; extern int bcsign(struct obj *) NONNULLARG1; extern int weight(struct obj *) NONNULLARG1; extern struct obj *mkgold(long, coordxy, coordxy); +extern void fixup_oil(struct obj *, struct obj *) NONNULLARG1; extern struct obj *mkcorpstat(int, struct monst *, struct permonst *, coordxy, coordxy, unsigned); extern int corpse_revive_type(struct obj *) NONNULLARG1; diff --git a/src/mkobj.c b/src/mkobj.c index 7970ca92c..9361fa304 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mkobj.c $NHDT-Date: 1689180492 2023/07/12 16:48:12 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.272 $ */ +/* NetHack 3.7 mkobj.c $NHDT-Date: 1704316444 2024/01/03 21:14:04 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.282 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1935,6 +1935,34 @@ mkgold(long amount, coordxy x, coordxy y) return gold; } +/* potions of oil use their obj->age field differently from other potions + so changing potion type to or from oil needs to have that fixed up */ +void +fixup_oil( + struct obj *potion, /* potion that just had its otyp changed */ + struct obj *source) /* item used to create potion; might be Null */ +{ + if (potion->otyp == POT_OIL) { + if (source && source->otyp == POT_OIL) { + /* potion of oil being used to set potion's otyp to oil; + source might be partly used */ + potion->age = source->age; + } else { + /* non-oil is being turned into oil; change absolute age + (turn created) into relative age (amount remaining / + burn time available) */ + potion->age = MAX_OIL_IN_FLASK; + } + } else if (source && source->otyp == POT_OIL) { + /* potion is no longer oil, being turned into non-oil */ + if (potion->age == source->age) + potion->age = gm.moves; + /* when source is a partly used oil, mark potion as diluted */ + if (source->age < MAX_OIL_IN_FLASK) + potion->odiluted = 1; + } +} + /* return TRUE if the corpse has special timing; lizards and lichen don't rot, trolls and Riders auto-revive */ #define special_corpse(num) \ @@ -2700,10 +2728,14 @@ hornoplenty( consume_obj_charge(horn, !tipping); if (!rn2(13)) { obj = mkobj(POTION_CLASS, FALSE); - if (objects[obj->otyp].oc_magic) + if (objects[obj->otyp].oc_magic) { do { obj->otyp = rnd_class(POT_BOOZE, POT_WATER); } while (obj->otyp == POT_SICKNESS); + /* oil uses obj->age field differently from other potions */ + if (obj->otyp == POT_OIL) + fixup_oil(obj, (struct obj *) NULL); + } what = (obj->quan > 1L) ? "Some potions" : "A potion"; } else { obj = mkobj(FOOD_CLASS, FALSE); diff --git a/src/potion.c b/src/potion.c index 93eed9dfe..d99474f5b 100644 --- a/src/potion.c +++ b/src/potion.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 potion.c $NHDT-Date: 1699582924 2023/11/10 02:22:04 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.251 $ */ +/* NetHack 3.7 potion.c $NHDT-Date: 1704316448 2024/01/03 21:14:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.256 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2504,6 +2504,9 @@ potion_dip(struct obj *obj, struct obj *potion) case 4: otmp = mkobj(POTION_CLASS, FALSE); obj->otyp = otmp->otyp; + /* oil uses obj->age field differently from other potions */ + if (obj->otyp == POT_OIL || otmp->otyp == POT_OIL) + fixup_oil(obj, otmp); obfree(otmp, (struct obj *) 0); break; default: diff --git a/src/zap.c b/src/zap.c index f04c4a2e4..64583a138 100644 --- a/src/zap.c +++ b/src/zap.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 zap.c $NHDT-Date: 1703070194 2023/12/20 11:03:14 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.501 $ */ +/* NetHack 3.7 zap.c $NHDT-Date: 1704316449 2024/01/03 21:14:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.508 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1780,6 +1780,9 @@ poly_obj(struct obj *obj, int id) case POTION_CLASS: while (otmp->otyp == POT_POLYMORPH) otmp->otyp = rnd_class(POT_GAIN_ABILITY, POT_WATER); + /* potions of oil use obj->age field differently from other potions */ + if (otmp->otyp == POT_OIL || obj->otyp == POT_OIL) + fixup_oil(otmp, obj); break; case SPBOOK_CLASS: