diff --git a/Assets/PerfectWorld/Scripts/DebugCommandMenu/DlgConsole.cs b/Assets/PerfectWorld/Scripts/DebugCommandMenu/DlgConsole.cs index 781e043509..502f66f585 100644 --- a/Assets/PerfectWorld/Scripts/DebugCommandMenu/DlgConsole.cs +++ b/Assets/PerfectWorld/Scripts/DebugCommandMenu/DlgConsole.cs @@ -6,6 +6,7 @@ using EditorAttributes; using TMPro; using UnityEngine; using UnityEngine.UI; +using BrewMonster.Scripts.UI; namespace BrewMonster.Scripts { @@ -33,7 +34,9 @@ namespace BrewMonster.Scripts [Header("Command Buttons")] [SerializeField] Button _btnNoCooldown; [SerializeField] Button _btnToggleAutoWrath; - + [SerializeField] Button _btnToggleTaskNpcTeleport; + + private bool _isAutoAddWrathEnabled = false; private Coroutine _autoAddWrathCoroutine; @@ -53,10 +56,18 @@ namespace BrewMonster.Scripts //_btnClose?.onClick.AddListener(OnBtnCloseClicked); _btnNoCooldown?.onClick.AddListener(OnBtnNoCooldownClicked); _btnToggleAutoWrath?.onClick.AddListener(OnBtnToggleAutoWrathClicked); + _btnToggleTaskNpcTeleport?.onClick.AddListener(OnBtnToggleTaskNpcTeleportClicked); DontDestroyOnLoad(this); } - + + public void OnBtnToggleTaskNpcTeleportClicked() + { + bool next = !CECUIHelper.DebugInstantTeleportToTaskNpc; + CECUIHelper.SetDebugInstantTeleportToTaskNpc(next); + Debug.Log($"[DlgConsole] Task NPC teleport cheat: {(next ? "ON" : "OFF")}"); + } + private void OnDestroy() { CancelAllLoopCommands(); diff --git a/Assets/PerfectWorld/Scripts/Task/UI/DlgNameLink.cs b/Assets/PerfectWorld/Scripts/Task/UI/DlgNameLink.cs index 05034090cd..1983a54d8e 100644 --- a/Assets/PerfectWorld/Scripts/Task/UI/DlgNameLink.cs +++ b/Assets/PerfectWorld/Scripts/Task/UI/DlgNameLink.cs @@ -194,30 +194,31 @@ namespace BrewMonster.UI public override LinkCommand Clone() => new MoveToLinkCommand(this); - public override bool Execute(TMP_Text pLink){ - if (pLink) + public override bool Execute(TMP_Text pLink) + { + if (pLink) { + // Prefer task+npc route first so FollowCoord(int id, int taskId) can apply debug teleport. + if (m_TargetId > 0 && m_TaskId > 0) + { + DlgTask.SetTraceNpc(m_TargetId, m_TaskId); + return true; + } + if (!m_TargetPos.IsZero()) { // show the flag on worldmap DlgTask.SetTracePosition(m_Targets, m_TargetName); return true; } - else if (m_TargetId > 0 && m_TaskId > 0) - { - DlgTask.SetTraceNpc(m_TargetId, m_TaskId); - return true; - } - else - { - //EC_Game.GetGameRun().AddFixedMessage(FIXMSG_ERR_FC_INVALID_OPERATION); - return false; - } + + //EC_Game.GetGameRun().AddFixedMessage(FIXMSG_ERR_FC_INVALID_OPERATION); + return false; } - return false; + return false; } - } + } ////////////////////////////////////////////////////////////////////////// // TaskNameHoverCommand ////////////////////////////////////////////////////////////////////////// @@ -271,4 +272,4 @@ namespace BrewMonster.UI return true; } } -} \ No newline at end of file +} diff --git a/Assets/PerfectWorld/Scripts/UI/EC_UIHelper.cs b/Assets/PerfectWorld/Scripts/UI/EC_UIHelper.cs index 86bce86e24..5547be8fd0 100644 --- a/Assets/PerfectWorld/Scripts/UI/EC_UIHelper.cs +++ b/Assets/PerfectWorld/Scripts/UI/EC_UIHelper.cs @@ -10,6 +10,8 @@ using BrewMonster.Scripts; using BrewMonster.Scripts.Chat; using CSNetwork.GPDataType; using CSNetwork; +using System.Numerics; +using UnityEngine; namespace BrewMonster.Scripts.UI { @@ -17,6 +19,34 @@ namespace BrewMonster.Scripts.UI { public static string DlgTaskName = "Win_Quest"; + public static bool DebugInstantTeleportToTaskNpc { get; private set; } + + public static void SetDebugInstantTeleportToTaskNpc(bool enabled) + { + DebugInstantTeleportToTaskNpc = enabled; + UnityEngine.Debug.Log($"[CECUIHelper] DebugInstantTeleportToTaskNpc={(enabled ? "ON" : "OFF")}"); + } + + private static bool IsNpcTeleportTarget(int id) + { + if (id <= 0) + return false; + + ATaskTemplMan pMan = EC_Game.GetTaskTemplateMan(); + if (pMan != null && pMan.TryGetTaskNPCInfo((uint)id, out _)) + return true; + + elementdataman edm = ElementDataManProvider.GetElementDataMan(); + if (edm != null) + { + DATA_TYPE dt = DATA_TYPE.DT_INVALID; + edm.get_data_ptr((uint)id, ID_SPACE.ID_SPACE_ESSENCE, ref dt); + return dt == DATA_TYPE.DT_NPC_ESSENCE; + } + + return false; + } + public static A3DVECTOR3 GetTaskObjectCoordinates(int id, ref bool in_table) { in_table = false; @@ -268,6 +298,60 @@ namespace BrewMonster.Scripts.UI return false; } + if (DebugInstantTeleportToTaskNpc && taskId > 0 && IsNpcTeleportTarget(id)) + { + wm.FinishAllWork(true); + wm.ClearDelayedWork(); + + bool canUseServerGoto = + UnityGameSession.Instance != null && + UnityGameSession.Instance.GameSession != null && + UnityGameSession.Instance.GameSession.IsConnected; + + if (canUseServerGoto) + { + // Online: use server-authoritative relocation to avoid snap-back by MSG_HST_CORRECTPOS. + UnityGameSession.c2s_CmdGoto(vPos.x, vPos.y, vPos.z); + + var npcManOnline = EC_ManMessageMono.Instance != null ? EC_ManMessageMono.Instance.CECNPCMan : null; + var npcOnline = npcManOnline != null ? npcManOnline.FindNPCByTemplateID(id) : null; + if (npcOnline != null) + { + host.SelectTarget(npcOnline.GetNPCID()); + } + + UnityEngine.Debug.Log( + $"[CECUIHelper] Debug teleport requested via server goto to ({vPos.x},{vPos.y},{vPos.z}), templateId={id}, taskId={taskId}"); + return true; + } + + // Offline/local fallback: keep old behavior. + UnityEngine.Vector3 newPos = new UnityEngine.Vector3(vPos.x, vPos.y, vPos.z); + A3DVECTOR3 newPosA3D = new A3DVECTOR3(vPos.x, vPos.y, vPos.z); + + host.SetPos(newPos); + + // Sync move baseline to avoid "old server pos -> new pos" speed spike on next move packet. + if (host.m_MoveCtrl != null) + { + host.m_MoveCtrl.SetLastSevPos(newPosA3D); + host.m_MoveCtrl.SetHostLastPos(newPosA3D); + host.m_MoveCtrl.SendStopMoveCmd(newPos, 0f, (int)GPMoveMode.GP_MOVE_RUN); + } + + var npcMan = EC_ManMessageMono.Instance != null ? EC_ManMessageMono.Instance.CECNPCMan : null; + var npc = npcMan != null ? npcMan.FindNPCByTemplateID(id) : null; + if (npc != null && host.SelectTarget(npc.GetNPCID())) + { + CECHPWorkTrace traceWork = wm.CreateNPCTraceWork(npc, taskId); + if (traceWork != null) + wm.StartWork_p2(traceWork, true); + } + + UnityEngine.Debug.Log($"[CECUIHelper] Teleported locally to task NPC templateId={id}, taskId={taskId}"); + return true; + } + CECHPWorkMove work = wm.CreateWork(CECHPWork.Host_work_ID.WORK_MOVETOPOS) as CECHPWorkMove; if (work == null) { @@ -287,7 +371,6 @@ namespace BrewMonster.Scripts.UI } wm.StartWork_p2(work); - return true; } @@ -542,4 +625,4 @@ namespace BrewMonster.Scripts.UI conv = chat.Replace("&", ""); } } -} \ No newline at end of file +}