fix player don't play stand animation when cast skill

This commit is contained in:
VDH
2025-11-12 15:24:36 +07:00
parent fb2288c2a2
commit 752d2cd69e
7 changed files with 282 additions and 22 deletions
@@ -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,以实现键盘控制移动中、对某怪应用技能时,立刻转向怪施放技能
// }
// }
//}
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)
@@ -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;
}*/
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 051fbc7dcde98b84b929d127d36e586f
@@ -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();
@@ -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;
@@ -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<cmd_object_cast_skill>(pDataBuf);
if (ISPLAYERID(pCmd2.caster))
EC_ManMessage.PostMessage(EC_MsgDef.MSG_PM_CASTSKILL, MANAGER_INDEX.MAN_PLAYER, -1, pDataBuf, pCmdHeader);
+15 -2
View File
@@ -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)