Files
2026-04-15 14:14:04 +07:00

479 lines
16 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using BrewMonster.Network;
using BrewMonster.Scripts.Pet;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
namespace BrewMonster.UI
{
public class DlgPetRec : AUIDialog
{
public const int PETSLOT_MAX = 20;
[Header("Component")]
[SerializeField] private TextMeshProUGUI m_pTxt_Gold;
[SerializeField] private TextMeshProUGUI m_pTxt_Name;
[SerializeField] private Image m_pImg_Item;
[Header("Pet List")]
[SerializeField] private Button[] m_pBtn_PetSlots = new Button[PETSLOT_MAX];
[Header("Button")]
[SerializeField] private Button m_btnComfirm;
[SerializeField] private Button m_btnCancle;
[SerializeField] private Button m_btnClose;
[Header("Icon Default")]
[SerializeField] private Sprite m_defaultIcon;
private int m_nSlot = -1;
private CECPetData m_pCurrentPet = null;
private CECPetData[] m_petSlots = new CECPetData[PETSLOT_MAX];
private float m_doubleClickTime = 0.3f;
public override void Awake()
{
base.Awake();
RegisterTargetSlotEvents(m_pImg_Item.transform);
for (int i = 0; i < PETSLOT_MAX; i++)
{
if (m_pBtn_PetSlots[i] == null)
continue;
int slotIndex = i; // Capture the current value of i for the lambda
m_pBtn_PetSlots[i].onClick.AddListener(() => OnPetSlotClicked(slotIndex));
}
if (m_btnComfirm != null)
m_btnComfirm.onClick.AddListener(OnCommandConfirm);
if (m_btnCancle != null)
m_btnCancle.onClick.AddListener(OnCommandCancel);
if (m_btnClose != null)
m_btnClose.onClick.AddListener(OnCommandCancel);
}
public override void OnEnable()
{
base.OnEnable();
ClearPet();
LoadPetSlotFromCorral();
UpdatePetSlotUI();
}
public override void Show(bool value)
{
base.Show(value);
if (value)
{
OnShowDialog();
}
}
public override void OnDisable()
{
base.OnDisable();
ClearHighlight();
}
private void RegisterTargetSlotEvents(Transform target)
{
if (target == null)
return;
var image = target.GetComponent<Image>();
if (image != null)
{
image.raycastTarget = true;
}
var trigger = target.GetComponent<EventTrigger>();
if (trigger == null)
trigger = target.gameObject.AddComponent<EventTrigger>();
trigger.triggers.Clear();
var clickEntry = new EventTrigger.Entry { eventID = EventTriggerType.PointerClick };
clickEntry.callback.AddListener((data) => { OnTargetSlotClick((PointerEventData)data); });
trigger.triggers.Add(clickEntry);
var dropEntry = new EventTrigger.Entry { eventID = EventTriggerType.Drop };
dropEntry.callback.AddListener((data) => { OnDropPetToTarget((PointerEventData)data); });
trigger.triggers.Add(dropEntry);
}
private void OnTargetSlotClick(PointerEventData eventData)
{
// Single click - clear the pet and return to slot
if (m_pCurrentPet != null && m_nSlot >= 0)
{
BMLogger.Log("DlgPetRec: Single click on target slot - returning pet to slot");
ClearPet();
UpdatePetSlotUI();
}
}
private void OnPetSlotClicked(int slotIndex)
{
var petData = GetPetSlot(slotIndex);
if (petData == null)
{
BMLogger.LogWarning($"DlgPetRec: No pet in slot {slotIndex}");
return;
}
SetPet(slotIndex);
UpdatePetSlotUI();
}
private void OnDropPetToTarget(PointerEventData eventData)
{
// Get the dragged pet slot index from the event
var draggedObject = eventData.pointerDrag;
if (draggedObject == null)
{
BMLogger.LogWarning("DlgPetRec: No dragged object found");
return;
}
// Find which pet slot was dragged
for (int i = 0; i < PETSLOT_MAX; i++)
{
if (m_pBtn_PetSlots[i] != null && m_pBtn_PetSlots[i].gameObject == draggedObject)
{
var petData = GetPetSlot(i);
if (petData == null)
{
BMLogger.LogWarning($"DlgPetRec: No pet in dragged slot {i}");
return;
}
// Check if this pet can be selected
var host = CECGameRun.Instance?.GetHostPlayer();
if (host != null)
{
var petCorral = host.GetPetCorral();
if (petCorral != null)
{
bool isActive = petCorral.GetActivePetIndex() == i;
if (isActive)
{
BMLogger.Log($"DlgPetRec: Cannot select active pet from slot {i}");
return;
}
}
}
BMLogger.Log($"DlgPetRec: Pet from slot {i} dropped to target");
SetPet(i);
UpdatePetSlotUI();
return;
}
}
BMLogger.LogWarning("DlgPetRec: Could not find source pet slot for dragged object");
}
private void OnShowDialog()
{
ClearPet();
LoadPetSlotFromCorral();
}
private void ClearPet()
{
m_pCurrentPet = null;
m_nSlot = -1;
if (m_pTxt_Name != null)
m_pTxt_Name.text = "";
if (m_pTxt_Gold != null)
m_pTxt_Gold.text = "0";
ClearSlotIcon(m_pImg_Item);
UpdatePetSlotUI();
}
private void OnCommandConfirm()
{
if (m_nSlot >= 0)
{
GetHostPlayer().RestorePet(m_nSlot);
LoadPetSlotFromCorral();
ClearPet();
UpdatePetSlotUI();
GetGameUIMan()?.EndNPCService();
//Show(false);
CloseDialogue();
//GetGameUIMan()->m_pDlgPetList->Show(false);
}
}
private void SetPet(int nSlot)
{
var host = CECGameRun.Instance.GetHostPlayer();
if (host == null)
return;
var petCorral = host.GetPetCorral();
if (petCorral == null)
return;
if (petCorral.GetActivePetIndex() == nSlot)
{
//GetGameUIMan()->MessageBox("", GetStringFromTable(820), MB_OK,
// A3DCOLORRGBA(255, 255, 255, 160));
//return;
}
var pDB = ElementDataManProvider.GetElementDataMan();
if (pDB == null)
return;
var petData = petCorral.GetPetData(nSlot);
if (petData != null)
{
DATA_TYPE dataType = DATA_TYPE.DT_INVALID;
var petEssenceData = pDB.get_data_ptr((uint)petData.GetTemplateID(), ID_SPACE.ID_SPACE_ESSENCE, ref dataType);
if (petEssenceData != null && dataType == DATA_TYPE.DT_PET_ESSENCE)
{
var petEssence = (PET_ESSENCE)petEssenceData;
dataType = DATA_TYPE.DT_INVALID;
var eggEssenceData = pDB.get_data_ptr((uint)petData.GetEggID(), ID_SPACE.ID_SPACE_ESSENCE, ref dataType);
if (eggEssenceData != null && dataType == DATA_TYPE.DT_PET_EGG_ESSENCE)
{
var eggEssence = (PET_EGG_ESSENCE)eggEssenceData;
m_pCurrentPet = petData;
m_nSlot = nSlot;
UpdatePetUI(petData, petEssence, eggEssence);
}
else
{
BMLogger.LogError($"DlgPetRec: Failed to get egg essence data for egg ID: {petData.GetEggID()}");
}
}
else
{
BMLogger.LogError($"DlgPetRec: Failed to get pet essence data for template ID: {petData.GetTemplateID()}");
}
}
}
private void UpdatePetUI(CECPetData petData, PET_ESSENCE petEssence, PET_EGG_ESSENCE eggEssence)
{
if (petData == null || eggEssence.id == 0)
{
BMLogger.LogWarning("DlgPetRec: UpdatePetUI - Invalid pet data or egg essence");
return;
}
if (m_pTxt_Name != null)
m_pTxt_Name.text = petData.GetName();
if (m_pTxt_Gold != null)
m_pTxt_Gold.text = eggEssence.money_restored.ToString();
if (m_pImg_Item != null)
{
string iconPath = petEssence.FileIcon;
BMLogger.Log($"DlgPetRec: Loading icon from path: {iconPath}");
var sprite = LoadPetIconSprite(iconPath);
if (sprite != null)
{
BMLogger.Log($"DlgPetRec: Sprite loaded successfully: {sprite.name}");
m_pImg_Item.sprite = sprite;
m_pImg_Item.enabled = true;
m_pImg_Item.color = Color.white;
m_pImg_Item.SetNativeSize();
}
else
{
BMLogger.LogWarning($"DlgPetRec: Failed to load sprite from path: {iconPath}");
ClearSlotIcon(m_pImg_Item);
}
}
}
private void ClearSlotIcon(Image slot)
{
if (slot == null)
return;
slot.sprite = m_defaultIcon;
slot.enabled = m_defaultIcon != null;
}
private Sprite LoadPetIconSprite(string iconPath)
{
if (string.IsNullOrEmpty(iconPath))
return null;
try
{
string fileName = Path.GetFileNameWithoutExtension(iconPath);
if (string.IsNullOrEmpty(fileName))
return null;
fileName = fileName.ToLower();
var gameRun = EC_Game.GetGameRun();
if (gameRun != null && gameRun.GetUIManager() != null)
{
return gameRun.GetUIManager().GetSpriteInListIvtr(fileName);
}
}
catch (Exception ex)
{
BMLogger.LogError($"DlgPetRec: Failed to load pet icon sprite from path: {iconPath}. Exception: {ex}");
}
return null;
}
private void LoadPetSlotFromCorral()
{
Array.Clear(m_petSlots, 0, m_petSlots.Length);
var host = CECGameRun.Instance?.GetHostPlayer();
if (host == null)
return;
var petCorral = host.GetPetCorral();
if (petCorral == null)
return;
for (int i = 0; i < PETSLOT_MAX; i++)
{
m_petSlots[i] = petCorral.GetPetData(i);
}
}
public CECPetData GetPetSlot(int slotIndex)
{
if (slotIndex < 0 || slotIndex >= PETSLOT_MAX)
{
return null;
}
return m_petSlots[slotIndex];
}
private void OnCommandCancel()
{
ClearPet();
GetGameUIMan()?.EndNPCService();
CloseDialogue();
//Show(false);
}
private void OnDestroy()
{
ClearPet();
}
private void UpdatePetSlotUI()
{
var host = CECGameRun.Instance?.GetHostPlayer();
if (host == null)
return;
var petCorral = host.GetPetCorral();
if (petCorral == null)
return;
var pDB = ElementDataManProvider.GetElementDataMan();
if (pDB == null)
return;
for (int i = 0; i < PETSLOT_MAX; i++)
{
if (m_pBtn_PetSlots[i] == null)
continue;
var buttonImage = m_pBtn_PetSlots[i].GetComponent<Image>();
var petData = m_petSlots[i];
if (petData != null)
{
if (buttonImage != null)
{
DATA_TYPE dataType = DATA_TYPE.DT_INVALID;
var petEssenceData = pDB.get_data_ptr((uint)petData.GetTemplateID(), ID_SPACE.ID_SPACE_ESSENCE, ref dataType);
if (petEssenceData != null && dataType == DATA_TYPE.DT_PET_ESSENCE)
{
var petEssence = (PET_ESSENCE)petEssenceData;
string iconPath = petEssence.FileIcon;
var sprite = LoadPetIconSprite(iconPath);
if (sprite != null)
{
buttonImage.sprite = sprite;
buttonImage.enabled = true;
bool isActive = petCorral.GetActivePetIndex() == i;
bool isDead = petData.GetHPFactor() <= 0.0f;
bool isSelected = (m_nSlot == i && m_pCurrentPet != null);
if (isActive || isDead || isSelected)
{
buttonImage.color = Color.gray;
}
else
{
buttonImage.color = Color.white;
}
}
else
{
BMLogger.LogWarning($"DlgPetRec: Failed to load icon for pet slot {i}, iconPath: {iconPath}");
ClearSlotIcon(buttonImage);
}
}
else
{
BMLogger.LogWarning($"DlgPetRec: Failed to get pet essence for slot {i}, templateID: {petData.GetTemplateID()}");
ClearSlotIcon(buttonImage);
}
}
bool isActivePet = petCorral.GetActivePetIndex() == i;
bool isSelectedPet = (m_nSlot == i && m_pCurrentPet != null);
m_pBtn_PetSlots[i].interactable = !isActivePet && !isSelectedPet;
}
else
{
if (buttonImage != null)
{
ClearSlotIcon(buttonImage);
buttonImage.color = Color.white;
}
m_pBtn_PetSlots[i].interactable = true;
}
}
}
private void ClearHighlight()
{
if (m_pBtn_PetSlots == null)
return;
for (int i = 0; i < m_pBtn_PetSlots.Length; i++)
{
if (m_pBtn_PetSlots[i] != null)
{
var image = m_pBtn_PetSlots[i].GetComponent<Image>();
if (image != null)
{
image.color = Color.white;
}
}
}
}
}
}