Files
BABA_YAGA/Assets/Opsive/UltimateCharacterController/Scripts/Inventory/InventoryBase.cs
2026-06-14 23:57:44 +07:00

650 lines
31 KiB
C#

/// ---------------------------------------------
/// Ultimate Character Controller
/// Copyright (c) Opsive. All Rights Reserved.
/// https://www.opsive.com
/// ---------------------------------------------
namespace Opsive.UltimateCharacterController.Inventory
{
using Opsive.Shared.Events;
#if ULTIMATE_CHARACTER_CONTROLLER_MULTIPLAYER
using Opsive.Shared.Game;
#endif
using Opsive.Shared.Inventory;
using Opsive.UltimateCharacterController.Events;
using Opsive.UltimateCharacterController.Items;
using Opsive.UltimateCharacterController.Items.Actions;
#if ULTIMATE_CHARACTER_CONTROLLER_MULTIPLAYER
using Opsive.UltimateCharacterController.Networking;
using Opsive.UltimateCharacterController.Networking.Character;
#endif
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// Provides a common base class for any character Inventory.
/// </summary>
public abstract class InventoryBase : MonoBehaviour
{
[Tooltip("Should all of the IItemIdentifier be removed when the character dies?")]
[SerializeField] protected bool m_RemoveAllOnDeath = true;
[Tooltip("Should the default loadout be loaded when the character respawns?")]
[SerializeField] protected bool m_LoadDefaultLoadoutOnRespawn = true;
[Tooltip("The name of the state when the inventory is unequipped.")]
[SerializeField] protected string m_UnequippedStateName = "Unequipped";
[Tooltip("Unity event that is invoked when an item is initially added to the inventory.")]
[SerializeField] protected UnityItemEvent m_OnAddItemEvent;
[Tooltip("Unity event that is invoked when an IItemIdentifier is picked up.")]
[SerializeField] protected UnityItemIdentifierFloatBoolBoolEvent m_OnPickupItemIdentifierEvent;
[Tooltip("Unity event that is invoked when an item is picked up.")]
[SerializeField] protected UnityItemFloatBoolBoolEvent m_OnPickupItemEvent;
[Tooltip("Unity event that is invoked when an item is equipped.")]
[SerializeField] protected UnityItemIntEvent m_OnEquipItemEvent;
[Tooltip("Unity event that is invoked when an IItemIdentifier is adjusted.")]
[SerializeField] protected UnityItemIdentifierFloatEvent m_OnAdjustItemIdentifierAmountEvent;
[Tooltip("Unity event that is invoked when an item is unequipped.")]
[SerializeField] protected UnityItemIntEvent m_OnUnequipItemEvent;
[Tooltip("Unity event that is invoked when an item is removed.")]
[SerializeField] protected UnityItemIntEvent m_OnRemoveItemEvent;
public bool RemoveAllOnDeath { get { return m_RemoveAllOnDeath; } set { m_RemoveAllOnDeath = value; } }
public bool LoadDefaultLoadoutOnRespawn { get { return m_LoadDefaultLoadoutOnRespawn; } set { m_LoadDefaultLoadoutOnRespawn = value; } }
public string UnequippedStateName { get { return m_UnequippedStateName; } set { m_UnequippedStateName = value; } }
public UnityItemEvent OnAddItemEvent { get { return m_OnAddItemEvent; } set { m_OnAddItemEvent = value; } }
public UnityItemIdentifierFloatBoolBoolEvent OnPickupItemIdentifierEvent { get { return m_OnPickupItemIdentifierEvent; } set { m_OnPickupItemIdentifierEvent = value; } }
public UnityItemFloatBoolBoolEvent OnPickupItemEvent { get { return m_OnPickupItemEvent; } set { m_OnPickupItemEvent = value; } }
public UnityItemIntEvent OnEquipItemEvent { get { return m_OnEquipItemEvent; } set { m_OnEquipItemEvent = value; } }
public UnityItemIdentifierFloatEvent OnAdjustItemIdentifierAmountEvent { get { return m_OnAdjustItemIdentifierAmountEvent; } set { m_OnAdjustItemIdentifierAmountEvent = value; } }
public UnityItemIntEvent OnUnequipItemEvent { get { return m_OnUnequipItemEvent; } set { m_OnUnequipItemEvent = value; } }
public UnityItemIntEvent OnRemoveItemEvent { get { return m_OnRemoveItemEvent; } set { m_OnRemoveItemEvent = value; } }
protected GameObject m_GameObject;
#if ULTIMATE_CHARACTER_CONTROLLER_MULTIPLAYER
private INetworkInfo m_NetworkInfo;
private INetworkCharacter m_NetworkCharacter;
#endif
protected int m_SlotCount = 1;
private List<Item> m_AllItems = new List<Item>();
private List<IItemIdentifier> m_AllItemIdentifiers = new List<IItemIdentifier>();
public int SlotCount { get {
#if UNITY_EDITOR
if (!Application.isPlaying) { DetermineSlotCount(); }
#endif
return m_SlotCount;
} }
/// <summary>
/// Initialize the default values.
/// </summary>
protected virtual void Awake()
{
m_GameObject = gameObject;
#if ULTIMATE_CHARACTER_CONTROLLER_MULTIPLAYER
m_NetworkInfo = m_GameObject.GetCachedComponent<INetworkInfo>();
m_NetworkCharacter = m_GameObject.GetCachedComponent<INetworkCharacter>();
#endif
DetermineSlotCount();
EventHandler.RegisterEvent<Vector3, Vector3, GameObject>(m_GameObject, "OnDeath", OnDeath);
EventHandler.RegisterEvent(m_GameObject, "OnRespawn", OnRespawn);
}
/// <summary>
/// Determines the number of slots on the character.
/// </summary>
public void DetermineSlotCount()
{
// The number of slots depends on the maximum number of ItemSlot IDs.
var itemSlots = GetComponentsInChildren<ItemSlot>(true);
for (int i = 0; i < itemSlots.Length; ++i) {
if (m_SlotCount <= itemSlots[i].ID) {
m_SlotCount = itemSlots[i].ID + 1;
}
}
}
/// <summary>
/// Loads the default loadout.
/// </summary>
protected virtual void Start()
{
// The character starts out unequipped.
if (!string.IsNullOrEmpty(m_UnequippedStateName)) {
StateSystem.StateManager.SetState(m_GameObject, m_UnequippedStateName, true);
}
#if ULTIMATE_CHARACTER_CONTROLLER_MULTIPLAYER
if (m_NetworkInfo == null || m_NetworkInfo.IsLocalPlayer()) {
if (m_NetworkInfo != null) {
// Load the default loadout on the network first to ensure it is received before any equip events.
m_NetworkCharacter.LoadDefaultLoadout();
}
#endif
LoadDefaultLoadout();
#if ULTIMATE_CHARACTER_CONTROLLER_MULTIPLAYER
}
#endif
EventHandler.ExecuteEvent(m_GameObject, "OnCharacterSnapAnimator");
}
/// <summary>
/// Pick up each ItemIdentifier within the DefaultLoadout.
/// </summary>
public abstract void LoadDefaultLoadout();
/// <summary>
/// Determines if the character has the specified item.
/// </summary>
/// <param name="item">The item to check against.</param>
/// <returns>True if the character has the item.</returns>
public bool HasItem(Item item) { return HasItemInternal(item); }
/// <summary>
/// Internal method which determines if the character has the specified item.
/// </summary>
/// <param name="item">The item to check against.</param>
/// <returns>True if the character has the item.</returns>
protected abstract bool HasItemInternal(Item item);
/// <summary>
/// Adds the item to the inventory. This does not add the actual ItemIdentifier - PickupItem does that.
/// </summary>
/// <param name="item">The Item to add.</param>
/// <param name="immediateEquip">Can the item be equipped immediately?</param>
/// <param name="forcePickup">Should the item be force equipped?</param>
public void AddItem(Item item, bool immediateEquip, bool forceEquip)
{
if (AddItemInternal(item)) {
m_AllItems.Add(item);
// Notify those interested that an item has been added.
EventHandler.ExecuteEvent(m_GameObject, "OnInventoryAddItem", item);
if (m_OnAddItemEvent != null) {
m_OnAddItemEvent.Invoke(item);
}
// The ItemIdentifier event should also be called in cases where the amount is greater than 0.
// This allows the ItemIdentifier to be picked up before the item has been added.
if (GetItemIdentifierAmount(item.ItemIdentifier) > 0) {
ItemIdentifierPickedUp(item.ItemIdentifier, 1, item.SlotID, immediateEquip, forceEquip);
}
}
}
/// <summary>
/// Internal method which adds the item to the Inventory. This does not add the actual IItemIdentifier - PickupItem does that.
/// </summary>
/// <param name="item">The item to add.</param>
/// <returns>True if the item was added to the inventory.</returns>
protected abstract bool AddItemInternal(Item item);
/// <summary>
/// Adds the specified amount of the ItemIdentifier to the inventory.
/// </summary>
/// <param name="itemIdentifier">The ItemIdentifier to add.</param>
/// <param name="amount">The amount of ItemIdentifier to add.</param>
/// <param name="slotID">The slot ID that picked up the item. A -1 value will indicate no specified slot.</param>
/// <param name="immediatePickup">Should the item be picked up immediately?</param>
/// <param name="forceEquip">Should the item be force equipped?</param>
/// <returns>True if the ItemIdentifier was picked up.</returns>
public bool Pickup(IItemIdentifier itemIdentifier, int amount, int slotID, bool immediatePickup, bool forceEquip)
{
return Pickup(itemIdentifier, amount, slotID, immediatePickup, forceEquip, true);
}
/// <summary>
/// Adds the specified amount of the ItemIdentifier to the inventory.
/// </summary>
/// <param name="itemIdentifier">The ItemIdentifier to add.</param>
/// <param name="amount">The amount of ItemIdentifier to add.</param>
/// <param name="slotID">The slot ID that picked up the item. A -1 value will indicate no specified slot.</param>
/// <param name="immediatePickup">Should the item be picked up immediately?</param>
/// <param name="forceEquip">Should the item be force equipped?</param>
/// <param name="notifyOnPickup">Should other objects be notified that the ItemIdentifier was picked up?</param>
/// <returns>True if the ItemIdentifier was picked up.</returns>
public bool Pickup(IItemIdentifier itemIdentifier, int amount, int slotID, bool immediatePickup, bool forceEquip, bool notifyOnPickup)
{
// Prevent pickup when the inventory isn't enabled.
if (itemIdentifier == null || !enabled || amount == 0) {
return false;
}
var pickedUp = PickupInternal(itemIdentifier, amount);
// Notify those interested that an item has been picked up.
if (pickedUp && notifyOnPickup) {
if (slotID == -1) {
// Find the slot that the item belongs to (if any).
for (int i = 0; i < m_SlotCount; ++i) {
if (GetItem(itemIdentifier, i) != null) {
ItemIdentifierPickedUp(itemIdentifier, amount, i, immediatePickup, forceEquip);
slotID = i;
}
}
if (slotID == -1) {
// The ItemIdentifier doesn't correspond to an item so execute the event once.
ItemIdentifierPickedUp(itemIdentifier, amount, -1, immediatePickup, forceEquip);
}
} else {
ItemIdentifierPickedUp(itemIdentifier, amount, slotID, immediatePickup, forceEquip);
}
// If the slot ID isn't -1 then AddItem has already run. Add the item if it hasn't already been added. This will occur if the item is removed
// and then later added again.
if (slotID != -1) {
var item = GetItem(itemIdentifier, slotID);
if (item != null && !m_AllItems.Contains(item)) {
m_AllItems.Add(item);
}
}
}
return pickedUp;
}
/// <summary>
/// Internal method which adds the specified amount of the ItemIdentifier to the inventory.
/// </summary>
/// <param name="itemIdentifier">The IItemIdentifier to add.</param>
/// <param name="amount">The amount of ItemIdentifier to add.</param>
/// <returns>True if the ItemIdentifier was picked up successfully.</returns>
protected abstract bool PickupInternal(IItemIdentifier itemIdentifier, int amount);
/// <summary>
/// The ItemIdentifier has been picked up. Notify interested objects.
/// </summary>
/// <param name="itemIdentifier">The ItemIdentifier that was picked up.</param>
/// <param name="amount">The number of ItemIdentifier picked up.</param>
/// <param name="slotID">The ID of the slot which the item belongs to.</param>
/// <param name="immediatePickup">Was the item be picked up immediately?</param>
/// <param name="forcePickup">Should the item be force equipped?</param>
protected void ItemIdentifierPickedUp(IItemIdentifier itemIdentifier, int amount, int slotID, bool immediatePickup, bool forceEquip)
{
#if ULTIMATE_CHARACTER_CONTROLLER_MULTIPLAYER
if (m_NetworkInfo != null && m_NetworkInfo.IsLocalPlayer()) {
m_NetworkCharacter.ItemIdentifierPickup(itemIdentifier.ID, amount, slotID, immediatePickup, forceEquip);
}
#endif
EventHandler.ExecuteEvent(m_GameObject, "OnInventoryPickupItemIdentifier", itemIdentifier, amount, immediatePickup, forceEquip);
if (m_OnPickupItemIdentifierEvent != null) {
m_OnPickupItemIdentifierEvent.Invoke(itemIdentifier, amount, immediatePickup, forceEquip);
}
if (slotID != -1) {
var item = GetItem(itemIdentifier, slotID);
if (item != null) {
item.Pickup();
EventHandler.ExecuteEvent(m_GameObject, "OnInventoryPickupItem", item, amount, immediatePickup, forceEquip);
if (m_OnPickupItemEvent != null) {
m_OnPickupItemEvent.Invoke(item, amount, immediatePickup, forceEquip);
}
}
}
if (!m_AllItemIdentifiers.Contains(itemIdentifier)) {
m_AllItemIdentifiers.Add(itemIdentifier);
}
}
/// <summary>
/// Returns the active item in the specified slot.
/// </summary>
/// <param name="slotID">The ID of the slot.</param>
/// <returns>The active item which occupies the specified slot. Can be null.</returns>
public Item GetActiveItem(int slotID) { return GetActiveItemInternal(slotID); }
/// <summary>
/// Internal method which returns the active item in the specified slot.
/// </summary>
/// <param name="slotID">The ID of the slot which the item belongs to.</param>
/// <returns>The active item which occupies the specified slot. Can be null.</returns>
protected abstract Item GetActiveItemInternal(int slotID);
/// <summary>
/// Returns the item that corresponds to the specified ItemIdentifier.
/// </summary>
/// <param name="itemIdentifier">The ItemIdentifier of the item.</param>
/// <param name="slotID">The ID of the slot which the item belongs to.</param>
/// <returns>The item which occupies the specified slot. Can be null.</returns>
public Item GetItem(IItemIdentifier itemIdentifier, int slotID) { return GetItemInternal(itemIdentifier, slotID); }
/// <summary>
/// Internal method which returns the item that corresponds to the specified IItemIdentifier.
/// </summary>
/// <param name="itemIdentifier">The ItemIdentifier of the item.</param>
/// <param name="slotID">The ID of the slot which the item belongs to.</param>
/// <returns>The item which occupies the specified slot. Can be null.</returns>
protected abstract Item GetItemInternal(IItemIdentifier itemIdentifier, int slotID);
/// <summary>
/// Returns a list of all of the items in the inventory.
/// </summary>
/// <returns>A list of all of the items in the inventory.</returns>
public List<Item> GetAllItems() { return m_AllItems; }
/// <summary>
/// Returns a list of all of the ItemIdentifier in the inventory. Only used by the editor for the inventory inspector.
/// </summary>
/// <returns>A list of all of the ItemIdentifier in the inventory.</returns>
public List<IItemIdentifier> GetAllItemIdentifiers() { return m_AllItemIdentifiers; }
/// <summary>
/// Equips the ItemIdentifier in the specified slot.
/// </summary>
/// <param name="itemIdentifier">The ItemIdentifier to equip.</param>
/// <param name="slotID">The ID of the slot.</param>
/// <param name="immediateEquip">Is the item being equipped immediately? Immediate equips will occur from the default loadout or quickly switching to the item.</param>
public void EquipItem(IItemIdentifier itemIdentifier, int slotID, bool immediateEquip)
{
if (itemIdentifier == null) {
return;
}
var currentItem = GetActiveItem(slotID);
if (currentItem != null && currentItem.ItemIdentifier != itemIdentifier) {
UnequipItem(slotID);
}
var item = EquipItemInternal(itemIdentifier, slotID);
if (item != null) {
item.Equip(immediateEquip);
// Notify those interested that an item has been equipped.
EventHandler.ExecuteEvent(m_GameObject, "OnInventoryEquipItem", item, slotID);
if (m_OnEquipItemEvent != null) {
m_OnEquipItemEvent.Invoke(item, slotID);
}
#if ULTIMATE_CHARACTER_CONTROLLER_MULTIPLAYER
if (m_NetworkInfo != null && m_NetworkInfo.IsLocalPlayer()) {
m_NetworkCharacter.EquipUnequipItem(itemIdentifier.ID, slotID, true);
}
#endif
if (!string.IsNullOrEmpty(m_UnequippedStateName)) {
StateSystem.StateManager.SetState(m_GameObject, m_UnequippedStateName, false);
}
}
}
/// <summary>
/// Internal method which equips the ItemIdentifier in the specified slot.
/// </summary>
/// <param name="itemIdentifier">The ItemIdentifier to equip.</param>
/// <param name="slotID">The ID of the slot.</param>
/// <returns>The item which corresponds to the ItemIdentifier. Can be null.</returns>
protected abstract Item EquipItemInternal(IItemIdentifier itemIdentifier, int slotID);
/// <summary>
/// Unequips the specified ItemIdentifier in the specified slot.
/// </summary>
/// <param name="itemIdentifier">The ItemIdentifier to unequip. If the ItemIdentifier isn't currently equipped then no changes will be made.</param>
/// <param name="slotID">The ID of the slot.</param>
public void UnequipItem(IItemIdentifier itemIdentifier, int slotID)
{
// No need to unequip if the item is already unequipped or the ItemIdentifier don't match.
var currentItem = GetActiveItem(slotID);
if (currentItem == null || currentItem.ItemIdentifier != itemIdentifier) {
return;
}
UnequipItem(slotID);
}
/// <summary>
/// Unequips the item in the specified slot.
/// </summary>
/// <param name="slotID">The ID of the slot.</param>
public void UnequipItem(int slotID)
{
// No need to unequip if the item is already unequipped.
var currentItem = GetActiveItem(slotID);
if (currentItem == null) {
return;
}
var item = UnequipItemInternal(slotID);
if (item != null) {
item.Unequip();
// Notify those interested that an item has been unequipped.
EventHandler.ExecuteEvent(m_GameObject, "OnInventoryUnequipItem", item, slotID);
if (m_OnUnequipItemEvent != null) {
m_OnUnequipItemEvent.Invoke(item, slotID);
}
#if ULTIMATE_CHARACTER_CONTROLLER_MULTIPLAYER
if (m_NetworkInfo != null && m_NetworkInfo.IsLocalPlayer()) {
m_NetworkCharacter.EquipUnequipItem(item.ItemIdentifier.ID, slotID, false);
}
#endif
// Optionally enable a state when the inventory is unequipped.
if (!string.IsNullOrEmpty(m_UnequippedStateName)) {
var unequipped = true;
for (int i = 0; i < m_SlotCount; ++i) {
if (i == slotID) {
continue;
}
if (GetActiveItem(i) != null) {
unequipped = false;
}
}
if (unequipped) {
StateSystem.StateManager.SetState(m_GameObject, m_UnequippedStateName, true);
}
}
}
}
/// <summary>
/// Internal method which unequips the item in the specified slot.
/// </summary>
/// <param name="slotID">The ID of the slot.</param>
/// <returns>The item that was unequipped.</returns>
protected abstract Item UnequipItemInternal(int slotID);
/// <summary>
/// Returns the amount of the specified ItemIdentifier.
/// </summary>
/// <param name="itemIdentifier">The ItemIdentifier to get the amount of.</param>
/// <returns>The amount of the specified ItemIdentifier.</returns>
public int GetItemIdentifierAmount(IItemIdentifier itemIdentifier) { if (itemIdentifier == null) { return 0; } return GetItemIdentifierAmountInternal(itemIdentifier); }
/// <summary>
/// Internal method which returns the amount of the specified ItemIdentifier.
/// </summary>
/// <param name="itemIdentifier">The ItemIdentifier to get the amount of.</param>
/// <returns>The amount of the specified ItemIdentifier.</returns>
protected abstract int GetItemIdentifierAmountInternal(IItemIdentifier itemIdentifier);
/// <summary>
/// Adjusts the amount of the specified ItemIdentifier.
/// </summary>
/// <param name="itemIdentifier">The ItemIdentifier to adjust.</param>
/// <param name="amount">The amount of ItemIdentifier to adjust.</param>
public void AdjustItemIdentifierAmount(IItemIdentifier itemIdentifier, int amount)
{
if (itemIdentifier == null || amount == 0) {
return;
}
AdjustItemIdentifierAmountInternal(itemIdentifier, amount);
// Notify those interested that an item has been adjusted.
var remaining = GetItemIdentifierAmount(itemIdentifier);
EventHandler.ExecuteEvent(m_GameObject, "OnInventoryAdjustItemIdentifierAmount", itemIdentifier, remaining);
if (m_OnAdjustItemIdentifierAmountEvent != null) {
m_OnAdjustItemIdentifierAmountEvent.Invoke(itemIdentifier, remaining);
}
}
/// <summary>
/// Internal method which adjusts the amount of the specified ItemIdentifier.
/// </summary>
/// <param name="itemIdentifier">The ItemIdentifier to adjust.</param>
/// <param name="amount">The amount of ItemIdentifier to adjust.</param>
protected abstract void AdjustItemIdentifierAmountInternal(IItemIdentifier itemIdentifier, int amount);
/// <summary>
/// Removes the ItemIdentifier from the inventory.
/// </summary>
/// <param name="itemIdentifier">The ItemIdentifier to remove.</param>
/// <param name="slotID">The ID of the slot.</param>
/// <param name="amount">The amount of the ItemIdentnfier that should be removed.</param>
/// <param name="drop">Should the item be dropped when removed?</param>
public void RemoveItem(IItemIdentifier itemIdentifier, int slotID, int amount, bool drop)
{
var item = GetItem(itemIdentifier, slotID);
if (item != null) {
// The item should be dropped before unequipped so the drop position will be correct.
if (drop) {
item.Drop(amount, false);
}
// An equipped item needs to be unequipped.
UnequipItem(itemIdentifier, slotID);
// If the item isn't dropped then it is removed immediately.
if (!drop) {
item.Remove();
}
if (item.DropConsumableItems) {
var itemActions = item.ItemActions;
if (itemActions != null) {
IUsableItem usableItem;
IItemIdentifier consumableItemIdentifier;
for (int i = 0; i < itemActions.Length; ++i) {
if (((usableItem = itemActions[i] as IUsableItem) != null) && (consumableItemIdentifier = usableItem.GetConsumableItemIdentifier()) != null) {
usableItem.RemoveConsumableItemIdentifierAmount();
// Any consumable ItemIdentifier should also be removed if there are no more of the same items remaining.
if (GetItemIdentifierAmount(itemIdentifier) == 1) {
RemoveItemIdentifierInternal(consumableItemIdentifier, slotID, amount);
m_AllItemIdentifiers.Remove(consumableItemIdentifier);
}
// Notify those interested of the removed amount.
SendItemIdentifierAdjustmentEvents(consumableItemIdentifier);
}
}
}
}
m_AllItems.Remove(item);
}
// The ItemIdentifier should be removed from the inventory.
RemoveItemIdentifierInternal(itemIdentifier, slotID, amount);
if (GetItemIdentifierAmount(itemIdentifier) == 0) {
m_AllItemIdentifiers.Remove(itemIdentifier);
}
// Notify those interested that the item will be removed.
if (item != null) {
EventHandler.ExecuteEvent(m_GameObject, "OnInventoryRemoveItem", item, slotID);
if (m_OnRemoveItemEvent != null) {
m_OnRemoveItemEvent.Invoke(item, slotID);
}
} else {
SendItemIdentifierAdjustmentEvents(itemIdentifier);
}
}
/// <summary>
/// Sends the ItemIdentifier adjustment events.
/// </summary>
/// <param name="itemIdentifier">The ItemIdentifier to remove.</param>
private void SendItemIdentifierAdjustmentEvents(IItemIdentifier itemIdentifier)
{
// Notify those interested of the removed amount.
var amount = GetItemIdentifierAmount(itemIdentifier);
EventHandler.ExecuteEvent(m_GameObject, "OnInventoryAdjustItemIdentifierAmount", itemIdentifier, amount);
if (m_OnAdjustItemIdentifierAmountEvent != null) {
m_OnAdjustItemIdentifierAmountEvent.Invoke(itemIdentifier, amount);
}
if (amount == 0) {
m_AllItemIdentifiers.Remove(itemIdentifier);
}
}
/// <summary>
/// Internal method which removes the ItemIdentifier from the inventory.
/// </summary>
/// <param name="itemIdentifier">The ItemIdentifier to remove.</param>
/// <param name="slotID">The ID of the slot.</param>
/// <param name="amount">The amount of the ItemIdentifier that should be removed.</param>
protected abstract void RemoveItemIdentifierInternal(IItemIdentifier itemIdentifier, int slotID, int amount);
/// <summary>
/// The character has died.
/// </summary>
/// <param name="position">The position of the force.</param>
/// <param name="force">The amount of force which killed the character.</param>
/// <param name="attacker">The GameObject that killed the character.</param>
private void OnDeath(Vector3 position, Vector3 force, GameObject attacker)
{
enabled = false;
// The item's drop method will call RemoveItem within the inventory.
if (m_RemoveAllOnDeath) {
RemoveAllItems(true);
#if ULTIMATE_CHARACTER_CONTROLLER_MULTIPLAYER
if (m_NetworkInfo != null && m_NetworkInfo.IsLocalPlayer()) {
m_NetworkCharacter.RemoveAllItems();
}
#endif
}
}
/// <summary>
/// Removes all of the items from the inventory.
/// </summary>
/// <param name="drop">Should the item be dropped when removed?</param>
public void RemoveAllItems(bool drop)
{
var allItems = GetAllItems();
for (int i = allItems.Count - 1; i >= 0; --i) {
// Multiple items may be dropped at the same time.
if (allItems.Count <= i) {
continue;
}
var itemIdentifier = allItems[i].ItemIdentifier;
var slotID = allItems[i].SlotID;
while (GetItemIdentifierAmount(itemIdentifier) > 0) {
RemoveItem(itemIdentifier, slotID, 1, drop);
}
}
}
/// <summary>
/// The character has respawned.
/// </summary>
private void OnRespawn()
{
enabled = true;
if (m_LoadDefaultLoadoutOnRespawn) {
LoadDefaultLoadout();
}
// Notify others that the inventory has respawned - allows EquipUnequip to equip any previously equipped items.
EventHandler.ExecuteEvent(m_GameObject, "OnInventoryRespawned");
}
/// <summary>
/// The object has been destroyed.
/// </summary>
private void OnDestroy()
{
EventHandler.UnregisterEvent<Vector3, Vector3, GameObject>(m_GameObject, "OnDeath", OnDeath);
EventHandler.UnregisterEvent(m_GameObject, "OnRespawn", OnRespawn);
}
}
}