eating 1 of N floor tins in shop

Reported directly to devteam, eating 1 of 2 tins of spinach from a
shop's floor forced the hero to buy both.  (1 was gone, the other was
intact and now owned by the hero rather than the shop.  Tins of other
contents behaved similarly.)  The bug is easy to fix but not so easy
to explain:  eating split one from the stack but passed the remaining
stack to useupf(obj,1) which also split one off and treated that as
used up.  The second one was billed as used up and the first one was
added to the bill--as being subjected to a costly modification made by
the hero--and kept intact, now marked no-charge with hero obligated to
pay for it.

Eating 1 of N tins, for N greater than 2, billed for two, one gone and
the other now in a separate stack and marked no-charge.  The remaining
N-2 stayed as normal shop goods in their original stack.

The fix is communicate the splitobj() for costly modification up-call
so that the use_up_tin code operates on the one which was split off
the stack rather than on the remainder of the original stack.
This commit is contained in:
PatR
2017-06-29 16:14:27 -07:00
parent 27c24536af
commit f9af42a2b7
2 changed files with 12 additions and 11 deletions

View File

@@ -404,6 +404,7 @@ fix the 'A' command to have the 'D' command's fix for C331-1 (quirk for
menustyle:Combination; if user included 'a' in "which object classes?"
response, to operate on applicable all items, there would still be a
followup menu asking to choose specific items)
eating 1 tin from stack of N (for N >= 2) on shop's floor forced hero to buy 2
Fixes to Post-3.6.0 Problems that Were Exposed Via git Repository

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 eat.c $NHDT-Date: 1470272344 2016/08/04 00:59:04 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.172 $ */
/* NetHack 3.6 eat.c $NHDT-Date: 1498778062 2017/06/29 23:14:22 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.178 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -6,7 +6,7 @@
STATIC_PTR int NDECL(eatmdone);
STATIC_PTR int NDECL(eatfood);
STATIC_PTR void FDECL(costly_tin, (int));
STATIC_PTR struct obj *FDECL(costly_tin, (int));
STATIC_PTR int NDECL(opentin);
STATIC_PTR int NDECL(unfaint);
@@ -1152,7 +1152,7 @@ violated_vegetarian()
/* common code to check and possibly charge for 1 context.tin.tin,
* will split() context.tin.tin if necessary */
STATIC_PTR void
STATIC_PTR struct obj *
costly_tin(alter_type)
int alter_type; /* COST_xxx */
{
@@ -1166,6 +1166,7 @@ int alter_type; /* COST_xxx */
}
costly_alteration(tin, alter_type);
}
return tin;
}
int
@@ -1293,7 +1294,7 @@ const char *mesg;
r = tin_variety(tin, FALSE);
if (tin->otrapped || (tin->cursed && r != HOMEMADE_TIN && !rn2(8))) {
b_trapped("tin", 0);
costly_tin(COST_DSTROY);
tin = costly_tin(COST_DSTROY);
goto use_up_tin;
}
@@ -1304,7 +1305,7 @@ const char *mesg;
if (mnum == NON_PM) {
pline("It turns out to be empty.");
tin->dknown = tin->known = 1;
costly_tin(COST_OPEN);
tin = costly_tin(COST_OPEN);
goto use_up_tin;
}
@@ -1333,7 +1334,7 @@ const char *mesg;
You("discard the open tin.");
if (!Hallucination)
tin->dknown = tin->known = 1;
costly_tin(COST_OPEN);
tin = costly_tin(COST_OPEN);
goto use_up_tin;
}
@@ -1352,7 +1353,7 @@ const char *mesg;
cpostfx(mnum);
/* charge for one at pre-eating cost */
costly_tin(COST_OPEN);
tin = costly_tin(COST_OPEN);
if (tintxts[r].nut < 0) /* rotten */
make_vomiting((long) rn1(15, 10), FALSE);
@@ -1378,7 +1379,7 @@ const char *mesg;
if (yn("Eat it?") == 'n') {
if (flags.verbose)
You("discard the open tin.");
costly_tin(COST_OPEN);
tin = costly_tin(COST_OPEN);
goto use_up_tin;
}
@@ -1386,14 +1387,13 @@ const char *mesg;
* Same order as with non-spinach above:
* conduct update, side-effects, shop handling, and nutrition.
*/
u.uconduct
.food++; /* don't need vegan/vegetarian checks for spinach */
u.uconduct.food++; /* don't need vegetarian checks for spinach */
if (!tin->cursed)
pline("This makes you feel like %s!",
Hallucination ? "Swee'pea" : "Popeye");
gainstr(tin, 0, FALSE);
costly_tin(COST_OPEN);
tin = costly_tin(COST_OPEN);
lesshungry(tin->blessed
? 600 /* blessed */