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

@@ -278,6 +278,11 @@ while inside a shop, dropping an unpaid item inside an engulfer would leave
the engulfer was killed; treat dropping shop items inside an engulfer
as stealing them and giving them to that engulfer--hero must pay for
for them and shop retains ownership of them
while levitating inside a shop, throwing an unpaid item and having recoil move
hero out of shop (or to shopkeeper's spot in front of door) would
leave the item unpaid on shop floor and also on the shop's bill but
not visible via 'Iu' or 'Ix'; leaving the shop after that would anger
the shopkeeper and summon kops
Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository

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)