using System; using System.Collections.Generic; using UnityEngine; namespace Kryz.CharacterStats.Examples { public class EquipmentPanel : MonoBehaviour { [SerializeField] Transform equipmentSlotsParent; [SerializeField] EquipmentSlot[] equipmentSlots; [SerializeField] GameEventListener onJoinedRoom; public UnityEvent_ItemInstance OnItemRightClickedEvent = new UnityEvent_ItemInstance(); EquipmentInstanceData equipmentData = new EquipmentInstanceData(); #region Singleton private static EquipmentPanel _instance; // Public reference to the singleton instance public static EquipmentPanel Instance { get { // If the instance doesn't exist, try to find it in the scene if (_instance == null) { _instance = FindObjectOfType(); } return _instance; } } #endregion private void Awake() { onJoinedRoom.Response.AddListener(LoadEquipment); } private void Start() { for (int i = 0; i < equipmentSlots.Length; i++) { equipmentSlots[i].OnRightClickEvent.AddListener((X) => OnItemRightClickedEvent.Invoke(X)); } } private void OnValidate() { } public EquippableItemInstance GetEquippedItemOnSpecificSlot(EquipmentType slot) { for (int i = 0; i < equipmentSlots.Length; i++) { if (equipmentSlots[i].EquipmentType == slot) { return (EquippableItemInstance)equipmentSlots[i].Item; } } return null; } // NEW: Helper method to get both weapon slots (now they're equivalent) private (EquipmentSlot weaponSlot1, EquipmentSlot weaponSlot2) GetWeaponSlots() { EquipmentSlot weaponSlot1 = null; EquipmentSlot weaponSlot2 = null; for (int i = 0; i < equipmentSlots.Length; i++) { if (equipmentSlots[i].EquipmentType == EquipmentType.Weapon1) weaponSlot1 = equipmentSlots[i]; else if (equipmentSlots[i].EquipmentType == EquipmentType.Weapon2) weaponSlot2 = equipmentSlots[i]; } return (weaponSlot1, weaponSlot2); } /// /// Calculates how many items would be displaced if the given item were equipped /// public int GetDisplacedItemCount(EquippableItemInstance item) { if (!item.IsWeapon) { // Non-weapons: at most 1 item displaced (standard replacement) var existingItem = GetEquippedItemOnSpecificSlot(item.EquipmentType); return (existingItem != null && !string.IsNullOrEmpty(existingItem.ItemName)) ? 1 : 0; } // Handle weapons var (mainHandSlot, offHandSlot) = GetWeaponSlots(); if (mainHandSlot == null || offHandSlot == null) return 0; var currentMainHand = (EquippableItemInstance)mainHandSlot.Item; var currentOffHand = (EquippableItemInstance)offHandSlot.Item; if (item.IsTwoHandedWeapon) { // Two-handed weapon displaces both current weapons int count = 0; if (currentMainHand != null && !string.IsNullOrEmpty(currentMainHand.ItemName)) count++; if (currentOffHand != null && !string.IsNullOrEmpty(currentOffHand.ItemName)) count++; return count; } else // One-handed weapon { if (currentMainHand != null && currentMainHand.IsTwoHandedWeapon) { // Replacing two-handed with one-handed return 1; } else { // Normal one-handed logic if (currentMainHand == null || currentOffHand == null) return 0; // Filling empty slot else return 1; // Will replace main hand } } } // NEW: Helper method to get slot index for saving private int GetSlotIndex(EquipmentSlot slot) { for (int i = 0; i < equipmentSlots.Length; i++) { if (equipmentSlots[i] == slot) return i; } return -1; } // UPDATED: Modified to handle two-handed weapon logic public bool AddItem(EquippableItemInstance item, out EquippableItemInstance previousItem) { return AddItem(item, out previousItem, out _); } // UPDATED: Simplified weapon equipping logic public bool AddItem(EquippableItemInstance item, out EquippableItemInstance previousItem, out EquippableItemInstance secondPreviousItem) { previousItem = null; secondPreviousItem = null; // Handle non-weapon items with original logic if (!item.IsWeapon) { for (int i = 0; i < equipmentSlots.Length; i++) { if (equipmentSlots[i].EquipmentType == item.EquipmentType) { previousItem = (EquippableItemInstance)equipmentSlots[i].Item; equipmentSlots[i].Item = item; equipmentData.equippedItems[i] = item; PlayerDataHandler.Instance.SaveCharacterEquipmentData(PlayerDataHandler.Instance.currentPlayerName.Value, PlayerDataHandler.Instance.currentCharacterName.Value, equipmentData); return true; } } return false; } // Handle weapon items - much simpler now var (weaponSlot1, weaponSlot2) = GetWeaponSlots(); if (weaponSlot1 == null || weaponSlot2 == null) return false; var currentWeapon1 = (EquippableItemInstance)weaponSlot1.Item; var currentWeapon2 = (EquippableItemInstance)weaponSlot2.Item; if (item.IsTwoHandedWeapon) { // Two-handed weapon takes both slots, return any existing weapons previousItem = currentWeapon1; secondPreviousItem = currentWeapon2; // Put two-handed weapon in first slot, clear second slot weaponSlot1.Item = item; weaponSlot2.Item = null; // Update data arrays int weapon1Index = GetSlotIndex(weaponSlot1); int weapon2Index = GetSlotIndex(weaponSlot2); equipmentData.equippedItems[weapon1Index] = item; equipmentData.equippedItems[weapon2Index] = null; PlayerDataHandler.Instance.SaveCharacterEquipmentData(PlayerDataHandler.Instance.currentPlayerName.Value, PlayerDataHandler.Instance.currentCharacterName.Value, equipmentData); return true; } else // One-handed weapon { // Check if currently have a two-handed weapon if (currentWeapon1 != null && currentWeapon1.IsTwoHandedWeapon) { // Replace two-handed weapon with one-handed in slot 1 previousItem = currentWeapon1; weaponSlot1.Item = item; int weapon1Index = GetSlotIndex(weaponSlot1); equipmentData.equippedItems[weapon1Index] = item; } else { // Normal one-handed weapon logic - fill first available slot if (currentWeapon1 == null) { // Fill slot 1 weaponSlot1.Item = item; int weapon1Index = GetSlotIndex(weaponSlot1); equipmentData.equippedItems[weapon1Index] = item; } else if (currentWeapon2 == null) { // Fill slot 2 (dual wielding) weaponSlot2.Item = item; int weapon2Index = GetSlotIndex(weaponSlot2); equipmentData.equippedItems[weapon2Index] = item; } else { // Both slots full, replace slot 1 previousItem = currentWeapon1; weaponSlot1.Item = item; int weapon1Index = GetSlotIndex(weaponSlot1); equipmentData.equippedItems[weapon1Index] = item; } } PlayerDataHandler.Instance.SaveCharacterEquipmentData(PlayerDataHandler.Instance.currentPlayerName.Value, PlayerDataHandler.Instance.currentCharacterName.Value, equipmentData); return true; } } public bool RemoveItem(EquippableItemInstance item) { for (int i = 0; i < equipmentSlots.Length; i++) { if (equipmentSlots[i].Item == item) { equipmentSlots[i].Item = null; equipmentData.equippedItems[i] = null; PlayerDataHandler.Instance.SaveCharacterEquipmentData(PlayerDataHandler.Instance.currentPlayerName.Value, PlayerDataHandler.Instance.currentCharacterName.Value, equipmentData); return true; } } return false; } public EquipmentSlot[] GetCurrentSlots() { return equipmentSlots; } public void LoadEquipment() { equipmentData = PlayerDataHandler.Instance.LoadCharacterEquipmentData(PlayerDataHandler.Instance.currentPlayerName.Value, PlayerDataHandler.Instance.currentCharacterName.Value); if (equipmentData != null) { Debug.Log("Success Loading Equipment"); for (int i = 0; i < equipmentData.equippedItems.Length; i++) { if (equipmentData.equippedItems[i] == null || string.IsNullOrEmpty(equipmentData.equippedItems[i].ItemName)) { equipmentSlots[i].Item = null; } else { if (equipmentData.equippedItems[i].templateIndex >= 0) equipmentData.equippedItems[i].Icon = ItemIndexer.Instance.Items[equipmentData.equippedItems[i].templateIndex].Icon; else equipmentData.equippedItems[i].Icon = Resources.Load(equipmentData.equippedItems[i].IconPath); equipmentSlots[i].Item = equipmentData.equippedItems[i]; } } } else { for (int i = 0; i < equipmentSlots.Length; i++) { equipmentSlots[i].Item = null; } equipmentData = new EquipmentInstanceData(); PlayerDataHandler.Instance.SaveCharacterEquipmentData(PlayerDataHandler.Instance.currentPlayerName.Value, PlayerDataHandler.Instance.currentCharacterName.Value, equipmentData); } } } }