Fix: billing shop boulder pushed thru shared wall
I realized that the "move the boulder billing to 'used-up items'" part
of 20392a6 didn't properly handle boulder movement from one shop to
another via a gap in a shared wall, becuase it wasn't looking at the
complete in_rooms() array (plus, it only triggered if the new spot
wasn't in any shops at all). When I tried to fix that, I realized that
stolen_value() was similarly not working reliably when passed a location
shared between two shops, and for the same reason: it was only using the
first character of the in_rooms() array.
I think this patch fixes both those things, but it would be worth
examining the change to stolen_value() carefully, to ensure getting the
roomno via the shkp won't change anything about its normal functioning.
I'm not totally sure about that -- I didn't notice any problems in some
brief tests of typical stolen_value() uses, but it seems like it
probably has some tricky edge cases.
At the very least, passing a boulder fully through a shared wall between
two shops one way, then back the other way, no longer triggers an unpaid
obj sanity check in my testing.
This commit is contained in:
+4
-2
@@ -462,8 +462,10 @@ moverock(void)
|
|||||||
!= 0)
|
!= 0)
|
||||||
&& onshopbill(otmp, shkp, TRUE)) {
|
&& onshopbill(otmp, shkp, TRUE)) {
|
||||||
subfrombill(otmp, shkp);
|
subfrombill(otmp, shkp);
|
||||||
} else if (otmp->unpaid && !*in_rooms(rx, ry, SHOPBASE)
|
} else if (otmp->unpaid
|
||||||
&& *in_rooms(sx, sy, SHOPBASE)) {
|
&& (shkp = find_objowner(otmp, sx, sy)) != 0
|
||||||
|
&& !strchr(in_rooms(rx, ry, SHOPBASE),
|
||||||
|
ESHK(shkp)->shoproom)) {
|
||||||
/* once the boulder is fully out of the shop, so that it's
|
/* once the boulder is fully out of the shop, so that it's
|
||||||
* impossible to change your mind and push it back in without
|
* impossible to change your mind and push it back in without
|
||||||
* leaving and triggering Kops, switch it to stolen_value */
|
* leaving and triggering Kops, switch it to stolen_value */
|
||||||
|
|||||||
@@ -3036,12 +3036,18 @@ stolen_value(
|
|||||||
boolean silent)
|
boolean silent)
|
||||||
{
|
{
|
||||||
long value = 0L, gvalue = 0L, billamt = 0L;
|
long value = 0L, gvalue = 0L, billamt = 0L;
|
||||||
char roomno = *in_rooms(x, y, SHOPBASE);
|
char roomno;
|
||||||
struct bill_x *bp;
|
struct bill_x *bp;
|
||||||
struct monst *shkp = 0;
|
struct monst *shkp;
|
||||||
boolean was_unpaid;
|
boolean was_unpaid;
|
||||||
long c_count = 0L, u_count = 0L;
|
long c_count = 0L, u_count = 0L;
|
||||||
|
|
||||||
|
if ((shkp = find_objowner(obj, x, y)) != (struct monst *) 0) {
|
||||||
|
roomno = ESHK(shkp)->shoproom;
|
||||||
|
} else {
|
||||||
|
roomno = *in_rooms(x, y, SHOPBASE);
|
||||||
|
}
|
||||||
|
|
||||||
/* gather information for message(s) prior to manipulating bill */
|
/* gather information for message(s) prior to manipulating bill */
|
||||||
was_unpaid = obj->unpaid ? TRUE : FALSE;
|
was_unpaid = obj->unpaid ? TRUE : FALSE;
|
||||||
if (Has_contents(obj)) {
|
if (Has_contents(obj)) {
|
||||||
@@ -3049,6 +3055,7 @@ stolen_value(
|
|||||||
u_count = count_contents(obj, TRUE, FALSE, FALSE, FALSE);
|
u_count = count_contents(obj, TRUE, FALSE, FALSE, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shkp = (struct monst *) 0;
|
||||||
if (!billable(&shkp, obj, roomno, TRUE)) {
|
if (!billable(&shkp, obj, roomno, TRUE)) {
|
||||||
/* things already on the bill yield a not-billable result, so
|
/* things already on the bill yield a not-billable result, so
|
||||||
we need to check bill before deciding that shk doesn't care */
|
we need to check bill before deciding that shk doesn't care */
|
||||||
|
|||||||
Reference in New Issue
Block a user