throwing recoil inside shop

Another bug from seven years ago, sent directly to devteam so no #H
number.  Report stated that throwing recoil could move a levitating
hero diagonally through a shop's doorway to exit it.  If the thrown
item was unpaid, it remained unpaid after landing on shop's floor
and was an unlisted item on shop's bill.  Moving diagonally out the
door seems to have been fixed, but the same effect still occurred
if you were far enough from the door to have the shopkeeper vacate
his door-blocking spot and throwing recoil took hero to that spot.
The thrown unpaid item remained unpaid, and walking out the door was
treated as shop robbery.
This commit is contained in:
PatR
2018-12-17 03:05:10 -08:00
parent f9cef53758
commit 942961e3e2
2 changed files with 15 additions and 5 deletions

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 dothrow.c $NHDT-Date: 1544401268 2018/12/10 00:21:08 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.153 $ */
/* NetHack 3.6 dothrow.c $NHDT-Date: 1545044705 2018/12/17 11:05:05 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.154 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2013. */
/* NetHack may be freely redistributed. See license for details. */
@@ -893,21 +893,26 @@ struct obj *obj;
xchar x, y;
boolean broken;
{
boolean costly_xy;
struct monst *shkp = shop_keeper(*u.ushops);
if (!shkp)
return;
if (broken || !costly_spot(x, y)
|| *in_rooms(x, y, SHOPBASE) != *u.ushops) {
costly_xy = costly_spot(x, y);
if (broken || !costly_xy || *in_rooms(x, y, SHOPBASE) != *u.ushops) {
/* thrown out of a shop or into a different shop */
if (is_unpaid(obj))
(void) stolen_value(obj, u.ux, u.uy, (boolean) shkp->mpeaceful,
FALSE);
if (broken)
obj->no_charge = 1;
} else {
if (costly_spot(u.ux, u.uy) && costly_spot(x, y)) {
} else if (costly_xy) {
char *oshops = in_rooms(x, y, SHOPBASE);
/* ushops0: in case we threw while levitating and recoiled
out of shop (most likely to the shk's spot in front of door) */
if (*oshops == *u.ushops || *oshops == *u.ushops0) {
if (is_unpaid(obj))
subfrombill(obj, shkp);
else if (x != shkp->mx || y != shkp->my)