From 98ff6a50a89cd1cba14c6874ff94ec87c2128f0f Mon Sep 17 00:00:00 2001 From: Tungdv Date: Wed, 1 Oct 2025 17:42:43 +0700 Subject: [PATCH] fix: Update logic normal attack. --- .../Scripts/Managers/EC_HPWork.cs | 8 +- .../Scripts/Managers/EC_HPWorkMove.cs | 276 +++++++++++++++--- .../Scripts/Managers/EC_HPWorkTrace.cs | 251 ++++++++++++++++ .../Scripts/Managers/EC_HPWorkTrace.cs.meta | 2 + .../Scripts/Managers/EC_ObjectWork.cs | 2 +- Assets/Scripts/CECHostPlayer.cs | 30 ++ 6 files changed, 530 insertions(+), 39 deletions(-) create mode 100644 Assets/PerfectWorld/Scripts/Managers/EC_HPWorkTrace.cs create mode 100644 Assets/PerfectWorld/Scripts/Managers/EC_HPWorkTrace.cs.meta diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_HPWork.cs b/Assets/PerfectWorld/Scripts/Managers/EC_HPWork.cs index e28ff3381f..08246cd78d 100644 --- a/Assets/PerfectWorld/Scripts/Managers/EC_HPWork.cs +++ b/Assets/PerfectWorld/Scripts/Managers/EC_HPWork.cs @@ -62,7 +62,7 @@ public class CECHPWork : CECObjectWork public CECHPWork(int iWorkID, CECHPWorkMan pWorkMan) : base(iWorkID) { m_pWorkMan = pWorkMan; - m_pHost = pWorkMan.GetHostPlayer(); + //m_pHost = pWorkMan.GetHostPlayer(); } // Operations @@ -361,11 +361,11 @@ public class CECHPWorkMan if (pWork.GetWorkID() == CECHPWork.Host_work_ID.WORK_MOVETOPOS) { CECHPWorkMove pWorkMove = pWork as CECHPWorkMove; - if (pWorkMove) + if (pWorkMove != null) { if (pWorkMove.GetAutoMove()) { - pWorkMove.Finish(); + //pWorkMove.Finish(); } else { @@ -390,7 +390,7 @@ public class CECHPWorkMan bool DelayWork(int iPriority, CECHPWork pWork) { - + return false; } void StartDelayedWork() { diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_HPWorkMove.cs b/Assets/PerfectWorld/Scripts/Managers/EC_HPWorkMove.cs index a3884625bc..318949b4b4 100644 --- a/Assets/PerfectWorld/Scripts/Managers/EC_HPWorkMove.cs +++ b/Assets/PerfectWorld/Scripts/Managers/EC_HPWorkMove.cs @@ -89,26 +89,28 @@ public class CECHPWorkMove : CECHPWork } else if (IsAutoPF()) { - m_vCurDir = CECIntelligentRoute::Instance().GetCurDest() - m_pHost->GetPos(); - m_vCurDir.y = 0.0f; - m_vCurDir.Normalize(); - if (m_bUseAutoMoveDialog) - { - // 此处禁用 m_bUseAutoMoveDialog,见 SetUseAutoMoveDialog 中说明 - m_bUseAutoMoveDialog = false; - m_bAutoLand = false; - m_fAutoHeight = -1.0f; - m_bAutoFly = false; - m_bReachedHeight = true; - m_bAutoFlyPending = false; - } + // TO DO: fix later + //m_vCurDir = CECIntelligentRoute::Instance().GetCurDest() - m_pHost->GetPos(); + //m_vCurDir.y = 0.0f; + //m_vCurDir.Normalize(); + //if (m_bUseAutoMoveDialog) + //{ + // // 此处禁用 m_bUseAutoMoveDialog,见 SetUseAutoMoveDialog 中说明 + // m_bUseAutoMoveDialog = false; + // m_bAutoLand = false; + // m_fAutoHeight = -1.0f; + // m_bAutoFly = false; + // m_bReachedHeight = true; + // m_bAutoFlyPending = false; + //} } - if (m_pHost.m_pMoveTargetGFX) - { - if (iDestType != DEST_PUSH) - m_pHost.m_pMoveTargetGFX.Stop(); - } + // TO DO: fix later + //if (m_pHost.m_pMoveTargetGFX) + //{ + // if (iDestType != DEST_PUSH) + // m_pHost.m_pMoveTargetGFX.Stop(); + //} } void ResetUseAutoPF() @@ -117,43 +119,249 @@ public class CECHPWorkMove : CECHPWork } // Tick routine - virtual bool Tick(uint dwDeltaTime) + public virtual bool Tick(float dwDeltaTime) + { + //UpdateResetUseAutoPF(); + //if (m_bSwitchTo2D) + //{ + // SwitchToDest2D(); + // m_bSwitchTo2D = false; + // return true; + //} + //if (IsAutoPF()) + //{ + // if (CECIntelligentRoute::Instance().IsIdle()) + // { + // // 智能寻路模式未成功时,等待下个 Tick 切换到 DEST_2D 模式 + // return true; + // } + // if (m_pHost.IsFlying()) + // { + // // 中途切换到飞行模式时,切换到 DEST_2D 模式 + // CECIntelligentRoute::Instance().ResetSearch(); + // m_bSwitchTo2D = true; + // return true; + // } + //} + + //base.Tick(dwDeltaTime); + + //if (m_pHost.IsRooting()) + // return true; + + //if (m_bUseAutoMoveDialog) + //{ + // if (m_pHost.IsFlying()) + // { + // m_bAutoFly = false; + // m_bAutoFlyPending = false; + // } + + // if (m_bAutoFly && !m_bAutoFlyPending && !m_pHost.IsFlying()) + // { + // if (m_pHost.CmdFly()) + // { + // m_bAutoFly = false; + // m_bAutoFlyPending = true; + // } + // } + //} + //else + //{ + // // Make sure 'Win_AutoPlay' dialog doesn't show up + // CECGameUIMan pGameUI = g_pGame.GetGameRun().GetUIManager().GetInGameUIMan(); + // pGameUI.AutoMoveShowDialog(false); + //} + + ////寻路过程中找到NPC对象转为WorkTrace状态 + //if ((m_vMoveDest - m_pHost.GetPos()).MagnitudeH() <= 5.0f) + //{ + // if (m_iNPCTempleId) + // { + // CECNPC pNPC = g_pGame.GetGameRun().GetWorld().GetNPCMan().FindNPCByTempleID(m_iNPCTempleId); + // if (pNPC && m_pHost.SelectTarget(pNPC->GetNPCID())) + // { + // CECHPWorkTrace pWork = m_pWorkMan.CreateNPCTraceWork(pNPC, m_iTaskId); + // if (pWork) + // { + // m_bAutoLand = false; //防止飞行状态寻路结束,转到worktrace之前自动着陆,进入workfall。 + // Finish(); + // m_pWorkMan.SetPostTickCommand(new CECHPWorkPostTickRunWorkCommand(pWork, true)); + // return true; + // } + // } + // } + //} + + //float fDeltaTime = dwDeltaTime; + //if (m_pHost.m_iMoveEnv == CECPlayer::MOVEENV_GROUND || + // m_pHost.m_iMoveEnv == CECPlayer::MOVEENV_WATER && m_pHost.IsJumping() && (m_pHost.m_CDRInfo.vAbsVelocity.y > 0 || m_pHost.m_CDRInfo.fYVel > 0)) + //{ + // // Play appropriate actions + // if (!m_pHost.IsJumping() && !m_pHost.IsPlayingAction(CECPlayer::ACT_TRICK_RUN) && + // m_pHost.m_iMoveMode != CECPlayer::MOVE_SLIDE && !m_bMeetSlide) + // { + // int iAction = m_pHost->GetMoveStandAction(true); + // m_pHost.PlayAction(iAction, false); + // } + + // Tick_Walk(fDeltaTime); + //} + //else // (m_pHost->m_iMoveEnv == CECPlayer::MOVEENV_AIR || m_pHost->m_iMoveEnv == CECPlayer::MOVEENV_WATER) + //{ + // m_pHost->ResetJump(); + + // // Play appropriate actions + // if (!m_bGliding) + // { + // int iAction = m_pHost.GetMoveStandAction(true); + // m_pHost.PlayAction(iAction, false); + // } + + // Tick_FlySwim(fDeltaTime); + //} + + return true; + } + // Reset work + public virtual void Reset() { } - // Reset work - virtual void Reset(); // Work is cancel - virtual void Cancel(); + public virtual void Cancel() + { + + } // This work is do player moving ? - virtual bool IsMoving() { return true; } + public virtual bool IsMoving() { return true; } // Copy work data - virtual bool CopyData(CECHPWork* pWork); + public virtual bool CopyData(CECHPWork pWork) + { + return true; + } // Play move target effect - void PlayMoveTargetGFX(const A3DVECTOR3& vPos, const A3DVECTOR3& vNormal); + public void PlayMoveTargetGFX(A3DVECTOR3 vPos, A3DVECTOR3 vNormal) + { + + } // User press cancel button - void PressCancel() { m_bReadyCancel = true; } + public void PressCancel() { m_bReadyCancel = true; } - void SetUseAutoMoveDialog(bool bUseAutoMoveDialog); - bool GetUseAutoMoveDialog() { return m_bUseAutoMoveDialog; } - bool GetAutoMove(); + public void SetUseAutoMoveDialog(bool bUseAutoMoveDialog) + { + + } + public bool GetUseAutoMoveDialog() { return m_bUseAutoMoveDialog; } + public bool GetAutoMove() + { + return true; + } void SetAutoLand(bool bAutoLand) { m_bAutoLand = bAutoLand; } bool GetAutoLand() { return m_bAutoLand; } void SetAutoHeight(float fHeight) { m_fAutoHeight = fHeight; m_bAutoFly = true; m_bReachedHeight = false; } float GetAutoHeight() { return m_fAutoHeight; } - bool IsAutoFly() const { return m_bAutoFly;} + bool IsAutoFly() { return m_bAutoFly;} -bool IsAutoPF()const{ return m_iDestType == DEST_AUTOPF; } + bool IsAutoPF(){ return m_iDestType == Types.DEST_AUTOPF; } // Finish work - void Finish(); + void Finish() + { -void SetTaskNPCInfo(int tid, int taskid); + } + + void SetTaskNPCInfo(int tid, int taskid) + { + + } + + void SwitchToDest2D() + { + //int tid, taskid; + //tid = m_iNPCTempleId; + //taskid = m_iTaskId; + //CECGameUIMan* pGameUI = g_pGame->GetGameRun()->GetUIManager()->GetInGameUIMan(); + //pGameUI->SetAutoMoveShowDialogTarget((int)m_vMoveDest.x, (int)m_vMoveDest.z); + //SetDestination(CECHPWorkMove::DEST_2D, m_vMoveDest); + //SetTaskNPCInfo(tid, taskid); + //SetUseAutoMoveDialog(true); + } + // On first tick + protected virtual void OnFirstTick() + { + + } + + // Tick routine of walking on ground + protected bool Tick_Walk(float fDeltaTime) + { + return true; + } + // Tick routine of flying or swimming + protected bool Tick_FlySwim(float fDeltaTime) + { + return true; + } + // Start gliding + protected void Glide(float fMoveTime, A3DVECTOR3 vMoveDirH, float fDeltaTime, bool bFly) + { + + } + + // Calculate vertical speed when fly or swim + protected float CalcFlySwimVertSpeed(float fSpeed1, float fPushDir, float fPushAccel, float fDeltaTime) + { + return 0; + } + + protected void ClearResetUseAutoPF() + { + + } + protected void UpdateResetUseAutoPF() + { +// if (!m_bResetAutoPF) +// { +// return; +// } +// CECIntelligentRoute::Instance().SetUsage(CECIntelligentRoute::enumUsageWorkMove); +// CECIntelligentRoute::Instance().ResetSearch(); +// if (m_iDestType == DEST_2D || m_iDestType == DEST_3D) +// { +//# ifdef SHOW_AUTOMOVE_FOOTPRINTS +// g_AutoPFFollowPoints.clear(); +// g_AutoPFPathPoints.clear(); +//#endif +// } +// else if (IsAutoPF()) +// { +// bool bSwitchTo2D(true); +// while (true) +// { +// if (m_pHost->IsFlying()) +// { +// break; +// } +// CECHostBrushTest brushTester(m_pHost->GetPos(), m_pHost->m_CDRInfo.vExtent, m_pHost->m_CDRInfo.fStepHeight); +// if (CECIntelligentRoute::Instance().Search(m_pHost->GetPos(), m_vMoveDest, &brushTester) != CECIntelligentRoute::enumSearchSuccess) +// { +// break; +// } +// bSwitchTo2D = false; +// break; +// } +// if (bSwitchTo2D) +// { +// m_bSwitchTo2D = true; +// } +// } +// ClearResetUseAutoPF(); + } -void SwitchToDest2D(); } diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_HPWorkTrace.cs b/Assets/PerfectWorld/Scripts/Managers/EC_HPWorkTrace.cs new file mode 100644 index 0000000000..3581d786d9 --- /dev/null +++ b/Assets/PerfectWorld/Scripts/Managers/EC_HPWorkTrace.cs @@ -0,0 +1,251 @@ +using CSNetwork.GPDataType; +using UnityEditor.Rendering; + +/////////////////////////////////////////////////////////////////////////// +// +// Class CECHPWorkTrace +// +/////////////////////////////////////////////////////////////////////////// + +enum TraceObjectType +{ + TRACE_NONE = 0, + TRACE_PLAYER, + TRACE_MATTER, + TRACE_NPC, + TRACE_TASKNPC +}; + +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) + { + 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 abstract bool OnTargetMissing(); + public abstract A3DVECTOR3 GetTargetPos(); + public abstract bool OnTouched(); + public abstract CECTracedObject Clone(); + + // TO DO: fix later + public virtual bool IsTargetMissing() + { + //if (m_iObjectId != 0) + //{ + // CECObject pObj = g_pGame->GetGameRun()->GetWorld()->GetObject(m_iObjectId, 0); + // if (pObj) + // { + // return false; + // } + //} + //return true; + return false; + } + // TO DO: fix later + //public virtual A3DVECTOR3 GetMovePos(); + + 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) + { + 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 = g_pGame->GetGameRun()->GetWorld()->GetObject(m_iObjectId, 0); + + float fTouchRadius = 0.0f; + if (ISPLAYERID(m_iObjectId)) + { + if (m_iReason == CECHPWorkTrace.Trace_reason.TRACE_TALK) + { + fTouchRadius = 0.0f; + } + else + { + CECPlayer pPlayer = pObject as CECPlayer; + fTouchRadius = pPlayer.GetTouchRadius(); + } + return m_pHost.CanTouchTarget(vHostPos, vTargetPos, fTouchRadius, iTouchReason, fMaxCut); + } + else if (ISNPCID(m_iObjectId)) + { + CECNPC pNPC = pObject as CECNPC; + fTouchRadius = pNPC.GetTouchRadius(); + return m_pHost.CanTouchTarget(vHostPos, vTargetPos, fTouchRadius, iTouchReason, fMaxCut); + } + else if (ISMATTERID(m_iObjectId)) + { + CECMatter pMatter = (pObject) as CECMatter; + return pMatter.CalcDist(vHostPos, true) < pMatter.GetGatherDist(); + } + break; + } + return false; + } + public int GetTraceType(); + public CECObject GetTargetObject(); +}; + + +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) + { + + } +public: // Attributes + +public: // Operations + + // Change trace target + //void ChangeTarget(int idTarget, int iReason, bool bUseAutoPF=false); + // 设定traceobject + public void SetTraceTarget(CECTracedObject pTraceObj, bool bUseAutoPF = false) + { + + } + +CECTracedObject* CreatTraceTarget(int iTraceObjId, int iReason, bool bForceAttack = false); + +// Tick routine +virtual bool Tick(DWORD dwDeltaTime); +// Reset work +virtual void Reset(); +// Work is cancel +virtual void Cancel(); + +// This work is do player moving ? +virtual bool IsMoving() { return true; } +// Copy work data +virtual bool CopyData(CECHPWork* pWork); + +// User press cancel button +void PressCancel(); +// Set move close flag +void SetMoveCloseFlag(bool bMoveClose) { m_pTraceObject->SetMoveCloseFlag(bMoveClose); } + +// Set / Get force attack flag +void SetForceAttack(bool bTrue) { m_bForceAttack = bTrue; } +bool GetForceAttack() { return m_bForceAttack; } +// Set / Get prepared skill +void SetPrepSkill(CECSkill* pSkill) { m_pPrepSkill = pSkill; } +CECSkill* GetPrepSkill() { return m_pPrepSkill; } +// Get target ID +int GetTarget() { return m_pTraceObject->GetObjectID(); } +// Get trace reason +int GetTraceReason() { return m_pTraceObject->GetTraceReason(); } +// AutoPF +void SetUseAutoPF(bool bUse); +bool GetUseAutoPF()const; +bool IsAutoPF()const; + +void SetActionDone(bool bActionDone) { m_bActionDone = bActionDone; } + +void OnTargetMissing(); + +void OnTouchTarget(); +bool CanTouch(); + +protected: // Attributes + + bool m_bHaveMoved; // Have moved flag +bool m_bMeetSlide; // true, meet slide +bool m_bCheckTouch; // Check whether touch target in this frame +A3DVECTOR3 m_vCurDirH; // Current move direction +bool m_bReadyCancel; // true, ready to cancel +bool m_bMoreClose; // Move close flag +bool m_bForceAttack; // Force attack flag +CECSkill* m_pPrepSkill; // Skill prepared to be casted +bool m_bActionDone; // 目标行为成功发出 +bool m_bShouldResetUseAutoPF; +bool m_bUseAutoPFResetValue; +bool m_bUseAutoPF; // Use CECIntelligentRoute::Search +DWORD m_dwAutoPFNextCheckTime; // 下次检查时间 + +CECTracedObject* m_pTraceObject; // 定义trace目标对象 + +protected: // Operations + + // On first tick + virtual void OnFirstTick(); + +// Trace on ground +bool Trace_Walk(float fDeltaTime); +// Trace in air and water +bool Trace_FlySwim(float fDeltaTime); + +// Stop move when touch target +void StopMove(bool bFinish); +// Handle the case that target died when host is tracing it +bool OnTargetDied(CECObject* pTarget); +// Is valid time to touch target ? +bool IsGoodTimeToTouch(); +// Check prepare skill +void CheckPrepSkill(); +bool GetTargetCurPos(A3DVECTOR3 &pos); +A3DVECTOR3 GetCurMovingDest(); +void UpdateUseAutoPF(); + +void ReplaceTarget(CECTracedObject* ptraceobj); + +void ResetUseAutoPF(bool bUseAutoPF); +void UpdateResetUseAutoPF(); +void ClearResetUseAutoPF(); +}; \ No newline at end of file diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_HPWorkTrace.cs.meta b/Assets/PerfectWorld/Scripts/Managers/EC_HPWorkTrace.cs.meta new file mode 100644 index 0000000000..fa9daf2a66 --- /dev/null +++ b/Assets/PerfectWorld/Scripts/Managers/EC_HPWorkTrace.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 8cd5ac42b14a07f459a8c68c35d38af6 \ No newline at end of file diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_ObjectWork.cs b/Assets/PerfectWorld/Scripts/Managers/EC_ObjectWork.cs index 3b7c92e2a0..77a4e6cde8 100644 --- a/Assets/PerfectWorld/Scripts/Managers/EC_ObjectWork.cs +++ b/Assets/PerfectWorld/Scripts/Managers/EC_ObjectWork.cs @@ -18,7 +18,7 @@ public class CECObjectWork m_bFinished = true; } - public virtual bool Tick(uint dwDeltaTime) + public virtual bool Tick(float dwDeltaTime) { if (m_bFirstTick) { diff --git a/Assets/Scripts/CECHostPlayer.cs b/Assets/Scripts/CECHostPlayer.cs index 9a3c99f325..ac6c1ec344 100644 --- a/Assets/Scripts/CECHostPlayer.cs +++ b/Assets/Scripts/CECHostPlayer.cs @@ -479,6 +479,36 @@ public class CECHostPlayer : EC_Player //CECPlayerWrapper* pWrapper = CECAutoPolicy::GetInstance().GetPlayerWrapper(); //if (CECAutoPolicy::GetInstance().IsAutoPolicyEnabled() && pWrapper->GetAttackError() >= 2) bUseAutoPF = true; + + CECHPWorkTrace pWorkTrace = null; + CECHPWork pWork = null; + if (pWork = m_pWorkMan.GetWork(CECHPWork.Host_work_ID.WORK_TRACEOBJECT)) + { + pWorkTrace = pWork as CECHPWorkTrace; + } + else if (pWork = m_pWorkMan.GetWork(CECHPWork.Host_work_ID.WORK_HACKOBJECT)) + { + if ((pWork as CECHPWorkMelee).GetTarget() == idTarget) + return false; // Host is attacking the target + + pWorkTrace = (CECHPWorkTrace)m_pWorkMan.CreateWork(CECHPWork.Host_work_ID.WORK_TRACEOBJECT); + bStartNewWork = true; + } + else if (m_pWorkMan.CanStartWork(CECHPWork.Host_work_ID.WORK_TRACEOBJECT)) + { + pWorkTrace = (CECHPWorkTrace)m_pWorkMan.CreateWork(CECHPWork.Host_work_ID.WORK_TRACEOBJECT); + bStartNewWork = true; + } + + if (pWorkTrace) + { + pWorkTrace.SetTraceTarget(pWorkTrace.CreatTraceTarget(idTarget, CECHPWorkTrace.Trace_reason.TRACE_ATTACK, bForceAttack), bUseAutoPF); + pWorkTrace.SetMoveCloseFlag(bMoreClose); + + if (bStartNewWork) + m_pWorkMan.StartWork_p1(pWorkTrace); + return true; + } return false; } }