Files
test/Assets/PerfectWorld/Scripts/UI/Dialogs/DlgPetHatch.cs
T
2026-02-26 20:22:07 +07:00

575 lines
17 KiB
C#

using BrewMonster.Assets.PerfectWorld.Scripts.UI;
using BrewMonster.Common;
using BrewMonster.Managers;
using BrewMonster.Scripts;
using BrewMonster.Scripts.Managers;
using CSNetwork.GPDataType;
using Cysharp.Threading.Tasks.Triggers;
using PerfectWorld.Scripts.Managers;
using System;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using static BrewMonster.Scripts.Managers.EC_Inventory;
namespace BrewMonster.UI
{
public class DlgPetHatch : AUIDialog
{
[Header("Component")]
[SerializeField] private TextMeshProUGUI m_pTxtName;
[SerializeField] private TextMeshProUGUI m_pTxtGold;
[SerializeField] private Image m_pImg_Item;
[SerializeField] private GameObject m_pTxtBindTip;
[Header("Buttons")]
[SerializeField] private Button m_btnConfirm;
[SerializeField] private Button m_btnCancel;
[SerializeField] private Button m_btnClose;
[Header("Defautl Icon")]
[SerializeField] private Sprite m_defaultIcon;
private int m_nSlot = 1;
private EC_IvtrPetEgg m_pCurrentEgg = null;
private float m_doubleClickTime = 1f;
private Dictionary<int, float> m_lastClickTime = new Dictionary<int, float>();
public override void Awake()
{
base.Awake();
RegisterDrop(m_pImg_Item.transform, OnDropEgg);
RegisterClick(m_pImg_Item.transform, OnClickEggSlot);
if (m_btnConfirm != null)
m_btnConfirm.onClick.AddListener(OnCommandConfirm);
if (m_btnCancel != null)
m_btnCancel.onClick.AddListener(OnCommandCancel);
if (m_btnClose != null)
m_btnClose.onClick.AddListener(OnCommandCancel);
}
public override void OnEnable()
{
base.OnEnable();
ClearEgg();
RegisterInventoryDoubleClick();
}
public override void OnDisable()
{
base.OnDisable();
RestoreInventoryColor();
UnregisterInventoryDoubleClick();
}
public override void Show(bool value)
{
base.Show(value);
if (value)
{
OnShowDialog();
}
}
private void OnShowDialog()
{
ClearEgg();
}
#region Double-Click Support
private void RegisterInventoryDoubleClick()
{
var inventoryUI = FindFirstObjectByType<EC_InventoryUI>();
if (inventoryUI == null)
{
return;
}
var field = typeof(EC_InventoryUI)
.GetField("inventoryPackButtons", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
if (field == null)
{
return;
}
var buttons = field.GetValue(inventoryUI) as List<Button>;
if (buttons == null || buttons.Count == 0)
{
return;
}
for (int i = 0; i < buttons.Count; i++)
{
if (buttons[i] != null)
{
RegisterDoubleClickOnButton(buttons[i], i);
}
}
}
private void UnregisterInventoryDoubleClick()
{
var inventoryUI = FindFirstObjectByType<EC_InventoryUI>();
if(inventoryUI == null)
{
return;
}
var field = typeof(EC_InventoryUI)
.GetField("inventoryPackButtons", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
if (field == null)
return;
var buttons = field.GetValue(inventoryUI) as List<Button>;
if (buttons == null)
return;
foreach (var btn in buttons)
{
if (btn != null)
{
var trigger = btn.GetComponent<EventTrigger>();
if (trigger != null)
{
trigger.triggers.RemoveAll(e =>
e.eventID == EventTriggerType.PointerClick &&
e.callback.GetPersistentEventCount() > 0);
}
}
}
}
private void RegisterDoubleClickOnButton(Button button, int slotIndex)
{
if (button == null)
return;
var trigger = button.GetComponent<EventTrigger>();
if (trigger == null)
trigger = button.gameObject.AddComponent<EventTrigger>();
var entry = new EventTrigger.Entry
{
eventID = EventTriggerType.PointerClick
};
entry.callback.AddListener((data) =>
{
OnInventoryButtonClick(slotIndex, (PointerEventData)data);
});
trigger.triggers.Add(entry);
}
private void OnInventoryButtonClick(int slotIndex, PointerEventData eventData)
{
float currentTime = Time.unscaledTime;
if (m_lastClickTime.ContainsKey(slotIndex))
{
float timeSinceLastClick = currentTime - m_lastClickTime[slotIndex];
if (timeSinceLastClick <= m_doubleClickTime)
{
OnInventoryItemDoubleClick(slotIndex);
m_lastClickTime.Remove(slotIndex);
return;
}
}
m_lastClickTime[slotIndex] = currentTime;
}
private void OnInventoryItemDoubleClick(int slotIndex)
{
var host = CECGameRun.Instance?.GetHostPlayer();
if (host == null)
{
return;
}
var inv = host.GetInventory(0);
if (inv == null)
{
return;
}
var item = inv.GetItem(slotIndex, false);
if (item == null)
{
return;
}
if (item.GetClassID() != (int)EC_IvtrItem.InventoryClassId.ICID_PETEGG)
{
return;
}
EC_IvtrItem detailedItem = EC_IvtrItem.CreateItem(item.m_tid, item.m_expire_date, item.m_iCount);
if (item.Content != null && item.Content.Length > 0)
{
detailedItem.SetItemInfo(item.Content, item.Content.Length);
}
else
{
detailedItem.GetDetailDataFromLocal();
}
EC_IvtrPetEgg petEgg = detailedItem as EC_IvtrPetEgg;
if (petEgg == null)
{
return;
}
SetEggInternal(petEgg, slotIndex);
}
private void SetEggInternal(EC_IvtrPetEgg petEgg, int slotIndex)
{
if(petEgg == null)
return;
if (m_nSlot >= 0)
{
var previousBtn = FindInventoryButtonBySlot(m_nSlot);
SetInventorySlotGray(previousBtn, false);
}
if(m_pCurrentEgg != null)
m_pCurrentEgg.Freeze(false);
m_pCurrentEgg = petEgg;
m_nSlot = slotIndex;
petEgg.Freeze(true);
UpdateEggUI(petEgg);
var btn = FindInventoryButtonBySlot(slotIndex);
SetInventorySlotGray(btn, true);
}
#endregion
private void RegisterDrop(Transform target, Action<PointerEventData> callback)
{
if (target == null)
return;
var trigger = target.GetComponent<EventTrigger>();
if(trigger == null)
trigger = target.gameObject.AddComponent<EventTrigger>();
var existingDrop = trigger.triggers.Find(e => e.eventID == EventTriggerType.Drop);
if(existingDrop != null)
trigger.triggers.Remove(existingDrop);
var entry = new EventTrigger.Entry
{
eventID = EventTriggerType.Drop
};
entry.callback.AddListener((data) => { callback((PointerEventData)data); });
trigger.triggers.Add(entry);
}
private void RegisterClick(Transform target, Action<PointerEventData> callback)
{
if (target == null)
return;
var trigger = target.GetComponent<EventTrigger>();
if (trigger == null)
trigger = target.gameObject.AddComponent<EventTrigger>();
var existingClick = trigger.triggers.Find(e => e.eventID == EventTriggerType.PointerClick);
if (existingClick != null)
trigger.triggers.Remove(existingClick);
var entry = new EventTrigger.Entry
{
eventID = EventTriggerType.PointerClick
};
entry.callback.AddListener((data) => { callback((PointerEventData)data); });
trigger.triggers.Add(entry);
}
private void OnClickEggSlot(PointerEventData eventData)
{
if (m_pCurrentEgg != null)
{
ReturnItemToInventory(m_nSlot);
ClearEgg();
}
}
private void OnDropEgg(PointerEventData eventData)
{
if (eventData.pointerDrag == null)
return;
var btn = eventData.pointerDrag.GetComponent<Button>();
if(btn == null)
return;
int slotIndex = btn.transform.GetSiblingIndex();
var item = GetItemFromDrag(eventData);
if (item == null)
return;
if(item.GetClassID() != (int)EC_IvtrItem.InventoryClassId.ICID_PETEGG)
{
return;
}
EC_IvtrItem detailedItem = EC_IvtrItem.CreateItem(item.m_tid, item.m_expire_date, item.m_iCount);
if(item.Content != null && item.Content.Length > 0)
{
detailedItem.SetItemInfo(item.Content, item.Content.Length);
}
else
{
detailedItem.GetDetailDataFromLocal();
}
//EC_IvtrPetEgg petEgg = detailedItem as EC_IvtrPetEgg;
EC_IvtrPetEgg petEgg = item as EC_IvtrPetEgg;
if(petEgg == null)
{
return;
}
if (m_nSlot >= 0)
{
var previosBtn = FindInventoryButtonBySlot(m_nSlot);
SetInventorySlotGray(previosBtn, false);
}
if(m_pCurrentEgg != null)
m_pCurrentEgg.Freeze(false);
m_pCurrentEgg = petEgg;
m_nSlot = slotIndex;
SetDataPtr(petEgg, "");
petEgg.Freeze(true);
UpdateEggUI(petEgg);
SetInventorySlotGray(btn, true);
}
private EC_IvtrItem GetItemFromDrag(PointerEventData eventData)
{
if (eventData.pointerDrag == null)
return null;
var btn = eventData.pointerDrag.GetComponent<Button>();
if(btn == null)
return null;
int slotIndex = btn.transform.GetSiblingIndex();
var host = CECGameRun.Instance?.GetHostPlayer();
if(host == null)
return null;
var inv = host.GetInventory(0);
if (inv == null)
return null;
return inv.GetItem(slotIndex, false);
}
private Button FindInventoryButtonBySlot(int slot)
{
var inventoryUI = FindFirstObjectByType<EC_InventoryUI>();
if(inventoryUI == null)
return null;
var field = typeof(EC_InventoryUI)
.GetField("inventoryPackButtons", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
if(field == null)
return null;
var list = field.GetValue(inventoryUI) as System.Collections.Generic.List<Button>;
if(list == null || slot < 0 || slot >= list.Count)
return null;
return list[slot];
}
private void SetInventorySlotGray(Button btn, bool gray)
{
if (btn == null)
return;
var img = btn.GetComponent<Image>();
if (img == null)
return;
img.color = gray ? Color.gray : Color.white;
}
private void SetSlotIcon(Image slot, EC_IvtrItem item)
{
if (slot == null || item == null)
{
BMLogger.LogWarning("DlgPetHatch: SetSlotIcon - slot or item is null");
return;
}
var sprite = EC_IvtrItemUtils.Instance.ResolveItemIconSprite(item.m_tid);
if (sprite == null)
{
BMLogger.LogWarning($"DlgPetHatch: No sprite found for item tid: {item.m_tid}");
return;
}
BMLogger.Log($"DlgPetHatch: Setting icon for {item.GetName()}");
slot.sprite = sprite;
slot.enabled = true;
slot.color = Color.white;
slot.SetNativeSize();
}
private void ClearSlotIcon(Image slot)
{
if (slot == null)
return;
slot.sprite = m_defaultIcon;
slot.enabled = m_defaultIcon != null;
}
private void ReturnItemToInventory(int slotIndex)
{
if (slotIndex < 0)
return;
var btn = FindInventoryButtonBySlot(slotIndex);
SetInventorySlotGray(btn, false);
}
private void RestoreInventoryColor()
{
if (m_nSlot >= 0)
{
var btn = FindInventoryButtonBySlot(m_nSlot);
SetInventorySlotGray(btn, false);
}
}
private void UpdateEggUI(EC_IvtrPetEgg pEgg)
{
if(pEgg == null)
return;
if (m_pTxtBindTip != null)
{
bool isBound = (pEgg.GetProcType() & (int)EC_IvtrItem.ProcType.PROC_BIND) != 0;
m_pTxtBindTip.SetActive(isBound);
if (isBound)
{
BMLogger.Log("DlgPetHatch: Pet egg is bound - displaying warning");
}
}
if(m_pTxtName != null)
{
m_pTxtName.text = pEgg.GetName();
}
if (m_pTxtGold != null)
{
try
{
var essence = pEgg.GetDBEssence();
if (essence.id != 0)
{
m_pTxtGold.SetText(essence.money_hatched.ToString());
}
else
{
m_pTxtGold.SetText("0");
}
}
catch (Exception ex)
{
BMLogger.LogError($"DlgPetHatch: Failed to get essence data for pet egg - {ex.Message}");
m_pTxtGold.SetText("0");
}
}
SetSlotIcon(m_pImg_Item, pEgg);
}
private void ClearEgg()
{
if(m_pTxtBindTip != null)
m_pTxtBindTip.SetActive(false);
if (m_pCurrentEgg != null)
{
m_pCurrentEgg.Freeze(false);
m_pCurrentEgg = null;
}
ClearSlotIcon(m_pImg_Item);
if (m_pTxtName != null)
m_pTxtName.text = "___";
if(m_pTxtGold != null)
m_pTxtGold.text = "0";
m_nSlot = -1;
}
private void OnCommandConfirm()
{
EC_IvtrItem pItem = (EC_IvtrItem)(GetDataPtr(""));
if (pItem != null)
{
pItem.Freeze(false);
GetHostPlayer().HatchPet(m_nSlot);
Debug.LogError("m_nSlot = " + m_nSlot);
SetDataPtr(null, "");
GetGameUIMan().EndNPCService();
Show(false);
GetGameUIMan().GetDialog("Win_Inventory").Show(false);
GetHostPlayer().GetPack(Inventory_type.IVTRTYPE_PACK).UnfreezeAllItems();
}
}
private void OnCommandCancel()
{
ClearEgg();
GetGameUIMan().EndNPCService();
Show(false);
GetHostPlayer().GetPack(Inventory_type.IVTRTYPE_PACK).UnfreezeAllItems();
}
public void SetEgg(EC_IvtrItem pItem, int nSlot)
{
if (pItem == null || !(pItem is EC_IvtrPetEgg))
return;
ClearEgg();
EC_IvtrPetEgg petEgg = (EC_IvtrPetEgg)pItem;
m_pCurrentEgg = petEgg;
m_nSlot = nSlot;
petEgg.Freeze(true);
UpdateEggUI(petEgg);
var btn = FindInventoryButtonBySlot(nSlot);
SetInventorySlotGray(btn, true);
}
private void OnDestroy()
{
ClearEgg();
RestoreInventoryColor();
}
}
}