Rather than clutter the Vanilla board, I'll discuss my findings here. Original thread is here
In summary, there is a repeatable crash if a monster picks up an object and that object is destroyed when the monster dies due to lack of floor space. The 'birth_stacking' flag seems to be ignored (the save file in the referenced thread has stacking on'.
In obj-pile.c in drop_near() there are a couple of chunks of code like this:
and in delist_object() we have:
I'm thinking that when an object is picked up by a monster, it's not being removed from the 'cave' completely.
In mon_move.c in process_monster_grab_objects(), the code which performs the pick-up is
square_excise_object() just calls pile_excise() - but nowhere does the code seem to touch cave_k->objects[obj->oidx]
Hopefully this helps track down this nasty
In summary, there is a repeatable crash if a monster picks up an object and that object is destroyed when the monster dies due to lack of floor space. The 'birth_stacking' flag seems to be ignored (the save file in the referenced thread has stacking on'.
In obj-pile.c in drop_near() there are a couple of chunks of code like this:
Code:
/* Message */ msg("The %s %s.", o_name, VERB_AGREEMENT(dropped->number, "disappears", "disappear")); /* Debug */ if (player->wizard) msg("Breakage (no floor space)."); /* Failure */ if (dropped->known) { delist_object(cave_k, dropped->known); object_delete(&dropped->known); } delist_object(c, dropped); object_delete(&dropped); return;
Code:
/* Don't delist an actual object if it still has a listed known object */ if ((c == cave) && cave_k->objects[obj->oidx]) return; c->objects[obj->oidx] = NULL; obj->oidx = 0;
In mon_move.c in process_monster_grab_objects(), the code which performs the pick-up is
Code:
square_excise_object(c, ny, nx, obj); monster_carry(c, mon, obj); square_note_spot(c, ny, nx); square_light_spot(c, ny, nx);
Hopefully this helps track down this nasty
Comment