Files
test/Assets/PerfectWorld/Scripts/UI/GamePlay/EC_GameUIMan.cs
T
2026-03-12 13:50:41 +07:00

405 lines
16 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 System;
using BrewMonster.Assets.PerfectWorld.Scripts.UI.GamePlay;
using BrewMonster.Managers;
using BrewMonster.Scripts.Task;
using BrewMonster.Scripts.Task.UI;
using BrewMonster.Scripts.UI;
using System.Collections.Generic;
using System.Linq;
using BrewMonster.Network;
using BrewMonster.Scripts;
using CSNetwork.GPDataType;
using PerfectWorld.UI.MiniMap;
using UnityEngine;
namespace BrewMonster.UI
{
public class CECGameUIMan : AUIManager
{
public const int LAYOUTDATA_VERSION = 15;
DlgNPC m_pDlgNPC;
CDlgPetList m_pDlgPetList;
public NPC_ESSENCE? m_pCurNPCEssence;
public int m_idCurFinishTask = -1;
private DlgTask m_pDlgTask;
private Dictionary<byte, (string, Sprite[])> m_IconMap;
private const string SKILL_ICONLIST_NAME = "iconlist_skill_multisprite";
private const string ACTION_ICONLIST_NAME = "ActionIcon/iconlist_action_multisprite";
public CDlgMiniMap m_pDlgMiniMap;
// Layout/settings flags for GetUserLayout (saved to server)
// 布局/设置标志,用于 GetUserLayout(保存到服务器)
private bool m_bAutoReply;
private bool m_bOnlineNotify;
private bool m_bSaveHistory;
private bool m_bShowItemDescCompare = true;
private bool m_bShowLowHP = true;
private bool m_bShowTargetOfTarget = true;
// TODO: System module quick bar dialog GetMiniMode() not yet wired in C#
private AUIDialog m_pDlgSysModuleQuickBar;
// TODO: System bar dialog IsShow() for bMenuMode
private AUIDialog m_pDlgSystemb;
public static bool TALKPROC_IS_TERMINAL(uint id)
{
return ((id & 0x80000000u) != 0) && ((id & 0x40000000u) != 0);
}
public static bool TALKPROC_IS_FUNCTION(uint id)
{
return ((id) & 0x80000000) != 0;
}
public static uint TALKPROC_GET_FUNCTION_ID(uint id)
{
return ((id) & 0x7FFFFFFF);
}
public void PopupNPCDialog(NPC_ESSENCE pEssence)
{
var dialogueNpc = CECUIManager.Instance.ShowUI("DialogNPC");
if (m_pDlgNPC == null)
{
if (dialogueNpc == null)
{
BMLogger.LogError("can not get dialogue npc");
return;
}
m_pDlgNPC = dialogueNpc.GetComponent<DlgNPC>();
m_pDlgNPC.SetAUIManager(this);
}
m_pDlgNPC.PopupDialog(pEssence);
}
public void PopupNPCDialog(talk_proc pTalk)
{
var dialogueNpc = CECUIManager.Instance.ShowUI("DialogNPC");
if (m_pDlgNPC == null)
{
if (dialogueNpc == null)
{
BMLogger.LogError("can not get dialogue npc");
return;
}
m_pDlgNPC = dialogueNpc.GetComponent<DlgNPC>();
m_pDlgNPC.SetAUIManager(this);
}
m_pDlgNPC.PopupNPCDialog(pTalk);
}
public CECShortcutSet GetSCSByDlg(int indexPanel)
{
CECHostPlayer pHost = CECGameRun.Instance.GetHostPlayer();
CDlgQuickBar cDlgQuickBar = CECUIManager.Instance.GetCDlgQuickBar();
CECShortcutSet pSCS = null;
int index = (0);
if (indexPanel == 1)
{
int panel = (index < 0 ? cDlgQuickBar.GetCurPanel1() : index) - 1;
pSCS = pHost.GetShortcutSet1(0);
}
else
{
int panel = (index < 0 ? cDlgQuickBar.GetCurPanel2() : index) - 1;
pSCS = pHost.GetShortcutSet2(panel);
}
return pSCS;
}
// 弹出任务完成对话框(到达/离开地点等触发) // Popup task-finish dialog (reach/leave site, etc.)
// C++: pTask->PopupTaskFinishDialog(taskId, &awardTalk); then OnUIDialogEnd() notifies server.
public bool PopupTaskFinishDialog(uint taskId, talk_proc pTalk)
{
if (pTalk.num_window == 0) return false;
var dialogueNpc = CECUIManager.Instance.ShowUI("DialogNPC");
if (m_pDlgNPC == null)
{
if (dialogueNpc == null)
{
BMLogger.LogError("can not get dialogue npc");
return false;
}
m_pDlgNPC = dialogueNpc.GetComponent<DlgNPC>();
m_pDlgNPC.SetAUIManager(this);
}
m_idCurFinishTask = (int)taskId;
m_pDlgNPC.PopupNPCDialog(pTalk);
m_pDlgNPC.SetData(DlgNPC.NPC_DIALOG.NPC_DIALOG_TASK_TALK, "");
return true;
}
public void EndNPCService()
{
m_pCurNPCEssence = null;
//EC_Game.GetGameRun().GetHostPlayer().EndNPCService();
EC_ManMessageMono.Instance.EC_ManPlayer.GetHostPlayer().EndNPCService();
}
public bool UpdateTask(uint idTask, int reason)
{
Debug.Log($"[EC_GameUIMan] UpdateTask: idTask={idTask}, reason={reason}");
DlgTaskTrace pDlg = GetDialog("Win_QuestMinion").GetComponent<DlgTaskTrace>();
if (pDlg) {
//pDlg->SetBtnUnTraceY(-1, 0);
pDlg.UpdateContributionTask();
if (reason == TaskTemplConstants.TASK_SVR_NOTIFY_NEW)
pDlg.OnTaskNew(idTask);
}
// TODO
// ´
// if (reason == TaskTemplConstants.TASK_SVR_NOTIFY_NEW)
// {
// m_pDlgQuestionTask.AddQuestionTask(idTask);
// }
// else if (reason == TaskTemplConstants.TASK_SVR_NOTIFY_COMPLETE || reason == TaskTemplConstants.TASK_SVR_NOTIFY_GIVE_UP)
// {
// m_pDlgQuestionTask.RemoveQuestionTask(idTask);
// }
if (reason == TaskTemplConstants.TASK_SVR_NOTIFY_STORAGE)
{
// TODO
// CDlgTaskList* pDlg = (CDlgTaskList*)GetDialog("Win_QuestList");
// if (pDlg && pDlg.IsShow())
// {
// // refresh data in OnShow()
// pDlg.RefreshTaskList();
// }
return true;
}
else
{
// zhangyitian 20140521
// ʱɽбҲҪ£˿ɽбµ
return m_pDlgTask.UpdateQuestView();
}
}
public DialogScriptTableObject GetDialogResource()
{
return m_dialogResouce;
}
public Canvas GetCanvas()
{
return m_canvas;
}
public void EnableUI(bool bEnable)
{
}
/// <summary>
/// Get user layout data for saving to server. Fills USER_LAYOUT and optionally writes to pData.
/// 获取用户布局数据用于保存到服务器。填充 USER_LAYOUT,并可选写入 pData。
/// </summary>
public void GetUserLayout(byte[] pData, int startIndex, ref uint dwUISize)
{
CECHostPlayer pHost = EC_Game.GetGameRun()?.GetHostPlayer();
if (pHost == null)
{
dwUISize = 0;
return;
}
// Build and fill USER_LAYOUT (ul)
USER_LAYOUT ul = new USER_LAYOUT();
// Initialize array fields (C# class does not auto-init these)
ul.bChecked1 = new byte[HostCfgConstants.NUM_HOSTSCSETS1];
ul.bChecked2 = new byte[HostCfgConstants.NUM_HOSTSCSETS2];
ul.a_Mark = new SAVE_MARK[EC_GameUIMan_Constants.CECGAMEUIMAN_MAX_MARKS];
ul.idGroup = new int[EC_GameUIMan_Constants.CECGAMEUIMAN_MAX_GROUPS];
ul.clrGroup = new uint[EC_GameUIMan_Constants.CECGAMEUIMAN_MAX_GROUPS];
ul.a_MarkMapID = new short[EC_GameUIMan_Constants.CECGAMEUIMAN_MAX_MARKS];
for (int k = 0; k < ul.a_Mark.Length; k++)
{
ul.a_Mark[k].szName = new ushort[EC_GameUIMan_Constants.CECGAMEUIMAN_MARK_NAME_LEN + 1];
ul.a_MarkMapID[k] = 1; // C++ inits to 1 per element
}
ul.nVersion = (sbyte)LAYOUTDATA_VERSION;
ul.nMapMode = (sbyte)(m_pDlgMiniMap != null ? m_pDlgMiniMap.GetMode() : 0);
// TODO: Win_QuickbarPetV dialog bQuickbarPetMode not wired in C# yet
// TODO: 快捷栏宠物模式对话框尚未在 C# 中接入
ul.bQuickbarPetMode = false;
// TODO : check later bQuickbar1Mode and bChecked1 from Win_Quickbar*Ha_* dialogs
// string dlgName = $"Win_Quickbar{HostCfgConstants.SIZE_HOSTSCSET1}Ha";
// AUIDialog dlgQuickbar1Ha = GetDialog(dlgName);
// ul.bQuickbar1Mode = dlgQuickbar1Ha != null && dlgQuickbar1Ha.IsShow();
ul.bQuickbar1Mode = false;
for (int i = 0; i < HostCfgConstants.NUM_HOSTSCSETS1; i++)
{
// TODO: check later Chk_Normal checkbox per quickbar panel
// TODO: 后续核对 每个快捷栏面板的 Chk_Normal 勾选状态
ul.bChecked1[i] = 0;
}
// TODO: check later bQuickbar2Mode and bChecked2 from Win_Quickbar*Hb_* dialogs
ul.bQuickbar2Mode = false;
for (int i = 0; i < HostCfgConstants.NUM_HOSTSCSETS2; i++)
ul.bChecked2[i] = 0;
if (m_pDlgTask != null)
m_pDlgTask.SyncTrace(ul, false);
CDlgQuickBar dlgQuickBar = CECUIManager.Instance?.GetCDlgQuickBar();
if (dlgQuickBar != null)
{
ul.bQuickbarShowAll1 = dlgQuickBar.m_bShowAll1;
ul.bQuickbarShowAll2 = dlgQuickBar.m_bShowAll2;
ul.nQuickbarCurPanel1 = dlgQuickBar.m_nCurPanel1;
ul.nQuickbarCurPanel2 = dlgQuickBar.m_nCurPanel2;
ul.nQuickbarDisplayPanels1 = dlgQuickBar.m_nDisplayPanels1;
ul.nQuickbarDisplayPanels2 = dlgQuickBar.m_nDisplayPanels2;
}
// TODO: chat window size/color m_pDlgChat not wired in C#
ul.nChatWinSize = 1;
ul.nCurChatColor = 1;
// MiniMap marks
if (m_pDlgMiniMap != null)
{
var marks = m_pDlgMiniMap.GetMarks();
int markCount = Mathf.Min(marks.Count, EC_GameUIMan_Constants.CECGAMEUIMAN_MAX_MARKS);
for (int i = 0; i < markCount; i++)
{
var m = marks[i];
ul.a_Mark[i].nNPC = m.nNPC;
ul.a_Mark[i].vecPos = m.vecPos;
ul.a_MarkMapID[i] = (short)m.mapID;
CopyStringToUshortArray(ul.a_Mark[i].szName, m.strName ?? "", EC_GameUIMan_Constants.CECGAMEUIMAN_MARK_NAME_LEN);
}
}
// TODO: friend group layout CECFriendMan / GetFriendMan() not available in C# yet
// TODO: 好友分组布局 C# 中尚未提供 CECFriendMan / GetFriendMan()
// Placeholder: idGroup / clrGroup remain zeroed (already initialized)
ul.bAutoReply = m_bAutoReply;
ul.bOnlineNotify = m_bOnlineNotify;
ul.bSaveHistory = m_bSaveHistory;
// TODO: current system module shortcut set index GetCurSysModShortcutSetIndex() not in C# host
// TODO: 当前使用的系统模块快捷栏索引 – C# 宿主中暂无 GetCurSysModShortcutSetIndex()
ul.ucCurSystemModuleSC = 0;
// TODO: m_pDlgSysModuleQuickBar GetMiniMode() not wired
ul.bSystemModuleQuickBarMini = m_pDlgSysModuleQuickBar != null && GetDlgSysModuleQuickBarMiniMode();
// TODO: m_pDlgSystemb system bar show state
ul.bMenuMode = m_pDlgSystemb != null && m_pDlgSystemb.IsShow();
ul.bShowCompareDesc = m_bShowItemDescCompare;
ul.bShowLowHP = m_bShowLowHP;
ul.bShowTargetOfTarget = m_bShowTargetOfTarget;
dwUISize = EC_GameUIMan_Constants.USER_LAYOUT_SIZE; // Match C++ sizeof(USER_LAYOUT)=344
if (pData != null)
{
// Serialize USER_LAYOUT to binary (344 bytes) and copy into pData (match C++ memcpy)
byte[] layoutBytes = ul.ToBytes();
Array.Copy(layoutBytes, 0, pData, startIndex, (int)dwUISize);
}
}
/// <summary>Copy string into fixed ushort[] (for SAVE_MARK.szName).</summary>
private static void CopyStringToUshortArray(ushort[] dest, string str, int maxLen)
{
if (dest == null || dest.Length < maxLen + 1) return;
int len = System.Math.Min(str?.Length ?? 0, maxLen);
for (int i = 0; i < len; i++)
dest[i] = (ushort)str[i];
for (int i = len; i < dest.Length; i++)
dest[i] = 0;
}
/// <summary>TODO: Wire to system module quick bar mini mode when dialog is available.</summary>
private bool GetDlgSysModuleQuickBarMiniMode()
{
return false;
}
public override void Init()
{
base.Init();
m_IconMap = new Dictionary<byte, (string, Sprite[])>();
m_pDlgTask = GetDialog(CECUIHelper.DlgTaskName).GetComponent<DlgTask>();
m_pDlgTask.Show(false);
m_pDlgMiniMap = GetDialog("Win_Map").GetComponent<CDlgMiniMap>();
m_IconMap[(byte)EC_GAMEUI_ICONS.ICONS_SKILL] = (SKILL_ICONLIST_NAME, Resources.LoadAll<Sprite>(SKILL_ICONLIST_NAME));
m_IconMap[(byte)EC_GAMEUI_ICONS.ICONS_ACTION] = (ACTION_ICONLIST_NAME, Resources.LoadAll<Sprite>(ACTION_ICONLIST_NAME));
}
public void SetCover(AUIImagePicture pImgPic, string nameImage, EC_GAMEUI_ICONS iCONS_TYPE)
{
pImgPic.SetImage(m_IconMap[(byte)iCONS_TYPE].Item2.FirstOrDefault(s => s.name == nameImage));
}
/// <summary>Refresh team UI (Arrange Team dialog). Called after team join/leave/member data.</summary>
public bool UpdateTeam(bool bUpdateNear = false)
{
var dlg = GetDialog("Win_ArrangeTeam");
if (dlg is DlgArrangeTeam arr)
{
return arr.UpdateTeam(bUpdateNear);
}
return true;
}
public string GetRealmName(int realmLevel)
{
string strRealm = string.Empty;
if (realmLevel > 0){
int layer = CECHostPlayer.GetRealmLayer(realmLevel);
int subLevel = CECHostPlayer.GetRealmSubLevel(realmLevel);
strRealm = string.Format(GetStringFromTable(11100), GetStringFromTable(11100+layer), GetStringFromTable(11120+subLevel));
}
return strRealm;
}
public void PopupPetListDialog()
{
if (m_pDlgPetList == null)
{
GameObject ob = m_dialogResouce.GetPrefabDialog("DlgPetList");
m_pDlgPetList = GameObject.Instantiate(ob, m_canvas.transform).GetComponent<CDlgPetList>();
m_pDlgPetList.SetAUIManager(this);
}
m_pDlgPetList.OnInitDialog();
}
public void TraceTask(uint ulTaskId)
{
if (m_pDlgTask != null)
{
m_pDlgTask.TraceTask(ulTaskId);
}
}
}
public enum EC_GAMEUI_ICONS : byte
{
ICONS_ACTION = 0,
ICONS_SKILL,
ICONS_INVENTORY,
ICONS_STATE,
ICONS_SKILLGRP,
ICONS_GUILD,
ICONS_PET,
ICONS_ELF,
ICONS_SUITE,
ICONS_CALENDAR,
ICONS_PQ,
ICONS_MAX
};
}