using Invector; using Invector.vItemManager; 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 { [Header("Dependencies")] public bInventory inventory; [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, checkIconBG, checkIcon, isSelectedIcon; public TMP_Text displayNameText; public Text displayTypeText; public TMP_Text displayAmountText; public Text displayDescriptionText, displayAttributesText; public GameObject notSeenMark; public bool IsClickable = true; private bool m_isClickable = true; [SerializeField] public bool Clickable { set { m_isClickable = value; if(m_canvasGroup) { 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, onChangeType, onChangeAmount, onChangeDescription, onChangeAttributes; public List customAttributeDisplay; [System.Serializable] public class AttributeDisplay { public Invector.vItemManager.vItemAttributes name; public string displayFormat = "(VALUE)"; public Text text; public InputField.OnChangeEvent onChangeDisplay; } public ItemSlotEvent onSubmitSlotCallBack, onSelectSlotCallBack, onDeselectSlotCallBack; public OnHandleItemEvent onAddItem, onRemoveItem; public UnityEvent onEnable, onDisable, onClick; protected Selectable selectable; // --- Static Colors (Restored) --- 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() => defaultTextColor; public static Color GetSelectedButtonTextColor() => selectedTextColor; public static Color GetDeselectedImageColor() => deselectedImageColor; public static Color GetSelectedImageColor() => selectedImageColor; // --- Explicit Inventory Setter --- public void SetInventory(bInventory newInventory) { if (this.inventory != null) this.inventory.OnUpdateInventory -= UpdateDisplays; this.inventory = newInventory; if (this.inventory != null) this.inventory.OnUpdateInventory += UpdateDisplays; UpdateDisplays(); } protected virtual void Start() { if (inventory == null) { var equipArea = GetComponentInParent(); if (equipArea != null) inventory = equipArea.inventory; if (inventory == null && Player.Instance != null && Player.Instance.ItemManager != null) inventory = Player.Instance.ItemManager.inventory; } if (inventory) inventory.OnUpdateInventory += UpdateDisplays; selectable = GetComponent(); if (!m_canvasGroup) m_canvasGroup = GetComponent(); SetValid(isValid); } private void OnEnable() { onEnable.Invoke(); UpdateDisplays(item); } private void OnDisable() { onDisable.Invoke(); UnloadCurrentImage(); } private void UnloadCurrentImage() { if (icon && icon.sprite) Resources.UnloadAsset(icon.sprite); if (secondaryIcon && secondaryIcon.sprite) Resources.UnloadAsset(secondaryIcon.sprite); if (teriaryIcon && teriaryIcon.sprite) Resources.UnloadAsset(teriaryIcon.sprite); } public virtual void UpdateDisplays() => UpdateDisplays(item); private void OnDestroy() { if (inventory) inventory.OnUpdateInventory -= UpdateDisplays; } // ... Existing Methods ... public virtual void CheckItem(bool value) { if (item && item.type == bItemType.PowerScroll && item.canBeDroped) isChecked = true; else if (checkIcon && item) { isChecked = value; checkIcon.color = item.checkColor; checkIcon.gameObject.SetActive(isChecked); } } public void TryToMarkAsSpeciallEquipped() { if (checkIcon) { checkIcon.gameObject.SetActive(true); checkIcon.color = Color.gray; } } public virtual void SetValid(bool value) { isValid = value; if (selectable) selectable.interactable = value; if (blockIcon) { blockIcon.color = value ? Color.clear : Color.white; blockIcon.SetAllDirty(); } } public virtual void AddItem(bItem item) { if (item != null) { this.item = item; onAddItem.Invoke(item); // --- FIX: Force display update immediately --- 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) notSeenMark.SetActive(!NewItemPopupSaver.itemsSeen.Contains(itemId)); } private void TryToSetRarityIcon(bItem item) { if (item && rarityInterestedType.Contains(item.type) && rarityImage) { rarityImage.gameObject.SetActive(true); bItemAttribute rarityAttribute = item.GetItemAttribute(bItemAttributes.Rarity); rarityImage.sprite = (rarityAttribute != null && rarityAttribute.value < raritySprites.Count) ? raritySprites[rarityAttribute.value] : raritySprites[0]; } } protected virtual void ChangeDisplayType(bItem item) { string txt = item ? item.ItemTypeText() : ""; onChangeType.Invoke(txt); if (displayTypeText) displayTypeText.text = txt; } protected virtual void ChangeDisplayAttributes(bItem item) { string txt = item ? item.GetItemAttributesText(ignoreAttributes) : ""; if (displayAttributesText) displayAttributesText.text = txt; onChangeAttributes.Invoke(txt); if(item && customAttributeDisplay != null) { foreach(var attr in item.attributes) { var display = customAttributeDisplay.Find(a => a.name.Equals(attr.name)); if(display != null) { string val = attr.GetDisplayText(); if(display.text) display.text.text = val; display.onChangeDisplay.Invoke(val); } } } } protected virtual void ChangeDisplayIcon(bItem item) { if (!item || !icon) return; if (item.icon != null) icon.sprite = item.icon; else if (!string.IsNullOrEmpty(item.iconPath)) icon.sprite = Resources.Load(item.iconPath); } 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); } protected virtual void ChangeDisplayDescription(bItem item) { string txt = item ? item.description : ""; onChangeDescription.Invoke(txt); if (displayDescriptionText) displayDescriptionText.text = txt; } protected virtual void ChangeDisplayAmount(bItem item) { string txt = (item != null && item.stackable && item.amount > 1) ? " " + item.amount.ToString() : ""; if (displayAmountText) displayAmountText.text = txt; onChangeAmount.Invoke(txt); } protected virtual void ChangeDisplayName(bItem item) { string txt = item ? item.name : ""; onChangeName.Invoke(txt); if (displayNameText) displayNameText.text = txt; } public virtual void RemoveItem() { this.item = null; onRemoveItem.Invoke(item); if (icon) { icon.sprite = null; icon.SetAllDirty(); } UpdateDisplays(null); } public virtual bool isOcupad() => item != null; public virtual void OnSelect(BaseEventData eventData) => onSelectSlotCallBack?.Invoke(this); public virtual void OnDeselect(BaseEventData eventData) => onDeselectSlotCallBack?.Invoke(this); public void MarkSlotAsSelected() { if (displayNameText) displayNameText.color = GetSelectedButtonTextColor(); if (item && !NewItemPopupSaver.itemsSeen.Contains(item.id)) { NewItemPopupSaver.itemsSeen.Add(item.id); SetNotSeenIcon(item.id); } if (isSelectedIcon) isSelectedIcon.enabled = true; else SetIconColor(GetSelectedImageColor()); } public void MarkSlotAsDeselected() { if (displayNameText) displayNameText.color = GetDefaultButtonTextColor(); if (isSelectedIcon) isSelectedIcon.enabled = false; else SetIconColor(GetDeselectedImageColor()); } private void SetIconColor(Color c) { if (icon) icon.color = c; if (secondaryIcon) secondaryIcon.color = c; if (teriaryIcon) teriaryIcon.color = c; if (rarityImage) rarityImage.color = c; } public virtual void OnSubmit(BaseEventData eventData) { if (isValid) { onClick.Invoke(); onSubmitSlotCallBack?.Invoke(this); } CheckItem(item != null && item.isInEquipArea); } public virtual void OnPointerEnter(PointerEventData eventData) { EventSystem.current.SetSelectedGameObject(gameObject); onSelectSlotCallBack?.Invoke(this); if (IsClickable != Clickable) Clickable = IsClickable; } public virtual void OnPointerExit(PointerEventData eventData) => onDeselectSlotCallBack?.Invoke(this); public virtual void OnPointerClick(PointerEventData eventData) { if (eventData.button == PointerEventData.InputButton.Left && isValid) { onClick.Invoke(); onSubmitSlotCallBack?.Invoke(this); } } } }