Files
test/Assets/Scripts/CECUIManager.cs
T
2026-03-23 16:01:58 +07:00

782 lines
26 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using BrewMonster;
using BrewMonster.Network;
using BrewMonster.UI;
using System;
using System.Collections.Generic;
using BrewMonster.PerfectWorld.Scripts.Utility.ChatFilter;
using BrewMonster.Scripts.Managers;
using UnityEngine;
using TMPro;
public class CECUIManager : MonoSingleton<CECUIManager>
{
[SerializeField] private TMP_Text _fpsText;
[SerializeField] private List<GameObject> uiPrefabs; // drag các prefab UI vào đây
private readonly Dictionary<Type, GameObject> _spawnedUIs = new();
/// <summary>Stack of dialog names (front = index 0 = top / currently on top).</summary>
[SerializeField]private List<string> _uiStack = new();
/// <summary>Max number of dialogs in stack; when exceeded on Push, the top is popped once. 0 = unlimited.</summary>
[SerializeField] private int _maxStack = 1;
[SerializeField] private HUDNPC npsUI;
[SerializeField] private int currentTargetNPCID;
CECGameUIMan gameUI;
public CECGameUIMan GameUI => gameUI;
AUIManager aUIManager;
AUIDialog _dlgPlayerOptions;
[SerializeField] private DialogScriptTableObject dialogResouce;
[SerializeField] private Canvas canvasDlg;
[SerializeField] private UnityEngine.UI.Button btnSecondClick;
[SerializeField] CDlgQuickBar m_pDlgQuickBar1;
[SerializeField] GameObject ChangeSkillShortcutButton;
public CDlgSkillSubOther m_pDlgSkillSubOther;
CDlgMessageBox m_pDlgMessageBox;
public CDlgSkillAction m_pDlgSkillAction;
Sprite[] m_iconlistIvtr;
private CDlgInfoTooltip m_pDlgSkillTooltip;
// Task update timer / 任务更新计时器
private float _nextTaskUpdateTime = 0f;
private const float TASK_UPDATE_INTERVAL = .1f;
protected override void Awake()
{
base.Awake();
EventBus.Subscribe<CECHostPlayer.NPCINFO>(ShowUINPC);
EventBus.Subscribe<CECHostPlayer.TargetHUDClearEvent>(OnTargetHUDClear);
EventBus.Subscribe<NPCDiedEvent>(TryHideUINPC);
EventBus.Subscribe<MessageBoxEvent>(OnMessageBox);
gameUI = new CECGameUIMan();
gameUI.SetDependency(dialogResouce, canvasDlg);
gameUI.Init();
m_pDlgSkillAction = GetComponent<CDlgSkillAction>();
// Wire up second-click button / 连接第二次点击按钮
if (btnSecondClick != null)
{
btnSecondClick.onClick.AddListener(OnSecondClickButtonClicked);
}
ShowUI("Win_Hpmpxp");
#if UNITY_EDITOR
ChangeSkillShortcutButton.SetActive(true);
#else
ChangeSkillShortcutButton.SetActive(false);
#endif
}
private void Update()
{
// _fpsText.text = $"{Mathf.RoundToInt(1f / Time.deltaTime)}";
if (m_pDlgQuickBar1 != null)
{
m_pDlgQuickBar1.UpdateShortcuts();
}
// Periodically update task UI (DlgTask and DlgTaskTrace) / 定期更新任务UIDlgTask和DlgTaskTrace
if (Time.unscaledTime >= _nextTaskUpdateTime)
{
_nextTaskUpdateTime = Time.unscaledTime + TASK_UPDATE_INTERVAL;
//if hostplayer is null, return
var hostPlayer = EC_Game.GetGameRun()?.GetHostPlayer();
if(hostPlayer == null)
{
return;
}
UpdateTaskUI();
}
}
/// <summary>
/// Update task UI from DlgTask and DlgTaskTrace / 从DlgTask和DlgTaskTrace更新任务UI
/// </summary>
private void UpdateTaskUI()
{
try
{
var inGameUIMan = GetInGameUIMan();
if (inGameUIMan == null) return;
var dlgTaskDialog = inGameUIMan.GetDialog("Win_Quest");
var dlgTaskTraceDialog = inGameUIMan.GetDialog("Win_QuestMinion");
if (dlgTaskDialog != null && dlgTaskDialog is BrewMonster.Scripts.Task.UI.DlgTask dlgTaskForTrace)
{
if (dlgTaskTraceDialog != null)
{
dlgTaskForTrace.RefreshTaskTrace(dlgTaskTraceDialog.IsShow());
}
dlgTaskForTrace.Tick();
}
}
catch (System.Exception)
{
// Silently handle errors to avoid spamming logs / 静默处理错误以避免日志刷屏
// Task UI update errors are handled silently / 任务UI更新错误被静默处理
}
}
private void OnDestroy()
{
EventBus.Unsubscribe<CECHostPlayer.NPCINFO>(ShowUINPC);
EventBus.Unsubscribe<CECHostPlayer.TargetHUDClearEvent>(OnTargetHUDClear);
EventBus.Unsubscribe<NPCDiedEvent>(TryHideUINPC);
EventBus.Unsubscribe<MessageBoxEvent>(OnMessageBox);
}
private void ShowUINPC(CECHostPlayer.NPCINFO obj)
{
var host = EC_Game.GetGameRun()?.GetHostPlayer();
if (host != null && host.GetSelectedTarget() != obj.IDNPC)
return;
npsUI.gameObject.SetActive(true);
string hpText = obj.MaxHealth > 0 ? $"{obj.CurrentHealth}/{obj.MaxHealth}" : "-/-";
npsUI.SetText(hpText, obj.Name ?? "", "");
float fill = obj.MaxHealth > 0 ? (float)obj.CurrentHealth / (float)obj.MaxHealth : 1f;
npsUI.SetHealthImage(fill);
currentTargetNPCID = obj.IDNPC;
}
private void OnTargetHUDClear(CECHostPlayer.TargetHUDClearEvent _)
{
npsUI.gameObject.SetActive(false);
}
public CDlgQuickBar GetCDlgQuickBar()
{
return m_pDlgQuickBar1;
}
private void TryHideUINPC(NPCDiedEvent obj)
{
if (obj.NPCID != currentTargetNPCID) return;
npsUI.gameObject.SetActive(false);
}
/// <summary>
/// Show UI by name of component ("DlgTask", "EC_InventoryUI"). When isStack is true, pushes the dialog onto the UI stack (brings to front and tracks for Pop).
/// </summary>
/// <param name="componentName">Name of component ("DlgTask", "EC_InventoryUI")</param>
/// <param name="isStack">If true, push onto stack (show + SetAsLastSibling + track); if false, just show.</param>
/// <param name="hideCurrentUI">just hide current ui- not pop</param>
public AUIDialog ShowUI(string componentName)
{
if (string.IsNullOrEmpty(componentName) || canvasDlg == null)
{
if (canvasDlg == null) Debug.LogError("canvasDlg is null");
return null;
}
var currentDialogue = GetCurrentDialog();
if (currentDialogue != null)
{
if (_uiStack.Count > 0 && string.Compare(_uiStack[0], componentName, StringComparison.Ordinal) == 0)
{
return currentDialogue;
}
currentDialogue.Show(false);
}
return Push(componentName);
}
public void HideCurrentUIInStack()
{
Pop();
//show next one
var currentDialogue = GetCurrentDialog();
if (currentDialogue != null)
{
currentDialogue.Show(true);
}
}
/// <summary>
/// Push a dialog onto the UI stack: show it, add to front of stack, and SetAsLastSibling so it draws on top. If already in stack, moves it to front.
/// </summary>
private AUIDialog Push(string componentName)
{
if (string.IsNullOrEmpty(componentName) || canvasDlg == null) return null;
_uiStack.Remove(componentName);
if (_maxStack > 0 && _uiStack.Count >= _maxStack)
Pop();
var dlg = GetInGameUIMan().GetDialog(componentName);
if (dlg == null) return null;
dlg.Show(true);
_uiStack.Insert(0, componentName);
dlg.transform.SetAsLastSibling();
return dlg;
}
/// <summary>
/// Pop the top dialog off the stack: hide it and bring the new top (if any) to front. Returns true if something was popped.
/// </summary>
private bool Pop()
{
if (_uiStack.Count == 0) return false;
string top = _uiStack[0];
_uiStack.RemoveAt(0);
var dlg = GetInGameUIMan().GetDialog(top);
if (dlg != null)
dlg.Show(false);
if (_uiStack.Count > 0)
{
var newTop = GetInGameUIMan().GetDialog(_uiStack[0]);
if (newTop != null)
newTop.transform.SetAsLastSibling();
}
return true;
}
/// <summary>Returns the name of the dialog currently on top of the stack, or null if stack is empty.</summary>
public string GetCurrentUI()
{
if (_uiStack.Count == 0) return null;
return _uiStack[0];
}
/// <summary>Returns the dialog instance currently on top of the stack, or null if stack is empty.</summary>
public AUIDialog GetCurrentDialog()
{
var currentUI = GetCurrentUI();
if (currentUI == null) return null;
return GetInGameUIMan().GetDialog(currentUI);
}
/// <summary>Returns the number of dialogs in the stack (0 when empty).</summary>
public int GetStackCount() => _uiStack.Count;
/// <summary>Returns true if the given dialog name is in the stack.</summary>
public bool IsInStack(string componentName)
{
return !string.IsNullOrEmpty(componentName) && _uiStack.Contains(componentName);
}
/// <summary>Returns the dialog name at the given index (0 = top) without removing. Returns null if index is out of range.</summary>
public string PeekStack(int index = 0)
{
if (index < 0 || index >= _uiStack.Count) return null;
return _uiStack[index];
}
/// <summary>Clears the entire stack. If hideAll is true, hides every dialog in the stack before clearing.</summary>
public void ClearStack(bool hideAll = true)
{
if (hideAll)
{
var gui = GetInGameUIMan();
foreach (string name in _uiStack)
{
var dlg = gui?.GetDialog(name);
if (dlg != null) dlg.Show(false);
}
}
_uiStack.Clear();
}
public CDlgMessageBox ShowMessageBoxGeneral(string title, string message, AUIDialog dlg)
{
var msgBox = GetInGameUIMan().GetDialog("DlgMessageBox") as CDlgMessageBox;
if (msgBox != null)
{
msgBox.ShowMessageBoxGeneral(title, message, dlg);
return msgBox;
}
Debug.LogError("DlgMessageBox not found in InGameUIMan");
return null;
}
public CDlgMessageBox ShowMessageBoxYes(string title, string message, AUIDialog dlg, Action onClickedYes)
{
var msgBox = GetInGameUIMan().GetDialog("DlgMessageBox") as CDlgMessageBox;
if (msgBox != null)
{
msgBox.ShowMessageBoxYes(title, message, dlg, onClickedYes);
return msgBox;
}
Debug.LogError("DlgMessageBox not found in InGameUIMan");
return null;
}
public CDlgMessageBox ShowMessageBoxNo(string title, string message, AUIDialog dlg, Action onClickedNo)
{
var msgBox = GetInGameUIMan().GetDialog("DlgMessageBox") as CDlgMessageBox;
if (msgBox != null)
{
msgBox.ShowMessageBoxNo(title, message, dlg, onClickedNo);
return msgBox;
}
Debug.LogError("DlgMessageBox not found in InGameUIMan");
return null;
}
public CDlgMessageBox ShowMessageBoxYesAndNo(string title, string message, AUIDialog dlg, Action onClickedYes, Action onClickedNo)
{
var msgBox = GetInGameUIMan().GetDialog("DlgMessageBox") as CDlgMessageBox;
if (msgBox != null)
{
msgBox.ShowMessageBoxYesAndNo(title, message, dlg,onClickedYes, onClickedNo);
return msgBox;
}
Debug.LogError("DlgMessageBox not found in InGameUIMan");
return null;
}
// public CDlgMessageBox ShowMessageBox(MessageBoxData messageBoxData)
// {
// var msgBox = GetInGameUIMan().GetDialog("DlgMessageBox") as CDlgMessageBox;
// if (msgBox != null)
// {
// msgBox.ShowMessageBox(messageBoxData);
// return msgBox;
// }
// else
// {
// Debug.LogError("DlgMessageBox not found in InGameUIMan");
// }
//
// return null;
// }
// public CDlgMessageBox ShowMessageBox(string title, string message, MessageBoxType messageBoxType,
// Action onClickedYes = null, Action onClickedNo = null)
// {
// var msgBox = GetInGameUIMan().GetDialog("DlgMessageBox") as CDlgMessageBox;
// if (msgBox != null)
// {
// msgBox.ShowMessageBox(new MessageBoxData()
// {
// Title = title,
// Message = message,
// MessageBoxType = messageBoxType,
// OnClickedYes = onClickedYes,
// OnClickedNo = onClickedNo
// });
// return msgBox;
// }
// else
// {
// Debug.LogError("DlgMessageBox not found in InGameUIMan");
// }
//
// return null;
// }
public void UpdateSkillRelatedUI()
{
// ¸üм¼ÄÜÏà¹ØµÄ½çÃæÏÔʾ
if (m_pDlgQuickBar1)
m_pDlgQuickBar1.UpdateShortcuts();
/* if (m_pDlgSkillEdit != null && m_pDlgSkillEdit->IsShow())
{
// ¼¼Äܱ༭½çÃæÖ»ÔÚ Show(true) µÄʱºò²ÅÄܸüÐÂ
m_pDlgSkillEdit->Show(false);
}*/
}
/// <summary>
/// Show skill tooltip with description near the clicked skill button.
/// </summary>
/// <param name="hintText">The skill description and requirements</param>
/// <param name="sourceButton">The button RectTransform to position near</param>
public void ShowSkillTooltip(string hintText, RectTransform sourceButton, Action triggerAction = null)
{
if (string.IsNullOrEmpty(hintText))
{
Debug.LogWarning("[CECUIManager] ShowSkillTooltip called with empty hint text");
return;
}
// Lazy-load the tooltip dialog
if (m_pDlgSkillTooltip == null)
{
var tooltip = GetInGameUIMan().GetDialog("CDlgInfoTooltip") as CDlgInfoTooltip;
if (tooltip != null)
{
m_pDlgSkillTooltip = tooltip;
}
else
{
Debug.LogWarning(
"[CECUIManager] CDlgSkillTooltip not found in dialog resource. Tooltip will not be displayed.");
return;
}
}
if (m_pDlgSkillTooltip != null)
{
m_pDlgSkillTooltip.ShowTooltip(hintText, sourceButton, triggerAction);
}
}
/// <summary>
/// Hide the skill tooltip if it's currently visible.
/// </summary>
public void HideSkillTooltip()
{
if (m_pDlgSkillTooltip != null)
{
m_pDlgSkillTooltip.HideTooltip();
}
}
private void OnMessageBox(MessageBoxEvent messageBoxEvent)
{
BMLogger.LogError("CECUIManager OnMessageBox called");
int iRetVal = messageBoxEvent.iRetVal;
AUIDialog pDlg = messageBoxEvent.pDlg;
if (pDlg == m_pDlgMessageBox)
{
OnNewMessageBox(iRetVal);
return;
}
UnityGameSession pSession = UnityGameSession.Instance;
CECHostPlayer pHost = CECGameRun.Instance.GetHostPlayer();
if (string.Equals(pDlg.GetName(), "Game_Quit", StringComparison.OrdinalIgnoreCase))
{
// TODO
// Cancel hotkey customize because hot key state is determinted by CECHostInputFilter
// which is shared between repick role
//
// if (m_pDlgSettingQuickKey->IsShow())
// m_pDlgSettingQuickKey->Show(false);
if( pSession.GameSession.IsConnected )
{
// TODO
// if (CECCrossServer::Instance().IsOnSpecialServer())
// g_pGame->GetGameRun()->GetPendingLogOut().AppendForSaveConfig(new CECPendingLogoutCrossServer());
// else
// g_pGame->GetGameRun()->GetPendingLogOut().AppendForSaveConfig(new CECPendingLogoutHalf());
EC_Game.GetGameRun().GetPendingLogOut().AppendForSaveConfig(new CECPendingLogoutHalf());
}
else
EC_Game.GetGameRun().SetLogoutFlag(2);
}
else if ((string.Equals(pDlg.GetName(), "Game_TeachSkill", StringComparison.OrdinalIgnoreCase) &&
DialogBoxCommandIDs.IDOK == iRetVal) ||
(string.Equals(pDlg.GetName(), "Game_LearnSkill", StringComparison.OrdinalIgnoreCase) &&
DialogBoxCommandIDs.IDOK == iRetVal))
{
if (string.Equals(pDlg.GetName(), "Game_TeachSkill", StringComparison.OrdinalIgnoreCase))
{
}
else if (string.Equals(pDlg.GetName(), "Game_LearnSkill", StringComparison.OrdinalIgnoreCase))
{
/* int skillID = (int)pDlg.GetData();
int nCondition = pHost.CheckSkillLearnCondition(skillID, true);
if (0 == nCondition)
{
UnityGameSession.c2s_SendCmdNPCSevLearnSkill(skillID);
}*/
/*else if (1 == nCondition)
AddChatMessage(GetStringFromTable(270), GP_CHAT_MISC);
else if (6 == nCondition)
AddChatMessage(GetStringFromTable(527), GP_CHAT_MISC);
else if (7 == nCondition)
AddChatMessage(GetStringFromTable(541), GP_CHAT_MISC);
else if (8 == nCondition)
AddChatMessage(GetStringFromTable(271), GP_CHAT_MISC);
else if (9 == nCondition)
AddChatMessage(GetStringFromTable(556), GP_CHAT_MISC);
else if (10 == nCondition)
AddChatMessage(GetStringFromTable(557), GP_CHAT_MISC);
else if (12 == nCondition)
AddChatMessage(GetStringFromTable(11168), GP_CHAT_MISC);*/
}
}
//else if (pDlg is DlgInstall dlgInstall && dlgInstall.GetInstallMode == DlgInstall.InstallMode.Disenchase &&
// DialogBoxCommandIDs.IDOK == iRetVal)
//{
// UnityGameSession.c2s_CmdNPCSevClearEmbeddedChip(dlgInstall.FirstSlotIndex,
// dlgInstall.SelectedEquip.GetTemplateID());
// UnityGameSession.c2s_CmdGetAllData(true, true, false);
// dlgInstall.Show(false);
// pHost.EndNPCService();
// // m_pCurNPCEssence = NULL;
// // m_pDlgInventory->Show(false);
// pHost.GetPack((int)InventoryType.IVTRTYPE_PACK).UnfreezeAllItems();
// ShowMessageBoxGeneral("", pDlg.GetStringFromTable(228), null);
//}
}
private bool OnNewMessageBox(int iRetVal)
{
return true;
}
// private System.Type FindTypeByName(string componentName)
// {
// string[] namespacePrefixes = {
// "", // No namespace
// "BrewMonster.Scripts.Task.UI.",
// "BrewMonster.UI.",
// "BrewMonster.Scripts.UI.",
// "BrewMonster."
// };
//
// // Try with common namespace prefixes
// foreach (var prefix in namespacePrefixes)
// {
// string fullTypeName = string.IsNullOrEmpty(prefix) ? componentName : prefix + componentName;
// var type = System.Type.GetType(fullTypeName);
// if (type != null) return type;
// }
//
// // Search in all assemblies
// foreach (var assembly in System.AppDomain.CurrentDomain.GetAssemblies())
// {
// var type = assembly.GetType(componentName);
// if (type != null) return type;
//
// foreach (var prefix in namespacePrefixes)
// {
// if (string.IsNullOrEmpty(prefix)) continue;
// type = assembly.GetType(prefix + componentName);
// if (type != null) return type;
// }
// }
//
// return null;
// }
//
// private bool TryShowCachedUI(System.Type type)
// {
// if (type != null && _spawnedUIs.TryGetValue(type, out var uiGo))
// {
// uiGo.SetActive(true);
// return true;
// }
// return false;
// }
//
// private bool FindUIByName(string componentName, System.Type type)
// {
// for (int i = 0; i < canvasDlg.transform.childCount; i++)
// {
// var child = canvasDlg.transform.GetChild(i);
// if (!child.name.Contains(componentName) && child.name != componentName) continue;
//
// if (type != null)
// {
// var foundComponent = child.GetComponentInChildren(type, true);
// if (foundComponent != null)
// {
// ActivateAndCacheUI(foundComponent.gameObject, type);
// return true;
// }
// }
//
// ActivateAndCacheUI(child.gameObject, type);
// return true;
// }
// return false;
// }
//
// private bool FindUIByType(System.Type type)
// {
// if (type == null) return false;
//
// var foundComponent = canvasDlg.GetComponentInChildren(type, true);
// if (foundComponent != null)
// {
// ActivateAndCacheUI(foundComponent.gameObject, type);
// return true;
// }
// return false;
// }
private void ActivateAndCacheUI(GameObject uiGameObject, System.Type type)
{
uiGameObject.SetActive(true);
if (type != null) _spawnedUIs[type] = uiGameObject;
}
/// <summary>
/// Ẩn UI (disable thay vì destroy)
/// </summary>
// public void HideUI<T>() where T : Component
// {
// var type = typeof(T);
// if (_spawnedUIs.TryGetValue(type, out var uiGo))
// {
// uiGo.SetActive(false);
// }
// }
/// <summary>
/// Kiểm tra UI có đang active không
/// </summary>
public bool IsUIActive<T>() where T : Component
{
var type = typeof(T);
return _spawnedUIs.TryGetValue(type, out var uiGo) && uiGo.activeSelf;
}
/// <summary>
/// Ẩn tất cả UI hiện tại
/// </summary>
public void HideAll()
{
foreach (var kv in _spawnedUIs)
{
kv.Value.SetActive(false);
}
}
public CECGameUIMan GetInGameUIMan()
{
if (gameUI == null)
{
gameUI = new CECGameUIMan();
gameUI.SetDependency(dialogResouce, canvasDlg);
gameUI.Init();
}
return gameUI;
}
/// <summary>Shows the player options menu for the given character. Requires a prefab with id "DlgPlayerOptions" in DialogScriptTableObject.</summary>
public void ShowPlayerOptionsDialog(int characterId, Vector2 position)
{
if (characterId == 0 || canvasDlg == null) return;
var gui = GetInGameUIMan();
if (_dlgPlayerOptions == null)
_dlgPlayerOptions = gui.GetDialog("DlgPlayerOptions");
_dlgPlayerOptions?.ShowForPlayer(characterId);
_dlgPlayerOptions.transform.position = position;
}
/// <summary>
/// Get the current target NPC ID (same as stored from NPCINFO event)
/// </summary>
public int GetCurrentTargetNPCID()
{
return currentTargetNPCID;
}
//todo: change this code to other place
private int slot = 0;
public Sprite[] IconlistIvtr
{
get
{
if (m_iconlistIvtr == null || m_iconlistIvtr.Length == 0)
{
m_iconlistIvtr = Resources.LoadAll<Sprite>("UI/IconSprites/iconlist_ivtrm_multisprite");
}
return m_iconlistIvtr;
}
}
public Sprite GetSpriteInListIvtr(string name)
{
foreach (var item in IconlistIvtr)
{
if (item.name.Equals(name))
{
return item;
}
}
return null;
}
public void OnClickedWaveHand()
{
// if (EC_Game.GetGameRun().GetPoseCmdShortcuts() == null)
// {
// EC_Game.GetGameRun().StartGame(0, Vector3.zero);
// }
CECShortcut pSC = EC_Game.GetGameRun().GetPoseCmdShortcuts().GetShortcut(slot);
if (pSC != null) // && pObjSrc->GetDataPtr("ptr_CECShortcut") == pSC
{
// a_LogOutput(1, "[Dat Emote] ptr_CECShortcut");
pSC.Execute();
}
}
public void OnClickFly()
{
CECHostPlayer hostPlayer = EC_Game.GetGameRun()?.GetHostPlayer();
if (hostPlayer != null)
{
hostPlayer.CmdFly(true);
}
}
public void OnChangeSkillShortcut()
{
#if UNITY_EDITOR
CECHostPlayer hostPlayer = EC_Game.GetGameRun()?.GetHostPlayer();
if (hostPlayer != null)
{
hostPlayer.CycleSkillShortcuts();
}
#endif
}
/// <summary>
/// Handle second-click button click - triggers attack or move to NPC / 处理第二次点击按钮 - 触发攻击或移动到NPC
/// Uses OnMsgLBtnClick with selected target to reuse existing logic / 使用OnMsgLBtnClick和选中的目标来重用现有逻辑
/// </summary>
private void OnSecondClickButtonClicked()
{
CECHostPlayer hostPlayer = EC_Game.GetGameRun()?.GetHostPlayer();
if (hostPlayer != null)
{
int selectedTarget = hostPlayer.GetSelectedTarget();
if (selectedTarget != 0)
{
// Call OnMsgLBtnClick with the selected target to simulate second click / 使用选中的目标调用OnMsgLBtnClick以模拟第二次点击
hostPlayer.OnMsgLBtnClick(selectedTarget);
}
}
}
public struct MessageBoxEvent
{
public int iRetVal;
public AUIDialog pDlg;
public MessageBoxEvent(int retVal, AUIDialog dlg)
{
iRetVal = retVal;
pDlg = dlg;
}
}
public void FilterBadWords(ref string str)
{
str = ChatFilterService.Filter(str, out var isValidWord);
}
}