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 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 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; } }