using BrewMonster.Network; using CSNetwork.C2SCommand; using CSNetwork.GPDataType; using System; using System.Collections.Generic; using System.Runtime.ConstrainedExecution; using System.Text; using UnityEngine; using CSNetwork.Protocols; using CSNetwork; using BrewMonster; public class CECHostMove { ushort m_wMoveStamp; float m_fMoveTime; CECHostPlayer m_pHost; bool m_bStop; const float MOVECMD_INTERVAL = .5f; Vector3 m_vLastSevPos; STOPMOVE m_DelayedStop; ulong cmdstopdelayCounter = 500; ulong cmdmovedelayCounter = 500; ulong m_dwLastTime; Vector3 m_vLastPos; float m_fAverSpeedH; public CECHostMove(CECHostPlayer pHost) { m_wMoveStamp = 0; m_fMoveTime = 0.0f; m_pHost = pHost; m_bStop = false; } public void Tick(ulong dwDeltaTime) { cmdstopdelayCounter += dwDeltaTime; cmdmovedelayCounter += dwDeltaTime; if (cmdstopdelayCounter >= 500 && m_DelayedStop.bValid) { var m = m_DelayedStop; // a_GetTime() -> Environment.TickCount (ms) ulong dwCurrent = (ulong)Mathf.RoundToInt( Time.time * 1000); // iTime: thời gian tích lũy (ms) + delta từ timestamp đến hiện tại int iTime = (int)((m.fTime * 1000f) + ((dwCurrent > m.dwTimeStamp) ? (dwCurrent - m.dwTimeStamp) : 0)); // tính tốc độ trung bình (giây = iTime * 0.001f) float fSpeed = l_CalcAverageSpeed(m_vLastSevPos, m.vPos, iTime * 0.001f, m.fSpeed); int iMoveMode = m.iMoveMode; // make a potential check with tuojigua iMoveMode |= (int)GPMoveMode.GP_MOVE_DEAD; UnityGameSession.Instance.c2s_SendCmdStopMove( m.vPos, fSpeed, iMoveMode, m.byDir, m_wMoveStamp++, iTime ); // Record this position m_vLastSevPos = m.vPos; Reset(); } m_dwLastTime = Math.Max(m_dwLastTime, 1); Vector3 vOffset = m_pHost.transform.position - m_vLastPos; m_fAverSpeedH = EC_Utility.MagnitudeH(vOffset) * 1000.0f / m_dwLastTime; m_vLastPos = m_pHost.transform.position; m_dwLastTime = dwDeltaTime; } public void SendStopMoveCmd(in Vector3 vPos, float fSpeed, int iMoveMode) { Debug.LogWarning("HoangDev : SendStopMoveCmd"); iMoveMode |= (int)GPMoveMode.GP_MOVE_DEAD; if (cmdstopdelayCounter == 500) { Vector3 vDir = m_pHost.transform.forward; byte byDir = EC_Utility.glb_CompressDirH(vDir.x, vDir.z); fSpeed = l_CalcAverageSpeed(m_vLastSevPos, vPos, m_fMoveTime, fSpeed); int iTime = (int)(m_fMoveTime * 1000); UnityGameSession.Instance.c2s_SendCmdStopMove(vPos, fSpeed, iMoveMode, byDir, m_wMoveStamp++, iTime); m_vLastSevPos = vPos; Reset(); } else { Vector3 vDir = m_pHost.transform.forward; byte byDir = EC_Utility.glb_CompressDirH(vDir.x, vDir.z); if (!m_DelayedStop.bValid) { m_DelayedStop.dwTimeStamp = (ulong)Mathf.RoundToInt(Time.time * 1000); m_DelayedStop.fTime = m_fMoveTime; } m_DelayedStop.bValid = true; m_DelayedStop.byDir = byDir; m_DelayedStop.vPos = vPos; m_DelayedStop.iMoveMode = iMoveMode; m_DelayedStop.fSpeed = fSpeed; } m_fMoveTime = 0.0f; } public void SendMoveCmd(in Vector3 vCurPos, in Vector3 vVel, int iMoveMode, bool bForceSend = false) { Vector3 vMoveDir = vVel; float fSpeed = vMoveDir.magnitude; SendMoveCmd(vCurPos, fSpeed, iMoveMode, bForceSend); } void SendMoveCmd(in Vector3 vCurPos, float fSpeed, int iMoveMode, bool bForceSend) { if (m_bStop) { // m_CmdTimeCnt.Reset(); cmdmovedelayCounter = (ulong)( m_fMoveTime * 1000); m_bStop = false; } if (!bForceSend && cmdmovedelayCounter < 500) return; int iTime = (int)(m_fMoveTime * 1000); if (iTime < 200) { if (iTime == 0 || !bForceSend) { // if time is too little, wait again cmdmovedelayCounter = (ulong)(iTime); return; } } cmdmovedelayCounter = 0; m_DelayedStop.bValid = false; fSpeed = l_CalcAverageSpeed(m_vLastSevPos, vCurPos, m_fMoveTime, fSpeed); m_fMoveTime = 0.0f; iMoveMode |= (int)GPMoveMode.GP_MOVE_DEAD; UnityGameSession.Instance.c2s_CmdPlayerMove(vCurPos, vCurPos, iTime/* MOVECMD_INTERVAL */, fSpeed, iMoveMode, m_wMoveStamp++); m_vLastSevPos = vCurPos; } float l_CalcAverageSpeed(in Vector3 p1, in Vector3 p2, float fTime, float fDefSpeed) { if (Mathf.Approximately(fTime, 0f)) return fDefSpeed; Vector3 d = p2 - p1; float fSpeed = d.magnitude / fTime; if (fTime < 0.05f || fSpeed > 50.0f) { // tương đương ASSERT(0) trong C++, ở đây có thể Debug.LogWarning Debug.LogWarning("CalcAverageSpeed: invalid input, fallback to default speed."); return fDefSpeed; } return fSpeed; } private void Reset() { cmdstopdelayCounter = 0; m_bStop = true; m_DelayedStop.bValid = false; } public void GroundMove(float ftime) { m_fMoveTime += ftime; } struct STOPMOVE { public bool bValid; // Valid flag public Vector3 vPos; public float fSpeed; public int iMoveMode; public byte byDir; public ulong dwTimeStamp; public float fTime; }; } public struct CDR_INFO { //the aabb public Vector3 vCenter; //@note : the caller should make sure ext(.x, .y, .z) > 0. By Kuiwu[22/9/2005] public Vector3 vExtent; public float fStepHeight; // Velocity Info public Vector3 vXOZVelDir; public float fYVel; public float fSpeed; // time span ( sec ) public float t; // Gravity acceleration public float fGravityAccel; // the Climb Slope Thresh public float fSlopeThresh; // Tangent plane Info public Vector3 vTPNormal; // Absolute Velocity: output for forcast! public Vector3 vAbsVelocity; //the moving dist public float fMoveDist; };