using BrewMonster.Network; using BrewMonster.Scripts; using CSNetwork; using CSNetwork.GPDataType; using System.Runtime.InteropServices; using Cysharp.Threading.Tasks; using UnityEngine; using static BrewMonster.Scripts.CECHPWork; namespace BrewMonster { public partial class CECHostPlayer { public void OnMsgHstCorrectPos(in ECMSG Msg) { //Debug.LogError("HoangDev : OnMsgHstCorrectPos"); byte[] buf = (byte[])Msg.dwParam1; // chỗ bạn lưu pDataBuf GCHandle handle = GCHandle.Alloc(buf, GCHandleType.Pinned); cmd_host_correct_pos pCmd = (cmd_host_correct_pos)Marshal.PtrToStructure( handle.AddrOfPinnedObject(), typeof(cmd_host_correct_pos)); handle.Free(); //cmd_host_correct_pos pCmd = GPDataTypeHelper.FromBytes((byte[])Msg.dwParam1); Debug.LogError("HoangDev :pCmd.pos " + pCmd.pos); SetPos(pCmd.pos); m_vVelocity.Clear(); m_CDRInfo.vAbsVelocity.Clear(); m_MoveCtrl.SetMoveStamp(pCmd.stamp); } public void OnMsgHstSetMoveStamp(ECMSG Msg) { cmd_set_move_stamp pCmd = GPDataTypeHelper.FromBytes((byte[])Msg.dwParam1); m_MoveCtrl.SetMoveStamp(pCmd.move_stamp); } public void OnMsgHstGoto(in ECMSG Msg) { PopupManager.Instance.OnPlayerRevived(); // p1 is a byte[] buffer; parse into cmd_notify_hostpos then set position // p1 是一个 byte[] 缓冲区;解析为 cmd_notify_hostpos 然后设置位置 byte[] buf = (byte[])Msg.dwParam1; cmd_notify_hostpos pCmd = GPDataTypeHelper.FromBytes(buf); int idInst = pCmd.tag; Vector3 vPos = new Vector3(pCmd.vPos.x, pCmd.vPos.y, pCmd.vPos.z); int iLine = pCmd.line; // Call Goto method to properly handle teleportation // 调用 Goto 方法来正确处理传送 if (!Goto(idInst, vPos, iLine)) { BMLogger.LogError($"OnMsgHstGoto: Failed to teleport to instance {idInst}"); return; } } void OnMsgHstWayPoint(ECMSG Msg) { //CECGameUIMan pGameUI = EC_Game.GetGameRun().GetUIManager().GetInGameUIMan(); //if (Convert.ToInt32(Msg.dwParam2) == CommandID.ACTIVATE_WAYPOINT) //{ // cmd_activate_waypoint pCmd = GPDataTypeHelper.FromBytes((byte[])Msg.dwParam1); // m_aWayPoints.Add(pCmd.waypoint); // // add to waypoints array // pGameUI.GetMapDlgsMgr().UpdateWayPoints(&pCmd.waypoint, 1, false); // // Print a notify message // const CECMapDlgsMgr::PointMap& aWayPoints = pGameUI.GetMapDlgsMgr().GetTransPoint(); // CECMapDlgsMgr::PointMap::const_iterator itr = aWayPoints.find(pCmd.waypoint); // if(itr != aWayPoints.end()) // { // g_pGame.GetGameRun().AddFixedMessage(FIXMSG_NEWWAYPOINT, (itr.second).strName); // bool bCanPopUITips = true; // int count = CECUIConfig::Instance().GetGameUI().GetTaskIDDisableWayPointsUITipsCount(); // // ¼ì²éÉíÉÏÊÇ·ñÓнûÖ¹µ¯³ötipsµÄÈÎÎñ // for (int i=0;i 0) { SelectTarget(0); return; } // Some work have lower priority pCurWork = m_pWorkMan.GetRunningWork(Host_work_ID.WORK_MOVETOPOS); if (pCurWork != null) { ((CECHPWorkMove)pCurWork).PressCancel(); return; } } public void StopMovement() { m_MoveCtrl.SendStopMoveCmd(playerTransform.position, 5f, (int)GPMoveMode.GP_MOVE_WALK); } // Return to a target town through skill // 通过技能返回目标城镇 // This method implements the Goto logic from the original C++ code // 此方法实现了原始 C++ 代码中的 Goto 逻辑 private bool Goto(int idInst, Vector3 vPos, int iParallelWorldID) { // Jump to instance (change world/instance) // 跳转到实例(更改世界/实例) // Note: JumpToInstance is currently a stub in CECGameRun, so we skip the call for now // 注意:JumpToInstance 目前在 CECGameRun 中是一个存根,所以我们现在跳过调用 // if (CECGameRun.Instance != null && !CECGameRun.Instance.JumpToInstance(idInst, vPos, iParallelWorldID)) // { // Debug.LogError($"CECHostPlayer::Goto, Failed to jump to instance {idInst}"); // return false; // } // Stop all current work and goto specified position // 停止所有当前工作并转到指定位置 if (m_pWorkMan != null) { // Stop auto-moving if active // 如果正在自动移动则停止 // Note: IsAutoMoving check would go here if available // 注意:如果可用,IsAutoMoving 检查将放在这里 // Finish all work // 完成所有工作 m_pWorkMan.FinishAllWork(true); } // Add a little height to ensure player's AABB won't embed with building // 增加一点高度以确保玩家的 AABB 不会嵌入建筑物 vPos.y += 0.1f; // Ensure we are not under ground (terrain height check would go here) // 确保我们不会在地下(地形高度检查将放在这里) // Note: Terrain height check is skipped for now as it requires world access // 注意:暂时跳过地形高度检查,因为它需要世界访问 // Set position // 设置位置 SetPos(vPos); // Reset jump state if available // 如果可用则重置跳跃状态 // ResetJump(); // Uncomment if ResetJump method exists // Update camera if available // 如果可用则更新相机 // UpdateFollowCamera(false, 10); // Uncomment if UpdateFollowCamera method exists LitModelHolder.Instance.LoadAllObjectsNearTargetPosition(vPos).Forget(); return true; } public void SetStatusRun(bool value) { if (!isGrounded) { Debug.LogError("Player not in ground"); return; } isRun = value; } public bool IsPlayerMoving() { return m_pWorkMan.IsMoving(); } } }