using UnityEngine; using UnityEngine.Events; using UnityEngine.EventSystems; using System; using System.Collections.Generic; using Object = UnityEngine.Object; namespace DuloGames.UI { [AddComponentMenu("UI/Icon Slots/Item Slot", 12)] public class UIItemSlot : UISlotBase, IUIItemSlot { [Serializable] public class OnRightClickEvent : UnityEvent { } [Serializable] public class OnDoubleClickEvent : UnityEvent { } [Serializable] public class OnAssignEvent : UnityEvent { } [Serializable] public class OnAssignWithSourceEvent : UnityEvent { } [Serializable] public class OnUnassignEvent : UnityEvent { } [SerializeField] private UIItemSlot_Group m_SlotGroup = UIItemSlot_Group.None; [SerializeField] private int m_ID = 0; /// /// Gets or sets the slot group. /// /// The slot group. public UIItemSlot_Group slotGroup { get { return this.m_SlotGroup; } set { this.m_SlotGroup = value; } } /// /// Gets or sets the slot ID. /// /// The I. public int ID { get { return this.m_ID; } set { this.m_ID = value; } } /// /// The assigned item info. /// private UIItemInfo m_ItemInfo; /// /// The right click event delegate. /// public OnRightClickEvent onRightClick = new OnRightClickEvent(); /// /// The double click event delegate. /// public OnDoubleClickEvent onDoubleClick = new OnDoubleClickEvent(); /// /// 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; } protected override void OnEnable() { base.OnEnable(); // Check for duplicate id List slots = GetSlotsInGroup(this.m_SlotGroup); UIItemSlot duplicate = slots.Find(x => x.ID == this.m_ID && !x.Equals(this)); if (duplicate != null) { int oldId = this.m_ID; this.AutoAssignID(); Debug.LogWarning("Item Slot with duplicate ID: " + oldId + " in Group: " + this.m_SlotGroup + ", generating and assigning new ID: " + this.m_ID + "."); } } /// /// 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; // 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) return this.Assign(sourceSlot.GetItemInfo(), source); } // Default return false; } /// /// 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) { // Make sure we have spell info, otherwise game might crash if (this.m_ItemInfo == null) return; // If we are showing the tooltip if (show) { UITooltip.InstantiateIfNecessary(this.gameObject); // Prepare the tooltip UIItemSlot.PrepareTooltip(this.m_ItemInfo); // Anchor to this slot UITooltip.AnchorToRect(this.transform as RectTransform); // Show the tooltip UITooltip.Show(); } else { // Hide the tooltip UITooltip.Hide(); } } /// /// Raises the pointer click event. /// /// Event data. public override void OnPointerClick(PointerEventData eventData) { base.OnPointerClick(eventData); // Make sure the slot is assigned if (!this.IsAssigned()) return; // Check for left double click if (eventData.button == PointerEventData.InputButton.Left && eventData.clickCount == 2) { // Reset the click count eventData.clickCount = 0; // Invoke the double click event if (this.onDoubleClick != null) this.onDoubleClick.Invoke(this); } // Check for right click if (eventData.button == PointerEventData.InputButton.Right) { // Invoke the double click event if (this.onRightClick != null) this.onRightClick.Invoke(this); } } /// /// 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; if (UIModalBoxManager.Instance == null) { Debug.LogWarning("Could not load the modal box manager while creating a modal box."); return; } UIModalBox box = UIModalBoxManager.Instance.Create(this.gameObject); if (box != null) { box.SetText1("Do you really want to destroy \"" + this.m_ItemInfo.Name + "\"?"); box.SetText2("You wont be able to reverse this operation and your item will be permamently removed."); box.SetConfirmButtonText("DESTROY"); box.onConfirm.AddListener(Unassign); box.Show(); } } /// /// Automatically generate and assign slot ID. /// [ContextMenu("Auto Assign ID")] public void AutoAssignID() { // Get the active slots in the slot's group List slots = GetSlotsInGroup(this.m_SlotGroup); if (slots.Count > 0) { slots.Reverse(); this.m_ID = slots[0].ID + 1; } else { // If we have no slots this.m_ID = 1; } slots.Clear(); } #region Static Methods /// /// Gets all the item slots. /// /// The slots. public static List GetSlots() { List slots = new List(); UIItemSlot[] sl = Resources.FindObjectsOfTypeAll(); foreach (UIItemSlot s in sl) { // Check if the slow is active in the hierarchy if (s.gameObject.activeInHierarchy) slots.Add(s); } return slots; } /// /// Gets all the item slots with the specified ID. /// /// The slots. /// The slot ID. public static List GetSlotsWithID(int ID) { List slots = new List(); UIItemSlot[] sl = Resources.FindObjectsOfTypeAll(); foreach (UIItemSlot s in sl) { // Check if the slow is active in the hierarchy if (s.gameObject.activeInHierarchy && s.ID == ID) slots.Add(s); } return slots; } /// /// Gets all the item slots in the specified group. /// /// The slots. /// The item slot group. public static List GetSlotsInGroup(UIItemSlot_Group group) { List slots = new List(); UIItemSlot[] sl = Resources.FindObjectsOfTypeAll(); foreach (UIItemSlot s in sl) { // Check if the slow is active in the hierarchy if (s.gameObject.activeInHierarchy && s.slotGroup == group) slots.Add(s); } // Sort the slots by id slots.Sort(delegate (UIItemSlot a, UIItemSlot b) { return a.ID.CompareTo(b.ID); }); return slots; } /// /// Gets the slot with the specified ID and Group. /// /// The slot. /// The slot ID. /// The slot Group. public static UIItemSlot GetSlot(int ID, UIItemSlot_Group group) { UIItemSlot[] sl = Resources.FindObjectsOfTypeAll(); foreach (UIItemSlot s in sl) { // Check if the slow is active in the hierarchy if (s.gameObject.activeInHierarchy && s.ID == ID && s.slotGroup == group) return s; } return null; } /// /// Prepares the tooltip with the specified item info. /// /// Item info. public static void PrepareTooltip(UIItemInfo itemInfo) { if (itemInfo == null) return; // Set the tooltip width if (UITooltipManager.Instance != null) UITooltip.SetWidth(UITooltipManager.Instance.itemTooltipWidth); // Set the title and description UITooltip.AddTitle("" + itemInfo.Name + ""); // Spacer UITooltip.AddSpacer(); // Item types UITooltip.AddLineColumn(itemInfo.Type, "ItemAttribute"); UITooltip.AddLineColumn(itemInfo.Subtype, "ItemAttribute"); if (itemInfo.ItemType == 1) { UITooltip.AddLineColumn(itemInfo.Damage.ToString() + " Damage", "ItemAttribute"); UITooltip.AddLineColumn(itemInfo.AttackSpeed.ToString("0.0") + " Attack speed", "ItemAttribute"); UITooltip.AddLine("(" + ((float)itemInfo.Damage / itemInfo.AttackSpeed).ToString("0.0") + " damage per second)", "ItemAttribute"); } else { UITooltip.AddLineColumn(itemInfo.Armor.ToString() + " Armor", "ItemAttribute"); UITooltip.AddLineColumn(itemInfo.Block.ToString() + " Block", "ItemAttribute"); } UITooltip.AddSpacer(); UITooltip.AddLine("+" + itemInfo.Stamina.ToString() + " Stamina", "ItemStat"); UITooltip.AddLine("+" + itemInfo.Strength.ToString() + " Strength", "ItemStat"); UITooltip.AddSpacer(); UITooltip.AddLine("Durability " + itemInfo.Durability + "/" + itemInfo.Durability, "ItemAttribute"); if (itemInfo.RequiredLevel > 0) UITooltip.AddLine("Requires Level " + itemInfo.RequiredLevel, "ItemAttribute"); // Set the item description if not empty if (!string.IsNullOrEmpty(itemInfo.Description)) { UITooltip.AddSpacer(); UITooltip.AddLine(itemInfo.Description, "ItemDescription"); } } #endregion } }