gzdoom-gles/wadsrc/static/zscript/actor_inventory.txt

162 lines
No EOL
4.1 KiB
Text

extend class Actor
{
//============================================================================
//
// AActor :: AddInventory
//
//============================================================================
virtual void AddInventory (Inventory item)
{
// Check if it's already attached to an actor
if (item.Owner != NULL)
{
// Is it attached to us?
if (item.Owner == self)
return;
// No, then remove it from the other actor first
item.Owner.RemoveInventory (item);
}
item.Owner = self;
item.Inv = Inv;
Inv = item;
// Each item receives an unique ID when added to an actor's inventory.
// This is used by the DEM_INVUSE command to identify the item. Simply
// using the item's position in the list won't work, because ticcmds get
// run sometime in the future, so by the time it runs, the inventory
// might not be in the same state as it was when DEM_INVUSE was sent.
Inv.InventoryID = InventoryID++;
}
//============================================================================
//
// AActor :: GiveInventory
//
//============================================================================
bool GiveInventory(Class<Inventory> type, int amount, bool givecheat = false)
{
bool result = true;
let player = self.player;
// This can be called from places which do not check the given item's type.
if (type == null || !(type is 'Inventory')) return false;
Weapon savedPendingWeap = player != NULL ? player.PendingWeapon : NULL;
bool hadweap = player != NULL ? player.ReadyWeapon != NULL : true;
Inventory item;
if (!givecheat)
{
item = Inventory(Spawn (type));
}
else
{
item = Inventory(Spawn (type, Pos, NO_REPLACE));
if (item == NULL) return false;
}
// This shouldn't count for the item statistics.
item.ClearCounters();
if (!givecheat || amount > 0)
{
item.SetGiveAmount(self, amount, givecheat);
}
if (!item.CallTryPickup (self))
{
item.Destroy ();
result = false;
}
// If the item was a weapon, don't bring it up automatically
// unless the player was not already using a weapon.
// Don't bring it up automatically if this is called by the give cheat.
if (!givecheat && player != NULL && savedPendingWeap != NULL && hadweap)
{
player.PendingWeapon = savedPendingWeap;
}
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;
}
}
//============================================================================
//
// AActor :: TakeInventory
//
//============================================================================
bool TakeInventory(class<Inventory> itemclass, int amount, bool fromdecorate = false, bool notakeinfinite = false)
{
amount = abs(amount);
let item = FindInventory(itemclass);
if (item == NULL)
return false;
if (!fromdecorate)
{
item.Amount -= amount;
if (item.Amount <= 0)
{
item.DepleteOrDestroy();
}
// It won't be used in non-decorate context, so return false here
return false;
}
bool result = false;
if (item.Amount > 0)
{
result = true;
}
// Do not take ammo if the "no take infinite/take as ammo depletion" flag is set
// and infinite ammo is on
if (notakeinfinite &&
(sv_infiniteammo || (player && FindInventory('PowerInfiniteAmmo', true))) && (item is 'Ammo'))
{
// Nothing to do here, except maybe res = false;? Would it make sense?
result = false;
}
else if (!amount || amount >= item.Amount)
{
item.DepleteOrDestroy();
}
else item.Amount -= amount;
return result;
}
}