using System; using Invector; using Invector.vItemManager; using System.Collections.Generic; using System.Text; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; using System.Linq; namespace Beyond { [vClassHeader("Equip Area", openClose = false)] public class bEquipArea : vMonoBehaviour { public delegate void OnPickUpItem(bEquipArea area, bItemSlot slot); private const int powerChargesMaxValue = 100; public OnPickUpItem onPickUpItemCallBack; public bInventory inventory; public bItemManager itemManager; public bItemWindow 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 event Action OnItemUsed; public UnityEngine.UI.Toggle.ToggleEvent onSetLockToEquip; [HideInInspector] public bEquipSlot currentSelectedSlot; public bEquipSlot lastSelectedSlot; [HideInInspector] public int indexOfEquippedItem; public bItem lastEquipedItem; protected bool _isLockedToEquip; [vHelpBox("Select what ItemType this EquipSlot will equip", vHelpBoxAttribute.MessageType.Warning)] public List itemTypes; private List items = new(); private List usedIndexes = new(); private List gemableWeapons = new(); private bItem selectedPowerableItem; private int selectedGemableItemIndex; 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(); } private void Start() { if (!isInit) { isInit = true; //indexOfEquipedItem = -1; inventory = GetComponentInParent(); itemManager = Player.Instance.GetComponent(); //itemManager.onEquipItem if (equipSlots.Count == 0) { var equipSlotsArray = GetComponentsInChildren(true); equipSlots = equipSlotsArray.vToList(); } foreach (bEquipSlot 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(""); } } if (itemPicker) { itemPicker.onSelectSlot.AddListener(SetPowerableWeaponImage); } } public void SetEquipmentWindow() { itemPicker.CreateEquipmentWindow(inventory.items, itemTypes, equipSlots[0].item, OnPickItem); } public void SetNewItemWindow(bItemWindow newItemPicker) { if (itemPicker) { DisableItemWindow(); } itemPicker = newItemPicker; EnableItemWindow(); } public void DisableItemWindow() { itemPicker.gameObject.SetActive(false); } public void EnableItemWindow() { itemPicker.gameObject.SetActive(true); } public void SetEquipmentwindowWithFilter(List types) { itemPicker.CreateEquipmentWindow(inventory.items, types, null, OnPickItem); //itemPicker.ReloadItems(); } public void SetEquipmentWindowsUsableWithFilter(List types) { itemPicker.CreateEquipmentWindowUsable(inventory.items, types, equipSlots[0].item, OnPickItem); } private void SetOccupiedIndexes() { for (int i = 0; i < equipSlots.Count; i++) { if (equipSlots[i].isOcupad()) usedIndexes.Add(i); } } public bool IsAnyItemEquipped() { for (int i = 0; i < equipSlots.Count; i++) { if (equipSlots[i].isOcupad()) { return true; } } return false; } /// /// Current Equipped Slot /// public bEquipSlot currentEquippedSlot { get { return equipSlots[indexOfEquippedItem]; } } /// /// Item in Current Equipped Slot /// public bItem 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; } private void UseItemInternal(bItem item) { if (item.type == bItemType.Gemstones) { if (gemableWeapons.Count < 1 || gemableWeapons[selectedGemableItemIndex] == null) { if (bItemCollectionDisplay.Instance && item.type == bItemType.Gemstones && item) { Player.Instance.PlayFullyChargedSound(); //in menu if (PopupMenuController.Instance != null) { PopupMenuController.Instance.TryToShowPopupMesssage("No proper weapons available"); } //cant use gemstone with no proper weapons available return; } } else //if (item.type == bItemType.Gemstones) { bItemAttribute powerAttribute = gemableWeapons[selectedGemableItemIndex].attributes.First(attribute => attribute.name == bItemAttributes.Power); if (powerAttribute.value >= powerChargesMaxValue) { Player.Instance.PlayFullyChargedSound(); //Player.Instance.MeleeManager.onEquipWeapon if (PopupMenuController.Instance != null) { PopupMenuController.Instance.TryToShowPopupMesssage(gemableWeapons[selectedGemableItemIndex].name + " is already fully charged"); } //cant use gemstone with no proper weapons available return; } powerAttribute.value += item.GetItemAttribute(bItemAttributes.Power).value; if (powerAttribute.value > powerChargesMaxValue) { powerAttribute.value = powerChargesMaxValue; } } } inventory.OnUseItem(item); } public void UseItem() { if (itemManager.UsingItem) { return; } //could move the logic to item manager UseItemInternal(itemPicker.currentSelectedSlot.item); /* bItem itemBeingUsed = itemPicker.currentSelectedSlot.item; //using here if (itemBeingUsed.type == bItemType.Gemstones) { bItem item = itemBeingUsed; if (gemableWeapons.Count < 1 || gemableWeapons[selectedGemableItemIndex] == null) { if (bItemCollectionDisplay.Instance && item.type == bItemType.Gemstones && item) { Player.Instance.PlayFullyChargedSound(); //in menu if (PopupMenuController.Instance != null) { PopupMenuController.Instance.TryToShowPopupMesssage("No proper weapons available"); } //cant use gemstone with no proper weapons available return; } } else if (item.type == bItemType.Gemstones) { bItemAttribute powerAttribute = gemableWeapons[selectedGemableItemIndex].attributes.First(attribute => attribute.name == bItemAttributes.Power); if (powerAttribute.value >= powerChargesMaxValue) { Player.Instance.PlayFullyChargedSound(); if (PopupMenuController.Instance != null) { PopupMenuController.Instance.TryToShowPopupMesssage(gemableWeapons[selectedGemableItemIndex].name + " is already fully charged"); } //cant use gemstone with no proper weapons available return; } powerAttribute.value += item.GetItemAttribute(bItemAttributes.Power).value; if (powerAttribute.value > powerChargesMaxValue) { powerAttribute.value = powerChargesMaxValue; } } } inventory.OnUseItem(itemBeingUsed); */ } public void UseItem(bEquipSlot equipSlot) { bItem itemBeingUsed = equipSlot.item; FindGemableWeapons(); UseItemInternal(itemBeingUsed); //do some nice things here i think //inventory.OnUseItem(itemBeingUsed); } public void UseEquippedItem() { inventory.OnUseItem(currentEquippedItem); } /// /// Event called from Inventory slot UI on Submit /// /// public void OnSubmitSlot(bItemSlot slot) { lastSelectedSlot = currentSelectedSlot; if (itemPicker != null) { currentSelectedSlot = slot as bEquipSlot; 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(bEquipSlot slot) { if (slot) { bItem 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(bItem 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 /// never fires apparently /// /// target slot public void OnSelectSlot(bItemSlot slot) { if (equipSlots.Contains(slot as bEquipSlot)) currentSelectedSlot = slot as bEquipSlot; else currentSelectedSlot = null; onSelectEquipArea.Invoke(this); CreateFullItemDescription(slot); } /// /// Event called from inventory UI when unselect an slot /// /// target slot public void OnDeselect(bItemSlot slot) { if (equipSlots.Contains(slot as bEquipSlot)) { currentSelectedSlot = null; } } /// /// Create item description /// /// target slot protected virtual void CreateFullItemDescription(bItemSlot 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); Debug.LogError("happeingng?"); } /// /// Event called from inventory UI to open when submit slot /// /// target slot public void OnPickItem(bItemSlot slot) { /* //for gemstones it does something different, it switches internal idnex of currently selected sword if (slot.item.type == bItemType.Gemstones) { SwitchPowerableWeapon(); return; } */ //1 check if any slot has this item, if it does, unequip it //2 if not fill the first free slot //3 if no free slots available swap with the oldest one if (usedIndexes.Count == 0) { SetOccupiedIndexes(); } //1 if (slot.isChecked) { bEquipSlot occupiedSlot = equipSlots.Find(eSlot => eSlot.item == slot.item); usedIndexes.Remove(equipSlots.IndexOf(occupiedSlot)); occupiedSlot.RemoveItem(); onUnequipItem.Invoke(this, slot.item); onFinishPickUpItem.Invoke(); return; } //2 bEquipSlot freeSlot = equipSlots.Find(eslot => !eslot.isOcupad() && eslot.isValid && eslot.itemType.Contains(slot.item.type)); if (freeSlot) { onPickUpItemCallBack?.Invoke(this, slot); freeSlot.AddItem(slot.item); if (!ignoreEquipEvents) { onEquipItem.Invoke(this, slot.item); } onFinishPickUpItem.Invoke(); usedIndexes.Add(equipSlots.IndexOf(freeSlot)); return; } //3 //get last used index that is of valid type bEquipSlot slotToBeTaken = equipSlots[0]; for (int i = 0; i < usedIndexes.Count; i++) { int tempIndex = usedIndexes[i]; if (equipSlots[tempIndex].itemType.Contains(slot.item.type)) { slotToBeTaken = equipSlots[tempIndex]; usedIndexes.RemoveAt(i); usedIndexes.Add(tempIndex); i = usedIndexes.Count; } } // bEquipSlot slotToBeTaken = equipSlots[usedIndexes[0]]; //remove old 1st slotToBeTaken.RemoveItem(); onUnequipItem.Invoke(this, slot.item); onFinishPickUpItem.Invoke(); //add new onPickUpItemCallBack?.Invoke(this, slot); slotToBeTaken.AddItem(slot.item); if (!ignoreEquipEvents) { onEquipItem.Invoke(this, slot.item); } onFinishPickUpItem.Invoke(); return; 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; onFinishPickUpItem.Invoke(); } void FindGemableWeapons() { List weaponTypes = new List() { bItemType.Swords, bItemType.Axes }; gemableWeapons = inventory.items.FindAll(item => weaponTypes.Contains(item.type) && item.GetItemAttribute(bItemAttributes.Power) != null); selectedGemableItemIndex = 0; } private void SetPowerableWeaponImage(bItemSlot itemSelected) { if (itemSelected.item.type == bItemType.Gemstones) { //for gemstones reset selection of gemable weapon, no saving per gem as of now FindGemableWeapons(); if (gemableWeapons.Count > 0) { selectedPowerableItem = gemableWeapons[selectedGemableItemIndex]; itemPicker.SetPowerableSwitchSwordImage(selectedPowerableItem); } } } public void SwitchPowerableWeapon() { if (gemableWeapons.Count < 1) { itemPicker.SetPowerableSwitchSwordImage(null); return; } selectedGemableItemIndex++; if (selectedGemableItemIndex >= gemableWeapons.Count) { selectedGemableItemIndex = 0; } selectedPowerableItem = gemableWeapons[selectedGemableItemIndex]; itemPicker.SetPowerableSwitchSwordImage(selectedPowerableItem); //updaing ui } /// /// 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(bItemSlot slot, bItem item, bool autoEquip = false) { if (slot is bEquipSlot && equipSlots.Contains(slot as bEquipSlot)) { AddItemToEquipSlot(equipSlots.IndexOf(slot as bEquipSlot), item, autoEquip); } } /// /// Add an item to an slot /// /// index of target Slot /// target Item public void AddItemToEquipSlot(int indexOfSlot, bItem item, bool autoEquip = false) { if (indexOfSlot < equipSlots.Count && item != null && item.canBeUsed) { 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.checkColor = slot.checkColor; 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(bItemSlot slot) { if (slot is bEquipSlot && equipSlots.Contains(slot as bEquipSlot)) { RemoveItemOfEquipSlot(equipSlots.IndexOf(slot as bEquipSlot)); } } /// /// 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(bItem 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); } } }