using UnityEngine; using UnityEngine.UI; using UnityEngine.Events; using System; using System.Collections.Generic; using Object = UnityEngine.Object; namespace DuloGames.UI { [AddComponentMenu("UI/Icon Slots/Equip Slot", 12)] public class UIEquipSlot : UISlotBase, IUIItemSlot { [Serializable] public class OnAssignEvent : UnityEvent { } [Serializable] public class OnAssignWithSourceEvent : UnityEvent { } [Serializable] public class OnUnassignEvent : UnityEvent { } [SerializeField] private UIEquipmentType m_EquipType = UIEquipmentType.None; /// /// Gets or sets the equip type of the slot. /// /// The type of the equip. public UIEquipmentType equipType { get { return this.m_EquipType; } set { this.m_EquipType = value; } } /// /// The assigned item info. /// private UIItemInfo m_ItemInfo; /// /// The assign event delegate. /// public OnAssignEvent onAssign = new OnAssignEvent(); /// /// The assign with source event delegate. /// public OnAssignWithSourceEvent onAssignWithSource = new OnAssignWithSourceEvent(); /// /// The unassign event delegate. /// public OnUnassignEvent onUnassign = new OnUnassignEvent(); /// /// Gets the item info of the item assigned to this slot. /// /// The spell info. public UIItemInfo GetItemInfo() { return this.m_ItemInfo; } /// /// Determines whether this slot is assigned. /// /// true if this instance is assigned; otherwise, false. public override bool IsAssigned() { return (this.m_ItemInfo != null); } /// /// Assign the slot by new item info while refering to the source. /// /// The item info. /// The source slot (Could be null). /// true if this instance is assigned; otherwise, false. public bool Assign(UIItemInfo itemInfo, Object source) { if (itemInfo == null) return false; // Check if the equipment type matches the target slot if (!this.CheckEquipType(itemInfo)) return false; // Make sure we unassign first, so the event is called before new assignment this.Unassign(); // Use the base class assign to set the icon this.Assign(itemInfo.Icon); // Set the spell info this.m_ItemInfo = itemInfo; // Invoke the on assign event if (this.onAssign != null) this.onAssign.Invoke(this); // Invoke the on assign event if (this.onAssignWithSource != null) this.onAssignWithSource.Invoke(this, source); // Success return true; } /// /// Assign the slot by item info. /// /// The item info. public bool Assign(UIItemInfo itemInfo) { return this.Assign(itemInfo, null); } /// /// Assign the slot by the passed source slot. /// /// Source. public override bool Assign(Object source) { if (source is IUIItemSlot) { IUIItemSlot sourceSlot = source as IUIItemSlot; if (sourceSlot != null) { // Check if the equipment type matches the target slot if (!this.CheckEquipType(sourceSlot.GetItemInfo())) return false; return this.Assign(sourceSlot.GetItemInfo(), source); } } // Default return false; } /// /// Checks if the given item can assigned to this slot. /// /// true, if equip type was checked, false otherwise. /// Info. public virtual bool CheckEquipType(UIItemInfo info) { if (info == null) return false; if (info.EquipType != this.equipType) return false; return true; } /// /// Unassign this slot. /// public override void Unassign() { // Remove the icon base.Unassign(); // Clear the spell info this.m_ItemInfo = null; // Invoke the on unassign event if (this.onUnassign != null) this.onUnassign.Invoke(this); } /// /// Determines whether this slot can swap with the specified target slot. /// /// true if this instance can swap with the specified target; otherwise, false. /// Target. public override bool CanSwapWith(Object target) { if (target is IUIItemSlot) { // Check if the equip slot accpets this item if (target is UIEquipSlot) { return (target as UIEquipSlot).CheckEquipType(this.GetItemInfo()); } // It's an item slot return true; } // Default return false; } // /// Performs a slot swap. /// /// true, if slot swap was performed, false otherwise. /// Source slot. public override bool PerformSlotSwap(Object sourceObject) { // Get the source slot IUIItemSlot sourceSlot = (sourceObject as IUIItemSlot); // Get the source item info UIItemInfo sourceItemInfo = sourceSlot.GetItemInfo(); // Assign the source slot by this slot bool assign1 = sourceSlot.Assign(this.GetItemInfo(), this); // Assign this slot by the source slot bool assign2 = this.Assign(sourceItemInfo, sourceObject); // Return the status return (assign1 && assign2); } /// /// Raises the tooltip event. /// /// If set to true show. public override void OnTooltip(bool show) { UITooltip.InstantiateIfNecessary(this.gameObject); // Handle unassigned if (!this.IsAssigned()) { // If we are showing the tooltip if (show) { UITooltip.AddTitle(UIEquipSlot.EquipTypeToString(this.m_EquipType)); UITooltip.SetHorizontalFitMode(ContentSizeFitter.FitMode.PreferredSize); UITooltip.AnchorToRect(this.transform as RectTransform); UITooltip.Show(); } else UITooltip.Hide(); } else { // Make sure we have spell info, otherwise game might crash if (this.m_ItemInfo == null) return; // If we are showing the tooltip if (show) { UIItemSlot.PrepareTooltip(this.m_ItemInfo); UITooltip.AnchorToRect(this.transform as RectTransform); UITooltip.Show(); } else UITooltip.Hide(); } } /// /// This method is raised when the slot is denied to be thrown away and returned to it's source. /// protected override void OnThrowAwayDenied() { if (!this.IsAssigned()) return; // Find free inventory slot List itemSlots = UIItemSlot.GetSlotsInGroup(UIItemSlot_Group.Inventory); if (itemSlots.Count > 0) { // Get the first free one foreach (UIItemSlot slot in itemSlots) { if (!slot.IsAssigned()) { // Assign this equip slot to the item slot slot.Assign(this); // Unassing this equip slot this.Unassign(); break; } } } } #region Static Methods /// /// Equip type to string convertion. /// /// The string. public static string EquipTypeToString(UIEquipmentType type) { string str = "Undefined"; switch (type) { case UIEquipmentType.Head: str = "Head"; break; case UIEquipmentType.Necklace: str = "Necklace"; break; case UIEquipmentType.Shoulders: str = "Shoulders"; break; case UIEquipmentType.Chest: str = "Chest"; break; case UIEquipmentType.Back: str = "Back"; break; case UIEquipmentType.Bracers: str = "Bracers"; break; case UIEquipmentType.Gloves: str = "Gloves"; break; case UIEquipmentType.Belt: str = "Belt"; break; case UIEquipmentType.Pants: str = "Pants"; break; case UIEquipmentType.Boots: str = "Boots"; break; case UIEquipmentType.Finger: str = "Ring"; break; case UIEquipmentType.Trinket: str = "Trinket"; break; case UIEquipmentType.Weapon_MainHand: str = "Main Hand"; break; case UIEquipmentType.Weapon_OffHand: str = "Off Hand"; break; } return str; } /// /// Gets all the equip slots. /// /// The slots. public static List GetSlots() { List slots = new List(); UIEquipSlot[] sl = Resources.FindObjectsOfTypeAll(); foreach (UIEquipSlot s in sl) { // Check if the slow is active in the hierarchy if (s.gameObject.activeInHierarchy) slots.Add(s); } return slots; } /// /// Gets the first equip slot found with the specified Equipment Type. /// /// The slot. /// The slot Equipment Type. public static UIEquipSlot GetSlotWithType(UIEquipmentType type) { UIEquipSlot[] sl = Resources.FindObjectsOfTypeAll(); foreach (UIEquipSlot s in sl) { // Check if the slow is active in the hierarchy if (s.gameObject.activeInHierarchy && s.equipType == type) return s; } // Default return null; } /// /// Gets all the equip slots with the specified Equipment Type. /// /// The slots. /// The slot Equipment Type. public static List GetSlotsWithType(UIEquipmentType type) { List slots = new List(); UIEquipSlot[] sl = Resources.FindObjectsOfTypeAll(); foreach (UIEquipSlot s in sl) { // Check if the slow is active in the hierarchy if (s.gameObject.activeInHierarchy && s.equipType == type) slots.Add(s); } return slots; } #endregion } }