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.
This commit is contained in:
nethack.rankin
2006-06-22 04:08:40 +00:00
parent ed202000f1
commit dc63ed8a80
4 changed files with 31 additions and 28 deletions

View File

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

View File

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

View File

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

View File

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