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
This commit is contained in:
PatR
2024-01-03 13:29:15 -08:00
parent db4a44735e
commit c6897bf331
5 changed files with 51 additions and 6 deletions

View File

@@ -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

View File

@@ -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;

View File

@@ -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);

View File

@@ -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:

View File

@@ -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: