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:
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
14
src/potion.c
14
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);
|
||||
}
|
||||
|
||||
21
src/shk.c
21
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;
|
||||
|
||||
Reference in New Issue
Block a user