From 5c42c9792bf12f6e3e08a1d2d6b86bb60d06be67 Mon Sep 17 00:00:00 2001 From: VDH Date: Tue, 2 Dec 2025 16:46:47 +0700 Subject: [PATCH] test buff skill --- Assets/PerfectWorld/Scripts/AutoPolicy.meta | 8 + .../PerfectWorld/Scripts/Common/Singleton.cs | 2 +- .../Scripts/Managers/A3DSkillGfxMan.cs | 3 +- .../Scripts/Managers/A3DTerrain2.cs | 1 - .../Scripts/Managers/CECAttacksMan.cs | 8 +- .../Scripts/Managers/CECManager.cs | 1 + .../Scripts/Managers/CECSkillGfxMan.cs | 5 +- .../Scripts/Managers/EC_EPWork.cs | 33 +- .../Scripts/Managers/EC_Faction.cs | 17 +- .../Scripts/Managers/EC_HPWork.cs | 4 + .../Scripts/Managers/EC_HPWorkMelee.cs | 5 +- .../Scripts/Managers/EC_HPWorkStand.cs | 16 +- .../Scripts/Managers/EC_HPWorkTrace.cs | 1778 +++++------ .../Scripts/Managers/EC_ManMatter.cs | 1 - .../Scripts/Managers/EC_ManPlayer.cs | 5 +- .../PerfectWorld/Scripts/Managers/aabbcd.cs | 1 - .../Scripts/Move/CECPlayer.Task.cs | 18 +- Assets/PerfectWorld/Scripts/Move/CECPlayer.cs | 2777 +++++++++-------- Assets/PerfectWorld/Scripts/Move/EC_CDR.cs | 5 +- Assets/PerfectWorld/Scripts/NPC/CECNPC.cs | 2 +- .../Scripts/Network/CSNetwork/GPDataType.cs | 2 +- .../Scripts/Network/EC_ManMessageMono.cs | 10 +- .../Scripts/PlayerState/PlayerIdleState.cs | 1 - .../Scripts/PlayerState/PlayerMoveState.cs | 1 - .../Players/CECPlayerActionController.cs | 317 +- .../Players/CECPlayerActionPlayPolicy.cs | 647 ++-- .../Scripts/Players/EC_ElsePlayer.cs | 23 +- .../Scripts/Skills/CECCastSkillWhenMove.cs | 533 ++++ .../Skills/CECCastSkillWhenMove.cs.meta | 2 + .../Scripts/Skills/ElementSkill.cs | 26 +- .../Scripts/Skills/SkillWrapper.cs | 3 +- .../PerfectWorld/Scripts/Skills/skill177.cs | 1 + .../PerfectWorld/Scripts/Skills/skill178.cs | 1 + Assets/PerfectWorld/Scripts/Skills/skill54.cs | 1 + Assets/PerfectWorld/Scripts/Skills/skill56.cs | 1 + Assets/PerfectWorld/Scripts/Skills/skill57.cs | 1 + Assets/PerfectWorld/Scripts/Skills/skill58.cs | 1 + Assets/PerfectWorld/Scripts/Skills/skill76.cs | 1 + Assets/PerfectWorld/Scripts/UI/CECUIConfig.cs | 3 +- .../PerfectWorld/Scripts/UI/Dialogs/DlgNPC.cs | 2 +- Assets/PerfectWorld/Scripts/UI/HUDPlayer.cs | 1 - Assets/PerfectWorld/Scripts/World/CECWorld.cs | 31 +- Assets/Scripts/CECHostPlayer.cs | 319 +- Assets/Scripts/CECPlayer_Inventory.cs | 823 ++--- Assets/Scripts/EC_Utility.cs | 1 - Assets/Scripts/PlayerVisual.cs | 294 +- 46 files changed, 4198 insertions(+), 3538 deletions(-) create mode 100644 Assets/PerfectWorld/Scripts/AutoPolicy.meta create mode 100644 Assets/PerfectWorld/Scripts/Skills/CECCastSkillWhenMove.cs create mode 100644 Assets/PerfectWorld/Scripts/Skills/CECCastSkillWhenMove.cs.meta diff --git a/Assets/PerfectWorld/Scripts/AutoPolicy.meta b/Assets/PerfectWorld/Scripts/AutoPolicy.meta new file mode 100644 index 0000000000..de055c8137 --- /dev/null +++ b/Assets/PerfectWorld/Scripts/AutoPolicy.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b61cfcd2a7b14114a8a64b79ad4e26ec +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PerfectWorld/Scripts/Common/Singleton.cs b/Assets/PerfectWorld/Scripts/Common/Singleton.cs index 5712814448..5b16cdb2e1 100644 --- a/Assets/PerfectWorld/Scripts/Common/Singleton.cs +++ b/Assets/PerfectWorld/Scripts/Common/Singleton.cs @@ -4,7 +4,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace BrewMonster.Assets.PerfectWorld.Scripts.Common +namespace BrewMonster { public abstract class Singleton where T : class, new() { diff --git a/Assets/PerfectWorld/Scripts/Managers/A3DSkillGfxMan.cs b/Assets/PerfectWorld/Scripts/Managers/A3DSkillGfxMan.cs index 2f639acc0b..34a99d9c05 100644 --- a/Assets/PerfectWorld/Scripts/Managers/A3DSkillGfxMan.cs +++ b/Assets/PerfectWorld/Scripts/Managers/A3DSkillGfxMan.cs @@ -1,5 +1,4 @@ -using BrewMonster.Assets.PerfectWorld.Scripts.Common; -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text; diff --git a/Assets/PerfectWorld/Scripts/Managers/A3DTerrain2.cs b/Assets/PerfectWorld/Scripts/Managers/A3DTerrain2.cs index e78f6de794..745dcd8a0c 100644 --- a/Assets/PerfectWorld/Scripts/Managers/A3DTerrain2.cs +++ b/Assets/PerfectWorld/Scripts/Managers/A3DTerrain2.cs @@ -1,7 +1,6 @@ using BrewMonster.Scripts.Player; using CSNetwork.GPDataType; using NUnit.Framework; -using PerfectWorld.Scripts.Player; using System.Collections.Generic; using System.Linq; using UnityEngine; diff --git a/Assets/PerfectWorld/Scripts/Managers/CECAttacksMan.cs b/Assets/PerfectWorld/Scripts/Managers/CECAttacksMan.cs index ed19fc297b..d562b61676 100644 --- a/Assets/PerfectWorld/Scripts/Managers/CECAttacksMan.cs +++ b/Assets/PerfectWorld/Scripts/Managers/CECAttacksMan.cs @@ -823,7 +823,7 @@ public class CECAttackEvent } else { - CECNPC pNPC = EC_ManMessageMono.Instance?._CECNPCMan?.GetNPC(m_idHost); + CECNPC pNPC = EC_ManMessageMono.Instance?.CECNPCMan?.GetNPC(m_idHost); if (pNPC == null) return true; @@ -908,7 +908,7 @@ public class CECAttackEvent } else if (GPDataTypeHelper.ISNPCID(nID)) { - CECNPC pNPC = EC_ManMessageMono.Instance?._CECNPCMan?.GetNPCFromAll(nID); + CECNPC pNPC = EC_ManMessageMono.Instance?.CECNPCMan?.GetNPCFromAll(nID); if (pNPC != null) { vPos = pNPC.GetPosVector3(); @@ -948,10 +948,10 @@ public class CECAttackEvent { CECNPC pNPC = null; if ((data.dwModifier & (uint)MOD.MOD_SUCCESS) != 0) - pNPC = EC_ManMessageMono.Instance._CECNPCMan.GetNPCFromAll(idTarget); + pNPC = EC_ManMessageMono.Instance.CECNPCMan.GetNPCFromAll(idTarget); else { - pNPC = EC_ManMessageMono.Instance._CECNPCMan.GetNPCFromAll(idTarget); + pNPC = EC_ManMessageMono.Instance.CECNPCMan.GetNPCFromAll(idTarget); if (!pNPC) return true; diff --git a/Assets/PerfectWorld/Scripts/Managers/CECManager.cs b/Assets/PerfectWorld/Scripts/Managers/CECManager.cs index 9b18f8c869..16ea3a3ce6 100644 --- a/Assets/PerfectWorld/Scripts/Managers/CECManager.cs +++ b/Assets/PerfectWorld/Scripts/Managers/CECManager.cs @@ -115,3 +115,4 @@ namespace BrewMonster.Managers + diff --git a/Assets/PerfectWorld/Scripts/Managers/CECSkillGfxMan.cs b/Assets/PerfectWorld/Scripts/Managers/CECSkillGfxMan.cs index e14d4d4215..706e00bf3c 100644 --- a/Assets/PerfectWorld/Scripts/Managers/CECSkillGfxMan.cs +++ b/Assets/PerfectWorld/Scripts/Managers/CECSkillGfxMan.cs @@ -1,5 +1,4 @@ using BrewMonster; -using BrewMonster.Assets.PerfectWorld.Scripts.Common; using BrewMonster.Managers; using BrewMonster.Network; using CSNetwork.GPDataType; @@ -19,7 +18,7 @@ namespace BrewMonster public CECSkillGfxEvent(GfxMoveMode mode) : base(mode) { m_pPlayerMan = EC_ManMessageMono.Instance?.GetECManPlayer; - m_pNPCMan = EC_ManMessageMono.Instance?._CECNPCMan; + m_pNPCMan = EC_ManMessageMono.Instance?.CECNPCMan; } /// @@ -584,7 +583,7 @@ namespace BrewMonster // m_pPlayerMan = pGameRun?.GetWorld()?.GetPlayerMan(); // m_pNPCMan = pGameRun?.GetWorld()?.GetNPCMan(); m_pPlayerMan = EC_ManMessageMono.Instance?.GetECManPlayer; - m_pNPCMan = EC_ManMessageMono.Instance?._CECNPCMan; + m_pNPCMan = EC_ManMessageMono.Instance?.CECNPCMan; } /// diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_EPWork.cs b/Assets/PerfectWorld/Scripts/Managers/EC_EPWork.cs index a278c6f4ef..13fb728c19 100644 --- a/Assets/PerfectWorld/Scripts/Managers/EC_EPWork.cs +++ b/Assets/PerfectWorld/Scripts/Managers/EC_EPWork.cs @@ -1,5 +1,4 @@ using CSNetwork.GPDataType; -using PerfectWorld.Scripts.Player; using System; using System.Collections.Generic; @@ -24,7 +23,7 @@ namespace BrewMonster.Scripts public override void Start() { GetPlayer().m_iMoveMode = (int)MoveMode.MOVE_STAND; - GetPlayer().PlayAction((int)CECPlayer.PLAYER_ACTION_TYPE.ACT_ATTACK_1 + UnityEngine.Random.Range(0, 3)); + GetPlayer().PlayAction((int)PLAYER_ACTION_TYPE.ACT_ATTACK_1 + UnityEngine.Random.Range(0, 3)); GetPlayer().EnterFightState(); } public override void Tick(float dwDeltaTime) @@ -128,18 +127,18 @@ namespace BrewMonster.Scripts GetPlayer().m_iMoveMode = (int)MoveMode.MOVE_STAND; if (m_dwParam != 0) - GetPlayer().PlayAction((int)CECPlayer.PLAYER_ACTION_TYPE.ACT_SITDOWN_LOOP); + GetPlayer().PlayAction((int)PLAYER_ACTION_TYPE.ACT_SITDOWN_LOOP); else { - GetPlayer().PlayAction((int)CECPlayer.PLAYER_ACTION_TYPE.ACT_SITDOWN); - GetPlayer().PlayAction((int)CECPlayer.PLAYER_ACTION_TYPE.ACT_SITDOWN_LOOP, true, 200, true); + GetPlayer().PlayAction((int)PLAYER_ACTION_TYPE.ACT_SITDOWN); + GetPlayer().PlayAction((int)PLAYER_ACTION_TYPE.ACT_SITDOWN_LOOP, true, 200, true); } break; case Idle_work_type.IDLE_REVIVE: - GetPlayer().PlayAction((int)CECPlayer.PLAYER_ACTION_TYPE.ACT_REVIVE); + GetPlayer().PlayAction((int)PLAYER_ACTION_TYPE.ACT_REVIVE); break; case Idle_work_type.IDLE_BOOTH: @@ -346,7 +345,7 @@ namespace BrewMonster.Scripts } private EC_ElsePlayer m_pElsePlayer; - private WorkList[] m_WorkStack = new WorkList[Work_type.NUM_WORKTYPE] + private WorkList[] m_WorkStack = new WorkList[Work_type.NUM_WORKTYPE] { new List(), new List(), @@ -726,7 +725,7 @@ namespace BrewMonster.Scripts m_dwParam = dwParam; } - void Start() + public void Start() { GetPlayer().m_iMoveMode = (int)MoveMode.MOVE_STAND; @@ -744,28 +743,28 @@ namespace BrewMonster.Scripts if (m_dwParam != null) { if (iFlag == 1) - GetPlayer().PlayAction((int)CECPlayer.PLAYER_ACTION_TYPE.ACT_WATERDIE_LOOP); + GetPlayer().PlayAction((int)PLAYER_ACTION_TYPE.ACT_WATERDIE_LOOP); else if (iFlag == 2) - GetPlayer().PlayAction((int)CECPlayer.PLAYER_ACTION_TYPE.ACT_AIRDIE); + GetPlayer().PlayAction((int)PLAYER_ACTION_TYPE.ACT_AIRDIE); else - GetPlayer().PlayAction((int)CECPlayer.PLAYER_ACTION_TYPE.ACT_GROUNDDIE_LOOP); + GetPlayer().PlayAction((int)PLAYER_ACTION_TYPE.ACT_GROUNDDIE_LOOP); } else { if (iFlag == 1) { - GetPlayer().PlayAction((int)CECPlayer.PLAYER_ACTION_TYPE.ACT_WATERDIE); - GetPlayer().PlayAction((int)CECPlayer.PLAYER_ACTION_TYPE.ACT_WATERDIE_LOOP, true, 200, true); + GetPlayer().PlayAction((int)PLAYER_ACTION_TYPE.ACT_WATERDIE); + GetPlayer().PlayAction((int)PLAYER_ACTION_TYPE.ACT_WATERDIE_LOOP, true, 200, true); } else if (iFlag == 2) { - GetPlayer().PlayAction((int)CECPlayer.PLAYER_ACTION_TYPE.ACT_AIRDIE_ST); - GetPlayer().PlayAction((int)CECPlayer.PLAYER_ACTION_TYPE.ACT_AIRDIE, true, 200, true); + GetPlayer().PlayAction((int)PLAYER_ACTION_TYPE.ACT_AIRDIE_ST); + GetPlayer().PlayAction((int)PLAYER_ACTION_TYPE.ACT_AIRDIE, true, 200, true); } else { - GetPlayer().PlayAction((int)CECPlayer.PLAYER_ACTION_TYPE.ACT_GROUNDDIE); - GetPlayer().PlayAction((int)CECPlayer.PLAYER_ACTION_TYPE.ACT_GROUNDDIE_LOOP, true, 200, true); + GetPlayer().PlayAction((int)PLAYER_ACTION_TYPE.ACT_GROUNDDIE); + GetPlayer().PlayAction((int)PLAYER_ACTION_TYPE.ACT_GROUNDDIE_LOOP, true, 200, true); } } } diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_Faction.cs b/Assets/PerfectWorld/Scripts/Managers/EC_Faction.cs index 5961887f3e..54a576234a 100644 --- a/Assets/PerfectWorld/Scripts/Managers/EC_Faction.cs +++ b/Assets/PerfectWorld/Scripts/Managers/EC_Faction.cs @@ -13,12 +13,12 @@ namespace BrewMonster public int m_nMemNum; public int GetLevel() { return m_nLev; } -} + } public class CECFactionMan { Dictionary m_FactionMap; - + public List m_alliance = new List(); public Faction_Info GetFaction(uint uId, bool bRequestFromServer) { if (!m_FactionMap.TryGetValue(uId, out var it)) @@ -30,5 +30,18 @@ namespace BrewMonster return it; } + public bool IsFactionAlliance(int fid) + { + if (fid == 0) + return false; + + foreach (var f in m_alliance) + { + if (f == fid) + return true; + } + + return false; + } } } diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_HPWork.cs b/Assets/PerfectWorld/Scripts/Managers/EC_HPWork.cs index 8945308028..dda87663b2 100644 --- a/Assets/PerfectWorld/Scripts/Managers/EC_HPWork.cs +++ b/Assets/PerfectWorld/Scripts/Managers/EC_HPWork.cs @@ -326,6 +326,10 @@ namespace BrewMonster.Scripts } return true; } + public bool CanCastSkillImmediately(int idSkill) + { + return !IsSpellingMagic() && !HasWorkRunningOnPriority(Work_priority.PRIORITY_2); + } bool CanRunSimultaneously(CECHPWork pWork1, CECHPWork pWork2) { if (pWork1.GetWorkID() == CECHPWork.Host_work_ID.WORK_MOVETOPOS && diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_HPWorkMelee.cs b/Assets/PerfectWorld/Scripts/Managers/EC_HPWorkMelee.cs index dcc50c915b..4e48a48117 100644 --- a/Assets/PerfectWorld/Scripts/Managers/EC_HPWorkMelee.cs +++ b/Assets/PerfectWorld/Scripts/Managers/EC_HPWorkMelee.cs @@ -4,7 +4,6 @@ using BrewMonster.Network; using BrewMonster.Scripts; using CSNetwork.GPDataType; using PerfectWorld.Scripts.Managers; -using PerfectWorld.Scripts.Player; using UnityEngine; class CECHPWorkPostTickCommand1 : CECHPWorkPostTickRunWorkCommand @@ -89,7 +88,7 @@ class CECHPWorkMelee : CECHPWork } else if (GPDataTypeHelper.ISNPCID(m_idTarget)) { - CECNPC pNPC = EC_ManMessageMono.Instance._CECNPCMan.GetNPC(m_idTarget); + CECNPC pNPC = EC_ManMessageMono.Instance.CECNPCMan.GetNPC(m_idTarget); if (!pNPC || pNPC.IsDead()) // Taget has missed ? return true; @@ -150,7 +149,7 @@ class CECHPWorkMelee : CECHPWork protected virtual void OnFirstTick() { m_pHost.m_iMoveMode = (int)MoveMode.MOVE_STAND; - m_pHost.PlayAction((int)CECPlayer.PLAYER_ACTION_TYPE.ACT_ATTACK_1 + Random.Range(0, 3), true, 200, false); + m_pHost.PlayAction((int)PLAYER_ACTION_TYPE.ACT_ATTACK_1 + Random.Range(0, 3), true, 200, false); m_idTarget = m_pHost.m_idSelTarget; } diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_HPWorkStand.cs b/Assets/PerfectWorld/Scripts/Managers/EC_HPWorkStand.cs index b9478551cd..613803c0a1 100644 --- a/Assets/PerfectWorld/Scripts/Managers/EC_HPWorkStand.cs +++ b/Assets/PerfectWorld/Scripts/Managers/EC_HPWorkStand.cs @@ -28,12 +28,12 @@ namespace BrewMonster.Scripts base.Reset(); m_bMeetSlide = false; - m_iPoseAction = (int)CECPlayer.PLAYER_ACTION_TYPE.ACT_STAND; + m_iPoseAction = (int)PLAYER_ACTION_TYPE.ACT_STAND; m_bSession = false; m_bWaterStop = false; m_bMoving = false; m_bStopSlide = false; - m_iCurAction = (int)CECPlayer.PLAYER_ACTION_TYPE.ACT_STAND; + m_iCurAction = (int)PLAYER_ACTION_TYPE.ACT_STAND; } // Copy work data @@ -62,7 +62,7 @@ namespace BrewMonster.Scripts m_pHost.PlayAction(m_iPoseAction, true); - if (!bSession && iAction != (int)CECPlayer.PLAYER_ACTION_TYPE.ACT_EXP_KISS) + if (!bSession && iAction != (int)PLAYER_ACTION_TYPE.ACT_EXP_KISS) m_pHost.PlayAction(m_pHost.GetMoveStandAction(false, false), true, 300, true); } @@ -107,7 +107,7 @@ namespace BrewMonster.Scripts // Work is cancel public override void Cancel() { - m_iPoseAction = (int)CECPlayer.PLAYER_ACTION_TYPE.ACT_STAND; + m_iPoseAction = (int)PLAYER_ACTION_TYPE.ACT_STAND; m_bSession = false; m_pHost.m_bPrepareFight = false; base.Cancel(); @@ -116,7 +116,7 @@ namespace BrewMonster.Scripts // Doing session pose? public bool DoingSessionPose() { - return (m_iPoseAction != (int)CECPlayer.PLAYER_ACTION_TYPE.ACT_STAND && m_bSession); + return (m_iPoseAction != (int)PLAYER_ACTION_TYPE.ACT_STAND && m_bSession); } // Tick routine @@ -154,7 +154,7 @@ namespace BrewMonster.Scripts } // Play appropriate actions - if (m_iPoseAction == (int)CECPlayer.PLAYER_ACTION_TYPE.ACT_STAND) + if (m_iPoseAction == (int)PLAYER_ACTION_TYPE.ACT_STAND) { bool bFight = m_pHost.IsFighting() || m_pHost.m_bPrepareFight; m_iCurAction = m_pHost.GetMoveStandAction(false, bFight); @@ -170,7 +170,7 @@ namespace BrewMonster.Scripts Tick_FlySwim(fDeltaTime);*/ } - if (m_iPoseAction == (int)CECPlayer.PLAYER_ACTION_TYPE.ACT_STAND && m_oldAction != m_iCurAction) + if (m_iPoseAction == (int)PLAYER_ACTION_TYPE.ACT_STAND && m_oldAction != m_iCurAction) { // Chariot war special case omitted for now m_pHost.PlayAction(m_iCurAction, false, 300); @@ -195,7 +195,7 @@ namespace BrewMonster.Scripts if (m_bStopSlide) return true; - m_iCurAction = (int)CECPlayer.PLAYER_ACTION_TYPE.ACT_JUMP_LOOP; + m_iCurAction = (int)PLAYER_ACTION_TYPE.ACT_JUMP_LOOP; m_bMeetSlide = true; m_bMoving = true; diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_HPWorkTrace.cs b/Assets/PerfectWorld/Scripts/Managers/EC_HPWorkTrace.cs index f06593fb62..b98c33844f 100644 --- a/Assets/PerfectWorld/Scripts/Managers/EC_HPWorkTrace.cs +++ b/Assets/PerfectWorld/Scripts/Managers/EC_HPWorkTrace.cs @@ -3,1007 +3,1007 @@ using BrewMonster.Managers; using BrewMonster.Network; using BrewMonster.Scripts; using CSNetwork.GPDataType; -using PerfectWorld.Scripts.Player; using System; using System.Runtime.ConstrainedExecution; using UnityEngine; -using static CECPlayer; /////////////////////////////////////////////////////////////////////////// // // Class CECHPWorkTrace // /////////////////////////////////////////////////////////////////////////// - -public static class TraceObjectType +namespace BrewMonster { - public const int TRACE_NONE = 0, - TRACE_PLAYER = 1, - TRACE_MATTER = 2, - TRACE_NPC = 3, - TRACE_TASKNPC = 4; -} - -public abstract class CECTracedObject -{ - //friend CECHPWorkTrace; - protected int m_iTraceType; - protected int m_iObjectId; - protected int m_iReason; - protected bool m_bMoreClose; - protected CECHostPlayer m_pHost; - - public CECTracedObject(int type, int id, CECHostPlayer pHost, int ireason) + public static class TraceObjectType { - m_iTraceType = type; - m_iObjectId = id; - m_iReason = ireason; - m_pHost = pHost; - m_bMoreClose = false; - } - public CECTracedObject(CECTracedObject rhs) - { - m_iTraceType = rhs.m_iTraceType; - m_iObjectId = rhs.m_iObjectId; - m_iReason = rhs.m_iReason; - m_bMoreClose = rhs.m_bMoreClose; - m_pHost = rhs.m_pHost; + public const int TRACE_NONE = 0, + TRACE_PLAYER = 1, + TRACE_MATTER = 2, + TRACE_NPC = 3, + TRACE_TASKNPC = 4; } - public abstract bool OnTargetMissing(); - public abstract A3DVECTOR3 GetTargetPos(); - public abstract bool OnTouched(); - public abstract CECTracedObject Clone(); - - public virtual bool IsTargetMissing() + public abstract class CECTracedObject { - if (m_iObjectId != 0) + //friend CECHPWorkTrace; + protected int m_iTraceType; + protected int m_iObjectId; + protected int m_iReason; + protected bool m_bMoreClose; + protected CECHostPlayer m_pHost; + + public CECTracedObject(int type, int id, CECHostPlayer pHost, int ireason) { - CECObject pObj = EC_ManMessageMono.Instance.GetObject(m_iObjectId, 0); - if (pObj) - { - return false; - } + m_iTraceType = type; + m_iObjectId = id; + m_iReason = ireason; + m_pHost = pHost; + m_bMoreClose = false; } - return true; - } - - public A3DVECTOR3? GetMovePos() - { - A3DVECTOR3 vMovePos; - CECObject pObject = EC_ManMessageMono.Instance.GetObject(m_iObjectId, 0); - if (pObject) + public CECTracedObject(CECTracedObject rhs) { - if (GPDataTypeHelper.ISPLAYERID(m_iObjectId)) + m_iTraceType = rhs.m_iTraceType; + m_iObjectId = rhs.m_iObjectId; + m_iReason = rhs.m_iReason; + m_bMoreClose = rhs.m_bMoreClose; + m_pHost = rhs.m_pHost; + } + + public abstract bool OnTargetMissing(); + public abstract A3DVECTOR3 GetTargetPos(); + public abstract bool OnTouched(); + public abstract CECTracedObject Clone(); + + public virtual bool IsTargetMissing() + { + if (m_iObjectId != 0) { - if (m_iObjectId == m_pHost.GetCharacterID()) + CECObject pObj = EC_ManMessageMono.Instance.GetObject(m_iObjectId, 0); + if (pObj) { - vMovePos = m_pHost.GetPos(); - } - else - { - vMovePos = (pObject as EC_ElsePlayer).GetServerPos(); + return false; } } - else if (GPDataTypeHelper.ISNPCID(m_iObjectId)) - { - vMovePos = (pObject as CECNPC).GetServerPos(); - } - else - { - vMovePos = pObject.GetPos(); - } - return vMovePos; + return true; } - return null; - } - public int GetObjectID() - { - return m_iObjectId; - } - public bool CanTouchMoreClose() - { - return m_bMoreClose; - } - public void SetMoveCloseFlag(bool bMoveClode) - { - m_bMoreClose = bMoveClode; - } - public int GetTraceReason() - { - return m_iReason; - } - public bool CanTouchFrom(A3DVECTOR3 vHostPos) - { - while (m_iObjectId != 0) + public A3DVECTOR3? GetMovePos() { - A3DVECTOR3 vTargetPos = new A3DVECTOR3(0f, 0f, 0f); - vTargetPos = GetTargetPos(); - - int iTouchReason = 0; - if (m_iReason == CECHPWorkTrace.Trace_reason.TRACE_ATTACK) - iTouchReason = 1; - else if (m_iReason == CECHPWorkTrace.Trace_reason.TRACE_SPELL) - iTouchReason = 2; - else if (m_iReason == CECHPWorkTrace.Trace_reason.TRACE_TALK) - iTouchReason = 3; - - float fMaxCut = m_bMoreClose ? -1.0f : 1.0f; - + A3DVECTOR3 vMovePos; CECObject pObject = EC_ManMessageMono.Instance.GetObject(m_iObjectId, 0); - - float fTouchRadius = 0.0f; - if (GPDataTypeHelper.ISPLAYERID(m_iObjectId)) + if (pObject) { - if (m_iReason == CECHPWorkTrace.Trace_reason.TRACE_TALK) + if (GPDataTypeHelper.ISPLAYERID(m_iObjectId)) { - fTouchRadius = 0.0f; + if (m_iObjectId == m_pHost.GetCharacterID()) + { + vMovePos = m_pHost.GetPos(); + } + else + { + vMovePos = (pObject as EC_ElsePlayer).GetServerPos(); + } + } + else if (GPDataTypeHelper.ISNPCID(m_iObjectId)) + { + vMovePos = (pObject as CECNPC).GetServerPos(); } else { - CECPlayer pPlayer = pObject.GetComponent(); - fTouchRadius = pPlayer.GetTouchRadius(); + vMovePos = pObject.GetPos(); } - return m_pHost.CanTouchTarget(vHostPos, vTargetPos, fTouchRadius, iTouchReason, fMaxCut); + return vMovePos; } - else if (GPDataTypeHelper.ISNPCID(m_iObjectId)) - { - CECNPC pNPC = pObject as CECNPC; - fTouchRadius = pNPC.GetTouchRadius(); - return m_pHost.CanTouchTarget(vHostPos, vTargetPos, fTouchRadius, iTouchReason, fMaxCut); - } - else if (GPDataTypeHelper.ISMATTERID(m_iObjectId)) - { - //CECMatter pMatter = (pObject) as CECMatter; - //return pMatter.CalcDist(vHostPos, true) < pMatter.GetGatherDist(); - } - break; + return null; } - return false; - } - public int GetTraceType() - { - return m_iTraceType; - } - public CECObject GetTargetObject() - { - return EC_ManMessageMono.Instance.GetObject(m_iObjectId, 0); - } -}; -public class CECTracedNPC : CECTracedObject -{ - protected bool m_bForceAttack; - - public CECTracedNPC(int type, int id, CECHostPlayer pHost, int ireason, bool bForceAttack = false) : base(type, id, pHost, ireason) - { - m_bForceAttack = bForceAttack; - } - public CECTracedNPC(CECTracedNPC rhs) : base(rhs) - { - m_bForceAttack = rhs.m_bForceAttack; - } - - public override bool OnTargetMissing() - { - bool bRet = false; - - if (m_iReason == CECHPWorkTrace.Trace_reason.TRACE_ATTACK) + public int GetObjectID() { - bRet = true; + return m_iObjectId; } - //else if (m_iReason == CECHPWorkTrace.Trace_reason.TRACE_SPELL) - //{ - // CECSkill pSkill = m_pHost.m_pPrepSkill; - // if (pSkill == null || pSkill.GetTargetType() != 2) - // { - // bRet = true; - // m_pHost.m_pPrepSkill = null; - // } - //} - return bRet; - } - - public override A3DVECTOR3 GetTargetPos() - { - return (GetTargetObject() as CECNPC).GetServerPos(); - } - - public override bool OnTouched() - { - bool bActionDone = false; - - if (GPDataTypeHelper.ISNPCID(m_iObjectId)) + public bool CanTouchMoreClose() { - CECNPC pNPC = (CECNPC)GetTargetObject(); - - if (m_iReason == CECHPWorkTrace.Trace_reason.TRACE_TALK) + return m_bMoreClose; + } + public void SetMoveCloseFlag(bool bMoveClode) + { + m_bMoreClose = bMoveClode; + } + public int GetTraceReason() + { + return m_iReason; + } + public bool CanTouchFrom(A3DVECTOR3 vHostPos) + { + while (m_iObjectId != 0) { - if ((!m_pHost.IsInBattle() || m_pHost.InSameBattleCamp(pNPC)) /*&& - !g_pGame.GetGameRun().GetUIManager().GetInGameUIMan().GetDialog("Win_SkillAction").IsShow()*/) + A3DVECTOR3 vTargetPos = new A3DVECTOR3(0f, 0f, 0f); + vTargetPos = GetTargetPos(); + + int iTouchReason = 0; + if (m_iReason == CECHPWorkTrace.Trace_reason.TRACE_ATTACK) + iTouchReason = 1; + else if (m_iReason == CECHPWorkTrace.Trace_reason.TRACE_SPELL) + iTouchReason = 2; + else if (m_iReason == CECHPWorkTrace.Trace_reason.TRACE_TALK) + iTouchReason = 3; + + float fMaxCut = m_bMoreClose ? -1.0f : 1.0f; + + CECObject pObject = EC_ManMessageMono.Instance.GetObject(m_iObjectId, 0); + + float fTouchRadius = 0.0f; + if (GPDataTypeHelper.ISPLAYERID(m_iObjectId)) { - UnityGameSession.c2s_CmdNPCSevHello(m_iObjectId); - bActionDone = true; - //a_LogOutput(1, "[NormalATK]- CECTracedNPC- OnTouched- TRACE_TALK"); + if (m_iReason == CECHPWorkTrace.Trace_reason.TRACE_TALK) + { + fTouchRadius = 0.0f; + } + else + { + CECPlayer pPlayer = pObject.GetComponent(); + fTouchRadius = pPlayer.GetTouchRadius(); + } + return m_pHost.CanTouchTarget(vHostPos, vTargetPos, fTouchRadius, iTouchReason, fMaxCut); } - } - else if (m_iReason == CECHPWorkTrace.Trace_reason.TRACE_ATTACK) - { - if (m_iObjectId == m_pHost.m_idSelTarget && - m_pHost.AttackableJudge(m_iObjectId, m_bForceAttack) == 1) + else if (GPDataTypeHelper.ISNPCID(m_iObjectId)) { - byte byPVPMask = EC_Utility.glb_BuildPVPMask(m_bForceAttack); - UnityGameSession.c2s_CmdNormalAttack(byPVPMask); - m_pHost.m_bPrepareFight = true; - bActionDone = true; - //a_LogOutput(1, "[NormalATK]- CECTracedNPC- OnTouched- TRACE_ATTACK"); + CECNPC pNPC = pObject as CECNPC; + fTouchRadius = pNPC.GetTouchRadius(); + return m_pHost.CanTouchTarget(vHostPos, vTargetPos, fTouchRadius, iTouchReason, fMaxCut); } - } - else if (m_iReason == CECHPWorkTrace.Trace_reason.TRACE_SPELL) - { - //a_LogOutput(1, "[NormalATK]- CECTracedNPC- OnTouched- TRACE_SPELL"); - if (!m_pHost.CannotAttack()) + else if (GPDataTypeHelper.ISMATTERID(m_iObjectId)) { - if (m_pHost.CastSkill(m_iObjectId, m_bForceAttack)) - bActionDone = true; + //CECMatter pMatter = (pObject) as CECMatter; + //return pMatter.CalcDist(vHostPos, true) < pMatter.GetGatherDist(); } - else - m_pHost.m_pPrepSkill = null; + break; } + return false; } - return bActionDone; - } - - public override CECTracedObject Clone() - { - return new CECTracedNPC(this); - } - - public override bool IsTargetMissing() - { - if (base.IsTargetMissing()) + public int GetTraceType() { - return true; + return m_iTraceType; } - CECNPC pNPC = GetTargetObject() as CECNPC; - if (pNPC.IsDead()) + public CECObject GetTargetObject() { - return true; + return EC_ManMessageMono.Instance.GetObject(m_iObjectId, 0); } - return false; - } -} + }; -public class CECTracedPlayer : CECTracedObject -{ - protected bool m_bForceAttack; - public CECTracedPlayer(int type, int id, CECHostPlayer pHost, int ireason, bool bForceAttack = false) : base(type, id, pHost, ireason) + public class CECTracedNPC : CECTracedObject { - m_bForceAttack = bForceAttack; - } - public CECTracedPlayer(CECTracedPlayer rhs) : base(rhs) - { - m_bForceAttack = rhs.m_bForceAttack; - } + protected bool m_bForceAttack; - public override bool OnTargetMissing() - { - bool bRet = false; - - if (m_iReason == CECHPWorkTrace.Trace_reason.TRACE_ATTACK) + public CECTracedNPC(int type, int id, CECHostPlayer pHost, int ireason, bool bForceAttack = false) : base(type, id, pHost, ireason) { - bRet = true; + m_bForceAttack = bForceAttack; } - //else if (m_iReason == CECHPWorkTrace.Trace_reason.TRACE_SPELL) - //{ - // CECSkill pSkill = m_pHost.m_pPrepSkill; - // if (pSkill == null || pSkill.GetTargetType() != 2) - // { - // bRet = true; - // m_pHost.m_pPrepSkill = null; - // } - //} - return bRet; - } - - public override A3DVECTOR3 GetTargetPos() - { - CECObject pObject = EC_ManMessageMono.Instance.GetObject(m_iObjectId, 0); - if (m_iObjectId == m_pHost.GetCharacterID()) + public CECTracedNPC(CECTracedNPC rhs) : base(rhs) { - return m_pHost.GetPos(); + m_bForceAttack = rhs.m_bForceAttack; } - else - { - return (pObject as EC_ElsePlayer).GetServerPos(); - } - } - public override bool OnTouched() - { - bool bActionDone = false; - if (GPDataTypeHelper.ISPLAYERID(m_iObjectId)) + public override bool OnTargetMissing() { - if (m_iObjectId == 0 || m_iObjectId == m_pHost.GetCharacterID()) - { - // Handle special case - //ASSERT(m_iReason == CECHPWorkTrace::TRACE_SPELL); - //if (!m_pHost.CannotAttack()) - //{ - // if (m_pHost.CastSkill(m_iObjectId, m_bForceAttack, null)) - // bActionDone = true; - //} - //else - //{ - // m_pHost.m_pPrepSkill = null; - //} - //a_LogOutput(1, "[NormalATK]- CECTracedPlayer- OnTouched- special case- TRACE_SPELL"); - return bActionDone; - } + bool bRet = false; + if (m_iReason == CECHPWorkTrace.Trace_reason.TRACE_ATTACK) { - if (m_iObjectId == m_pHost.m_idSelTarget && - m_pHost.AttackableJudge(m_iObjectId, m_bForceAttack) == 1) - { - byte byPVPMask = EC_Utility.glb_BuildPVPMask(m_bForceAttack); - UnityGameSession.c2s_CmdNormalAttack(byPVPMask); - m_pHost.m_bPrepareFight = true; - bActionDone = true; - //a_LogOutput(1, "[NormalATK]- CECTracedPlayer- OnTouched- TRACE_ATTACK"); - } + bRet = true; } //else if (m_iReason == CECHPWorkTrace.Trace_reason.TRACE_SPELL) //{ - // //a_LogOutput(1, "[NormalATK]- CECTracedPlayer- OnTouched- TRACE_SPELL"); - // if (!m_pHost.CastSkill(m_iObjectId, m_bForceAttack, GetTargetObject())) + // CECSkill pSkill = m_pHost.m_pPrepSkill; + // if (pSkill == null || pSkill.GetTargetType() != 2) // { + // bRet = true; // m_pHost.m_pPrepSkill = null; // } - // else - // { - // bActionDone = true; - // } //} - else if (m_iReason == CECHPWorkTrace.Trace_reason.TRACE_TALK) + return bRet; + } + + public override A3DVECTOR3 GetTargetPos() + { + return (GetTargetObject() as CECNPC).GetServerPos(); + } + + public override bool OnTouched() + { + bool bActionDone = false; + + if (GPDataTypeHelper.ISNPCID(m_iObjectId)) { - // Visite other's booth, send hello message to him - //a_LogOutput(1, "[NormalATK]- CECTracedPlayer- OnTouched- TRACE_TALK"); - UnityGameSession.c2s_CmdNPCSevHello(m_iObjectId); - bActionDone = true; + CECNPC pNPC = (CECNPC)GetTargetObject(); + + if (m_iReason == CECHPWorkTrace.Trace_reason.TRACE_TALK) + { + if ((!m_pHost.IsInBattle() || m_pHost.InSameBattleCamp(pNPC)) /*&& + !g_pGame.GetGameRun().GetUIManager().GetInGameUIMan().GetDialog("Win_SkillAction").IsShow()*/) + { + UnityGameSession.c2s_CmdNPCSevHello(m_iObjectId); + bActionDone = true; + //a_LogOutput(1, "[NormalATK]- CECTracedNPC- OnTouched- TRACE_TALK"); + } + } + else if (m_iReason == CECHPWorkTrace.Trace_reason.TRACE_ATTACK) + { + if (m_iObjectId == m_pHost.m_idSelTarget && + m_pHost.AttackableJudge(m_iObjectId, m_bForceAttack) == 1) + { + byte byPVPMask = EC_Utility.glb_BuildPVPMask(m_bForceAttack); + UnityGameSession.c2s_CmdNormalAttack(byPVPMask); + m_pHost.m_bPrepareFight = true; + bActionDone = true; + //a_LogOutput(1, "[NormalATK]- CECTracedNPC- OnTouched- TRACE_ATTACK"); + } + } + else if (m_iReason == CECHPWorkTrace.Trace_reason.TRACE_SPELL) + { + //a_LogOutput(1, "[NormalATK]- CECTracedNPC- OnTouched- TRACE_SPELL"); + if (!m_pHost.CannotAttack()) + { + if (m_pHost.CastSkill(m_iObjectId, m_bForceAttack)) + bActionDone = true; + } + else + m_pHost.m_pPrepSkill = null; + } } + return bActionDone; } - return bActionDone; - } - public override CECTracedObject Clone() - { - return new CECTracedPlayer(this); - } - - public override bool IsTargetMissing() - { - if (base.IsTargetMissing()) + public override CECTracedObject Clone() { - return true; + return new CECTracedNPC(this); } - CECPlayer pPlayer = GetTargetObject() as CECPlayer; - if (pPlayer.IsElsePlayer()) + + public override bool IsTargetMissing() { - if (pPlayer.IsDead()) + if (base.IsTargetMissing()) { - //if (m_iReason == CECHPWorkTrace.Trace_reason.TRACE_SPELL) - //{ - // CECSkill pSkill = m_pHost.m_pPrepSkill; - // if (pSkill && pSkill.GetTargetType() == 2) - // { - // return false; - // } - //} return true; } - } - return false; - } -}; - -public class CECTracedMatter : CECTracedObject -{ - - public CECTracedMatter(int type, int id, CECHostPlayer pHost, int ireason) : base(type, id, pHost, ireason) - { - - } - public CECTracedMatter(CECTracedMatter rhs) : base(rhs) - { - - } - - public override bool OnTargetMissing() - { - return false; - } - - public override A3DVECTOR3 GetTargetPos() - { - return GetTargetObject().GetPos(); - } - - public override bool OnTouched() - { - bool bActionDone = false; - //if (GPDataTypeHelper.ISMATTERID(m_iObjectId)) - //{ - // if (m_pHost.GetProfession() == PROF_GHOST && m_pHost.IsInvisible()) - // { - // g_pGame.GetGameRun().AddFixedMessage(FIXMSG_CANNOT_USE_WHEN_INVISIBLE); - // return bActionDone; - // } - // CECMatter* pMatter = (CECMatter*)GetTargetObject(); - - // if (m_iReason == CECHPWorkTrace::TRACE_PICKUP) - // { - // // Check whether we have enougth place to hold this item or money - // a_LogOutput(1, "[NormalATK]- CECTracedMatter- OnTouched- TRACE_PICKUP"); - // if (m_pHost.CanTakeItem(pMatter.GetTemplateID(), 1)) - // { - // // Send pickup asking and wait response command - // g_pGame.GetGameSession().c2s_CmdPickup(m_iObjectId, pMatter.GetTemplateID()); - // bActionDone = true; - // } - // else - // { - // // Print a notify message - // g_pGame.GetGameRun().AddFixedMessage(FIXMSG_PACKISFULL); - // } - // } - // else - // { // m_iReason == TRACE_GATHER - // int tidMatter = pMatter.GetTemplateID(); - // a_LogOutput(1, "[NormalATK]- CECTracedMatter- OnTouched- TRACE_GATHER"); - // // Check mine level requirement - // if (m_pHost.GetBasicProps().iLevel < pMatter.GetLevelReq()) - // { - // g_pGame.GetGameRun().AddFixedMessage(FIXMSG_LEVELTOOLOW); - // return bActionDone; - // } - - // // Check whether we have a mine tool - // int iPack, iIndex, idTool; - // if (m_pHost.FindMineTool(tidMatter, &iPack, &iIndex, &idTool)) - // { - // DATA_TYPE DataType; - // const MINE_ESSENCE* pData = (const MINE_ESSENCE*)g_pGame.GetElementDataMan().get_data_ptr(pMatter.GetTemplateID(), ID_SPACE_ESSENCE, DataType); - // if (DataType != DT_MINE_ESSENCE) - // { - // ASSERT(DataType == DT_MINE_ESSENCE); - // return bActionDone; - // } - - // if (m_pHost.GetCoolTime(GP_CT_PLAYER_GATHER)) - // { - // g_pGame.GetGameRun().AddFixedMessage(FIXMSG_CMD_INCOOLTIME); - // } - // else - // { - // // Send gather asking and wait response command - // g_pGame.GetGameSession().c2s_CmdGatherMaterial(m_iObjectId, iPack, iIndex, idTool, pData.task_in); - // } - // } - // else - // { - // g_pGame.GetGameRun().AddFixedMessage(FIXMSG_NEEDTOOL); - // } - // } - //} - return bActionDone; - } - - public override CECTracedObject Clone() - { - return new CECTracedMatter(this); - } -}; -public class CECHPWorkTrace : CECHPWork -{ - // Trace reason - public static class Trace_reason - { - public const int TRACE_NONE = -1, - TRACE_ATTACK = 0, // Normal attack - TRACE_PICKUP = 1, // Pickup object - TRACE_TALK = 2, // Go to talk - TRACE_SPELL = 3, // Cast magic - TRACE_GATHER = 4; // Gather object - } - // Constructor and Destructor - public CECHPWorkTrace(CECHPWorkMan pWorkMan) : base(Host_work_ID.WORK_TRACEOBJECT, pWorkMan) - { - m_dwMask = Work_mask.MASK_TRACEOBJECT; - m_dwTransMask = Work_mask.MASK_STAND | Work_mask.MASK_MOVETOPOS | Work_mask.MASK_FLYOFF | Work_mask.MASK_FREEFALL | - Work_mask.MASK_FOLLOW | Work_mask.MASK_USEITEM; - - Reset(); - } - - // Change trace target - //void ChangeTarget(int idTarget, int iReason, bool bUseAutoPF=false); - // �趨traceobject - public void SetTraceTarget(CECTracedObject pTraceObj, bool bUseAutoPF = false) - { - ResetUseAutoPF(bUseAutoPF); - if (!pTraceObj.GetTargetObject() || pTraceObj.GetObjectID() == m_pHost.GetCharacterID()) - { - // This is special case - ReplaceTarget(pTraceObj); - return; - } - int idTarget = pTraceObj.GetObjectID(); - if (!GPDataTypeHelper.ISPLAYERID(idTarget) && !GPDataTypeHelper.ISNPCID(idTarget) && !GPDataTypeHelper.ISMATTERID(idTarget)) - { - return; - } - CECObject pObject = pTraceObj.GetTargetObject(); - if (!pObject) - { - //delete pTraceObj; - return; - } - ReplaceTarget(pTraceObj); - if (m_pTraceObject.GetTargetObject()) - { - A3DVECTOR3 vDirH = pTraceObj.GetTargetPos() - m_pHost.GetPos(); - vDirH.y = 0.0f; - vDirH.Normalize(); - m_vCurDirH = !vDirH.IsZero() ? vDirH : m_vCurDirH = GPDataTypeHelper.g_vAxisZ; - } - } - - public CECTracedObject CreatTraceTarget(int iTraceObjId, int iReason, bool bForceAttack = false) - { - if (GPDataTypeHelper.ISPLAYERID(iTraceObjId)) - { - return new CECTracedPlayer(TraceObjectType.TRACE_PLAYER, iTraceObjId, m_pHost, iReason, bForceAttack); - } - else if (GPDataTypeHelper.ISNPCID(iTraceObjId)) - { - return new CECTracedNPC(TraceObjectType.TRACE_NPC, iTraceObjId, m_pHost, iReason, bForceAttack); - } - //else if (GPDataTypeHelper.ISMATTERID(iTraceObjId)) - //{ - // return new CECTracedMatter(TraceObjectType.TRACE_MATTER, iTraceObjId, m_pHost, iReason); - //} - return null; - } - - // Tick routine - public override bool Tick(float dwDeltaTime) - { - base.Tick(dwDeltaTime); - CheckPrepSkill(); - - UpdateResetUseAutoPF(); - UpdateUseAutoPF(); - - // m_bFinished flag may be set both in OnFirstTick() and CheckPrepSkill(), - // so check it here ! - if (m_bFinished) - { - return true; - } - if (m_pTraceObject.IsTargetMissing()) - { - OnTargetMissing(); - return true; - } - - if (m_bCheckTouch) - { - if (IsGoodTimeToTouch()) + CECNPC pNPC = GetTargetObject() as CECNPC; + if (pNPC.IsDead()) { - //OnTouchTarget(); - //return true; - if (m_pTraceObject.CanTouchFrom(m_pHost.GetPos() + new A3DVECTOR3(0f, m_pHost.m_CDRInfo.vExtent.y, 0f))) - { - OnTouchTarget(); - return true; - } + return true; } - } - m_bCheckTouch = true; - - //return true; // TO DO: remove later - if (!m_pHost.IsRooting()) - { - // Continue tracing object - float fDeltaTime = dwDeltaTime /** 0.001f*/; - if (m_pHost.m_iMoveEnv == CECPlayer.Move_environment.MOVEENV_GROUND) - { - // Play appropriate actions - if (!m_pHost.IsJumping() && !m_pHost.IsPlayingAction((int)PLAYER_ACTION_TYPE.ACT_TRICK_RUN) && - m_pHost.m_iMoveMode != (int)MoveMode.MOVE_SLIDE) - { - int iAction = m_pHost.GetMoveStandAction(true); - m_pHost.PlayAction(iAction, false, 200, false); - } - - Trace_Walk(fDeltaTime); - } - else // (m_pHost.m_iMoveEnv == CECPlayer::MOVEENV_AIR || m_pHost.m_iMoveEnv == CECPlayer::MOVEENV_WATER) - { - m_pHost.ResetJump(); - - // Play appropriate actions - int iAction = m_pHost.GetMoveStandAction(true); - m_pHost.PlayAction(iAction, false, 200, false); - - Trace_FlySwim(fDeltaTime); - } - - m_bHaveMoved = true; - } - - return true; - } - // Reset work - public override void Reset() - { - base.Reset(); - - m_bHaveMoved = false; - m_bMeetSlide = false; - m_bCheckTouch = true; - m_bReadyCancel = false; - m_bMoreClose = false; - //m_pPrepSkill = null; - m_bForceAttack = false; - m_bActionDone = false; - ClearResetUseAutoPF(); - m_bUseAutoPF = false; - m_dwAutoPFNextCheckTime = 0; - m_pTraceObject = null; - } - // Work is cancel - public override void Cancel() - { - //if (m_pHost.m_pPrepSkill && m_pTraceObject.GetTraceReason() == Trace_reason.TRACE_SPELL) - // m_pHost.m_pPrepSkill = null; - - ClearResetUseAutoPF(); - if (GetUseAutoPF()) - { - SetUseAutoPF(false); - } - //m_pHost.StopModelMove(); - base.Cancel(); - - //AP_ActionEvent(m_bActionDone ? AP_EVENT_TRACEOK : AP_EVENT_MOVEFINISHED, m_pTraceObject.GetTraceReason()); - } - - // This work is do player moving ? - public override bool IsMoving() { return true; } - // Copy work data - public override bool CopyData(CECHPWork pWork) - { - if (!base.CopyData(pWork)) return false; - - CECHPWorkTrace pSrc = (CECHPWorkTrace)pWork; - - m_bHaveMoved = pSrc.m_bHaveMoved; - m_bMeetSlide = pSrc.m_bMeetSlide; - m_bCheckTouch = pSrc.m_bCheckTouch; - m_bReadyCancel = pSrc.m_bReadyCancel; - m_bMoreClose = pSrc.m_bMoreClose; - m_vCurDirH = pSrc.m_vCurDirH; - //m_pPrepSkill = pSrc.m_pPrepSkill; - m_bForceAttack = pSrc.m_bForceAttack; - m_bActionDone = pSrc.m_bActionDone; - m_bShouldResetUseAutoPF = pSrc.m_bShouldResetUseAutoPF; - m_bUseAutoPFResetValue = pSrc.m_bUseAutoPFResetValue; - m_bUseAutoPF = pSrc.m_bUseAutoPF; - m_dwAutoPFNextCheckTime = pSrc.m_dwAutoPFNextCheckTime; - - //delete m_pTraceObject; - m_pTraceObject = pSrc.m_pTraceObject.Clone(); - - return true; - } - - // User press cancel button - public void PressCancel() - { - m_bReadyCancel = true; - //if (m_pTraceObject.GetTraceReason() == TRACE_SPELL) - // m_pHost.m_pPrepSkill = NULL; - } - // Set move close flag - public void SetMoveCloseFlag(bool bMoveClose) { m_pTraceObject.SetMoveCloseFlag(bMoveClose); } - - // Set / Get force attack flag - public void SetForceAttack(bool bTrue) { m_bForceAttack = bTrue; } - public bool GetForceAttack() { return m_bForceAttack; } - // Set / Get prepared skill - public void SetPrepSkill(CECSkill pSkill) { m_pPrepSkill = pSkill; } - public CECSkill GetPrepSkill() { /*return m_pPrepSkill;*/ return null; } - // Get target ID - public int GetTarget() { return m_pTraceObject.GetObjectID(); } - // Get trace reason - public int GetTraceReason() { return m_pTraceObject.GetTraceReason(); } - // AutoPF - public void SetUseAutoPF(bool bUse) - { - m_bUseAutoPF = bUse; - //if (!m_bUseAutoPF && CECIntelligentRoute.Instance().IsUsageTrace()) - //{ - // CECIntelligentRoute.Instance().ResetSearch(); - //} - } - public bool GetUseAutoPF() - { - return m_bUseAutoPF; - } - public bool IsAutoPF() - { - return false; - } - - public void SetActionDone(bool bActionDone) { m_bActionDone = bActionDone; } - - public void OnTargetMissing() - { - StopMove(true); - if ((m_pTraceObject.GetTraceType() == TraceObjectType.TRACE_NPC) || (m_pTraceObject.GetTraceType() == TraceObjectType.TRACE_PLAYER)) - { - m_pTraceObject.OnTargetMissing(); } - //else if (m_pTraceObject.GetTraceReason() == Trace_reason.TRACE_SPELL) - //{ - // m_pHost.m_pPrepSkill = null; - //} } - public void OnTouchTarget() + public class CECTracedPlayer : CECTracedObject { - StopMove(true); - m_bActionDone = m_pTraceObject.OnTouched(); - } - public bool CanTouch() - { - //CECSkill pPrepSkill = m_pHost.m_pPrepSkill; - CheckPrepSkill(); - bool result = m_pTraceObject.CanTouchFrom(m_pHost.GetPos()); - //m_pHost.m_pPrepSkill = pPrepSkill; - return result; - } - // Attributes - - protected bool m_bHaveMoved; // Have moved flag - protected bool m_bMeetSlide; // true, meet slide - protected bool m_bCheckTouch; // Check whether touch target in this frame - protected A3DVECTOR3 m_vCurDirH; // Current move direction - protected bool m_bReadyCancel; // true, ready to cancel - protected bool m_bMoreClose; // Move close flag - protected bool m_bForceAttack; // Force attack flag - protected CECSkill m_pPrepSkill; // Skill prepared to be casted - protected bool m_bActionDone; // Ŀ����Ϊ�ɹ����� - protected bool m_bShouldResetUseAutoPF; - protected bool m_bUseAutoPFResetValue; - protected bool m_bUseAutoPF; // Use CECIntelligentRoute::Search - protected uint m_dwAutoPFNextCheckTime; // �´μ��ʱ�� - - protected CECTracedObject m_pTraceObject; // ����traceĿ����� - - // Operations - - // On first tick - protected virtual void OnFirstTick() - { - m_pHost.m_iMoveMode = (int)MoveMode.MOVE_MOVE; - m_bHaveMoved = false; - } - - // Trace on ground - protected bool Trace_Walk(float fDeltaTime) - { - A3DVECTOR3 vCurPos = m_pHost.GetPos(); - A3DVECTOR3 vTargetPos = GetCurMovingDest(); - CDR_INFO cdr = m_pHost.m_CDRInfo; - - if (m_pHost.m_iMoveMode == (int)MoveMode.MOVE_SLIDE) + protected bool m_bForceAttack; + public CECTracedPlayer(int type, int id, CECHostPlayer pHost, int ireason, bool bForceAttack = false) : base(type, id, pHost, ireason) { - m_pHost.PlayAction((int)CECPlayer.PLAYER_ACTION_TYPE.ACT_JUMP_LOOP, false, 200, false); + m_bForceAttack = bForceAttack; + } + public CECTracedPlayer(CECTracedPlayer rhs) : base(rhs) + { + m_bForceAttack = rhs.m_bForceAttack; + } - // This will cause stop moming after we slide down. - A3DVECTOR3 vDir = vTargetPos - vCurPos; - vDir.y = 0; - vDir.Normalize(); + public override bool OnTargetMissing() + { + bool bRet = false; - float fMaxSpeedV = 0f; - m_bMeetSlide = m_pHost.m_MoveCtrl.MeetSlope(vDir, fMaxSpeedV); - EC_Utility.a_ClampFloor(cdr.fYVel, -fMaxSpeedV); - - if (!vDir.IsZero()) - m_vCurDirH = vDir; - - vCurPos = m_pHost.m_MoveCtrl.GroundMove(m_vCurDirH, m_pHost.GetGroundSpeed(), fDeltaTime); - m_pHost.SetDirAndUp(EC_Utility.ToVector3(vCurPos - m_pHost.GetPos()), Vector3.up); - if (m_pHost.m_MoveCtrl.MoveBlocked() >= 3) + if (m_iReason == CECHPWorkTrace.Trace_reason.TRACE_ATTACK) { - m_pHost.m_MoveCtrl.SetSlideLock(true); - m_pHost.m_MoveCtrl.SendStopMoveCmd(EC_Utility.ToVector3(vCurPos), m_pHost.GetGroundSpeed(), (int)GPMoveMode.GP_MOVE_SLIDE); - m_bFinished = true; + bRet = true; + } + //else if (m_iReason == CECHPWorkTrace.Trace_reason.TRACE_SPELL) + //{ + // CECSkill pSkill = m_pHost.m_pPrepSkill; + // if (pSkill == null || pSkill.GetTargetType() != 2) + // { + // bRet = true; + // m_pHost.m_pPrepSkill = null; + // } + //} + return bRet; + } + + public override A3DVECTOR3 GetTargetPos() + { + CECObject pObject = EC_ManMessageMono.Instance.GetObject(m_iObjectId, 0); + if (m_iObjectId == m_pHost.GetCharacterID()) + { + return m_pHost.GetPos(); } else { + return (pObject as EC_ElsePlayer).GetServerPos(); + } + } + + public override bool OnTouched() + { + bool bActionDone = false; + if (GPDataTypeHelper.ISPLAYERID(m_iObjectId)) + { + if (m_iObjectId == 0 || m_iObjectId == m_pHost.GetCharacterID()) + { + // Handle special case + //ASSERT(m_iReason == CECHPWorkTrace::TRACE_SPELL); + //if (!m_pHost.CannotAttack()) + //{ + // if (m_pHost.CastSkill(m_iObjectId, m_bForceAttack, null)) + // bActionDone = true; + //} + //else + //{ + // m_pHost.m_pPrepSkill = null; + //} + //a_LogOutput(1, "[NormalATK]- CECTracedPlayer- OnTouched- special case- TRACE_SPELL"); + return bActionDone; + } + if (m_iReason == CECHPWorkTrace.Trace_reason.TRACE_ATTACK) + { + if (m_iObjectId == m_pHost.m_idSelTarget && + m_pHost.AttackableJudge(m_iObjectId, m_bForceAttack) == 1) + { + byte byPVPMask = EC_Utility.glb_BuildPVPMask(m_bForceAttack); + UnityGameSession.c2s_CmdNormalAttack(byPVPMask); + m_pHost.m_bPrepareFight = true; + bActionDone = true; + //a_LogOutput(1, "[NormalATK]- CECTracedPlayer- OnTouched- TRACE_ATTACK"); + } + } + //else if (m_iReason == CECHPWorkTrace.Trace_reason.TRACE_SPELL) + //{ + // //a_LogOutput(1, "[NormalATK]- CECTracedPlayer- OnTouched- TRACE_SPELL"); + // if (!m_pHost.CastSkill(m_iObjectId, m_bForceAttack, GetTargetObject())) + // { + // m_pHost.m_pPrepSkill = null; + // } + // else + // { + // bActionDone = true; + // } + //} + else if (m_iReason == CECHPWorkTrace.Trace_reason.TRACE_TALK) + { + // Visite other's booth, send hello message to him + //a_LogOutput(1, "[NormalATK]- CECTracedPlayer- OnTouched- TRACE_TALK"); + UnityGameSession.c2s_CmdNPCSevHello(m_iObjectId); + bActionDone = true; + } + } + return bActionDone; + } + + public override CECTracedObject Clone() + { + return new CECTracedPlayer(this); + } + + public override bool IsTargetMissing() + { + if (base.IsTargetMissing()) + { + return true; + } + CECPlayer pPlayer = GetTargetObject() as CECPlayer; + if (pPlayer.IsElsePlayer()) + { + if (pPlayer.IsDead()) + { + //if (m_iReason == CECHPWorkTrace.Trace_reason.TRACE_SPELL) + //{ + // CECSkill pSkill = m_pHost.m_pPrepSkill; + // if (pSkill && pSkill.GetTargetType() == 2) + // { + // return false; + // } + //} + return true; + } + } + return false; + } + }; + + public class CECTracedMatter : CECTracedObject + { + + public CECTracedMatter(int type, int id, CECHostPlayer pHost, int ireason) : base(type, id, pHost, ireason) + { + + } + public CECTracedMatter(CECTracedMatter rhs) : base(rhs) + { + + } + + public override bool OnTargetMissing() + { + return false; + } + + public override A3DVECTOR3 GetTargetPos() + { + return GetTargetObject().GetPos(); + } + + public override bool OnTouched() + { + bool bActionDone = false; + //if (GPDataTypeHelper.ISMATTERID(m_iObjectId)) + //{ + // if (m_pHost.GetProfession() == PROF_GHOST && m_pHost.IsInvisible()) + // { + // g_pGame.GetGameRun().AddFixedMessage(FIXMSG_CANNOT_USE_WHEN_INVISIBLE); + // return bActionDone; + // } + // CECMatter* pMatter = (CECMatter*)GetTargetObject(); + + // if (m_iReason == CECHPWorkTrace::TRACE_PICKUP) + // { + // // Check whether we have enougth place to hold this item or money + // a_LogOutput(1, "[NormalATK]- CECTracedMatter- OnTouched- TRACE_PICKUP"); + // if (m_pHost.CanTakeItem(pMatter.GetTemplateID(), 1)) + // { + // // Send pickup asking and wait response command + // g_pGame.GetGameSession().c2s_CmdPickup(m_iObjectId, pMatter.GetTemplateID()); + // bActionDone = true; + // } + // else + // { + // // Print a notify message + // g_pGame.GetGameRun().AddFixedMessage(FIXMSG_PACKISFULL); + // } + // } + // else + // { // m_iReason == TRACE_GATHER + // int tidMatter = pMatter.GetTemplateID(); + // a_LogOutput(1, "[NormalATK]- CECTracedMatter- OnTouched- TRACE_GATHER"); + // // Check mine level requirement + // if (m_pHost.GetBasicProps().iLevel < pMatter.GetLevelReq()) + // { + // g_pGame.GetGameRun().AddFixedMessage(FIXMSG_LEVELTOOLOW); + // return bActionDone; + // } + + // // Check whether we have a mine tool + // int iPack, iIndex, idTool; + // if (m_pHost.FindMineTool(tidMatter, &iPack, &iIndex, &idTool)) + // { + // DATA_TYPE DataType; + // const MINE_ESSENCE* pData = (const MINE_ESSENCE*)g_pGame.GetElementDataMan().get_data_ptr(pMatter.GetTemplateID(), ID_SPACE_ESSENCE, DataType); + // if (DataType != DT_MINE_ESSENCE) + // { + // ASSERT(DataType == DT_MINE_ESSENCE); + // return bActionDone; + // } + + // if (m_pHost.GetCoolTime(GP_CT_PLAYER_GATHER)) + // { + // g_pGame.GetGameRun().AddFixedMessage(FIXMSG_CMD_INCOOLTIME); + // } + // else + // { + // // Send gather asking and wait response command + // g_pGame.GetGameSession().c2s_CmdGatherMaterial(m_iObjectId, iPack, iIndex, idTool, pData.task_in); + // } + // } + // else + // { + // g_pGame.GetGameRun().AddFixedMessage(FIXMSG_NEEDTOOL); + // } + // } + //} + return bActionDone; + } + + public override CECTracedObject Clone() + { + return new CECTracedMatter(this); + } + }; + public class CECHPWorkTrace : CECHPWork + { + // Trace reason + public static class Trace_reason + { + public const int TRACE_NONE = -1, + TRACE_ATTACK = 0, // Normal attack + TRACE_PICKUP = 1, // Pickup object + TRACE_TALK = 2, // Go to talk + TRACE_SPELL = 3, // Cast magic + TRACE_GATHER = 4; // Gather object + } + // Constructor and Destructor + public CECHPWorkTrace(CECHPWorkMan pWorkMan) : base(Host_work_ID.WORK_TRACEOBJECT, pWorkMan) + { + m_dwMask = Work_mask.MASK_TRACEOBJECT; + m_dwTransMask = Work_mask.MASK_STAND | Work_mask.MASK_MOVETOPOS | Work_mask.MASK_FLYOFF | Work_mask.MASK_FREEFALL | + Work_mask.MASK_FOLLOW | Work_mask.MASK_USEITEM; + + Reset(); + } + + // Change trace target + //void ChangeTarget(int idTarget, int iReason, bool bUseAutoPF=false); + // �趨traceobject + public void SetTraceTarget(CECTracedObject pTraceObj, bool bUseAutoPF = false) + { + ResetUseAutoPF(bUseAutoPF); + if (!pTraceObj.GetTargetObject() || pTraceObj.GetObjectID() == m_pHost.GetCharacterID()) + { + // This is special case + ReplaceTarget(pTraceObj); + return; + } + int idTarget = pTraceObj.GetObjectID(); + if (!GPDataTypeHelper.ISPLAYERID(idTarget) && !GPDataTypeHelper.ISNPCID(idTarget) && !GPDataTypeHelper.ISMATTERID(idTarget)) + { + return; + } + CECObject pObject = pTraceObj.GetTargetObject(); + if (!pObject) + { + //delete pTraceObj; + return; + } + ReplaceTarget(pTraceObj); + if (m_pTraceObject.GetTargetObject()) + { + A3DVECTOR3 vDirH = pTraceObj.GetTargetPos() - m_pHost.GetPos(); + vDirH.y = 0.0f; + vDirH.Normalize(); + m_vCurDirH = !vDirH.IsZero() ? vDirH : m_vCurDirH = GPDataTypeHelper.g_vAxisZ; + } + } + + public CECTracedObject CreatTraceTarget(int iTraceObjId, int iReason, bool bForceAttack = false) + { + if (GPDataTypeHelper.ISPLAYERID(iTraceObjId)) + { + return new CECTracedPlayer(TraceObjectType.TRACE_PLAYER, iTraceObjId, m_pHost, iReason, bForceAttack); + } + else if (GPDataTypeHelper.ISNPCID(iTraceObjId)) + { + return new CECTracedNPC(TraceObjectType.TRACE_NPC, iTraceObjId, m_pHost, iReason, bForceAttack); + } + //else if (GPDataTypeHelper.ISMATTERID(iTraceObjId)) + //{ + // return new CECTracedMatter(TraceObjectType.TRACE_MATTER, iTraceObjId, m_pHost, iReason); + //} + return null; + } + + // Tick routine + public override bool Tick(float dwDeltaTime) + { + base.Tick(dwDeltaTime); + CheckPrepSkill(); + + UpdateResetUseAutoPF(); + UpdateUseAutoPF(); + + // m_bFinished flag may be set both in OnFirstTick() and CheckPrepSkill(), + // so check it here ! + if (m_bFinished) + { + return true; + } + if (m_pTraceObject.IsTargetMissing()) + { + OnTargetMissing(); + return true; + } + + if (m_bCheckTouch) + { + if (IsGoodTimeToTouch()) + { + //OnTouchTarget(); + //return true; + if (m_pTraceObject.CanTouchFrom(m_pHost.GetPos() + new A3DVECTOR3(0f, m_pHost.m_CDRInfo.vExtent.y, 0f))) + { + OnTouchTarget(); + return true; + } + } + } + m_bCheckTouch = true; + + //return true; // TO DO: remove later + if (!m_pHost.IsRooting()) + { + // Continue tracing object + float fDeltaTime = dwDeltaTime /** 0.001f*/; + if (m_pHost.m_iMoveEnv == CECPlayer.Move_environment.MOVEENV_GROUND) + { + // Play appropriate actions + if (!m_pHost.IsJumping() && !m_pHost.IsPlayingAction((int)PLAYER_ACTION_TYPE.ACT_TRICK_RUN) && + m_pHost.m_iMoveMode != (int)MoveMode.MOVE_SLIDE) + { + int iAction = m_pHost.GetMoveStandAction(true); + m_pHost.PlayAction(iAction, false, 200, false); + } + + Trace_Walk(fDeltaTime); + } + else // (m_pHost.m_iMoveEnv == CECPlayer::MOVEENV_AIR || m_pHost.m_iMoveEnv == CECPlayer::MOVEENV_WATER) + { + m_pHost.ResetJump(); + + // Play appropriate actions + int iAction = m_pHost.GetMoveStandAction(true); + m_pHost.PlayAction(iAction, false, 200, false); + + Trace_FlySwim(fDeltaTime); + } + + m_bHaveMoved = true; + } + + return true; + } + // Reset work + public override void Reset() + { + base.Reset(); + + m_bHaveMoved = false; + m_bMeetSlide = false; + m_bCheckTouch = true; + m_bReadyCancel = false; + m_bMoreClose = false; + //m_pPrepSkill = null; + m_bForceAttack = false; + m_bActionDone = false; + ClearResetUseAutoPF(); + m_bUseAutoPF = false; + m_dwAutoPFNextCheckTime = 0; + m_pTraceObject = null; + } + // Work is cancel + public override void Cancel() + { + //if (m_pHost.m_pPrepSkill && m_pTraceObject.GetTraceReason() == Trace_reason.TRACE_SPELL) + // m_pHost.m_pPrepSkill = null; + + ClearResetUseAutoPF(); + if (GetUseAutoPF()) + { + SetUseAutoPF(false); + } + //m_pHost.StopModelMove(); + base.Cancel(); + + //AP_ActionEvent(m_bActionDone ? AP_EVENT_TRACEOK : AP_EVENT_MOVEFINISHED, m_pTraceObject.GetTraceReason()); + } + + // This work is do player moving ? + public override bool IsMoving() { return true; } + // Copy work data + public override bool CopyData(CECHPWork pWork) + { + if (!base.CopyData(pWork)) + return false; + + CECHPWorkTrace pSrc = (CECHPWorkTrace)pWork; + + m_bHaveMoved = pSrc.m_bHaveMoved; + m_bMeetSlide = pSrc.m_bMeetSlide; + m_bCheckTouch = pSrc.m_bCheckTouch; + m_bReadyCancel = pSrc.m_bReadyCancel; + m_bMoreClose = pSrc.m_bMoreClose; + m_vCurDirH = pSrc.m_vCurDirH; + //m_pPrepSkill = pSrc.m_pPrepSkill; + m_bForceAttack = pSrc.m_bForceAttack; + m_bActionDone = pSrc.m_bActionDone; + m_bShouldResetUseAutoPF = pSrc.m_bShouldResetUseAutoPF; + m_bUseAutoPFResetValue = pSrc.m_bUseAutoPFResetValue; + m_bUseAutoPF = pSrc.m_bUseAutoPF; + m_dwAutoPFNextCheckTime = pSrc.m_dwAutoPFNextCheckTime; + + //delete m_pTraceObject; + m_pTraceObject = pSrc.m_pTraceObject.Clone(); + + return true; + } + + // User press cancel button + public void PressCancel() + { + m_bReadyCancel = true; + //if (m_pTraceObject.GetTraceReason() == TRACE_SPELL) + // m_pHost.m_pPrepSkill = NULL; + } + // Set move close flag + public void SetMoveCloseFlag(bool bMoveClose) { m_pTraceObject.SetMoveCloseFlag(bMoveClose); } + + // Set / Get force attack flag + public void SetForceAttack(bool bTrue) { m_bForceAttack = bTrue; } + public bool GetForceAttack() { return m_bForceAttack; } + // Set / Get prepared skill + public void SetPrepSkill(CECSkill pSkill) { m_pPrepSkill = pSkill; } + public CECSkill GetPrepSkill() { /*return m_pPrepSkill;*/ return null; } + // Get target ID + public int GetTarget() { return m_pTraceObject.GetObjectID(); } + // Get trace reason + public int GetTraceReason() { return m_pTraceObject.GetTraceReason(); } + // AutoPF + public void SetUseAutoPF(bool bUse) + { + m_bUseAutoPF = bUse; + //if (!m_bUseAutoPF && CECIntelligentRoute.Instance().IsUsageTrace()) + //{ + // CECIntelligentRoute.Instance().ResetSearch(); + //} + } + public bool GetUseAutoPF() + { + return m_bUseAutoPF; + } + public bool IsAutoPF() + { + return false; + } + + public void SetActionDone(bool bActionDone) { m_bActionDone = bActionDone; } + + public void OnTargetMissing() + { + StopMove(true); + if ((m_pTraceObject.GetTraceType() == TraceObjectType.TRACE_NPC) || (m_pTraceObject.GetTraceType() == TraceObjectType.TRACE_PLAYER)) + { + m_pTraceObject.OnTargetMissing(); + } + //else if (m_pTraceObject.GetTraceReason() == Trace_reason.TRACE_SPELL) + //{ + // m_pHost.m_pPrepSkill = null; + //} + } + + public void OnTouchTarget() + { + StopMove(true); + m_bActionDone = m_pTraceObject.OnTouched(); + } + public bool CanTouch() + { + //CECSkill pPrepSkill = m_pHost.m_pPrepSkill; + CheckPrepSkill(); + bool result = m_pTraceObject.CanTouchFrom(m_pHost.GetPos()); + //m_pHost.m_pPrepSkill = pPrepSkill; + return result; + } + // Attributes + + protected bool m_bHaveMoved; // Have moved flag + protected bool m_bMeetSlide; // true, meet slide + protected bool m_bCheckTouch; // Check whether touch target in this frame + protected A3DVECTOR3 m_vCurDirH; // Current move direction + protected bool m_bReadyCancel; // true, ready to cancel + protected bool m_bMoreClose; // Move close flag + protected bool m_bForceAttack; // Force attack flag + protected CECSkill m_pPrepSkill; // Skill prepared to be casted + protected bool m_bActionDone; // Ŀ����Ϊ�ɹ����� + protected bool m_bShouldResetUseAutoPF; + protected bool m_bUseAutoPFResetValue; + protected bool m_bUseAutoPF; // Use CECIntelligentRoute::Search + protected uint m_dwAutoPFNextCheckTime; // �´μ��ʱ�� + + protected CECTracedObject m_pTraceObject; // ����traceĿ����� + + // Operations + + // On first tick + protected virtual void OnFirstTick() + { + m_pHost.m_iMoveMode = (int)MoveMode.MOVE_MOVE; + m_bHaveMoved = false; + } + + // Trace on ground + protected bool Trace_Walk(float fDeltaTime) + { + A3DVECTOR3 vCurPos = m_pHost.GetPos(); + A3DVECTOR3 vTargetPos = GetCurMovingDest(); + CDR_INFO cdr = m_pHost.m_CDRInfo; + + if (m_pHost.m_iMoveMode == (int)MoveMode.MOVE_SLIDE) + { + m_pHost.PlayAction((int)PLAYER_ACTION_TYPE.ACT_JUMP_LOOP, false, 200, false); + + // This will cause stop moming after we slide down. + A3DVECTOR3 vDir = vTargetPos - vCurPos; + vDir.y = 0; + vDir.Normalize(); + + float fMaxSpeedV = 0f; + m_bMeetSlide = m_pHost.m_MoveCtrl.MeetSlope(vDir, fMaxSpeedV); + EC_Utility.a_ClampFloor(cdr.fYVel, -fMaxSpeedV); + + if (!vDir.IsZero()) + m_vCurDirH = vDir; + + vCurPos = m_pHost.m_MoveCtrl.GroundMove(m_vCurDirH, m_pHost.GetGroundSpeed(), fDeltaTime); + m_pHost.SetDirAndUp(EC_Utility.ToVector3(vCurPos - m_pHost.GetPos()), Vector3.up); + if (m_pHost.m_MoveCtrl.MoveBlocked() >= 3) + { + m_pHost.m_MoveCtrl.SetSlideLock(true); + m_pHost.m_MoveCtrl.SendStopMoveCmd(EC_Utility.ToVector3(vCurPos), m_pHost.GetGroundSpeed(), (int)GPMoveMode.GP_MOVE_SLIDE); + m_bFinished = true; + } + else + { + m_pHost.SetPos(EC_Utility.ToVector3(vCurPos)); + //if (GetUseAutoPF() && CECIntelligentRoute::Instance().IsMoveOn()) + //{ + // CECIntelligentRoute::Instance().OnPlayerPosChange(vCurPos); + //} + m_pHost.m_MoveCtrl.SendMoveCmd(vCurPos, 2, GPDataTypeHelper.g_vOrigin, EC_Utility.ToA3DVECTOR3(cdr.vAbsVelocity), (int)GPMoveMode.GP_MOVE_SLIDE); + } + } + else if (!m_bMeetSlide) + { + int iMoveMode = m_pHost.m_bWalkRun ? (int)GPMoveMode.GP_MOVE_RUN : (int)GPMoveMode.GP_MOVE_WALK; + if (m_pHost.IsJumping()) + iMoveMode = (int)GPMoveMode.GP_MOVE_JUMP; + else if (!m_pHost.m_GndInfo.bOnGround) + iMoveMode = (int)GPMoveMode.GP_MOVE_FALL; + + RaycastHit lastGroundHit; + m_pHost.m_GndInfo.bOnGround = m_pHost.GroundCheck(out lastGroundHit); + if (m_pHost.m_GndInfo.bOnGround) + { + if (m_bReadyCancel) + { + StopMove(true); + return true; + } + + // Ajust direction only when player on ground + A3DVECTOR3 vDirH = vTargetPos - vCurPos; + //Debug.DrawLine(EC_Utility.ToVector3(vCurPos), EC_Utility.ToVector3(vTargetPos), Color.blue, 10f); + A3DVECTOR3 v = A3DFuncs.a3d_Normalize(vDirH); + if (Math.Abs(v.y) > 0.9848f) + { + PressCancel(); + return true; + } + + vDirH.y = 0.0f; + vDirH.Normalize(); + if (!vDirH.IsZero()) + m_vCurDirH = vDirH; + } + + vCurPos = m_pHost.m_MoveCtrl.GroundMove(m_vCurDirH, m_pHost.GetGroundSpeed(), fDeltaTime, m_pHost.m_fVertSpeed); + m_pHost.SetDirAndUp(EC_Utility.ToVector3(vCurPos - m_pHost.GetPos()), Vector3.up); + m_pHost.SetPos(EC_Utility.ToVector3(vCurPos)); //if (GetUseAutoPF() && CECIntelligentRoute::Instance().IsMoveOn()) //{ // CECIntelligentRoute::Instance().OnPlayerPosChange(vCurPos); //} - m_pHost.m_MoveCtrl.SendMoveCmd(vCurPos, 2, GPDataTypeHelper.g_vOrigin, EC_Utility.ToA3DVECTOR3(cdr.vAbsVelocity), (int)GPMoveMode.GP_MOVE_SLIDE); - } - } - else if (!m_bMeetSlide) - { - int iMoveMode = m_pHost.m_bWalkRun ? (int)GPMoveMode.GP_MOVE_RUN : (int)GPMoveMode.GP_MOVE_WALK; - if (m_pHost.IsJumping()) - iMoveMode = (int)GPMoveMode.GP_MOVE_JUMP; - else if (!m_pHost.m_GndInfo.bOnGround) - iMoveMode = (int)GPMoveMode.GP_MOVE_FALL; - RaycastHit lastGroundHit; - m_pHost.m_GndInfo.bOnGround = m_pHost.GroundCheck(out lastGroundHit); - if (m_pHost.m_GndInfo.bOnGround) - { - if (m_bReadyCancel) + if (cdr.vTPNormal == Vector3.zero) { - StopMove(true); - return true; + m_bCheckTouch = false; } - // Ajust direction only when player on ground - A3DVECTOR3 vDirH = vTargetPos - vCurPos; - //Debug.DrawLine(EC_Utility.ToVector3(vCurPos), EC_Utility.ToVector3(vTargetPos), Color.blue, 10f); - A3DVECTOR3 v = A3DFuncs.a3d_Normalize(vDirH); - if (Math.Abs(v.y) > 0.9848f) + //if (!m_vCurDirH.IsZero()) + //{ + // m_pHost.StartModelMove(m_vCurDirH, g_vAxisY, 0); + //} + + if (m_pHost.m_MoveCtrl.MoveBlocked() >= 3) { + //m_pHost.m_MoveCtrl.SendStopMoveCmd(EC_Utility.ToVector3(vCurPos), m_pHost.GetGroundSpeed(), iMoveMode); PressCancel(); - return true; + } + else + { + m_pHost.m_MoveCtrl.SendMoveCmd(vCurPos, 0, vTargetPos, EC_Utility.ToA3DVECTOR3(cdr.vAbsVelocity), iMoveMode); + } + } + else // m_bMeetSlide == true + { + if (m_bHaveMoved) + { + m_pHost.m_MoveCtrl.SendStopMoveCmd(EC_Utility.ToVector3(vCurPos), m_pHost.GetGroundSpeed(), (int)GPMoveMode.GP_MOVE_SLIDE); } - vDirH.y = 0.0f; - vDirH.Normalize(); - if (!vDirH.IsZero()) - m_vCurDirH = vDirH; + m_bFinished = true; + } + return true; + } + // Trace in air and water + public bool Trace_FlySwim(float fDeltaTime) + { + return true; + } + + // Stop move when touch target + public void StopMove(bool bFinish) + { + if (m_bHaveMoved || !m_pHost.m_MoveCtrl.IsStop()) + { + m_pHost.m_MoveCtrl.SendStopMoveCmd(); } - vCurPos = m_pHost.m_MoveCtrl.GroundMove(m_vCurDirH, m_pHost.GetGroundSpeed(), fDeltaTime, m_pHost.m_fVertSpeed); - m_pHost.SetDirAndUp(EC_Utility.ToVector3(vCurPos - m_pHost.GetPos()), Vector3.up); - - m_pHost.SetPos(EC_Utility.ToVector3(vCurPos)); - //if (GetUseAutoPF() && CECIntelligentRoute::Instance().IsMoveOn()) + m_pHost.m_vVelocity.Clear(); + //m_pHost.StopModelMove(); + m_pHost.PlayAction((int)PLAYER_ACTION_TYPE.ACT_STAND, true, 1, false); + if (bFinish) + { + m_bFinished = true; + } + } + // Handle the case that target died when host is tracing it + public bool OnTargetDied(CECObject pTarget) + { + return true; + } + // Is valid time to touch target ? + public bool IsGoodTimeToTouch() + { + if (m_pHost.IsJumping()) + { + return false; + } + return true; + } + // Check prepare skill + public void CheckPrepSkill() + { + + } + public bool GetTargetCurPos(A3DVECTOR3 pos) + { + return true; + } + public A3DVECTOR3 GetCurMovingDest() + { + return m_pTraceObject.GetTargetPos(); + } + public void UpdateUseAutoPF() + { + + } + + public void ReplaceTarget(CECTracedObject ptraceobj) + { + //if (m_pTraceObject) //{ - // CECIntelligentRoute::Instance().OnPlayerPosChange(vCurPos); + // delete m_pTraceObject; //} + m_pTraceObject = ptraceobj; + } - if (cdr.vTPNormal == Vector3.zero) + public void ResetUseAutoPF(bool bUseAutoPF) + { + m_bShouldResetUseAutoPF = true; + m_bUseAutoPFResetValue = bUseAutoPF; + } + public void UpdateResetUseAutoPF() + { + if (!m_bShouldResetUseAutoPF) { - m_bCheckTouch = false; - } - - //if (!m_vCurDirH.IsZero()) - //{ - // m_pHost.StartModelMove(m_vCurDirH, g_vAxisY, 0); - //} - - if (m_pHost.m_MoveCtrl.MoveBlocked() >= 3) - { - //m_pHost.m_MoveCtrl.SendStopMoveCmd(EC_Utility.ToVector3(vCurPos), m_pHost.GetGroundSpeed(), iMoveMode); - PressCancel(); - } - else - { - m_pHost.m_MoveCtrl.SendMoveCmd(vCurPos, 0, vTargetPos, EC_Utility.ToA3DVECTOR3(cdr.vAbsVelocity), iMoveMode); + return; } + //# ifdef SHOW_AUTOMOVE_FOOTPRINTS + // g_AutoPFFollowPoints.clear(); + // g_AutoPFPathPoints.clear(); + //#endif + //CECIntelligentRoute::Instance().SetUsage(CECIntelligentRoute::enumUsageWorkTrace); + //CECIntelligentRoute::Instance().ResetSearch(); + SetUseAutoPF(m_bUseAutoPFResetValue); + ClearResetUseAutoPF(); } - else // m_bMeetSlide == true + public void ClearResetUseAutoPF() { - if (m_bHaveMoved) - { - m_pHost.m_MoveCtrl.SendStopMoveCmd(EC_Utility.ToVector3(vCurPos), m_pHost.GetGroundSpeed(), (int)GPMoveMode.GP_MOVE_SLIDE); - } - - m_bFinished = true; + m_bShouldResetUseAutoPF = false; + m_bUseAutoPFResetValue = false; } - return true; - } - // Trace in air and water - public bool Trace_FlySwim(float fDeltaTime) - { - return true; - } - - // Stop move when touch target - public void StopMove(bool bFinish) - { - if (m_bHaveMoved || !m_pHost.m_MoveCtrl.IsStop()) - { - m_pHost.m_MoveCtrl.SendStopMoveCmd(); - } - - m_pHost.m_vVelocity.Clear(); - //m_pHost.StopModelMove(); - m_pHost.PlayAction((int)CECPlayer.PLAYER_ACTION_TYPE.ACT_STAND, true, 1, false); - if (bFinish) - { - m_bFinished = true; - } - } - // Handle the case that target died when host is tracing it - public bool OnTargetDied(CECObject pTarget) - { - return true; - } - // Is valid time to touch target ? - public bool IsGoodTimeToTouch() - { - if (m_pHost.IsJumping()) - { - return false; - } - return true; - } - // Check prepare skill - public void CheckPrepSkill() - { - - } - public bool GetTargetCurPos(A3DVECTOR3 pos) - { - return true; - } - public A3DVECTOR3 GetCurMovingDest() - { - return m_pTraceObject.GetTargetPos(); - } - public void UpdateUseAutoPF() - { - - } - - public void ReplaceTarget(CECTracedObject ptraceobj) - { - //if (m_pTraceObject) - //{ - // delete m_pTraceObject; - //} - m_pTraceObject = ptraceobj; - } - - public void ResetUseAutoPF(bool bUseAutoPF) - { - m_bShouldResetUseAutoPF = true; - m_bUseAutoPFResetValue = bUseAutoPF; - } - public void UpdateResetUseAutoPF() - { - if (!m_bShouldResetUseAutoPF) - { - return; - } - //# ifdef SHOW_AUTOMOVE_FOOTPRINTS - // g_AutoPFFollowPoints.clear(); - // g_AutoPFPathPoints.clear(); - //#endif - //CECIntelligentRoute::Instance().SetUsage(CECIntelligentRoute::enumUsageWorkTrace); - //CECIntelligentRoute::Instance().ResetSearch(); - SetUseAutoPF(m_bUseAutoPFResetValue); - ClearResetUseAutoPF(); - } - public void ClearResetUseAutoPF() - { - m_bShouldResetUseAutoPF = false; - m_bUseAutoPFResetValue = false; - } -}; \ No newline at end of file + }; +} \ No newline at end of file diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_ManMatter.cs b/Assets/PerfectWorld/Scripts/Managers/EC_ManMatter.cs index 1660fe6aa5..b19e5aea37 100644 --- a/Assets/PerfectWorld/Scripts/Managers/EC_ManMatter.cs +++ b/Assets/PerfectWorld/Scripts/Managers/EC_ManMatter.cs @@ -5,7 +5,6 @@ using CSNetwork; using CSNetwork.GPDataType; using CSNetwork.Protocols; using CSNetwork.Protocols.RPCData; -using PerfectWorld.Scripts.Player; using System; using System.Collections; using System.Collections.Generic; diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_ManPlayer.cs b/Assets/PerfectWorld/Scripts/Managers/EC_ManPlayer.cs index 3adea52fca..1cf106d433 100644 --- a/Assets/PerfectWorld/Scripts/Managers/EC_ManPlayer.cs +++ b/Assets/PerfectWorld/Scripts/Managers/EC_ManPlayer.cs @@ -5,7 +5,6 @@ using CSNetwork; using CSNetwork.GPDataType; using CSNetwork.Protocols; using CSNetwork.Protocols.RPCData; -using PerfectWorld.Scripts.Player; using System; using System.Collections; using System.Collections.Generic; @@ -90,8 +89,8 @@ namespace PerfectWorld.Scripts.Managers //if (pPlayer && !pPlayer.IsAboutToDie()) // pPlayer.Killed(pCmd.idKiller); - EventBus.PublishChannel(pPlayer.GetCharacterID(), new CECPlayer.ClearComActFlagAllRankNodesEvent(true)); - pPlayer.PlayAction((int)CECPlayer.PLAYER_ACTION_TYPE.ACT_GROUNDDIE); + EventBus.PublishChannel(pPlayer.GetCharacterID(), new ClearComActFlagAllRankNodesEvent(true)); + pPlayer.PlayAction((int)PLAYER_ACTION_TYPE.ACT_GROUNDDIE); } private void OnMsgPlayerRevive(ECMSG Msg) diff --git a/Assets/PerfectWorld/Scripts/Managers/aabbcd.cs b/Assets/PerfectWorld/Scripts/Managers/aabbcd.cs index 33c2b0852c..63e60b9b99 100644 --- a/Assets/PerfectWorld/Scripts/Managers/aabbcd.cs +++ b/Assets/PerfectWorld/Scripts/Managers/aabbcd.cs @@ -1,6 +1,5 @@ using CSNetwork.GPDataType; using BrewMonster.Scripts.Player; -using PerfectWorld.Scripts.Player; namespace BrewMonster.Scripts { diff --git a/Assets/PerfectWorld/Scripts/Move/CECPlayer.Task.cs b/Assets/PerfectWorld/Scripts/Move/CECPlayer.Task.cs index b6d80b7d2b..98d53e0503 100644 --- a/Assets/PerfectWorld/Scripts/Move/CECPlayer.Task.cs +++ b/Assets/PerfectWorld/Scripts/Move/CECPlayer.Task.cs @@ -1,11 +1,15 @@ -partial class CECPlayer +namespace BrewMonster { - protected int m_iMoneyCnt; // Amount of money the player has - public int GetMoneyAmount(){ return m_iMoneyCnt; } - - public byte GetShapeMask() + partial class CECPlayer + { - // restore the original data from 8~15 bit - return (byte)((m_iShape & 0xff00) >> 8); + protected int m_iMoneyCnt; // Amount of money the player has + public int GetMoneyAmount() { return m_iMoneyCnt; } + + public byte GetShapeMask() + { + // restore the original data from 8~15 bit + return (byte)((m_iShape & 0xff00) >> 8); + } } } \ No newline at end of file diff --git a/Assets/PerfectWorld/Scripts/Move/CECPlayer.cs b/Assets/PerfectWorld/Scripts/Move/CECPlayer.cs index 08665caa22..07d1a330b3 100644 --- a/Assets/PerfectWorld/Scripts/Move/CECPlayer.cs +++ b/Assets/PerfectWorld/Scripts/Move/CECPlayer.cs @@ -1,90 +1,94 @@ using Animancer; using BrewMonster; using BrewMonster.Managers; +using BrewMonster.Network; +using BrewMonster.PerfectWorld.Scripts.Vfx; +using BrewMonster.Scripts; using BrewMonster.Scripts; using BrewMonster.Scripts.Managers; using BrewMonster.Scripts.Skills; using CSNetwork.GPDataType; using ModelRenderer.Scripts.GameData; using PerfectWorld.Scripts.Managers; -using PerfectWorld.Scripts.Player; using System; using System.Collections.Generic; using System.Threading.Tasks; using System.Xml.Linq; -using BrewMonster.PerfectWorld.Scripts.Vfx; -using BrewMonster.Scripts; using TMPro; using Unity.VisualScripting; using UnityEngine; using UnityEngine.SceneManagement; -using BrewMonster.Network; using UnityEngine.UIElements; -using static CECPlayer; +using static BrewMonster.CECPlayer; -public abstract partial class CECPlayer : CECObject +namespace BrewMonster { - [SerializeField] protected Transform parentModel; - [SerializeField] protected TextMeshProUGUI txtName; - [ResetStatic] - private static PLAYER_ACTION[] _default_actions; - [ResetStatic] - private static PLAYER_ACTION[] _turning_actions; - PLAYER_ACTION[] m_PlayerActions; - [SerializeField] internal INFO m_PlayerInfo; - protected GameObject _pPlayerModel; - protected float rotationSpeed = 5; - internal int m_iMoveMode; // Player's move mode - [SerializeField] internal int m_idSelTarget; - [SerializeField] internal int m_idCurHover; // ID of object under cursor - protected int m_iShape; // Ñ¡ÖÐÄ¿±êµÄID - protected uint m_dwStates; // Player's basic states - - // 当前攻击方式 // Action type for attack animation - protected uint m_uAttackType; - protected int[] m_aEquips; - protected ROLEEXTPROP m_ExtProps; // Extend properties - protected int m_iFashionWeaponType; - protected float m_fTouchRad = 0.3f; // Touch radius - protected bool m_bWeaponAttached; - protected bool m_bFight; - protected int m_iBattleCamp = Player_camp_in_battle.GP_BATTLE_CAMP_NONE; // Battle this player belongs to - byte m_factionPVPMask; // pvp mask - protected uint m_dwResFlags; // pvp mask - protected ROLEBASICPROP m_BasicProps; - public int m_iMoveEnv = Move_environment.MOVEENV_GROUND; // Move environment - public bool m_bWalkRun = true; - public A3DAABB m_aabbServer = new A3DAABB(); // Óë·þÎñÆ÷±£³ÖÒ»ÖµÄaabb£¬ ²»ÊÜËõ·ÅÓ°Ïì - public A3DAABB m_aabb = new A3DAABB(); // Player's aabb£¬ÓÃÓÚÏÔʾµÄaabb£¬ÊÜËõ·ÅÓ°Ïì - public int m_iProfession; // Profession - public float m_fScaleBySkill; - public int m_iGender; // Gender - protected bool m_bFashionMode; - public bool m_bShowWeapon; - private QueueActionEvent queueActionEvent; - protected static PLAYER_LEVELEXP_CONFIG _player_levelup_exp; - private CECPlayerActionController m_pActionController; - private enumWingType m_wingType; - protected int m_idCurSkillTarget; - protected CECSkill m_pCurSkill; - - protected int NUM_WEAPON_TYPE = 15; - public static readonly int[] m_sciStateIDForStateAction = { 117 }; - private static Dictionary _default_skill_actions - = new Dictionary(); - - protected int m_iBoothState = 0; // Booth state. 0, none; 1, prepare; 2, open booth; 3, visite other's booth - public int m_idFRole = GNETRoles._R_UNMEMBER; // ID of player's faction role - protected int m_idCountry = 0; // ¹úÕ½ÕóÓª id - public static int MAX_REINCARNATION = 2; - protected List m_aCurEffects = new List(); // Current effects - byte m_ReincarnationCount = 0; - string m_strName; // Player name - - public MOVECONST m_MoveConst; // Const used when moving control - public Move_Mode m_MoveMode; - public MOVECONST[] aMoveConsts = new MOVECONST[PROFESSION.NUM_PROFESSION * GENDER.NUM_GENDER] + public abstract partial class CECPlayer : CECObject { + [SerializeField] protected Transform parentModel; + [SerializeField] protected TextMeshProUGUI txtName; + [ResetStatic] + private static PLAYER_ACTION[] _default_actions; + [ResetStatic] + private static PLAYER_ACTION[] _turning_actions; + PLAYER_ACTION[] m_PlayerActions; + [SerializeField] internal INFO m_PlayerInfo; + protected GameObject _pPlayerModel; + protected float rotationSpeed = 5; + internal int m_iMoveMode; // Player's move mode + [SerializeField] internal int m_idSelTarget; + [SerializeField] internal int m_idCurHover; // ID of object under cursor + protected int m_iShape; // Ñ¡ÖÐÄ¿±êµÄID + protected uint m_dwStates; // Player's basic states + protected PVPINFO m_pvp; // pvp information + + // 当前攻击方式 // Action type for attack animation + protected uint m_uAttackType; + protected int[] m_aEquips; + protected ROLEEXTPROP m_ExtProps; // Extend properties + protected int m_iFashionWeaponType; + protected float m_fTouchRad = 0.3f; // Touch radius + protected bool m_bWeaponAttached; + protected bool m_bFight; + protected int m_iBattleCamp = Player_camp_in_battle.GP_BATTLE_CAMP_NONE; // Battle this player belongs to + byte m_factionPVPMask; // pvp mask + protected uint m_dwResFlags; // pvp mask + protected ROLEBASICPROP m_BasicProps; + public int m_iMoveEnv = Move_environment.MOVEENV_GROUND; // Move environment + public bool m_bWalkRun = true; + public A3DAABB m_aabbServer = new A3DAABB(); // Óë·þÎñÆ÷±£³ÖÒ»ÖµÄaabb£¬ ²»ÊÜËõ·ÅÓ°Ïì + public A3DAABB m_aabb = new A3DAABB(); // Player's aabb£¬ÓÃÓÚÏÔʾµÄaabb£¬ÊÜËõ·ÅÓ°Ïì + public int m_iProfession; // Profession + public float m_fScaleBySkill; + public int m_iGender; // Gender + protected bool m_bFashionMode; + public bool m_bShowWeapon; + private QueueActionEvent queueActionEvent; + protected static PLAYER_LEVELEXP_CONFIG _player_levelup_exp; + private CECPlayerActionController m_pActionController; + private enumWingType m_wingType; + protected int m_idCurSkillTarget; + protected CECSkill m_pCurSkill; + protected int m_idFaction; // ID of player's faction + protected int m_idForce; // id of the player's force + + protected int NUM_WEAPON_TYPE = 15; + public static readonly int[] m_sciStateIDForStateAction = { 117 }; + private static Dictionary _default_skill_actions + = new Dictionary(); + + protected int m_iBoothState = 0; // Booth state. 0, none; 1, prepare; 2, open booth; 3, visite other's booth + public int m_idFRole = GNETRoles._R_UNMEMBER; // ID of player's faction role + protected int m_idCountry = 0; // ¹úÕ½ÕóÓª id + public static int MAX_REINCARNATION = 2; + protected List m_aCurEffects = new List(); // Current effects + byte m_ReincarnationCount = 0; + string m_strName; // Player name + + public MOVECONST m_MoveConst; // Const used when moving control + public Move_Mode m_MoveMode; + 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), @@ -122,10 +126,10 @@ public abstract partial class CECPlayer : CECObject // ÔÂÏÉ 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] - { + 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), // ·¨Ê¦ @@ -150,208 +154,208 @@ public abstract partial class CECPlayer : CECObject 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 static class Effect_type - { - public const int EFF_FACEPILL = 1; - } - private BaseVfxObject _levelUpVfx; - - protected void Awake() - { - m_PlayerActions = _default_actions; - m_iShape = 0; - m_aEquips = new int[(int)IndexOfIteminEquipmentInventory.SIZE_ALL_EQUIPIVTR]; - queueActionEvent = new QueueActionEvent("", null, false, null); - } - - /// This function will get the coressponding model player for the player based on the profession and gender - public async Task SetPlayerModel(byte profession, byte gender) - { - parentModel = transform.GetChild(0); - txtName = GetComponentInChildren(); - - _pPlayerModel = await NPCManager.Instance.GetModelPlayer(profession, gender); - Scene scene = SceneManager.GetActiveScene(); - SceneManager.MoveGameObjectToScene(_pPlayerModel, scene); - _pPlayerModel.transform.SetParent(parentModel); - _pPlayerModel.transform.localPosition = Vector3.zero; - _pPlayerModel.SetActive(true); - } - public virtual void SetUpPlayer() - { - m_dwResFlags = 0; - m_iFashionWeaponType = -1; - m_uAttackType = DEFAULT_ACTION_TYPE; - - - AttachWeapon(); - } - - public void SetPlayerInfor(INFO playinfo) - { - m_PlayerInfo = playinfo; - } - - public INFO GetPlayInfo() - { - return m_PlayerInfo; - } - - public 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 static async Task LoadPlayerSkin(GameObject aSkins, int index, string szFile) - { - // these are LOD suffix - string[] suffix1 = {"一�?", "二级", "三级"}; - string[] suffix2 = {"", "二级", "三级"}; - - string szSkinFile = ""; - - if( index == EC_Player_Skin_Const.SKIN_BODY_INDEX || index == EC_Player_Skin_Const.SKIN_HEAD_INDEX ) - szSkinFile = $"{szFile}{suffix2[0]}"; - else - szSkinFile = $"{szFile}{suffix1[0]}"; - - aSkins = await AddressableManager.Instance.LoadPrefabAsync(szSkinFile); - - if (aSkins == null) - return false; - - return true; - } - - public static void InitStaticRes() - { - BuildActionList(); - DATA_TYPE dt = default; - _player_levelup_exp = (PLAYER_LEVELEXP_CONFIG)ElementDataManProvider.GetElementDataMan() - .get_data_ptr(202, ID_SPACE.ID_SPACE_CONFIG, ref dt); - } - - public bool IsDead() - { - return (m_dwStates & PlayerNPCState.GP_STATE_CORPSE) != 0; - } - - public bool IsValidAction(int iIndex) - { - return (iIndex >= 0 && iIndex < (int)PLAYER_ACTION_TYPE.ACT_MAX) ? true : false; - } - - public int GetCharacterID() - { - return m_PlayerInfo.cid; - } - - - private static void BuildActionList() - { - if (_default_actions == null) + public static class Effect_type { + public const int EFF_FACEPILL = 1; + } + private BaseVfxObject _levelUpVfx; - Dictionary actionMap = - new Dictionary(100); + protected void Awake() + { + m_PlayerActions = _default_actions; + m_iShape = 0; + m_aEquips = new int[(int)IndexOfIteminEquipmentInventory.SIZE_ALL_EQUIPIVTR]; + queueActionEvent = new QueueActionEvent("", null, false, null); + } - Dictionary skillActionMap = - new Dictionary(100); + /// This function will get the coressponding model player for the player based on the profession and gender + public async Task SetPlayerModel(byte profession, byte gender) + { + parentModel = transform.GetChild(0); + txtName = GetComponentInChildren(); - elementdataman dataman = ElementDataManProvider.GetElementDataMan(); - PLAYER_ACTION_INFO_CONFIG data; + _pPlayerModel = await NPCManager.Instance.GetModelPlayer(profession, gender); + Scene scene = SceneManager.GetActiveScene(); + SceneManager.MoveGameObjectToScene(_pPlayerModel, scene); + _pPlayerModel.transform.SetParent(parentModel); + _pPlayerModel.transform.localPosition = Vector3.zero; + _pPlayerModel.SetActive(true); + } + public virtual void SetUpPlayer() + { + m_dwResFlags = 0; + m_iFashionWeaponType = -1; + m_uAttackType = DEFAULT_ACTION_TYPE; - int count = dataman.get_data_num(ID_SPACE.ID_SPACE_CONFIG); + AttachWeapon(); + } + + public void SetPlayerInfor(INFO playinfo) + { + m_PlayerInfo = playinfo; + } + + public INFO GetPlayInfo() + { + return m_PlayerInfo; + } + + public 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 static async Task LoadPlayerSkin(GameObject aSkins, int index, string szFile) + { + // these are LOD suffix + string[] suffix1 = { "一�?", "二级", "三级" }; + string[] suffix2 = { "", "二级", "三级" }; + + string szSkinFile = ""; + + if (index == EC_Player_Skin_Const.SKIN_BODY_INDEX || index == EC_Player_Skin_Const.SKIN_HEAD_INDEX) + szSkinFile = $"{szFile}{suffix2[0]}"; + else + szSkinFile = $"{szFile}{suffix1[0]}"; + + aSkins = await AddressableManager.Instance.LoadPrefabAsync(szSkinFile); + + if (aSkins == null) + return false; + + return true; + } + + public static void InitStaticRes() + { + BuildActionList(); DATA_TYPE dt = default; - uint id = 0; + _player_levelup_exp = (PLAYER_LEVELEXP_CONFIG)ElementDataManProvider.GetElementDataMan() + .get_data_ptr(202, ID_SPACE.ID_SPACE_CONFIG, ref dt); + } - for (int i = 0; i < count; ++i) + public bool IsDead() + { + return (m_dwStates & PlayerNPCState.GP_STATE_CORPSE) != 0; + } + + public bool IsValidAction(int iIndex) + { + return (iIndex >= 0 && iIndex < (int)PLAYER_ACTION_TYPE.ACT_MAX) ? true : false; + } + + public int GetCharacterID() + { + return m_PlayerInfo.cid; + } + + + private static void BuildActionList() + { + if (_default_actions == null) { - id = dataman.get_data_id(ID_SPACE.ID_SPACE_CONFIG, i, ref dt); - if (dt != DATA_TYPE.DT_PLAYER_ACTION_INFO_CONFIG) - continue; - data = (PLAYER_ACTION_INFO_CONFIG)dataman.get_data_ptr(id, ID_SPACE.ID_SPACE_CONFIG, ref dt); - if (!string.IsNullOrEmpty(data.ActionName) && data.ActionName[0] != '0') + Dictionary actionMap = + new Dictionary(100); + + Dictionary skillActionMap = + new Dictionary(100); + + elementdataman dataman = ElementDataManProvider.GetElementDataMan(); + PLAYER_ACTION_INFO_CONFIG data; + + int count = dataman.get_data_num(ID_SPACE.ID_SPACE_CONFIG); + + DATA_TYPE dt = default; + uint id = 0; + + for (int i = 0; i < count; ++i) { - if (!actionMap.TryAdd(data.ActionName, data)) - { + id = dataman.get_data_id(ID_SPACE.ID_SPACE_CONFIG, i, ref dt); + if (dt != DATA_TYPE.DT_PLAYER_ACTION_INFO_CONFIG) + continue; + data = (PLAYER_ACTION_INFO_CONFIG)dataman.get_data_ptr(id, ID_SPACE.ID_SPACE_CONFIG, ref dt); + if (!string.IsNullOrEmpty(data.ActionName) && data.ActionName[0] != '0') + { + if (!actionMap.TryAdd(data.ActionName, data)) + { + + } + } + if (!string.IsNullOrEmpty(data.ActionName) && data.ActionName[0] != '0') + { + if (!skillActionMap.TryAdd(data.Name, data)) + { + + } } } - if (!string.IsNullOrEmpty(data.ActionName) && data.ActionName[0] != '0') - { - if (!skillActionMap.TryAdd(data.Name, data)) - { + /// + CECStringTab actionNames = new CECStringTab(); + actionNames.Init("actions_player", false); + _default_actions = new PLAYER_ACTION[(int)PLAYER_ACTION_TYPE.ACT_MAX]; + + for (int i = 0; i < _default_actions.Length; i++) + { + _default_actions[i].type = (PLAYER_ACTION_TYPE)i; + + string szName = actionNames.GetANSIString(i); + + if (!string.IsNullOrEmpty(szName)) + { + if (actionMap.TryGetValue(szName, out var it)) + { + _default_actions[i].data = it; + } } } - } - /// - CECStringTab actionNames = new CECStringTab(); - actionNames.Init("actions_player", false); - - _default_actions = new PLAYER_ACTION[(int)PLAYER_ACTION_TYPE.ACT_MAX]; - - for (int i = 0; i < _default_actions.Length; i++) - { - _default_actions[i].type = (PLAYER_ACTION_TYPE)i; - - string szName = actionNames.GetANSIString(i); - - if (!string.IsNullOrEmpty(szName)) + if (_turning_actions != null) _turning_actions = new PLAYER_ACTION[(int)PLAYER_ACTION_TYPE.ACT_MAX]; + _turning_actions = new PLAYER_ACTION[(int)PLAYER_ACTION_TYPE.ACT_MAX]; + if (actionMap.TryGetValue("自身旋转", out PLAYER_ACTION_INFO_CONFIG turningData)) { - if (actionMap.TryGetValue(szName, out var it)) + for (int i = 0; i < (int)PLAYER_ACTION_TYPE.ACT_MAX; i++) { - _default_actions[i].data = it; + if (i < (int)PLAYER_ACTION_TYPE.ACT_GROUNDDIE || + i > (int)PLAYER_ACTION_TYPE.ACT_REVIVE) + { + // Dùng hành động xoay thay thế hành động thường + _turning_actions[i].type = (PLAYER_ACTION_TYPE)i; + _turning_actions[i].data = turningData; + } + else + { + // Dùng hành động mặc định + _turning_actions[i] = _default_actions[i]; + } } } - } - if (_turning_actions != null) _turning_actions = new PLAYER_ACTION[(int)PLAYER_ACTION_TYPE.ACT_MAX]; - _turning_actions = new PLAYER_ACTION[(int)PLAYER_ACTION_TYPE.ACT_MAX]; - if (actionMap.TryGetValue("自身旋转", out PLAYER_ACTION_INFO_CONFIG turningData)) - { - for (int i = 0; i < (int)PLAYER_ACTION_TYPE.ACT_MAX; i++) + + uint idSkill = 0; + + while (true) { - if (i < (int)PLAYER_ACTION_TYPE.ACT_GROUNDDIE || - i > (int)PLAYER_ACTION_TYPE.ACT_REVIVE) + idSkill = ElementSkill.NextSkill(idSkill); + if (idSkill == 0) + break; + + string skillName = ElementSkill.GetName(idSkill); + + if (!string.IsNullOrEmpty(skillName)) { - // Dùng hành động xoay thay thế hành động thường - _turning_actions[i].type = (PLAYER_ACTION_TYPE)i; - _turning_actions[i].data = turningData; - } - else - { - // Dùng hành động mặc định - _turning_actions[i] = _default_actions[i]; - } - } - } - - uint idSkill = 0; - - while (true) - { - idSkill = ElementSkill.NextSkill(idSkill); - if (idSkill == 0) - break; - - string skillName = ElementSkill.GetName(idSkill); - - if (!string.IsNullOrEmpty(skillName)) - { - if (skillActionMap.TryGetValue(skillName, out PLAYER_ACTION_INFO_CONFIG data1)) - { - // ✅ Gán dữ liệu hành động cho skill tương ứng - _default_skill_actions[idSkill] = data1; + if (skillActionMap.TryGetValue(skillName, out PLAYER_ACTION_INFO_CONFIG data1)) + { + // ✅ Gán dữ liệu hành động cho skill tương ứng + _default_skill_actions[idSkill] = data1; #if DEBUG_OUTPUT_ACTIONS for (int n = 0; n < PlayerSkillAction.NUM_WEAPON_TYPE; n++) @@ -365,81 +369,1150 @@ public abstract partial class CECPlayer : CECObject } } #endif - continue; + continue; + } + } + + // ❌ not found + // Debug.LogWarning($"CECPlayer::BuildActionList() Failed to find skill action {idSkill}!"); + } + } + } + + public bool PlayAction(int iAction, bool bRestart = true, int iTransTime = 200, bool bQueue = false) + { + return PlayActionWithConfig(iAction, 0, bRestart, iTransTime, bQueue); + } + + public bool PlayActionWithConfig(int iAction, int actionConfigID, bool bRestart = true, int iTransTime = 200, + bool bQueue = false) + { + if (iAction < 0 || iAction >= (int)PLAYER_ACTION_TYPE.ACT_MAX) + { + return false; + } + + if (actionConfigID > 0) + { + DATA_TYPE dt = DATA_TYPE.DT_INVALID; + var p = ElementDataManProvider.GetElementDataMan() + .get_data_ptr((uint)actionConfigID, ID_SPACE.ID_SPACE_CONFIG, ref dt); + if (dt == DATA_TYPE.DT_PLAYER_ACTION_INFO_CONFIG) + { + PLAYER_ACTION actionConfig; + actionConfig.type = (PLAYER_ACTION_TYPE)iAction; + actionConfig.data = (PLAYER_ACTION_INFO_CONFIG)p; + return PlayActionWithConfig(iAction, actionConfig, bRestart, iTransTime, bQueue); + } + else + { + } + } + + return PlayActionWithConfig(iAction, m_PlayerActions[iAction], bRestart, iTransTime, bQueue); + } + + public bool PlayActionWithConfig(int iAction, in PLAYER_ACTION actionConfig, + bool bRestart = true, int iTransTime = 200, bool bQueue = false) + { + PLAYER_ACTION action = actionConfig; + + var szAct = EC_Utility.BuildActionName(action, 0); + EventBus.PublishChannel(m_PlayerInfo.cid, new PlayActionEvent(szAct)); + return true; + } + + public static void Dispose() + { + _default_actions = null; + _turning_actions = null; + } + + + + public INFO GetPlayerInfo() + { + return m_PlayerInfo; + } + + protected override void Update() + { + base.Update(); + } + + + + public void PlayAttackEffect(int idTarget, int idSkill, int skillLevel, int nDamage, + uint dwModifier, int nAttackSpeed, ref int piAttackTime, int nSection = 0) + { + if (!IsAllResReady()) + return; + + if (idSkill == 0) + { + int idWeapon = IsShapeChanged() ? 0 : GetWeaponID(); + + int nTimeFly = 10; + if (idWeapon != 0) + { + // ¿´¿´ÊDz»ÊÇÔ¶³ÌÎäÆ÷ + DATA_TYPE dt = default; + WEAPON_ESSENCE? pWeapon = (WEAPON_ESSENCE)ElementDataManProvider.GetElementDataMan() + .get_data_ptr((uint)idWeapon, ID_SPACE.ID_SPACE_ESSENCE, ref dt); + + if (dt == DATA_TYPE.DT_WEAPON_ESSENCE && pWeapon != null && pWeapon.Value.require_projectile != 0) + { + nTimeFly = 700; + + if (m_aEquips[(int)IndexOfIteminEquipmentInventory.EQUIPIVTR_PROJECTILE] != 0) + idWeapon = m_aEquips[(int)IndexOfIteminEquipmentInventory.EQUIPIVTR_PROJECTILE]; } } - // ❌ not found - // Debug.LogWarning($"CECPlayer::BuildActionList() Failed to find skill action {idSkill}!"); + if (CECAttacksMan.Instance.FindAttackByAttacker(GetPlayerInfo().cid)) + { + ClearComActFlagAllRankNodes(true); + } + + // melee attack + CECAttackEvent pAttack1 = CECAttacksMan.Instance.AddMeleeAttack( + GetPlayerInfo().cid, idTarget, idWeapon, dwModifier, nDamage, nTimeFly); + + if (pAttack1 != null) + { + if (!IsDead() && (dwModifier & (uint)MOD.MOD_RETORT) == 0 + && (dwModifier & (uint)MOD.MOD_ATTACK_AURA) == 0 + && PlayAttackAction(nAttackSpeed, ref piAttackTime, pAttack1) + && (dwModifier & (uint)MOD.MOD_BEAT_BACK) == 0) + { + } + else + { + pAttack1.m_bSignaled = true; + } + } + } + else + { + if (skillLevel == 0) + { + if (m_pCurSkill != null) + skillLevel = m_pCurSkill.GetSkillLevel(); + else + skillLevel = 1; + } + + CECAttackEvent pAttack = null; + + // first try to find if there is already a skill attack event in attackman + CECAttackerEvents attackerEvents = CECAttacksMan.Instance.FindAttackByAttacker(GetPlayerInfo().cid); + if (attackerEvents) + { + CECAttackEvent pAttack1 = attackerEvents.Find(idSkill, nSection); + if (pAttack1 != null) + { + // Ãæ¹¥»÷µÄ·ÇµÚÒ»´ÎÉ˺¦ÏûÏ¢ + pAttack1.AddTarget(idTarget, dwModifier, nDamage); + goto EXIT; + } + else + { + attackerEvents.Signal(); + } + } + if (ElementSkill.IsGoblinSkill((uint)idSkill) && + ElementSkill.GetType((uint)idSkill) == 2) + { + pAttack = CECAttacksMan.Instance.AddSkillAttack( + GetPlayerInfo().cid, GetPlayerInfo().cid, idTarget, GetWeaponID(), idSkill, skillLevel, dwModifier, nDamage); + } + else + { + // begin a skill attack + pAttack = CECAttacksMan.Instance.AddSkillAttack( + GetPlayerInfo().cid, m_idCurSkillTarget, idTarget, GetWeaponID(), idSkill, skillLevel, dwModifier, nDamage); + } + + if (pAttack != null) + { + int unusedInt = 0; + pAttack.SetSkillSection(nSection); + if (!IsDead() && (dwModifier & (uint)MOD.MOD_RETORT) == 0 + && (dwModifier & (uint)MOD.MOD_ATTACK_AURA) == 0 + && PlaySkillAttackAction(idSkill, nAttackSpeed, ref unusedInt, nSection, pAttack) + && (dwModifier & (uint)MOD.MOD_BEAT_BACK) == 0) + { + } + else + { + pAttack.m_bSignaled = true; + } + } + + EXIT: + // // For skill attacking, time is always set to 0 + if (piAttackTime != 0) + piAttackTime = 0; } } - } - public bool PlayAction(int iAction, bool bRestart = true, int iTransTime = 200, bool bQueue = false) - { - return PlayActionWithConfig(iAction, 0, bRestart, iTransTime, bQueue); - } + protected void ClearComActFlagAllRankNodes(bool v) + { + EventBus.PublishChannel(m_PlayerInfo.cid, new ClearComActFlagAllRankNodesEvent(v)); + } - public bool PlayActionWithConfig(int iAction, int actionConfigID, bool bRestart = true, int iTransTime = 200, - bool bQueue = false) - { - if (iAction < 0 || iAction >= (int)PLAYER_ACTION_TYPE.ACT_MAX) + public bool PlayAttackAction(int nAttackSpeed, ref int attackTime, CECAttackEvent attackEvent) + { + //attackTime = 0; + + //if (_pPlayerModel == null) + // return false; + + int nRand = UnityEngine.Random.Range(0, 4); + string szAct = string.Empty; + + int weapon_type = GetShowingWeaponType(); + + int nTime1 = 0, nTime2 = 0; + int iAction = (int)PLAYER_ACTION_TYPE.ACT_ATTACK_1 + nRand; + PLAYER_ACTION action = m_PlayerActions[iAction]; + + if (string.IsNullOrEmpty(action.data.ActionPrefix)) + return false; + + ShowWeaponByConfig(action.data); + + /* var pRightHandWeapon = GetRightHandWeapon(); + bool bHideFX = !CECOptimize.Instance.GFX.CanShowAttack(GetCharacterID(), GetClassID());*/ + // ============================== + // Ground Attack + // ============================== + if (GetMoveEnv() == (int)MoveEnvironment.MOVEENV_GROUND) + { + + // “起�? 动作(挥起) + szAct = EC_Utility.BuildActionName(action, weapon_type, "起"); + EventBus.PublishChannel(m_PlayerInfo.cid, new PlayActionEvent(szAct)); + szAct = EC_Utility.BuildActionName(action, weapon_type, "落"); + queueActionEvent.SetData(szAct, SetApplyDamage, true, attackEvent); + EventBus.PublishChannelClass(m_PlayerInfo.cid, queueActionEvent); + //PlayNonSkillActionWithName(iAction, szAct, true, 200, true, ref pActFlag, COMACT_FLAG_MODE_ONCE_MULTIIGNOREGFX);gagága + /* + if (pRightHandWeapon != null && IsUsingMagicWeapon()) + pRightHandWeapon.PlayActionByName(_GenWeaponActionName(szAct, m_iGender), 1.0f, true, 200, true, iAction, bHideFX); + + nTime1 = _pPlayerModel.GetComActTimeSpanByName(szAct); + + // “收” 动作(挥下) + szAct = $"{action.data.action_prefix}_{action.data.action_weapon_suffix[weapon_type].suffix}Âä"; + QueueNonSkillActionWithName(iAction, szAct, 0, false, bHideFX); + + if (pRightHandWeapon != null && IsUsingMagicWeapon()) + pRightHandWeapon.QueueAction(_GenWeaponActionName(szAct, m_iGender), 0, iAction, false, false, bHideFX); + + nTime2 = _pPlayerModel.GetComActTimeSpanByName(szAct);*/ + } + // ============================== + // Air Attack + // ============================== + else + { + /*string szActionMiddleName; + + if ((m_wingType == WINGTYPE_WING && IsFlying()) || + GetProfession() == PROF_ANGEL || + GetProfession() == PROF_ARCHOR || + GetProfession() == PROF_MONK || + GetProfession() == PROF_GHOST) + { + szActionMiddleName = "¿ÕÖгá°ò"; // tấn công trên không + } + else + { + szActionMiddleName = "¿ÕÖзɽ£"; // rơi xuống hoặc bay + } + + szAct = $"{action.data.action_prefix}_{szActionMiddleName}_{action.data.action_weapon_suffix[weapon_type].suffix}Æð"; + PlayNonSkillActionWithName(iAction, szAct, true, 200, bHideFX, ref pActFlag, COMACT_FLAG_MODE_ONCE_MULTIIGNOREGFX); + + if (pRightHandWeapon != null && IsUsingMagicWeapon()) + pRightHandWeapon.PlayActionByName(_GenWeaponActionName(szAct, m_iGender), 1.0f, true, 200, true, iAction, bHideFX); + + nTime1 = m_pPlayerModel.GetComActTimeSpanByName(szAct); + + szAct = $"{action.data.action_prefix}_{szActionMiddleName}_{action.data.action_weapon_suffix[weapon_type].suffix}Âä"; + QueueNonSkillActionWithName(iAction, szAct, 0, false, bHideFX); + + if (pRightHandWeapon != null && IsUsingMagicWeapon()) + pRightHandWeapon.QueueAction(_GenWeaponActionName(szAct, m_iGender), 0, iAction, false, false, bHideFX); + + nTime2 = m_pPlayerModel.GetComActTimeSpanByName(szAct);*/ + } + + // ============================== + // Kết thúc bằng FightStand + // ============================== + PLAYER_ACTION stand_action = m_PlayerActions[(int)PLAYER_ACTION_TYPE.ACT_FIGHTSTAND]; + szAct = EC_Utility.BuildActionName(stand_action, 0); + queueActionEvent.SetData(szAct, SetApplyDamage, false, attackEvent); + EventBus.PublishChannelClass(m_PlayerInfo.cid, queueActionEvent); + + /* QueueNonSkillActionWithName(ACT_FIGHTSTAND, szAct, 300, false, bHideFX, true); + + if (pRightHandWeapon != null && IsUsingMagicWeapon()) + pRightHandWeapon.QueueAction(_GenWeaponActionName(szAct, m_iGender), 300, iAction, false, false, bHideFX, true);*/ + + // ============================== + // Điều chỉnh tốc độ phát animation theo tốc độ tấn công + // ============================== + /* if (nAttackSpeed > 0) + { + float vScale = (nTime1 + nTime2) / (float)nAttackSpeed; + if (vScale > 0f) + { + m_pPlayerModel.SetPlaySpeed(vScale); + + if (pRightHandWeapon != null && IsUsingMagicWeapon()) + pRightHandWeapon.SetPlaySpeed(vScale); + } + } + + attackTime = nTime1 + nTime2;*/ + + // ============================== + // Cập nhật vị trí weapon hanger (vũ khí) + // ============================== + //UpdateWeaponHangerPosByAction(iAction); + + return true; + } + + public void SetApplyDamage(bool isApplyDamage, CECAttackEvent cECAttackEvent) + { + cECAttackEvent.m_bSignaled = isApplyDamage; + } + + public void ShowWeaponByConfig(PLAYER_ACTION_INFO_CONFIG p) + { + m_bShowWeapon = p.hide_weapon != 0 ? false : true; + //ShowWeapon(m_bShowWeapon); + } + + 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) + { + weapon_type = (EC_Utility.BinaryEquals(m_iFashionWeaponType, DEFAULT_ACTION_TYPE) || !IsWeaponAttached()) + ? 10 + : m_iFashionWeaponType; + } + else + { + weapon_type = (EC_Utility.BinaryEquals(m_uAttackType, DEFAULT_ACTION_TYPE) || !IsWeaponAttached()) ? 10 : (int)m_uAttackType; + } + + return weapon_type; + } + + public bool IsWeaponAttached() + { + return m_bWeaponAttached; + } + bool AttachWeapon() + { + bool result = (false); + + /*while (GetPlayerModel() && (GetLeftHandWeapon() || GetRightHandWeapon())){ + A3DSkinModel *pSkinModel = GetPlayerModel()->GetA3DSkinModel(); + if (!pSkinModel || + !pSkinModel->GetSkeleton()){ + break; + } + if (!pSkinModel->GetSkeletonHook(GetLeftWeaponHookPos(m_weaponHangerPos),true) || + !pSkinModel->GetSkeletonHook(GetRightWeaponHookPos(m_weaponHangerPos),true)){ + break; + } + if (GetLeftHandWeapon()){ + GetPlayerModel()->AddChildModel( + _left_hand_weapon, + false, + GetLeftWeaponHookPos(m_weaponHangerPos), + GetLeftHandWeapon(), + GetLeftWeaponOwnHookPos(GetLeftHandWeapon())); + } + if (GetRightHandWeapon()){ + GetPlayerModel()->AddChildModel( + _right_hand_weapon, + false, + GetRightWeaponHookPos(m_weaponHangerPos), + GetRightHandWeapon(), + GetRightWeaponOwnHookPos(GetRightHandWeapon())); + } + ALog log; + log.Init("EC.log", "My Application Log"); + + // Anywhere in your code where you want to see the call flow: + log.Log("[HoangDev]Checking execution flow at this point:"); + log.LogStackTrace(); + + log.Release(); + m_bWeaponAttached = true; + result = true; + break; + }*/ + m_bWeaponAttached = true; + result = true; + return result; + } + public bool InFashionMode() + { + return m_bFashionMode; + } + + public bool CanShowFashionWeapon(int weapon_type, int fashion_weapon_type) + { + return IsFashionWeaponTypeFit(weapon_type, fashion_weapon_type) && InFashionMode(); + } + + public bool IsFashionWeaponTypeFit(int weapon_type, int fashion_weapon_type) + { + if (fashion_weapon_type < 0 || fashion_weapon_type >= NUM_WEAPON_TYPE) return false; + FASHION_WEAPON_CONFIG? pConfig = GetFashionConfig(); + if (null == pConfig) + { + BMLogger.LogError("CECPlayer::GetFashionConfig, Failed to load fashion weapon config"); + return false; + } + + int fashion_weapon_mask = (int)pConfig.Value.action_mask[fashion_weapon_type]; + return (fashion_weapon_mask & (1 << GetWeaponType(weapon_type))) != 0; + } + + public FASHION_WEAPON_CONFIG GetFashionConfig() + { + FASHION_WEAPON_CONFIG? pFashionConfig = null; + if (null == pFashionConfig) + { + elementdataman pDataMan = ElementDataManProvider.GetElementDataMan(); + DATA_TYPE DataType = DATA_TYPE.DT_FASHION_WEAPON_CONFIG; + uint tid = pDataMan.get_id_with_data_type(ID_SPACE.ID_SPACE_CONFIG, DataType); + + if (tid != 0) + { + pFashionConfig = + (FASHION_WEAPON_CONFIG)pDataMan.get_data_ptr(tid, ID_SPACE.ID_SPACE_CONFIG, ref DataType); + BMLogger.LogError($"HoangDev : get_data_ptr {pFashionConfig.GetType()}"); + } + } + + return pFashionConfig == null ? default : pFashionConfig.Value; + } + + public int GetSelectedTarget() + { + return m_idSelTarget; + } + + public float GetTouchRadius() + { + return m_fTouchRad; + } + + // Is player in battle + public bool IsInBattle() + { + return m_iBattleCamp != Player_camp_in_battle.GP_BATTLE_CAMP_NONE; + } + + // Check whether specified npc in a same battle camp + public bool InSameBattleCamp(CECNPC pNPC) + { + if (!pNPC || m_iBattleCamp == Player_camp_in_battle.GP_BATTLE_CAMP_NONE || + (m_iBattleCamp == Player_camp_in_battle.GP_BATTLE_CAMP_INVADER && !pNPC.IsInBattleInvaderCamp()) || + (m_iBattleCamp == Player_camp_in_battle.GP_BATTLE_CAMP_DEFENDER && !pNPC.IsInBattleDefenderCamp())) + return false; + + return true; + } + public int GetBattleCamp() { return m_iBattleCamp; } + + public bool InSameBattleCamp(CECPlayer pPlayer) + { + if (!pPlayer || m_iBattleCamp == Player_camp_in_battle.GP_BATTLE_CAMP_NONE || + m_iBattleCamp != pPlayer.GetBattleCamp()) + return false; + + return true; + } + + public const uint DEFAULT_ACTION_TYPE = 0xFFFFFFFF; + + public static int GetWeaponType(int iWeaponType) + { + return iWeaponType == DEFAULT_ACTION_TYPE ? 10 : iWeaponType; + } + + public bool IsInFactionPVP() => (m_factionPVPMask & 0x01) != 0; + public bool CanAttackFactionPVPMineCar() => (m_factionPVPMask & 0x02) != 0; + public bool CanAttackFactionPVPMineBase() => (m_factionPVPMask & 0x04) != 0; + + public int GetLevelUpExp(int iLevel) + { + return _player_levelup_exp.exp[iLevel - 1]; + //return iLevel * iLevel * 500; + } + + // Get basic properties + public ROLEBASICPROP GetBasicProps() + { + return m_BasicProps; + } + + public override void TurnFaceTo(int idTarget, float dwTime = 200) + { + if (idTarget != 0) + { + if (idTarget == GetCharacterID()) + { + return; + } + + if (IsWorkMoveRunning() /*&& !IsPlayingCastingSkillAndMoveActions()*/) + { + // ÒÆ¶¯Ê±Ò»°ãÓ¦ÃæÏòÒÆ¶¯·½Ïò¡¢Ö»ÔÚÒÆ¶¯Ê©·¨ÖвÅתÏò + return; + } + } + + var target = EC_ManMessageMono.Instance?.GetObject(idTarget, 0)?.gameObject.transform; + if (target == null) + { + BMLogger.LogError("HoangDev: ko có transform "); + return; + } + + Vector3 direction = (target.position - transform.position).normalized; + direction.y = 0f; + int turnSpeed = 5; + if (direction.sqrMagnitude > 0.001f) + { + // T�?o rotation mới hướng tới target + Quaternion targetRotation = Quaternion.LookRotation(direction, Vector3.up); + + // Xoay mư�?t t�? rotation hiện t�?i sang rotation m�?c tiêu + //transform.rotation = Quaternion.Slerp( + // transform.rotation, + // targetRotation, + // Time.deltaTime * turnSpeed + //); + transform.rotation = targetRotation; + } + } + + public virtual bool IsWorkMoveRunning() { return false; } - if (actionConfigID > 0) + /* public bool IsPlayingCastingSkillAndMoveActions() + { + return IsPlayingCastingSkillAction() && IsPlayingMoveAction(); + } + public bool IsPlayingCastingSkillAction() + { + return m_pActionController ? m_pActionController.IsPlayingCastingSkillAction() : false; + } + bool IsPlayingMoveAction() + { + return m_pActionController ? m_pActionController.IsPlayingMoveAction() : false; + }*/ + public int GetMoveStandAction(bool bMove, bool bFight = false) { - DATA_TYPE dt = DATA_TYPE.DT_INVALID; - var p = ElementDataManProvider.GetElementDataMan() - .get_data_ptr((uint)actionConfigID, ID_SPACE.ID_SPACE_CONFIG, ref dt); - if (dt == DATA_TYPE.DT_PLAYER_ACTION_INFO_CONFIG) + int iMoveEnv = m_iMoveEnv; + //if (m_AttachMode != enumAttachNone) + //{ + // bFight = false; + // if (m_bHangerOn) + // iMoveEnv = MOVEENV_GROUND; + //} + + int iAction = (int)PLAYER_ACTION_TYPE.ACT_STAND; + + if (bMove) { - PLAYER_ACTION actionConfig; - actionConfig.type = (PLAYER_ACTION_TYPE)iAction; - actionConfig.data = (PLAYER_ACTION_INFO_CONFIG)p; - return PlayActionWithConfig(iAction, actionConfig, bRestart, iTransTime, bQueue); + // Play appropriate actions + if (iMoveEnv == (int)MoveEnvironment.MOVEENV_GROUND) + { + if (m_bWalkRun) + iAction = (int)PLAYER_ACTION_TYPE.ACT_RUN; + else + iAction = (int)PLAYER_ACTION_TYPE.ACT_WALK; + } + //else if (iMoveEnv == MOVEENV_AIR) + //{ + // //if (/*UsingWing()*/ m_wingType == WINGTYPE_WING) + // // iAction = ACT_FLY; + // //else + // // iAction = ACT_FLY_SWORD; + //} + //else if (iMoveEnv == MOVEENV_WATER) + //{ + // //if (CanCombineWithMoveForSkill()) + // //{ + // // iAction = ACT_SWIM_FOR_MOVESKILL; + // //} + // //else + // //{ + // // iAction = ACT_SWIM; + // //} + //} } else { + // Play appropriate actions + if (iMoveEnv == (int)MoveEnvironment.MOVEENV_GROUND) + { + if (bFight) + iAction = (int)PLAYER_ACTION_TYPE.ACT_FIGHTSTAND; + else + iAction = (int)PLAYER_ACTION_TYPE.ACT_STAND; + } + //else if (iMoveEnv == MOVEENV_AIR) + //{ + // if (/*UsingWing()*/ m_wingType == WINGTYPE_WING) + // iAction = ACT_HANGINAIR; + // else + // iAction = ACT_HANGINAIR_SWORD; + //} + //else if (iMoveEnv == MOVEENV_WATER) + // iAction = ACT_HANGINWATER; + } + + return iAction; + } + + public void Damaged(int nDamage, uint dwModifier = 0, int skill = 0) + { + if (nDamage == -2) + { + // this message is caused by a help skill, so don't use a wounded action here + /* if (dwModifier & CECAttackEvent::MOD_IMMUNE) + BubbleText(BUBBLE_IMMUNE, 0); + else if (dwModifier & CECAttackEvent::MOD_NULLITY) + BubbleText(BUBBLE_INVALIDHIT, 0); + else if (dwModifier & CECAttackEvent::MOD_DODGE_DEBUFF) + BubbleText(BUBBLE_DODGE_DEBUFF, 0);*/ + } + else if (nDamage == -1) + { + // when else player hit this player iDamage is -1, + // Just play a wounded action + if (!OnDamaged(skill)) + { + // PlayAction((int)PLAYER_ACTION_TYPE.ACT_WOUNDED); + } + /*if (dwModifier & CECAttackEvent::MOD_IMMUNE) + BubbleText(BUBBLE_IMMUNE, 0); + else if (dwModifier & CECAttackEvent::MOD_NULLITY) + BubbleText(BUBBLE_INVALIDHIT, 0); + else if (dwModifier & CECAttackEvent::MOD_DODGE_DEBUFF) + BubbleText(BUBBLE_DODGE_DEBUFF, 0);*/ + } + else + { + // Popup a damage decal + if (nDamage > 0) + { + int p1 = 0; + /*if (dwModifier & CECAttackEvent::MOD_CRITICAL_STRIKE) + p1 |= 0x0001; + + if (dwModifier & CECAttackEvent::MOD_RETORT) + p1 |= 0x0002;*/ + + if (!OnDamaged(skill)) + // PlayAction((int)PLAYER_ACTION_TYPE.ACT_WOUNDED); + + DamageTextManager.Instance.ShowDamageText( + transform.position, nDamage, Color.yellow, 1.0f); + /* if (dwModifier & CECAttackEvent::MOD_IMMUNE) + BubbleText(BUBBLE_IMMUNE, 0); + else if (dwModifier & CECAttackEvent::MOD_REBOUND) + BubbleText(BUBBLE_REBOUND, nDamage); + else if (dwModifier & CECAttackEvent::MOD_BEAT_BACK) + BubbleText(BUBBLE_BEAT_BACK, nDamage); + else + BubbleText(BUBBLE_DAMAGE, nDamage, p1);*/ + } + /* else if (dwModifier & CECAttackEvent::MOD_IMMUNE) + BubbleText(BUBBLE_IMMUNE, 0); + else if (dwModifier & CECAttackEvent::MOD_NULLITY) + BubbleText(BUBBLE_INVALIDHIT, 0); + else + BubbleText(BUBBLE_HITMISSED, 0);*/ + } + } + public bool PlaySkillCastAction(int idSkill) + { + string szAct = ""; + + int weapon_type = GetShowingWeaponType(); + + if (!_default_skill_actions.TryGetValue((uint)idSkill, out PLAYER_ACTION_INFO_CONFIG data) || data.action_prefix == null || data.action_prefix.Length == 0 || data.action_prefix[0] == 0) + { + // Check if it's a target item skill + if (ElementSkill.GetCommonCoolDown((uint)idSkill) > 1 << 4) + { + data = m_PlayerActions[(int)PLAYER_ACTION_TYPE.ACT_USING_TARGET_ITEM].data; + + if (data.action_prefix == null || data.action_prefix.Length == 0 || data.action_prefix[0] == 0) + return false; + } + else + return false; + } + + if (GetMoveEnv() == (int)MoveEnvironment.MOVEENV_GROUND) + { + szAct = EC_Utility.BuildActionName(data, weapon_type, "_Ò÷³ª_"); + BMLogger.LogError($"HoangDev: PlaySkillCastAction szAct={szAct} "); + } + else + { + /* if ((*//*UsingWing()*//*m_wingType == enumWingType.WINGTYPE_WING && IsFlying()) || (GetProfession() == PROF_ANGEL) || (GetProfession() == PROF_ARCHOR) || (GetProfession() == PROF_MONK) || (GetProfession() == PROF_GHOST)) + sprintf(szAct, "%s_¿ÕÖгá°ò_Ò÷³ª_%s", data->action_prefix, data->action_weapon_suffix[weapon_type].suffix); + else + sprintf(szAct, "%s_¿ÕÖзɽ£_Ò÷³ª_%s", data->action_prefix, data->action_weapon_suffix[weapon_type].suffix);*/ + } + + bool bHideFX = false; /*!CECOptimize::Instance().GetGFX().CanShowCast(GetCharacterID(), GetClassID());*/ + if (!PlaySkillCastActionWithName(idSkill, szAct, bHideFX)) + { + return false; + } + + ShowWeaponByConfig(data); + //UpdateWeaponHangerPosBySkillAction(idSkill);// ¸ù¾Ý¼¼Äܲ¥·ÅµÄ¶¯×÷£¬¸ü¸ÄÎäÆ÷Ðü¹ÒλÖã¨Ö»Äܼì²é²»ÅŶӶ¯×÷£© + return true; + } + public bool OnDamaged(int skill) + { + var atkMan = CECAttacksMan.Instance; + if (atkMan == null) + return false; + + string name1, name2; + + for (int i = 0; i < m_sciStateIDForStateAction.Length; i++) + { + /* if (atkMan.GetSkillStateActionName(skill, m_sciStateIDForStateAction[i], out name1, out name2)) + { + m_SkillIDForStateAction = skill; + return true; + }*/ + } + + return false; + } + public bool PlaySkillCastActionWithName(int idSkill, string szActName, bool bNoFX/* =false */) + { + return m_pActionController != null + && m_pActionController.PlaySkillCastActionWithName(idSkill, szActName, bNoFX); + } + + public bool PlaySkillAttackAction(int idSkill, int nAttackSpeed, ref int piAttackTime, int nSection = 0, CECAttackEvent attackEvent = null) + { + if (_pPlayerModel == null) + return false; + + string szAct = ""; + + int weapon_type = GetShowingWeaponType(); + + if (!_default_skill_actions.TryGetValue((uint)idSkill, out PLAYER_ACTION_INFO_CONFIG data) || + data.action_prefix == null || data.action_prefix.Length == 0 || data.action_prefix[0] == 0) + { + // Check if it's a target item skill / 检查是否为目标道具技能 + if (ElementSkill.GetCommonCoolDown((uint)idSkill) > 1 << 4) + { + PLAYER_ACTION_INFO_CONFIG? data2 = m_PlayerActions[(int)PLAYER_ACTION_TYPE.ACT_USING_TARGET_ITEM].data; + if (data2 == null || data2.Value.action_prefix == null || data2.Value.action_prefix.Length == 0 || data2.Value.action_prefix[0] == 0) + return false; + } + else + return false; + } + + int nTime1, nTime2; + bool bInfinite = false; + // CECModel pRightHandWeapon = GetRightHandWeapon(); // 获取右手武器 / Get right hand weapon + bool bHideFX = false; // !CECOptimize::Instance().GetGFX().CanShowAttack(GetCharacterID(), GetClassID()); + + var atkMan = CECAttacksMan.Instance; + + if (GetMoveEnv() == (int)MoveEnvironment.MOVEENV_GROUND) + { + szAct = EC_Utility.BuildActionName(data, weapon_type, "_施放起_"); + GetSkillSectionActionName(ref szAct, idSkill, nSection); + + if (!PlaySkillAttackActionWithName(idSkill, szAct, bHideFX, attackEvent)) + { + return false; + } + + // nTime1 = m_pPlayerModel->GetComActTimeSpanByName(szAct); // 获取动作时长 / Get action time span + // pAct = m_pPlayerModel->GetComActByName(szAct); + // if (pAct) bInfinite |= pAct->IsInfinite(); + nTime1 = 1000; // 临时值 / Temporary value + + szAct = EC_Utility.BuildActionName(data, weapon_type, "_施放落_"); + GetSkillSectionActionName(ref szAct, idSkill, nSection); + QueueSkillAttackActionWithName(idSkill, szAct, 0, bHideFX); + + // nTime2 = m_pPlayerModel->GetComActTimeSpanByName(szAct); + // pAct = m_pPlayerModel->GetComActByName(szAct); + // if (pAct) bInfinite |= pAct->IsInfinite(); + nTime2 = 1000; // 临时值 / Temporary value + } + else + { + // 空中动作 / Air action + string szActionMiddleName = null; + if ((m_wingType == enumWingType.WINGTYPE_WING && IsFlying()) || + (m_iProfession == PROFESSION.PROF_ANGEL) || + (m_iProfession == PROFESSION.PROF_ARCHOR) || + (m_iProfession == PROFESSION.PROF_MONK) || + (m_iProfession == PROFESSION.PROF_GHOST)) + { + szActionMiddleName = "_空中翅膀"; // Air with wings / 空中翅膀 + } + else + { + szActionMiddleName = "_空中飞剑"; // Air with sword / 空中飞剑 + } + + szActionMiddleName += "_施放起_"; + szAct = EC_Utility.BuildActionName(data, weapon_type, szActionMiddleName); + GetSkillSectionActionName(ref szAct, idSkill, nSection); + + if (!PlaySkillAttackActionWithName(idSkill, szAct, bHideFX, attackEvent)) + { + return false; + } + + // if (pRightHandWeapon && IsUsingMagicWeapon()) + // pRightHandWeapon->PlayActionByName(_GenWeaponActionName(szAct, m_iGender), 1.0f, true, 200, true, ACT_CASTSKILL, bHideFX); + + // nTime1 = m_pPlayerModel->GetComActTimeSpanByName(szAct); + // pAct = m_pPlayerModel->GetComActByName(szAct); + // if (pAct) bInfinite |= pAct->IsInfinite(); + nTime1 = 1000; // 临时值 / Temporary value + + szAct = $"{data.action_prefix}_{szActionMiddleName}_施法行_{data.action_weapon_suffix[weapon_type].suffix}"; + GetSkillSectionActionName(ref szAct, idSkill, nSection); + QueueSkillAttackActionWithName(idSkill, szAct, 0, bHideFX); + + // if (pRightHandWeapon && IsUsingMagicWeapon()) + // pRightHandWeapon->QueueAction(_GenWeaponActionName(szAct, m_iGender), 0, ACT_CASTSKILL, false, false, bHideFX); + + // nTime2 = m_pPlayerModel->GetComActTimeSpanByName(szAct); + // pAct = m_pPlayerModel->GetComActByName(szAct); + // if (pAct) bInfinite |= pAct->IsInfinite(); + nTime2 = 1000; // 临时值 / Temporary value + } + + // int nExecuteTime = GNET::ElementSkill::GetExecuteTime(idSkill, 0); // 获取技能执行时间 / Get skill execute time + int nExecuteTime = 2000; // 临时值 / Temporary value + + // 调整动画速度以匹配攻击速度 / Adjust animation speed to match attack speed + if (!bInfinite) + { + if (nExecuteTime > 0) + { + float vScale = (nTime1 + nTime2) / (float)nExecuteTime; + // m_pPlayerModel->SetPlaySpeed(vScale * 1.2f); + + // if (pRightHandWeapon && IsUsingMagicWeapon()) + // pRightHandWeapon->SetPlaySpeed(vScale * 1.2f); + } + + piAttackTime = nTime1 + nTime2; + } + else + { + // 动作循环,返回技能决定的执行时间 / Action loops, return skill-determined execute time + piAttackTime = nExecuteTime; + } + + ShowWeaponByConfig(data); + // UpdateWeaponHangerPosBySkillAction(idSkill); // 根据技能播放的动作,更改武器悬挂位置 / Update weapon hanger position based on skill action + return true; + } + public bool IsTeamMember(int idPlayer) + { + //TODO: HoangDev implement later + return false; + /* if (!m_pTeam) + return false; + + return m_pTeam->GetMemberByID(idPlayer) ? true : false;*/ + } + public bool PlaySkillAttackActionWithName(int idSkill, string szActName, bool bNoFX = false, CECAttackEvent attackEvent = null) + { + return m_pActionController != null + && m_pActionController.PlaySkillAttackActionWithName(idSkill, szActName, bNoFX, attackEvent != null ? new bool[] { attackEvent.m_bSignaled } : null, 0); + } + + public bool QueueSkillAttackActionWithName(int idSkill, string szActName, int nTransTime = 200, bool bNoFX = false, bool bResetSpeed = false, bool bResetActFlag = false, bool[] pNewActFlag = null, uint dwNewFlagMode = 0) + { + return m_pActionController != null + && m_pActionController.QueueSkillAttackActionWithName(idSkill, szActName, nTransTime, bNoFX, bResetSpeed, bResetActFlag, pNewActFlag, dwNewFlagMode); + } + + private void GetSkillSectionActionName(ref string szAct, int idSkill, int nSection) + { + if (nSection != 0) + { + var pAtkMan = CECAttacksMan.Instance; + if (pAtkMan != null && pAtkMan.GetSkillSectionActionSuffix(idSkill, nSection, out string suffix)) + { + szAct += "_" + suffix; + } } } - return PlayActionWithConfig(iAction, m_PlayerActions[iAction], bRestart, iTransTime, bQueue); + // 判断是否在飞行 / Check if flying + public bool IsFlying() + { + // 临时实现 / Temporary implementation + return m_iMoveEnv == (int)MoveEnvironment.MOVEENV_AIR; + } + public bool IsInvader() + { + return (m_dwStates & PlayerNPCState.GP_STATE_INVADER) != 0; + } + public int GetFactionID() { return m_idFaction; } + public int GetForce() { return m_idForce; } + public bool IsInDuel() { return m_pvp.iDuelState == (int)DuelState.DUEL_ST_INDUEL; } + // Duel state + public enum DuelState + + { + DUEL_ST_NONE = 0, + DUEL_ST_PREPARE, + DUEL_ST_INDUEL, + DUEL_ST_STOPPING, + }; + public bool IsPariah() + { + return (m_dwStates & PlayerNPCState.GP_STATE_PARIAH) != 0; + } + bool GetSkillStateActionName(int skill, int state, string name1, string name2) + { + /* for (int i = 0; i < (int)m_SkillStateActionVec.size(); i++) + { + if (m_SkillStateActionVec[i].skill == skill && m_SkillStateActionVec[i].state == state) + { + name1 = m_SkillStateActionVec[i].beHitAction; + name2 = m_SkillStateActionVec[i].stayDownAction; + return true; + } + }*/ + return false; + } + public virtual bool IsFighting() { return m_bFight; } + public float GetGroundSpeed() + { + // return m_bWalkRun ? g_pGame.GetConfigs().GetHostRunSpeed() : m_ExtProps.mv.walk_speed; + return 5f; + return m_bWalkRun ? m_ExtProps.mv.run_speed : m_ExtProps.mv.walk_speed; + } + + // Get move environment + public int GetMoveEnv() + { + return m_iMoveEnv; + } + + public bool IsShapeChanged() + { + return m_iShape != 0; + } + + // 获取职业 // Get profession + public int GetProfession() + { + return m_iProfession; + } + + // 获取性别 // Get gender + public int GetGender() + { + return m_iGender; + } + + // 获取变身类型 // Get shape type + // PLAYERMODEL_GETTYPE(iShape) = (iShape & 0xff) >> 6 + public int GetShapeType() + { + return (m_iShape & 0xff) >> 6; + } + + // 获取变身ID // Get shape ID + // PLAYERMODEL_GETID(iShape) = iShape & 0x3f + public int GetShapeID() + { + return m_iShape & 0x3f; + } + + public int GetWeaponID() + { + return m_aEquips[(int)IndexOfIteminEquipmentInventory.EQUIPIVTR_WEAPON] & 0xffff; + } + + public bool IsAllResReady() + { + return (m_dwResFlags & (uint)PlayerResourcesReadyFlag.RESFG_ALL) == (uint)PlayerResourcesReadyFlag.RESFG_ALL; + } + // Get character ID + + // Play Gfx on Models + protected bool PlayGfx(string szPath, string szHook, float fScale /*1.0f*/, uint iShapeTypeMask /*(1<PlayGfx(szPath, szHook, fScale); + // bPlayed = true; + // } + // if(bSkipRecord) continue; + // A3DGFXEx* pGfx = m_pModels[i]->GetGfx(szPath, szHook); + // if (pGfx && pGfx->IsInfinite()){ + // GFXRECORD rec; + // rec.strPath = szPath; + // rec.strHook = szHook; + // rec.fScale = fScale; + // AString key = rec.strPath + rec.strHook; + // m_GfxRecords[key] = rec; + // bSkipRecord = true; + // } + // } + // } + PlayLevelUpGfx(szPath); + return false; + } + + private async void PlayLevelUpGfx(string path) + { + // Usage: Load the prefab asynchronously using AddressableManager + GameObject prefab = await AddressableManager.Instance.LoadPrefabAsync(path); + if (prefab != null) + { + if (_levelUpVfx != null) + { + if (_levelUpVfx.IsPlaying()) + return; + _levelUpVfx.Play(); + return; + } + + // Instantiate at player's current position and rotation + _levelUpVfx = Instantiate(prefab, transform).GetComponent(); + _levelUpVfx.Play(); + // vfx.transform.SetParent(transform); transform.position, prefab.transform.rotation + _levelUpVfx.transform.localPosition = Vector3.zero; + } + else + { + BMLogger.LogError($"Failed to load level up effect prefab at: {path}"); + } + } + + // Get booth state + public int GetBoothState() { return m_iBoothState; } + + // Check whether player has effect of specified type + public bool HasEffectType(int iEffType) + { + int i; + + switch (iEffType) + { + case Effect_type.EFF_FACEPILL: + { + elementdataman pDataMan = EC_Game.GetElementDataMan(); + + // Get item data type + for (i = 0; i < m_aCurEffects.Count; i++) + { + DATA_TYPE DataType = pDataMan.get_data_type((uint)m_aCurEffects[i], ID_SPACE.ID_SPACE_ESSENCE); + if (DataType == DATA_TYPE.DT_FACEPILL_ESSENCE) + return true; + } + + break; + } + } + + return false; + } + + public byte GetReincarnationCount() { return m_ReincarnationCount; } + + public string GetName() + { + return m_strName; + } } - public bool PlayActionWithConfig(int iAction, in PLAYER_ACTION actionConfig, - bool bRestart = true, int iTransTime = 200, bool bQueue = false) + public struct PlayActionEvent { - PLAYER_ACTION action = actionConfig; + public string AnimationName; - var szAct = EC_Utility.BuildActionName(action, 0); - EventBus.PublishChannel(m_PlayerInfo.cid, new PlayActionEvent(szAct)); - return true; + public PlayActionEvent(string animationName) + { + this.AnimationName = animationName; + } } - - public static void Dispose() - { - _default_actions = null; - _turning_actions = null; - } - public struct PLAYER_ACTION { public PLAYER_ACTION_TYPE type; public PLAYER_ACTION_INFO_CONFIG data; }; - - public INFO GetPlayerInfo() + public class QueueActionEvent { - return m_PlayerInfo; - } + public string AnimationName; + public Action SetFlag; + public CECAttackEvent AttackEvent; + public bool IsHitAnim; - protected override void Update() - { - base.Update(); - } + public QueueActionEvent(string animationName, Action setFlag, bool isHitAnim, + CECAttackEvent attackEvent) + { + this.AnimationName = animationName; + SetFlag = setFlag; + IsHitAnim = isHitAnim; + AttackEvent = attackEvent; + } + public void SetData(string animationName, Action setFlag, bool isHitAnim, + CECAttackEvent attackEvent) + { + this.AnimationName = animationName; + SetFlag = setFlag; + IsHitAnim = isHitAnim; + AttackEvent = attackEvent; + } + } public enum PLAYER_ACTION_TYPE { // 0 @@ -575,126 +1648,6 @@ public abstract partial class CECPlayer : CECObject ACT_MAX, ACT_CASTSKILL // Ch�? là placeholder cho skill actions } - - public void PlayAttackEffect(int idTarget, int idSkill, int skillLevel, int nDamage, - uint dwModifier, int nAttackSpeed, ref int piAttackTime, int nSection = 0) - { - if (!IsAllResReady()) - return; - - if (idSkill == 0) - { - int idWeapon = IsShapeChanged() ? 0 : GetWeaponID(); - - int nTimeFly = 10; - if (idWeapon != 0) - { - // ¿´¿´ÊDz»ÊÇÔ¶³ÌÎäÆ÷ - DATA_TYPE dt = default; - WEAPON_ESSENCE? pWeapon = (WEAPON_ESSENCE)ElementDataManProvider.GetElementDataMan() - .get_data_ptr((uint)idWeapon, ID_SPACE.ID_SPACE_ESSENCE, ref dt); - - if (dt == DATA_TYPE.DT_WEAPON_ESSENCE && pWeapon != null && pWeapon.Value.require_projectile != 0) - { - nTimeFly = 700; - - if (m_aEquips[(int)IndexOfIteminEquipmentInventory.EQUIPIVTR_PROJECTILE] != 0) - idWeapon = m_aEquips[(int)IndexOfIteminEquipmentInventory.EQUIPIVTR_PROJECTILE]; - } - } - - if (CECAttacksMan.Instance.FindAttackByAttacker(GetPlayerInfo().cid)) - { - ClearComActFlagAllRankNodes(true); - } - - // melee attack - CECAttackEvent pAttack1 = CECAttacksMan.Instance.AddMeleeAttack( - GetPlayerInfo().cid, idTarget, idWeapon, dwModifier, nDamage, nTimeFly); - - if (pAttack1 != null) - { - if (!IsDead() && (dwModifier & (uint)MOD.MOD_RETORT) == 0 - && (dwModifier & (uint)MOD.MOD_ATTACK_AURA) == 0 - && PlayAttackAction(nAttackSpeed, ref piAttackTime, pAttack1) - && (dwModifier & (uint)MOD.MOD_BEAT_BACK) == 0) - { - } - else - { - pAttack1.m_bSignaled = true; - } - } - } - else - { - if (skillLevel == 0) - { - if (m_pCurSkill != null) - skillLevel = m_pCurSkill.GetSkillLevel(); - else - skillLevel = 1; - } - - CECAttackEvent pAttack = null; - - // first try to find if there is already a skill attack event in attackman - CECAttackerEvents attackerEvents = CECAttacksMan.Instance.FindAttackByAttacker(GetPlayerInfo().cid); - if (attackerEvents) - { - CECAttackEvent pAttack1 = attackerEvents.Find(idSkill, nSection); - if (pAttack1 != null) - { - // Ãæ¹¥»÷µÄ·ÇµÚÒ»´ÎÉ˺¦ÏûÏ¢ - pAttack1.AddTarget(idTarget, dwModifier, nDamage); - goto EXIT; - } - else - { - attackerEvents.Signal(); - } - } - if (ElementSkill.IsGoblinSkill((uint)idSkill) && - ElementSkill.GetType((uint)idSkill) == 2) - { - pAttack = CECAttacksMan.Instance.AddSkillAttack( - GetPlayerInfo().cid, GetPlayerInfo().cid, idTarget, GetWeaponID(), idSkill, skillLevel, dwModifier, nDamage); - } - else - { - // begin a skill attack - pAttack = CECAttacksMan.Instance.AddSkillAttack( - GetPlayerInfo().cid, m_idCurSkillTarget, idTarget, GetWeaponID(), idSkill, skillLevel, dwModifier, nDamage); - } - - if (pAttack != null) - { - int unusedInt = 0; - pAttack.SetSkillSection(nSection); - if (!IsDead() && (dwModifier & (uint)MOD.MOD_RETORT) == 0 - && (dwModifier & (uint)MOD.MOD_ATTACK_AURA) == 0 - && PlaySkillAttackAction(idSkill, nAttackSpeed,ref unusedInt, nSection, pAttack) - && (dwModifier & (uint)MOD.MOD_BEAT_BACK) == 0) - { - } - else - { - pAttack.m_bSignaled = true; - } - } - - EXIT: - // // For skill attacking, time is always set to 0 - if (piAttackTime != 0) - piAttackTime = 0; - } - } - - protected void ClearComActFlagAllRankNodes(bool v) - { - EventBus.PublishChannel(m_PlayerInfo.cid, new ClearComActFlagAllRankNodesEvent(v)); - } - public struct ClearComActFlagAllRankNodesEvent { public bool v; @@ -704,958 +1657,80 @@ public abstract partial class CECPlayer : CECObject v = value; } } - - public bool PlayAttackAction(int nAttackSpeed, ref int attackTime, CECAttackEvent attackEvent) + [Serializable] + public struct INFO { - //attackTime = 0; + public int cid; // Character ID + public int crc_c; // customized data crc + public int crc_e; // Equipment data crc - //if (_pPlayerModel == null) - // return false; - - int nRand = UnityEngine.Random.Range(0, 4); - string szAct = string.Empty; - - int weapon_type = GetShowingWeaponType(); - - int nTime1 = 0, nTime2 = 0; - int iAction = (int)PLAYER_ACTION_TYPE.ACT_ATTACK_1 + nRand; - PLAYER_ACTION action = m_PlayerActions[iAction]; - - if (string.IsNullOrEmpty(action.data.ActionPrefix)) - return false; - - ShowWeaponByConfig(action.data); - - /* var pRightHandWeapon = GetRightHandWeapon(); - bool bHideFX = !CECOptimize.Instance.GFX.CanShowAttack(GetCharacterID(), GetClassID());*/ - // ============================== - // Ground Attack - // ============================== - if (GetMoveEnv() == (int)MoveEnvironment.MOVEENV_GROUND) + public INFO(int cid, int crc_c, int crc_) { - - // “起�? 动作(挥起) - szAct = EC_Utility.BuildActionName(action, weapon_type, "起"); - EventBus.PublishChannel(m_PlayerInfo.cid, new PlayActionEvent(szAct)); - szAct = EC_Utility.BuildActionName(action, weapon_type, "落"); - queueActionEvent.SetData(szAct, SetApplyDamage, true, attackEvent); - EventBus.PublishChannelClass(m_PlayerInfo.cid, queueActionEvent); - //PlayNonSkillActionWithName(iAction, szAct, true, 200, true, ref pActFlag, COMACT_FLAG_MODE_ONCE_MULTIIGNOREGFX);gagága - /* - if (pRightHandWeapon != null && IsUsingMagicWeapon()) - pRightHandWeapon.PlayActionByName(_GenWeaponActionName(szAct, m_iGender), 1.0f, true, 200, true, iAction, bHideFX); - - nTime1 = _pPlayerModel.GetComActTimeSpanByName(szAct); - - // “收” 动作(挥下) - szAct = $"{action.data.action_prefix}_{action.data.action_weapon_suffix[weapon_type].suffix}Âä"; - QueueNonSkillActionWithName(iAction, szAct, 0, false, bHideFX); - - if (pRightHandWeapon != null && IsUsingMagicWeapon()) - pRightHandWeapon.QueueAction(_GenWeaponActionName(szAct, m_iGender), 0, iAction, false, false, bHideFX); - - nTime2 = _pPlayerModel.GetComActTimeSpanByName(szAct);*/ - } - // ============================== - // Air Attack - // ============================== - else - { - /*string szActionMiddleName; - - if ((m_wingType == WINGTYPE_WING && IsFlying()) || - GetProfession() == PROF_ANGEL || - GetProfession() == PROF_ARCHOR || - GetProfession() == PROF_MONK || - GetProfession() == PROF_GHOST) - { - szActionMiddleName = "¿ÕÖгá°ò"; // tấn công trên không - } - else - { - szActionMiddleName = "¿ÕÖзɽ£"; // rơi xuống hoặc bay - } - - szAct = $"{action.data.action_prefix}_{szActionMiddleName}_{action.data.action_weapon_suffix[weapon_type].suffix}Æð"; - PlayNonSkillActionWithName(iAction, szAct, true, 200, bHideFX, ref pActFlag, COMACT_FLAG_MODE_ONCE_MULTIIGNOREGFX); - - if (pRightHandWeapon != null && IsUsingMagicWeapon()) - pRightHandWeapon.PlayActionByName(_GenWeaponActionName(szAct, m_iGender), 1.0f, true, 200, true, iAction, bHideFX); - - nTime1 = m_pPlayerModel.GetComActTimeSpanByName(szAct); - - szAct = $"{action.data.action_prefix}_{szActionMiddleName}_{action.data.action_weapon_suffix[weapon_type].suffix}Âä"; - QueueNonSkillActionWithName(iAction, szAct, 0, false, bHideFX); - - if (pRightHandWeapon != null && IsUsingMagicWeapon()) - pRightHandWeapon.QueueAction(_GenWeaponActionName(szAct, m_iGender), 0, iAction, false, false, bHideFX); - - nTime2 = m_pPlayerModel.GetComActTimeSpanByName(szAct);*/ - } - - // ============================== - // Kết thúc bằng FightStand - // ============================== - PLAYER_ACTION stand_action = m_PlayerActions[(int)PLAYER_ACTION_TYPE.ACT_FIGHTSTAND]; - szAct = EC_Utility.BuildActionName(stand_action, 0); - queueActionEvent.SetData(szAct, SetApplyDamage, false, attackEvent); - EventBus.PublishChannelClass(m_PlayerInfo.cid, queueActionEvent); - - /* QueueNonSkillActionWithName(ACT_FIGHTSTAND, szAct, 300, false, bHideFX, true); - - if (pRightHandWeapon != null && IsUsingMagicWeapon()) - pRightHandWeapon.QueueAction(_GenWeaponActionName(szAct, m_iGender), 300, iAction, false, false, bHideFX, true);*/ - - // ============================== - // Điều chỉnh tốc độ phát animation theo tốc độ tấn công - // ============================== - /* if (nAttackSpeed > 0) - { - float vScale = (nTime1 + nTime2) / (float)nAttackSpeed; - if (vScale > 0f) - { - m_pPlayerModel.SetPlaySpeed(vScale); - - if (pRightHandWeapon != null && IsUsingMagicWeapon()) - pRightHandWeapon.SetPlaySpeed(vScale); - } - } - - attackTime = nTime1 + nTime2;*/ - - // ============================== - // Cập nhật vị trí weapon hanger (vũ khí) - // ============================== - //UpdateWeaponHangerPosByAction(iAction); - - return true; - } - - public void SetApplyDamage(bool isApplyDamage, CECAttackEvent cECAttackEvent) - { - cECAttackEvent.m_bSignaled = isApplyDamage; - } - - public void ShowWeaponByConfig(PLAYER_ACTION_INFO_CONFIG p) - { - m_bShowWeapon = p.hide_weapon != 0 ? false : true; - //ShowWeapon(m_bShowWeapon); - } - - 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) - { - weapon_type = (EC_Utility.BinaryEquals(m_iFashionWeaponType, DEFAULT_ACTION_TYPE) || !IsWeaponAttached()) - ? 10 - : m_iFashionWeaponType; - } - else - { - weapon_type = (EC_Utility.BinaryEquals(m_uAttackType, DEFAULT_ACTION_TYPE) || !IsWeaponAttached()) ? 10 : (int)m_uAttackType; - } - - return weapon_type; - } - - public bool IsWeaponAttached() - { - return m_bWeaponAttached; - } - bool AttachWeapon() - { - bool result = (false); - - /*while (GetPlayerModel() && (GetLeftHandWeapon() || GetRightHandWeapon())){ - A3DSkinModel *pSkinModel = GetPlayerModel()->GetA3DSkinModel(); - if (!pSkinModel || - !pSkinModel->GetSkeleton()){ - break; - } - if (!pSkinModel->GetSkeletonHook(GetLeftWeaponHookPos(m_weaponHangerPos),true) || - !pSkinModel->GetSkeletonHook(GetRightWeaponHookPos(m_weaponHangerPos),true)){ - break; - } - if (GetLeftHandWeapon()){ - GetPlayerModel()->AddChildModel( - _left_hand_weapon, - false, - GetLeftWeaponHookPos(m_weaponHangerPos), - GetLeftHandWeapon(), - GetLeftWeaponOwnHookPos(GetLeftHandWeapon())); - } - if (GetRightHandWeapon()){ - GetPlayerModel()->AddChildModel( - _right_hand_weapon, - false, - GetRightWeaponHookPos(m_weaponHangerPos), - GetRightHandWeapon(), - GetRightWeaponOwnHookPos(GetRightHandWeapon())); - } - ALog log; - log.Init("EC.log", "My Application Log"); - - // Anywhere in your code where you want to see the call flow: - log.Log("[HoangDev]Checking execution flow at this point:"); - log.LogStackTrace(); - - log.Release(); - m_bWeaponAttached = true; - result = true; - break; - }*/ - m_bWeaponAttached = true; - result = true; - return result; - } - public bool InFashionMode() - { - return m_bFashionMode; - } - - public bool CanShowFashionWeapon(int weapon_type, int fashion_weapon_type) - { - return IsFashionWeaponTypeFit(weapon_type, fashion_weapon_type) && InFashionMode(); - } - - public bool IsFashionWeaponTypeFit(int weapon_type, int fashion_weapon_type) - { - if (fashion_weapon_type < 0 || fashion_weapon_type >= NUM_WEAPON_TYPE) return false; - FASHION_WEAPON_CONFIG? pConfig = GetFashionConfig(); - if (null == pConfig) - { - BMLogger.LogError("CECPlayer::GetFashionConfig, Failed to load fashion weapon config"); - return false; - } - - int fashion_weapon_mask = (int)pConfig.Value.action_mask[fashion_weapon_type]; - return (fashion_weapon_mask & (1 << GetWeaponType(weapon_type))) != 0; - } - - public FASHION_WEAPON_CONFIG GetFashionConfig() - { - FASHION_WEAPON_CONFIG? pFashionConfig = null; - if (null == pFashionConfig) - { - elementdataman pDataMan = ElementDataManProvider.GetElementDataMan(); - DATA_TYPE DataType = DATA_TYPE.DT_FASHION_WEAPON_CONFIG; - uint tid = pDataMan.get_id_with_data_type(ID_SPACE.ID_SPACE_CONFIG, DataType); - - if (tid != 0) - { - pFashionConfig = - (FASHION_WEAPON_CONFIG)pDataMan.get_data_ptr(tid, ID_SPACE.ID_SPACE_CONFIG, ref DataType); - BMLogger.LogError($"HoangDev : get_data_ptr {pFashionConfig.GetType()}"); - } - } - - return pFashionConfig == null ? default : pFashionConfig.Value; - } - - public int GetSelectedTarget() - { - return m_idSelTarget; - } - - public float GetTouchRadius() - { - return m_fTouchRad; - } - - // Is player in battle - public bool IsInBattle() - { - return m_iBattleCamp != Player_camp_in_battle.GP_BATTLE_CAMP_NONE; - } - - // Check whether specified npc in a same battle camp - public bool InSameBattleCamp(CECNPC pNPC) - { - if (!pNPC || m_iBattleCamp == Player_camp_in_battle.GP_BATTLE_CAMP_NONE || - (m_iBattleCamp == Player_camp_in_battle.GP_BATTLE_CAMP_INVADER && !pNPC.IsInBattleInvaderCamp()) || - (m_iBattleCamp == Player_camp_in_battle.GP_BATTLE_CAMP_DEFENDER && !pNPC.IsInBattleDefenderCamp())) - return false; - - return true; - } - - public const uint DEFAULT_ACTION_TYPE = 0xFFFFFFFF; - - public static int GetWeaponType(int iWeaponType) - { - return iWeaponType == DEFAULT_ACTION_TYPE ? 10 : iWeaponType; - } - - public bool IsInFactionPVP() => (m_factionPVPMask & 0x01) != 0; - public bool CanAttackFactionPVPMineCar() => (m_factionPVPMask & 0x02) != 0; - public bool CanAttackFactionPVPMineBase() => (m_factionPVPMask & 0x04) != 0; - - public int GetLevelUpExp(int iLevel) - { - return _player_levelup_exp.exp[iLevel - 1]; - //return iLevel * iLevel * 500; - } - - // Get basic properties - public ROLEBASICPROP GetBasicProps() - { - return m_BasicProps; - } - - public override void TurnFaceTo(int idTarget, float dwTime = 200) - { - if (idTarget != 0) - { - if (idTarget == GetCharacterID()) - { - return; - } - - if (IsWorkMoveRunning() /*&& !IsPlayingCastingSkillAndMoveActions()*/) - { - // ÒÆ¶¯Ê±Ò»°ãÓ¦ÃæÏòÒÆ¶¯·½Ïò¡¢Ö»ÔÚÒÆ¶¯Ê©·¨ÖвÅתÏò - return; - } - } - - var target = EC_ManMessageMono.Instance?.GetObject(idTarget, 0)?.gameObject.transform; - if (target == null) - { - BMLogger.LogError("HoangDev: ko có transform "); - return; - } - - Vector3 direction = (target.position - transform.position).normalized; - direction.y = 0f; - int turnSpeed = 5; - if (direction.sqrMagnitude > 0.001f) - { - // T�?o rotation mới hướng tới target - Quaternion targetRotation = Quaternion.LookRotation(direction, Vector3.up); - - // Xoay mư�?t t�? rotation hiện t�?i sang rotation m�?c tiêu - //transform.rotation = Quaternion.Slerp( - // transform.rotation, - // targetRotation, - // Time.deltaTime * turnSpeed - //); - transform.rotation = targetRotation; + this.cid = cid; + this.crc_c = crc_c; + this.crc_e = crc_; } } - - public virtual bool IsWorkMoveRunning() + public + enum enumWingType { - return false; + WINGTYPE_WING, // ·ÉÐÐÆ÷ÀàÐÍ£º³á°ò + WINGTYPE_FLYSWORD, // ·ÉÐÐÆ÷ÀàÐÍ£º·É½£ + WINGTYPE_DOUBLEWHEEL, // ·ÉÐÐÆ÷ÀàÐÍ£ºË«½Å·ÉÐÐÆ÷ + }; + public struct PVPINFO + { + public bool bEnable; // PVP switch + public uint dwCoolTime; + public uint dwMaxCoolTime; + public bool bFreePVP; // Free PVP flag, ignore bEnable flag + public bool bInPVPCombat; // true, in PVP combat + public int iDuelState; // Duel state + public int idDuelOpp; // Duel opponent + public int iDuelTimeCnt; // Duel time counter + public int iDuelRlt; // Duel result. 0, no defined; 1-win; 2-lose; 3-draw + }; + public enum PlayerResourcesReadyFlag + + { + RESFG_SKELETON = 0x01, + RESFG_SKIN = 0x02, + RESFG_CUSTOM = 0x04, + RESFG_ASSEMBLED = 0x08, + RESFG_ALL = 0x0f, + }; + + public static class Duel_state // Duel state + { + public const int DUEL_ST_NONE = 0, + DUEL_ST_PREPARE = 1, + DUEL_ST_INDUEL = 2, + DUEL_ST_STOPPING = 3; } - /* public bool IsPlayingCastingSkillAndMoveActions() - { - return IsPlayingCastingSkillAction() && IsPlayingMoveAction(); - } - public bool IsPlayingCastingSkillAction() - { - return m_pActionController ? m_pActionController.IsPlayingCastingSkillAction() : false; - } - bool IsPlayingMoveAction() - { - return m_pActionController ? m_pActionController.IsPlayingMoveAction() : false; - }*/ - public int GetMoveStandAction(bool bMove, bool bFight = false) + //// Move mode + public class Move_Mode { - int iMoveEnv = m_iMoveEnv; - //if (m_AttachMode != enumAttachNone) - //{ - // bFight = false; - // if (m_bHangerOn) - // iMoveEnv = MOVEENV_GROUND; - //} - - int iAction = (int)PLAYER_ACTION_TYPE.ACT_STAND; - - if (bMove) - { - // Play appropriate actions - if (iMoveEnv == (int)MoveEnvironment.MOVEENV_GROUND) - { - if (m_bWalkRun) - iAction = (int)PLAYER_ACTION_TYPE.ACT_RUN; - else - iAction = (int)PLAYER_ACTION_TYPE.ACT_WALK; - } - //else if (iMoveEnv == MOVEENV_AIR) - //{ - // //if (/*UsingWing()*/ m_wingType == WINGTYPE_WING) - // // iAction = ACT_FLY; - // //else - // // iAction = ACT_FLY_SWORD; - //} - //else if (iMoveEnv == MOVEENV_WATER) - //{ - // //if (CanCombineWithMoveForSkill()) - // //{ - // // iAction = ACT_SWIM_FOR_MOVESKILL; - // //} - // //else - // //{ - // // iAction = ACT_SWIM; - // //} - //} - } - else - { - // Play appropriate actions - if (iMoveEnv == (int)MoveEnvironment.MOVEENV_GROUND) - { - if (bFight) - iAction = (int)PLAYER_ACTION_TYPE.ACT_FIGHTSTAND; - else - iAction = (int)PLAYER_ACTION_TYPE.ACT_STAND; - } - //else if (iMoveEnv == MOVEENV_AIR) - //{ - // if (/*UsingWing()*/ m_wingType == WINGTYPE_WING) - // iAction = ACT_HANGINAIR; - // else - // iAction = ACT_HANGINAIR_SWORD; - //} - //else if (iMoveEnv == MOVEENV_WATER) - // iAction = ACT_HANGINWATER; - } - - return iAction; + public const int MOVE_STAND = 0, + MOVE_MOVE = 1, // Normal move, walk, run, swim or fly + MOVE_JUMP = 2, + MOVE_FREEFALL = 3, + MOVE_SLIDE = 4; } - public void Damaged(int nDamage, uint dwModifier = 0, int skill = 0) + public class EC_Player_Skin_Const { - if (nDamage == -2) - { - // this message is caused by a help skill, so don't use a wounded action here - /* if (dwModifier & CECAttackEvent::MOD_IMMUNE) - BubbleText(BUBBLE_IMMUNE, 0); - else if (dwModifier & CECAttackEvent::MOD_NULLITY) - BubbleText(BUBBLE_INVALIDHIT, 0); - else if (dwModifier & CECAttackEvent::MOD_DODGE_DEBUFF) - BubbleText(BUBBLE_DODGE_DEBUFF, 0);*/ - } - else if (nDamage == -1) - { - // when else player hit this player iDamage is -1, - // Just play a wounded action - if (!OnDamaged(skill)) - { - // PlayAction((int)PLAYER_ACTION_TYPE.ACT_WOUNDED); - } - /*if (dwModifier & CECAttackEvent::MOD_IMMUNE) - BubbleText(BUBBLE_IMMUNE, 0); - else if (dwModifier & CECAttackEvent::MOD_NULLITY) - BubbleText(BUBBLE_INVALIDHIT, 0); - else if (dwModifier & CECAttackEvent::MOD_DODGE_DEBUFF) - BubbleText(BUBBLE_DODGE_DEBUFF, 0);*/ - } - else - { - // Popup a damage decal - if (nDamage > 0) - { - int p1 = 0; - /*if (dwModifier & CECAttackEvent::MOD_CRITICAL_STRIKE) - p1 |= 0x0001; - - if (dwModifier & CECAttackEvent::MOD_RETORT) - p1 |= 0x0002;*/ - - if (!OnDamaged(skill)) - // PlayAction((int)PLAYER_ACTION_TYPE.ACT_WOUNDED); - - DamageTextManager.Instance.ShowDamageText( - transform.position, nDamage, Color.yellow, 1.0f); - /* if (dwModifier & CECAttackEvent::MOD_IMMUNE) - BubbleText(BUBBLE_IMMUNE, 0); - else if (dwModifier & CECAttackEvent::MOD_REBOUND) - BubbleText(BUBBLE_REBOUND, nDamage); - else if (dwModifier & CECAttackEvent::MOD_BEAT_BACK) - BubbleText(BUBBLE_BEAT_BACK, nDamage); - else - BubbleText(BUBBLE_DAMAGE, nDamage, p1);*/ - } - /* else if (dwModifier & CECAttackEvent::MOD_IMMUNE) - BubbleText(BUBBLE_IMMUNE, 0); - else if (dwModifier & CECAttackEvent::MOD_NULLITY) - BubbleText(BUBBLE_INVALIDHIT, 0); - else - BubbleText(BUBBLE_HITMISSED, 0);*/ - } + // Skin index + public static byte SKIN_BODY_INDEX = 0; + public static byte SKIN_UPPER_BODY_INDEX = 1; + public static byte SKIN_WRIST_INDEX = 2; + public static byte SKIN_LOWER_INDEX = 3; + public static byte SKIN_FOOT_INDEX = 4; + public static byte SKIN_HEAD_INDEX = 5; + public static byte SKIN_FASHION_UPPER_BODY_INDEX = 6; + public static byte SKIN_FASHION_WRIST_INDEX = 7; + public static byte SKIN_FASHION_LOWER_INDEX = 8; + public static byte SKIN_FASHION_FOOT_INDEX = 9; + public static byte NUM_SKIN_INDEX = 10; } - public bool PlaySkillCastAction(int idSkill) - { - string szAct = ""; - - int weapon_type = GetShowingWeaponType(); - - if (!_default_skill_actions.TryGetValue((uint)idSkill, out PLAYER_ACTION_INFO_CONFIG data) || data.action_prefix == null || data.action_prefix.Length == 0 || data.action_prefix[0] == 0) - { - // Check if it's a target item skill - if (ElementSkill.GetCommonCoolDown((uint)idSkill) > 1 << 4) - { - data = m_PlayerActions[(int)PLAYER_ACTION_TYPE.ACT_USING_TARGET_ITEM].data; - - if (data.action_prefix == null || data.action_prefix.Length == 0 || data.action_prefix[0] == 0) - return false; - } - else - return false; - } - - if (GetMoveEnv() == (int)MoveEnvironment.MOVEENV_GROUND) - { - szAct = EC_Utility.BuildActionName(data, weapon_type, "_Ò÷³ª_"); - BMLogger.LogError($"HoangDev: PlaySkillCastAction szAct={szAct} "); - } - else - { - /* if ((*//*UsingWing()*//*m_wingType == enumWingType.WINGTYPE_WING && IsFlying()) || (GetProfession() == PROF_ANGEL) || (GetProfession() == PROF_ARCHOR) || (GetProfession() == PROF_MONK) || (GetProfession() == PROF_GHOST)) - sprintf(szAct, "%s_¿ÕÖгá°ò_Ò÷³ª_%s", data->action_prefix, data->action_weapon_suffix[weapon_type].suffix); - else - sprintf(szAct, "%s_¿ÕÖзɽ£_Ò÷³ª_%s", data->action_prefix, data->action_weapon_suffix[weapon_type].suffix);*/ - } - - bool bHideFX = false; /*!CECOptimize::Instance().GetGFX().CanShowCast(GetCharacterID(), GetClassID());*/ - if (!PlaySkillCastActionWithName(idSkill, szAct, bHideFX)) - { - return false; - } - - ShowWeaponByConfig(data); - //UpdateWeaponHangerPosBySkillAction(idSkill);// ¸ù¾Ý¼¼Äܲ¥·ÅµÄ¶¯×÷£¬¸ü¸ÄÎäÆ÷Ðü¹ÒλÖã¨Ö»Äܼì²é²»ÅŶӶ¯×÷£© - return true; - } - public bool OnDamaged(int skill) - { - var atkMan = CECAttacksMan.Instance; - if (atkMan == null) - return false; - - string name1, name2; - - for (int i = 0; i < m_sciStateIDForStateAction.Length; i++) - { - /* if (atkMan.GetSkillStateActionName(skill, m_sciStateIDForStateAction[i], out name1, out name2)) - { - m_SkillIDForStateAction = skill; - return true; - }*/ - } - - return false; - } - public bool PlaySkillCastActionWithName(int idSkill, string szActName, bool bNoFX/* =false */) - { - return m_pActionController != null - && m_pActionController.PlaySkillCastActionWithName(idSkill, szActName, bNoFX); - } - - public bool PlaySkillAttackAction(int idSkill, int nAttackSpeed, ref int piAttackTime, int nSection = 0, CECAttackEvent attackEvent = null) - { - if (_pPlayerModel == null) - return false; - - string szAct = ""; - - int weapon_type = GetShowingWeaponType(); - - if (!_default_skill_actions.TryGetValue((uint)idSkill, out PLAYER_ACTION_INFO_CONFIG data) || - data.action_prefix == null || data.action_prefix.Length == 0 || data.action_prefix[0] == 0) - { - // Check if it's a target item skill / 检查是否为目标道具技能 - if (ElementSkill.GetCommonCoolDown((uint)idSkill) > 1 << 4) - { - PLAYER_ACTION_INFO_CONFIG? data2 = m_PlayerActions[(int)PLAYER_ACTION_TYPE.ACT_USING_TARGET_ITEM].data; - if (data2 == null || data2.Value.action_prefix == null || data2.Value.action_prefix.Length == 0 || data2.Value.action_prefix[0] == 0) - return false; - } - else - return false; - } - - int nTime1, nTime2; - bool bInfinite = false; - // CECModel pRightHandWeapon = GetRightHandWeapon(); // 获取右手武器 / Get right hand weapon - bool bHideFX = false; // !CECOptimize::Instance().GetGFX().CanShowAttack(GetCharacterID(), GetClassID()); - - var atkMan = CECAttacksMan.Instance; - - if (GetMoveEnv() == (int)MoveEnvironment.MOVEENV_GROUND) - { - szAct = EC_Utility.BuildActionName(data, weapon_type, "_施放起_"); - GetSkillSectionActionName(ref szAct, idSkill, nSection); - - if (!PlaySkillAttackActionWithName(idSkill, szAct, bHideFX, attackEvent)) - { - return false; - } - - // nTime1 = m_pPlayerModel->GetComActTimeSpanByName(szAct); // 获取动作时长 / Get action time span - // pAct = m_pPlayerModel->GetComActByName(szAct); - // if (pAct) bInfinite |= pAct->IsInfinite(); - nTime1 = 1000; // 临时值 / Temporary value - - szAct = EC_Utility.BuildActionName(data, weapon_type, "_施放落_"); - GetSkillSectionActionName(ref szAct, idSkill, nSection); - QueueSkillAttackActionWithName(idSkill, szAct, 0, bHideFX); - - // nTime2 = m_pPlayerModel->GetComActTimeSpanByName(szAct); - // pAct = m_pPlayerModel->GetComActByName(szAct); - // if (pAct) bInfinite |= pAct->IsInfinite(); - nTime2 = 1000; // 临时值 / Temporary value - } - else - { - // 空中动作 / Air action - string szActionMiddleName = null; - if ((m_wingType == enumWingType.WINGTYPE_WING && IsFlying()) || - (m_iProfession == PROFESSION.PROF_ANGEL) || - (m_iProfession == PROFESSION.PROF_ARCHOR) || - (m_iProfession == PROFESSION.PROF_MONK) || - (m_iProfession == PROFESSION.PROF_GHOST)) - { - szActionMiddleName = "_空中翅膀"; // Air with wings / 空中翅膀 - } - else - { - szActionMiddleName = "_空中飞剑"; // Air with sword / 空中飞剑 - } - - szActionMiddleName += "_施放起_"; - szAct = EC_Utility.BuildActionName(data, weapon_type, szActionMiddleName); - GetSkillSectionActionName(ref szAct, idSkill, nSection); - - if (!PlaySkillAttackActionWithName(idSkill, szAct, bHideFX, attackEvent)) - { - return false; - } - - // if (pRightHandWeapon && IsUsingMagicWeapon()) - // pRightHandWeapon->PlayActionByName(_GenWeaponActionName(szAct, m_iGender), 1.0f, true, 200, true, ACT_CASTSKILL, bHideFX); - - // nTime1 = m_pPlayerModel->GetComActTimeSpanByName(szAct); - // pAct = m_pPlayerModel->GetComActByName(szAct); - // if (pAct) bInfinite |= pAct->IsInfinite(); - nTime1 = 1000; // 临时值 / Temporary value - - szAct = $"{data.action_prefix}_{szActionMiddleName}_施法行_{data.action_weapon_suffix[weapon_type].suffix}"; - GetSkillSectionActionName(ref szAct, idSkill, nSection); - QueueSkillAttackActionWithName(idSkill, szAct, 0, bHideFX); - - // if (pRightHandWeapon && IsUsingMagicWeapon()) - // pRightHandWeapon->QueueAction(_GenWeaponActionName(szAct, m_iGender), 0, ACT_CASTSKILL, false, false, bHideFX); - - // nTime2 = m_pPlayerModel->GetComActTimeSpanByName(szAct); - // pAct = m_pPlayerModel->GetComActByName(szAct); - // if (pAct) bInfinite |= pAct->IsInfinite(); - nTime2 = 1000; // 临时值 / Temporary value - } - - // int nExecuteTime = GNET::ElementSkill::GetExecuteTime(idSkill, 0); // 获取技能执行时间 / Get skill execute time - int nExecuteTime = 2000; // 临时值 / Temporary value - - // 调整动画速度以匹配攻击速度 / Adjust animation speed to match attack speed - if (!bInfinite) - { - if (nExecuteTime > 0) - { - float vScale = (nTime1 + nTime2) / (float)nExecuteTime; - // m_pPlayerModel->SetPlaySpeed(vScale * 1.2f); - - // if (pRightHandWeapon && IsUsingMagicWeapon()) - // pRightHandWeapon->SetPlaySpeed(vScale * 1.2f); - } - - piAttackTime = nTime1 + nTime2; - } - else - { - // 动作循环,返回技能决定的执行时间 / Action loops, return skill-determined execute time - piAttackTime = nExecuteTime; - } - - ShowWeaponByConfig(data); - // UpdateWeaponHangerPosBySkillAction(idSkill); // 根据技能播放的动作,更改武器悬挂位置 / Update weapon hanger position based on skill action - return true; - } - - // 播放技能攻击动作(带名称)/ Play skill attack action with name - public bool PlaySkillAttackActionWithName(int idSkill, string szActName, bool bNoFX = false, CECAttackEvent attackEvent = null) - { - return m_pActionController != null - && m_pActionController.PlaySkillAttackActionWithName(idSkill, szActName, bNoFX, attackEvent != null ? new bool[] { attackEvent.m_bSignaled } : null, 0); - } - - // 队列播放技能攻击动作(带名称)/ Queue skill attack action with name - public bool QueueSkillAttackActionWithName(int idSkill, string szActName, int nTransTime = 200, bool bNoFX = false, bool bResetSpeed = false, bool bResetActFlag = false, bool[] pNewActFlag = null, uint dwNewFlagMode = 0) - { - return m_pActionController != null - && m_pActionController.QueueSkillAttackActionWithName(idSkill, szActName, nTransTime, bNoFX, bResetSpeed, bResetActFlag, pNewActFlag, dwNewFlagMode); - } - - // 获取技能段动作名称 / Get skill section action name - private void GetSkillSectionActionName(ref string szAct, int idSkill, int nSection) - { - if (nSection != 0) - { - var pAtkMan = CECAttacksMan.Instance; - if (pAtkMan != null && pAtkMan.GetSkillSectionActionSuffix(idSkill, nSection, out string suffix)) - { - szAct += "_" + suffix; - } - } - } - - // 判断是否在飞行 / Check if flying - public bool IsFlying() - { - // 临时实现 / Temporary implementation - return m_iMoveEnv == (int)MoveEnvironment.MOVEENV_AIR; - } - - bool GetSkillStateActionName(int skill, int state, string name1, string name2) - { - /* for (int i = 0; i < (int)m_SkillStateActionVec.size(); i++) - { - if (m_SkillStateActionVec[i].skill == skill && m_SkillStateActionVec[i].state == state) - { - name1 = m_SkillStateActionVec[i].beHitAction; - name2 = m_SkillStateActionVec[i].stayDownAction; - return true; - } - }*/ - return false; - } - public virtual bool IsFighting() { return m_bFight; } - public float GetGroundSpeed() - { - // return m_bWalkRun ? g_pGame.GetConfigs().GetHostRunSpeed() : m_ExtProps.mv.walk_speed; - return 5f; - return m_bWalkRun ? m_ExtProps.mv.run_speed : m_ExtProps.mv.walk_speed; - } - - // Get move environment - public int GetMoveEnv() - { - return m_iMoveEnv; - } - - public bool IsShapeChanged() - { - return m_iShape != 0; - } - - public int GetWeaponID() - { - return m_aEquips[(int)IndexOfIteminEquipmentInventory.EQUIPIVTR_WEAPON] & 0xffff; - } - - public bool IsAllResReady() - { - return (m_dwResFlags & (uint)PlayerResourcesReadyFlag.RESFG_ALL) == (uint)PlayerResourcesReadyFlag.RESFG_ALL; - } - // Get character ID - - // Play Gfx on Models - protected bool PlayGfx(string szPath, string szHook, float fScale /*1.0f*/, uint iShapeTypeMask /*(1<PlayGfx(szPath, szHook, fScale); - // bPlayed = true; - // } - // if(bSkipRecord) continue; - // A3DGFXEx* pGfx = m_pModels[i]->GetGfx(szPath, szHook); - // if (pGfx && pGfx->IsInfinite()){ - // GFXRECORD rec; - // rec.strPath = szPath; - // rec.strHook = szHook; - // rec.fScale = fScale; - // AString key = rec.strPath + rec.strHook; - // m_GfxRecords[key] = rec; - // bSkipRecord = true; - // } - // } - // } - PlayLevelUpGfx(szPath); - return false; - } - - private async void PlayLevelUpGfx(string path) - { - // Usage: Load the prefab asynchronously using AddressableManager - GameObject prefab = await AddressableManager.Instance.LoadPrefabAsync(path); - if(prefab != null) - { - if (_levelUpVfx != null) - { - if(_levelUpVfx.IsPlaying()) - return; - _levelUpVfx.Play(); - return; - } - - // Instantiate at player's current position and rotation - _levelUpVfx = Instantiate(prefab, transform).GetComponent(); - _levelUpVfx.Play(); - // vfx.transform.SetParent(transform); transform.position, prefab.transform.rotation - _levelUpVfx.transform.localPosition = Vector3.zero; - } - else - { - BMLogger.LogError($"Failed to load level up effect prefab at: {path}"); - } - } - - // Get booth state - public int GetBoothState() { return m_iBoothState; } - - // Check whether player has effect of specified type - public bool HasEffectType(int iEffType) - { - int i; - - switch (iEffType) - { - case Effect_type.EFF_FACEPILL: - { - elementdataman pDataMan = EC_Game.GetElementDataMan(); - - // Get item data type - for (i = 0; i < m_aCurEffects.Count; i++) - { - DATA_TYPE DataType = pDataMan.get_data_type((uint)m_aCurEffects[i], ID_SPACE.ID_SPACE_ESSENCE); - if (DataType == DATA_TYPE.DT_FACEPILL_ESSENCE) - return true; - } - - break; - } - } - - return false; - } - - public byte GetReincarnationCount() { return m_ReincarnationCount; } - - public string GetName() - { - return m_strName; - } -} - -public struct PlayActionEvent -{ - public string AnimationName; - - public PlayActionEvent(string animationName) - { - this.AnimationName = animationName; - } -} - -public class QueueActionEvent -{ - public string AnimationName; - public Action SetFlag; - public CECAttackEvent AttackEvent; - public bool IsHitAnim; - - public QueueActionEvent(string animationName, Action setFlag, bool isHitAnim, - CECAttackEvent attackEvent) - { - this.AnimationName = animationName; - SetFlag = setFlag; - IsHitAnim = isHitAnim; - AttackEvent = attackEvent; - } - - public void SetData(string animationName, Action setFlag, bool isHitAnim, - CECAttackEvent attackEvent) - { - this.AnimationName = animationName; - SetFlag = setFlag; - IsHitAnim = isHitAnim; - AttackEvent = attackEvent; - } -} - -[Serializable] -public struct INFO -{ - public int cid; // Character ID - public int crc_c; // customized data crc - public int crc_e; // Equipment data crc - - public INFO(int cid, int crc_c, int crc_) - { - this.cid = cid; - this.crc_c = crc_c; - this.crc_e = crc_; - } -} -public -enum enumWingType -{ - WINGTYPE_WING, // ·ÉÐÐÆ÷ÀàÐÍ£º³á°ò - WINGTYPE_FLYSWORD, // ·ÉÐÐÆ÷ÀàÐÍ£º·É½£ - WINGTYPE_DOUBLEWHEEL, // ·ÉÐÐÆ÷ÀàÐÍ£ºË«½Å·ÉÐÐÆ÷ -}; - -public enum PlayerResourcesReadyFlag - -{ - RESFG_SKELETON = 0x01, - RESFG_SKIN = 0x02, - RESFG_CUSTOM = 0x04, - RESFG_ASSEMBLED = 0x08, - RESFG_ALL = 0x0f, -}; - -public static class Duel_state // Duel state -{ - public const int DUEL_ST_NONE = 0, - DUEL_ST_PREPARE = 1, - DUEL_ST_INDUEL = 2, - DUEL_ST_STOPPING = 3; -} - -//// Move mode -public class Move_Mode -{ - public const int MOVE_STAND = 0, - MOVE_MOVE = 1, // Normal move, walk, run, swim or fly - MOVE_JUMP = 2, - MOVE_FREEFALL = 3, - MOVE_SLIDE = 4; -} - -public class EC_Player_Skin_Const -{ - // Skin index - public static byte SKIN_BODY_INDEX = 0; - public static byte SKIN_UPPER_BODY_INDEX = 1; - public static byte SKIN_WRIST_INDEX = 2; - public static byte SKIN_LOWER_INDEX = 3; - public static byte SKIN_FOOT_INDEX = 4; - public static byte SKIN_HEAD_INDEX = 5; - public static byte SKIN_FASHION_UPPER_BODY_INDEX = 6; - public static byte SKIN_FASHION_WRIST_INDEX = 7; - public static byte SKIN_FASHION_LOWER_INDEX = 8; - public static byte SKIN_FASHION_FOOT_INDEX = 9; - public static byte NUM_SKIN_INDEX = 10; } \ No newline at end of file diff --git a/Assets/PerfectWorld/Scripts/Move/EC_CDR.cs b/Assets/PerfectWorld/Scripts/Move/EC_CDR.cs index c5f4b24a68..615ed515e0 100644 --- a/Assets/PerfectWorld/Scripts/Move/EC_CDR.cs +++ b/Assets/PerfectWorld/Scripts/Move/EC_CDR.cs @@ -1,4 +1,5 @@ -using BrewMonster.Scripts.Ornament; +using BrewMonster.Scripts; +using BrewMonster.Scripts.Ornament; using BrewMonster.Scripts.Player; using BrewMonster.Scripts.World; using CSNetwork.GPDataType; @@ -6,7 +7,7 @@ using System; using UnityEngine; using WORD = System.UInt16; -namespace BrewMonster.Scripts +namespace BrewMonster { public static class EC_CDR { diff --git a/Assets/PerfectWorld/Scripts/NPC/CECNPC.cs b/Assets/PerfectWorld/Scripts/NPC/CECNPC.cs index 14ef9b13c6..26a2c38c43 100644 --- a/Assets/PerfectWorld/Scripts/NPC/CECNPC.cs +++ b/Assets/PerfectWorld/Scripts/NPC/CECNPC.cs @@ -244,7 +244,7 @@ public class CECNPC : CECObject // Attack target is host's pet else if (GPDataTypeHelper.ISNPCID(pCmd.target_id)) { - var pTarget = EC_ManMessageMono.Instance._CECNPCMan.GetNPC(pCmd.target_id); + var pTarget = EC_ManMessageMono.Instance.CECNPCMan.GetNPC(pCmd.target_id); if (pTarget != null && pTarget.GetMasterID() == pHost.GetCharacterID()) iDamage = pCmd.damage; } diff --git a/Assets/PerfectWorld/Scripts/Network/CSNetwork/GPDataType.cs b/Assets/PerfectWorld/Scripts/Network/CSNetwork/GPDataType.cs index b05abbd041..fb3dbb4018 100644 --- a/Assets/PerfectWorld/Scripts/Network/CSNetwork/GPDataType.cs +++ b/Assets/PerfectWorld/Scripts/Network/CSNetwork/GPDataType.cs @@ -919,7 +919,7 @@ namespace CSNetwork.GPDataType } // PVP mask [Flags] - public enum PVPMask + public enum PVPMask : byte { GP_PVPMASK_FORCE = 0x0001, // Ç¿Á¦¹¥»÷ GP_PVPMASK_NOMAFIA = 0x0002, diff --git a/Assets/PerfectWorld/Scripts/Network/EC_ManMessageMono.cs b/Assets/PerfectWorld/Scripts/Network/EC_ManMessageMono.cs index e419a72a88..82903588cb 100644 --- a/Assets/PerfectWorld/Scripts/Network/EC_ManMessageMono.cs +++ b/Assets/PerfectWorld/Scripts/Network/EC_ManMessageMono.cs @@ -28,16 +28,16 @@ namespace BrewMonster.Managers public EC_ManMatter EC_ManMatter; public EC_ManPlayer GetECManPlayer { get => EC_ManPlayer;} public EC_ManMatter GetECManMatter { get => EC_ManMatter;} - public CECNPCMan _CECNPCMan { get; private set; } + public CECNPCMan CECNPCMan { get; private set; } private void Awake() { instance = this; //TODO: Remove later EC_ManPlayer = new EC_ManPlayer(); - _CECNPCMan = new CECNPCMan(); + CECNPCMan = new CECNPCMan(); EC_ManMessage.RegisterHandler(EC_ManPlayer); - EC_ManMessage.RegisterHandler(_CECNPCMan); + EC_ManMessage.RegisterHandler(CECNPCMan); EC_ManMatter = new EC_ManMatter(); EC_ManMessage.RegisterHandler(EC_ManMatter); Debug.Log($"EC_ManMessage RegisterHandlerRegisterHandlerRegisterHandler"); @@ -52,7 +52,7 @@ namespace BrewMonster.Managers private void Update() { EC_ManMessage.Tick(); - _CECNPCMan.Tick(); + CECNPCMan.Tick(); } // Get object by specified ID @@ -63,7 +63,7 @@ namespace BrewMonster.Managers if (GPDataTypeHelper.ISNPCID((int)idObject)) { - if (!(pObject = _CECNPCMan.GetNPC((int)idObject))) + if (!(pObject = CECNPCMan.GetNPC((int)idObject))) return null; if ((iAliveFlag == 1 && (pObject as CECNPC).IsDead()) || diff --git a/Assets/PerfectWorld/Scripts/PlayerState/PlayerIdleState.cs b/Assets/PerfectWorld/Scripts/PlayerState/PlayerIdleState.cs index 7292af5ecc..4b8164c477 100644 --- a/Assets/PerfectWorld/Scripts/PlayerState/PlayerIdleState.cs +++ b/Assets/PerfectWorld/Scripts/PlayerState/PlayerIdleState.cs @@ -1,6 +1,5 @@ using BrewMonster.Scripts.Player; using UnityEngine; -using static CECPlayer; namespace BrewMonster { diff --git a/Assets/PerfectWorld/Scripts/PlayerState/PlayerMoveState.cs b/Assets/PerfectWorld/Scripts/PlayerState/PlayerMoveState.cs index 5db592893c..a2fb0ebd33 100644 --- a/Assets/PerfectWorld/Scripts/PlayerState/PlayerMoveState.cs +++ b/Assets/PerfectWorld/Scripts/PlayerState/PlayerMoveState.cs @@ -1,6 +1,5 @@ using BrewMonster.Scripts.Player; using UnityEngine; -using static CECPlayer; namespace BrewMonster { diff --git a/Assets/PerfectWorld/Scripts/Players/CECPlayerActionController.cs b/Assets/PerfectWorld/Scripts/Players/CECPlayerActionController.cs index 20a3c0c347..39d30cf490 100644 --- a/Assets/PerfectWorld/Scripts/Players/CECPlayerActionController.cs +++ b/Assets/PerfectWorld/Scripts/Players/CECPlayerActionController.cs @@ -2,189 +2,192 @@ using System; // CECPlayerActionController // 玩家动作控制器 / Player action controller -public class CECPlayerActionController +namespace BrewMonster { - // Action channels for split-body animation (kept for parity with C++) - // 动作通道(保留与C++一致的接口语义) / Channels kept to mirror C++ API - public const int ACT_CHANNEL_UPPERBODY = 0; - public const int ACT_CHANNEL_LOWERBODY = 1; - public const int ACT_CHANNEL_WOUND = 2; + public class CECPlayerActionController + { + // Action channels for split-body animation (kept for parity with C++) + // 动作通道(保留与C++一致的接口语义) / Channels kept to mirror C++ API + public const int ACT_CHANNEL_UPPERBODY = 0; + public const int ACT_CHANNEL_LOWERBODY = 1; + public const int ACT_CHANNEL_WOUND = 2; - private CECPlayer m_pPlayer; - private CECModel m_pPlayerModel; - private bool m_bSupportCastSkillWhenMove; - private CECPlayerActionPlayPolicy m_actionPlayPolicy; - private bool m_bSkillAttackActionPlayed; + private CECPlayer m_pPlayer; + private CECModel m_pPlayerModel; + private bool m_bSupportCastSkillWhenMove; + private CECPlayerActionPlayPolicy m_actionPlayPolicy; + private bool m_bSkillAttackActionPlayed; - public CECPlayerActionController() - { - m_pPlayer = null; - m_pPlayerModel = null; - m_bSupportCastSkillWhenMove = false; - m_actionPlayPolicy = null; - m_bSkillAttackActionPlayed = false; - } + public CECPlayerActionController() + { + m_pPlayer = null; + m_pPlayerModel = null; + m_bSupportCastSkillWhenMove = false; + m_actionPlayPolicy = null; + m_bSkillAttackActionPlayed = false; + } - ~CECPlayerActionController() - { - ReleaseActionPlayPolicy(); - } + ~CECPlayerActionController() + { + ReleaseActionPlayPolicy(); + } - public void Bind(CECPlayer player, CECModel playerModel) - { - if (player == null) - { - return; - } - if (player == m_pPlayer && playerModel == m_pPlayerModel) - { - return; - } + public void Bind(CECPlayer player, CECModel playerModel) + { + if (player == null) + { + return; + } + if (player == m_pPlayer && playerModel == m_pPlayerModel) + { + return; + } - ReleaseActionPlayPolicy(); - m_pPlayer = player; - m_pPlayerModel = playerModel; + ReleaseActionPlayPolicy(); + m_pPlayer = player; + m_pPlayerModel = playerModel; - // 是否支持移动中施法(当前C#端未实现,统一设为false) - // Support cast-while-move (not implemented in C# port -> false) - m_bSupportCastSkillWhenMove = false; + // 是否支持移动中施法(当前C#端未实现,统一设为false) + // Support cast-while-move (not implemented in C# port -> false) + m_bSupportCastSkillWhenMove = false; - if (!m_bSupportCastSkillWhenMove) - { - // 如果不支持,仍保留“受击”通道逻辑钩子(在C#里留空) - // If not supported, keep the hook for wound channel (no-op in C#) - } + if (!m_bSupportCastSkillWhenMove) + { + // 如果不支持,仍保留“受击”通道逻辑钩子(在C#里留空) + // If not supported, keep the hook for wound channel (no-op in C#) + } - InitializeActionPlayPolicy(); - } + InitializeActionPlayPolicy(); + } - public bool SupportCastSkillWhenMove() - { - return m_bSupportCastSkillWhenMove; - } + public bool SupportCastSkillWhenMove() + { + return m_bSupportCastSkillWhenMove; + } - public bool CanCombineWithMoveForSkill(int idSkill) - { - return m_actionPlayPolicy != null && m_actionPlayPolicy.CanCombineWithMoveForSkill(idSkill); - } + public bool CanCombineWithMoveForSkill(int idSkill) + { + return m_actionPlayPolicy != null && m_actionPlayPolicy.CanCombineWithMoveForSkill(idSkill); + } - private void InitializeActionPlayPolicy() - { - // 当前C#只提供默认策略(不拆分上下半身) - // Use default policy in this C# port - m_actionPlayPolicy = new CECPlayerActionPlayPolicy(m_pPlayer, m_pPlayerModel); - } + private void InitializeActionPlayPolicy() + { + // 当前C#只提供默认策略(不拆分上下半身) + // Use default policy in this C# port + m_actionPlayPolicy = new CECPlayerActionPlayPolicy(m_pPlayer, m_pPlayerModel); + } - private void ReleaseActionPlayPolicy() - { - m_actionPlayPolicy = null; - } + private void ReleaseActionPlayPolicy() + { + m_actionPlayPolicy = null; + } - // Build channels (C# no-op, return false to indicate not supported here) - // 构建动作通道(C#未实现,返回false) - private bool BuildChannelForCastSkillWhenMove() - { - return false; - } + // Build channels (C# no-op, return false to indicate not supported here) + // 构建动作通道(C#未实现,返回false) + private bool BuildChannelForCastSkillWhenMove() + { + return false; + } - public bool PlayNonSkillActionWithName(int iAction, string szActName, bool bRestart = true, int nTransTime = 200, bool bNoFx = false, bool[] pActFlag = null, uint dwFlagMode = 0) - { - return m_actionPlayPolicy != null - && m_actionPlayPolicy.PlayNonSkillActionWithName(iAction, szActName, bRestart, nTransTime, bNoFx, pActFlag, dwFlagMode); - } + public bool PlayNonSkillActionWithName(int iAction, string szActName, bool bRestart = true, int nTransTime = 200, bool bNoFx = false, bool[] pActFlag = null, uint dwFlagMode = 0) + { + return m_actionPlayPolicy != null + && m_actionPlayPolicy.PlayNonSkillActionWithName(iAction, szActName, bRestart, nTransTime, bNoFx, pActFlag, dwFlagMode); + } - public bool QueueNonSkillActionWithName(int iAction, string szActName, int nTransTime = 200, bool bForceStopPrevAct = false, bool bNoFx = false, bool bResetSpeed = false, bool bResetActFlag = false, bool[] pNewActFlag = null, uint dwNewFlagMode = 0) - { - return m_actionPlayPolicy != null - && m_actionPlayPolicy.QueueNonSkillActionWithName(iAction, szActName, nTransTime, bForceStopPrevAct, bNoFx, bResetSpeed, bResetActFlag, pNewActFlag, dwNewFlagMode); - } + public bool QueueNonSkillActionWithName(int iAction, string szActName, int nTransTime = 200, bool bForceStopPrevAct = false, bool bNoFx = false, bool bResetSpeed = false, bool bResetActFlag = false, bool[] pNewActFlag = null, uint dwNewFlagMode = 0) + { + return m_actionPlayPolicy != null + && m_actionPlayPolicy.QueueNonSkillActionWithName(iAction, szActName, nTransTime, bForceStopPrevAct, bNoFx, bResetSpeed, bResetActFlag, pNewActFlag, dwNewFlagMode); + } - public bool PlaySkillCastActionWithName(int idSkill, string szActName, bool bNoFX = false) - { - if (m_actionPlayPolicy != null - && m_actionPlayPolicy.PlaySkillCastActionWithName(idSkill, szActName, bNoFX)) - { - m_bSkillAttackActionPlayed = false; - return true; - } - return false; - } + public bool PlaySkillCastActionWithName(int idSkill, string szActName, bool bNoFX = false) + { + if (m_actionPlayPolicy != null + && m_actionPlayPolicy.PlaySkillCastActionWithName(idSkill, szActName, bNoFX)) + { + m_bSkillAttackActionPlayed = false; + return true; + } + return false; + } - public bool PlaySkillAttackActionWithName(int idSkill, string szActName, bool bNoFX = false, bool[] pActFlag = null, uint dwFlagMode = 0) - { - if (m_actionPlayPolicy != null - && m_actionPlayPolicy.PlaySkillAttackActionWithName(idSkill, szActName, bNoFX, pActFlag, dwFlagMode)) - { - m_bSkillAttackActionPlayed = true; - return true; - } - return false; - } + public bool PlaySkillAttackActionWithName(int idSkill, string szActName, bool bNoFX = false, bool[] pActFlag = null, uint dwFlagMode = 0) + { + if (m_actionPlayPolicy != null + && m_actionPlayPolicy.PlaySkillAttackActionWithName(idSkill, szActName, bNoFX, pActFlag, dwFlagMode)) + { + m_bSkillAttackActionPlayed = true; + return true; + } + return false; + } - public bool QueueSkillAttackActionWithName(int idSkill, string szActName, int nTransTime = 200, bool bNoFX = false, bool bResetSpeed = false, bool bResetActFlag = false, bool[] pNewActFlag = null, uint dwNewFlagMode = 0) - { - return m_actionPlayPolicy != null - && m_actionPlayPolicy.QueueSkillAttackActionWithName(idSkill, szActName, nTransTime, bNoFX, bResetSpeed, bResetActFlag, pNewActFlag, dwNewFlagMode); - } + public bool QueueSkillAttackActionWithName(int idSkill, string szActName, int nTransTime = 200, bool bNoFX = false, bool bResetSpeed = false, bool bResetActFlag = false, bool[] pNewActFlag = null, uint dwNewFlagMode = 0) + { + return m_actionPlayPolicy != null + && m_actionPlayPolicy.QueueSkillAttackActionWithName(idSkill, szActName, nTransTime, bNoFX, bResetSpeed, bResetActFlag, pNewActFlag, dwNewFlagMode); + } - public bool PlayWoundActionWithName(string szActName) - { - return m_actionPlayPolicy != null - && m_actionPlayPolicy.PlayWoundActionWithName(szActName); - } + public bool PlayWoundActionWithName(string szActName) + { + return m_actionPlayPolicy != null + && m_actionPlayPolicy.PlayWoundActionWithName(szActName); + } - public void ClearComActFlagAllRankNodes(bool bSignalCurrent) - { - if (m_actionPlayPolicy != null) - { - m_actionPlayPolicy.ClearComActFlagAllRankNodes(bSignalCurrent); - } - } + public void ClearComActFlagAllRankNodes(bool bSignalCurrent) + { + if (m_actionPlayPolicy != null) + { + m_actionPlayPolicy.ClearComActFlagAllRankNodes(bSignalCurrent); + } + } - public void StopChannelAction() - { - if (m_actionPlayPolicy != null) - { - m_actionPlayPolicy.StopChannelAction(); - } - } + public void StopChannelAction() + { + if (m_actionPlayPolicy != null) + { + m_actionPlayPolicy.StopChannelAction(); + } + } - public void StopSkillCastAction() - { - if (m_actionPlayPolicy != null && m_actionPlayPolicy.IsPlayingCastingSkillAction() && !m_bSkillAttackActionPlayed) - { - m_actionPlayPolicy.StopSkillAction(); - // LOG kept minimal in C# - } - } + public void StopSkillCastAction() + { + if (m_actionPlayPolicy != null && m_actionPlayPolicy.IsPlayingCastingSkillAction() && !m_bSkillAttackActionPlayed) + { + m_actionPlayPolicy.StopSkillAction(); + // LOG kept minimal in C# + } + } - public void StopSkillAttackAction() - { - if (m_actionPlayPolicy != null && m_actionPlayPolicy.IsPlayingCastingSkillAction() && m_bSkillAttackActionPlayed) - { - m_actionPlayPolicy.StopSkillAction(); - // LOG kept minimal in C# - } - } + public void StopSkillAttackAction() + { + if (m_actionPlayPolicy != null && m_actionPlayPolicy.IsPlayingCastingSkillAction() && m_bSkillAttackActionPlayed) + { + m_actionPlayPolicy.StopSkillAction(); + // LOG kept minimal in C# + } + } - public bool IsPlayingAction(int iAction) - { - return m_actionPlayPolicy != null && m_actionPlayPolicy.IsPlayingAction(iAction); - } + public bool IsPlayingAction(int iAction) + { + return m_actionPlayPolicy != null && m_actionPlayPolicy.IsPlayingAction(iAction); + } - public bool IsPlayingCastingSkillAction() - { - return m_actionPlayPolicy != null && m_actionPlayPolicy.IsPlayingCastingSkillAction(); - } + public bool IsPlayingCastingSkillAction() + { + return m_actionPlayPolicy != null && m_actionPlayPolicy.IsPlayingCastingSkillAction(); + } - public bool IsPlayingMoveAction() - { - return m_actionPlayPolicy != null && m_actionPlayPolicy.IsPlayingMoveAction(); - } + public bool IsPlayingMoveAction() + { + return m_actionPlayPolicy != null && m_actionPlayPolicy.IsPlayingMoveAction(); + } - public int GetLowerBodyAction() - { - return m_actionPlayPolicy != null ? m_actionPlayPolicy.GetLowerBodyAction() : -1; - } -} + public int GetLowerBodyAction() + { + return m_actionPlayPolicy != null ? m_actionPlayPolicy.GetLowerBodyAction() : -1; + } + } +} \ No newline at end of file diff --git a/Assets/PerfectWorld/Scripts/Players/CECPlayerActionPlayPolicy.cs b/Assets/PerfectWorld/Scripts/Players/CECPlayerActionPlayPolicy.cs index e76b3fa427..e3b396c002 100644 --- a/Assets/PerfectWorld/Scripts/Players/CECPlayerActionPlayPolicy.cs +++ b/Assets/PerfectWorld/Scripts/Players/CECPlayerActionPlayPolicy.cs @@ -1,340 +1,343 @@ using System; -/*public class CECPlayerActionController +namespace BrewMonster { - // Action channels for split-body animation (kept for parity with C++) - // 动作通道(保留与C++一致的接口语义) / Channels kept to mirror C++ API - public const int ACT_CHANNEL_UPPERBODY = 0; - public const int ACT_CHANNEL_LOWERBODY = 1; - public const int ACT_CHANNEL_WOUND = 2; - - private CECPlayer m_pPlayer; - private CECModel m_pPlayerModel; - private bool m_bSupportCastSkillWhenMove; - private CECPlayerActionPlayPolicy m_actionPlayPolicy; - private bool m_bSkillAttackActionPlayed; - - public CECPlayerActionController() + /*public class CECPlayerActionController { - m_pPlayer = null; - m_pPlayerModel = null; - m_bSupportCastSkillWhenMove = false; - m_actionPlayPolicy = null; - m_bSkillAttackActionPlayed = false; - } + // Action channels for split-body animation (kept for parity with C++) + // 动作通道(保留与C++一致的接口语义) / Channels kept to mirror C++ API + public const int ACT_CHANNEL_UPPERBODY = 0; + public const int ACT_CHANNEL_LOWERBODY = 1; + public const int ACT_CHANNEL_WOUND = 2; - ~CECPlayerActionController() - { - ReleaseActionPlayPolicy(); - } + private CECPlayer m_pPlayer; + private CECModel m_pPlayerModel; + private bool m_bSupportCastSkillWhenMove; + private CECPlayerActionPlayPolicy m_actionPlayPolicy; + private bool m_bSkillAttackActionPlayed; - public void Bind(CECPlayer player, CECModel playerModel) - { - if (player == null) - { - return; - } - if (player == m_pPlayer && playerModel == m_pPlayerModel) - { - return; - } - - ReleaseActionPlayPolicy(); - m_pPlayer = player; - m_pPlayerModel = playerModel; - - // 是否支持移动中施法(当前C#端未实现,统一设为false) - // Support cast-while-move (not implemented in C# port -> false) - m_bSupportCastSkillWhenMove = false; - - if (!m_bSupportCastSkillWhenMove) - { - // 如果不支持,仍保留“受击”通道逻辑钩子(在C#里留空) - // If not supported, keep the hook for wound channel (no-op in C#) - } - - InitializeActionPlayPolicy(); - } - - public bool SupportCastSkillWhenMove() - { - return m_bSupportCastSkillWhenMove; - } - - public bool CanCombineWithMoveForSkill(int idSkill) - { - return m_actionPlayPolicy != null && m_actionPlayPolicy.CanCombineWithMoveForSkill(idSkill); - } - - private void InitializeActionPlayPolicy() - { - // 当前C#只提供默认策略(不拆分上下半身) - // Use default policy in this C# port - m_actionPlayPolicy = new CECPlayerActionPlayPolicy(m_pPlayer, m_pPlayerModel); - } - - private void ReleaseActionPlayPolicy() - { - m_actionPlayPolicy = null; - } - - // Build channels (C# no-op, return false to indicate not supported here) - // 构建动作通道(C#未实现,返回false) - private bool BuildChannelForCastSkillWhenMove() - { - return false; - } - - public bool PlayNonSkillActionWithName(int iAction, string szActName, bool bRestart = true, int nTransTime = 200, bool bNoFx = false, bool[] pActFlag = null, uint dwFlagMode = 0) - { - return m_actionPlayPolicy != null - && m_actionPlayPolicy.PlayNonSkillActionWithName(iAction, szActName, bRestart, nTransTime, bNoFx, pActFlag, dwFlagMode); - } - - public bool QueueNonSkillActionWithName(int iAction, string szActName, int nTransTime = 200, bool bForceStopPrevAct = false, bool bNoFx = false, bool bResetSpeed = false, bool bResetActFlag = false, bool[] pNewActFlag = null, uint dwNewFlagMode = 0) - { - return m_actionPlayPolicy != null - && m_actionPlayPolicy.QueueNonSkillActionWithName(iAction, szActName, nTransTime, bForceStopPrevAct, bNoFx, bResetSpeed, bResetActFlag, pNewActFlag, dwNewFlagMode); - } - - public bool PlaySkillCastActionWithName(int idSkill, string szActName, bool bNoFX = false) - { - if (m_actionPlayPolicy != null - && m_actionPlayPolicy.PlaySkillCastActionWithName(idSkill, szActName, bNoFX)) + public CECPlayerActionController() { + m_pPlayer = null; + m_pPlayerModel = null; + m_bSupportCastSkillWhenMove = false; + m_actionPlayPolicy = null; m_bSkillAttackActionPlayed = false; + } + + ~CECPlayerActionController() + { + ReleaseActionPlayPolicy(); + } + + public void Bind(CECPlayer player, CECModel playerModel) + { + if (player == null) + { + return; + } + if (player == m_pPlayer && playerModel == m_pPlayerModel) + { + return; + } + + ReleaseActionPlayPolicy(); + m_pPlayer = player; + m_pPlayerModel = playerModel; + + // 是否支持移动中施法(当前C#端未实现,统一设为false) + // Support cast-while-move (not implemented in C# port -> false) + m_bSupportCastSkillWhenMove = false; + + if (!m_bSupportCastSkillWhenMove) + { + // 如果不支持,仍保留“受击”通道逻辑钩子(在C#里留空) + // If not supported, keep the hook for wound channel (no-op in C#) + } + + InitializeActionPlayPolicy(); + } + + public bool SupportCastSkillWhenMove() + { + return m_bSupportCastSkillWhenMove; + } + + public bool CanCombineWithMoveForSkill(int idSkill) + { + return m_actionPlayPolicy != null && m_actionPlayPolicy.CanCombineWithMoveForSkill(idSkill); + } + + private void InitializeActionPlayPolicy() + { + // 当前C#只提供默认策略(不拆分上下半身) + // Use default policy in this C# port + m_actionPlayPolicy = new CECPlayerActionPlayPolicy(m_pPlayer, m_pPlayerModel); + } + + private void ReleaseActionPlayPolicy() + { + m_actionPlayPolicy = null; + } + + // Build channels (C# no-op, return false to indicate not supported here) + // 构建动作通道(C#未实现,返回false) + private bool BuildChannelForCastSkillWhenMove() + { + return false; + } + + public bool PlayNonSkillActionWithName(int iAction, string szActName, bool bRestart = true, int nTransTime = 200, bool bNoFx = false, bool[] pActFlag = null, uint dwFlagMode = 0) + { + return m_actionPlayPolicy != null + && m_actionPlayPolicy.PlayNonSkillActionWithName(iAction, szActName, bRestart, nTransTime, bNoFx, pActFlag, dwFlagMode); + } + + public bool QueueNonSkillActionWithName(int iAction, string szActName, int nTransTime = 200, bool bForceStopPrevAct = false, bool bNoFx = false, bool bResetSpeed = false, bool bResetActFlag = false, bool[] pNewActFlag = null, uint dwNewFlagMode = 0) + { + return m_actionPlayPolicy != null + && m_actionPlayPolicy.QueueNonSkillActionWithName(iAction, szActName, nTransTime, bForceStopPrevAct, bNoFx, bResetSpeed, bResetActFlag, pNewActFlag, dwNewFlagMode); + } + + public bool PlaySkillCastActionWithName(int idSkill, string szActName, bool bNoFX = false) + { + if (m_actionPlayPolicy != null + && m_actionPlayPolicy.PlaySkillCastActionWithName(idSkill, szActName, bNoFX)) + { + m_bSkillAttackActionPlayed = false; + return true; + } + return false; + } + + public bool PlaySkillAttackActionWithName(int idSkill, string szActName, bool bNoFX = false, bool[] pActFlag = null, uint dwFlagMode = 0) + { + if (m_actionPlayPolicy != null + && m_actionPlayPolicy.PlaySkillAttackActionWithName(idSkill, szActName, bNoFX, pActFlag, dwFlagMode)) + { + m_bSkillAttackActionPlayed = true; + return true; + } + return false; + } + + public bool QueueSkillAttackActionWithName(int idSkill, string szActName, int nTransTime = 200, bool bNoFX = false, bool bResetSpeed = false, bool bResetActFlag = false, bool[] pNewActFlag = null, uint dwNewFlagMode = 0) + { + return m_actionPlayPolicy != null + && m_actionPlayPolicy.QueueSkillAttackActionWithName(idSkill, szActName, nTransTime, bNoFX, bResetSpeed, bResetActFlag, pNewActFlag, dwNewFlagMode); + } + + public bool PlayWoundActionWithName(string szActName) + { + return m_actionPlayPolicy != null + && m_actionPlayPolicy.PlayWoundActionWithName(szActName); + } + + public void ClearComActFlagAllRankNodes(bool bSignalCurrent) + { + if (m_actionPlayPolicy != null) + { + m_actionPlayPolicy.ClearComActFlagAllRankNodes(bSignalCurrent); + } + } + + public void StopChannelAction() + { + if (m_actionPlayPolicy != null) + { + m_actionPlayPolicy.StopChannelAction(); + } + } + + public void StopSkillCastAction() + { + if (m_actionPlayPolicy != null && m_actionPlayPolicy.IsPlayingCastingSkillAction() && !m_bSkillAttackActionPlayed) + { + m_actionPlayPolicy.StopSkillAction(); + // LOG kept minimal in C# + } + } + + public void StopSkillAttackAction() + { + if (m_actionPlayPolicy != null && m_actionPlayPolicy.IsPlayingCastingSkillAction() && m_bSkillAttackActionPlayed) + { + m_actionPlayPolicy.StopSkillAction(); + // LOG kept minimal in C# + } + } + + public bool IsPlayingAction(int iAction) + { + return m_actionPlayPolicy != null && m_actionPlayPolicy.IsPlayingAction(iAction); + } + + public bool IsPlayingCastingSkillAction() + { + return m_actionPlayPolicy != null && m_actionPlayPolicy.IsPlayingCastingSkillAction(); + } + + public bool IsPlayingMoveAction() + { + return m_actionPlayPolicy != null && m_actionPlayPolicy.IsPlayingMoveAction(); + } + + public int GetLowerBodyAction() + { + return m_actionPlayPolicy != null ? m_actionPlayPolicy.GetLowerBodyAction() : -1; + } + }*/ + public class CECPlayerActionPlayPolicy + { + protected readonly CECPlayer m_pPlayer; + protected readonly CECModel m_pPlayerModel; + + // 简单状态记录以支持“是否在施法中”的判断 + // Simple state to support IsPlayingCastingSkillAction + private bool m_isCastingSkill; + + public CECPlayerActionPlayPolicy(CECPlayer pPlayer, CECModel pPlayerModel) + { + m_pPlayer = pPlayer; + m_pPlayerModel = pPlayerModel; + m_isCastingSkill = false; + } + + public virtual bool CanCombineWithMoveForSkill(int idSkill) + { + return false; + } + + public CECPlayer GetPlayer() + { + return m_pPlayer; + } + + public CECModel GetModel() + { + return m_pPlayerModel; + } + + public bool IsMoving() + { + return IsPlayingMoveAction() && (m_pPlayer != null && m_pPlayer.IsWorkMoveRunning()); + } + + public static bool IsMoveAction(int action) + { + return action == (int)PLAYER_ACTION_TYPE.ACT_RUN + || action == (int)PLAYER_ACTION_TYPE.ACT_WALK + || action == (int)PLAYER_ACTION_TYPE.ACT_FLY + || action == (int)PLAYER_ACTION_TYPE.ACT_FLY_SWORD + || action == (int)PLAYER_ACTION_TYPE.ACT_SWIM + || action == (int)PLAYER_ACTION_TYPE.ACT_SWIM_FOR_MOVESKILL; + } + + public bool IsPlayingCastingSkillAction() + { + return m_isCastingSkill; + } + + // Non-skill action + public virtual bool PlayNonSkillActionWithName(int iAction, string szActName, bool bRestart, int nTransTime, bool bNoFx, bool[] pActFlag, uint dwFlagMode) + { + if (m_pPlayer == null || string.IsNullOrEmpty(szActName)) + { + return false; + } + EventBus.PublishChannel(m_pPlayer.GetPlayerInfo().cid, new PlayActionEvent(szActName)); return true; } - return false; - } - public bool PlaySkillAttackActionWithName(int idSkill, string szActName, bool bNoFX = false, bool[] pActFlag = null, uint dwFlagMode = 0) - { - if (m_actionPlayPolicy != null - && m_actionPlayPolicy.PlaySkillAttackActionWithName(idSkill, szActName, bNoFX, pActFlag, dwFlagMode)) + public virtual bool QueueNonSkillActionWithName(int iAction, string szActName, int nTransTime, bool bForceStopPrevAct, bool bNoFx, bool bResetSpeed, bool bResetActFlag, bool[] pNewActFlag, uint dwNewFlagMode) { - m_bSkillAttackActionPlayed = true; + // 当前实现:直接播放(队列行为由上层系统处理) + // Current: just play, queue behavior handled by upper systems + return PlayNonSkillActionWithName(iAction, szActName, false, nTransTime, bNoFx, pNewActFlag, dwNewFlagMode); + } + + // Skill actions + public virtual bool PlaySkillCastActionWithName(int idSkill, string szActName, bool bNoFX) + { + if (m_pPlayer == null || string.IsNullOrEmpty(szActName)) + { + return false; + } + if (IsMoving()) + { + return false; + } + m_isCastingSkill = true; + EventBus.PublishChannel(m_pPlayer.GetPlayerInfo().cid, new PlayActionEvent(szActName)); return true; } - return false; - } - public bool QueueSkillAttackActionWithName(int idSkill, string szActName, int nTransTime = 200, bool bNoFX = false, bool bResetSpeed = false, bool bResetActFlag = false, bool[] pNewActFlag = null, uint dwNewFlagMode = 0) - { - return m_actionPlayPolicy != null - && m_actionPlayPolicy.QueueSkillAttackActionWithName(idSkill, szActName, nTransTime, bNoFX, bResetSpeed, bResetActFlag, pNewActFlag, dwNewFlagMode); - } - - public bool PlayWoundActionWithName(string szActName) - { - return m_actionPlayPolicy != null - && m_actionPlayPolicy.PlayWoundActionWithName(szActName); - } - - public void ClearComActFlagAllRankNodes(bool bSignalCurrent) - { - if (m_actionPlayPolicy != null) + public virtual bool PlaySkillAttackActionWithName(int idSkill, string szActName, bool bNoFX, bool[] pActFlag, uint dwFlagMode) { - m_actionPlayPolicy.ClearComActFlagAllRankNodes(bSignalCurrent); + if (m_pPlayer == null || string.IsNullOrEmpty(szActName)) + { + return false; + } + if (IsMoving()) + { + return false; + } + m_isCastingSkill = true; + EventBus.PublishChannel(m_pPlayer.GetPlayerInfo().cid, new PlayActionEvent(szActName)); + return true; + } + + public virtual bool QueueSkillAttackActionWithName(int idSkill, string szActName, int nTransTime, bool bNoFX, bool bResetSpeed, bool bResetActFlag, bool[] pNewActFlag, uint dwNewFlagMode) + { + return PlaySkillAttackActionWithName(idSkill, szActName, bNoFX, pNewActFlag, dwNewFlagMode); + } + + public virtual bool PlayWoundActionWithName(string szActName) + { + if (m_pPlayer == null || string.IsNullOrEmpty(szActName)) + { + return false; + } + EventBus.PublishChannel(m_pPlayer.GetPlayerInfo().cid, new PlayActionEvent(szActName)); + return true; + } + + public virtual void ClearComActFlagAllRankNodes(bool bSignalCurrent) + { + if (m_pPlayer != null) + { + EventBus.PublishChannel(m_pPlayer.GetPlayerInfo().cid, new ClearComActFlagAllRankNodesEvent(bSignalCurrent)); + } + } + + public virtual void StopChannelAction() + { + // 在C#端没有底层通道概念,做成清旗标即可 + // No channel concept here; clear act flags as a substitute + ClearComActFlagAllRankNodes(true); + } + + public virtual void StopSkillAction() + { + m_isCastingSkill = false; + StopChannelAction(); + } + + public virtual bool IsPlayingAction(int iAction) + { + // C#动画系统由上层驱动,这里不跟踪具体动作,统一返回false + // Not tracked here; return false by default + return false; + } + + public virtual bool IsPlayingMoveAction() + { + return false; + } + + public virtual int GetLowerBodyAction() + { + return -1; } } - - public void StopChannelAction() - { - if (m_actionPlayPolicy != null) - { - m_actionPlayPolicy.StopChannelAction(); - } - } - - public void StopSkillCastAction() - { - if (m_actionPlayPolicy != null && m_actionPlayPolicy.IsPlayingCastingSkillAction() && !m_bSkillAttackActionPlayed) - { - m_actionPlayPolicy.StopSkillAction(); - // LOG kept minimal in C# - } - } - - public void StopSkillAttackAction() - { - if (m_actionPlayPolicy != null && m_actionPlayPolicy.IsPlayingCastingSkillAction() && m_bSkillAttackActionPlayed) - { - m_actionPlayPolicy.StopSkillAction(); - // LOG kept minimal in C# - } - } - - public bool IsPlayingAction(int iAction) - { - return m_actionPlayPolicy != null && m_actionPlayPolicy.IsPlayingAction(iAction); - } - - public bool IsPlayingCastingSkillAction() - { - return m_actionPlayPolicy != null && m_actionPlayPolicy.IsPlayingCastingSkillAction(); - } - - public bool IsPlayingMoveAction() - { - return m_actionPlayPolicy != null && m_actionPlayPolicy.IsPlayingMoveAction(); - } - - public int GetLowerBodyAction() - { - return m_actionPlayPolicy != null ? m_actionPlayPolicy.GetLowerBodyAction() : -1; - } -}*/ -public class CECPlayerActionPlayPolicy -{ - protected readonly CECPlayer m_pPlayer; - protected readonly CECModel m_pPlayerModel; - - // 简单状态记录以支持“是否在施法中”的判断 - // Simple state to support IsPlayingCastingSkillAction - private bool m_isCastingSkill; - - public CECPlayerActionPlayPolicy(CECPlayer pPlayer, CECModel pPlayerModel) - { - m_pPlayer = pPlayer; - m_pPlayerModel = pPlayerModel; - m_isCastingSkill = false; - } - - public virtual bool CanCombineWithMoveForSkill(int idSkill) - { - return false; - } - - public CECPlayer GetPlayer() - { - return m_pPlayer; - } - - public CECModel GetModel() - { - return m_pPlayerModel; - } - - public bool IsMoving() - { - return IsPlayingMoveAction() && (m_pPlayer != null && m_pPlayer.IsWorkMoveRunning()); - } - - public static bool IsMoveAction(int action) - { - return action == (int)CECPlayer.PLAYER_ACTION_TYPE.ACT_RUN - || action == (int)CECPlayer.PLAYER_ACTION_TYPE.ACT_WALK - || action == (int)CECPlayer.PLAYER_ACTION_TYPE.ACT_FLY - || action == (int)CECPlayer.PLAYER_ACTION_TYPE.ACT_FLY_SWORD - || action == (int)CECPlayer.PLAYER_ACTION_TYPE.ACT_SWIM - || action == (int)CECPlayer.PLAYER_ACTION_TYPE.ACT_SWIM_FOR_MOVESKILL; - } - - public bool IsPlayingCastingSkillAction() - { - return m_isCastingSkill; - } - - // Non-skill action - public virtual bool PlayNonSkillActionWithName(int iAction, string szActName, bool bRestart, int nTransTime, bool bNoFx, bool[] pActFlag, uint dwFlagMode) - { - if (m_pPlayer == null || string.IsNullOrEmpty(szActName)) - { - return false; - } - EventBus.PublishChannel(m_pPlayer.GetPlayerInfo().cid, new PlayActionEvent(szActName)); - return true; - } - - public virtual bool QueueNonSkillActionWithName(int iAction, string szActName, int nTransTime, bool bForceStopPrevAct, bool bNoFx, bool bResetSpeed, bool bResetActFlag, bool[] pNewActFlag, uint dwNewFlagMode) - { - // 当前实现:直接播放(队列行为由上层系统处理) - // Current: just play, queue behavior handled by upper systems - return PlayNonSkillActionWithName(iAction, szActName, false, nTransTime, bNoFx, pNewActFlag, dwNewFlagMode); - } - - // Skill actions - public virtual bool PlaySkillCastActionWithName(int idSkill, string szActName, bool bNoFX) - { - if (m_pPlayer == null || string.IsNullOrEmpty(szActName)) - { - return false; - } - if (IsMoving()) - { - return false; - } - m_isCastingSkill = true; - EventBus.PublishChannel(m_pPlayer.GetPlayerInfo().cid, new PlayActionEvent(szActName)); - return true; - } - - public virtual bool PlaySkillAttackActionWithName(int idSkill, string szActName, bool bNoFX, bool[] pActFlag, uint dwFlagMode) - { - if (m_pPlayer == null || string.IsNullOrEmpty(szActName)) - { - return false; - } - if (IsMoving()) - { - return false; - } - m_isCastingSkill = true; - EventBus.PublishChannel(m_pPlayer.GetPlayerInfo().cid, new PlayActionEvent(szActName)); - return true; - } - - public virtual bool QueueSkillAttackActionWithName(int idSkill, string szActName, int nTransTime, bool bNoFX, bool bResetSpeed, bool bResetActFlag, bool[] pNewActFlag, uint dwNewFlagMode) - { - return PlaySkillAttackActionWithName(idSkill, szActName, bNoFX, pNewActFlag, dwNewFlagMode); - } - - public virtual bool PlayWoundActionWithName(string szActName) - { - if (m_pPlayer == null || string.IsNullOrEmpty(szActName)) - { - return false; - } - EventBus.PublishChannel(m_pPlayer.GetPlayerInfo().cid, new PlayActionEvent(szActName)); - return true; - } - - public virtual void ClearComActFlagAllRankNodes(bool bSignalCurrent) - { - if (m_pPlayer != null) - { - EventBus.PublishChannel(m_pPlayer.GetPlayerInfo().cid, new CECPlayer.ClearComActFlagAllRankNodesEvent(bSignalCurrent)); - } - } - - public virtual void StopChannelAction() - { - // 在C#端没有底层通道概念,做成清旗标即可 - // No channel concept here; clear act flags as a substitute - ClearComActFlagAllRankNodes(true); - } - - public virtual void StopSkillAction() - { - m_isCastingSkill = false; - StopChannelAction(); - } - - public virtual bool IsPlayingAction(int iAction) - { - // C#动画系统由上层驱动,这里不跟踪具体动作,统一返回false - // Not tracked here; return false by default - return false; - } - - public virtual bool IsPlayingMoveAction() - { - return false; - } - - public virtual int GetLowerBodyAction() - { - return -1; - } -} +} \ No newline at end of file diff --git a/Assets/PerfectWorld/Scripts/Players/EC_ElsePlayer.cs b/Assets/PerfectWorld/Scripts/Players/EC_ElsePlayer.cs index 40b834e0d1..1d226de8a7 100644 --- a/Assets/PerfectWorld/Scripts/Players/EC_ElsePlayer.cs +++ b/Assets/PerfectWorld/Scripts/Players/EC_ElsePlayer.cs @@ -13,9 +13,8 @@ using System.Data; using System.Text; using BrewMonster.PerfectWorld.Scripts.Vfx; using UnityEngine; -using static CECNPC; -namespace PerfectWorld.Scripts.Player +namespace BrewMonster { public class EC_ElsePlayer : CECPlayer { @@ -624,26 +623,6 @@ namespace PerfectWorld.Scripts.Player 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; diff --git a/Assets/PerfectWorld/Scripts/Skills/CECCastSkillWhenMove.cs b/Assets/PerfectWorld/Scripts/Skills/CECCastSkillWhenMove.cs new file mode 100644 index 0000000000..7b369c85df --- /dev/null +++ b/Assets/PerfectWorld/Scripts/Skills/CECCastSkillWhenMove.cs @@ -0,0 +1,533 @@ +// Filename : CECCastSkillWhenMove.cs +// Creator : Xu Wenbin +// Date : 2014/8/1 +// Converted to C# from C++ by AI Assistant + +using BrewMonster.Scripts.Skills; +using System.Linq; + +namespace BrewMonster +{ + // Constants from EC_RoleTypes.h + public static class RoleTypes + { + // 职业 // Profession + public const int PROF_WARRIOR = 0; // 武侠 // Warrior + public const int PROF_MAGE = 1; // 法师 // Mage + public const int PROF_MONK = 2; // 巫师 // Monk + public const int PROF_HAG = 3; // 妖精 // Hag + public const int PROF_ORC = 4; // 妖兽 // Orc + public const int PROF_GHOST = 5; // 刺客 // Ghost + public const int PROF_ARCHOR = 6; // 羽芒 // Archer + public const int PROF_ANGEL = 7; // 羽灵 // Angel + public const int PROF_JIANLING = 8; // 剑灵 // Jianling + public const int PROF_MEILING = 9; // 魅灵 // Meiling + public const int PROF_YEYING = 10; // 夜影 // Yeying + public const int PROF_YUEXIAN = 11; // 月仙 // Yuexian + public const int NUM_PROFESSION = 12; + + // 性别 // Gender + public const int GENDER_MALE = 0; + public const int GENDER_FEMALE = 1; + public const int NUM_GENDER = 2; + } + + // Constants from EC_Player.h + public static class PlayerModelType + { + public const int PLAYERMODEL_MAJOR = 0; // 主模型 // Major model + public const int PLAYERMODEL_PROFESSION = 1; // 职业变身 // Profession transformation + public const int PLAYERMODEL_DUMMYTYPE2 = 2; // Buff相关 // Buff related + public const int PLAYERMODEL_DUMMYTYPE3 = 3; // 未使用 // Not used + public const int PLAYERMODEL_MAX = 4; + public const int PLAYERMODEL_TYPEALL = unchecked((int)0xffffffff); + } + + // Constants from EC_Resource.h + public static class ResourceModel + { + public const int RES_MOD_YUEXIAN_M = 0; // 月仙男标准模型 // Yuexian male standard model + public const int RES_MOD_YUEXIAN_F = 1; // 月仙女标准模型 // Yuexian female standard model + public const int RES_MOD_YUEXIAN_RESHAPE_M = 2; // 月仙男职业变身 // Yuexian male profession reshape + public const int RES_MOD_YUEXIAN_RESHAPE_F = 3; // 月仙女职业变身 // Yuexian female profession reshape + } + + /// + /// 移动施法管理类 // Cast Skill When Move Manager + /// + public class CECCastSkillWhenMove : Singleton + { + // 朦胧 // Oboro + // 标准男性 UpperBody // Standard male upper body bones + private static readonly string[] s_szOboroMaleStandardUpperBodyBonesName = { + "Bip01 shangshen", + "Bip01 Spine", + "Bip01 Spine1", + "Bip01 Spine2", + "Bip01 Neck", + "Bip01 Head", + "Bip01 L Clavicle", + "Bip01 L UpperArm", + "Bip01 L Forearm", + "Bip01 L Hand", + "Bip01 L Finger0", + "Bip01 L Finger01", + "Bip01 L Finger1", + "Bip01 L Finger11", + "Bip01 R Clavicle", + "Bip01 R UpperArm", + "Bip01 R Forearm", + "Bip01 R Hand", + "Bip01 R Finger0", + "Bip01 R Finger01", + "Bip01 R Finger1", + "Bip01 R Finger11", + "Bone05", + }; + + // 标准男性 LowerBody // Standard male lower body bones + private static readonly string[] s_szOboroMaleStandardLowerBodyBonesName = { + "Bip01", + "Bip01 Pelvis", + "Bip01 xiashen", + "Bip01 L Thigh", + "Bip01 L Calf", + "Bip01 L Foot", + "Bip01 L Toe0", + "Bip01 R Thigh", + "Bip01 R Calf", + "Bip01 R Foot", + "Bip01 R Toe0", + "Bone01", + "Bone02", + "Bone03", + "Bone04", + }; + + // 职业变身男性 UpperBody // Profession reshape male upper body bones + private static readonly string[] s_szOboroMaleShape1UpperBodyBonesName = { + "Bip01 shangshen", + "Bip01 Spine", + "Bip01 Spine1", + "Bip01 Spine2", + "Bip01 Neck", + "Bip01 Head", + "Bip01 L Clavicle", + "Bip01 L UpperArm", + "Bip01 L Forearm", + "Bip01 L Hand", + "Bip01 L Finger0", + "Bip01 L Finger01", + "Bip01 L Finger1", + "Bip01 L Finger11", + "Bip01 R Clavicle", + "Bip01 R UpperArm", + "Bip01 R Forearm", + "Bip01 R Hand", + "Bip01 R Finger0", + "Bip01 R Finger01", + "Bip01 R Finger1", + "Bip01 R Finger11", + "Bone05", + "Bone13", + "Bone14", + "Bone15", + "Bone16", + "Bone17", + "Bone18", + }; + + // 职业变身男性 LowerBody // Profession reshape male lower body bones + private static readonly string[] s_szOboroMaleShape1LowerBodyBonesName = { + "Bip01", + "Bip01 Pelvis", + "Bip01 xiashen", + "Bip01 L Thigh", + "Bip01 L Calf", + "Bip01 L Foot", + "Bip01 L Toe0", + "Bip01 R Thigh", + "Bip01 R Calf", + "Bip01 R Foot", + "Bip01 R Toe0", + "Bone06", + "Bone07", + "Bone08", + "Bone09", + "Bone10", + "Bone11", + "Bone12", + "Bone19", + "Bone20", + "Bone21", + }; + + // 标准女性 UpperBody // Standard female upper body bones + private static readonly string[] s_szOboroFemaleStandardUpperBodyBonesName = { + "Bip01 Spine shangshen", + "Bip01 Spine", + "Bip01 Spine1", + "Bip01 Spine2", + "Bip01 Neck", + "Bip01 Head", + "Bip01 Ponytail1", + "Bip01 Ponytail11", + "Bip01 Ponytail12", + "Bip01 L Clavicle", + "Bip01 L UpperArm", + "Bip01 L Forearm", + "Bip01 L Hand", + "Bip01 L Finger0", + "Bip01 L Finger01", + "Bip01 L Finger1", + "Bip01 L Finger11", + "Bip01 R Clavicle", + "Bip01 R UpperArm", + "Bip01 R Forearm", + "Bip01 R Hand", + "Bip01 R Finger0", + "Bip01 R Finger01", + "Bip01 R Finger1", + "Bip01 R Finger11", + "Bone05", + "Bone01", + }; + + // 标准女性 LowerBody // Standard female lower body bones + private static readonly string[] s_szOboroFemaleStandardLowerBodyBonesName = { + "Bip01", + "Bip01 Pelvis", + "Bip01 Spine xiashen", + "Bip01 L Thigh", + "Bip01 L Calf", + "Bip01 L Foot", + "Bip01 L Toe0", + "Bip01 R Thigh", + "Bip01 R Calf", + "Bip01 R Foot", + "Bip01 R Toe0", + "Bone08", + "Bone09", + "Bone10", + "Bone02", + "Bone03", + "Bone04", + }; + + // 职业变身女性 UpperBody // Profession reshape female upper body bones + private static readonly string[] s_szOboroFemaleShape1UpperBodyBonesName = { + "Bip01 Spine shangshen", + "Bip01 Spine", + "Bip01 Spine1", + "Bip01 Spine2", + "Bip01 Neck", + "Bip01 Head", + "Bip01 Ponytail1", + "Bip01 Ponytail11", + "Bip01 Ponytail12", + "Bip01 L Clavicle", + "Bip01 L UpperArm", + "Bip01 L Forearm", + "Bip01 L Hand", + "Bip01 L Finger0", + "Bip01 L Finger01", + "Bip01 L Finger1", + "Bip01 L Finger11", + "Bip01 R Clavicle", + "Bip01 R UpperArm", + "Bip01 R Forearm", + "Bip01 R Hand", + "Bip01 R Finger0", + "Bip01 R Finger01", + "Bip01 R Finger1", + "Bip01 R Finger11", + "Bone05", + "Bone01", + "Bone14", + "Bone15", + "Bone16", + "Bone17", + "Bone18", + "Bone19", + "Bone20", + "Bone21", + "Bone22", + "Bone23", + "Bone24", + }; + + // 职业变身女性 LowerBody // Profession reshape female lower body bones + private static readonly string[] s_szOboroFemaleShape1LowerBodyBonesName = { + "Bip01", + "Bip01 Pelvis", + "Bip01 Spine xiashen", + "Bip01 L Thigh", + "Bip01 L Calf", + "Bip01 L Foot", + "Bip01 L Toe0", + "Bip01 R Thigh", + "Bip01 R Calf", + "Bip01 R Foot", + "Bip01 R Toe0", + "Bone08", + "Bone09", + "Bone10", + "Bone02", + "Bone03", + "Bone04", + "Bone06", + "Bone07", + "Bone11", + "Bone12", + "Bone13", + }; + + /// + /// 玩家信息 // Player information + /// + public class PlayerInfo + { + public int profession; // 职业 // Profession + public int gender; // 性别 // Gender + public int shapeType; // 变身类型 // Shape type + public int shapeID; // 变身ID // Shape ID + + public PlayerInfo(int profession, int gender, int shapeType, int shapeID) + { + this.profession = profession; + this.gender = gender; + this.shapeType = shapeType; + this.shapeID = shapeID; + } + + public PlayerInfo(CECPlayer pPlayer) + { + if (pPlayer != null) + { + this.profession = pPlayer.GetProfession(); + this.gender = pPlayer.GetGender(); + this.shapeType = pPlayer.GetShapeType(); + this.shapeID = pPlayer.GetShapeID(); + } + } + } + + // Singleton instance + private static readonly object s_lock = new object(); + + // Private constructor for singleton + public CECCastSkillWhenMove() + { + } + + /// + /// 获取单例实例 // Get singleton instance + /// + + /// + /// 检查模型是否支持移动施法 // Check if model supports casting while moving + /// + private bool HasModelSupport(PlayerInfo player) + { + if (player.profession == RoleTypes.PROF_YUEXIAN) + { + switch (player.shapeType) + { + case PlayerModelType.PLAYERMODEL_MAJOR: // 标准模型 // Standard model + return true; + case PlayerModelType.PLAYERMODEL_PROFESSION: // 职业变身模型 // Profession reshape model + if (player.gender == RoleTypes.GENDER_MALE) + { + return player.shapeID == ResourceModel.RES_MOD_YUEXIAN_RESHAPE_M; // 男职业变身 // Male profession reshape + } + else + { + return player.shapeID == ResourceModel.RES_MOD_YUEXIAN_RESHAPE_F; // 女职业变身 // Female profession reshape + } + } + } + // 支持移动施法的ecm模型 // ecm models that support casting while moving + // 注意夜影 PROF_YEYING 模型也支持,但他们没有任何移动施法的技能,故此处不加,以避免不必要的开销 + // Note: PROF_YEYING models also support this, but they don't have any moving cast skills, so not added here to avoid unnecessary overhead + return false; + } + + /// + /// 检查技能是否支持移动施法 // Check if skill supports casting while moving + /// + private bool IsSkillSupported(int idSkill, PlayerInfo player) + { + // 支持移动施法的技能ID // Skill IDs that support casting while moving + return ElementSkill.IsMovingSkill((uint)idSkill); + } + + /// + /// 检查技能动作是否支持移动施法 // Check if skill action supports casting while moving + /// + private bool HasActionSupport(int idSkill, PlayerInfo player) + { + if (HasModelSupport(player)) + { + const int SKILL_COUNT = 19; + int[] s_skills = new int[SKILL_COUNT] { + 2571, 2572, 2579, 2580, 2588, 2591, // 2571素罗闪 2572朱雀闪 2579辞诗箫 2580沐仙曲 2588霜雪铃 2591夕月飞星 + 2627, 2619, 2620, 2621, 2622, 2787, // 2627镜花水月 2619天·素罗闪 2620地·素罗闪 2621天·朱雀闪 2622地·朱雀闪 2787天·辞诗箫 + 2788, 2789, 2790, 2805, 2806, 2811, // 2788地·辞诗箫 2789天·沐仙曲 2790地·沐仙曲 2805天·霜雪铃 2806地·霜雪铃 2811天·夕月飞星 + 2812 // 2812地·夕月飞星 + }; + return s_skills.Contains(idSkill); + } + return false; + } + + /// + /// 获取上半身骨骼名称 // Get upper body bones name + /// + private bool GetUpperBodyBonesName(PlayerInfo player, out int bonesNameCount, out string[] szBonesName) + { + bonesNameCount = 0; + szBonesName = null; + bool result = false; + + if (HasModelSupport(player)) + { + switch (player.shapeType) + { + case PlayerModelType.PLAYERMODEL_MAJOR: + if (RoleTypes.GENDER_MALE == player.gender) + { + szBonesName = s_szOboroMaleStandardUpperBodyBonesName; + bonesNameCount = s_szOboroMaleStandardUpperBodyBonesName.Length; + } + else + { + szBonesName = s_szOboroFemaleStandardUpperBodyBonesName; + bonesNameCount = s_szOboroFemaleStandardUpperBodyBonesName.Length; + } + break; + case PlayerModelType.PLAYERMODEL_PROFESSION: + if (RoleTypes.GENDER_MALE == player.gender) + { + if (ResourceModel.RES_MOD_YUEXIAN_RESHAPE_M == player.shapeID) + { + szBonesName = s_szOboroMaleShape1UpperBodyBonesName; + bonesNameCount = s_szOboroMaleShape1UpperBodyBonesName.Length; + } + } + else + { + if (ResourceModel.RES_MOD_YUEXIAN_RESHAPE_F == player.shapeID) + { + szBonesName = s_szOboroFemaleShape1UpperBodyBonesName; + bonesNameCount = s_szOboroFemaleShape1UpperBodyBonesName.Length; + } + } + break; + default: + // ASSERT(false); + break; + } + result = true; + } + return result; + } + + /// + /// 获取下半身骨骼名称 // Get lower body bones name + /// + private bool GetLowerBodyBonesName(PlayerInfo player, out int bonesNameCount, out string[] szBonesName) + { + bonesNameCount = 0; + szBonesName = null; + bool result = false; + + if (HasModelSupport(player)) + { + switch (player.shapeType) + { + case PlayerModelType.PLAYERMODEL_MAJOR: + if (RoleTypes.GENDER_MALE == player.gender) + { + szBonesName = s_szOboroMaleStandardLowerBodyBonesName; + bonesNameCount = s_szOboroMaleStandardLowerBodyBonesName.Length; + } + else + { + szBonesName = s_szOboroFemaleStandardLowerBodyBonesName; + bonesNameCount = s_szOboroFemaleStandardLowerBodyBonesName.Length; + } + break; + case PlayerModelType.PLAYERMODEL_PROFESSION: + if (RoleTypes.GENDER_MALE == player.gender) + { + if (ResourceModel.RES_MOD_YUEXIAN_RESHAPE_M == player.shapeID) + { + szBonesName = s_szOboroMaleShape1LowerBodyBonesName; + bonesNameCount = s_szOboroMaleShape1LowerBodyBonesName.Length; + } + } + else + { + if (ResourceModel.RES_MOD_YUEXIAN_RESHAPE_F == player.shapeID) + { + szBonesName = s_szOboroFemaleShape1LowerBodyBonesName; + bonesNameCount = s_szOboroFemaleShape1LowerBodyBonesName.Length; + } + } + break; + default: + // ASSERT(false); + break; + } + result = true; + } + return result; + } + + // Public methods that accept CECPlayer + /// + /// 检查玩家模型是否支持移动施法 // Check if player model supports casting while moving + /// + public bool HasModelSupport(CECPlayer pPlayer) + { + return pPlayer != null && HasModelSupport(new PlayerInfo(pPlayer)); + } + + /// + /// 检查技能是否支持移动施法 // Check if skill supports casting while moving + /// + public bool IsSkillSupported(int idSkill, CECPlayer pPlayer) + { + return pPlayer != null && IsSkillSupported(idSkill, new PlayerInfo(pPlayer)); + } + + /// + /// 检查技能动作是否支持移动施法 // Check if skill action supports casting while moving + /// + public bool HasActionSupport(int idSkill, CECPlayer pPlayer) + { + return pPlayer != null && HasActionSupport(idSkill, new PlayerInfo(pPlayer)); + } + + /// + /// 获取玩家上半身骨骼名称 // Get player upper body bones name + /// + public bool GetUpperBodyBonesName(CECPlayer pPlayer, out int bonesNameCount, out string[] szBonesName) + { + bonesNameCount = 0; + szBonesName = null; + return pPlayer != null && GetUpperBodyBonesName(new PlayerInfo(pPlayer), out bonesNameCount, out szBonesName); + } + + /// + /// 获取玩家下半身骨骼名称 // Get player lower body bones name + /// + public bool GetLowerBodyBonesName(CECPlayer pPlayer, out int bonesNameCount, out string[] szBonesName) + { + bonesNameCount = 0; + szBonesName = null; + return pPlayer != null && GetLowerBodyBonesName(new PlayerInfo(pPlayer), out bonesNameCount, out szBonesName); + } + } +} + diff --git a/Assets/PerfectWorld/Scripts/Skills/CECCastSkillWhenMove.cs.meta b/Assets/PerfectWorld/Scripts/Skills/CECCastSkillWhenMove.cs.meta new file mode 100644 index 0000000000..10ad481843 --- /dev/null +++ b/Assets/PerfectWorld/Scripts/Skills/CECCastSkillWhenMove.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 1f189ae1325aa9e40a4e2aadce181e65 \ No newline at end of file diff --git a/Assets/PerfectWorld/Scripts/Skills/ElementSkill.cs b/Assets/PerfectWorld/Scripts/Skills/ElementSkill.cs index 9c0427a865..c1f21bd09f 100644 --- a/Assets/PerfectWorld/Scripts/Skills/ElementSkill.cs +++ b/Assets/PerfectWorld/Scripts/Skills/ElementSkill.cs @@ -17,7 +17,7 @@ namespace BrewMonster.Scripts.Skills TYPE_PASSIVE = 5, // Passive // ���� TYPE_ENABLED = 6, // Enabled // �������� TYPE_LIVE = 7, // Live // ���� - TYPE_JUMP = 8, // Jump // ˲�� + TYPE_FLASHMOVE = 8, // Jump // ˲�� TYPE_PRODUCE = 9, // Production (Crafting) // ����(����) TYPE_BLESSPET = 10, // Pet Blessing // ����ף�� TYPE_NEUTRALBLESS = 11, // Neutral Blessing // ����ף�� @@ -25,12 +25,12 @@ namespace BrewMonster.Scripts.Skills public enum range_type { - TYPE_POINT = 0, // �� - TYPE_LINE = 1, // �� - TYPE_SELFSPHERE = 2, // ����Ϊ���ĵ��� - TYPE_TARGETSPHERE = 3, // Ŀ��Ϊ���ĵ��� - TYPE_TAPER = 4, // Բ׶ - TYPE_SLEF = 5, // ���� + RANGE_POINT = 0, // µã + RANGE_LINE, // Ïß + RANGE_SELFSPHERE, // ×ÔÉíΪÖÐÐĵÄÇò + RANGE_TARGETSPHERE, // Ä¿±êΪÖÐÐĵÄÇò + RANGE_TAPER, // Ô²×¶ + RANGE_SLEF, // ×ÔÉí }; [StructLayout(LayoutKind.Sequential, Pack = 1)] @@ -274,9 +274,17 @@ namespace BrewMonster.Scripts.Skills public virtual bool IsAllowWater() { return true; } public virtual bool IsAllowAir() { return true; } public virtual bool GetNotuseInCombat() { return false; } - //�Ƿ��ƶ�ʩ�� + //�Ƿ��ƶ�ʩ�� // Whether it's a moving skill public virtual bool IsMovingSkill() { return false; } - // �����ܷ��ڵ�ǰ����״̬��ʹ�� + // �Ƿ�Ϊ�ƶ�ʩ���� // Check if skill ID is a moving skill + public static bool IsMovingSkill(uint id) + { + SkillStub s = SkillStub.GetStub(id); + if (s != null) + return s.IsMovingSkill(); + return false; + } + // �����ܷ��ڵ�ǰ����״̬��ʹ�� // Whether skill can be used in current form state public bool IsValidForm(byte form) { byte form_type = (byte)((form & FORM_MASK_HIGH) >> 6); diff --git a/Assets/PerfectWorld/Scripts/Skills/SkillWrapper.cs b/Assets/PerfectWorld/Scripts/Skills/SkillWrapper.cs index f62cfa0e34..031e4aae5a 100644 --- a/Assets/PerfectWorld/Scripts/Skills/SkillWrapper.cs +++ b/Assets/PerfectWorld/Scripts/Skills/SkillWrapper.cs @@ -1,5 +1,4 @@ -using BrewMonster.Assets.PerfectWorld.Scripts.Common; -using CSNetwork.GPDataType; +using CSNetwork.GPDataType; using System; using System.Collections.Generic; using System.Linq; diff --git a/Assets/PerfectWorld/Scripts/Skills/skill177.cs b/Assets/PerfectWorld/Scripts/Skills/skill177.cs index ca42efded0..ae597df7c0 100644 --- a/Assets/PerfectWorld/Scripts/Skills/skill177.cs +++ b/Assets/PerfectWorld/Scripts/Skills/skill177.cs @@ -222,3 +222,4 @@ namespace BrewMonster + diff --git a/Assets/PerfectWorld/Scripts/Skills/skill178.cs b/Assets/PerfectWorld/Scripts/Skills/skill178.cs index 17b152f602..b83d4c2bb7 100644 --- a/Assets/PerfectWorld/Scripts/Skills/skill178.cs +++ b/Assets/PerfectWorld/Scripts/Skills/skill178.cs @@ -222,3 +222,4 @@ namespace BrewMonster + diff --git a/Assets/PerfectWorld/Scripts/Skills/skill54.cs b/Assets/PerfectWorld/Scripts/Skills/skill54.cs index 43c3f8f2d1..baf6db699d 100644 --- a/Assets/PerfectWorld/Scripts/Skills/skill54.cs +++ b/Assets/PerfectWorld/Scripts/Skills/skill54.cs @@ -319,3 +319,4 @@ namespace BrewMonster + diff --git a/Assets/PerfectWorld/Scripts/Skills/skill56.cs b/Assets/PerfectWorld/Scripts/Skills/skill56.cs index 70810e757c..702eefb910 100644 --- a/Assets/PerfectWorld/Scripts/Skills/skill56.cs +++ b/Assets/PerfectWorld/Scripts/Skills/skill56.cs @@ -313,3 +313,4 @@ namespace BrewMonster + diff --git a/Assets/PerfectWorld/Scripts/Skills/skill57.cs b/Assets/PerfectWorld/Scripts/Skills/skill57.cs index 862af1185c..bdb047eb55 100644 --- a/Assets/PerfectWorld/Scripts/Skills/skill57.cs +++ b/Assets/PerfectWorld/Scripts/Skills/skill57.cs @@ -324,3 +324,4 @@ namespace BrewMonster + diff --git a/Assets/PerfectWorld/Scripts/Skills/skill58.cs b/Assets/PerfectWorld/Scripts/Skills/skill58.cs index 19ecdc788e..6dd7ae4507 100644 --- a/Assets/PerfectWorld/Scripts/Skills/skill58.cs +++ b/Assets/PerfectWorld/Scripts/Skills/skill58.cs @@ -317,3 +317,4 @@ namespace BrewMonster + diff --git a/Assets/PerfectWorld/Scripts/Skills/skill76.cs b/Assets/PerfectWorld/Scripts/Skills/skill76.cs index 063a4710b1..c9434f2b8f 100644 --- a/Assets/PerfectWorld/Scripts/Skills/skill76.cs +++ b/Assets/PerfectWorld/Scripts/Skills/skill76.cs @@ -227,3 +227,4 @@ namespace BrewMonster + diff --git a/Assets/PerfectWorld/Scripts/UI/CECUIConfig.cs b/Assets/PerfectWorld/Scripts/UI/CECUIConfig.cs index 439f6bd2e0..72d2bfab72 100644 --- a/Assets/PerfectWorld/Scripts/UI/CECUIConfig.cs +++ b/Assets/PerfectWorld/Scripts/UI/CECUIConfig.cs @@ -1,5 +1,4 @@ -using BrewMonster.Assets.PerfectWorld.Scripts.Common; -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text; diff --git a/Assets/PerfectWorld/Scripts/UI/Dialogs/DlgNPC.cs b/Assets/PerfectWorld/Scripts/UI/Dialogs/DlgNPC.cs index f5f8dd72c1..fd388ec7a0 100644 --- a/Assets/PerfectWorld/Scripts/UI/Dialogs/DlgNPC.cs +++ b/Assets/PerfectWorld/Scripts/UI/Dialogs/DlgNPC.cs @@ -188,7 +188,7 @@ namespace BrewMonster.UI } if (HasTracedTask()) { - CECNPC pNPC = (EC_ManMessageMono.Instance._CECNPCMan.SeekOutNPC(m_iTracedTaskNPCID)); + CECNPC pNPC = (EC_ManMessageMono.Instance.CECNPCMan.SeekOutNPC(m_iTracedTaskNPCID)); if (pNPC) { if (pEssence.id == pNPC.GetNPCID()) diff --git a/Assets/PerfectWorld/Scripts/UI/HUDPlayer.cs b/Assets/PerfectWorld/Scripts/UI/HUDPlayer.cs index ce7c7ea87c..1e8a6255a0 100644 --- a/Assets/PerfectWorld/Scripts/UI/HUDPlayer.cs +++ b/Assets/PerfectWorld/Scripts/UI/HUDPlayer.cs @@ -44,7 +44,6 @@ namespace BrewMonster private void UpdateHostPlayerInfoUI(cmd_self_info_00 obj) { - BMLogger.LogError("Update HUD Player Info"); healthText.text = $"{obj.iHP}/{obj.iMaxHP}"; manaText.text = $"{obj.iMP}/{obj.iMaxMP}"; expText.text = $"{((float)obj.iExp/neededExp)*100}%"; diff --git a/Assets/PerfectWorld/Scripts/World/CECWorld.cs b/Assets/PerfectWorld/Scripts/World/CECWorld.cs index afaad74d26..b129ca9f9a 100644 --- a/Assets/PerfectWorld/Scripts/World/CECWorld.cs +++ b/Assets/PerfectWorld/Scripts/World/CECWorld.cs @@ -1,6 +1,8 @@ using BrewMonster; -using BrewMonster.Assets.PerfectWorld.Scripts.Common; +using BrewMonster.Managers; using BrewMonster.Scripts.Ornament; +using CSNetwork.GPDataType; +using PerfectWorld.Scripts.Managers.BrewMonster.Managers; using UnityEngine; @@ -26,5 +28,32 @@ namespace BrewMonster.Scripts.World { return m_pOnmtMan; } + public CECObject GetObject(int idObject, int iAliveFlag) + { + CECObject pObject = null; + + if (GPDataTypeHelper.ISNPCID(idObject)) + { + if (!(pObject = EC_ManMessageMono.Instance.CECNPCMan.GetNPC(idObject))) + return null; + + if ((iAliveFlag == 1 && ((CECNPC)pObject).IsDead()) || + (iAliveFlag == 2 && !((CECNPC)pObject).IsDead())) + return null; + } + else if (GPDataTypeHelper.ISPLAYERID(idObject)) + { + if (!(pObject = EC_ManMessageMono.Instance.GetECManPlayer.GetPlayer(idObject))) + return null; + + if ((iAliveFlag == 1 && ((CECPlayer)pObject).IsDead()) || + (iAliveFlag == 2 && !((CECPlayer)pObject).IsDead())) + return null; + } + else if (GPDataTypeHelper.ISMATTERID(idObject)) + pObject = EC_ManMessageMono.Instance.GetECManMatter.GetMatter(idObject); + + return pObject; + } } } diff --git a/Assets/Scripts/CECHostPlayer.cs b/Assets/Scripts/CECHostPlayer.cs index dd121f63af..31c4e6814b 100644 --- a/Assets/Scripts/CECHostPlayer.cs +++ b/Assets/Scripts/CECHostPlayer.cs @@ -12,7 +12,6 @@ using CSNetwork.GPDataType; using CSNetwork.Protocols.RPCData; using ModelRenderer.Scripts.GameData; using PerfectWorld.Scripts.Managers; -using PerfectWorld.Scripts.Player; using System; using System.Collections.Generic; using System.Runtime.InteropServices; @@ -22,7 +21,7 @@ using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.UI; using Host_work_ID = BrewMonster.Scripts.CECHPWork.Host_work_ID; -using Trace_reason = CECHPWorkTrace.Trace_reason; +using Trace_reason = BrewMonster.CECHPWorkTrace.Trace_reason; namespace BrewMonster { @@ -287,7 +286,7 @@ namespace BrewMonster int idObject = CECObject.GetObjectID(clickedObject); if (idObject != 0) { - CECNPC pNPC = EC_ManMessageMono.Instance._CECNPCMan.GetNPC(idObject); + CECNPC pNPC = EC_ManMessageMono.Instance.CECNPCMan.GetNPC(idObject); if (pNPC != null) { if (!pNPC.IsDead() && m_idSelTarget == idObject) @@ -664,7 +663,7 @@ namespace BrewMonster // Mark host player as corpse so CECPlayer.IsDead() returns true m_dwStates |= (uint)PlayerNPCState.GP_STATE_CORPSE; - EventBus.PublishChannel(GetCharacterID(), new CECPlayer.ClearComActFlagAllRankNodesEvent(true)); + EventBus.PublishChannel(GetCharacterID(), new ClearComActFlagAllRankNodesEvent(true)); PlayAction((int)PLAYER_ACTION_TYPE.ACT_GROUNDDIE); if (PopupManager.Instance != null) { @@ -767,7 +766,7 @@ namespace BrewMonster } else if (GPDataTypeHelper.ISNPCID(pCmd.idAttacker)) { - CECNPC pAttacker = EC_ManMessageMono.Instance._CECNPCMan.GetNPC(pCmd.idAttacker); + CECNPC pAttacker = EC_ManMessageMono.Instance.CECNPCMan.GetNPC(pCmd.idAttacker); if (pAttacker) { pAttacker.OnMsgAttackHostResult(GetCharacterID(), pCmd.iDamage, pCmd.attack_flag, pCmd.speed); @@ -1388,12 +1387,12 @@ namespace BrewMonster //CECHPWorkDead pWork = (CECHPWorkDead*)m_pWorkMan->CreateWork(CECHPWork.Host_work_ID.WORK_DEAD); //pWork->SetBeDeadFlag(true); //m_pWorkMan->StartWork_p0(pWork); - EventBus.PublishChannel(GetCharacterID(), new CECPlayer.ClearComActFlagAllRankNodesEvent(true)); - PlayAction((int)PLAYER_ACTION_TYPE.ACT_GROUNDDIE); - if (PopupManager.Instance != null) - { - PopupManager.Instance.OnPlayerDied(); - } + EventBus.PublishChannel(GetCharacterID(), new ClearComActFlagAllRankNodesEvent(true)); + PlayAction((int)PLAYER_ACTION_TYPE.ACT_GROUNDDIE); + if (PopupManager.Instance != null) + { + PopupManager.Instance.OnPlayerDied(); + } } else { @@ -1989,41 +1988,41 @@ namespace BrewMonster // If host has set bless skill filter only to himself, bless skill couldn't add to other players byte byBLSMask = EC_Utility.glb_BuildBLSMask(); - /* if (pSkill->GetRangeType() == CECSkill::RANGE_POINT) + if (pSkill.GetRangeType() == (int)range_type.RANGE_POINT) { if (!IsTeamMember(idCastTarget)) { - if (byBLSMask & GP_BLSMASK_SELF) + if ((byBLSMask & (byte)PVPMask.GP_BLSMASK_SELF) != 0) idCastTarget = m_PlayerInfo.cid; else { - CECElsePlayer* pPlayer = (CECElsePlayer*)g_pGame->GetGameRun()->GetWorld()->GetPlayerMan()->GetPlayer(idCastTarget); - if (!pPlayer) + EC_ElsePlayer pPlayer = (EC_ElsePlayer)EC_ManMessageMono.Instance.GetECManPlayer.GetPlayer(idCastTarget); + if (pPlayer == null) { // Ä¿±êÏûʧ return false; } - if (pPlayer->IsInvader() || pPlayer->IsPariah()) + if (pPlayer.IsInvader() || pPlayer.IsPariah()) { - if (byBLSMask & GP_BLSMASK_NORED) + if ((byBLSMask & (byte)PVPMask.GP_BLSMASK_NORED) != 0) idCastTarget = m_PlayerInfo.cid; } - if (!IsFactionMember(pPlayer->GetFactionID())) + if (!IsFactionMember(pPlayer.GetFactionID())) { - if (byBLSMask & GP_BLSMASK_NOMAFIA) + if ((byBLSMask & (byte)PVPMask.GP_BLSMASK_NOMAFIA) != 0) idCastTarget = m_PlayerInfo.cid; } - if (!IsFactionAllianceMember(pPlayer->GetFactionID())) + if (!IsFactionAllianceMember(pPlayer.GetFactionID())) { - if (byBLSMask & GP_BLSMASK_NOALLIANCE) + if ((byBLSMask & (byte)PVPMask.GP_BLSMASK_NOALLIANCE) != 0) idCastTarget = m_PlayerInfo.cid; } - if (GetForce() != pPlayer->GetForce()) + if (GetForce() != pPlayer.GetForce()) { - if (byBLSMask & GP_BLSMASK_NOFORCE) + if ((byBLSMask & (byte)PVPMask.GP_BLSMASK_NOFORCE) != 0) idCastTarget = m_PlayerInfo.cid; } } @@ -2037,133 +2036,136 @@ namespace BrewMonster // If host is in battle, bless skill couldn't add to enemies if (IsInBattle()) { - CECElsePlayer* pPlayer = m_pPlayerMan->GetElsePlayer(idCastTarget); + EC_ElsePlayer pPlayer = EC_ManMessageMono.Instance.GetECManPlayer.GetElsePlayer(idCastTarget); if (!InSameBattleCamp(pPlayer)) idCastTarget = m_PlayerInfo.cid; - }*/ + } } } - //else if (pSkill->GetType() == CECSkill::TYPE_BLESSPET) - //{ - // CECPet* pPet = g_pGame->GetGameRun()->GetWorld()->GetNPCMan()->GetPetByID(idSelTarget); - // if (!pPet || pPet->GetMasterID() == GetCharacterID()) - // { - // // Spell skill on host's pet - // CECPetData* pPetData = m_pPetCorral->GetActivePet(); - // if (!pPetData || - // pPetData->GetClass() != GP_PET_CLASS_COMBAT && - // pPetData->GetClass() != GP_PET_CLASS_SUMMON && - // pPetData->GetClass() != GP_PET_CLASS_EVOLUTION) - // return false; + /* else if (pSkill.GetType() == CECSkill::TYPE_BLESSPET) + { + CECPet* pPet = g_pGame->GetGameRun()->GetWorld()->GetNPCMan()->GetPetByID(idSelTarget); + if (!pPet || pPet->GetMasterID() == GetCharacterID()) + { + // Spell skill on host's pet + CECPetData* pPetData = m_pPetCorral->GetActivePet(); + if (!pPetData || + pPetData->GetClass() != GP_PET_CLASS_COMBAT && + pPetData->GetClass() != GP_PET_CLASS_SUMMON && + pPetData->GetClass() != GP_PET_CLASS_EVOLUTION) + return false; - // idCastTarget = m_pPetCorral->GetActivePetNPCID(); - // } - // // Only fighting pet can be blessed. - // if (pPet && !pPet->CanBeAttacked()) - // return false; - //} - //else - //{ - // if (iTargetType != 0 && !idCastTarget) - // return false; - //} - - //// iTargetType == 4 means target must be pet. The problem is that pet will - //// disappear from world after it died, so GetWorld()->GetObject() will return - //// NULL when host spells revive-pet skill on his dead pet. So, the target - //// type of revive-pet skill should be 0 - //if (iTargetType) - //{ - // // Target shoundn't be a corpse ? - // int iAliveFlag = 0; - // if (iTargetType == 1) - // iAliveFlag = 1; - // else if (iTargetType == 2) - // iAliveFlag = 2; - - // CECObject* pObject = g_pGame->GetGameRun()->GetWorld()->GetObject(idCastTarget, iAliveFlag); - // if (!pObject) - // return false; - //} - - //if (!IsMeleeing() && !IsSpellingMagic() && - // (!iTargetType || idCastTarget == m_PlayerInfo.cid)) - //{ - // // Cast this skill need't checking cast distance - // if (!pSkill->ReadyToCast()) - // return false; - - // // Prepare to cast skill, if skill isn't INSTANT and FLASHMOVE, - // // we must stop moving and stand - // if (!pSkill->IsInstant() && pSkill->GetType() != CECSkill::TYPE_FLASHMOVE) - // { - // if (!NaturallyStopMoving()) - // return false; // Couldn't stop naturally, so cancel casting skill - // } - // else if (pSkill->GetType() == CECSkill::TYPE_FLASHMOVE) - // { - // if (!CanDo(CANDO_FLASHMOVE)) - // return false; - // } - - m_pPrepSkill = pSkill; - //CastSkill(m_idSelTarget, bForceAttack); - //} - //else if (IsSpellingMagic() && m_pCurSkill == pSkill) - //{ - // // If we are casting the same skill and it's in cooling time - // return false; - //} - //else // Have to trace selected object before cast skill - //{ - // if (!pSkill->ReadyToCast()) - // return false; - - // if (CECCastSkillWhenMove::Instance().IsSkillSupported(pSkill->GetSkillID(), this) && - // m_pWorkMan->IsMovingToPosition() && - // m_pWorkMan->CanCastSkillImmediately(pSkill->GetSkillID())) - // { - // m_pPrepSkill = pSkill; - // return CastSkill(idCastTarget, bForceAttack); - // } - // else - // { - bool bTraceOK = false; - bool bUseAutoPF = false; - /* CECPlayerWrapper* pWrapper = CECAutoPolicy::GetInstance().GetPlayerWrapper(); - if (CECAutoPolicy::GetInstance().IsAutoPolicyEnabled() && pWrapper->GetAttackError() >= 2) - bUseAutoPF = true;*/ - - if (idCastTarget == 0) + idCastTarget = m_pPetCorral->GetActivePetNPCID(); + } + // Only fighting pet can be blessed. + if (pPet && !pPet->CanBeAttacked()) + return false; + }*/ + else { - idCastTarget = GetCharacterID(); // ±ÜÃâË²ÒÆµÈ¼¼ÄÜʱ idCastTarget Ϊ0µ¼Ö CECWorkTrace::CreateTraceTarget ·µ»Ø¿Õ - } - CECHPWork pWork = m_pWorkMan.GetWork(Host_work_ID.WORK_TRACEOBJECT); - if (pWork != null) - { - CECHPWorkTrace pWorkTrace = (CECHPWorkTrace)(pWork); - if (pWorkTrace.GetTraceReason() == Trace_reason.TRACE_SPELL && - pWorkTrace.GetTarget() == idCastTarget && - pWorkTrace.GetPrepSkill() == pSkill) - return false; // We are just doing the same thing - - pWorkTrace.SetTraceTarget(pWorkTrace.CreatTraceTarget(idCastTarget, Trace_reason.TRACE_SPELL, bForceAttack), bUseAutoPF); - pWorkTrace.SetPrepSkill(pSkill); - bTraceOK = true; - } - else if (m_pWorkMan.CanStartWork(Host_work_ID.WORK_TRACEOBJECT)) - { - CECHPWorkTrace pWork2 = (CECHPWorkTrace)m_pWorkMan.CreateWork(Host_work_ID.WORK_TRACEOBJECT); - pWork2.SetTraceTarget(pWork2.CreatTraceTarget(idCastTarget, Trace_reason.TRACE_SPELL, bForceAttack), bUseAutoPF); - pWork2.SetPrepSkill(pSkill); - m_pWorkMan.StartWork_p1(pWork2); - bTraceOK = true; + if (iTargetType != 0 && idCastTarget == 0) + return false; } - if (!bTraceOK) return false; - // } - //} + // iTargetType == 4 means target must be pet. The problem is that pet will + // disappear from world after it died, so GetWorld()->GetObject() will return + // NULL when host spells revive-pet skill on his dead pet. So, the target + // type of revive-pet skill should be 0 + if (iTargetType != 0) + { + // Target shoundn't be a corpse ? + int iAliveFlag = 0; + if (iTargetType == 1) + iAliveFlag = 1; + else if (iTargetType == 2) + iAliveFlag = 2; + CECObject pObject = EC_Game.GetGameRun().GetWorld().GetObject(idCastTarget, iAliveFlag); + if (!pObject) + return false; + } + + if (!IsMeleeing() && !IsSpellingMagic() && + (iTargetType == 0 || idCastTarget == m_PlayerInfo.cid)) + { + // Cast this skill need't checking cast distance + if (!pSkill.ReadyToCast()) + return false; + + // Prepare to cast skill, if skill isn't INSTANT and FLASHMOVE, + // we must stop moving and stand + if (!pSkill.IsInstant() && pSkill.GetType() != (int)skill_type.TYPE_FLASHMOVE) + { + /* if (!NaturallyStopMoving()) + return false; */ // Couldn't stop naturally, so cancel casting skill + } + else if (pSkill.GetType() == (int)skill_type.TYPE_FLASHMOVE) + { + if (!CanDo(ActionCanDo.CANDO_FLASHMOVE)) + return false; + } + BMLogger.LogError("HoangDev: ApplySkillShortcut - PATH 1: Calling CastSkill (self-cast)"); + + m_pPrepSkill = pSkill; + CastSkill(m_idSelTarget, bForceAttack); + } + else if (IsSpellingMagic() && m_pCurSkill == pSkill) + { + // If we are casting the same skill and it's in cooling time + return false; + } + else // Have to trace selected object before cast skill + { + if (!pSkill.ReadyToCast()) + return false; + + if (CECCastSkillWhenMove.Instance.IsSkillSupported(pSkill.GetSkillID(), this) && + m_pWorkMan.IsMovingToPosition() && + m_pWorkMan.CanCastSkillImmediately(pSkill.GetSkillID())) + { + m_pPrepSkill = pSkill; + return CastSkill(idCastTarget, bForceAttack); + } + else + { + bool bTraceOK = false; + bool bUseAutoPF = false; + /* CECPlayerWrapper pWrapper = CECAutoPolicy::GetInstance().GetPlayerWrapper(); + if (CECAutoPolicy::GetInstance().IsAutoPolicyEnabled() && pWrapper->GetAttackError() >= 2) + bUseAutoPF = true;*/ + + if (idCastTarget == 0) + { + idCastTarget = GetCharacterID(); // ±ÜÃâË²ÒÆµÈ¼¼ÄÜʱ idCastTarget Ϊ0µ¼Ö CECWorkTrace::CreateTraceTarget ·µ»Ø¿Õ + } + CECHPWork pWork = m_pWorkMan.GetWork(Host_work_ID.WORK_TRACEOBJECT); + if (pWork != null) + { + CECHPWorkTrace pWorkTrace = (CECHPWorkTrace)(pWork); + if (pWorkTrace.GetTraceReason() == Trace_reason.TRACE_SPELL && + pWorkTrace.GetTarget() == idCastTarget && + pWorkTrace.GetPrepSkill() == pSkill) + return false; // We are just doing the same thing + + pWorkTrace.SetTraceTarget(pWorkTrace.CreatTraceTarget(idCastTarget, Trace_reason.TRACE_SPELL, bForceAttack), bUseAutoPF); + pWorkTrace.SetPrepSkill(pSkill); + bTraceOK = true; + } + else if (m_pWorkMan.CanStartWork(Host_work_ID.WORK_TRACEOBJECT)) + { + CECHPWorkTrace pWork2 = (CECHPWorkTrace)m_pWorkMan.CreateWork(Host_work_ID.WORK_TRACEOBJECT); + pWork2.SetTraceTarget(pWork2.CreatTraceTarget(idCastTarget, Trace_reason.TRACE_SPELL, bForceAttack), bUseAutoPF); + pWork2.SetPrepSkill(pSkill); + m_pWorkMan.StartWork_p1(pWork2); + bTraceOK = true; + } + + if (!bTraceOK) return false; + // } + //} + + } + } return true; } public void PrepareNPCService(int idSev) @@ -2465,7 +2467,7 @@ namespace BrewMonster } else if (GPDataTypeHelper.ISNPCID(idTarget)) { - CECNPC pNPC = EC_ManMessageMono.Instance._CECNPCMan.GetNPC(idTarget); + CECNPC pNPC = EC_ManMessageMono.Instance.CECNPCMan.GetNPC(idTarget); if (pNPC != null) { if (CanSafelySelect(pNPC) && !pNPC.IsDead()) @@ -2772,6 +2774,7 @@ namespace BrewMonster // } // return fSpeedSev; //} + public bool IsMeleeing() { return m_bMelee; } private void OnMsgHstNPCGreeting(ECMSG Msg) { @@ -2793,7 +2796,7 @@ namespace BrewMonster // return; //} - CECNPC pNPC = EC_ManMessageMono.Instance._CECNPCMan.GetNPC(pCmd.idObject); + CECNPC pNPC = EC_ManMessageMono.Instance.CECNPCMan.GetNPC(pCmd.idObject); if (!pNPC || !pNPC.IsServerNPC()) { return; @@ -2962,7 +2965,18 @@ namespace BrewMonster } return bInWar; } - + public bool IsFactionMember(int idTargetFaction) + { + // µ±Ç°ÊôÓÚij°ïÅÉ£¬ÇÒ¶Ô·½ÊôÓÚͬһ°ïÅÉʱ·µ»Ø true + return GetFactionID() != 0 && GetFactionID() == idTargetFaction; + } + public bool IsFactionAllianceMember(int idTargetFaction) + { + // µ±Ç°ÊôÓÚij°ïÅÉ£¬¶Ô·½ÊôÓÚͬһ°ïÅÉ¡¢»òÕßÊôÓÚͬÃ˰ïÅÉ + return GetFactionID() != 0 + && idTargetFaction != 0 + && (GetFactionID() == idTargetFaction || EC_Game.GetFactionMan().IsFactionAlliance(idTargetFaction)); + } public int GetCountry() { return m_idCountry; } // Get battle info. @@ -3153,7 +3167,7 @@ namespace BrewMonster if (GPDataTypeHelper.ISNPCID(idHitObject)) { // NPC handling - CECNPC pNPC = EC_ManMessageMono.Instance?._CECNPCMan?.GetNPC(idHitObject); + CECNPC pNPC = EC_ManMessageMono.Instance?.CECNPCMan?.GetNPC(idHitObject); if (pNPC != null && !pNPC.IsDead()) { m_idCurHover = idHitObject; @@ -3308,21 +3322,6 @@ namespace BrewMonster } }; - // PVP infomation - public struct PVPINFO - { - public bool bEnable; // PVP switch - public uint dwCoolTime; - public uint dwMaxCoolTime; - public bool bFreePVP; // Free PVP flag, ignore bEnable flag - public bool bInPVPCombat; // true, in PVP combat - public int iDuelState; // Duel state - public int idDuelOpp; // Duel opponent - public int iDuelTimeCnt; // Duel time counter - public int iDuelRlt; // Duel result. 0, no defined; 1-win; 2-lose; 3-draw - }; - - // Current ground information public struct GNDINFO { public float fGndHei; // Ground height diff --git a/Assets/Scripts/CECPlayer_Inventory.cs b/Assets/Scripts/CECPlayer_Inventory.cs index 3e56f0d7a6..71dc970ecc 100644 --- a/Assets/Scripts/CECPlayer_Inventory.cs +++ b/Assets/Scripts/CECPlayer_Inventory.cs @@ -6,46 +6,48 @@ using BrewMonster.Scripts.Managers; using ModelRenderer.Scripts.GameData; using UnityEngine; -public partial class CECPlayer +namespace BrewMonster { - public const int NUM_PROFESSION = (int)Profession.NUM_PROFESSION; - public const int NUM_GENDER = (int)Gender.NUM_GENDER; - - public static readonly string _left_hand_weapon = "LeftHand"; - public static readonly string _right_hand_weapon = "RightHand"; - public static readonly string _wing = "Wing"; - public static readonly string _wing2 = "Wing2"; - public const string _cc_ride = "CC_Ride"; - public static readonly string _cc_ride2 = "CC_Ride2"; - public const string _hh_ride = "HH_Ride"; - public const string _hanger_ride = "Rider"; - public static readonly string _hanger_ride2 = "Rider2"; - public static readonly string _hanger_hug = "Hug"; - public static readonly string _hh_bind = "HH_Bind"; - public static readonly string _cc_bind = "CC_Bind"; - - public const string _cc_fenghuolun = "CC_feijian"; - public const string _hh_left_foot = "HH_左脚"; - public const string _hh_right_foot = "HH_右脚"; - - public static readonly string _hh_left_shoulder_weapon = "HH_leftsword"; - public static readonly string _hh_right_shoulder_weapon = "HH_rightsword"; - - public static readonly string _hh_left_hand_weapon = "HH_lefthandweapon"; - public static readonly string _hh_right_hand_weapon = "HH_righthandweapon"; - - public static readonly string _hh_qiu = "HH_qiu"; - - public static readonly string _hh_right_hand_nickle_weapon = "HH_weapon"; - - public static readonly string _cc_weapon = "CC_weapon"; - public static readonly string _cc_qiu = "CC_qiu"; - public static readonly string _hh_qiu_base = "HH_base"; - - public static readonly string[] _multiobject_effect = { "绿色连线.gfx", "红色连线.gfx", "黑色连线.gfx" }; - - public static readonly string[] _equipment_skin = + public partial class CECPlayer { + public const int NUM_PROFESSION = (int)Profession.NUM_PROFESSION; + public const int NUM_GENDER = (int)Gender.NUM_GENDER; + + public static readonly string _left_hand_weapon = "LeftHand"; + public static readonly string _right_hand_weapon = "RightHand"; + public static readonly string _wing = "Wing"; + public static readonly string _wing2 = "Wing2"; + public const string _cc_ride = "CC_Ride"; + public static readonly string _cc_ride2 = "CC_Ride2"; + public const string _hh_ride = "HH_Ride"; + public const string _hanger_ride = "Rider"; + public static readonly string _hanger_ride2 = "Rider2"; + public static readonly string _hanger_hug = "Hug"; + public static readonly string _hh_bind = "HH_Bind"; + public static readonly string _cc_bind = "CC_Bind"; + + public const string _cc_fenghuolun = "CC_feijian"; + public const string _hh_left_foot = "HH_左脚"; + public const string _hh_right_foot = "HH_右脚"; + + public static readonly string _hh_left_shoulder_weapon = "HH_leftsword"; + public static readonly string _hh_right_shoulder_weapon = "HH_rightsword"; + + public static readonly string _hh_left_hand_weapon = "HH_lefthandweapon"; + public static readonly string _hh_right_hand_weapon = "HH_righthandweapon"; + + public static readonly string _hh_qiu = "HH_qiu"; + + public static readonly string _hh_right_hand_nickle_weapon = "HH_weapon"; + + public static readonly string _cc_weapon = "CC_weapon"; + public static readonly string _cc_qiu = "CC_qiu"; + public static readonly string _hh_qiu_base = "HH_base"; + + public static readonly string[] _multiobject_effect = { "绿色连线.gfx", "红色连线.gfx", "黑色连线.gfx" }; + + public static readonly string[] _equipment_skin = + { "models/players/装备/男/{0}/男通用{1}", "models/players/装备/女/{0}/女通用{1}", "models/players/装备/男/{0}/男通用{1}", @@ -62,7 +64,7 @@ public partial class CECPlayer "models/players/装备/女/{0}/女通用{1}", "models/players/装备/男/{0}/男通用{1}", "models/players/装备/女/{0}/女通用{1}", - + "models/players/装备/男/{0}/男通用{1}", "models/players/装备/女/{0}/女通用{1}", "models/players/装备/男/{0}/男通用{1}", @@ -74,419 +76,420 @@ public partial class CECPlayer }; - // Skin index - public enum SkinIndex - { - SKIN_BODY_INDEX = 0, - SKIN_UPPER_BODY_INDEX, - SKIN_WRIST_INDEX, - SKIN_LOWER_INDEX, - SKIN_FOOT_INDEX, - SKIN_HEAD_INDEX, - SKIN_FASHION_UPPER_BODY_INDEX, - SKIN_FASHION_WRIST_INDEX, - SKIN_FASHION_LOWER_INDEX, - SKIN_FASHION_FOOT_INDEX, - NUM_SKIN_INDEX, - } - - // Wing types - public enum WingType - { - WINGTYPE_WING, // 锟斤拷锟斤拷锟斤拷锟斤拷锟酵o拷锟斤拷锟?????? - WINGTYPE_FLYSWORD, // 锟斤拷锟斤拷锟斤拷锟斤拷锟酵o拷锟缴斤拷 - WINGTYPE_DOUBLEWHEEL, // 锟斤拷锟斤拷锟斤拷锟斤拷锟酵o拷双锟脚凤拷锟斤拷锟斤�? - } - - private static readonly SkinIndex[] _location_skin_map = - { - SkinIndex.SKIN_BODY_INDEX, - SkinIndex.SKIN_UPPER_BODY_INDEX, - SkinIndex.SKIN_WRIST_INDEX, - SkinIndex.SKIN_LOWER_INDEX, - SkinIndex.SKIN_FOOT_INDEX, - SkinIndex.SKIN_UPPER_BODY_INDEX, - SkinIndex.SKIN_UPPER_BODY_INDEX, - SkinIndex.SKIN_LOWER_INDEX, - SkinIndex.SKIN_UPPER_BODY_INDEX - }; - - // The skeleton builder holds the reference to the player's bones - // We use this to setup the bones for the equipment skinned mesh renderers - private SkeletonBuilder _skeletonBuilder; - private PlayerDefaultEquipments _playerDefaultEquipments; - - // Track instantiated armor objects for each slot - private GameObject _currentUpperArmor; - private GameObject _currentLowerArmor; - private GameObject _currentWristArmor; - private GameObject _currentFootArmor; - - // Track instantiated weapon objects - private GameObject _currentRightHandWeapon; - private GameObject _currentLeftHandWeapon; - private PlayerDefaultEquipments PlayerDefaultEquipments - { - get + // Skin index + public enum SkinIndex { - if (_playerDefaultEquipments == null) + SKIN_BODY_INDEX = 0, + SKIN_UPPER_BODY_INDEX, + SKIN_WRIST_INDEX, + SKIN_LOWER_INDEX, + SKIN_FOOT_INDEX, + SKIN_HEAD_INDEX, + SKIN_FASHION_UPPER_BODY_INDEX, + SKIN_FASHION_WRIST_INDEX, + SKIN_FASHION_LOWER_INDEX, + SKIN_FASHION_FOOT_INDEX, + NUM_SKIN_INDEX, + } + + // Wing types + public enum WingType + { + WINGTYPE_WING, // 锟斤拷锟斤拷锟斤拷锟斤拷锟酵o拷锟斤拷锟?????? + WINGTYPE_FLYSWORD, // 锟斤拷锟斤拷锟斤拷锟斤拷锟酵o拷锟缴斤拷 + WINGTYPE_DOUBLEWHEEL, // 锟斤拷锟斤拷锟斤拷锟斤拷锟酵o拷双锟脚凤拷锟斤拷锟斤�? + } + + private static readonly SkinIndex[] _location_skin_map = + { + SkinIndex.SKIN_BODY_INDEX, + SkinIndex.SKIN_UPPER_BODY_INDEX, + SkinIndex.SKIN_WRIST_INDEX, + SkinIndex.SKIN_LOWER_INDEX, + SkinIndex.SKIN_FOOT_INDEX, + SkinIndex.SKIN_UPPER_BODY_INDEX, + SkinIndex.SKIN_UPPER_BODY_INDEX, + SkinIndex.SKIN_LOWER_INDEX, + SkinIndex.SKIN_UPPER_BODY_INDEX + }; + + // The skeleton builder holds the reference to the player's bones + // We use this to setup the bones for the equipment skinned mesh renderers + private SkeletonBuilder _skeletonBuilder; + private PlayerDefaultEquipments _playerDefaultEquipments; + + // Track instantiated armor objects for each slot + private GameObject _currentUpperArmor; + private GameObject _currentLowerArmor; + private GameObject _currentWristArmor; + private GameObject _currentFootArmor; + + // Track instantiated weapon objects + private GameObject _currentRightHandWeapon; + private GameObject _currentLeftHandWeapon; + private PlayerDefaultEquipments PlayerDefaultEquipments + { + get { - _playerDefaultEquipments = GetComponentInChildren(); + if (_playerDefaultEquipments == null) + { + _playerDefaultEquipments = GetComponentInChildren(); + } + return _playerDefaultEquipments; } - return _playerDefaultEquipments; } - } - - public bool UpdateEquipSkins() - { - int[] aNewEquips = new int[InventoryConst.IVTRSIZE_EQUIPPACK]; - EC_IvtrItem pItem = null; - for (int i = 0; i < InventoryConst.IVTRSIZE_EQUIPPACK; i++) + + public bool UpdateEquipSkins() { - // Use host player's equipment inventory (per-instance CECInventory) - var host = CECGameRun.Instance?.GetHostPlayer(); - var equipInv = host?.EquipInventory; - pItem = equipInv?.GetItem(i, false); - if (pItem != null) - aNewEquips[i] = pItem.m_tid; - } + int[] aNewEquips = new int[InventoryConst.IVTRSIZE_EQUIPPACK]; + EC_IvtrItem pItem = null; + for (int i = 0; i < InventoryConst.IVTRSIZE_EQUIPPACK; i++) + { + // Use host player's equipment inventory (per-instance CECInventory) + var host = CECGameRun.Instance?.GetHostPlayer(); + var equipInv = host?.EquipInventory; + pItem = equipInv?.GetItem(i, false); + if (pItem != null) + aNewEquips[i] = pItem.m_tid; + } ShowEquipments(aNewEquips, true, true); return true; } - public async void ShowEquipments(int[] pEquipmentID, bool bLoadAtOnce, bool bForceLoad) - { - var elemendataman = BrewMonster.ElementDataManProvider.GetElementDataMan(); - DATA_TYPE DataType = default; - bool useDefaultUpper = false; - bool useDefaultLower = false; - bool useDefaultWrist = false; - bool useDefaultFoot = false; - for (int i = 0; i < InventoryConst.IVTRSIZE_EQUIPPACK; i++) + public async void ShowEquipments(int[] pEquipmentID, bool bLoadAtOnce, bool bForceLoad) { - //TODO: The equipment ids store the stone information, we need to extract the stone information from the equipment id. - /* - int idEquipment = pEquipmentID[i]; - if((i >= EQUIPIVTR_FASHION_BODY && i <= EQUIPIVTR_FASHION_WRIST ) || - i == EQUIPIVTR_FASHION_HEAD || i == EQUIPIVTR_FASHION_WEAPON) - { - WORD wColor = (idEquipment & 0xffff0000) >> 16; - idEquipment &= 0x0000ffff; - color = FASHION_WORDCOLOR_TO_A3DCOLOR(wColor); - } - else - { - if( i == EQUIPIVTR_WEAPON ) - { - pResult->stoneWeapon = (idEquipment & 0xffff0000) >> 16; - } - if( i == EQUIPIVTR_BODY ) - { - pResult->stoneUpperBody = (idEquipment & 0xffff0000) >> 16; - } - if( i == EQUIPIVTR_WRIST ) - { - pResult->stoneWrist = (idEquipment & 0xffff0000) >> 16; - } - if( i == EQUIPIVTR_LEG ) - { - pResult->stoneLowerBody = (idEquipment & 0xffff0000) >> 16; - } - if( i == EQUIPIVTR_FOOT ) - { - pResult->stoneFoot = (idEquipment & 0xffff0000) >> 16; - } - idEquipment &= 0x0000ffff; - } - */ - if (pEquipmentID[i] != m_aEquips[i]) + var elemendataman = BrewMonster.ElementDataManProvider.GetElementDataMan(); + DATA_TYPE DataType = default; + bool useDefaultUpper = false; + bool useDefaultLower = false; + bool useDefaultWrist = false; + bool useDefaultFoot = false; + for (int i = 0; i < InventoryConst.IVTRSIZE_EQUIPPACK; i++) { - m_aEquips[i] = pEquipmentID[i]; // store the current equipment id - // new equipment. Need to load and equip to host player - var equipData = elemendataman.get_data_ptr((uint)pEquipmentID[i], ID_SPACE.ID_SPACE_ESSENCE, ref DataType); - object subTypeData = null; - switch (DataType) + //TODO: The equipment ids store the stone information, we need to extract the stone information from the equipment id. + /* + int idEquipment = pEquipmentID[i]; + if((i >= EQUIPIVTR_FASHION_BODY && i <= EQUIPIVTR_FASHION_WRIST ) || + i == EQUIPIVTR_FASHION_HEAD || i == EQUIPIVTR_FASHION_WEAPON) { - case DATA_TYPE.DT_WEAPON_ESSENCE: - var weaponData = (WEAPON_ESSENCE)equipData; - subTypeData = elemendataman.get_data_ptr((uint)weaponData.id_sub_type, ID_SPACE.ID_SPACE_ESSENCE, ref DataType); - if (subTypeData != null && DataType == DATA_TYPE.DT_WEAPON_SUB_TYPE) - { - var subTypeDataWeapon = (WEAPON_SUB_TYPE)subTypeData; - m_uAttackType = subTypeDataWeapon.action_type; - m_ExtProps.ak.AttackRange = weaponData.attack_range; - } - string fileModelRight = AFile.NormalizePath(weaponData.FileModelRight, true).ToLower(); - string fileModelLeft = AFile.NormalizePath(weaponData.FileModelLeft, true).ToLower(); - // BMLogger.Log($"ShowEquipments():: Weapon Essence: {fileModelRight} -- {fileModelLeft}"); - - // Destroy existing right hand weapon before creating new one - if (_currentRightHandWeapon != null) - { - Destroy(_currentRightHandWeapon); - _currentRightHandWeapon = null; - } - - // Destroy existing left hand weapon before creating new one - if (_currentLeftHandWeapon != null) - { - Destroy(_currentLeftHandWeapon); - _currentLeftHandWeapon = null; - } - - GameObject weaponPrefab = null; - if (!string.IsNullOrEmpty(fileModelRight)) - { - weaponPrefab = await AddressableManager.Instance.LoadPrefabAsync(fileModelRight); - var weaponObject = Instantiate(weaponPrefab); - if (weaponObject != null) + WORD wColor = (idEquipment & 0xffff0000) >> 16; + idEquipment &= 0x0000ffff; + color = FASHION_WORDCOLOR_TO_A3DCOLOR(wColor); + } + else + { + if( i == EQUIPIVTR_WEAPON ) + { + pResult->stoneWeapon = (idEquipment & 0xffff0000) >> 16; + } + if( i == EQUIPIVTR_BODY ) + { + pResult->stoneUpperBody = (idEquipment & 0xffff0000) >> 16; + } + if( i == EQUIPIVTR_WRIST ) + { + pResult->stoneWrist = (idEquipment & 0xffff0000) >> 16; + } + if( i == EQUIPIVTR_LEG ) + { + pResult->stoneLowerBody = (idEquipment & 0xffff0000) >> 16; + } + if( i == EQUIPIVTR_FOOT ) + { + pResult->stoneFoot = (idEquipment & 0xffff0000) >> 16; + } + idEquipment &= 0x0000ffff; + } + */ + if (pEquipmentID[i] != m_aEquips[i]) + { + m_aEquips[i] = pEquipmentID[i]; // store the current equipment id + // new equipment. Need to load and equip to host player + var equipData = elemendataman.get_data_ptr((uint)pEquipmentID[i], ID_SPACE.ID_SPACE_ESSENCE, ref DataType); + object subTypeData = null; + switch (DataType) + { + case DATA_TYPE.DT_WEAPON_ESSENCE: + var weaponData = (WEAPON_ESSENCE)equipData; + subTypeData = elemendataman.get_data_ptr((uint)weaponData.id_sub_type, ID_SPACE.ID_SPACE_ESSENCE, ref DataType); + if (subTypeData != null && DataType == DATA_TYPE.DT_WEAPON_SUB_TYPE) { - weaponObject.transform.SetParent(FindChildObjectRecursive(transform, _hh_right_hand_weapon).transform); - weaponObject.transform.localPosition = weaponPrefab.transform.localPosition; - weaponObject.transform.localRotation = weaponPrefab.transform.localRotation; - weaponObject.transform.localScale = Vector3.one; - weaponObject.SetActive(true); - _currentRightHandWeapon = weaponObject; + var subTypeDataWeapon = (WEAPON_SUB_TYPE)subTypeData; + m_uAttackType = subTypeDataWeapon.action_type; + m_ExtProps.ak.AttackRange = weaponData.attack_range; } - } + string fileModelRight = AFile.NormalizePath(weaponData.FileModelRight, true).ToLower(); + string fileModelLeft = AFile.NormalizePath(weaponData.FileModelLeft, true).ToLower(); + // BMLogger.Log($"ShowEquipments():: Weapon Essence: {fileModelRight} -- {fileModelLeft}"); - if (!string.IsNullOrEmpty(fileModelLeft)) - { - weaponPrefab = await AddressableManager.Instance.LoadPrefabAsync(fileModelLeft); - var weaponObject = Instantiate(weaponPrefab); - if (weaponObject != null) + // Destroy existing right hand weapon before creating new one + if (_currentRightHandWeapon != null) { - weaponObject.transform.SetParent(FindChildObjectRecursive(transform, _hh_left_hand_weapon).transform); - weaponObject.transform.localPosition = weaponPrefab.transform.localPosition; - weaponObject.transform.localRotation = weaponPrefab.transform.localRotation; - weaponObject.transform.localScale = Vector3.one; - weaponObject.SetActive(true); - _currentLeftHandWeapon = weaponObject; - } - } - break; - case DATA_TYPE.DT_ARMOR_ESSENCE: - var pArmor = (ARMOR_ESSENCE)equipData; - var nLocation = pArmor.equip_location; - // BMLogger.Log($"ShowEquipments():: Armor Essence: {pArmor.RealName}"); - - var armorSkinPath = _GenEquipmentSkinPath(UnityGameSession.Instance.GetRoleInfo().occupation, UnityGameSession.Instance.GetRoleInfo().gender, pArmor.RealName); - if (!armorSkinPath.EndsWith(".ecm")) - { - armorSkinPath += ".ecm"; - } - var armorPrefab = await AddressableManager.Instance.LoadPrefabAsync(armorSkinPath); - if (armorPrefab != null) - { - // Destroy existing armor for this slot before creating new one - switch (nLocation) - { - case (uint)SkinIndex.SKIN_UPPER_BODY_INDEX: - if (_currentUpperArmor != null) - { - Destroy(_currentUpperArmor); - _currentUpperArmor = null; - } - break; - case (uint)SkinIndex.SKIN_LOWER_INDEX: - if (_currentLowerArmor != null) - { - Destroy(_currentLowerArmor); - _currentLowerArmor = null; - } - break; - case (uint)SkinIndex.SKIN_WRIST_INDEX: - if (_currentWristArmor != null) - { - Destroy(_currentWristArmor); - _currentWristArmor = null; - } - break; - case (uint)SkinIndex.SKIN_FOOT_INDEX: - if (_currentFootArmor != null) - { - Destroy(_currentFootArmor); - _currentFootArmor = null; - } - break; + Destroy(_currentRightHandWeapon); + _currentRightHandWeapon = null; } - var armorObject = Instantiate(armorPrefab); - armorObject.transform.SetParent(GetSkeletonBuilder()?.transform); - armorObject.transform.localPosition = Vector3.zero; - armorObject.transform.localRotation = Quaternion.identity; - armorObject.transform.localScale = Vector3.one; - - var skinnedMeshRenderer = armorObject.GetComponent(); - var skinnedMeshRenderereFromDataList = armorObject.GetComponentsInChildren(); - foreach (var skinnedMeshRenderereFromData in skinnedMeshRenderereFromDataList) + // Destroy existing left hand weapon before creating new one + if (_currentLeftHandWeapon != null) { - if (skinnedMeshRenderereFromData != null) + Destroy(_currentLeftHandWeapon); + _currentLeftHandWeapon = null; + } + + GameObject weaponPrefab = null; + if (!string.IsNullOrEmpty(fileModelRight)) + { + weaponPrefab = await AddressableManager.Instance.LoadPrefabAsync(fileModelRight); + var weaponObject = Instantiate(weaponPrefab); + if (weaponObject != null) { - skinnedMeshRenderereFromData._skinnedMeshRenderer.bones = GetSkeletonBuilder().GetBones(skinnedMeshRenderereFromData.BoneNames); - skinnedMeshRenderereFromData._skinnedMeshRenderer.rootBone = skinnedMeshRenderereFromData._skinnedMeshRenderer.bones[^1]; + weaponObject.transform.SetParent(FindChildObjectRecursive(transform, _hh_right_hand_weapon).transform); + weaponObject.transform.localPosition = weaponPrefab.transform.localPosition; + weaponObject.transform.localRotation = weaponPrefab.transform.localRotation; + weaponObject.transform.localScale = Vector3.one; + weaponObject.SetActive(true); + _currentRightHandWeapon = weaponObject; } } - // Store the armor object for this slot - switch (nLocation) + if (!string.IsNullOrEmpty(fileModelLeft)) { - case (uint)SkinIndex.SKIN_UPPER_BODY_INDEX: - _currentUpperArmor = armorObject; - useDefaultUpper = false; - break; - case (uint)SkinIndex.SKIN_LOWER_INDEX: - _currentLowerArmor = armorObject; - useDefaultLower = false; - break; - case (uint)SkinIndex.SKIN_WRIST_INDEX: - _currentWristArmor = armorObject; - useDefaultWrist = false; - break; - case (uint)SkinIndex.SKIN_FOOT_INDEX: - _currentFootArmor = armorObject; - useDefaultFoot = false; - break; + weaponPrefab = await AddressableManager.Instance.LoadPrefabAsync(fileModelLeft); + var weaponObject = Instantiate(weaponPrefab); + if (weaponObject != null) + { + weaponObject.transform.SetParent(FindChildObjectRecursive(transform, _hh_left_hand_weapon).transform); + weaponObject.transform.localPosition = weaponPrefab.transform.localPosition; + weaponObject.transform.localRotation = weaponPrefab.transform.localRotation; + weaponObject.transform.localScale = Vector3.one; + weaponObject.SetActive(true); + _currentLeftHandWeapon = weaponObject; + } } - } - else - { - // disable/enable the default equipment - switch (nLocation) - { - case (uint)SkinIndex.SKIN_UPPER_BODY_INDEX: - useDefaultUpper = true; - break; - case (uint)SkinIndex.SKIN_LOWER_INDEX: - useDefaultLower = true; - break; - case (uint)SkinIndex.SKIN_WRIST_INDEX: - useDefaultWrist = true; - break; - case (uint)SkinIndex.SKIN_FOOT_INDEX: - useDefaultFoot = true; - break; - } - } - - break; + break; + case DATA_TYPE.DT_ARMOR_ESSENCE: + var pArmor = (ARMOR_ESSENCE)equipData; + var nLocation = pArmor.equip_location; + // BMLogger.Log($"ShowEquipments():: Armor Essence: {pArmor.RealName}"); - - default: - break; + var armorSkinPath = _GenEquipmentSkinPath(UnityGameSession.Instance.GetRoleInfo().occupation, UnityGameSession.Instance.GetRoleInfo().gender, pArmor.RealName); + if (!armorSkinPath.EndsWith(".ecm")) + { + armorSkinPath += ".ecm"; + } + var armorPrefab = await AddressableManager.Instance.LoadPrefabAsync(armorSkinPath); + if (armorPrefab != null) + { + // Destroy existing armor for this slot before creating new one + switch (nLocation) + { + case (uint)SkinIndex.SKIN_UPPER_BODY_INDEX: + if (_currentUpperArmor != null) + { + Destroy(_currentUpperArmor); + _currentUpperArmor = null; + } + break; + case (uint)SkinIndex.SKIN_LOWER_INDEX: + if (_currentLowerArmor != null) + { + Destroy(_currentLowerArmor); + _currentLowerArmor = null; + } + break; + case (uint)SkinIndex.SKIN_WRIST_INDEX: + if (_currentWristArmor != null) + { + Destroy(_currentWristArmor); + _currentWristArmor = null; + } + break; + case (uint)SkinIndex.SKIN_FOOT_INDEX: + if (_currentFootArmor != null) + { + Destroy(_currentFootArmor); + _currentFootArmor = null; + } + break; + } + + var armorObject = Instantiate(armorPrefab); + armorObject.transform.SetParent(GetSkeletonBuilder()?.transform); + armorObject.transform.localPosition = Vector3.zero; + armorObject.transform.localRotation = Quaternion.identity; + armorObject.transform.localScale = Vector3.one; + + var skinnedMeshRenderer = armorObject.GetComponent(); + var skinnedMeshRenderereFromDataList = armorObject.GetComponentsInChildren(); + foreach (var skinnedMeshRenderereFromData in skinnedMeshRenderereFromDataList) + { + if (skinnedMeshRenderereFromData != null) + { + skinnedMeshRenderereFromData._skinnedMeshRenderer.bones = GetSkeletonBuilder().GetBones(skinnedMeshRenderereFromData.BoneNames); + skinnedMeshRenderereFromData._skinnedMeshRenderer.rootBone = skinnedMeshRenderereFromData._skinnedMeshRenderer.bones[^1]; + } + } + + // Store the armor object for this slot + switch (nLocation) + { + case (uint)SkinIndex.SKIN_UPPER_BODY_INDEX: + _currentUpperArmor = armorObject; + useDefaultUpper = false; + break; + case (uint)SkinIndex.SKIN_LOWER_INDEX: + _currentLowerArmor = armorObject; + useDefaultLower = false; + break; + case (uint)SkinIndex.SKIN_WRIST_INDEX: + _currentWristArmor = armorObject; + useDefaultWrist = false; + break; + case (uint)SkinIndex.SKIN_FOOT_INDEX: + _currentFootArmor = armorObject; + useDefaultFoot = false; + break; + } + } + else + { + // disable/enable the default equipment + switch (nLocation) + { + case (uint)SkinIndex.SKIN_UPPER_BODY_INDEX: + useDefaultUpper = true; + break; + case (uint)SkinIndex.SKIN_LOWER_INDEX: + useDefaultLower = true; + break; + case (uint)SkinIndex.SKIN_WRIST_INDEX: + useDefaultWrist = true; + break; + case (uint)SkinIndex.SKIN_FOOT_INDEX: + useDefaultFoot = true; + break; + } + } + + break; + + + default: + break; + } } - } - - if (m_aEquips[i] == 0) - { - switch (i) + + if (m_aEquips[i] == 0) { - case InventoryConst.EQUIPIVTR_WEAPON: - // Destroy weapons when weapon slot is empty - if (_currentRightHandWeapon != null) - { - Destroy(_currentRightHandWeapon); - _currentRightHandWeapon = null; - } - if (_currentLeftHandWeapon != null) - { - Destroy(_currentLeftHandWeapon); - _currentLeftHandWeapon = null; - } - break; - case InventoryConst.EQUIPIVTR_BODY: - useDefaultUpper = true; - break; - case InventoryConst.EQUIPIVTR_LEG: - useDefaultLower = true; - break; - case InventoryConst.EQUIPIVTR_WRIST: - useDefaultWrist = true; - break; - case InventoryConst.EQUIPIVTR_FOOT: - useDefaultFoot = true; - break; + switch (i) + { + case InventoryConst.EQUIPIVTR_WEAPON: + // Destroy weapons when weapon slot is empty + if (_currentRightHandWeapon != null) + { + Destroy(_currentRightHandWeapon); + _currentRightHandWeapon = null; + } + if (_currentLeftHandWeapon != null) + { + Destroy(_currentLeftHandWeapon); + _currentLeftHandWeapon = null; + } + break; + case InventoryConst.EQUIPIVTR_BODY: + useDefaultUpper = true; + break; + case InventoryConst.EQUIPIVTR_LEG: + useDefaultLower = true; + break; + case InventoryConst.EQUIPIVTR_WRIST: + useDefaultWrist = true; + break; + case InventoryConst.EQUIPIVTR_FOOT: + useDefaultFoot = true; + break; + } } } + + // enable/disable the default equipment + // If using default, destroy non-default equipment if it exists + if (useDefaultUpper) + { + if (_currentUpperArmor != null) + { + Destroy(_currentUpperArmor); + _currentUpperArmor = null; + } + } + PlayerDefaultEquipments.DefaultUpper.SetActive(useDefaultUpper); + + if (useDefaultLower) + { + if (_currentLowerArmor != null) + { + Destroy(_currentLowerArmor); + _currentLowerArmor = null; + } + } + PlayerDefaultEquipments.DefaultLower.SetActive(useDefaultLower); + + if (useDefaultWrist) + { + if (_currentWristArmor != null) + { + Destroy(_currentWristArmor); + _currentWristArmor = null; + } + } + PlayerDefaultEquipments.DefaultWirst.SetActive(useDefaultWrist); + + if (useDefaultFoot) + { + if (_currentFootArmor != null) + { + Destroy(_currentFootArmor); + _currentFootArmor = null; + } + } + PlayerDefaultEquipments.DefaultFoot.SetActive(useDefaultFoot); } - // enable/disable the default equipment - // If using default, destroy non-default equipment if it exists - if (useDefaultUpper) + #region Helper Methods + private GameObject FindChildObjectRecursive(Transform parent, string name) { - if (_currentUpperArmor != null) + foreach (Transform child in parent) { - Destroy(_currentUpperArmor); - _currentUpperArmor = null; + if (child.name == name) + { + return child.gameObject; + } + var childObject = FindChildObjectRecursive(child, name); + if (childObject != null) + { + return childObject; + } } + return null; } - PlayerDefaultEquipments.DefaultUpper.SetActive(useDefaultUpper); - - if (useDefaultLower) + + private SkeletonBuilder GetSkeletonBuilder() { - if (_currentLowerArmor != null) + if (_skeletonBuilder == null) { - Destroy(_currentLowerArmor); - _currentLowerArmor = null; + _skeletonBuilder = GetComponentInChildren(); } + return _skeletonBuilder; } - PlayerDefaultEquipments.DefaultLower.SetActive(useDefaultLower); - - if (useDefaultWrist) + #endregion + + + + public static string _GenEquipmentSkinPath(int nProfession, int nGender, string szSkinName) { - if (_currentWristArmor != null) - { - Destroy(_currentWristArmor); - _currentWristArmor = null; - } + return string.Format(_equipment_skin[nProfession * NUM_GENDER + nGender], szSkinName, szSkinName); } - PlayerDefaultEquipments.DefaultWirst.SetActive(useDefaultWrist); - - if (useDefaultFoot) - { - if (_currentFootArmor != null) - { - Destroy(_currentFootArmor); - _currentFootArmor = null; - } - } - PlayerDefaultEquipments.DefaultFoot.SetActive(useDefaultFoot); } - - #region Helper Methods - private GameObject FindChildObjectRecursive(Transform parent, string name) - { - foreach (Transform child in parent) - { - if (child.name == name) - { - return child.gameObject; - } - var childObject = FindChildObjectRecursive(child, name); - if (childObject != null) - { - return childObject; - } - } - return null; - } - - private SkeletonBuilder GetSkeletonBuilder() - { - if (_skeletonBuilder == null) - { - _skeletonBuilder = GetComponentInChildren(); - } - return _skeletonBuilder; - } - #endregion - - - - public static string _GenEquipmentSkinPath(int nProfession, int nGender, string szSkinName) - { - return string.Format(_equipment_skin[nProfession * NUM_GENDER + nGender], szSkinName, szSkinName); - } -} +} \ No newline at end of file diff --git a/Assets/Scripts/EC_Utility.cs b/Assets/Scripts/EC_Utility.cs index 0884e95d8f..86defb2e9a 100644 --- a/Assets/Scripts/EC_Utility.cs +++ b/Assets/Scripts/EC_Utility.cs @@ -9,7 +9,6 @@ using System.Runtime.InteropServices; using System.Text; using System.Text.RegularExpressions; using UnityEngine; -using static CECPlayer; public static class EC_Utility { diff --git a/Assets/Scripts/PlayerVisual.cs b/Assets/Scripts/PlayerVisual.cs index 6b75da9b3d..d8c7bd7ddd 100644 --- a/Assets/Scripts/PlayerVisual.cs +++ b/Assets/Scripts/PlayerVisual.cs @@ -5,163 +5,165 @@ using System.Collections; using System.Collections.Generic; using System.Linq; using UnityEngine; -using static CECPlayer; -public class PlayerVisual : MonoBehaviour +namespace BrewMonster { - [SerializeField] NamedAnimancerComponent namedAnimancer; - - [SerializeField] private INFO _playerInfo; - private Dictionary _activeStates = new(); - [SerializeField] private AnimancerState _currentState; - [SerializeField] private Queue _animationQueue = new Queue(); - [SerializeField] private List _animationList = new List(); - [SerializeField] private bool isHit; - [SerializeField] private int id; - - private const float FadeTime = 0.1f; - private const FadeMode FadeMode = Animancer.FadeMode.FixedDuration; - QueueActionEvent queueActionEvent; - - private void PlayActionEventHandler(PlayActionEvent @event) + public class PlayerVisual : MonoBehaviour { - if (_animationQueue.Count > 0) + [SerializeField] NamedAnimancerComponent namedAnimancer; + + [SerializeField] private INFO _playerInfo; + private Dictionary _activeStates = new(); + [SerializeField] private AnimancerState _currentState; + [SerializeField] private Queue _animationQueue = new Queue(); + [SerializeField] private List _animationList = new List(); + [SerializeField] private bool isHit; + [SerializeField] private int id; + + private const float FadeTime = 0.1f; + private const FadeMode FadeMode = Animancer.FadeMode.FixedDuration; + QueueActionEvent queueActionEvent; + + private void PlayActionEventHandler(PlayActionEvent @event) { - _animationQueue.Enqueue(@event.AnimationName); - return; + if (_animationQueue.Count > 0) + { + _animationQueue.Enqueue(@event.AnimationName); + return; + } + InternalPlayAnimation(@event.AnimationName); } - InternalPlayAnimation(@event.AnimationName); - } - public void InitPlayerEventDoneHandler() - { - namedAnimancer = GetComponentInChildren(); - if (namedAnimancer == null) + public void InitPlayerEventDoneHandler() { - BrewMonster.BMLogger.LogWarning("InitPlayerEventDoneHandler animancer == null"); - return; - } - var player = GetComponentInParent(); - if (player == null) - { - BMLogger.LogWarning("player == null"); - return; + namedAnimancer = GetComponentInChildren(); + if (namedAnimancer == null) + { + BrewMonster.BMLogger.LogWarning("InitPlayerEventDoneHandler animancer == null"); + return; + } + var player = GetComponentInParent(); + if (player == null) + { + BMLogger.LogWarning("player == null"); + return; + } + + _playerInfo = player.GetPlayInfo(); + id = _playerInfo.cid; + EventBus.SubscribeChannel(_playerInfo.cid, PlayActionEventHandler); + EventBus.SubscribeChannelClass(_playerInfo.cid, QueueActionEventHandler); + EventBus.SubscribeChannel(_playerInfo.cid, ClearComActFlagAllRankNodesEventHandler); } - _playerInfo = player.GetPlayInfo(); - id = _playerInfo.cid; - EventBus.SubscribeChannel(_playerInfo.cid, PlayActionEventHandler); - EventBus.SubscribeChannelClass(_playerInfo.cid, QueueActionEventHandler); - EventBus.SubscribeChannel(_playerInfo.cid, ClearComActFlagAllRankNodesEventHandler); - } - - // public void InitElsePlayerEventDoneHandler(INFO playerInfo) - // { - // namedAnimancer = GetComponentInChildren(); - // if (namedAnimancer == null) - // { - // BrewMonster.BMLogger.LogError("animancer == null"); - // return; - // } - // //var player = GetComponentInParent(); - // //if (player == null) - // //{ - // // BrewMonster.BMLogger.LogError("player == null"); - // // return; - // //} - // _playerInfo = playerInfo;//player.GetPlayInfo(); - // EventBus.SubscribeChannel(_playerInfo.cid, PlayActionEventHandler); - // EventBus.SubscribeChannelClass(_playerInfo.cid, QueueActionEventHandler); - // EventBus.SubscribeChannel(_playerInfo.cid, CleearComActFlagAllRankNodesEventHandler); - // } - - private void ClearComActFlagAllRankNodesEventHandler(ClearComActFlagAllRankNodesEvent @event) - { - _animationQueue.Clear(); - _animationList = _animationQueue.ToList(); - if (isHit) - { - ApplyDamage(); - } - //todo: this is dummy to force change to idle state - // EventBus.PublishChannel(_playerInfo.cid, new PlayActionEvent("站立_通用")); - } - - private void QueueActionEventHandler(QueueActionEvent @event) - { - if (!EnqueueAnimation(@event)) - { - BMLogger.LogError("HoangDev : EnqueueAnimation Failed"); - } - } - private void Update() - { - PlayNext(); - } - public bool EnqueueAnimation(QueueActionEvent @event) - { - if (namedAnimancer == null) return false; - _animationQueue.Enqueue(@event.AnimationName); - _animationList = _animationQueue.ToList(); - - if (!isHit) - { - queueActionEvent = @event; - isHit = @event.IsHitAnim; - } - return true; - } - private void PlayNext() - { - if (_animationQueue.Count == 0) - { - return; - } - - // if (_currentState == null) + // public void InitElsePlayerEventDoneHandler(INFO playerInfo) // { - // _animationQueue.Dequeue(); - // return; + // namedAnimancer = GetComponentInChildren(); + // if (namedAnimancer == null) + // { + // BrewMonster.BMLogger.LogError("animancer == null"); + // return; + // } + // //var player = GetComponentInParent(); + // //if (player == null) + // //{ + // // BrewMonster.BMLogger.LogError("player == null"); + // // return; + // //} + // _playerInfo = playerInfo;//player.GetPlayInfo(); + // EventBus.SubscribeChannel(_playerInfo.cid, PlayActionEventHandler); + // EventBus.SubscribeChannelClass(_playerInfo.cid, QueueActionEventHandler); + // EventBus.SubscribeChannel(_playerInfo.cid, CleearComActFlagAllRankNodesEventHandler); // } - if (_currentState!=null && _currentState.NormalizedTime < 1f) return; - if (isHit)// have it relative to check _currentState == null? - { - ApplyDamage(); - } - string animName = _animationQueue.Dequeue(); - _animationList = _animationQueue.ToList(); - InternalPlayAnimation(animName); - } - void ApplyDamage() - { - if(queueActionEvent == null) return; - isHit = false; - queueActionEvent.SetFlag(true, queueActionEvent.AttackEvent); - queueActionEvent = null; - } - private void OnDestroy() - { - EventBus.UnsubscribeChannel(_playerInfo.cid, PlayActionEventHandler); - EventBus.UnsubscribeChannelClass(_playerInfo.cid, QueueActionEventHandler); - EventBus.UnsubscribeChannel(_playerInfo.cid, ClearComActFlagAllRankNodesEventHandler); - // EventBus.UnsubscribeAllInChannel(_playerInfo.cid); - } - public bool IsAnimationExist(string animationName) - { - return namedAnimancer.States.TryGet("ActionName", out var existingState) ? true : false; - } - /// - /// play an animation with name - /// - /// - /// - /// - private void InternalPlayAnimation(string animationName, float duration = FadeTime, FadeMode fadeMode = FadeMode) - { - _currentState = namedAnimancer.TryPlay(animationName, duration, fadeMode); - if (_currentState == null) + private void ClearComActFlagAllRankNodesEventHandler(ClearComActFlagAllRankNodesEvent @event) { - BMLogger.LogError($"Null animation with name: {animationName}"); + _animationQueue.Clear(); + _animationList = _animationQueue.ToList(); + if (isHit) + { + ApplyDamage(); + } + //todo: this is dummy to force change to idle state + // EventBus.PublishChannel(_playerInfo.cid, new PlayActionEvent("站立_通用")); + } + + private void QueueActionEventHandler(QueueActionEvent @event) + { + if (!EnqueueAnimation(@event)) + { + BMLogger.LogError("HoangDev : EnqueueAnimation Failed"); + } + } + private void Update() + { + PlayNext(); + } + public bool EnqueueAnimation(QueueActionEvent @event) + { + if (namedAnimancer == null) return false; + _animationQueue.Enqueue(@event.AnimationName); + _animationList = _animationQueue.ToList(); + + if (!isHit) + { + queueActionEvent = @event; + isHit = @event.IsHitAnim; + } + return true; + } + private void PlayNext() + { + if (_animationQueue.Count == 0) + { + return; + } + + // if (_currentState == null) + // { + // _animationQueue.Dequeue(); + // return; + // } + if (_currentState != null && _currentState.NormalizedTime < 1f) return; + if (isHit)// have it relative to check _currentState == null? + { + ApplyDamage(); + } + string animName = _animationQueue.Dequeue(); + _animationList = _animationQueue.ToList(); + InternalPlayAnimation(animName); + } + void ApplyDamage() + { + if (queueActionEvent == null) return; + isHit = false; + queueActionEvent.SetFlag(true, queueActionEvent.AttackEvent); + queueActionEvent = null; + } + private void OnDestroy() + { + EventBus.UnsubscribeChannel(_playerInfo.cid, PlayActionEventHandler); + EventBus.UnsubscribeChannelClass(_playerInfo.cid, QueueActionEventHandler); + EventBus.UnsubscribeChannel(_playerInfo.cid, ClearComActFlagAllRankNodesEventHandler); + // EventBus.UnsubscribeAllInChannel(_playerInfo.cid); + } + public bool IsAnimationExist(string animationName) + { + return namedAnimancer.States.TryGet("ActionName", out var existingState) ? true : false; + } + + /// + /// play an animation with name + /// + /// + /// + /// + private void InternalPlayAnimation(string animationName, float duration = FadeTime, FadeMode fadeMode = FadeMode) + { + _currentState = namedAnimancer.TryPlay(animationName, duration, fadeMode); + if (_currentState == null) + { + BMLogger.LogError($"Null animation with name: {animationName}"); + } } } -} +} \ No newline at end of file