Merge pull request 'feature/skill-data' (#85) from feature/skill-data into develop

Reviewed-on: https://git.brew.monster/Unity/perfect-world-unity/pulls/85
This commit is contained in:
hoangvd
2025-12-17 10:22:53 +00:00
25 changed files with 35333 additions and 576 deletions
@@ -248,7 +248,7 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1450290190322086200}
serializedVersion: 2
m_LocalRotation: {x: 0.000000041676675, y: 0.70710677, z: 0.000000009546054, w: -0.7071067}
m_LocalRotation: {x: 0.000000041676678, y: 0.7071068, z: 0.000000009546055, w: -0.70710677}
m_LocalPosition: {x: 0.20218171, y: -0.00000011874363, z: 0.14265004}
m_LocalScale: {x: 1, y: 0.99999994, z: 1}
m_ConstrainProportionsScale: 0
@@ -559,7 +559,7 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3779568298678900252}
serializedVersion: 2
m_LocalRotation: {x: -0.0000024752133, y: -0.24174231, z: 0.0000009670787, w: 0.97034043}
m_LocalRotation: {x: -0.0000024752135, y: -0.24174233, z: 0.0000009670788, w: 0.9703405}
m_LocalPosition: {x: 0.2888395, y: 0.0000000024365652, z: 0.00000007817289}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
@@ -592,7 +592,7 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4030888598971003578}
serializedVersion: 2
m_LocalRotation: {x: -0.6044032, y: -0.07699761, z: -0.7905391, w: 0.061774462}
m_LocalRotation: {x: -0.60440326, y: -0.07699761, z: -0.79053915, w: 0.061774462}
m_LocalPosition: {x: -0.18489406, y: 0.12445245, z: 0.05787985}
m_LocalScale: {x: 0.99999994, y: 1, z: 1}
m_ConstrainProportionsScale: 0
@@ -1012,7 +1012,7 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4948442401136316024}
serializedVersion: 2
m_LocalRotation: {x: -0.4488744, y: 0.51203674, z: -0.54636633, w: 0.4876617}
m_LocalRotation: {x: -0.44887444, y: 0.5120368, z: -0.5463664, w: 0.48766172}
m_LocalPosition: {x: -0.1453542, y: -0.04050339, z: -0.038502775}
m_LocalScale: {x: 1, y: 0.99999994, z: 0.99999994}
m_ConstrainProportionsScale: 0
@@ -1044,7 +1044,7 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4997153185552211034}
serializedVersion: 2
m_LocalRotation: {x: 0.65481967, y: 0.0053792964, z: 0.019061971, w: -0.7555255}
m_LocalRotation: {x: 0.6548197, y: 0.0053792964, z: 0.019061973, w: -0.7555255}
m_LocalPosition: {x: 0.42279825, y: -0.000000058457182, z: 0.00000035064298}
m_LocalScale: {x: 1, y: 0.99999994, z: 0.99999994}
m_ConstrainProportionsScale: 0
@@ -1350,7 +1350,7 @@ GameObject:
serializedVersion: 6
m_Component:
- component: {fileID: 8291201483499919416}
- component: {fileID: 5100284403898444692}
- component: {fileID: 884070991123099207}
m_Layer: 0
m_Name: "\u96CC\u6027\u51E4\u7FBD\u9E7F"
m_TagString: Untagged
@@ -1374,7 +1374,7 @@ Transform:
- {fileID: 8685953938703042471}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &5100284403898444692
--- !u!114 &884070991123099207
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
@@ -126,6 +126,13 @@ namespace BrewMonster.Managers
@@ -15,7 +15,6 @@ public class CECNPCMan : IMsgHandler
private Dictionary<int, CECNPC> m_NPCTab = new Dictionary<int, CECNPC>(512);
private Dictionary<int, int> m_UkNPCTab = new Dictionary<int, int>(32);
List<CECNPC> m_aDisappearNPCs = new List<CECNPC>(32);
public int HandlerId => (int)MANAGER_INDEX.MAN_NPC;
@@ -285,7 +284,10 @@ public class CECNPCMan : IMsgHandler
private bool OnMsgNPCStopMove(ECMSG msg)
{
cmd_object_stop_move pCmd = EC_Utility.ByteArrayToStructure<cmd_object_stop_move>((byte[])msg.dwParam1);
if(-2041571143 == pCmd.id)
{
BMLogger.Log("HoangDev: OnMsgNPCStopMove NPCID: " + pCmd.id);
}
CECNPC pNPC = SeekOutNPC(pCmd.id);
if (pNPC)
pNPC.StopMoveTo(pCmd);
@@ -14,7 +14,7 @@ using UnityEngine;
public class CECObject : MonoBehaviour
{
protected static int ALPHA_HASH = Shader.PropertyToID("_Alpha");
protected Quaternion targetRotation;
protected Quaternion startRotation; // Store starting rotation for Slerp
@@ -111,13 +111,13 @@ public class CECObject : MonoBehaviour
m_bAdjustOrient = false;
}
// Set destination orientation of model
public void SetDestDirAndUp(Vector3 vDir, Vector3 vUp, float dwTime)
public void SetDestDirAndUp(A3DVECTOR3 vDir, Vector3 vUp, float dwTime)
{
m_bAdjustOrient = true;
m_dwOrientTime = dwTime;
m_dwOrientTimeCnt = 0;
startRotation = transform.rotation; // Store current rotation as start
targetRotation = Quaternion.LookRotation(vDir, Vector3.up);
targetRotation = Quaternion.LookRotation(EC_Utility.ToVector3(vDir), Vector3.up);
}
// Calculate distance between this object and specified position
@@ -184,7 +184,7 @@ public class CECObject : MonoBehaviour
{
vDir.Normalize();
}
SetDestDirAndUp(vDir, g_vAxisY, timeturn);
SetDestDirAndUp(EC_Utility.ToA3DVECTOR3(vDir), g_vAxisY, timeturn);
}
protected virtual void Update()
{
@@ -555,7 +555,6 @@ namespace BrewMonster
protected void ClearComActFlagAllRankNodes(bool v)
{
BMLogger.LogError("ClearComActFlagAllRankNodes " + gameObject.name + ": " + m_PlayerInfo.cid);
EventBus.PublishChannel(m_PlayerInfo.cid, new ClearComActFlagAllRankNodesEvent(v));
}
public bool PlayAttackAction(int nAttackSpeed, ref int attackTime, CECAttackEvent attackEvent)
@@ -697,9 +696,6 @@ namespace BrewMonster
public int GetShowingWeaponType()
{
//todo: mr Hoang should double check it
return 10;
int weapon_type = 0;
if (CanShowFashionWeapon((int)m_uAttackType, m_iFashionWeaponType) &&
m_aEquips[(int)IndexOfIteminEquipmentInventory.EQUIPIVTR_FASHION_WEAPON] != 0)
@@ -393,6 +393,10 @@ public class CECModel
EventBus.PublishChannel(iNFO.nid, new QueueNPCActionEvent(szActName));
return true;
}
public void StopChannelAction(int nChannel, bool bStopAct, bool bStopFx = false)
{
//TODO: Implement StopChannelAction
}
public struct QueueNPCActionEvent
{
public string AnimationName;
@@ -46,7 +46,7 @@ public class CECMonster : CECNPC
SetSelectable(false);
transform.position = EC_Utility.ToVector3(info.pos);
transform.forward = EC_Utility.glb_DecompressDirH(info.dir);
transform.forward = EC_Utility.ToVector3(EC_Utility.glb_DecompressDirH(info.dir));
StartWork((int)WorkType.WT_NOTHING, (int)WorkID.WORK_STAND);
return true;
+236 -95
View File
@@ -1,21 +1,20 @@
using Animancer;
using BrewMonster;
using BrewMonster.Managers;
using BrewMonster.Scripts;
using CSNetwork;
using CSNetwork.GPDataType;
using ModelRenderer.Scripts.Common;
using System;
using System.IO;
using System.Threading.Tasks;
using Unity.VisualScripting;
using UnityEngine;
public class CECNPC : CECObject
{
protected INFO m_NPCInfo;
[SerializeField] protected INFO m_NPCInfo;
protected private uint m_dwStates;
protected private uint m_dwStates2;
protected private Vector3 m_vServerPos;
protected private A3DVECTOR3 m_vServerPos;
protected private int m_iRandomProp;
protected private int m_iMoveEnv;
protected int m_idMaster;
@@ -25,7 +24,7 @@ public class CECNPC : CECObject
protected float m_fDistToHostH;
protected OtherPlayer_Move_Info m_cdr;
protected float m_fTouchRad = 1f;
protected Vector3 m_vMoveDir;
protected A3DVECTOR3 m_vMoveDir;
protected int m_iPassiveMove;
protected bool m_bStopMove;
protected bool m_bStartFight;
@@ -39,16 +38,21 @@ public class CECNPC : CECObject
protected CECCounter m_TransCnt = new CECCounter();
protected int m_StartDisappearCnt;
protected bool m_bAboutToDie;
protected Vector3 m_vStopDir;
protected A3DVECTOR3 m_vStopDir;
protected ROLEEXTPROP m_ExtProps;
protected ROLEBASICPROP m_BasicProps;
protected CECNPCModelPolicy m_pNPCModelPolicy;
protected CECPolicyAction m_pPolicyAction;
public int m_iMMIndex;
public int m_idAttackTarget;
public UINPC m_npcUI;
protected UINPC m_npcUI;
CECCounter m_IdleCnt = new CECCounter();
protected float m_nFightTimeLeft = 0; // Work Fight time left
[SerializeField] protected float m_fMoveSpeed;
[SerializeField] protected CharacterController _characterController;
[SerializeField] protected bool isDebug;
[SerializeField] protected NPCVisual npcVisual;
protected static CECStringTab m_ActionNames;
@@ -59,8 +63,12 @@ public class CECNPC : CECObject
public virtual void SetUpCECNPC(CECNPCMan pNPCMan)
{
base.SetUpCECObject();
m_vServerPos = new Vector3();
m_vServerPos = new A3DVECTOR3();
m_iCID = (int)Class_ID.OCID_NPC;
m_DisappearCnt.SetPeriod(5000);
m_IdleCnt.SetPeriod(25000);
m_IdleCnt.IncCounter(UnityEngine.Random.Range(0, 6000));
m_pNPCModelPolicy = new CECNPCModelDefaultPolicy(this);
}
public string GetName()
@@ -74,7 +82,7 @@ public class CECNPC : CECObject
m_NPCInfo.vis_tid = info.vis_tid;
m_dwStates = (uint)info.state;
m_dwStates2 = (uint)info.state2;
m_vServerPos = EC_Utility.ToVector3(info.pos);
m_vServerPos = info.pos;
m_iRandomProp = (info.state & 0x0f00) >> 8;
m_pNPCModelPolicy = new CECNPCModelDefaultPolicy(this);
m_idSelTarget = 0;
@@ -83,7 +91,7 @@ public class CECNPC : CECObject
m_iCurWork = 0;
m_bStartFight = false;
m_bAboutToDie = false;
m_DisappearCnt.SetPeriod(5000);
m_StartDisappearCnt = 0;
m_BasicProps = new ROLEBASICPROP(true); // struct mặc định, các trường số = 0, mảng đã tạo
@@ -95,7 +103,11 @@ public class CECNPC : CECObject
: (info.state & PlayerNPCState.GP_STATE_NPC_SWIM) != 0 ? Move_environment.MOVEENV_WATER
: Move_environment.MOVEENV_GROUND);
var npcVisual = GetComponent<NPCVisual>();
npcVisual = GetComponent<NPCVisual>();
if (npcVisual == null)
{
BMLogger.LogError("HoangDev npcVisual");
}
m_pNPCModelPolicy.SetNpcVisual(npcVisual);
m_npcUI = GetComponentInChildren<UINPC>();
@@ -164,7 +176,7 @@ public class CECNPC : CECObject
var pHost = CECGameRun.Instance.GetHostPlayer();
if (pHost != null)
{
m_fDistToHost = Vector3.Distance(m_vServerPos, pHost.transform.position);
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));
@@ -178,8 +190,37 @@ public class CECNPC : CECObject
switch (Msg.dwMsg)
{
case long value when value == EC_MsgDef.MSG_NM_NPCATKRESULT: OnMsgNPCAtkResult(Msg); break;
case long value when value == EC_MsgDef.MSG_NM_NPCSTARTPLAYACTION: OnMsgNPCStartPlayAction(Msg); break;
}
}
private void OnMsgNPCStartPlayAction(ECMSG Msg)
{
if (IsInPolicyAction())
CheckStopPolicyAction();
cmd_object_start_play_action cmd = GPDataTypeHelper.FromBytes<cmd_object_start_play_action>((byte[])Msg.dwParam1);
StartWork((int)WorkType.WT_INTERRUPT, (int)WorkID.WORK_POLICYACTION, 0, cmd);
}
private void CheckStopPolicyAction()
{
if (!IsInPolicyAction()) return;
WorkFinished((int)WorkID.WORK_POLICYACTION);
if (m_pPolicyAction != null)
{
m_pNPCModelPolicy.StopChannelAction();
m_pPolicyAction = null;
m_nPolicyActionIntervalTimer = 0;
}
}
private bool IsInPolicyAction()
{
return m_pPolicyAction != null;
}
public void OnMsgAttackHostResult(int idHost, int nDamage, int nFlag, int nSpeed)
{
//BMLogger.LogError("HoangDev: OnMsgAttackHostResultNPC");
@@ -416,6 +457,11 @@ public class CECNPC : CECObject
switch (m_iCurWork)
{
case (int)WorkID.WORK_MOVE: TickWork_Move(Time.deltaTime); break;
case (int)WorkID.WORK_STAND: TickWork_Stand(Time.deltaTime); break;
case (int)WorkID.WORK_FIGHT: TickWork_Fight(Time.deltaTime); break;
case (int)WorkID.WORK_SPELL: TickWork_Spell(Time.deltaTime); break;
case (int)WorkID.WORK_DEAD: TickWork_Dead(Time.deltaTime); break;
//case (int)WorkID.WORK_POLICYACTION: TickWork_PolicyAction(Time.deltaTime); break;
}
// Calculate distance to host player
@@ -441,6 +487,60 @@ public class CECNPC : CECObject
StartAdjustTransparency(-1.0f, GetTransparentLimit(), 500);
}
}
private void TickWork_Dead(float deltaTime)
{
}
private void TickWork_Spell(float deltaTime)
{
}
private void TickWork_Fight(float deltaTime)
{
m_nFightTimeLeft -= deltaTime;
if (m_nFightTimeLeft < 0)
{
m_nFightTimeLeft = 0;
WorkFinished((int)WorkID.WORK_FIGHT);
return;
}
NPCTurnFaceTo(m_idAttackTarget, 100);
A3DVECTOR3 vDir = m_vServerPos - GetPos();
float fDist = vDir.Normalize();
if (fDist > 0.0001f)
{
float fMoveDist = 10.0f * deltaTime * 0.001f;
if (fMoveDist > fDist)
fMoveDist = fDist;
SetPos(EC_Utility.ToVector3(GetPos() + vDir * fMoveDist));
}
}
private void TickWork_Stand(float deltaTime)
{
if (m_IdleCnt.IncCounter(deltaTime * 1000))
{
m_IdleCnt.Reset();
if (IsMonsterOrPet())
{
PlayModelAction((int)NPCActionIndex.ACT_IDLE);
if (IsPetNPC() && !IsDead() && !IsDisappearing())
{
//OnPetSays(CECPetWords::TW_REST);
}
}
else
PlayModelAction((int)NPCActionIndex.ACT_NPC_IDLE1 + UnityEngine.Random.Range(0, 2));
}
}
public void DestroySelf()
{
Destroy(gameObject);
@@ -493,10 +593,10 @@ public class CECNPC : CECObject
}
else if (MovingTo(dwDeltaTime))
{
/* if (!IsDirFixed())
{
SetDestDirAndUp(m_vStopDir, g_vAxisY, 150);
}*/
if (!IsDirFixed())
{
SetDestDirAndUp((m_vStopDir), g_vAxisY, 150);
}
WorkFinished((int)WorkID.WORK_MOVE);
@@ -507,11 +607,11 @@ public class CECNPC : CECObject
public void Release()
{
// Release current skill if it exists
/* if (m_pCurSkill)
{
delete m_pCurSkill;
m_pCurSkill = NULL;
}*/
/*if (m_pCurSkill)
{
delete m_pCurSkill;
m_pCurSkill = NULL;
}*/
// Clear extend states before model is released
/* ClearShowExtendStates();
@@ -558,67 +658,59 @@ public class CECNPC : CECObject
}
public bool MovingTo(float deltaTime)
{
bool reachedDestination = false;
Vector3 curPos = transform.position;
bool bRet = false;
A3DVECTOR3 vCurPos = EC_Utility.ToA3DVECTOR3(transform.position);
if (m_bStopMove)
{
// Tính hướng đến serverPos
Vector3 dir = (m_vServerPos - curPos);
float dist = dir.magnitude;
if (dist > 0.001f)
A3DVECTOR3 vDir = m_vServerPos - vCurPos;
float fDist = vDir.Normalize();
A3DVECTOR3 vPos = vDir * m_fMoveSpeed * deltaTime;
float fMoveDelta = Vector3.Magnitude(EC_Utility.ToVector3(vPos) - EC_Utility.ToVector3(vCurPos));
// If already very close to destination, consider it reached
if (fMoveDelta >= fDist)
{
dir.Normalize();
// Di chuyển một bước
Vector3 moveDelta = dir * m_fMoveSpeed * deltaTime;
if (moveDelta.magnitude >= dist)
{
// Nếu vượt quá đích thì teleport
_characterController.enabled = false;
transform.position = m_vServerPos;
_characterController.enabled = true;
reachedDestination = true;
FaceDirectionImmediate(moveDelta);
}
else
{
_characterController.Move(moveDelta);
FaceDirectionImmediate(moveDelta);
}
// Already at destination
_characterController.enabled = false;
transform.position = EC_Utility.ToVector3(m_vServerPos);
_characterController.enabled = true;
bRet = true;
}
else
{
_characterController.Move(EC_Utility.ToVector3(vPos));
FaceDirectionImmediate(EC_Utility.ToVector3(vPos));
}
}
else // đang move bình thường
{
float fDist = Vector3.Magnitude(EC_Utility.ToVector3(m_vServerPos) - EC_Utility.ToVector3(vCurPos));
float dist = (m_vServerPos - curPos).magnitude;
if (IsLag(dist))
if (IsLag(fDist))
{
// Teleport nếu lag xa
_characterController.enabled = false;
transform.position = m_vServerPos;
transform.position = EC_Utility.ToVector3(m_vServerPos);
_characterController.enabled = true;
m_vStopDir = transform.forward;
m_vStopDir = EC_Utility.ToA3DVECTOR3(transform.forward);
return true;
}
Vector3 dir = m_vMoveDir.normalized;
Vector3 moveDelta = dir * m_fMoveSpeed * deltaTime;
A3DVECTOR3 dir = m_vMoveDir;
dir.Normalize();
var vDir = EC_Utility.ToVector3(dir);
Vector3 moveDelta = vDir * m_fMoveSpeed * deltaTime;
if (_characterController == null)
{
BMLogger.LogError(" CECNPC.MovingTo _characterController == null " + gameObject.name);
BMLogger.LogError("CECNPC.MovingTo _characterController == null " + gameObject.name);
}
_characterController.Move(moveDelta);
// Thêm xoay theo trục Y
FaceDirectionSmooth(dir, 10f, deltaTime);
FaceDirectionImmediate(vDir);
}
return reachedDestination;
return bRet;
}
/// <summary>
/// Xoay model NGAY LẬP TỨC theo hướng chỉ định (giữ nguyên trục Y đứng thẳng).
@@ -752,20 +844,28 @@ public class CECNPC : CECObject
{
throw new InvalidOperationException("Invalid work state in WorkFinished");
}
// Release current work
ReleaseWork(m_iCurWorkType);
bool foundNextWork = false;
for (int i = m_iCurWorkType - 1; i >= 0; i--)
{
if (m_aWorks[i] != 0) // giả định m_aWorks là mảng int workIDs
{
m_iCurWorkType = i;
StartWorkByID(m_aWorks[i], 0);
foundNextWork = true;
break;
}
}
// If no lower priority work found, default to WORK_STAND (idle state)
// This matches C++ behavior where NPC should stand when movement finishes
if (!foundNextWork && !IsDead())
{
StartWork((int)WorkType.WT_NORMAL, (int)WorkID.WORK_STAND, 0);
}
// clear passive move flag
if (iWorkID == (int)WorkID.WORK_MOVE)
m_iPassiveMove = 0;
@@ -899,15 +999,20 @@ public class CECNPC : CECObject
}
public void StopMoveTo(cmd_object_stop_move cmd)
{
/* if (IsDead())
return;*/
if (IsDead())
return;
int iMoveMode = cmd.move_mode & (int)GPMoveMode.GP_MOVE_MASK;
m_vMoveDir = EC_Utility.ToVector3(cmd.dest) - transform.position;
cmd.dest = new A3DVECTOR3(
(float)Math.Round(cmd.dest.x, 4),
(float)Math.Round(cmd.dest.y, 4),
(float)Math.Round(cmd.dest.z, 4)
);
m_vMoveDir = (cmd.dest) - EC_Utility.ToA3DVECTOR3(transform.position);
m_bStopMove = true;
m_fMoveSpeed = EC_Utility.FIX8TOFLOAT(cmd.sSpeed);
m_vServerPos = EC_Utility.ToVector3(cmd.dest);
m_vServerPos = cmd.dest;
m_vStopDir = EC_Utility.glb_DecompressDirH(cmd.dir);
// only store the passive move mode
@@ -918,17 +1023,14 @@ public class CECNPC : CECObject
if (IsDirFixed())
{
// hướng cố định, set luôn
transform.forward = m_vStopDir;
transform.forward = EC_Utility.ToVector3(m_vStopDir);
}
float fDist = m_vMoveDir.normalized.magnitude; // Normalize() trả về float trong C++, ở đây cần xử lý lại
m_vMoveDir.Normalize();
float fDist = m_vMoveDir.Normalize();
// Trong các trường hợp dưới thì kéo NPC về đích
if (iMoveMode != (int)GPMoveMode.GP_MOVE_RETURN &&
iMoveMode != (int)GPMoveMode.GP_MOVE_PUSH &&
iMoveMode != (int)GPMoveMode.GP_MOVE_PULL)
iMoveMode != (int)GPMoveMode.GP_MOVE_PUSH &&
iMoveMode != (int)GPMoveMode.GP_MOVE_PULL)
{
bool bPull = false;
@@ -940,10 +1042,10 @@ public class CECNPC : CECObject
else if (fDist < 1.0f)
{
// case 2
Vector3 vDirH = m_vMoveDir;
A3DVECTOR3 vDirH = (m_vMoveDir);
vDirH.y = 0.0f;
vDirH.Normalize();
if (Vector3.Dot(vDirH, m_vStopDir) < 0.7f)
if (DotProduct(vDirH, (m_vStopDir)) < 0.7f)
bPull = true;
}
else if (iMoveMode == (int)GPMoveMode.GP_MOVE_BLINK)
@@ -955,18 +1057,47 @@ public class CECNPC : CECObject
if (bPull)
{
SetPos(EC_Utility.ToVector3(cmd.dest));
if (!IsDirFixed())
{
SetDestDirAndUp(m_vStopDir, g_vAxisY, 150);
}
if (-2041571143 == m_NPCInfo.nid)
{
BMLogger.LogError($"cmd.dest={cmd.dest}");
}
WorkFinished((int)WorkID.WORK_MOVE);
return;
}
}
m_cdr.bTraceGround = true;
if ((cmd.move_mode & (int)GPMoveMode.GP_MOVE_AIR) != 0)
{
m_iMoveEnv = (int)MoveEnvironment.MOVEENV_AIR;
m_cdr.bTraceGround = false;
}
else if ((cmd.move_mode & (int)GPMoveMode.GP_MOVE_WATER) != 0)
{
m_iMoveEnv = (int)MoveEnvironment.MOVEENV_WATER;
m_cdr.bTraceGround = false;
}
else
{
m_iMoveEnv = (int)MoveEnvironment.MOVEENV_GROUND;
if (iMoveMode == (int)GPMoveMode.GP_MOVE_FALL || iMoveMode == (int)GPMoveMode.GP_MOVE_FLYFALL)
m_cdr.bTraceGround = false;
}
if (!IsDirFixed() && m_iPassiveMove == 0)
{
Vector3 vDir = m_vMoveDir;
A3DVECTOR3 vDir = m_vMoveDir;
vDir.y = 0.0f;
if (vDir != Vector3.zero)
if (!vDir.IsZero())
{
vDir.Normalize();
SetDestDirAndUp(vDir, g_vAxisY, 150);
}
}
@@ -980,6 +1111,10 @@ public class CECNPC : CECObject
}
}
}
public static float DotProduct(A3DVECTOR3 v1, A3DVECTOR3 v2)
{
return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
}
public bool GetCHAABB(ref A3DAABB aabb)
{
return m_pNPCModelPolicy.GetCHAABB(ref aabb);
@@ -992,10 +1127,10 @@ public class CECNPC : CECObject
{
if (Cmd.use_time == 0)
return;
var dest = EC_Utility.ToVector3(Cmd.dest);
m_vServerPos = dest;
m_vMoveDir = dest - transform.position;
float fDist = m_vMoveDir.magnitude; // lấy độ dài ban đầu
var dest = Cmd.dest;
m_vServerPos = (dest);
m_vMoveDir = dest - EC_Utility.ToA3DVECTOR3(transform.position);
float fDist = m_vMoveDir.Magnitude(); // lấy độ dài ban đầu
m_vMoveDir.Normalize(); // giả sử Normalize() trả về độ dài trước khi chuẩn hóa
// If destination position is too far, forcely pull player
@@ -1081,9 +1216,7 @@ public class CECNPC : CECObject
case (int)WorkID.WORK_MOVE:
{
// Để tránh trường hợp WORK_MOVE bị ghi đè bởi WORK_SPELL hoặc WORK khác
// dẫn đến NPC sai vị trí, ta sẽ kiểm tra và kéo NPC về đúng server position
var pos = m_vServerPos;
var pos = EC_Utility.ToVector3(m_vServerPos);
var vDelta = pos - transform.position;
float fDist = vDelta.magnitude; // Vector3.magnitude trong Unity
@@ -1114,7 +1247,7 @@ public class CECNPC : CECObject
m_iCurWork = 0;
}
public void StartWork(int iWorkType, int iNewWork, uint dwParam = 0)
public void StartWork(int iWorkType, int iNewWork, uint dwParam = 0, cmd_object_start_play_action cmd_Object_Start_Play_Action = default)
{
Debug.Assert(iWorkType >= 0 && iWorkType < (int)WorkType.NUM_WORKTYPE);
@@ -1167,13 +1300,13 @@ public class CECNPC : CECObject
return;
}
StartWorkByID(iNewWork, dwParam);
StartWorkByID(iNewWork, dwParam, cmd_Object_Start_Play_Action);
}
public bool ShouldDisappear() { return m_DisappearCnt.IsFull(); }
public void StopWork(int iWorkType)
{
}
public void StartWorkByID(int iWorkID, uint dwParam)
public void StartWorkByID(int iWorkID, uint dwParam, cmd_object_start_play_action cmd_Object_Start_Play_Action = default)
{
// Ignore all message if this NPC is dead.
// if (IsDead())
@@ -1186,7 +1319,7 @@ public class CECNPC : CECObject
case (int)WorkID.WORK_SPELL: StartWork_Spell(dwParam); break;
case (int)WorkID.WORK_DEAD: StartWork_Dead(dwParam); break;
case (int)WorkID.WORK_MOVE: StartWork_Move(dwParam); break;
case (int)WorkID.WORK_POLICYACTION: StartWork_PolicyAction(dwParam); break;
case (int)WorkID.WORK_POLICYACTION: StartWork_PolicyAction(cmd_Object_Start_Play_Action); break;
}
// if (iWorkID != WORK_MOVE) m_iPassiveMove = 0;
@@ -1194,6 +1327,10 @@ public class CECNPC : CECObject
}
public void StartWork_Stand(uint dwParam)
{
if (isDebug)
{
BMLogger.LogError("StartWork_Stand ");
}
if (!m_bStartFight)
{
if (IsMonsterOrPet())
@@ -1236,18 +1373,17 @@ public class CECNPC : CECObject
}*/
}
public void StartWork_PolicyAction(uint dwParam)
public void StartWork_PolicyAction(cmd_object_start_play_action cmd_Object_Start_Play_Action)
{
/* if (m_pPolicyAction == null)
m_pPolicyAction = new CECPolicyAction();
/* if (m_pPolicyAction == null)
m_pPolicyAction = new CECPolicyAction();
// Trong C++: m_pPolicyAction->Init((const S2C::cmd_object_start_play_action *)dwParam);
// Sang C#: dwParam không thể cast trực tiếp. Bạn sẽ cần truyền object phù hợp vào.
m_pPolicyAction.Init((S2C.cmd_object_start_play_action)dwParam);
m_pPolicyAction.Tick(0);
m_nPolicyActionIntervalTimer = 0;
CheckStartPolicyAction();*/
m_pPolicyAction.Init((cmd_object_start_play_action)cmd_Object_Start_Play_Action);
m_pPolicyAction.Tick(0);
m_nPolicyActionIntervalTimer = 0;
CheckStartPolicyAction();*/
}
public bool ShouldPlayNewActionFor(int iMoveMode)
@@ -1335,6 +1471,10 @@ public class CECNPC : CECObject
}
m_npcUI.gameObject.SetActive(false);
}
if (isDebug)
{
BMLogger.LogError("PlayModelAction iAction :" + iAction);
}
m_pNPCModelPolicy.PlayModelAction(iAction, bRestart, null);
}
bool IsDisappearing() { return m_DisappearCnt.GetCounter() != 0 ? true : false; }
@@ -1347,6 +1487,7 @@ public class CECNPC : CECObject
}
public INFO GetNPCInfo() { return m_NPCInfo; }
[Serializable]
public struct INFO
{
public int nid; // NPC id
@@ -1358,7 +1499,7 @@ public class CECNPC : CECObject
// Get NPC's real position on server
public A3DVECTOR3 GetServerPos()
{
return EC_Utility.ToA3DVECTOR3(m_vServerPos);
return (m_vServerPos);
}
// Get master id
@@ -55,6 +55,13 @@ public class CECNPCModelDefaultPolicy
}
return true;
}
public override void StopChannelAction()
{
if (m_pNPCModel != null)
{
m_pNPCModel.StopChannelAction(0, true);
}
}
public override bool GetCHAABB(ref A3DAABB aabb)
{
@@ -172,11 +179,17 @@ public class CECNPCModelDefaultPolicy
}
else
{
if (iAction == (int)NPCActionIndex.ACT_DIE || iAction == (int)NPCActionIndex.ACT_NPC_DIE)
if (_npcVisual.isDebug)
{
BMLogger.LogError("CECNPCModelDefaultPolicy::PlayModelAction iAction :" + iAction);
BMLogger.LogError("GetActionName(iAction) :" + GetActionName(iAction));
}
result = _npcVisual.TryPlayAction(GetActionName(iAction), cECAttackEvent);
if (_npcVisual.isDebug)
{
BMLogger.LogError("result :" + result);
}
}
return result;
}
@@ -14,6 +14,6 @@ namespace BrewMonster
public abstract void ClearComActFlag(bool bSignalCurrent);
public abstract bool PlayAttackAction(int nAttackSpeed, CECAttackEvent attackevent);
public abstract bool GetCHAABB(ref A3DAABB ab);
public abstract void StopChannelAction();
}
}
@@ -53,7 +53,7 @@ public class CECNPCServer : CECNPC
m_npcUI.SetName(m_strName);
}
transform.forward = EC_Utility.glb_DecompressDirH(info.dir);
transform.forward = EC_Utility.ToVector3(EC_Utility.glb_DecompressDirH(info.dir));
transform.position = EC_Utility.ToVector3(info.pos);
StartWork((int)WorkType.WT_NOTHING, (int)WorkID.WORK_STAND);
+36 -19
View File
@@ -13,42 +13,50 @@ public class NPCVisual : MonoBehaviour
[SerializeField] private AnimancerState _currentState;
public CECNPC.INFO GetNPCINFO => m_NPCInfo;
#if UNITY_EDITOR
[SerializeField] bool isDebug;
public void DEBUG(string text)
{
if (!isDebug) return;
BMLogger.LogError(text);
}
public bool isDebug;
#endif
public bool TryPlayAction(string animationName, CECAttackEvent cECAttackEvent, bool isHit = false, bool bRestart = true)
{
#if UNITY_EDITOR
DEBUG("HoangDev: TryPlayAction: " + animationName);
if (isDebug)
{
BMLogger.LogError("HoangDev: TryPlayAction: " + animationName);
}
#endif
if (namedAnimancer == null) return false;
#if UNITY_EDITOR
DEBUG("HoangDev: namedAnimancer == null: " + animationName);
if (isDebug)
{
BMLogger.LogError("HoangDev: namedAnimancer == null: " + animationName);
}
#endif
if (namedAnimancer.IsPlaying(animationName)) return false;
#if UNITY_EDITOR
DEBUG("HoangDev: namedAnimancerIsPlaying == null1: " + animationName);
if (isDebug)
{
BMLogger.LogError("HoangDev: namedAnimancerIsPlaying == null1: " + animationName);
}
#endif
_currentState = namedAnimancer.TryPlay(animationName);
if (isHit)
{
_currentState.Events.OnEnd = ()=>SetHitOnEnd(cECAttackEvent);
_currentState.Events.OnEnd = () => SetHitOnEnd(cECAttackEvent);
}
#if UNITY_EDITOR
if (_currentState != null)
DEBUG("HoangDev: _currentState != null1: " + _currentState.Clip.name);
if (isDebug)
{
if (_currentState != null)
BMLogger.LogError("HoangDev: _currentState != null1: " + _currentState.Clip.name);
}
#endif
return _currentState != null;
}
private void SetHitOnEnd(CECAttackEvent cECAttackEvent)
{
cECAttackEvent.m_bSignaled = true;
}
}
public void InitNPCEventDoneHandler(CECNPC.INFO iNFO)
{
m_NPCInfo = iNFO;
@@ -64,16 +72,22 @@ public class NPCVisual : MonoBehaviour
private void OnClearComActFlagEvent(ClearComActFlagEvent @event)
{
#if UNITY_EDITOR
if (_currentState != null)
DEBUG("HoangDev: OnClearComActFlagEvent _currentState:" + _currentState.Clip.name);
if (isDebug)
{
if (_currentState != null)
BMLogger.LogError("HoangDev: OnClearComActFlagEvent _currentState:" + _currentState.Clip.name);
}
#endif
#if UNITY_EDITOR
foreach (var state in _animationQueue)
if (isDebug)
{
DEBUG("HoangDev: OnClearComActFlagEvent state:" + state);
foreach (var state in _animationQueue)
{
BMLogger.LogError("HoangDev: OnClearComActFlagEvent state:" + state);
}
BMLogger.LogError("HoangDev: OnClearComActFlagEvent");
}
DEBUG("HoangDev: OnClearComActFlagEvent");
#endif
_animationQueue.Clear();
}
@@ -109,7 +123,10 @@ public class NPCVisual : MonoBehaviour
if (_currentState.NormalizedTime < 1f) return;
string animName = _animationQueue.Dequeue();
#if UNITY_EDITOR
DEBUG("HoangDev: PlayNext: " + animName);
if (isDebug)
{
BMLogger.LogError("HoangDev: PlayNext: " + animName);
}
#endif
_currentState = namedAnimancer.TryPlay(animName);
}
@@ -1821,7 +1821,17 @@ namespace CSNetwork.GPDataType
}
};
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct cmd_object_start_play_action
{
public int id;
public int play_times;
public int action_last_time;
public int interval_time;
public uint name_length;
public char[] action_name;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct cmd_change_curr_title_re
{
@@ -1850,7 +1860,7 @@ namespace CSNetwork.GPDataType
// In C++, placeholder is byte. It used to first byte of a byte[] data
// but in C# we need to define it as byte[] to hold the whole data.
//public byte placeholder; // Task data ...
public byte[] placeholder; // Task data ...
public byte[] placeholder; // Task data ...
}
// PLAYER_EXT_PROP_BASE
@@ -439,7 +439,6 @@ namespace CSNetwork
case CommandID.OBJECT_STOP_MOVE:
{
int id1 = GPDataTypeHelper.FromBytes<int>(pDataBuf);
//BMLogger.LogError($"### GameDataSend: STOP MOVE ID: {id1}");
if (ISPLAYERID(id1))
{
@@ -448,7 +447,6 @@ namespace CSNetwork
}
else if (ISNPCID(id1))
{
//BMLogger.LogError($"### GameDataSend: NPC STOP MOVE ID: {id1}");
EC_ManMessage.PostMessage(EC_MsgDef.MSG_NM_NPCSTOPMOVE, (int)MANAGER_INDEX.MAN_NPC, 0, pDataBuf,
pCmdHeader);
}
@@ -1,3 +1,4 @@
using CSNetwork.GPDataType;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -8,6 +9,43 @@ namespace BrewMonster
{
public class CECPolicyAction
{
public void Init(cmd_object_start_play_action pCmd)
{
// TODO: CECPolicyAction convert
// Çå³ýÒÑÓÐÊý¾Ý
/* Reset();
// ÉèÖÃЭÒéÊý¾Ý
m_playTimes = pCmd->play_times;
m_actionTime = pCmd->action_last_time;
m_intervalTime = pCmd->interval_time;
if (pCmd->name_length && pCmd->action_name[0])
m_actionName = AString(pCmd->action_name, pCmd->name_length);
// Ñé֤ЭÒéÄÚÈÝ
ASSERT(m_actionTime >= 0); // ÔÊÐí²¥·Å¶¯×÷ʱ¼äΪ0
ASSERT(m_intervalTime >= 0); // ÔÊÐí¶¯×÷²¥·Å¼ä¸ôʱ¼äΪ0
ASSERT(m_actionTime > 0 || m_intervalTime > 0); // ²»ÔÊÐí¶¯×÷²¥·Åʱ¼äºÍ¶¯×÷²¥·Å¼ä¸ôͬʱΪ0
ASSERT(m_actionTime == 0 || m_actionTime > 0 && !m_actionName.IsEmpty()); // ²»ÔÊÐí²¥·Å¶¯×÷ʱµ«¶¯×÷Ãû³ÆÎª¿Õ
ASSERT(m_playTimes > 0); // ²»ÔÊÐí²¥·Å´ÎÊý·ÇÕý
if (m_playTimes > 0 && m_actionTime >= 0 && m_intervalTime >= 0)
m_timeLength = m_playTimes * m_actionTime + (m_playTimes - 1) * m_intervalTime;
// ³õʼ»¯×´Ì¬±äÁ¿
m_validPolicy = true;
if (m_actionTime < 0 || m_intervalTime < 0 || m_actionTime == 0 && m_intervalTime == 0 ||
m_playTimes <= 0)
{
m_validPolicy = false;
}
m_inPolicy = (m_validPolicy && m_timeLength > 0);
m_inPlay = (m_inPolicy && m_playTimes > 0 && m_actionTime > 0);
m_policyTimer = 0;
m_playedTimes = 0;
m_playTimer = 0;
m_internalTimer = 0;*/
}
}
}
+11 -12
View File
@@ -85,8 +85,8 @@ namespace BrewMonster
public Skill390Stub() : base(390)
{
cls = 0;
name = "真·劈空掌";
nativename = "真·劈空掌";
name = "真劈空掌";
nativename = "真劈空掌";
icon = "劈空掌1.dds";
max_level = 1;
type = 1;
@@ -108,17 +108,10 @@ namespace BrewMonster
long_range = 0;
restrict_corpse = 0;
allow_forms = 1;
effect = "1劈空掌.sgc";
doenchant = 1;
dobless = 1;
commoncooldown = 0;
commoncooldowntime = 0;
restrict_weapons.Add(182);
restrict_weapons.Add(0);
effect = "";
range = new Range();
range.type = 0;
pre_skills = new Dictionary<uint, int>();
pre_skills.Add(60, 10);
#if SKILL_SERVER
statestub.Add(new State1());
statestub.Add(new State2());
@@ -155,8 +148,14 @@ namespace BrewMonster
#if SKILL_SERVER
public int GetEnmity(Skill skill) => 3000;
public bool StateAttack(Skill skill) => true;
public bool BlessMe(Skill skill) => true;
public bool StateAttack(Skill skill)
{
return true;
}
public bool BlessMe(Skill skill)
{
return true;
}
public bool TakeEffect(Skill skill) => true;
public float GetEffectdistance(Skill skill) => 12.5f;
public int GetAttackspeed(Skill skill) => 10;
@@ -163,3 +163,10 @@ namespace BrewMonster
}
@@ -161,3 +161,10 @@ namespace BrewMonster
}
@@ -100,3 +100,10 @@ namespace BrewMonster
}
@@ -192,7 +192,7 @@ namespace BrewMonster
{
if (pSkill != null)
{
BMLogger.Log("HoangDev: QuickBar Set Skill Icon: " + (uint)pSkill.GetSkillID() + " : " + ElementSkill.GetIcon((uint)pSkill.GetSkillID()));
//BMLogger.Log("HoangDev: QuickBar Set Skill Icon: " + (uint)pSkill.GetSkillID() + " : " + ElementSkill.GetIcon((uint)pSkill.GetSkillID()));
var nameskill = ElementSkill.GetIcon((uint)pSkill.GetSkillID());
Sprite[] sprites = Resources.LoadAll<Sprite>("iconlist_skill_multisprite");
pCell.SetSkillImage(sprites.FirstOrDefault(s => s.name == nameskill));
+14 -6
View File
@@ -476,7 +476,7 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6780952369966265306}
serializedVersion: 2
m_LocalRotation: {x: 0.020765202, y: 0.6585355, z: -0.01818329, w: 0.7520433}
m_LocalRotation: {x: 0.026024496, y: 0.5726356, z: -0.0181917, w: 0.8191949}
m_LocalPosition: {x: 0, y: 1, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
@@ -525,7 +525,7 @@ GameObject:
- component: {fileID: 2542060226037108388}
- component: {fileID: -3520322077839857420}
- component: {fileID: -2400324395862947468}
- component: {fileID: 8595541918946480801}
- component: {fileID: 6956701954572561772}
m_Layer: 0
m_Name: MonsterPrefab
m_TagString: Untagged
@@ -561,11 +561,17 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 2cd22b82fc76bed46ac948cef9c7119d, type: 3}
m_Name:
m_EditorClassIdentifier:
m_NPCInfo:
nid: 0
tid: 0
vis_tid: 0
m_iMMIndex: 0
m_idAttackTarget: 0
m_npcUI: {fileID: 0}
m_fMoveSpeed: 0
_characterController: {fileID: -2400324395862947468}
isDebug: 0
npcVisual: {fileID: 0}
--- !u!114 &-3520322077839857420
MonoBehaviour:
m_ObjectHideFlags: 0
@@ -606,8 +612,8 @@ CharacterController:
m_SkinWidth: 0.08
m_MinMoveDistance: 0.001
m_Center: {x: 0, y: 1, z: 0}
--- !u!65 &8595541918946480801
BoxCollider:
--- !u!136 &6956701954572561772
CapsuleCollider:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
@@ -624,8 +630,10 @@ BoxCollider:
m_IsTrigger: 0
m_ProvidesContacts: 0
m_Enabled: 1
serializedVersion: 3
m_Size: {x: 2, y: 2, z: 2}
serializedVersion: 2
m_Radius: 0.8
m_Height: 1
m_Direction: 1
m_Center: {x: 0, y: 1, z: 0}
--- !u!1 &7614570036441268122
GameObject:
-1
View File
@@ -2088,7 +2088,6 @@ namespace BrewMonster
m_bMelee = false;
//
// // if there is an attack event currently, we should let it fire now.
BMLogger.LogError("HoangDev: OnMsgHstStopAttack " + gameObject.name);
ClearComActFlagAllRankNodes(true);
cmd_host_stop_attack pCmd = GPDataTypeHelper.FromBytes<cmd_host_stop_attack>((byte[])Msg.dwParam1);
+2 -2
View File
@@ -66,12 +66,12 @@ public static class EC_Utility
Marshal.FreeHGlobal(ptr);
}
}
public static Vector3 glb_DecompressDirH(byte byDir)
public static A3DVECTOR3 glb_DecompressDirH(byte byDir)
{
const float fInter = 360.0f / 256.0f;
float fRad = Mathf.Deg2Rad * (byDir * fInter);
Vector3 v;
A3DVECTOR3 v;
v.x = Mathf.Cos(fRad);
v.z = Mathf.Sin(fRad);
v.y = 0.0f;
File diff suppressed because one or more lines are too long