- rewrote AActor::DestroyAllInventory so that it clears the item's link to its owner and the owner's inventory list before destroying them.

There have been reports about crashes in here with Linux that point to some of the code that gets called here doing unwanted things on the owner, so with these links cleared that should no longer be possible.
This commit is contained in:
Christoph Oelckers 2016-10-06 08:50:46 +02:00
parent 59d5b42abf
commit c56d2eecb0
1 changed files with 23 additions and 4 deletions

View File

@ -685,11 +685,30 @@ bool AActor::TakeInventory(PClassActor *itemclass, int amount, bool fromdecorate
void AActor::DestroyAllInventory () void AActor::DestroyAllInventory ()
{ {
while (Inventory != NULL) AInventory *inv = Inventory;
if (inv != nullptr)
{ {
AInventory *item = Inventory; TArray<AInventory *> toDelete;
item->Destroy ();
assert (item != Inventory); // Delete the list in a two stage approach.
// This is necessary because an item may destroy another item (e.g. sister weapons)
// which would break the list and leave parts of it undestroyed, maybe doing bad things later.
while (inv != nullptr)
{
toDelete.Push(inv);
AInventory *item = inv->Inventory;
inv->Inventory = nullptr;
inv->Owner = nullptr;
inv = item;
}
for (auto p : toDelete)
{
// the item may already have been deleted by another one, so check this here to avoid problems.
if (!(p->ObjectFlags & OF_EuthanizeMe))
{
p->Destroy();
}
}
} }
} }