bill_dummy_object

Various actions (potion dilution, igniting candles or oil, dulling a
weapon by engraving) on an unpaid object can modify it in such a way that
a shopkeeper will force the hero to buy it.  bill_dummy_object() is used
to make a copy for the shop bill; play continues with the modified item
now owned by the player.  bill_dummy_object() was setting the no_charge
flag unconditionally on the modified object but the flag shouldn't be set
for items in inventory.  It was possible to drop the object and sell it,
pick it back up for free due to that flag setting, then drop it and sell
it again.  One easy way to reproduce is to zap yourself with a wand of
cancellation while carrying unpaid positively enchanted armor or weapon.

     The no_charge flag gets cleared when you pick something up off the
floor or take it out of a container, so this sell-it-again case would only
repeat once.  Selling a dropped item ought to clear the flag, but my head
is still spinning after looking at the shop code to see about implementing
that.  This fix just prevents bill_dummy_object() from mis-setting the
flag in the first place; sellobj() still can't fix it up after the fact.
This commit is contained in:
nethack.rankin
2005-03-27 04:54:20 +00:00
parent 51f4a6b174
commit 085af405d6
2 changed files with 5 additions and 2 deletions

View File

@@ -106,6 +106,7 @@ fix various places that "finally finished" could be displayed after the hero
stopped doing something other than eating
fix some cases where movement was disallowed but the hero was still conscious
after destroying drawbridge, hero could appear to be in the wall
sometimes shop items which hero is forced to buy could be sold back twice
Platform- and/or Interface-Specific Fixes

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)mkobj.c 3.5 2002/10/07 */
/* SCCS Id: @(#)mkobj.c 3.5 2005/03/26 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -342,7 +342,9 @@ register struct obj *otmp;
(void)strncpy(ONAME(dummy), ONAME(otmp), (int)otmp->onamelth);
if (Is_candle(dummy)) dummy->lamplit = 0;
addtobill(dummy, FALSE, TRUE, TRUE);
otmp->no_charge = 1;
/* no_charge is only valid for some locations */
otmp->no_charge = (otmp->where == OBJ_FLOOR ||
otmp->where == OBJ_CONTAINED) ? 1 : 0;
otmp->unpaid = 0;
return;
}