diff --git a/Assets/NetworkLib/Debug/netstandard2.1/CSNetwork.dll b/Assets/NetworkLib/Debug/netstandard2.1/CSNetwork.dll index 49944829e2..d2e242a49d 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/CECObject.cs b/Assets/PerfectWorld/Scripts/Common/CECObject.cs index ebf894cb7b..cd9215eb53 100644 --- a/Assets/PerfectWorld/Scripts/Common/CECObject.cs +++ b/Assets/PerfectWorld/Scripts/Common/CECObject.cs @@ -4,9 +4,11 @@ public class CECObject : MonoBehaviour { private uint m_dwBornStamp; private bool m_bBornInSight; + private bool m_bSelectable; public void SetBornStamp(uint dwStamp) { m_dwBornStamp = dwStamp; } public void SetBornInSight(bool bFlag) { m_bBornInSight = bFlag; } + public void SetSelectable(bool bSelectable) { m_bSelectable = bSelectable; } public enum ClassID { OCID_OBJECT = 0, diff --git a/Assets/PerfectWorld/Scripts/GameData/EC_RoleType.cs b/Assets/PerfectWorld/Scripts/GameData/EC_RoleType.cs new file mode 100644 index 0000000000..0bd44954e0 --- /dev/null +++ b/Assets/PerfectWorld/Scripts/GameData/EC_RoleType.cs @@ -0,0 +1,22 @@ +using UnityEngine; + +public struct ROLEBASICPROP +{ + public int iLevel; // Level + public int iLevel2; // 2th. level + public int iCurHP; // Current HP + public int iCurMP; // Current MP + public int iExp; // Experience + public int iSP; // Skill point + public int iStatusPt; // Status point + public int iCurAP; // Current AP + public int iAtkDegree; // Attack degree + public int iDefDegree; // Defence degree + public int iCritRate; // Critical rate + public int iCritDamageBonus;// Critical damage bonus + public int iInvisibleDegree;// Invisible degree + public int iAntiInvisibleDegree; // Anti-invisible degree + public int iPenetration; // 穿透力 + public int iResilience; // 抵抗力 + public int iVigour; // 气魄 +}; diff --git a/Assets/PerfectWorld/Scripts/GameData/EC_RoleType.cs.meta b/Assets/PerfectWorld/Scripts/GameData/EC_RoleType.cs.meta new file mode 100644 index 0000000000..8a5c7014a9 --- /dev/null +++ b/Assets/PerfectWorld/Scripts/GameData/EC_RoleType.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: f315b4c1df822c84f90cddb595d11482 \ No newline at end of file diff --git a/Assets/PerfectWorld/Scripts/Managers/CECNPCMan.cs b/Assets/PerfectWorld/Scripts/Managers/CECNPCMan.cs index f9476cbee7..6410d93783 100644 --- a/Assets/PerfectWorld/Scripts/Managers/CECNPCMan.cs +++ b/Assets/PerfectWorld/Scripts/Managers/CECNPCMan.cs @@ -53,20 +53,20 @@ public class CECNPCMan : IMsgHandler int iSize = info_npc.HEADER_SIZE; - if ((info.state & info_npc.GP_STATE_EXTEND_PROPERTY) != 0) + if ((info.state & PlayerNPCState.GP_STATE_EXTEND_PROPERTY) != 0) iSize += sizeof(uint) * NumberDWORDsPlayerNPC.OBJECT_EXT_STATE_COUNT; - if ((info.state & info_npc.GP_STATE_NPC_PET) != 0) + if ((info.state & PlayerNPCState.GP_STATE_NPC_PET) != 0) iSize += sizeof(int); - if ((info.state & info_npc.GP_STATE_NPC_NAME) != 0) + if ((info.state & PlayerNPCState.GP_STATE_NPC_NAME) != 0) { if (buffer.Length < offset + iSize + 1) return false; byte len = buffer[offset + iSize]; iSize += 1 + len; } - if ((info.state & info_npc.GP_STATE_MULTIOBJ_EFFECT) != 0) + if ((info.state & PlayerNPCState.GP_STATE_MULTIOBJ_EFFECT) != 0) { if (buffer.Length < offset + iSize + sizeof(int)) return false; int countEff = BinaryPrimitives.ReadInt32LittleEndian( @@ -75,13 +75,13 @@ public class CECNPCMan : IMsgHandler iSize += countEff * (sizeof(int) + 1); } - if ((info.state & info_npc.GP_STATE_NPC_MAFIA) != 0) + if ((info.state & PlayerNPCState.GP_STATE_NPC_MAFIA) != 0) iSize += sizeof(int); Console.WriteLine( $"HoangDev: NPC_INFO_LIST, nid: {info.nid}, tid: {info.tid}, vis_tid: {info.vis_tid}, pos: {info.pos.x} {info.pos.y} {info.pos.z}"); - NPCEnter(info, false); + NPCEnter(info, false,buffer,offset); offset += iSize; } @@ -90,7 +90,7 @@ public class CECNPCMan : IMsgHandler } return false; } - public bool NPCEnter(in info_npc Info, bool bBornInSight) + public bool NPCEnter(in info_npc Info, bool bBornInSight, ReadOnlySpan packet, int infoOffset) { var npc = GetNPC(Info.nid); if (npc != null) @@ -105,7 +105,7 @@ public class CECNPCMan : IMsgHandler } // T岷 NPC m峄沬 - npc = CreateNPC(Info, bBornInSight); + npc = CreateNPC(Info, bBornInSight, packet, infoOffset); if (npc == null) { BrewMonster.Logger.LogError($"Failed to create NPC ({Info.tid})"); @@ -125,7 +125,7 @@ public class CECNPCMan : IMsgHandler return npc; } - public CECNPC CreateNPC(info_npc Info, bool bBornInSight) + public CECNPC CreateNPC(info_npc Info, bool bBornInSight, ReadOnlySpan packet, int infoOffset) { CECNPC pNPC = null; @@ -169,7 +169,7 @@ public class CECNPCMan : IMsgHandler // Init v峄沬 tid + Info nh瓢 C++ - if (pNPC == null || !pNPC.Init(tid, Info)) + if (pNPC == null || !pNPC.Init(tid, Info, packet, infoOffset)) { // 膽岷 b岷 gi岷 ph贸ng n岷縰 b岷 c贸 t脿i nguy锚n k猫m theo //pNPC?.Release(); diff --git a/Assets/PerfectWorld/Scripts/NPC/CECMonster.cs b/Assets/PerfectWorld/Scripts/NPC/CECMonster.cs index 8b187ee6c8..2fe323302c 100644 --- a/Assets/PerfectWorld/Scripts/NPC/CECMonster.cs +++ b/Assets/PerfectWorld/Scripts/NPC/CECMonster.cs @@ -1,6 +1,7 @@ 锘縰sing BrewMonster; using CSNetwork.GPDataType; using ModelRenderer.Scripts.GameData; +using System; using Unity.VisualScripting; using UnityEngine; @@ -16,13 +17,17 @@ public class CECMonster : CECNPC m_iCID = (int)ClassID.OCID_MONSTER; m_pDBEssence = default; - + m_fTouchRad = m_pDBEssence.size; + m_BasicProps.iLevel = m_pDBEssence.level; + QueueLoadNPCModel(); } - public override bool Init(int tid, info_npc Info) + public override bool Init(int tid, in info_npc info, ReadOnlySpan packet, int infoOffset) { - base.Init(tid, Info); + base.Init(tid, info, packet,infoOffset); var pDB = ElementDataManProvider.GetElementDataMan(); + DATA_TYPE DataType = default ; + m_pDBEssence = (MONSTER_ESSENCE)pDB.get_data_ptr((uint)tid, ID_SPACE.ID_SPACE_ESSENCE,ref DataType); return true; diff --git a/Assets/PerfectWorld/Scripts/NPC/CECNPC.cs b/Assets/PerfectWorld/Scripts/NPC/CECNPC.cs index 1bdac98607..763fc91923 100644 --- a/Assets/PerfectWorld/Scripts/NPC/CECNPC.cs +++ b/Assets/PerfectWorld/Scripts/NPC/CECNPC.cs @@ -3,78 +3,199 @@ using System.Text; using System; using UnityEditor.Rendering; using UnityEngine; +using BrewMonster; +using CSNetwork; +using ModelRenderer.Scripts.Common; public class CECNPC : CECObject { - INFO m_NPCInfo; - private uint m_dwStates; - private uint m_dwStates2; - private A3DVECTOR3 m_vServerPos; - private int m_iRandomProp; - private int m_iMoveEnv; - int m_idMaster; - string m_strName; - int m_idOwnerFaction; + protected INFO m_NPCInfo; + protected private uint m_dwStates; + protected private uint m_dwStates2; + protected private A3DVECTOR3 m_vServerPos; + protected private int m_iRandomProp; + protected private int m_iMoveEnv; + protected int m_idMaster; + protected string m_strName; + protected int m_idOwnerFaction; + protected float m_fDistToHost; + protected float m_fDistToHostH; + protected OtherPlayer_Move_Info m_cdr; + protected float m_fTouchRad; + protected ROLEBASICPROP m_BasicProps; public CECNPC(CECNPCMan pNPCMan) { } - public virtual bool Init(int tid, info_npc Info) + public virtual bool Init(int tid, in info_npc info, ReadOnlySpan packet, int infoOffset) { - m_NPCInfo.nid = Info.nid; + m_NPCInfo.nid = info.nid; m_NPCInfo.tid = tid; - m_NPCInfo.vis_tid = Info.vis_tid; - m_dwStates = (uint)Info.state; - m_dwStates2 = (uint)Info.state2; - m_vServerPos = Info.pos; - m_iRandomProp = (Info.state & 0x0f00) >> 8; + m_NPCInfo.vis_tid = info.vis_tid; + m_dwStates = (uint)info.state; + m_dwStates2 = (uint)info.state2; + m_vServerPos = info.pos; + m_iRandomProp = (info.state & 0x0f00) >> 8; - m_iMoveEnv = (int)((Info.state & PlayerNPCState.GP_STATE_NPC_FLY) != 0 ? EnviromentMoveType.MOVEENV_AIR - : (Info.state & PlayerNPCState.GP_STATE_NPC_SWIM) != 0 ? EnviromentMoveType.MOVEENV_WATER - : EnviromentMoveType.MOVEENV_GROUND); + m_iMoveEnv = (int)((info.state & PlayerNPCState.GP_STATE_NPC_FLY) != 0 ? EnviromentMoveType.MOVEENV_AIR + : (info.state & PlayerNPCState.GP_STATE_NPC_SWIM) != 0 ? EnviromentMoveType.MOVEENV_WATER + : EnviromentMoveType.MOVEENV_GROUND); - // 膽峄峜 ph岷 膽u么i b岷眓g reader, KH脭NG c岷 膽峄昳 Info_npc - var r = new ByteReader(new ReadOnlySpan() ); - var oj_ext_state_count = (int)OBJECT_EXT_STATE.OBJECT_EXT_STATE_COUNT; - uint[] ext = new uint[oj_ext_state_count]; - if ((Info.state & PlayerNPCState.GP_STATE_EXTEND_PROPERTY) != 0) + // 2) C岷痶 鈥溎憉么i鈥 ngay sau ph岷 c峄 膽峄媙h info_npc + int fixedSize = System.Runtime.InteropServices.Marshal.SizeOf(); + var tail = packet.Slice(infoOffset + fixedSize); + + var r = new ByteReader(tail); + + // 3) 膼峄峜 theo c峄 state, gi峄憂g C++ (pData t膬ng d岷) + // EXTEND_PROPERTY + var ojexitStateCount = (uint)OBJECT_EXT_STATE.OBJECT_EXT_STATE_COUNT; + + var ext = new uint[ojexitStateCount]; + if ((info.state & PlayerNPCState.GP_STATE_EXTEND_PROPERTY) != 0) r.ReadInto(ext); - //SetNewExtendStates(0, ext, oj_ext_state_count); + //SetNewExtendStates(0, ext, ojexitStateCount ); + // PET m_idMaster = 0; - if ((Info.state & PlayerNPCState.GP_STATE_NPC_PET) != 0) + if ((info.state & PlayerNPCState.GP_STATE_NPC_PET) != 0) m_idMaster = r.ReadInt32(); - if ((Info.state & PlayerNPCState.GP_STATE_NPC_NAME) != 0) + // NAME + if ((info.state & PlayerNPCState.GP_STATE_NPC_NAME) != 0) { byte len = r.ReadByte(); if (len > 0) - m_strName = Encoding.Unicode.GetString(r.ReadBytes(len)); + { + // ACHAR th瓢峄漬g l脿 UTF-16LE 鈫 len l脿 s峄 byte + var nameBytes = r.ReadBytes(len); + m_strName = System.Text.Encoding.Unicode.GetString(nameBytes); + } } - /*SetSelectable((Info.state & PlayerNPCState.GP_STATE_FORBIDBESELECTED) == 0); + SetSelectable((info.state & PlayerNPCState.GP_STATE_FORBIDBESELECTED) == 0); - if ((Info.state & PlayerNPCState.GP_STATE_MULTIOBJ_EFFECT) != 0) + // MULTIOBJ_EFFECT + if ((info.state & PlayerNPCState.GP_STATE_MULTIOBJ_EFFECT) != 0) { int n = r.ReadInt32(); - for (int i = 0; i < n; i++) { int idT = r.ReadInt32(); char t = (char)r.ReadByte(); AddMultiObjectEffect(idT, t); } - }*/ + for (int i = 0; i < n; i++) + { + int idTarget = r.ReadInt32(); + char cType = (char)r.ReadByte(); + //AddMultiObjectEffect(idTarget, cType); + } + } + // MAFIA m_idOwnerFaction = 0; - if ((Info.state & PlayerNPCState.GP_STATE_NPC_MAFIA) != 0) + if ((info.state & PlayerNPCState.GP_STATE_NPC_MAFIA) != 0) m_idOwnerFaction = r.ReadInt32(); - // 鈥 ph岷 seed collider, kho岷g c谩ch t峄沬 host, v.v. y h峄噒 nh瓢 b岷 tr瓢峄沜 + m_cdr.fStepHeight = 0.4f; + m_cdr.vVelocity.Clear(); + + var pHost = GameController.Instance.GetHostPlayer(); + if (pHost != null) + { + m_fDistToHost = Vector3.Distance(EC_Utility.ToVector3(m_vServerPos), pHost.transform.position); + m_fDistToHostH = Vector2.Distance( + new Vector2(m_vServerPos.x, m_vServerPos.z), + new Vector2(pHost.transform.position.x, pHost.transform.position.z)); + } + return true; } - struct INFO + public void QueueLoadNPCModel() + { + /* if (ShouldUseMasterModel()) + { + if (GetMaster()) + { + return; // 脛脺禄帽脠隆陆脟脡芦脛拢脨脥脢卤拢卢碌陆脧脗赂枚 Tick 录脫脭脴脛拢脨脥 + } // 脦脼路篓禄帽脠隆陆脟脡芦脢卤隆垄脭脻脢卤脢鹿脫脙 NPC 脛拢脨脥 + }*/ + int tid = 0; + string szModelFile = ""; + if (!GetVisibleModel( out tid, out szModelFile)) + { + return; + } + //QueueECModelForLoad(MTL_ECM_NPC, GetNPCInfo().nid, GetBornStamp(), GetServerPos(), szModelFile, tid); + } + public bool GetVisibleModel(out int tid, out string szModelFile) + { + tid = 0; + szModelFile = string.Empty; + + // n岷縰 vis_tid c贸 model file + if (GetModelFile(GetNPCInfo().vis_tid, out szModelFile)) + { + tid = GetNPCInfo().vis_tid; + } + // n岷縰 kh么ng c贸 th矛 th峄 l岷 t峄 tid th瓢峄漬g + else if (GetModelFile(GetNPCInfo().tid, out szModelFile)) + { + tid = GetNPCInfo().tid; + } + + return tid > 0; + } + public bool GetModelFile(int tid, out string szModelFile) + { + szModelFile = string.Empty; + + // L岷 database + var pDB = ElementDataManProvider.GetElementDataMan(); // g_pGame->GetElementDataMan() + DATA_TYPE dataType = default; + + // Gi岷 膽峄媙h get_data_ptr tr岷 v峄 object (Essence) v脿 out DataType + var pDBEssence = pDB.get_data_ptr((uint)tid, ID_SPACE.ID_SPACE_ESSENCE, ref dataType); + if (pDBEssence == null) + return false; + + bool ret = true; + Debug.Log($"HoangDev : DataType : {dataType}"); + + switch (dataType) + { + case DATA_TYPE.DT_MONSTER_ESSENCE: + { + var ess = (MONSTER_ESSENCE)pDBEssence; + szModelFile = ByteToStringUtils.ByteArrayToCP936String( ess.file_model); + Debug.Log($"HoangDev : MONSTER_ESSENCE path : {szModelFile}"); + break; + } + case DATA_TYPE.DT_PET_ESSENCE: + { + var ess = (PET_ESSENCE)pDBEssence; + szModelFile = ByteToStringUtils.ByteArrayToCP936String(ess.file_model); + break; + } + case DATA_TYPE.DT_NPC_ESSENCE: + { + var ess = (NPC_ESSENCE)pDBEssence; + szModelFile = ByteToStringUtils.ByteArrayToCP936String(ess.file_model); + break; + } + default: + ret = false; + break; + } + + Debug.Log($"HoangDev : path 99 : {szModelFile}"); + return ret; + } + + public INFO GetNPCInfo() { return m_NPCInfo; } + + public struct INFO { public int nid; // NPC id public int tid; // Template id public int vis_tid;// template id for shape }; - } public ref struct ByteReader { diff --git a/Assets/Scripts/EC_Utility.cs b/Assets/Scripts/EC_Utility.cs index 7417d80a68..83352e13a8 100644 --- a/Assets/Scripts/EC_Utility.cs +++ b/Assets/Scripts/EC_Utility.cs @@ -34,6 +34,10 @@ public static class EC_Utility { return new System.Numerics.Vector3(v.x, v.y, v.z); } + public static A3DVECTOR3 ToA3DVECTOR3(this UnityEngine.Vector3 v) + { + return new A3DVECTOR3(v.x, v.y, v.z); + } public static Vector3 ToVector3(A3DVECTOR3 a3DVECTOR3) { return new Vector3(a3DVECTOR3.x, a3DVECTOR3.y, a3DVECTOR3.z); diff --git a/Assets/Scripts/Move/EC_CDR.cs b/Assets/Scripts/Move/EC_CDR.cs index a2e7b83b1d..e6e29eb985 100644 --- a/Assets/Scripts/Move/EC_CDR.cs +++ b/Assets/Scripts/Move/EC_CDR.cs @@ -1,4 +1,5 @@ -锘縰sing System; +锘縰sing CSNetwork.GPDataType; +using System; using TMPro; using Unity.VisualScripting; using UnityEngine; @@ -236,3 +237,15 @@ public static class EC_CDR if (vTPNormal != Vector3.zero) CDRInfo.vTPNormal = vTPNormal; } } +public struct OtherPlayer_Move_Info +{ + // Bounding sphere of avator + public A3DVECTOR3 vCenter; + public A3DVECTOR3 vExts; + public float fStepHeight; + public A3DVECTOR3 vVelocity; + 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 +}; \ No newline at end of file