using System.Collections.Generic; using System.Text; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; namespace Invector.vItemManager { [vClassHeader("Equip Area", openClose = false)] public class vEquipArea : vMonoBehaviour { public delegate void OnPickUpItem(vEquipArea area, vItemSlot slot); public OnPickUpItem onPickUpItemCallBack; public vInventory inventory; public vItemWindow itemPicker; [Tooltip("Set current equiped slot when submit an slot of this area")] public bool setEquipSlotWhenSubmit; [Tooltip("Skip empty slots when switching between slots")] public bool skipEmptySlots; public List equipSlots; public string equipPointName; public Text displayNameText; public Text displayTypeText; public Text displayAmountText; public Text displayDescriptionText; public Text displayAttributesText; [vHelpBox("You can ignore display Attributes using this property")] public List ignoreAttributes; public UnityEngine.Events.UnityEvent onInitPickUpItem, onFinishPickUpItem; public InputField.OnChangeEvent onChangeName; public InputField.OnChangeEvent onChangeType; public InputField.OnChangeEvent onChangeAmount; public InputField.OnChangeEvent onChangeDescription; public InputField.OnChangeEvent onChangeAttributes; public OnChangeEquipmentEvent onEquipItem; public OnChangeEquipmentEvent onUnequipItem; public OnSelectEquipArea onSelectEquipArea; public UnityEngine.UI.Toggle.ToggleEvent onSetLockToEquip; [HideInInspector] public vEquipSlot currentSelectedSlot; public vEquipSlot lastSelectedSlot; [HideInInspector] public int indexOfEquippedItem; public vItem lastEquipedItem; protected bool _isLockedToEquip; public bool isLockedToEquip { get { return _isLockedToEquip; } set { if (_isLockedToEquip != value) onSetLockToEquip.Invoke(value); _isLockedToEquip = value; } } public bool ignoreEquipEvents; /// /// used to ignore event. if true, the inventory will just add the equipment to area but dont will send to Equip the item. you will nedd to call to equip the item in the area. /// internal bool isInit; public void Init() { if (!isInit) Start(); } void Start() { if (!isInit) { isInit = true; //indexOfEquipedItem = -1; inventory = GetComponentInParent(); if (equipSlots.Count == 0) { var equipSlotsArray = GetComponentsInChildren(true); equipSlots = equipSlotsArray.vToList(); } foreach (vEquipSlot slot in equipSlots) { slot.onSubmitSlotCallBack = OnSubmitSlot; slot.onSelectSlotCallBack = OnSelectSlot; slot.onDeselectSlotCallBack = OnDeselect; onSetLockToEquip.AddListener(slot.SetLockToEquip); if (slot.displayAmountText) slot.displayAmountText.text = ""; slot.onChangeAmount.Invoke(""); } } } /// /// Current Equipped Slot /// public vEquipSlot currentEquippedSlot { get { return equipSlots[indexOfEquippedItem]; } } /// /// Item in Current Equipped Slot /// public vItem currentEquippedItem { get { var validEquipSlots = ValidSlots; if (validEquipSlots.Count > 0 && indexOfEquippedItem >= 0 && indexOfEquippedItem < validEquipSlots.Count) return validEquipSlots[indexOfEquippedItem].item; return null; } } /// /// All valid slot /// public List ValidSlots { get { return equipSlots.FindAll(slot => slot.isValid && (!skipEmptySlots || slot.item != null)); } } /// /// Check if Item is in Area /// /// item to check /// public bool ContainsItem(vItem item) { return ValidSlots.Find(slot => slot.item == item) != null; } /// /// Event called from Inventory slot UI on Submit /// /// public void OnSubmitSlot(vItemSlot slot) { lastSelectedSlot = currentSelectedSlot; if (itemPicker != null) { currentSelectedSlot = slot as vEquipSlot; if (setEquipSlotWhenSubmit) { SetEquipSlot(equipSlots.IndexOf(currentSelectedSlot)); } itemPicker.gameObject.SetActive(true); itemPicker.onCancelSlot.RemoveAllListeners(); itemPicker.onCancelSlot.AddListener(CancelCurrentSlot); itemPicker.CreateEquipmentWindow(inventory.items, currentSelectedSlot.itemType, slot.item, OnPickItem); onInitPickUpItem.Invoke(); } } /// /// Event called to cancel Submit action /// public void CancelCurrentSlot() { if (currentSelectedSlot == null) currentSelectedSlot = lastSelectedSlot; if (currentSelectedSlot != null) currentSelectedSlot.OnCancel(); onFinishPickUpItem.Invoke(); } /// /// Unequip Item of the Slot /// /// target slot public void UnequipItem(vEquipSlot slot) { if (slot) { vItem item = slot.item; if (ValidSlots[indexOfEquippedItem].item == item) lastEquipedItem = item; slot.RemoveItem(); onUnequipItem.Invoke(this, item); } } /// /// Unequip Item if is present in slots /// /// public void UnequipItem(vItem item) { var slot = ValidSlots.Find(_slot => _slot.item == item); if (slot) { if (ValidSlots[indexOfEquippedItem].item == item) lastEquipedItem = item; slot.RemoveItem(); onUnequipItem.Invoke(this, item); } } /// /// Unequip /// public void UnequipCurrentItem() { if (currentSelectedSlot && currentSelectedSlot.item) { var _item = currentSelectedSlot.item; if (ValidSlots[indexOfEquippedItem].item == _item) lastEquipedItem = _item; currentSelectedSlot.RemoveItem(); onUnequipItem.Invoke(this, _item); } } /// /// Event called from inventory UI when select an slot /// /// target slot public void OnSelectSlot(vItemSlot slot) { if (equipSlots.Contains(slot as vEquipSlot)) currentSelectedSlot = slot as vEquipSlot; else currentSelectedSlot = null; onSelectEquipArea.Invoke(this); CreateFullItemDescription(slot); } /// /// Event called from inventory UI when unselect an slot /// /// target slot public void OnDeselect(vItemSlot slot) { if (equipSlots.Contains(slot as vEquipSlot)) { currentSelectedSlot = null; } } /// /// Create item description /// /// target slot protected virtual void CreateFullItemDescription(vItemSlot slot) { var _name = slot.item ? slot.item.name : ""; var _type = slot.item ? slot.item.ItemTypeText() : ""; var _amount = slot.item ? slot.item.amount.ToString() : ""; var _description = slot.item ? slot.item.description : ""; var _attributes = slot.item ? slot.item.GetItemAttributesText(ignoreAttributes) : ""; if (displayNameText) displayNameText.text = _name; onChangeName.Invoke(_name); if (displayTypeText) displayTypeText.text = _type; onChangeType.Invoke(_type); if (displayAmountText) displayAmountText.text = _amount; onChangeAmount.Invoke(_amount); if (displayDescriptionText) displayDescriptionText.text = _description; onChangeDescription.Invoke(_description); if (displayAttributesText) displayAttributesText.text = _attributes; onChangeAttributes.Invoke(_attributes); } /// /// Event called from inventory UI to open when submit slot /// /// target slot public void OnPickItem(vItemSlot slot) { if (!currentSelectedSlot) currentSelectedSlot = lastSelectedSlot; if (!currentSelectedSlot) return; if (currentSelectedSlot.item != null && slot.item != currentSelectedSlot.item) { currentSelectedSlot.item.isInEquipArea = false; var item = currentSelectedSlot.item; if (item == slot.item) lastEquipedItem = item; currentSelectedSlot.RemoveItem(); onUnequipItem.Invoke(this, item); } if (slot.item != currentSelectedSlot.item) { if (onPickUpItemCallBack != null) onPickUpItemCallBack(this, slot); currentSelectedSlot.AddItem(slot.item); if (!ignoreEquipEvents) onEquipItem.Invoke(this, currentSelectedSlot.item); } currentSelectedSlot.OnCancel(); currentSelectedSlot = null; lastSelectedSlot = null; itemPicker.gameObject.SetActive(false); onFinishPickUpItem.Invoke(); } /// /// Equip next slot /// public void NextEquipSlot() { if (equipSlots == null || equipSlots.Count == 0) return; lastEquipedItem = currentEquippedItem; var validEquipSlots = ValidSlots; if (indexOfEquippedItem + 1 < validEquipSlots.Count) indexOfEquippedItem++; else indexOfEquippedItem = 0; if (currentEquippedItem != null && !ignoreEquipEvents) onEquipItem.Invoke(this, currentEquippedItem); onUnequipItem.Invoke(this, lastEquipedItem); } /// /// Equip previous slot /// public void PreviousEquipSlot() { if (equipSlots == null || equipSlots.Count == 0) return; lastEquipedItem = currentEquippedItem; var validEquipSlots = ValidSlots; if (indexOfEquippedItem - 1 >= 0) indexOfEquippedItem--; else indexOfEquippedItem = validEquipSlots.Count - 1; if (currentEquippedItem != null && !ignoreEquipEvents) onEquipItem.Invoke(this, currentEquippedItem); onUnequipItem.Invoke(this, lastEquipedItem); } /// /// Equip slot /// /// index of target slot public void SetEquipSlot(int indexOfSlot) { if (equipSlots == null || equipSlots.Count == 0) return; if (indexOfSlot < equipSlots.Count && indexOfSlot >= 0) { lastEquipedItem = currentEquippedItem; indexOfEquippedItem = indexOfSlot; if (currentEquippedItem != null && !ignoreEquipEvents) { onEquipItem.Invoke(this, currentEquippedItem); } if(currentEquippedItem != lastEquipedItem) onUnequipItem.Invoke(this, lastEquipedItem); } } public void EquipCurrentSlot() { if (!currentEquippedSlot|| (currentEquippedSlot.item!=null && currentEquippedSlot.item.isEquiped)) return; if (currentEquippedItem) onEquipItem.Invoke(this, currentEquippedItem); else if(lastEquipedItem) onUnequipItem.Invoke(this, lastEquipedItem); } /// /// Add an item to an slot /// /// target Slot /// target Item public void AddItemToEquipSlot(vItemSlot slot, vItem item, bool autoEquip = false) { if (slot is vEquipSlot && equipSlots.Contains(slot as vEquipSlot)) { AddItemToEquipSlot(equipSlots.IndexOf(slot as vEquipSlot), item, autoEquip); } } /// /// Add an item to an slot /// /// index of target Slot /// target Item public void AddItemToEquipSlot(int indexOfSlot, vItem item, bool autoEquip = false) { if (indexOfSlot < equipSlots.Count && item != null) { var slot = equipSlots[indexOfSlot]; if (slot != null && slot.isValid && slot.itemType.Contains(item.type)) { var sameSlot = equipSlots.Find(s => s.item == item && s != slot); if (sameSlot != null) RemoveItemOfEquipSlot(equipSlots.IndexOf(sameSlot)); if (slot.item != null && slot.item != item) { if (currentEquippedItem == slot.item) lastEquipedItem = slot.item; slot.item.isInEquipArea = false; onUnequipItem.Invoke(this, slot.item); } item.isInEquipArea = true; slot.AddItem(item); if (autoEquip) SetEquipSlot(indexOfSlot); else if(!ignoreEquipEvents) onEquipItem.Invoke(this, item); } } } /// /// Remove item of an slot /// /// target Slot public void RemoveItemOfEquipSlot(vItemSlot slot) { if (slot is vEquipSlot && equipSlots.Contains(slot as vEquipSlot)) { RemoveItemOfEquipSlot(equipSlots.IndexOf(slot as vEquipSlot)); } } /// /// Remove item of an slot /// /// index of target Slot public void RemoveItemOfEquipSlot(int indexOfSlot) { if (indexOfSlot < equipSlots.Count) { var slot = equipSlots[indexOfSlot]; if (slot != null && slot.item != null) { var item = slot.item; item.isInEquipArea = false; if (currentEquippedItem == item) lastEquipedItem = currentEquippedItem; slot.RemoveItem(); onUnequipItem.Invoke(this, item); } } } /// /// Add item to current equiped slot /// /// target item public void AddCurrentItem(vItem item) { if (indexOfEquippedItem < equipSlots.Count) { var slot = equipSlots[indexOfEquippedItem]; if (slot.item != null && item != slot.item) { if (currentEquippedItem == slot.item) lastEquipedItem = slot.item; slot.item.isInEquipArea = false; onUnequipItem.Invoke(this, currentSelectedSlot.item); } slot.AddItem(item); if(!ignoreEquipEvents) onEquipItem.Invoke(this, item); } } /// /// Remove current equiped Item /// public void RemoveCurrentItem() { if (!currentEquippedItem) return; lastEquipedItem = currentEquippedItem; ValidSlots[indexOfEquippedItem].RemoveItem(); onUnequipItem.Invoke(this, lastEquipedItem); } } }