deleted object sanity checking revisited

Give a different message from "obj not free" if attempting to delete
an already deleted object.  Also, skip sanity checking of in_use/
bypass/nomerge bits for deleted objects instead of clearing them when
going onto the objs_deleted list.
This commit is contained in:
PatR
2024-05-08 07:34:22 -07:00
parent 82c9e9b737
commit 0f2897c704

View File

@@ -2658,14 +2658,19 @@ container_weight(struct obj *object)
}
/*
* Mark object to be deallocated. _All_ objects should be run through here for
* them to be deallocated.
* Mark object to be deallocated. _All_ objects should be run through here
* for them to be deallocated.
*/
void
dealloc_obj(struct obj *obj)
{
if (obj->where != OBJ_FREE && obj->where != OBJ_LUAFREE)
panic("dealloc_obj: obj not free");
if (obj->where == OBJ_DELETED) {
impossible("dealloc_obj: obj already deleted (type=%d)", obj->otyp);
return;
} else if (obj->where != OBJ_FREE && obj->where != OBJ_LUAFREE) {
panic("dealloc_obj: obj not free (type=%d, where=%d)",
obj->otyp, obj->where);
}
if (obj->nobj)
panic("dealloc_obj with nobj");
if (obj->cobj)
@@ -2692,13 +2697,6 @@ dealloc_obj(struct obj *obj)
obj->lamplit = 0;
}
/* clear some bits that obj_sanity() would complain about if it were
to be called when the objs_deleted list is populated */
obj->unpaid = obj->no_charge = 0;
obj->in_use = obj->bypass = obj->nomerge = 0;
if (obj->otyp == BOULDER)
obj->next_boulder = 0;
if (obj == gt.thrownobj)
gt.thrownobj = 0;
if (obj == gk.kickedobj)
@@ -3140,12 +3138,18 @@ mon_obj_sanity(struct monst *monlist, const char *mesg)
staticfn void
insane_obj_bits(struct obj *obj, struct monst *mon)
{
unsigned o_in_use = obj->in_use, o_bypass = obj->bypass,
/* having obj->nomerge be set might be intentional */
o_nomerge = (obj->nomerge && !nomerge_exception(obj)),
/* next_boulder is only for object name formatting when
pushing boulders and should be reset by next sanity check */
o_boulder = (obj->otyp == BOULDER && obj->next_boulder);
unsigned o_in_use, o_bypass, o_nomerge, o_boulder;
if (obj->where == OBJ_DELETED)
return; /* skip bit checking for deleted objects */
o_in_use = obj->in_use;
o_bypass = obj->bypass;
/* having obj->nomerge be set might be intentional */
o_nomerge = (obj->nomerge && !nomerge_exception(obj));
/* next_boulder is only for object name formatting when pushing
boulders and should be reset by time of next sanity check */
o_boulder = (obj->otyp == BOULDER && obj->next_boulder);
if (o_in_use || o_bypass || o_nomerge || o_boulder) {
char infobuf[QBUFSZ];