shopping objects, unpaid and no_charge, what else?

Revise sanity_check to acknowledge that buried objects might be unpaid
or no_charge.  (For unpaid, drop shop-owned object in a gap in the
shop wall or in the free spot; for no_charge, drop something the shk
doesn't care about, or drop any hero-owned item and decline to sell.
Dig a pit.  Push or drop a boulder to fill the pit.)

Change 'I' to look for unpaid objects on the floor and for buried ones
when deciding when to include 'u' in the list of candidate object
classes and pseudo-classes.

Change 'Iu' to mention buried unpaid objects as well as floor ones.
For both non-invent categories, show a combined count without cost
info.

Have sanity_check of monster inventory test for unpaid and no_charge.

When a monster (including pet) picks up an item that's marked unpaid
(so one dropped on shop boundary, not an ordinary for-sale one), take
it off hero's shopping bill.  If dropped--pet behavior or monster
death--inside the shop, it will become for-sale rather than no_charge
or back on bill.  [Removal from bill is needed to prevent an unpaid
object ending up outside the shop if a monster carries it out, and
current sanity_check complains about an unpaid item in mon->minvent.]
This commit is contained in:
PatR
2022-12-09 04:18:20 -08:00
parent 4c32ca571a
commit 9fa08b383f
3 changed files with 68 additions and 35 deletions

View File

@@ -2131,10 +2131,7 @@ place_object(struct obj *otmp, coordxy x, coordxy y)
here without display code needing to traverse pile chain to find one */
if (otmp2 && otmp2->otyp == BOULDER && otmp->otyp != BOULDER) {
/* 3.6.3: put otmp under last consecutive boulder rather than under
just the first one; multiple boulders at same spot in new games
will be consecutive due to this, ones in old games saved before
this change might not be; can affect the map display if the top
boulder is moved/removed by some means other than pushing */
just the first one */
while (otmp2->nexthere && otmp2->nexthere->otyp == BOULDER)
otmp2 = otmp2->nexthere;
otmp->nexthere = otmp2->nexthere;
@@ -2145,11 +2142,16 @@ place_object(struct obj *otmp, coordxy x, coordxy y)
gl.level.objects[x][y] = otmp;
}
/* set the new object's location */
/* set the object's new location */
otmp->ox = x;
otmp->oy = y;
otmp->where = OBJ_FLOOR;
/* if placed outside of shop, no_charge is no longer applicable */
if (otmp->no_charge && !costly_spot(x, y)
&& !costly_adjacent(find_objowner(otmp, x, y), x, y))
otmp->no_charge = 0;
/* add to floor chain */
otmp->nobj = fobj;
fobj = otmp;
@@ -2819,10 +2821,11 @@ shop_obj_sanity(struct obj *obj, const char *mesg)
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 */
repair of shop walls or items buried while on boundary */
if (otop->where != OBJ_INVENT
&& obj->where != OBJ_ONBILL /* when on bill, obj==otop */
&& (otop->where != OBJ_FLOOR || (!costly && !costlytoo)))
&& ((otop->where != OBJ_FLOOR && obj->where != OBJ_BURIED)
|| !(costly || costlytoo)))
why = "%s unpaid obj not carried! %s %s: %s";
else if (!costly && !costlytoo)
why = "%s unpaid obj not inside tended shop! %s %s: %s";
@@ -2831,9 +2834,12 @@ shop_obj_sanity(struct obj *obj, const char *mesg)
else if (!onshopbill(obj, shkp, TRUE))
why = "%s unpaid obj not on shop bill! %s %s: %s";
} else if (obj->no_charge) {
/* no_charge is only applicable for floor objects in shops
and for objects inside floor containers in shops */
if (otop->where != OBJ_FLOOR)
/* no_charge is only applicable for floor objects in shops, for
objects inside floor containers in shops, and for objects buried
beneath the shop floor or carried by a monster (usually pet) */
if (otop->where != OBJ_FLOOR
&& otop->where != OBJ_BURIED
&& otop->where != OBJ_MINVENT)
why = "%s no_charge obj not on floor! %s %s: %s";
else if (!costly && !costlytoo)
why = "%s no_charge obj not inside tended shop! %s %s: %s";
@@ -2843,7 +2849,8 @@ shop_obj_sanity(struct obj *obj, const char *mesg)
why = "%s no_charge obj on shop bill! %s %s: %s";
}
if (why)
insane_object(obj, why, mesg, (struct monst *) 0);
insane_object(obj, why, mesg,
mcarried(otop) ? otop->ocarry : (struct monst *) 0);
return;
}
@@ -2872,6 +2879,8 @@ mon_obj_sanity(struct monst *monlist, const char *mesg)
if (obj->globby)
check_glob(obj, mesg);
check_contained(obj, mesg);
if (obj->unpaid || obj->no_charge)
shop_obj_sanity(obj, mesg);
if (obj->in_use || obj->bypass || obj->nomerge
|| (obj->otyp == BOULDER && obj->next_boulder))
insane_obj_bits(obj, mon);