/// --------------------------------------------- /// Ultimate Character Controller /// Copyright (c) Opsive. All Rights Reserved. /// https://www.opsive.com /// --------------------------------------------- namespace Opsive.UltimateCharacterController.UI { using Opsive.Shared.Events; using Opsive.Shared.Inventory; using Opsive.UltimateCharacterController.Items; using Opsive.UltimateCharacterController.Items.Actions; using Opsive.UltimateCharacterController.Utility; using UnityEngine; using UnityEngine.UI; /// /// The ItemMonitor will update the UI for the character's items. /// public class SlotItemMonitor : ItemMonitor { [SerializeField] protected GameObject m_CountParent; [Tooltip("A reference to the text used for the usable item loaded count.")] [SerializeField] protected Text m_LoadedCount; [Tooltip("A reference to the text used for the usable item unloaded count.")] [SerializeField] protected Text m_UnloadedCount; [Tooltip("The ID that UI represents.")] [SerializeField] protected int m_ID; [Tooltip("A reference to the image used for the item's icon.")] [SerializeField] protected Image m_ItemIcon; [Tooltip("The action ID that the UI represents.")] [SerializeField] protected int m_ItemActionID; public Image ItemIcon { get { return m_ItemIcon; } } private GameObject m_GameObject; private RectTransform m_ItemRectTransform; private Item m_EquippedItem; private IItemIdentifier m_ConsumableItemIdentifier; /// /// Initialize the default values. /// protected override void Awake() { base.Awake(); m_GameObject = gameObject; if (m_ItemIcon == null) { m_ItemIcon = GetComponent(); } m_ItemRectTransform = m_ItemIcon.GetComponent(); m_ItemIcon.sprite = null; // Wait until an item has been equipped to activate. m_GameObject.SetActive(false); } /// /// Attaches the monitor to the specified character. /// /// The character to attach the monitor to. protected override void OnAttachCharacter(GameObject character) { if (m_Character != null) { EventHandler.UnregisterEvent(m_Character, "OnAbilityWillEquipItem", OnEquipItem); EventHandler.UnregisterEvent(m_Character, "OnAbilityUnequipItemComplete", OnUnequipItem); EventHandler.UnregisterEvent(m_Character, "OnInventoryRemoveItem", OnUnequipItem); ResetMonitor(); } base.OnAttachCharacter(character); if (m_Character == null || m_CharacterInventory == null) { return; } EventHandler.RegisterEvent(m_Character, "OnAbilityWillEquipItem", OnEquipItem); EventHandler.RegisterEvent(m_Character, "OnAbilityUnequipItemComplete", OnUnequipItem); EventHandler.RegisterEvent(m_Character, "OnInventoryRemoveItem", OnUnequipItem); // An item may already be equipped. for (int i = 0; i < m_CharacterInventory.SlotCount; ++i) { var item = m_CharacterInventory.GetActiveItem(i); if (item != null) { OnEquipItem(item, i); } } } /// /// An ItemIdentifier has been picked up within the inventory. /// /// The ItemIdentifier that has been picked up. /// The amount of item picked up. /// Was the item be picked up immediately? /// Should the item be force equipped? protected override void OnPickupItemIdentifier(IItemIdentifier itemIdentifier, int amount, bool immediatePickup, bool forceEquip) { if (itemIdentifier != m_ConsumableItemIdentifier) { return; } var countString = m_CharacterInventory.GetItemIdentifierAmount(m_ConsumableItemIdentifier).ToString(); if (m_PrimaryCount.enabled) { m_PrimaryCount.text = countString; } else { m_UnloadedCount.text = countString; } } /// /// An item has been equipped. /// /// The equipped item. /// The slot that the item now occupies. private void OnEquipItem(Item item, int slotID) { if (!item.DominantItem || item.UIMonitorID != m_ID) { return; } m_EquippedItem = item; m_ItemIcon.sprite = item.Icon; UnityEngineUtility.SizeSprite(m_ItemIcon.sprite, m_ItemRectTransform); m_GameObject.SetActive(CanShowUI()); // Multiple item actions can be attached to the same item. ItemAction itemAction = null; if (m_ItemActionID < item.ItemActions.Length) { itemAction = item.ItemActions[m_ItemActionID]; } if (itemAction is IUsableItem) { var usableItem = itemAction as IUsableItem; if ((m_ConsumableItemIdentifier = usableItem.GetConsumableItemIdentifier()) != null) { var consumableItemIdentifierAmount = usableItem.GetConsumableItemIdentifierAmount(); // If the count is -1 then only the loaded should be shown. if (consumableItemIdentifierAmount != -1) { m_LoadedCount.text = usableItem.GetConsumableItemIdentifierAmount().ToString(); m_UnloadedCount.text = m_CharacterInventory.GetItemIdentifierAmount(usableItem.GetConsumableItemIdentifier()).ToString(); m_LoadedCount.enabled = m_UnloadedCount.enabled = true; m_PrimaryCount.enabled = false; } else { m_PrimaryCount.text = m_CharacterInventory.GetItemIdentifierAmount(usableItem.GetConsumableItemIdentifier()).ToString(); m_PrimaryCount.enabled = true; m_LoadedCount.enabled = m_UnloadedCount.enabled = false; } if (m_CountParent != null) { m_CountParent.SetActive(true); } } else { DisableCountText(); } } else { DisableCountText(); } } /// /// Disables the text objects. /// private void DisableCountText() { if (m_CountParent != null) { m_CountParent.SetActive(false); } if (m_PrimaryCount != null) { m_PrimaryCount.enabled = false; } if (m_LoadedCount != null) { m_LoadedCount.enabled = false; } if (m_UnloadedCount != null) { m_UnloadedCount.enabled = false; } } /// /// The DominantItem field has been updated for the specified item. /// /// The Item whose DominantItem field was updated. /// True if the item is now a dominant item. protected override void OnUpdateDominantItem(Item item, bool dominantItem) { if ((m_EquippedItem != null && item != m_EquippedItem) || m_CharacterInventory.GetItemIdentifierAmount(item.ItemIdentifier) == 0 || m_CharacterInventory.GetActiveItem(item.SlotID) != item) { return; } if (item.DominantItem) { OnEquipItem(item, item.SlotID); } else { ResetMonitor(); } } /// /// The specified consumable ItemIdentifier has been used. /// /// The Item that has been used. /// The ItemIdentifier that has been used. /// The remaining amount of the specified ItemIdentifier. protected override void OnUseConsumableItemIdentifier(Item item, IItemIdentifier itemIdentifier, int amount) { if (item.UIMonitorID != m_ID || itemIdentifier != m_ConsumableItemIdentifier) { return; } m_LoadedCount.text = amount.ToString(); } /// /// The specified ItemIdentifier amount has been adjusted. /// /// The ItemIdentifier to adjust. /// The amount of ItemIdentifier to adjust. protected override void OnAdjustItemIdentifierAmount(IItemIdentifier itemIdentifier, int amount) { if (itemIdentifier != m_ConsumableItemIdentifier) { return; } // The primary count will be disabled if the item has both a loaded and unloaded count. if (m_PrimaryCount.enabled) { m_PrimaryCount.text = amount.ToString(); } else { m_UnloadedCount.text = amount.ToString(); } } /// /// An item has been unequipped. /// /// The unequipped item. /// The slot that the item previously occupied. private void OnUnequipItem(Item item, int slotID) { Item equippedItem = null; if (!item.DominantItem || item.UIMonitorID != m_ID || ((equippedItem = m_CharacterInventory.GetActiveItem(slotID)) != null && equippedItem.DominantItem && equippedItem != item)) { return; } ResetMonitor(); } /// /// Can the UI be shown? /// /// True if the UI can be shown. protected override bool CanShowUI() { return base.CanShowUI() && m_EquippedItem != null && m_ItemIcon.sprite != null; } /// /// Resets the monitor back to the default state. /// private void ResetMonitor() { m_EquippedItem = null; m_ConsumableItemIdentifier = null; m_GameObject.SetActive(false); } } }