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.
This commit is contained in:
PatR
2022-12-01 02:23:01 -08:00
parent 4ede5f1cd4
commit 2f09bcba31
2 changed files with 27 additions and 14 deletions
+8 -4
View File
@@ -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 /* these will always be needed for the normal case, so don't bother
waiting until we find an insanity to fetch them */ waiting until we find an insanity to fetch them */
shkp = find_objowner(obj, x, y); shkp = find_objowner(obj, x, y);
if (shkp && obj->where == OBJ_ONBILL)
x = shkp->mx, y = shkp->my;
costly = costly_spot(x, y); costly = costly_spot(x, y);
costlytoo = costly_adjacent(shkp, 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"; why = "%s obj both unpaid and no_charge! %s %s: %s";
} else if (obj->unpaid) { } else if (obj->unpaid) {
/* unpaid is only applicable for directly carried objects, for /* unpaid is only applicable for directly carried objects, for
objects inside carried containers, and for floor items outside objects inside carried containers, for used up items on the
the shop proper but within the shop boundary (walls, door, "free billobjs list, and for floor items outside the shop proper
spot") and for objects moved from such spots into the shop proper but within the shop boundary (walls, door, "free spot") and
by repair of shop walls */ for objects moved from such spots into the shop proper by
repair of shop walls */
if (otop->where != OBJ_INVENT if (otop->where != OBJ_INVENT
&& obj->where != OBJ_ONBILL /* when on bill, obj==otop */
&& (otop->where != OBJ_FLOOR || (!costly && !costlytoo))) && (otop->where != OBJ_FLOOR || (!costly && !costlytoo)))
why = "%s unpaid obj not carried! %s %s: %s"; why = "%s unpaid obj not carried! %s %s: %s";
else if (!costly && !costlytoo) else if (!costly && !costlytoo)
+19 -10
View File
@@ -872,19 +872,28 @@ find_objowner(
* they shouldn't be modified */ * they shouldn't be modified */
{ {
struct monst *shkp, *deflt_shkp = 0; struct monst *shkp, *deflt_shkp = 0;
char *roomindx, *where = in_rooms(x, y, SHOPBASE);
/* conceptually object could be inside up to four rooms simultaneously; if (obj->where == OBJ_ONBILL) {
in practice it will usually be one room but can sometimes be two; /* used up item; bill obj coordinates are useless and so are x,y */
check shk and bill for each room rather than just the first; for (shkp = next_shkp(fmon, TRUE); shkp;
fallback to the first shk if obj isn't on the relevant bill(s) */ shkp = next_shkp(shkp->nmon, TRUE))
for (roomindx = where; *roomindx; ++roomindx)
if ((shkp = shop_keeper(*roomindx)) != 0) {
if (onshopbill(obj, shkp, TRUE)) if (onshopbill(obj, shkp, TRUE))
return shkp; return shkp;
if (!deflt_shkp) } else {
deflt_shkp = shkp; 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; return deflt_shkp;
} }