From 2f09bcba31cdddcbb1d24105783e4cb6601963b1 Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 1 Dec 2022 02:23:01 -0800 Subject: [PATCH] more shop billing object sanity Used up items moved to the billobjs list still have obj->unpaid set. That should probably be cleared since it has no meaning there, but this hasn't done that. For those keeping score: unpaid checking has triggered three false positives (so far) and found one bug. --- src/mkobj.c | 12 ++++++++---- src/shk.c | 29 +++++++++++++++++++---------- 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/src/mkobj.c b/src/mkobj.c index be999f140..8461369ef 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -2800,6 +2800,8 @@ shop_obj_sanity(struct obj *obj, const char *mesg) /* these will always be needed for the normal case, so don't bother waiting until we find an insanity to fetch them */ shkp = find_objowner(obj, x, y); + if (shkp && obj->where == OBJ_ONBILL) + x = shkp->mx, y = shkp->my; costly = costly_spot(x, y); costlytoo = costly_adjacent(shkp, x, y); @@ -2808,11 +2810,13 @@ shop_obj_sanity(struct obj *obj, const char *mesg) why = "%s obj both unpaid and no_charge! %s %s: %s"; } else if (obj->unpaid) { /* unpaid is only applicable for directly carried objects, for - objects inside carried containers, and for floor items outside - the shop proper but within the shop boundary (walls, door, "free - spot") and for objects moved from such spots into the shop proper - by repair of shop walls */ + objects inside carried containers, for used up items on the + billobjs list, and for floor items outside the shop proper + but within the shop boundary (walls, door, "free spot") and + for objects moved from such spots into the shop proper by + repair of shop walls */ if (otop->where != OBJ_INVENT + && obj->where != OBJ_ONBILL /* when on bill, obj==otop */ && (otop->where != OBJ_FLOOR || (!costly && !costlytoo))) why = "%s unpaid obj not carried! %s %s: %s"; else if (!costly && !costlytoo) diff --git a/src/shk.c b/src/shk.c index b8132f23f..6e2b053de 100644 --- a/src/shk.c +++ b/src/shk.c @@ -872,19 +872,28 @@ find_objowner( * they shouldn't be modified */ { struct monst *shkp, *deflt_shkp = 0; - char *roomindx, *where = in_rooms(x, y, SHOPBASE); - /* conceptually object could be inside up to four rooms simultaneously; - in practice it will usually be one room but can sometimes be two; - check shk and bill for each room rather than just the first; - fallback to the first shk if obj isn't on the relevant bill(s) */ - for (roomindx = where; *roomindx; ++roomindx) - if ((shkp = shop_keeper(*roomindx)) != 0) { + if (obj->where == OBJ_ONBILL) { + /* used up item; bill obj coordinates are useless and so are x,y */ + for (shkp = next_shkp(fmon, TRUE); shkp; + shkp = next_shkp(shkp->nmon, TRUE)) if (onshopbill(obj, shkp, TRUE)) return shkp; - if (!deflt_shkp) - deflt_shkp = shkp; - } + } else { + char *roomindx, *where = in_rooms(x, y, SHOPBASE); + + /* conceptually object could be inside up to 4 rooms simultaneously; + in practice it will usually be one room but can sometimes be two; + check shk and bill for each room rather than just the first; + fallback to the first shk if obj isn't on the relevant bill(s) */ + for (roomindx = where; *roomindx; ++roomindx) + if ((shkp = shop_keeper(*roomindx)) != 0) { + if (onshopbill(obj, shkp, TRUE)) + return shkp; + if (!deflt_shkp) + deflt_shkp = shkp; + } + } return deflt_shkp; }