mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-12-01 00:21:43 +00:00
- scriptified AActor::ClearInventory
This commit is contained in:
parent
2cb0b2db87
commit
719598aae4
3 changed files with 54 additions and 45 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue