using Invector; using Invector.vCharacterController; using Invector.vItemManager; using Sirenix.OdinInspector; using System; using System.Collections.Generic; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.EventSystems; using UnityEngine.UI; namespace Beyond { public delegate void ItemSlotEvent(bItemSlot item); [vClassHeader("Item Slot", openClose = false)] public class bItemSlot : vMonoBehaviour, IPointerClickHandler, ISelectHandler, IDeselectHandler, ISubmitHandler, IPointerEnterHandler, IPointerExitHandler { [vEditorToolbar("Default")] [SerializeField] private CanvasGroup m_canvasGroup; public bItem item; public bool isValid = true; [HideInInspector] public bool isChecked; public List rarityInterestedType = new List { bItemType.Swords, bItemType.Axes, bItemType.Resources, bItemType.Consumable, bItemType.ConsumablesFaith, bItemType.Gemstones }; public Color checkColor = Color.cyan; [vEditorToolbar("Optional")] public Image icon, secondaryIcon, teriaryIcon, rarityImage; public Image blockIcon; public Image checkIconBG; public Image checkIcon; public Image isSelectedIcon; public TMP_Text displayNameText; public Text displayTypeText; public TMP_Text displayAmountText; public Text displayDescriptionText; public Text displayAttributesText; public GameObject notSeenMark; public bool IsClickable = true; private bool m_isClickable = true; [SerializeField] public bool Clickable { set { m_isClickable = value; m_canvasGroup.alpha = m_isClickable ? 1f : 0.5f; m_canvasGroup.blocksRaycasts = m_isClickable; } get => m_isClickable; } [SerializeField] public List raritySprites; [vHelpBox("You can ignore display Attributes using this property")] public List ignoreAttributes; [vEditorToolbar("Events")] public InputField.OnChangeEvent onChangeName; public InputField.OnChangeEvent onChangeType; public InputField.OnChangeEvent onChangeAmount; public InputField.OnChangeEvent onChangeDescription; public InputField.OnChangeEvent onChangeAttributes; public List customAttributeDisplay; [System.Serializable] public class AttributeDisplay { public Invector.vItemManager.vItemAttributes name; [Tooltip("Special Tags\n(NAME) = Display name of the Attribute\n(VALUE) = Display the value of the Attribute\n ***Keep Empty to use default attribute display***")] public string displayFormat = "(VALUE)"; public Text text; public InputField.OnChangeEvent onChangeDisplay; } [vEditorToolbar("Events")] public ItemSlotEvent onSubmitSlotCallBack, onSelectSlotCallBack, onDeselectSlotCallBack; public OnHandleItemEvent onAddItem, onRemoveItem; public UnityEvent onEnable; public UnityEvent onDisable; public UnityEvent onClick; protected Selectable selectable; protected Color color = Color.white; private static Color deselectedImageColor = new Color(1, 1, 1, 0.7f); private static Color selectedImageColor = new Color(1, 1, 1, 1); private static Color selectedTextColor = new Color(0, 0, 0, 1); private static Color defaultTextColor = new Color(0.3f, 0.3f, 0.3f, 1); public static Color GetDefaultButtonTextColor() { return defaultTextColor; } public static Color GetSelectedButtonTextColor() { return selectedTextColor; } public static Color GetDeselectedImageColor() { return deselectedImageColor; } public static Color GetSelectedImageColor() { return selectedImageColor; } private void OnEnable() { onEnable.Invoke(); UpdateDisplays(item); } private void OnDisable() { onDisable.Invoke(); UnloadCurrentImage(); //unload } private void UnloadCurrentImage() { if (icon) { Resources.UnloadAsset(icon.sprite); } if (secondaryIcon) { Resources.UnloadAsset(secondaryIcon.sprite); } if (teriaryIcon) { Resources.UnloadAsset(teriaryIcon.sprite); } // icon.sprite = null; // secondaryIcon.sprite = null; // teriaryIcon.sprite = null; //Resources.UnloadUnusedAssets(); } protected virtual void Start() { var inventory = GetComponentInParent(); if (inventory) inventory.OnUpdateInventory += UpdateDisplays; selectable = GetComponent(); if (!m_canvasGroup) m_canvasGroup = GetComponent(); SetValid(isValid); } /// /// Update all slot display texts /// public virtual void UpdateDisplays() { UpdateDisplays(item); } private void OnDestroy() { var inventory = GetComponentInParent(); if (inventory) inventory.OnUpdateInventory -= UpdateDisplays; } /// /// Enable or disable checkIcon /// /// Enable or disable value public virtual void CheckItem(bool value) { /* if (item && item.type == bItemType.Gemstones && checkIcon) { //checkIconBG.gameObject.SetActive(false); // checkIcon.gameObject.SetActive(false); return; } */ if (item && item.type == bItemType.PowerScroll && item.canBeDroped) //there are power scrolls which are not equippable { isChecked = true; } else if (checkIcon && item) { isChecked = value; checkIcon.color = item.checkColor; checkIcon.gameObject.SetActive(isChecked); } } public void TryToMarkAsSpeciallEquipped() { if (!checkIcon) { return; } checkIcon.gameObject.SetActive(true); checkIcon.color = Color.gray; } /// /// Set if the slot is Selectable or not /// /// Enable or disable value public virtual void SetValid(bool value) { isValid = value; if (selectable) selectable.interactable = value; if (blockIcon == null) return; blockIcon.color = value ? Color.clear : Color.white; blockIcon.SetAllDirty(); isValid = value; } /// /// Add item to slot /// /// target item public virtual void AddItem(bItem item) { if (item != null) { this.item = item; onAddItem.Invoke(item); // UpdateDisplays(item); } else RemoveItem(); } private void UpdateDisplays(bItem item) { ChangeDisplayIcon(item); ChangeAdditionalDisplayIcons(item); ChangeDisplayName(item); ChangeDisplayType(item); ChangeDisplayAmount(item); ChangeDisplayDescription(item); ChangeDisplayAttributes(item); CheckItem(item != null && item.isInEquipArea); TryToSetRarityIcon(item); if (item) { SetNotSeenIcon(item.id); } } private void SetNotSeenIcon(int itemId) { if (notSeenMark == null) { return; } if (NewItemPopupSaver.itemsSeen.Contains(itemId)) { notSeenMark.SetActive(false); } else { notSeenMark.SetActive(true); } } private void TryToSetRarityIcon(bItem item) { if (item && rarityInterestedType.Contains(item.type) && rarityImage) { rarityImage.gameObject.SetActive(true); bItemAttribute rarityAttribute = item.GetItemAttribute(bItemAttributes.Rarity); if (rarityAttribute != null) { rarityImage.sprite = raritySprites[rarityAttribute.value]; } else { rarityImage.sprite = raritySprites[0]; } } } /// /// Update the Display type text /// /// target item protected virtual void ChangeDisplayType(bItem item) { if (item) { onChangeType.Invoke(item.ItemTypeText()); if (displayTypeText) displayTypeText.text = item.ItemTypeText(); } else { onChangeType.Invoke(""); if (displayTypeText) displayTypeText.text = ""; } } /// /// Update the Display attribute text /// /// protected virtual void ChangeDisplayAttributes(bItem item) { if (item) { if (displayAttributesText) displayAttributesText.text = item.GetItemAttributesText(ignoreAttributes); onChangeAttributes.Invoke(item.GetItemAttributesText(ignoreAttributes)); for (int i = 0; i < item.attributes.Count; i++) { AttributeDisplay attributeDisplay = customAttributeDisplay.Find(att => att.name.Equals(item.attributes[i].name)); if (attributeDisplay != null) { string displayText = item.attributes[i].GetDisplayText(); if (attributeDisplay.text) attributeDisplay.text.text = displayText; attributeDisplay.onChangeDisplay.Invoke(displayText); } } } else { if (displayAttributesText) displayAttributesText.text = ""; onChangeAttributes.Invoke(""); for (int i = 0; i < customAttributeDisplay.Count; i++) { if (customAttributeDisplay[i].text) customAttributeDisplay[i].text.text = ""; customAttributeDisplay[i].onChangeDisplay.Invoke(""); } } } /// /// Update the Display item Icon image /// /// protected virtual void ChangeDisplayIcon(bItem item) { if (!item) return; if (icon) { icon.sprite = Resources.Load(item.iconPath); // color.a = 1; // icon.color = color; } } public void ChangeAdditionalDisplayIcons(bItem item) { if (!item) return; if (secondaryIcon && item.secondaryIconPath.Length > 1) { secondaryIcon.sprite = Resources.Load(item.secondaryIconPath); } if (teriaryIcon && item.teriaryIconPath.Length > 1) { teriaryIcon.sprite = Resources.Load(item.teriaryIconPath); } } /// /// Update the Display Description text /// /// protected virtual void ChangeDisplayDescription(bItem item) { if (item) { onChangeDescription.Invoke(item.description); if (displayDescriptionText) displayDescriptionText.text = item.description; } else { onChangeDescription.Invoke(""); if (displayDescriptionText) displayDescriptionText.text = ""; } } /// /// Update the Display Amount text /// /// protected virtual void ChangeDisplayAmount(bItem item) { string amountText = ""; if (item != null && this.gameObject.activeSelf) { if (item.stackable && item.amount > 1) amountText = " " + item.amount.ToString(); else amountText = ""; } else if (item == null) amountText = ""; if (displayAmountText) displayNameText.text += amountText; onChangeAmount.Invoke(amountText); } /// /// Update the Display item Name text /// /// protected virtual void ChangeDisplayName(bItem item) { if (item) { onChangeName.Invoke(item.name); if (displayNameText) { displayNameText.text = item.name; } } else { onChangeName.Invoke(""); if (displayNameText) displayNameText.text = ""; } } /// /// Remove current item from the slot /// public virtual void RemoveItem() { this.item = null; onRemoveItem.Invoke(item); if (icon) { // color.a = 0; //icon.color = color; icon.sprite = null; icon.SetAllDirty(); } UpdateDisplays(null); } /// /// Check if slot has an item /// /// public virtual bool isOcupad() { return item != null; } #region UnityEngine.EventSystems Implementation public virtual void OnSelect(BaseEventData eventData) { // isSelectedIcon.enabled = true; if (onSelectSlotCallBack != null) onSelectSlotCallBack(this); } public void MarkSlotAsSelected() { displayNameText.color = GetSelectedButtonTextColor(); if (!NewItemPopupSaver.itemsSeen.Contains(item.id)) { NewItemPopupSaver.itemsSeen.Add(item.id); SetNotSeenIcon(item.id); } if (isSelectedIcon) { isSelectedIcon.enabled = true; } else { icon.color = GetSelectedImageColor(); if (secondaryIcon) { secondaryIcon.color = icon.color; } if (teriaryIcon) { teriaryIcon.color = icon.color; } if (rarityImage) { rarityImage.color = icon.color; } } } public void MarkSlotAsDeselected() { displayNameText.color = GetDefaultButtonTextColor(); if (isSelectedIcon) { isSelectedIcon.enabled = false; } else { icon.color = GetDeselectedImageColor(); if (secondaryIcon) { secondaryIcon.color = icon.color; } if (teriaryIcon) { teriaryIcon.color = icon.color; } if (rarityImage) { rarityImage.color = icon.color; } } } public virtual void OnDeselect(BaseEventData eventData) { // isSelectedIcon.enabled = false; if (onDeselectSlotCallBack != null) onDeselectSlotCallBack(this); } public virtual void OnSubmit(BaseEventData eventData) { if (isValid) { onClick.Invoke(); if (onSubmitSlotCallBack != null) onSubmitSlotCallBack(this); } CheckItem(item != null && item.isInEquipArea); } public virtual void OnPointerEnter(PointerEventData eventData) { //if(vInput.instance.inputDevice == InputDevice.MouseKeyboard) { EventSystem.current.SetSelectedGameObject(this.gameObject); if (onSelectSlotCallBack != null) onSelectSlotCallBack(this); } ///DEBUG if (IsClickable != Clickable) { Clickable = IsClickable; } } public virtual void OnPointerExit(PointerEventData eventData) { //if (vInput.instance.inputDevice == InputDevice.MouseKeyboard) { if (onDeselectSlotCallBack != null) onDeselectSlotCallBack(this); } } public virtual void OnPointerClick(PointerEventData eventData) { return; #if UNITY_ANDROID || UNITY_IOS if (vInput.instance.inputDevice == InputDevice.Mobile) #else //if (vInput.instance.inputDevice == InputDevice.MouseKeyboard) #endif { if (eventData.button == PointerEventData.InputButton.Left) { if (isValid) { onClick.Invoke(); if (onSubmitSlotCallBack != null) onSubmitSlotCallBack(this); } } } } #endregion UnityEngine.EventSystems Implementation } }