From 752d2cd69ef18db5ef53c48cf4e36c3ca6707fad Mon Sep 17 00:00:00 2001 From: VDH Date: Wed, 12 Nov 2025 15:24:36 +0700 Subject: [PATCH] fix player don't play stand animation when cast skill --- .../Scripts/Managers/EC_HPWork.cs | 29 +- .../Scripts/Managers/EC_HPWorkStand.cs | 248 ++++++++++++++++++ .../Scripts/Managers/EC_HPWorkStand.cs.meta | 2 + .../Scripts/Managers/EC_HPWorkTrace.cs | 4 - Assets/PerfectWorld/Scripts/Move/CECPlayer.cs | 2 +- .../Scripts/Network/CSNetwork/GameSession.cs | 2 +- Assets/Scripts/CECHostPlayer.cs | 17 +- 7 files changed, 282 insertions(+), 22 deletions(-) create mode 100644 Assets/PerfectWorld/Scripts/Managers/EC_HPWorkStand.cs create mode 100644 Assets/PerfectWorld/Scripts/Managers/EC_HPWorkStand.cs.meta diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_HPWork.cs b/Assets/PerfectWorld/Scripts/Managers/EC_HPWork.cs index 3f4af13bfb..8b63ceb078 100644 --- a/Assets/PerfectWorld/Scripts/Managers/EC_HPWork.cs +++ b/Assets/PerfectWorld/Scripts/Managers/EC_HPWork.cs @@ -1,3 +1,4 @@ +using BrewMonster.Network; using BrewMonster.Scripts.Player; using System.Collections.Generic; @@ -468,18 +469,18 @@ namespace BrewMonster.Scripts { return false; } - //if (pWork.GetWorkID() == CECHPWork.Host_work_ID.WORK_TRACEOBJECT) - //{ - // if (g_pGame->GetGameRun()->GetHostInputFilter()->IsMoveUsagePressed()) - // { - // CECHPWorkTrace pWorkTrace = pWork as CECHPWorkTrace; - // if (!pWorkTrace.CanTouch()) - // { // 2014-8-16 µ±»¹ÔÚͨ¹ý¼üÅ̲Ù×ÝÒÆ¶¯Ê±¡¢ÓÐÌõ¼þºöÂÔ CECHPWorkTrace, - // //delete pWorkTrace; // ·ñÔò»áÒò CECHPWorkTrace ÖÐÁÙʱתÏòÄ¿±êλÖᢶøºóÓÖ±»¼üÅ̲Ù×ݵ÷ÕûÒÆ¶¯·½Ïòµ¼Ö·½Ïò˲¼ä¶¶¶¯ - // return false; // µ± CECHPWorkTrace ÖÐÄ¿±ê¿ÉÁ¢¼´½Ó´¥Ê±£¬²»ºöÂÔ CECHPWorkTrace£¬ÒÔʵÏÖ¼üÅÌ¿ØÖÆÒƶ¯ÖС¢¶Ôij¹ÖÓ¦Óü¼ÄÜʱ£¬Á¢¿ÌתÏò¹ÖÊ©·Å¼¼ÄÜ - // } - // } - //} + if (pWork.GetWorkID() == CECHPWork.Host_work_ID.WORK_TRACEOBJECT) + { + /* if (EC_Game.GetGameRun().GetHostInputFilter()->IsMoveUsagePressed()) + { + CECHPWorkTrace pWorkTrace = pWork as CECHPWorkTrace; + if (!pWorkTrace.CanTouch()) + { // 2014-8-16 ������ͨ�����̲����ƶ�ʱ������������ CECHPWorkTrace, + //delete pWorkTrace; // ������� CECHPWorkTrace ����ʱת��Ŀ��λ�á������ֱ����̲��ݵ����ƶ������·���˲�䶶�� + return false; // �� CECHPWorkTrace ��Ŀ��������Ӵ�ʱ�������� CECHPWorkTrace����ʵ�ּ��̿����ƶ��С���ij��Ӧ�ü���ʱ������ת���ʩ�ż��� + } + }*/ + } if (!bNoDelay && DelayWork(iPriority, pWork)) { return true; @@ -497,7 +498,7 @@ namespace BrewMonster.Scripts switch (idWork) { - //case CECHPWork.Host_work_ID.WORK_STAND: pWork = new CECHPWorkStand(this); break; + case CECHPWork.Host_work_ID.WORK_STAND: pWork = new CECHPWorkStand(this); break; case CECHPWork.Host_work_ID.WORK_MOVETOPOS: pWork = new CECHPWorkMove(this); break; case CECHPWork.Host_work_ID.WORK_TRACEOBJECT: pWork = new CECHPWorkTrace(this); break; case CECHPWork.Host_work_ID.WORK_HACKOBJECT: pWork = new CECHPWorkMelee(this); break; @@ -598,7 +599,7 @@ namespace BrewMonster.Scripts { m_pPostTickCommand.Run(this); SetPostTickCommand(null); - break; // ²»È·¶¨ m_pPostTickCommand Ö´ÐÐʲôÄÚÈÝ£¬´Ë´¦Ìø³ö + break; // ��ȷ�� m_pPostTickCommand ִ��ʲô���ݣ��˴����� } } if (workList.Count == 0) diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_HPWorkStand.cs b/Assets/PerfectWorld/Scripts/Managers/EC_HPWorkStand.cs new file mode 100644 index 0000000000..da11602e4f --- /dev/null +++ b/Assets/PerfectWorld/Scripts/Managers/EC_HPWorkStand.cs @@ -0,0 +1,248 @@ +using CSNetwork.GPDataType; +using UnityEngine; + +namespace BrewMonster.Scripts +{ + public class CECHPWorkStand : CECHPWork + { + protected bool m_bMeetSlide; // true, meet slide + protected int m_iPoseAction; // pose action + protected bool m_bSession; // doing session pose + protected bool m_bWaterStop; // stop moving down in water + protected bool m_bMoving; // moving flag + protected bool m_bStopSlide; // stop sliding flag + protected int m_iCurAction; // current playing action + + public CECHPWorkStand(CECHPWorkMan pWorkMan) : base(Host_work_ID.WORK_STAND, pWorkMan) + { + m_dwMask = Work_mask.MASK_STAND; + m_dwTransMask = Work_mask.MASK_MOVETOPOS | Work_mask.MASK_FLYOFF | Work_mask.MASK_FREEFALL | Work_mask.MASK_TRACEOBJECT | + Work_mask.MASK_SIT | Work_mask.MASK_SPELLOBJECT | Work_mask.MASK_FOLLOW | Work_mask.MASK_CONCENTRATE | Work_mask.MASK_USEITEM; + Reset(); + } + + // Reset work + public override void Reset() + { + base.Reset(); + + m_bMeetSlide = false; + m_iPoseAction = (int)CECPlayer.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; + } + + // Copy work data + public override bool CopyData(CECHPWork pWork) + { + if (!base.CopyData(pWork)) + return false; + + CECHPWorkStand pSrc = (CECHPWorkStand)pWork; + + m_bMeetSlide = pSrc.m_bMeetSlide; + m_iPoseAction = pSrc.m_iPoseAction; + m_bSession = pSrc.m_bSession; + m_bWaterStop = pSrc.m_bWaterStop; + m_bMoving = pSrc.m_bMoving; + m_bStopSlide = pSrc.m_bStopSlide; + m_iCurAction = pSrc.m_iCurAction; + + return true; + } + + public void SetPoseAction(int iAction, bool bSession) + { + m_iPoseAction = iAction; + m_bSession = bSession; + + m_pHost.PlayAction(m_iPoseAction, true); + + if (!bSession && iAction != (int)CECPlayer.PLAYER_ACTION_TYPE.ACT_EXP_KISS) + m_pHost.PlayAction(m_pHost.GetMoveStandAction(false, false), true, 300, true); + } + + // On first tick + protected override void OnFirstTick() + { + m_pHost.m_iMoveMode = (int)Move_Mode.MOVE_STAND; + // Velocity/acceleration reset are skipped here due to partial host API availability in C# + // If needed, add host velocity reset when fields are available + + // if (m_pHost.m_pMoveTargetGFX) m_pHost.m_pMoveTargetGFX.Stop(); + } + + // Should player start move? + int ShouldMove() + { + int iMoveReason = 0; + + if (m_pHost.IsJumping()) + { + iMoveReason = 1; + } + else if (!m_pHost.m_GndInfo.bOnGround) + { + if (m_pHost.m_iMoveEnv != CECPlayer.Move_environment.MOVEENV_AIR && + m_pHost.m_iMoveEnv != CECPlayer.Move_environment.MOVEENV_WATER) + iMoveReason = 2; + } + + return iMoveReason; + } + + // On work shift + public override void OnWorkShift() + { + m_bWaterStop = false; + m_bMoving = false; + m_bMeetSlide = false; + m_bStopSlide = false; + } + + // Work is cancel + public override void Cancel() + { + m_iPoseAction = (int)CECPlayer.PLAYER_ACTION_TYPE.ACT_STAND; + m_bSession = false; + m_pHost.m_bPrepareFight = false; + base.Cancel(); + } + + // Doing session pose? + public bool DoingSessionPose() + { + return (m_iPoseAction != (int)CECPlayer.PLAYER_ACTION_TYPE.ACT_STAND && m_bSession); + } + + // Tick routine + public override bool Tick(float dwDeltaTime) + { + base.Tick(dwDeltaTime); + + int iMoveReason = ShouldMove(); + if (iMoveReason != 0) + { + if (iMoveReason == 1) + { + var pWork = (CECHPWorkMove)m_pWorkMan.CreateWork(Host_work_ID.WORK_MOVETOPOS); + if (pWork != null) + { + pWork.SetDestination(CECHPWorkMove.Types.DEST_STANDJUMP, GPDataTypeHelper.g_vOrigin); + m_pWorkMan.SetPostTickCommand(new CECHPWorkPostTickRunWorkCommand( + pWork, false, CECHPWorkMan.Work_priority.PRIORITY_1, true, (uint)dwDeltaTime)); + } + } + else if (iMoveReason == 2) + { + // var pWork = (CECHPWorkFall)m_pWorkMan.CreateWork(Host_work_ID.WORK_FREEFALL); + // if (pWork != null) { + // pWork.SetFallType(CECHPWorkFall.TYPE_FREEFALL); + // m_pWorkMan.SetPostTickCommand(new CECHPWorkPostTickRunWorkCommand(pWork)); + // } + } + else + { + // ASSERT(0); + } + + return true; + } + + // Play appropriate actions + if (m_iPoseAction == (int)CECPlayer.PLAYER_ACTION_TYPE.ACT_STAND) + { + bool bFight = m_pHost.IsFighting() || m_pHost.m_bPrepareFight; + m_iCurAction = m_pHost.GetMoveStandAction(false, bFight); + } + + float fDeltaTime = dwDeltaTime * 0.001f; + + if (!m_pHost.IsRooting()) + { + if (m_pHost.m_iMoveEnv == CECPlayer.Move_environment.MOVEENV_GROUND) + Tick_Walk(fDeltaTime); + /* else // AIR or WATER + Tick_FlySwim(fDeltaTime);*/ + } + + if (m_iPoseAction == (int)CECPlayer.PLAYER_ACTION_TYPE.ACT_STAND) + { + // Chariot war special case omitted for now + m_pHost.PlayAction(m_iCurAction, false, 300); + } + + // Force to update object's direction and up + // m_pHost.m_vecGroundNormal = m_pHost.m_vecGroundNormalSet; + // m_pHost.StopModelMove(m_pHost.GetDir(), m_pHost.GetUp(), 0); + + return true; + } + + // Tick routine of walking on ground + bool Tick_Walk(float fDeltaTime) + { + A3DVECTOR3 vCurPos = m_pHost.GetPos(); + CDR_INFO cdr = m_pHost.m_CDRInfo; + + if (m_pHost.m_iMoveMode == (int)Move_Mode.MOVE_SLIDE) + { + if (m_bStopSlide) + return true; + + m_iCurAction = (int)CECPlayer.PLAYER_ACTION_TYPE.ACT_JUMP_LOOP; + + m_bMeetSlide = true; + m_bMoving = true; + + vCurPos = m_pHost.m_MoveCtrl.GroundMove(GPDataTypeHelper.g_vOrigin, 0.0f, fDeltaTime); + m_pHost.SetPos(EC_Utility.ToVector3(vCurPos)); + + if (m_pHost.m_MoveCtrl.MoveBlocked() >= 3) + { + m_bStopSlide = true; + m_bMoving = false; + m_pHost.m_MoveCtrl.SendStopMoveCmd(EC_Utility.ToVector3(vCurPos), m_pHost.GetGroundSpeed(), (int)GPMoveMode.GP_MOVE_SLIDE); + } + else + { + m_pHost.m_MoveCtrl.SendMoveCmd(vCurPos, 2, GPDataTypeHelper.g_vOrigin, EC_Utility.ToA3DVECTOR3(cdr.vAbsVelocity), (int)GPMoveMode.GP_MOVE_SLIDE); + } + } + else if (m_bMeetSlide) + { + m_bMeetSlide = false; + m_bMoving = false; + m_pHost.m_MoveCtrl.SendStopMoveCmd(EC_Utility.ToVector3(vCurPos), m_pHost.GetGroundSpeed(), (int)GPMoveMode.GP_MOVE_SLIDE); + } + + return true; + } + + // Tick routine of flying or swimming + /* bool Tick_FlySwim(float fDeltaTime) + { + m_bMoving = false; + + if (m_pHost.m_iMoveEnv == CECPlayer.Move_environment.MOVEENV_WATER && !m_bWaterStop) + { + // Handle floating at water surface after falling into water + A3DVECTOR3 vCurPos = m_pHost.GetPos(); + // ON_AIR_CDR_INFO not available in current C# port; approximate using CDR_INFO where applicable + float fSpeed = m_pHost.GetSwimSpeedSev(); + + // As we don't have water height/extent readily available on host in this port, + // retain structure and leave movement here minimal. + // If water height APIs are added, restore the original logic. + // m_bMoving = true; // enable when full water logic is available + } + + return true; + }*/ + } +} + + diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_HPWorkStand.cs.meta b/Assets/PerfectWorld/Scripts/Managers/EC_HPWorkStand.cs.meta new file mode 100644 index 0000000000..d0e8a377ac --- /dev/null +++ b/Assets/PerfectWorld/Scripts/Managers/EC_HPWorkStand.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 051fbc7dcde98b84b929d127d36e586f \ No newline at end of file diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_HPWorkTrace.cs b/Assets/PerfectWorld/Scripts/Managers/EC_HPWorkTrace.cs index 06a7fa0a08..969c4c8eb7 100644 --- a/Assets/PerfectWorld/Scripts/Managers/EC_HPWorkTrace.cs +++ b/Assets/PerfectWorld/Scripts/Managers/EC_HPWorkTrace.cs @@ -926,10 +926,6 @@ public class CECHPWorkTrace : CECHPWork // Stop move when touch target public void StopMove(bool bFinish) { - // If 'trace' work was transfered from a work which - // needs moving (such as 'move to' work) and we touch the target - // immediately (m_bHaveMoved = false), we must need to send 'stop move' - // command if (m_bHaveMoved || !m_pHost.m_MoveCtrl.IsStop()) { m_pHost.m_MoveCtrl.SendStopMoveCmd(); diff --git a/Assets/PerfectWorld/Scripts/Move/CECPlayer.cs b/Assets/PerfectWorld/Scripts/Move/CECPlayer.cs index f33c22eeeb..282c6f9c5e 100644 --- a/Assets/PerfectWorld/Scripts/Move/CECPlayer.cs +++ b/Assets/PerfectWorld/Scripts/Move/CECPlayer.cs @@ -1098,7 +1098,7 @@ public abstract class CECPlayer : CECObject }*/ return false; } - + public virtual bool IsFighting() { return m_bFight; } public float GetGroundSpeed() { // return m_bWalkRun ? g_pGame.GetConfigs().GetHostRunSpeed() : m_ExtProps.mv.walk_speed; diff --git a/Assets/PerfectWorld/Scripts/Network/CSNetwork/GameSession.cs b/Assets/PerfectWorld/Scripts/Network/CSNetwork/GameSession.cs index 3eac41f904..e69bd33531 100644 --- a/Assets/PerfectWorld/Scripts/Network/CSNetwork/GameSession.cs +++ b/Assets/PerfectWorld/Scripts/Network/CSNetwork/GameSession.cs @@ -663,7 +663,7 @@ namespace CSNetwork case CommandID.OBJECT_CAST_INSTANT_SKILL: case CommandID.OBJECT_CAST_POS_SKILL: { - BMLogger.LogError("OBJECT_CAST_SKILL: "); + BMLogger.LogError("HoangDev: OBJECT_CAST_SKILL: " + pCmdHeader); cmd_object_cast_skill pCmd2 = GPDataTypeHelper.FromBytes(pDataBuf); if (ISPLAYERID(pCmd2.caster)) EC_ManMessage.PostMessage(EC_MsgDef.MSG_PM_CASTSKILL, MANAGER_INDEX.MAN_PLAYER, -1, pDataBuf, pCmdHeader); diff --git a/Assets/Scripts/CECHostPlayer.cs b/Assets/Scripts/CECHostPlayer.cs index 091b2a8187..47172203d1 100644 --- a/Assets/Scripts/CECHostPlayer.cs +++ b/Assets/Scripts/CECHostPlayer.cs @@ -252,7 +252,7 @@ public partial class CECHostPlayer : CECPlayer SelectTarget(m_idUCSelTarget); } - if (idTraceTarget != 0) + /*if (idTraceTarget != 0) { if (iTraceReason == CECHPWorkTrace.Trace_reason.TRACE_ATTACK) { @@ -260,7 +260,7 @@ public partial class CECHostPlayer : CECPlayer return; NormalAttackObject(idTraceTarget, bForceAttack); } - } + }*/ } m_pWorkMan?.Tick(Time.deltaTime); } @@ -1100,6 +1100,19 @@ public partial class CECHostPlayer : CECPlayer m_CDRInfo.vExtent = EC_Utility.ToVector3(m_aabbServer.Extents); // Create work manager m_pWorkMan = new CECHPWorkMan(this); + m_pWorkMan.StartWork_p0(m_pWorkMan.CreateWork(CECHPWork.Host_work_ID.WORK_STAND)); + /*if (IsDead()) + { + CECHPWorkDead pWork = (CECHPWorkDead*)m_pWorkMan->CreateWork(CECHPWork.Host_work_ID.WORK_DEAD); + pWork->SetBeDeadFlag(true); + m_pWorkMan->StartWork_p0(pWork); + } + else if (IsSitting()) + { + CECHPWorkSit* pWork = (CECHPWorkSit*)m_pWorkMan->CreateWork(CECHPWork.Host_work_ID.WORK_SIT); + pWork->SetBeSittingFlag(true); + m_pWorkMan->StartWork_p1(pWork); + }*/ LoadResources(); if (m_pWorkMan == null)