Many changes to Invector inventory system, added WIP UI system, added implementation for max stamina, moving speed, attack speed, attack power, thorns

This commit is contained in:
2025-12-05 15:10:52 +01:00
parent 53fa05e246
commit af7706bfac
21 changed files with 2352 additions and 3868 deletions

View File

@@ -1,8 +1,5 @@
using Invector;
using Invector.vCharacterController;
using Invector.vItemManager;
using Sirenix.OdinInspector;
using System;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
@@ -17,33 +14,24 @@ namespace Beyond
[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;
[SerializeField] private CanvasGroup m_canvasGroup;
public bItem item;
public bool isValid = true;
[HideInInspector]
public bool isChecked;
[HideInInspector] public bool isChecked;
public List<bItemType> rarityInterestedType = new List<bItemType> { 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 Image blockIcon, checkIconBG, checkIcon, isSelectedIcon;
public TMP_Text displayNameText;
public Text displayTypeText;
public TMP_Text displayAmountText;
public Text displayDescriptionText;
public Text displayAttributesText;
public Text displayDescriptionText, displayAttributesText;
public GameObject notSeenMark;
public bool IsClickable = true;
@@ -53,74 +41,72 @@ namespace Beyond
{
set {
m_isClickable = value;
m_canvasGroup.alpha = m_isClickable ? 1f : 0.5f;
m_canvasGroup.blocksRaycasts = m_isClickable;
if(m_canvasGroup) {
m_canvasGroup.alpha = m_isClickable ? 1f : 0.5f;
m_canvasGroup.blocksRaycasts = m_isClickable;
}
}
get => m_isClickable;
}
[SerializeField]
public List<Sprite> raritySprites;
[SerializeField] public List<Sprite> raritySprites;
[vHelpBox("You can ignore display Attributes using this property")]
public List<bItemAttributes> ignoreAttributes;
[vEditorToolbar("Events")]
public InputField.OnChangeEvent onChangeName;
public InputField.OnChangeEvent onChangeType;
public InputField.OnChangeEvent onChangeAmount;
public InputField.OnChangeEvent onChangeDescription;
public InputField.OnChangeEvent onChangeAttributes;
public InputField.OnChangeEvent onChangeName, onChangeType, onChangeAmount, onChangeDescription, onChangeAttributes;
public List<AttributeDisplay> 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;
public UnityEvent onEnable, onDisable, onClick;
protected Selectable selectable;
protected Color color = Color.white;
// --- 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()
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)
{
return defaultTextColor;
if (this.inventory != null) this.inventory.OnUpdateInventory -= UpdateDisplays;
this.inventory = newInventory;
if (this.inventory != null) this.inventory.OnUpdateInventory += UpdateDisplays;
UpdateDisplays();
}
public static Color GetSelectedButtonTextColor()
protected virtual void Start()
{
return selectedTextColor;
}
if (inventory == null)
{
var equipArea = GetComponentInParent<bEquipArea>();
if (equipArea != null) inventory = equipArea.inventory;
if (inventory == null && Player.Instance != null && Player.Instance.ItemManager != null)
inventory = Player.Instance.ItemManager.inventory;
}
public static Color GetDeselectedImageColor()
{
return deselectedImageColor;
}
if (inventory) inventory.OnUpdateInventory += UpdateDisplays;
public static Color GetSelectedImageColor()
{
return selectedImageColor;
selectable = GetComponent<Selectable>();
if (!m_canvasGroup) m_canvasGroup = GetComponent<CanvasGroup>();
SetValid(isValid);
}
private void OnEnable()
@@ -132,77 +118,28 @@ namespace Beyond
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();
if (icon && icon.sprite) Resources.UnloadAsset(icon.sprite);
if (secondaryIcon && secondaryIcon.sprite) Resources.UnloadAsset(secondaryIcon.sprite);
if (teriaryIcon && teriaryIcon.sprite) Resources.UnloadAsset(teriaryIcon.sprite);
}
protected virtual void Start()
{
var inventory = GetComponentInParent<bInventory>();
if (inventory)
inventory.OnUpdateInventory += UpdateDisplays;
selectable = GetComponent<Selectable>();
if (!m_canvasGroup)
m_canvasGroup = GetComponent<CanvasGroup>();
SetValid(isValid);
}
/// <summary>
/// Update all slot display texts
/// </summary>
public virtual void UpdateDisplays()
{
UpdateDisplays(item);
}
public virtual void UpdateDisplays() => UpdateDisplays(item);
private void OnDestroy()
{
var inventory = GetComponentInParent<bInventory>();
if (inventory)
inventory.OnUpdateInventory -= UpdateDisplays;
if (inventory) inventory.OnUpdateInventory -= UpdateDisplays;
}
/// <summary>
/// Enable or disable checkIcon
/// </summary>
/// <param name="value">Enable or disable value</param>
// ... Existing Methods ...
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;
}
if (item && item.type == bItemType.PowerScroll && item.canBeDroped) isChecked = true;
else if (checkIcon && item)
{
isChecked = value;
@@ -213,40 +150,25 @@ namespace Beyond
public void TryToMarkAsSpeciallEquipped()
{
if (!checkIcon)
{
return;
}
checkIcon.gameObject.SetActive(true);
checkIcon.color = Color.gray;
if (checkIcon) { checkIcon.gameObject.SetActive(true); checkIcon.color = Color.gray; }
}
/// <summary>
/// Set if the slot is Selectable or not
/// </summary>
/// <param name="value">Enable or disable value</param>
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;
if (blockIcon) { blockIcon.color = value ? Color.clear : Color.white; blockIcon.SetAllDirty(); }
}
/// <summary>
/// Add item to slot
/// </summary>
/// <param name="item">target item</param>
public virtual void AddItem(bItem item)
{
if (item != null)
{
this.item = item;
onAddItem.Invoke(item);
// UpdateDisplays(item);
// --- FIX: Force display update immediately ---
UpdateDisplays(item);
// ---------------------------------------------
}
else RemoveItem();
}
@@ -262,26 +184,12 @@ namespace Beyond
ChangeDisplayAttributes(item);
CheckItem(item != null && item.isInEquipArea);
TryToSetRarityIcon(item);
if (item)
{
SetNotSeenIcon(item.id);
}
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);
}
if (notSeenMark) notSeenMark.SetActive(!NewItemPopupSaver.itemsSeen.Contains(itemId));
}
private void TryToSetRarityIcon(bItem item)
@@ -290,314 +198,127 @@ namespace Beyond
{
rarityImage.gameObject.SetActive(true);
bItemAttribute rarityAttribute = item.GetItemAttribute(bItemAttributes.Rarity);
if (rarityAttribute != null)
{
rarityImage.sprite = raritySprites[rarityAttribute.value];
}
else
{
rarityImage.sprite = raritySprites[0];
}
rarityImage.sprite = (rarityAttribute != null && rarityAttribute.value < raritySprites.Count) ? raritySprites[rarityAttribute.value] : raritySprites[0];
}
}
/// <summary>
/// Update the Display type text
/// </summary>
/// <param name="item">target item</param>
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 = "";
}
string txt = item ? item.ItemTypeText() : "";
onChangeType.Invoke(txt);
if (displayTypeText) displayTypeText.text = txt;
}
/// <summary>
/// Update the Display attribute text
/// </summary>
/// <param name="item"></param>
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);
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);
}
}
}
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("");
}
}
}
/// <summary>
/// Update the Display item Icon image
/// </summary>
/// <param name="item"></param>
protected virtual void ChangeDisplayIcon(bItem item)
{
if (!item) return;
if (icon)
{
icon.sprite = Resources.Load<Sprite>(item.iconPath);
// color.a = 1;
// icon.color = color;
}
if (!item || !icon) return;
if (item.icon != null) icon.sprite = item.icon;
else if (!string.IsNullOrEmpty(item.iconPath)) icon.sprite = Resources.Load<Sprite>(item.iconPath);
}
public void ChangeAdditionalDisplayIcons(bItem item)
{
if (!item) return;
if (secondaryIcon && item.secondaryIconPath.Length > 1)
{
secondaryIcon.sprite = Resources.Load<Sprite>(item.secondaryIconPath);
}
if (teriaryIcon && item.teriaryIconPath.Length > 1)
{
teriaryIcon.sprite = Resources.Load<Sprite>(item.teriaryIconPath);
}
if (secondaryIcon && item.secondaryIconPath.Length > 1) secondaryIcon.sprite = Resources.Load<Sprite>(item.secondaryIconPath);
if (teriaryIcon && item.teriaryIconPath.Length > 1) teriaryIcon.sprite = Resources.Load<Sprite>(item.teriaryIconPath);
}
/// <summary>
/// Update the Display Description text
/// </summary>
/// <param name="item"></param>
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 = "";
}
string txt = item ? item.description : "";
onChangeDescription.Invoke(txt);
if (displayDescriptionText) displayDescriptionText.text = txt;
}
/// <summary>
/// Update the Display Amount text
/// </summary>
/// <param name="item"></param>
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);
string txt = (item != null && item.stackable && item.amount > 1) ? " " + item.amount.ToString() : "";
if (displayAmountText) displayAmountText.text = txt;
onChangeAmount.Invoke(txt);
}
/// <summary>
/// Update the Display item Name text
/// </summary>
/// <param name="item"></param>
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 = "";
}
string txt = item ? item.name : "";
onChangeName.Invoke(txt);
if (displayNameText) displayNameText.text = txt;
}
/// <summary>
/// Remove current item from the slot
/// </summary>
public virtual void RemoveItem()
{
this.item = null;
onRemoveItem.Invoke(item);
if (icon)
{
// color.a = 0;
//icon.color = color;
icon.sprite = null;
icon.SetAllDirty();
}
if (icon) { icon.sprite = null; icon.SetAllDirty(); }
UpdateDisplays(null);
}
/// <summary>
/// Check if slot has an item
/// </summary>
/// <returns></returns>
public virtual bool isOcupad()
{
return item != null;
}
public virtual bool isOcupad() => item != null;
#region UnityEngine.EventSystems Implementation
public virtual void OnSelect(BaseEventData eventData)
{
// isSelectedIcon.enabled = true;
if (onSelectSlotCallBack != null)
onSelectSlotCallBack(this);
}
public virtual void OnSelect(BaseEventData eventData) => onSelectSlotCallBack?.Invoke(this);
public virtual void OnDeselect(BaseEventData eventData) => onDeselectSlotCallBack?.Invoke(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;
}
}
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()
{
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;
}
}
if (displayNameText) displayNameText.color = GetDefaultButtonTextColor();
if (isSelectedIcon) isSelectedIcon.enabled = false;
else SetIconColor(GetDeselectedImageColor());
}
public virtual void OnDeselect(BaseEventData eventData)
private void SetIconColor(Color c)
{
// isSelectedIcon.enabled = false;
if (onDeselectSlotCallBack != null)
onDeselectSlotCallBack(this);
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();
if (onSubmitSlotCallBack != null)
onSubmitSlotCallBack(this);
}
if (isValid) { onClick.Invoke(); onSubmitSlotCallBack?.Invoke(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;
}
EventSystem.current.SetSelectedGameObject(gameObject);
onSelectSlotCallBack?.Invoke(this);
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 OnPointerExit(PointerEventData eventData) => onDeselectSlotCallBack?.Invoke(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 && isValid)
{
if (eventData.button == PointerEventData.InputButton.Left)
{
if (isValid)
{
onClick.Invoke();
if (onSubmitSlotCallBack != null)
onSubmitSlotCallBack(this);
}
}
onClick.Invoke();
onSubmitSlotCallBack?.Invoke(this);
}
}
#endregion UnityEngine.EventSystems Implementation
}
}