From: nethack.rankin Date: Thu, 22 Jun 2006 04:08:40 +0000 (+0000) Subject: shop theft/breakage (trunk only) X-Git-Tag: MOVE2GIT~977 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=dc63ed8a8079eeab082022790b76bfbc76f62596;p=nethack shop theft/breakage (trunk only) The recent fix for "breaking glass wand in tool shop" looked suspect, adding a call to costly_alteration after an existing call to stolen_value. Either one or the other ought to suffice. (For items on the floor, costly_alteration() calls stolen_value(); for items in inventory, or just released from inventory and not placed on floor yet, costly_alteration() adds a usage fee to the shop bill but doesn't annoy the shopkeeper into adding surcharges to prices or summoning the kops if already hostile.) In 3.4.3, stolen_value() wasn't smart enough to charge for an out-of- shk's-field item (like a wand in a tool shop) taken from a shop container, and that's the problem the user was reporting. But the post-3.4.3 code was changed to handle that by checking billable() instead of saleable(); this bug should have been gone. Unfortunately, billable() treats items already on the bill as not interesting--from the perspective of adding things to the bill--so the change accidentally resulted in stolen_value() no longer handling objects which are marked unpaid, triggering the same symptom for a different reason. (Other events besides the breakage of thrown objects suffered from the bug's new incarnation since various places deliberately call stolen_value() for unpaid objects.) This updates stolen_value() and stolen_container() to account for the behavior of billable(). And a few calls to subfrombill() go away since stolen_value() now takes care of that. --- diff --git a/src/dokick.c b/src/dokick.c index ba110ecb0..e9f7d2949 100644 --- a/src/dokick.c +++ b/src/dokick.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)dokick.c 3.5 2005/12/02 */ +/* SCCS Id: @(#)dokick.c 3.5 2006/06/21 */ /* Copyright (c) Izchak Miller, Mike Stephenson, Steve Linhart, 1989. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1337,7 +1337,6 @@ boolean shop_floor_obj; if(unpaid || shop_floor_obj) { if(unpaid) { - subfrombill(otmp, shop_keeper(*u.ushops)); (void)stolen_value(otmp, u.ux, u.uy, TRUE, FALSE); } else { ox = otmp->ox; diff --git a/src/dothrow.c b/src/dothrow.c index fae5d3404..ccb89e0e6 100644 --- a/src/dothrow.c +++ b/src/dothrow.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)dothrow.c 3.5 2006/04/14 */ +/* SCCS Id: @(#)dothrow.c 3.5 2006/06/21 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -700,31 +700,24 @@ register boolean broken; if(!shkp) return; if(broken) { - if (obj->unpaid) { + if (obj->unpaid) (void)stolen_value(obj, u.ux, u.uy, (boolean)shkp->mpeaceful, FALSE); - costly_alteration(obj, COST_DSTROY); - /* costly_alteration() probably already called - subfrombill() for the object, but just in case it - didn't, call it again. If it did, this is a NOOP. */ - subfrombill(obj, shkp); - } obj->no_charge = 1; return; } if (!costly_spot(x, y) || *in_rooms(x, y, SHOPBASE) != *u.ushops) { /* thrown out of a shop or into a different shop */ - if (obj->unpaid) { + if (obj->unpaid) (void)stolen_value(obj, u.ux, u.uy, (boolean)shkp->mpeaceful, FALSE); - subfrombill(obj, shkp); - } } else { if (costly_spot(u.ux, u.uy) && costly_spot(x, y)) { - if(obj->unpaid) subfrombill(obj, shkp); - else if(!(x == shkp->mx && y == shkp->my)) - sellobj(obj, x, y); + if (obj->unpaid) + subfrombill(obj, shkp); + else if (x != shkp->mx || y != shkp->my) + sellobj(obj, x, y); } } } diff --git a/src/potion.c b/src/potion.c index 8fb596bec..4f3c55281 100644 --- a/src/potion.c +++ b/src/potion.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)potion.c 3.5 2005/12/05 */ +/* SCCS Id: @(#)potion.c 3.5 2006/06/21 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1317,16 +1317,14 @@ boolean your_fault; !objects[obj->otyp].oc_uname && cansee(mon->mx,mon->my)) docall(obj); if(*u.ushops && obj->unpaid) { - register struct monst *shkp = - shop_keeper(*in_rooms(u.ux, u.uy, SHOPBASE)); + struct monst *shkp = + shop_keeper(*in_rooms(u.ux, u.uy, SHOPBASE)); - if(!shkp) - obj->unpaid = 0; - else { + if (shkp) (void)stolen_value(obj, u.ux, u.uy, (boolean)shkp->mpeaceful, FALSE); - subfrombill(obj, shkp); - } + else + obj->unpaid = 0; } obfree(obj, (struct obj *)0); } diff --git a/src/shk.c b/src/shk.c index e32c8848d..ca48c33a2 100644 --- a/src/shk.c +++ b/src/shk.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)shk.c 3.5 2006/06/17 */ +/* SCCS Id: @(#)shk.c 3.5 2006/06/21 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2438,7 +2438,15 @@ boolean ininv; /* the price of contained objects, if any */ for(otmp = obj->cobj; otmp; otmp = otmp->nobj) { if (otmp->oclass == COIN_CLASS) continue; - if (!billable(&shkp, otmp, ESHK(shkp)->shoproom, TRUE)) continue; + if (!billable(&shkp, otmp, ESHK(shkp)->shoproom, TRUE)) { + /* billable() returns false for objects already on bill */ + if (!onbill(obj, shkp, FALSE)) continue; + /* this assumes that we're being called by stolen_value() + (or by a recursive call to self on behalf of it) where + the cost of this object is about to be added to shop + debt in place of having it remain on the current bill */ + subfrombill(obj, shkp); /* avoid doubling billing */ + } if (!Has_contents(otmp)) { if (otmp->unpaid || !ininv) @@ -2460,8 +2468,13 @@ boolean peaceful, silent; char roomno = *in_rooms(x, y, SHOPBASE); struct monst *shkp = 0; - if (!billable(&shkp, obj, roomno, FALSE)) - return 0L; + if (!billable(&shkp, obj, roomno, FALSE)) { + /* things already on the bill yield a not-billable result, so + we need to check bill before deciding that shk doesn't care */ + if (!onbill(obj, shkp, FALSE)) return 0L; + /* shk does care; take obj off bill to avoid double billing */ + subfrombill(obj, shkp); + } if(obj->oclass == COIN_CLASS) { gvalue += obj->quan;