- scriptified AActor::ClearInventory

This commit is contained in:
Christoph Oelckers 2018-12-02 15:24:44 +01:00
parent 2cb0b2db87
commit 719598aae4
3 changed files with 54 additions and 45 deletions

View file

@ -925,54 +925,13 @@ DEFINE_ACTION_FUNCTION(AActor, GiveInventoryType)
void AActor::ClearInventory()
{
// In case destroying an inventory item causes another to be destroyed
// (e.g. Weapons destroy their sisters), keep track of the pointer to
// the next inventory item rather than the next inventory item itself.
// For example, if a weapon is immediately followed by its sister, the
// next weapon we had tracked would be to the sister, so it is now
// invalid and we won't be able to find the complete inventory by
// following it.
//
// When we destroy an item, we leave invp alone, since the destruction
// process will leave it pointing to the next item we want to check. If
// we don't destroy an item, then we move invp to point to its Inventory
// pointer.
//
// It should be safe to assume that an item being destroyed will only
// destroy items further down in the chain, because if it was going to
// destroy something we already processed, we've already destroyed it,
// so it won't have anything to destroy.
AInventory **invp = &Inventory;
while (*invp != NULL)
IFVIRTUAL(AActor, ClearInventory)
{
AInventory *inv = *invp;
if (!(inv->ItemFlags & IF_UNDROPPABLE))
{
DepleteOrDestroy(inv);
if (!(inv->ObjectFlags & OF_EuthanizeMe)) invp = &inv->Inventory; // was only depleted so advance the pointer manually.
}
else
{
invp = &inv->Inventory;
}
}
if (player != nullptr)
{
player->ReadyWeapon = nullptr;
player->PendingWeapon = WP_NOCHANGE;
VMValue params[] = { this };
VMCall(func, params, 1, nullptr, 0);
}
}
DEFINE_ACTION_FUNCTION(AActor, ClearInventory)
{
PARAM_SELF_PROLOGUE(AActor);
self->ClearInventory();
return 0;
}
//============================================================================
//
// AActor :: CopyFriendliness

View file

@ -741,7 +741,6 @@ class Actor : Thinker native
native clearscope int GetAge() const;
native bool CheckClass(class<Actor> checkclass, int ptr_select = AAPTR_DEFAULT, bool match_superclass = false);
native void ClearInventory();
protected native void DestroyAllInventory(); // This is not supposed to be called by user code!
native clearscope Inventory FindInventory(class<Inventory> itemtype, bool subclass = false) const;
native Inventory GiveInventoryType(class<Inventory> itemtype);

View file

@ -305,6 +305,57 @@ extend class Actor
}
//============================================================================
//
// AActor :: ClearInventory
//
// Clears the inventory of a single actor.
//
//============================================================================
virtual void ClearInventory()
{
// In case destroying an inventory item causes another to be destroyed
// (e.g. Weapons destroy their sisters), keep track of the pointer to
// the next inventory item rather than the next inventory item itself.
// For example, if a weapon is immediately followed by its sister, the
// next weapon we had tracked would be to the sister, so it is now
// invalid and we won't be able to find the complete inventory by
// following it.
//
// When we destroy an item, we leave last alone, since the destruction
// process will leave it pointing to the next item we want to check. If
// we don't destroy an item, then we move last to point to its Inventory
// pointer.
//
// It should be safe to assume that an item being destroyed will only
// destroy items further down in the chain, because if it was going to
// destroy something we already processed, we've already destroyed it,
// so it won't have anything to destroy.
let last = self;
while (last.inv != NULL)
{
let inv = last.inv;
if (!inv.bUndroppable)
{
inv.DepleteOrDestroy();
if (!inv.bDestroyed) last = inv; // was only depleted so advance the pointer manually.
}
else
{
last = inv;
}
}
if (player != null)
{
player.ReadyWeapon = null;
player.PendingWeapon = WP_NOCHANGE;
}
}
//============================================================================
//
// AActor :: GiveAmmo