- scriptified RemoveInventory and Inventory.OnDestroy.

This commit is contained in:
Christoph Oelckers 2018-12-01 17:09:23 +01:00
parent eb47fb9adc
commit 023efc7685
10 changed files with 122 additions and 120 deletions

View file

@ -746,9 +746,6 @@ public:
// APlayerPawn for some specific handling for players. None of this
// should ever be overridden by custom classes.
// Removes the item from the inventory list.
virtual void RemoveInventory (AInventory *item);
// Take the amount value of an item from the inventory list.
// If nothing is left, the item may be destroyed.
// Returns true if the initial item count is positive.

View file

@ -89,7 +89,6 @@ public:
virtual void PostBeginPlay() override;
virtual void Tick() override;
virtual void RemoveInventory (AInventory *item) override;
virtual bool UseInventory (AInventory *item) override;
virtual void BeginPlay () override;
virtual bool UpdateWaterLevel (bool splash) override;

View file

@ -180,26 +180,6 @@ DEFINE_ACTION_FUNCTION(AInventory, PrintPickupMessage)
return 0;
}
//===========================================================================
//
// AInventory :: Destroy
//
//===========================================================================
void AInventory::OnDestroy ()
{
if (Owner != NULL)
{
Owner->RemoveInventory (this);
}
Inventory = NULL;
Super::OnDestroy();
// Although contrived it can theoretically happen that these variables still got a pointer to this item
if (SendItemUse == this) SendItemUse = NULL;
if (SendItemDrop == this) SendItemDrop = NULL;
}
//===========================================================================
//
// AInventory :: DepleteOrDestroy

View file

@ -71,7 +71,6 @@ class AInventory : public AActor
public:
virtual void Serialize(FSerializer &arc) override;
virtual void OnDestroy() override;
virtual void Tick() override;
virtual bool Massacre() override;

View file

@ -753,48 +753,6 @@ DEFINE_ACTION_FUNCTION(AActor, SetState)
ACTION_RETURN_BOOL(self->SetState(state, nofunction));
};
//============================================================================
//
// AActor :: RemoveInventory
//
//============================================================================
void AActor::RemoveInventory(AInventory *item)
{
AInventory *inv, **invp;
if (item != NULL && item->Owner != NULL) // can happen if the owner was destroyed by some action from an item's use state.
{
invp = &item->Owner->Inventory;
for (inv = *invp; inv != NULL; invp = &inv->Inventory, inv = *invp)
{
if (inv == item)
{
*invp = item->Inventory;
IFVIRTUALPTR(item, AInventory, DetachFromOwner)
{
VMValue params[1] = { item };
VMCall(func, params, 1, nullptr, 0);
}
item->Owner = NULL;
item->Inventory = NULL;
break;
}
}
}
}
DEFINE_ACTION_FUNCTION(AActor, RemoveInventory)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_OBJECT_NOT_NULL(item, AInventory);
self->RemoveInventory(item);
return 0;
}
//============================================================================
//
// AActor :: TakeInventory

View file

@ -938,58 +938,6 @@ void APlayerPawn::PostBeginPlay()
}
}
//===========================================================================
//
// APlayerPawn :: RemoveInventory
//
//===========================================================================
void APlayerPawn::RemoveInventory (AInventory *item)
{
bool pickWeap = false;
// Since voodoo dolls aren't supposed to have an inventory, there should be
// no need to redirect them to the real player here as there is with AddInventory.
// If the item removed is the selected one, select something else, either the next
// item, if there is one, or the previous item.
if (player != NULL)
{
if (InvSel == item)
{
InvSel = item->NextInv ();
if (InvSel == NULL)
{
InvSel = item->PrevInv ();
}
}
if (InvFirst == item)
{
InvFirst = item->NextInv ();
if (InvFirst == NULL)
{
InvFirst = item->PrevInv ();
}
}
if (item == player->PendingWeapon)
{
player->PendingWeapon = WP_NOCHANGE;
}
if (item == player->ReadyWeapon)
{
// If the current weapon is removed, clear the refire counter and pick a new one.
pickWeap = true;
player->ReadyWeapon = NULL;
player->refire = 0;
}
}
Super::RemoveInventory (item);
if (pickWeap && player->mo == this && player->PendingWeapon == WP_NOCHANGE)
{
PickNewWeapon (NULL);
}
}
//===========================================================================
//
// APlayerPawn :: UseInventory

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 RemoveInventory(Inventory inv);
native void ClearInventory();
protected native void DestroyAllInventory(); // This is not supposed to be called by user code!
native bool SetInventory(class<Inventory> itemclass, int amount, bool beyondMax = false);

View file

@ -80,4 +80,34 @@ extend class Actor
return result;
}
//============================================================================
//
// AActor :: RemoveInventory
//
//============================================================================
virtual void RemoveInventory(Inventory item)
{
Inventory invp;
if (item != NULL && item.Owner != NULL) // can happen if the owner was destroyed by some action from an item's use state.
{
if (Inv == item) Inv = item.Inv;
else
{
for (invp = Inv; invp != null; invp = invp.Inv)
{
if (invp.Inv == item)
{
invp.Inv = item.Inv;
item.DetachFromOwner();
break;
}
}
}
item.Owner = NULL;
item.Inv = NULL;
}
}
}

View file

@ -98,6 +98,22 @@ class Inventory : Actor native
bDropped = true; // [RH] Items are dropped by default
}
//===========================================================================
//
// AInventory :: Destroy
//
//===========================================================================
override void OnDestroy ()
{
if (Owner != NULL)
{
Owner.RemoveInventory (self);
}
Inv = NULL;
Super.OnDestroy();
}
//---------------------------------------------------------------------------
//
// PROC A_RestoreSpecialThing1
@ -990,6 +1006,30 @@ class Inventory : Actor native
}
//===========================================================================
//
// AInventory :: PrevInv
//
// Returns the previous item with IF_INVBAR set.
//
//===========================================================================
Inventory PrevInv ()
{
Inventory lastgood = NULL;
Inventory item = Owner.Inv;
while (item != NULL && item != self)
{
if (item.bInvBar)
{
lastgood = item;
}
item = item.Inv;
}
return lastgood;
}
//===========================================================================
//
// AInventory :: OnDrop

View file

@ -23,4 +23,56 @@ extend class PlayerPawn
}
}
//===========================================================================
//
// APlayerPawn :: RemoveInventory
//
//===========================================================================
override void RemoveInventory (Inventory item)
{
bool pickWeap = false;
// Since voodoo dolls aren't supposed to have an inventory, there should be
// no need to redirect them to the real player here as there is with AddInventory.
// If the item removed is the selected one, select something else, either the next
// item, if there is one, or the previous item.
if (player != NULL)
{
if (InvSel == item)
{
InvSel = item.NextInv ();
if (InvSel == NULL)
{
InvSel = item.PrevInv ();
}
}
if (InvFirst == item)
{
InvFirst = item.NextInv ();
if (InvFirst == NULL)
{
InvFirst = item.PrevInv ();
}
}
if (item == player.PendingWeapon)
{
player.PendingWeapon = WP_NOCHANGE;
}
if (item == player.ReadyWeapon)
{
// If the current weapon is removed, clear the refire counter and pick a new one.
pickWeap = true;
player.ReadyWeapon = NULL;
player.refire = 0;
}
}
Super.RemoveInventory (item);
if (pickWeap && player.mo == self && player.PendingWeapon == WP_NOCHANGE)
{
PickNewWeapon (NULL);
}
}
}