diff --git a/Assets/PerfectWorld/Scripts/Task/CECTaskInterface.cs b/Assets/PerfectWorld/Scripts/Task/CECTaskInterface.cs index 8901447f7f..0940a3fda1 100644 --- a/Assets/PerfectWorld/Scripts/Task/CECTaskInterface.cs +++ b/Assets/PerfectWorld/Scripts/Task/CECTaskInterface.cs @@ -1550,7 +1550,11 @@ namespace BrewMonster.Scripts.Task { case (uint)TaskCompletionMethod.enumTMReachSite: pTempl.IncValidCount(); - _notify_svr(this, 3, (ushort)ulTask); //TASK_CLT_NOTIFY_REACH_SITE = 3 + _notify_svr(this, (byte)ClientNotificationConstants.TASK_CLT_NOTIFY_REACH_SITE, (ushort)ulTask); + break; + case (uint)TaskCompletionMethod.enumTMLeaveSite: + pTempl.IncValidCount(); + _notify_svr(this, (byte)ClientNotificationConstants.TASK_CLT_NOTIFY_LEAVE_SITE, (ushort)ulTask); break; } } diff --git a/Assets/PerfectWorld/Scripts/Task/TaskClient.cs b/Assets/PerfectWorld/Scripts/Task/TaskClient.cs index cfad538509..1b695aac0f 100644 --- a/Assets/PerfectWorld/Scripts/Task/TaskClient.cs +++ b/Assets/PerfectWorld/Scripts/Task/TaskClient.cs @@ -3,6 +3,7 @@ using System.Reflection; using System.Runtime.InteropServices; using BrewMonster.Network; using BrewMonster.Scripts.Task; +using BrewMonster.UI; using CSNetwork.GPDataType; using PerfectWorld.Scripts.Task; using UnityEngine; @@ -197,8 +198,13 @@ namespace BrewMonster.Scripts.Task } else { - // TODO: PopupTaskFinishDialog not exposed; implement UI as needed - s_finishDlgShownTime = ulCurTime; + // 弹出任务完成对话框(奖励对话有选项) // Popup finish dialog when award talk has options + var uiMan = EC_Game.GetGameRun()?.GetUIManager()?.GetInGameUIMan(); + if (uiMan != null) + { + uiMan.PopupTaskFinishDialog(pTempl.GetID(), pTalk); + s_finishDlgShownTime = ulCurTime; + } } break; } @@ -259,8 +265,13 @@ namespace BrewMonster.Scripts.Task } else { - // TODO: PopupTaskFinishDialog not exposed; implement UI as needed - s_finishDlgShownTime = ulCurTime; + // 弹出任务完成对话框(奖励对话有选项) // Popup finish dialog when award talk has options + var uiMan = EC_Game.GetGameRun()?.GetUIManager()?.GetInGameUIMan(); + if (uiMan != null) + { + uiMan.PopupTaskFinishDialog(pTempl.GetID(), pTalk); + s_finishDlgShownTime = ulCurTime; + } } } continue; diff --git a/Assets/PerfectWorld/Scripts/UI/GamePlay/EC_GameUIMan.cs b/Assets/PerfectWorld/Scripts/UI/GamePlay/EC_GameUIMan.cs index 4b48a710ef..2622c4ce91 100644 --- a/Assets/PerfectWorld/Scripts/UI/GamePlay/EC_GameUIMan.cs +++ b/Assets/PerfectWorld/Scripts/UI/GamePlay/EC_GameUIMan.cs @@ -57,6 +57,25 @@ namespace BrewMonster.UI m_pDlgNPC.PopupNPCDialog(pTalk); } + // 弹出任务完成对话框(到达/离开地点等触发) // 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; + + if (m_pDlgNPC == null) + { + GameObject ob = m_dialogResouce.GetPrefabDialog("DialogNPC"); + m_pDlgNPC = GameObject.Instantiate(ob, m_canvas.transform).GetComponent(); + 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; diff --git a/Assets/PerfectWorld/Scripts/World/CECWorld.cs b/Assets/PerfectWorld/Scripts/World/CECWorld.cs index 3ebf6a5d18..a25ea8c4f4 100644 --- a/Assets/PerfectWorld/Scripts/World/CECWorld.cs +++ b/Assets/PerfectWorld/Scripts/World/CECWorld.cs @@ -71,6 +71,12 @@ namespace BrewMonster.Scripts.World return pObject; } public int GetInstanceID() { return m_idInst; } + + // 设置实例ID(地图ID) // Set instance ID (map ID) + public void SetInstanceID(int idInst) + { + m_idInst = idInst; + } public CECAssureMove GetAssureMove() { return m_pAssureMove; } diff --git a/Assets/Scripts/CECGameRun.cs b/Assets/Scripts/CECGameRun.cs index a51430797c..c750ee32c4 100644 --- a/Assets/Scripts/CECGameRun.cs +++ b/Assets/Scripts/CECGameRun.cs @@ -5,7 +5,6 @@ using BrewMonster.Scripts.World; using BrewMonster.UI; using CSNetwork; using CSNetwork.GPDataType; -using CSNetwork.GPDataType; using CSNetwork.Protocols.RPCData; using System.Collections.Generic; using System.Data; @@ -144,6 +143,25 @@ public partial class CECGameRun BMLogger.LogError("null _playerPrefab"); return; } + + // 同步世界/地图ID给任务系统(GetPos 返回的 worldId) + // English: Sync map ID to task system (worldId returned by GetPos). + // We don't receive mapId in cmd_self_info_1, so use selected RoleInfo.worldtag as current map id. + var roleInfo = UnityGameSession.Instance != null ? UnityGameSession.Instance.GetRoleInfo() : null; + if (roleInfo != null) + { + int idInst = roleInfo.worldtag; + if (idInst > 0) + { + // Ensure instance exists in table (minimal stub instance is fine for now) + if (!m_InstTab.ContainsKey(idInst)) + m_InstTab.Add(idInst, new CECInstance()); + + // Update global world instance id used by task checks + CECWorld.Instance?.SetInstanceID(idInst); + } + } + CECPlayer.InitStaticRes(); hostPlayer = ObjectSpawner.Instance.InstantiateObject(_playerPrefab, setThisAsParent: true).AddComponent(); hostPlayer.InitCharacter(info); diff --git a/Assets/Scripts/CECHostPlayer.cs b/Assets/Scripts/CECHostPlayer.cs index 8d29850a5f..7210cd6b75 100644 --- a/Assets/Scripts/CECHostPlayer.cs +++ b/Assets/Scripts/CECHostPlayer.cs @@ -226,7 +226,11 @@ namespace BrewMonster ccSkin = controller.skinWidth; } - m_TaskCounter.SetCounter(3000f); + // 任务状态检查节流(毫秒) // Throttle task status check (milliseconds) + // NOTE: CECCounter uses "Period" as threshold; SetCounter only sets current value. + // We want task checking roughly every 3 seconds, not every frame. + m_TaskCounter.SetPeriod(3000f); + m_TaskCounter.Reset(true); // trigger first check immediately m_bTitleDataReady = false; playerTransform = transform; m_GatherCnt ??= new CECCounter();