diff --git a/Assets/NetworkLib/Debug/netstandard2.1/CSNetwork.dll b/Assets/NetworkLib/Debug/netstandard2.1/CSNetwork.dll index f6fbc4c6a9..a217d0e800 100644 Binary files a/Assets/NetworkLib/Debug/netstandard2.1/CSNetwork.dll and b/Assets/NetworkLib/Debug/netstandard2.1/CSNetwork.dll differ diff --git a/Assets/PerfectWorld/Scripts/Common/DataProcess/elementdataman.cs b/Assets/PerfectWorld/Scripts/Common/DataProcess/elementdataman.cs index a04b82e2a3..4f215c16fd 100644 --- a/Assets/PerfectWorld/Scripts/Common/DataProcess/elementdataman.cs +++ b/Assets/PerfectWorld/Scripts/Common/DataProcess/elementdataman.cs @@ -586,11 +586,11 @@ namespace ModelRenderer.Scripts.GameData add_id_data(ID_SPACE.ID_SPACE_ESSENCE, item.id, item); } - foreach (var item in unionscroll_essence_array) - { - add_id_index(ID_SPACE.ID_SPACE_ESSENCE, item.id, DATA_TYPE.DT_UNIONSCROLL_ESSENCE); - add_id_data(ID_SPACE.ID_SPACE_ESSENCE, item.id, item); - } + //foreach (var item in unionscroll_essence_array) + //{ + // add_id_index(ID_SPACE.ID_SPACE_ESSENCE, item.id, DATA_TYPE.DT_UNIONSCROLL_ESSENCE); + // add_id_data(ID_SPACE.ID_SPACE_ESSENCE, item.id, item); + //} } public void SaveDataToTextFile() diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_ManPlayer.cs b/Assets/PerfectWorld/Scripts/Managers/EC_ManPlayer.cs index 236161e2f2..5dd1940d3f 100644 --- a/Assets/PerfectWorld/Scripts/Managers/EC_ManPlayer.cs +++ b/Assets/PerfectWorld/Scripts/Managers/EC_ManPlayer.cs @@ -2,8 +2,11 @@ using BrewMonster.Network; using CSNetwork; using CSNetwork.GPDataType; +using CSNetwork.Protocols.RPCData; +using PerfectWorld.Scripts.Player; using System; using System.Collections; +using System.Collections.Generic; using System.Runtime.InteropServices; using TMPro; using UnityEngine; @@ -16,6 +19,9 @@ namespace PerfectWorld.Scripts.Managers [Serializable] public class EC_ManPlayer : IMsgHandler { + Dictionary m_UkPlayerTab = new Dictionary(); + Dictionary m_PlayerTab = new Dictionary(); + private readonly object m_csPlayerTab = new object(); public int HandlerId => (int)MANAGER_INDEX.MAN_PLAYER; public bool ProcessMessage(ECMSG Msg) { @@ -39,6 +45,11 @@ namespace PerfectWorld.Scripts.Managers OnMsgPlayerMove(Msg); break; } + case int value when value == EC_MsgDef.MSG_PM_PLAYERSTOPMOVE: + { + OnMsgPlayerStopMove(Msg); + break; + } } } else @@ -60,7 +71,8 @@ namespace PerfectWorld.Scripts.Managers byteArray[i] = data[i]; } int cid = BitConverter.ToInt32(byteArray); - switch (Convert.ToInt32(Msg.dwParam2)) + int commandID = Convert.ToInt32(Msg.dwParam2); + switch (commandID) { case CommandID.PLAYER_INFO_1: case CommandID.PLAYER_ENTER_WORLD: @@ -68,6 +80,9 @@ namespace PerfectWorld.Scripts.Managers { if (cid != iHostID) { + info_player_1 info_Player_1 = GPDataTypeHelper.FromBytes((byte[])Msg.dwParam1); + RoleInfo roleInfo = (RoleInfo)Msg.dwParam4; + ElsePlayerEnter(info_Player_1, commandID, roleInfo); GameController.Instance.Log("ElsePlayer has join"); } break; @@ -90,7 +105,7 @@ namespace PerfectWorld.Scripts.Managers EC_ElsePlayer pPlayer = SeekOutElsePlayer(pCmd.id); if (pPlayer) { - //pPlayer->MoveTo(*pCmd); + pPlayer.MoveTo(pCmd); } } } @@ -109,78 +124,161 @@ namespace PerfectWorld.Scripts.Managers GameController.Instance.InitCharacter(info); }; string nameScene = "NPCRender"; - /* UnityGameSession.Instance.LoadScene(nameScene, LoadSceneMode.Single, (value) => + UnityGameSession.Instance.LoadScene(nameScene, LoadSceneMode.Single, (value) => { isDoneNPCRender = value; actLoadChar?.Invoke(); }); nameScene = "WorldRender"; UnityGameSession.Instance.LoadScene(nameScene, LoadSceneMode.Additive, (value) => - { - isDoneWorldRender = value; - actLoadChar?.Invoke(); - });*/ - UnityGameSession.Instance.LoadScene("HoangTest", LoadSceneMode.Single, (value) => { isDoneWorldRender = value; actLoadChar?.Invoke(); }); + //UnityGameSession.Instance.LoadScene("HoangTest", LoadSceneMode.Single, (value) => + //{ + // isDoneWorldRender = value; + // actLoadChar?.Invoke(); + //}); return true; } - public EC_ElsePlayer ElsePlayerEnter() + public EC_ElsePlayer ElsePlayerEnter(info_player_1 info, int iCmd, RoleInfo roleInfo) { - return null; + // If this player's id is in unknown table, remove it because this player + // won't be unknown anymore + if (m_UkPlayerTab.TryGetValue(info.cid, out int value)) + { + if (value != 0) // Pair.second != 0 + { + m_UkPlayerTab.Remove(info.cid); + } + } + + int iAppearFlag = (iCmd == (int)CommandID.PLAYER_ENTER_WORLD) ? + (int)PlayerAppearFlag.APPEAR_ENTERWORLD : (int)PlayerAppearFlag.APPEAR_RUNINTOVIEW; + + // Has player been in active player table ? + EC_ElsePlayer pPlayer = GetElsePlayer(info.cid); + if (pPlayer) + { + // This player has existed in player table, call special initial function + // TODO: fix after pPlayer init + pPlayer.Init(roleInfo, info); + return pPlayer; + } + + // Create a new player + if (!(pPlayer = CreateElsePlayer(roleInfo, info, iAppearFlag))) + { + return null; + } + lock (m_csPlayerTab) + { + if (m_PlayerTab.ContainsKey(info.cid)) + { + m_PlayerTab[info.cid] = pPlayer; + } + else + { + m_PlayerTab.Add(info.cid ,pPlayer); + } + } + return pPlayer; + } + + private EC_ElsePlayer CreateElsePlayer(RoleInfo roleInfo, info_player_1 info, int iAppearFlag) + { + var ob = GameController.Instance.InitCharacter(info); + EC_ElsePlayer elsePlayer = ob.AddComponent(); + elsePlayer.GetComponent().enabled = false; + //init + elsePlayer.Init(roleInfo, info); + return elsePlayer; + } + + public EC_ElsePlayer GetElsePlayer(int cid, long dwBornStamp = 0) + { + lock (m_csPlayerTab) + { + if (!m_PlayerTab.TryGetValue(cid, out var player)) + return null; + if (dwBornStamp != 0) + { + //TO DO: fix after GetBornStamp() is create in code + //if (player.GetBornStamp() != dwBornStamp) + return null; + } + + return player; + } } private EC_ElsePlayer SeekOutElsePlayer(int cid) { - return null; - } - - private cmd_object_move ConvertToStruct(byte[] bytes) - { - if (bytes.Length < Marshal.SizeOf()) + if (!m_PlayerTab.TryGetValue(cid, out var player)) { - return default; + // Couldn't find this else player, put it into unknown player table + m_UkPlayerTab[cid] = cid; + return null; } - cmd_object_move result = new cmd_object_move(); - int preLenghtData = 0; - int lenghtDataType = Marshal.SizeOf(); - byte[] arrByteData = GetBytes(bytes, lenghtDataType, preLenghtData); - result.id = BitConverter.ToInt32(arrByteData); - - preLenghtData += lenghtDataType; - lenghtDataType = Marshal.SizeOf(); - arrByteData = GetBytes(bytes, lenghtDataType, preLenghtData); - result.dest_X = BitConverter.ToSingle(arrByteData); - - preLenghtData += lenghtDataType; - lenghtDataType = Marshal.SizeOf(); - arrByteData = GetBytes(bytes, lenghtDataType, preLenghtData); - result.dest_Y = BitConverter.ToSingle(arrByteData); - - preLenghtData += lenghtDataType; - lenghtDataType = Marshal.SizeOf(); - arrByteData = GetBytes(bytes, lenghtDataType, preLenghtData); - result.dest_Z = BitConverter.ToSingle(arrByteData); - - preLenghtData += lenghtDataType; - lenghtDataType = Marshal.SizeOf(); - arrByteData = GetBytes(bytes, lenghtDataType, preLenghtData); - result.use_time = BitConverter.ToUInt16(arrByteData); - - preLenghtData += lenghtDataType; - lenghtDataType = Marshal.SizeOf(); - arrByteData = GetBytes(bytes, lenghtDataType, preLenghtData); - result.sSpeed = BitConverter.ToInt16(arrByteData); - - preLenghtData += lenghtDataType; - result.move_mode = bytes[preLenghtData + 1]; - return result; + return player; } + + public bool OnMsgPlayerStopMove(ECMSG Msg) + { + cmd_object_stop_move pCmd = GPDataTypeHelper.FromBytes((byte[])Msg.dwParam1); + EC_ElsePlayer pPlayer = SeekOutElsePlayer(pCmd.id); + if (pPlayer) + pPlayer.StopMoveTo(pCmd); + return true; + } + + //private cmd_object_move ConvertToStruct(byte[] bytes) + //{ + // if (bytes.Length < Marshal.SizeOf()) + // { + // return default; + // } + + // cmd_object_move result = new cmd_object_move(); + // int preLenghtData = 0; + // int lenghtDataType = Marshal.SizeOf(); + // byte[] arrByteData = GetBytes(bytes, lenghtDataType, preLenghtData); + // result.id = BitConverter.ToInt32(arrByteData); + + // preLenghtData += lenghtDataType; + // lenghtDataType = Marshal.SizeOf(); + // arrByteData = GetBytes(bytes, lenghtDataType, preLenghtData); + // result.dest_X = BitConverter.ToSingle(arrByteData); + + // preLenghtData += lenghtDataType; + // lenghtDataType = Marshal.SizeOf(); + // arrByteData = GetBytes(bytes, lenghtDataType, preLenghtData); + // result.dest_Y = BitConverter.ToSingle(arrByteData); + + // preLenghtData += lenghtDataType; + // lenghtDataType = Marshal.SizeOf(); + // arrByteData = GetBytes(bytes, lenghtDataType, preLenghtData); + // result.dest_Z = BitConverter.ToSingle(arrByteData); + + // preLenghtData += lenghtDataType; + // lenghtDataType = Marshal.SizeOf(); + // arrByteData = GetBytes(bytes, lenghtDataType, preLenghtData); + // result.use_time = BitConverter.ToUInt16(arrByteData); + + // preLenghtData += lenghtDataType; + // lenghtDataType = Marshal.SizeOf(); + // arrByteData = GetBytes(bytes, lenghtDataType, preLenghtData); + // result.sSpeed = BitConverter.ToInt16(arrByteData); + + // preLenghtData += lenghtDataType; + // result.move_mode = bytes[preLenghtData + 1]; + // return result; + //} + private byte[] GetBytes(byte[] bytes, int length, int index) { byte[] arrByteData = new byte[length]; diff --git a/Assets/PerfectWorld/Scripts/Managers/NPCManager.cs b/Assets/PerfectWorld/Scripts/Managers/NPCManager.cs index 6b8aee75ea..3f80cd6492 100644 --- a/Assets/PerfectWorld/Scripts/Managers/NPCManager.cs +++ b/Assets/PerfectWorld/Scripts/Managers/NPCManager.cs @@ -1,27 +1,30 @@ using UnityEngine; -public class NPCManager : MonoBehaviour +namespace PerfectWorld.Scripts.Managers { - private static NPCManager instance; - - [SerializeField] private GameObject modelPlayerCharacter; - - public static NPCManager Instance + public class NPCManager : MonoBehaviour { - get + private static NPCManager instance; + + [SerializeField] private GameObject modelPlayerCharacter; + + public static NPCManager Instance { - if (instance == null) + get { - instance = FindAnyObjectByType(); - } - return instance; - } - } + if (instance == null) + { + instance = FindAnyObjectByType(); + } + return instance; + } + } - public GameObject GetModelPlayer() - { - var player = Instantiate(modelPlayerCharacter); - player.SetActive(true); - return player; + public GameObject GetModelPlayer() + { + var player = Instantiate(modelPlayerCharacter); + player.SetActive(true); + return player; + } } } diff --git a/Assets/PerfectWorld/Scripts/Network/EC_ManMessageMono.cs b/Assets/PerfectWorld/Scripts/Network/EC_ManMessageMono.cs index 811baf14aa..59345e793f 100644 --- a/Assets/PerfectWorld/Scripts/Network/EC_ManMessageMono.cs +++ b/Assets/PerfectWorld/Scripts/Network/EC_ManMessageMono.cs @@ -8,9 +8,26 @@ namespace BrewMonster [Serializable] public class EC_ManMessageMono : MonoBehaviour { - public EC_ManPlayer EC_ManPlayer; + private static EC_ManMessageMono instance; + + public static EC_ManMessageMono Instance + { + get + { + if(instance == null) + { + instance = FindAnyObjectByType(); + } + return instance; + } + } + + public EC_ManPlayer EC_ManPlayer; + public EC_ManPlayer GetECManPlayer { get => EC_ManPlayer;} + private void Awake() { + instance = this; //TODO: Remove later EC_ManPlayer = new EC_ManPlayer(); EC_ManMessage.RegisterHandler(EC_ManPlayer); diff --git a/Assets/PerfectWorld/Scripts/Players/EC_ElsePlayer.cs b/Assets/PerfectWorld/Scripts/Players/EC_ElsePlayer.cs index 9885ebb9d4..e3d9caf3b6 100644 --- a/Assets/PerfectWorld/Scripts/Players/EC_ElsePlayer.cs +++ b/Assets/PerfectWorld/Scripts/Players/EC_ElsePlayer.cs @@ -1,16 +1,502 @@ +using BrewMonster; +using CSNetwork; +using CSNetwork.GPDataType; +using CSNetwork.Protocols.RPCData; +using System; using UnityEngine; -public class EC_ElsePlayer : MonoBehaviour +namespace PerfectWorld.Scripts.Player { - // Start is called once before the first execution of Update after the MonoBehaviour is created - void Start() + public class EC_ElsePlayer : MonoBehaviour { - + A3DVECTOR3 m_vMoveDir; // Player's velocity + A3DVECTOR3 m_vServerPos; // Player's real position on server + A3DVECTOR3 m_vStopDir; // The direction when player stop moving + // 是否是依附者 = Is it a dependent/attacher? + bool m_bHangerOn; + // 依附者或被依附者id = The ID of the attacher (dependent) or the attached target. + int m_iBuddyId; + bool m_bStopMove; // Stop move flag + public const float MAX_LAGDIST = 10.0f; // Maximum lag distance + A3DVECTOR3 g_vAxisY = new A3DVECTOR3(0.0f, 1.0f, 0.0f); + long m_dwLastMoveTime = 0; // Last move command arrived time + float m_fMoveSpeed; // Move speed + OtherPlayer_Move_Info m_cdr = new OtherPlayer_Move_Info(); + // 和服务器提供的 aabb,无法影响朝向 = The AABB provided by the server cannot affect the facing/orientation + A3DAABB m_aabbServer = new A3DAABB(); + A3DAABB m_aabb = new A3DAABB(); // Player's aabb£¬ÓÃÓÚÏÔʾµÄaabb£¬ÊÜËõ·ÅÓ°Ïì + string m_strName; // Player name + int m_iProfession; // Profession + int m_iGender; // Gender + float m_fScaleBySkill = 1f; + MOVECONST m_MoveConst; // Const used when moving control + + public MOVECONST[] aMoveConsts = new MOVECONST[PROFESSION.NUM_PROFESSION * GENDER.NUM_GENDER] + { + // ÎäÏÀ + // fStepHei fMinAirHei fMinWaterHei fShoreDepth fWaterSurf + new MOVECONST(0.8f, 1.6f, 0.3f, 1.6f, 0.6f), + new MOVECONST(0.8f, 1.6f, 0.3f, 1.5f, 0.55f), + // ·¨Ê¦ + new MOVECONST(0.8f, 1.6f, 0.3f, 1.6f, 0.6f), + new MOVECONST(0.8f, 1.6f, 0.3f, 1.5f, 0.55f), + // Î×ʦ + new MOVECONST(0.8f, 1.6f, 0.3f, 1.6f, 0.6f), + new MOVECONST(0.8f, 1.6f, 0.3f, 1.5f, 0.55f), + // Ñý¾« + new MOVECONST(0.8f, 1.6f, 0.3f, 1.6f, 0.6f), + new MOVECONST(0.8f, 1.6f, 0.3f, 1.5f, 0.55f), + // ÑýÊÞ + new MOVECONST(0.8f, 1.6f, 0.3f, 1.8f, 0.7f), + new MOVECONST(0.8f, 1.6f, 0.3f, 1.6f, 0.6f), + // ´Ì¿Í + new MOVECONST(0.8f, 1.6f, 0.3f, 1.6f, 0.6f), + new MOVECONST(0.8f, 1.6f, 0.3f, 1.5f, 0.55f), + // Óðâ + new MOVECONST(0.8f, 1.6f, 0.3f, 1.6f, 0.6f), + new MOVECONST(0.8f, 1.6f, 0.3f, 1.5f, 0.55f), + // ÓðÁé + new MOVECONST(0.8f, 1.6f, 0.3f, 1.6f, 0.6f), + new MOVECONST(0.8f, 1.6f, 0.3f, 1.5f, 0.55f), + // ½£Áé + new MOVECONST(0.8f, 1.6f, 0.3f, 1.6f, 0.6f), + new MOVECONST(0.8f, 1.6f, 0.3f, 1.5f, 0.55f), + // ÷ÈÁé + new MOVECONST(0.8f, 1.6f, 0.3f, 1.6f, 0.6f), + new MOVECONST(0.8f, 1.6f, 0.3f, 1.5f, 0.55f), + // Ò¹Ó° + new MOVECONST(0.8f, 1.6f, 0.3f, 1.6f, 0.6f), + new MOVECONST(0.8f, 1.6f, 0.3f, 1.5f, 0.55f), + // ÔÂÏÉ + new MOVECONST(0.8f, 1.6f, 0.3f, 1.6f, 0.6f), + new MOVECONST(0.8f, 1.6f, 0.3f, 1.5f, 0.55f), + }; + + public A3DVECTOR3[] aExts = new A3DVECTOR3[PROFESSION.NUM_PROFESSION * GENDER.NUM_GENDER] + { + new A3DVECTOR3(0.4f, 0.9f, 0.4f), // ÎäÏÀ + new A3DVECTOR3(0.3f, 0.85f, 0.3f), + new A3DVECTOR3(0.3f, 0.9f, 0.3f), // ·¨Ê¦ + new A3DVECTOR3(0.3f, 0.85f, 0.3f), + new A3DVECTOR3(0.3f, 0.9f, 0.3f), // Î×ʦ + new A3DVECTOR3(0.3f, 0.85f, 0.3f), + new A3DVECTOR3(0.3f, 0.9f, 0.3f), // Ñý¾« + new A3DVECTOR3(0.3f, 0.85f, 0.3f), + new A3DVECTOR3(0.5f, 1.05f, 0.5f), // ÑýÊÞ + new A3DVECTOR3(0.3f, 0.9f, 0.3f), + new A3DVECTOR3(0.3f, 0.9f, 0.3f), // ´Ì¿Í + new A3DVECTOR3(0.3f, 0.85f, 0.3f), + new A3DVECTOR3(0.3f, 0.9f, 0.3f), // Óðâ + new A3DVECTOR3(0.3f, 0.85f, 0.3f), + new A3DVECTOR3(0.3f, 0.9f, 0.3f), // ÓðÁé + new A3DVECTOR3(0.3f, 0.85f, 0.3f), + new A3DVECTOR3(0.3f, 0.9f, 0.3f), // ½£Áé + new A3DVECTOR3(0.3f, 0.85f, 0.3f), + new A3DVECTOR3(0.3f, 0.9f, 0.3f), // ÷ÈÁé + new A3DVECTOR3(0.3f, 0.85f, 0.3f), + new A3DVECTOR3(0.3f, 0.9f, 0.3f), // Ò¹Ó° + new A3DVECTOR3(0.3f, 0.85f, 0.3f), + new A3DVECTOR3(0.3f, 0.9f, 0.3f), // ÔÂÏÉ + new A3DVECTOR3(0.3f, 0.85f, 0.3f), + }; + + public void Init(RoleInfo roleInfo, info_player_1 Info) + { + m_iProfession = roleInfo.occupation; + m_iGender = roleInfo.gender; + + CalcPlayerAABB(); + + SetServerPos(Info.pos); + SetPos(Info.pos); + + m_cdr.fStepHeight = m_MoveConst.fStepHei; + m_cdr.vExts = m_aabbServer.Extents; + m_cdr.vVelocity.Clear(); + + A3DVECTOR3 vPos = GetPos(); + m_aabb.Center = vPos + new A3DVECTOR3(0.0f, m_aabb.Extents.y, 0.0f); + m_aabb.CompleteMinsMaxs(); + m_aabbServer.Center = vPos + new A3DVECTOR3(0.0f, m_aabbServer.Extents.y, 0.0f); + m_aabbServer.CompleteMinsMaxs(); + } + + void CalcPlayerAABB() + { + int iIndex = m_iProfession * GENDER.NUM_GENDER + m_iGender; + + m_aabb.Extents = aExts[iIndex] * m_fScaleBySkill; + m_aabbServer.Extents = aExts[iIndex]; + m_MoveConst = aMoveConsts[iIndex]; + } + + public void MoveTo(cmd_object_move Cmd) + { + if (Cmd.use_time == 0) + return; + SetServerPos(Cmd.dest); + m_vMoveDir = Cmd.dest - GetPos(); + float fDist = m_vMoveDir.Normalize(); + m_bStopMove = false; + + // If destination position is too far to us, forcely pull player + // to that position. + if (fDist >= MAX_LAGDIST) + { + SetPos(Cmd.dest); + //m_pEPWorkMan->FinishWork(CECEPWork::WORK_MOVE); + return; + } + + long dwTimeNow = Environment.TickCount; + long dwDeltaTime = (dwTimeNow > m_dwLastMoveTime) ? (dwTimeNow - m_dwLastMoveTime) : 0; + m_dwLastMoveTime = dwTimeNow; + if (dwDeltaTime < 500) + dwDeltaTime = 500; + if (dwDeltaTime > 1000) + dwDeltaTime = 1000; + + float fSpeed = (Cmd.sSpeed) / 256f; // short / 256 <=> FIX8TOFLOAT(short) + m_fMoveSpeed = fDist / (dwDeltaTime * 0.001f); + Mathf.Clamp(m_fMoveSpeed, 0.0f, fSpeed * 1.2f); + + } + + public bool MovingTo(float dwDeltaTime) + { + bool bRet = false; + + A3DVECTOR3 vPos, vCurPos = GetPos(); + float fDeltaTime = dwDeltaTime; + + if (m_bStopMove) + { + A3DVECTOR3 vDir = m_vServerPos - vCurPos; + float fDist = vDir.Normalize(); + vPos = MoveStep(vDir, m_fMoveSpeed, fDeltaTime); + + float fMoveDelta = A3d_Magnitude(vPos - vCurPos); + if (Math.Abs(fMoveDelta - 0f) <= float.Epsilon || fMoveDelta >= fDist) //!fMoveDelta <=> (Math.Abs(fMoveDelta - 0f) <= float.Epsilon) Compare with 0 + { + SetPos(m_vServerPos); + bRet = true; + } + else + { + SetPos(vPos); + } + } + else // Just move on + { + // If we have move so far from destination and still don't + // receive new 'move' or 'stop move' command, it's better to + // stop moving and goto last destination at once + float fDist = A3d_Magnitude(m_vServerPos - vCurPos); + if (fDist >= MAX_LAGDIST) + { + SetPos(m_vServerPos); + return true; + } + + A3DVECTOR3 vDir = m_vMoveDir; + vDir.Normalize(); + vPos = MoveStep(vDir, m_fMoveSpeed, fDeltaTime); + SetPos(vPos); + } + + return bRet; + } + + public void StopMoveTo(cmd_object_stop_move Cmd) + { + m_vMoveDir = Cmd.dest - GetPos(); + m_bStopMove = true; + m_fMoveSpeed = (Cmd.sSpeed) / 256f; + m_vStopDir = glb_DecompressDirH(Cmd.dir); + + SetServerPos(Cmd.dest); + + float fDist = m_vMoveDir.Normalize(); + if (fDist >= MAX_LAGDIST || m_fMoveSpeed < 0.01f) + { + m_bStopMove = false; + SetPos(Cmd.dest); + return; + } + + int iMoveMode = Cmd.move_mode; + m_cdr.bTraceGround = true; + } + + // Decompress horizontal direction + A3DVECTOR3 glb_DecompressDirH(byte byDir) + { + float fInter = 360.0f / 256.0f; + + float fRad = Mathf.Deg2Rad * (byDir * fInter); + A3DVECTOR3 v; + v.x = (float)Math.Cos(fRad); + v.z = (float)Math.Sin(fRad); + v.y = 0.0f; + + return v; + } + + private A3DVECTOR3 MoveStep(A3DVECTOR3 vDir, float fSpeed, float fTime) + { + A3DVECTOR3 vRealDir = vDir; + // OnAirMove only accept positive speed value + if (fSpeed < 0.0f) + { + vRealDir = -vDir; + fSpeed = -fSpeed; + } + m_cdr.vCenter = m_aabbServer.Center; + //Debug.LogError("m_aabbServer.Center = " + m_aabbServer.Center.x + "," + m_aabbServer.Center.y + ","+ m_aabbServer.Center.z); + m_cdr.vVelocity = vRealDir * fSpeed; + //Debug.LogError("vVelocity = " + m_cdr.vVelocity.x + "," + m_cdr.vVelocity.y + "," + m_cdr.vVelocity.z); + m_cdr.t = fTime; + m_cdr.bTestTrnOnly = false; + //OtherPlayerMove(m_cdr); + A3DVECTOR3 vDelta = m_cdr.t * m_cdr.vVelocity; + m_cdr.vCenter += vDelta; + + m_cdr.vecGroundNormal = g_vAxisY; + //if (m_cdr.bTraceGround) + // SetGroundNormal(m_cdr.vecGroundNormal); + //else + // SetGroundNormal(g_vAxisY); + + return m_cdr.vCenter - g_vAxisY * m_cdr.vExts.y; + } + + void OtherPlayerMove(OtherPlayer_Move_Info OPMoveInfo) + { + A3DVECTOR3 vDelta = OPMoveInfo.t * OPMoveInfo.vVelocity; + OPMoveInfo.vCenter += vDelta; + + OPMoveInfo.vecGroundNormal = g_vAxisY; + A3DVECTOR3 vGroundPos, vNormal; + + // Now, we directly interpolate the pos, and we don't use bTraceGround + //if (OPMoveInfo.bTestTrnOnly) + //{ + // GetTerrainInfo(OPMoveInfo.vCenter, vGroundPos, vNormal); + // vGroundPos.y += OPMoveInfo.vExts.y; + + // if (OPMoveInfo.vCenter.y < vGroundPos.y + 0.1f) + // OPMoveInfo.vecGroundNormal = vNormal; + + // // verify not below the terrain + // if (OPMoveInfo.vCenter.y < vGroundPos.y) + // OPMoveInfo.vCenter.y = vGroundPos.y; + //} + //else + //{ + // if (VertRayTrace(OPMoveInfo.vCenter, vGroundPos, vNormal, 3.0f)) + // { + // OPMoveInfo.vecGroundNormal = vNormal; + + // vGroundPos.y += OPMoveInfo.vExts.y; + + // // verify not below the ground + // if (OPMoveInfo.vCenter.y < vGroundPos.y) + // OPMoveInfo.vCenter.y = vGroundPos.y; + // } + //} + } + + private float A3d_Magnitude(A3DVECTOR3 v) + { + return Mathf.Sqrt(v.x * v.x + v.y * v.y + v.z * v.z); + } + + // Set server position + public void SetServerPos(A3DVECTOR3 vPos) + { + m_vServerPos = vPos; + // If this player is a mule, change it's rider's server pos too. + if (m_iBuddyId != 0 && !m_bHangerOn) + { + var pPlayer = EC_ManMessageMono.Instance.GetECManPlayer.GetElsePlayer(m_iBuddyId); + if (pPlayer) + pPlayer.SetServerPos(vPos); + } + } + + private void Update() + { + MovingTo(Time.deltaTime); + } + + private void SetPos(A3DVECTOR3 vPos) + { + Vector3 vector = new Vector3(); + vector.x = vPos.x; + vector.y = vPos.y; + vector.z = vPos.z; + transform.position = vector; + + m_aabb.Center = vPos + new A3DVECTOR3(0.0f, m_aabb.Extents.y, 0.0f); + m_aabb.CompleteMinsMaxs(); + m_aabbServer.Center = vPos + new A3DVECTOR3(0.0f, m_aabbServer.Extents.y, 0.0f); + m_aabbServer.CompleteMinsMaxs(); + } + + private A3DVECTOR3 GetPos() + { + A3DVECTOR3 result = new A3DVECTOR3(); + result.x = transform.position.x; + result.y = transform.position.y; + result.z = transform.position.z; + return result; + } } - // Update is called once per frame - void Update() + // Player appear flag + public enum PlayerAppearFlag { - + APPEAR_DISAPPEAR = -1, // Player disappear + APPEAR_ENTERWORLD = 0, // Player join world + APPEAR_RUNINTOVIEW, // Player run into view + APPEAR_GHOST, // Player is in ghost state, in player list but not active + }; + + public struct OtherPlayer_Move_Info + { + // Bounding sphere of avator + public A3DVECTOR3 vCenter; + public A3DVECTOR3 vExts; + public float fStepHeight; + + // Velocity + public A3DVECTOR3 vVelocity; + + // time span ( sec ) + public float t; + + public bool bTraceGround; // Whether trace the ground + public bool bTestTrnOnly; // Trace terrain only + + public A3DVECTOR3 vecGroundNormal; // if bTraceGround is true, this will contain the ground normal when returned + } + + public class A3DAABB + { + public A3DVECTOR3 Center; + public A3DVECTOR3 Extents; + public A3DVECTOR3 Mins; + public A3DVECTOR3 Maxs; + + public A3DAABB() { } + + public A3DAABB(A3DAABB aabb) + { + Center = aabb.Center; + Extents = aabb.Extents; + Mins = aabb.Mins; + Maxs = aabb.Maxs; + } + + public A3DAABB(A3DVECTOR3 mins, A3DVECTOR3 maxs) + { + Mins = mins; + Maxs = maxs; + Center = (mins + maxs) * 0.5f; + Extents = maxs - Center; + } + + // Reset AABB về trạng thái rỗng + public void Clear() + { + Mins = new A3DVECTOR3(999999f, 999999f, 999999f); + Maxs = new A3DVECTOR3(-999999f, -999999f, -999999f); + Center = new A3DVECTOR3(0f, 0f, 0f); + Extents = new A3DVECTOR3(0f, 0f, 0f); + } + + // Thêm 1 điểm vào AABB + public void AddVertex(A3DVECTOR3 v) + { + if (v.x < Mins.x) Mins.x = v.x; + if (v.y < Mins.y) Mins.y = v.y; + if (v.z < Mins.z) Mins.z = v.z; + + if (v.x > Maxs.x) Maxs.x = v.x; + if (v.y > Maxs.y) Maxs.y = v.y; + if (v.z > Maxs.z) Maxs.z = v.z; + + CompleteCenterExts(); + } + + // Hợp nhất 2 AABB + public void Merge(A3DAABB subAABB) + { + if (subAABB.Mins.x < Mins.x) Mins.x = subAABB.Mins.x; + if (subAABB.Mins.y < Mins.y) Mins.y = subAABB.Mins.y; + if (subAABB.Mins.z < Mins.z) Mins.z = subAABB.Mins.z; + + if (subAABB.Maxs.x > Maxs.x) Maxs.x = subAABB.Maxs.x; + if (subAABB.Maxs.y > Maxs.y) Maxs.y = subAABB.Maxs.y; + if (subAABB.Maxs.z > Maxs.z) Maxs.z = subAABB.Maxs.z; + + CompleteCenterExts(); + } + + // Cập nhật Mins, Maxs từ Center + Extents + public void CompleteMinsMaxs() + { + Mins = Center - Extents; + Maxs = Center + Extents; + } + + // Cập nhật Center + Extents từ Mins, Maxs + public void CompleteCenterExts() + { + Center = (Mins + Maxs) * 0.5f; + Extents = Maxs - Center; + } + + // Kiểm tra điểm có nằm trong AABB không + public bool IsPointIn(A3DVECTOR3 v) + { + return !(v.x > Maxs.x || v.x < Mins.x || + v.y > Maxs.y || v.y < Mins.y || + v.z > Maxs.z || v.z < Mins.z); + } + + // Kiểm tra 1 AABB khác có nằm trong AABB này không + public bool IsAABBIn(A3DAABB aabb) + { + return (aabb.Mins.x >= Mins.x && aabb.Maxs.x <= Maxs.x && + aabb.Mins.y >= Mins.y && aabb.Maxs.y <= Maxs.y && + aabb.Mins.z >= Mins.z && aabb.Maxs.z <= Maxs.z); + } + + // Xây AABB từ một tập vertices + public void Build(A3DVECTOR3[] vertices) + { + Clear(); + foreach (var v in vertices) + AddVertex(v); + } + + // Lấy các vertices (8 điểm) của AABB + public A3DVECTOR3[] GetVertices() + { + A3DVECTOR3[] verts = new A3DVECTOR3[8]; + + verts[0] = new A3DVECTOR3(Mins.x, Mins.y, Mins.z); + verts[1] = new A3DVECTOR3(Maxs.x, Mins.y, Mins.z); + verts[2] = new A3DVECTOR3(Maxs.x, Maxs.y, Mins.z); + verts[3] = new A3DVECTOR3(Mins.x, Maxs.y, Mins.z); + + verts[4] = new A3DVECTOR3(Mins.x, Mins.y, Maxs.z); + verts[5] = new A3DVECTOR3(Maxs.x, Mins.y, Maxs.z); + verts[6] = new A3DVECTOR3(Maxs.x, Maxs.y, Maxs.z); + verts[7] = new A3DVECTOR3(Mins.x, Maxs.y, Maxs.z); + + return verts; + } } } diff --git a/Assets/Prefabs/HostPlayer.prefab b/Assets/Prefabs/HostPlayer.prefab index 21128662e4..8edd55e729 100644 --- a/Assets/Prefabs/HostPlayer.prefab +++ b/Assets/Prefabs/HostPlayer.prefab @@ -107,7 +107,7 @@ MonoBehaviour: joystick: {fileID: 0} btnJump: {fileID: 0} btnRun: {fileID: 0} - parentModel: {fileID: 0} + parentModel: {fileID: 78581589932911603} extraGroundDistance: 0.05 radiusEpsilon: 0.005 groundMask: diff --git a/Assets/Scripts/CECHostPlayer.cs b/Assets/Scripts/CECHostPlayer.cs index 500e26dfe7..3be2d7435c 100644 --- a/Assets/Scripts/CECHostPlayer.cs +++ b/Assets/Scripts/CECHostPlayer.cs @@ -8,12 +8,12 @@ using System; using System.IO; using System.Text; using TMPro; -using UnityEditor.SearchService; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.SceneManagement; using UnityEngine.UI; using Scene = UnityEngine.SceneManagement.Scene; +using PerfectWorld.Scripts.Managers; public class CECHostPlayer : MonoBehaviour { @@ -224,6 +224,20 @@ public class CECHostPlayer : MonoBehaviour Debug.LogError("Pos Character = " + pos); joystick = FindAnyObjectByType(); } + + public void InitCharacter(info_player_1 role) + { + string roleName = "(Error decoding name)"; + //if (role.name != null && role.name.ByteArray != null) + //{ + // roleName = Encoding.UTF8.GetString(role.name.ByteArray, 0, role.name.Length); + //} + Vector3 pos = new Vector3(role.pos.x, role.pos.y, role.pos.z); + if (txtName != null) txtName.text = roleName; + transform.position = pos; + SetModelHostPlayer(); + Debug.LogError("Pos Character = " + pos); + } } public enum StateAnim diff --git a/Assets/Scripts/CanvasController.cs b/Assets/Scripts/CanvasController.cs index 143c7ce08a..214f98307d 100644 --- a/Assets/Scripts/CanvasController.cs +++ b/Assets/Scripts/CanvasController.cs @@ -1,5 +1,6 @@ using BrewMonster.UI; using CSNetwork.Protocols.RPCData; +using PerfectWorld.Scripts.Managers; using System.Collections.Generic; using System.Threading; using UnityEngine; diff --git a/Assets/Scripts/GameController.cs b/Assets/Scripts/GameController.cs index 30029b448b..03a846792b 100644 --- a/Assets/Scripts/GameController.cs +++ b/Assets/Scripts/GameController.cs @@ -62,4 +62,16 @@ public class GameController : MonoBehaviour //posGround.y -= 2f; //ground.transform.position = posGround; } + + public GameObject InitCharacter(info_player_1 info) + { + if (characterPrefab == null) + { + Debug.LogError("null prefab"); + return null; + } + CECHostPlayer character = Instantiate(characterPrefab, transform); + character.InitCharacter(info); + return character.gameObject; + } }