Files
test/Assets/PerfectWorld/Scripts/Managers/EC_HPWorkMove.cs
T
2026-01-09 17:06:53 +07:00

1260 lines
51 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using CSNetwork.GPDataType;
using System;
using UnityEngine;
using Types = BrewMonster.Scripts.CECHPWorkMove.DestTypes;
namespace BrewMonster.Scripts
{
public class CECHPWorkMove : CECHPWork
{
public static class DestTypes
{
public const int DEST_2D = 0,
DEST_3D = 1,
DEST_DIR = 2,
DEST_PUSH = 3,
DEST_STANDJUMP = 4,
DEST_AUTOPF = 5; // Movement type
}
const float A3D_PI = 3.1415926535f;
static float DEG2RAD(float deg) => ((deg) * A3D_PI / 180.0f);
static float pitch_ang_wing => DEG2RAD(45.0f);
static float pitch_ang_fly_sword => DEG2RAD(25.0f);
static float lean_max_ang => DEG2RAD(45.0f);
static float ang_vel_fly => 1.0f / DEG2RAD(60.0f);
static float ang_vel_swim => 1.0f / DEG2RAD(180.0f);
static float pitch_co_wing => pitch_ang_wing / A3D_PI;
static float pitch_co_fly_sword => pitch_ang_fly_sword / A3D_PI;
const float sidle_co = .5f;
static float sidle_co_r => 1.0f - sidle_co;
static float push_pitch_vel_wing => pitch_ang_wing / 0.5f;
static float push_pitch_vel_fly_sword => pitch_ang_fly_sword / 0.5f;
private const uint MoveInputMask = 0x0F; // MD_FORWARD | MD_RIGHT | MD_BACK | MD_LEFT
protected A3DVECTOR3 m_vMoveDest; // Move destination position or direction
protected int m_iDestType; // Destination type
protected bool m_bHaveDest; // true, have destination
protected bool m_bMeetSlide; // true, meet slide
protected A3DVECTOR3 m_vCurDir; // Current move direction
protected bool m_bReadyCancel; // true, ready to cancel
protected bool m_bGliding; // glide
protected float m_fGlideTime;
protected float m_fGlideSpan;
protected float m_fGlideAng;
protected float m_fGlideVel; // glide angular vel
protected float m_fGlidePitch; // glide pitch angle
protected float m_fCurPitch;
protected float m_fPushPitch;
protected float m_fPushLean;
protected A3DVECTOR3 vDir = new A3DVECTOR3();
protected bool m_bUseAutoMoveDialog; // Auto move
protected float m_fAutoHeight; // Height of auto moving destination
protected bool m_bAutoLand; // Auto land when arrive at destination
protected bool m_bAutoFly; // Auto fly
protected bool m_bReachedHeight;// Player reached specified height
protected bool m_bAutoFlyPending; // Mark whether a fly command had been executed
protected int m_iNPCTempleId;
protected int m_iTaskId;
protected bool m_bSwitchTo2D;
protected bool m_bResetAutoPF;
public CECHPWorkMove(CECHPWorkMan pWorkMan) : base(Host_work_ID.WORK_MOVETOPOS, pWorkMan)
{
m_dwMask = Work_mask.MASK_MOVETOPOS;
m_dwTransMask = Work_mask.MASK_STAND | Work_mask.MASK_TRACEOBJECT | Work_mask.MASK_FOLLOW;
Reset();
}
public CECHPWorkMove(int iWorkID, CECHPWorkMan pWorkMan) : base(iWorkID, pWorkMan)
{
}
// Set destination position or direction
public void SetDestination(int iDestType, A3DVECTOR3 vMoveDest)
{
m_iDestType = iDestType;
m_vMoveDest = vMoveDest;
m_bHaveDest = true;
m_bGliding = false;
//m_pHost.SetAdjustOrient(false); // 2014-9-10 ı CECHPWorkMove ʱ򶼻ô˺ʱͨ SetDestDirAndUp öijʧЧ
// ַΪɡӽͷźϰס'A''D'ƶסţʩƫĿƶγԣ
//Ϣ
m_iTaskId = 0;
m_iNPCTempleId = 0;
ResetUseAutoPF();
if (iDestType == Types.DEST_DIR)
{
m_vCurDir = vMoveDest;
if (m_bUseAutoMoveDialog)
{
m_bUseAutoMoveDialog = false;
m_bAutoLand = false;
m_fAutoHeight = -1.0f;
m_bAutoFly = false;
m_bReachedHeight = true;
m_bAutoFlyPending = false;
}
}
else if (iDestType == Types.DEST_2D || iDestType == Types.DEST_3D)
{
m_vCurDir = vMoveDest - new A3DVECTOR3(m_pHost.transform.position.x, m_pHost.transform.position.y, m_pHost.transform.position.z);
m_vCurDir.y = 0.0f;
m_vCurDir.Normalize();
}
else if (IsAutoPF())
{
// 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;
//}
}
// TO DO: fix later
//if (m_pHost.m_pMoveTargetGFX)
//{
// if (iDestType != DEST_PUSH)
// m_pHost.m_pMoveTargetGFX.Stop();
//}
}
void ResetUseAutoPF()
{
m_bResetAutoPF = true;
}
// Tick routine
public override 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 != 0)
{
CECNPC pNPC = EC_Game.GetGameRun().GetWorld().GetNPCMan().FindNPCByTempleID(m_iNPCTempleId);
if (pNPC && m_pHost.SelectTarget(pNPC.GetNPCID()))
{
CECHPWorkTrace pWork = m_pWorkMan.CreateNPCTraceWork(pNPC, m_iTaskId);
if (pWork != null)
{
m_bAutoLand = false; //ֹ״̬Ѱ·תworktrace֮ǰԶ½workfall
Finish();
m_pWorkMan.SetPostTickCommand(new CECHPWorkPostTickRunWorkCommand(pWork, true));
return true;
}
}
}
}*/
//m_pHost.SetGroundInfoClient();
float fDeltaTime = dwDeltaTime;
if (m_pHost.m_iMoveEnv == (int)MoveEnvironment.MOVEENV_GROUND ||
m_pHost.m_iMoveEnv == (int)MoveEnvironment.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((int)PLAYER_ACTION_TYPE.ACT_TRICK_RUN) &&
m_pHost.m_iMoveMode != (int)MoveMode.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 override void Reset()
{
base.Reset();
m_iDestType = DestTypes.DEST_2D;
m_bHaveDest = false;
m_bMeetSlide = false;
m_bReadyCancel = false;
m_bGliding = false;
m_fGlideTime = 0;
m_fCurPitch = 0;
m_fPushPitch = 0;
m_fPushLean = 0;
m_bUseAutoMoveDialog = false;
m_fAutoHeight = -1.0f;
m_bAutoLand = false;
m_bAutoFly = false;
m_bReachedHeight = true;
m_bAutoFlyPending = false;
m_iNPCTempleId = 0;
m_iTaskId = 0;
m_bSwitchTo2D = false;
m_bResetAutoPF = false;
}
// Work is cancel
public override void Cancel()
{
//if (m_pHost.m_pMoveTargetGFX)
// m_pHost.m_pMoveTargetGFX.Stop();
//A3DVECTOR3 vDir = m_pHost.GetDir();
//vDir.y = 0;
//vDir.Normalize();
//if (!vDir.IsZero())
//{
// m_pHost.StopModelMove(vDir, g_vAxisY, 0);
//}
ClearResetUseAutoPF();
//if (CECIntelligentRoute::Instance().IsUsageMove())
//{
// if (!CECIntelligentRoute::Instance().IsIdle())
// {
// CECIntelligentRoute::Instance().ResetSearch();
// m_bSwitchTo2D = true; // Æô¶¯·ÉÐÐÖжϺó»Ö¸´Ê±¡¢ÐèÒªÇл»µ½ DEST_2D ģʽ
// }
//}
base.Cancel();
//AP_ActionEvent(AP_EVENT_MOVEFINISHED);
}
// 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;
CECHPWorkMove pSrc = pWork as CECHPWorkMove;
m_iDestType = pSrc.m_iDestType;
m_bHaveDest = pSrc.m_bHaveDest;
m_bMeetSlide = pSrc.m_bMeetSlide;
m_bReadyCancel = pSrc.m_bReadyCancel;
m_bGliding = pSrc.m_bGliding;
m_fGlideTime = pSrc.m_fGlideTime;
m_fGlideSpan = pSrc.m_fGlideSpan;
m_fGlideAng = pSrc.m_fGlideAng;
m_fGlideVel = pSrc.m_fGlideVel;
m_fGlidePitch = pSrc.m_fGlidePitch;
m_fCurPitch = pSrc.m_fCurPitch;
m_fPushPitch = pSrc.m_fPushPitch;
m_fPushLean = pSrc.m_fPushLean;
m_iDestType = pSrc.m_iDestType;
m_vMoveDest = pSrc.m_vMoveDest;
m_vCurDir = pSrc.m_vCurDir;
m_bUseAutoMoveDialog = pSrc.m_bUseAutoMoveDialog;
m_fAutoHeight = pSrc.m_fAutoHeight;
m_bAutoLand = pSrc.m_bAutoLand;
m_bAutoFly = pSrc.m_bAutoFly;
m_bReachedHeight = pSrc.m_bReachedHeight;
m_bAutoFlyPending = pSrc.m_bAutoFlyPending;
m_iNPCTempleId = pSrc.m_iNPCTempleId;
m_iTaskId = pSrc.m_iTaskId;
m_bSwitchTo2D = pSrc.m_bSwitchTo2D;
m_bResetAutoPF = pSrc.m_bResetAutoPF;
return true;
}
// Play move target effect
public void PlayMoveTargetGFX(A3DVECTOR3 vPos, A3DVECTOR3 vNormal)
{
}
// User press cancel button
public void PressCancel() { m_bReadyCancel = true; }
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() { return m_bAutoFly; }
bool IsAutoPF() { return m_iDestType == Types.DEST_AUTOPF; }
// Finish work
public void Finish()
{
m_bFinished = true;
Cancel();
// Close 'Win_AutoPlay' dialog if it exists
//CECGameUIMan* pGameUI = g_pGame.GetGameRun().GetUIManager().GetInGameUIMan();
//pGameUI.AutoMoveShowDialog(false);
if (m_bUseAutoMoveDialog)
{
if (m_bAutoLand)
{
m_bAutoLand = false;
//if (g_pGame.GetGameRun().GetHostPlayer().IsFlying())
// g_pGame.GetGameRun().GetHostPlayer().CmdFly(false);
}
m_bUseAutoMoveDialog = false;
m_fAutoHeight = -1.0f;
m_bAutoFly = false;
m_bReachedHeight = true;
}
//׷
m_iNPCTempleId = 0;
m_iTaskId = 0;
}
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 override void OnFirstTick()
{
m_pHost.m_iMoveMode = Move_Mode.MOVE_MOVE;
//PlayMoveTargetGFX();
//if (m_pHost.m_iMoveEnv != CECPlayer::MOVEENV_AIR)
// m_pHost.ShowWing(false);
if (!m_pHost.IsJumping())
{
int iAction = m_pHost.GetMoveStandAction(true);
m_pHost.PlayAction(iAction, false);
}
}
// Tick routine of walking on ground
protected bool Tick_Walk(float fDeltaTime)
{
A3DVECTOR3 vCurPos = m_pHost.GetPos();
ref CDR_INFO cdr = ref m_pHost.m_CDRInfo;
if (m_pHost.m_iMoveMode == (int)MoveMode.MOVE_SLIDE)
{
m_pHost.PlayAction((int)PLAYER_ACTION_TYPE.ACT_JUMP_LOOP, false);
A3DVECTOR3 vDir;
if (m_iDestType == DestTypes.DEST_DIR)
{
vDir = m_vCurDir;
}
else if (m_iDestType == DestTypes.DEST_PUSH)
{
vDir = GetCurrentModelDir();
}
#if ENABLE_CEC_INTELLIGENT_ROUTE
else if (IsAutoPF())
{
vDir = CECIntelligentRoute.Instance().GetCurDest() - vCurPos;
vDir.y = 0.0f;
vDir.Normalize();
}
#endif
else
{
vDir = m_vMoveDest - vCurPos;
vDir.y = 0.0f;
vDir.Normalize();
}
float fMaxSpeedV = 0.0f;
m_bMeetSlide = m_pHost.m_MoveCtrl.MeetSlope(vDir, fMaxSpeedV);
cdr.fYVel = EC_Utility.a_ClampFloor(cdr.fYVel, -fMaxSpeedV);
if (m_pHost.m_GndInfo.bOnGround)
m_vCurDir = vDir;
vCurPos = m_pHost.m_MoveCtrl.GroundMove(m_vCurDir, m_pHost.GetGroundSpeed(), fDeltaTime);
if (m_pHost.m_MoveCtrl.MoveBlocked() >= 3)
{
m_pHost.m_MoveCtrl.SetSlideLock(true);
cdr.fYVel = 0.0f;
Finish();
m_pHost.m_MoveCtrl.SendStopMoveCmd(EC_Utility.ToVector3(vCurPos), m_pHost.GetGroundSpeed(), (int)GPMoveMode.GP_MOVE_SLIDE);
}
else
{
m_pHost.SetPos(EC_Utility.ToVector3(vCurPos));
#if ENABLE_CEC_INTELLIGENT_ROUTE
if (IsAutoPF() && CECIntelligentRoute.Instance().IsMoveOn())
CECIntelligentRoute.Instance().OnPlayerPosChange(vCurPos);
#endif
#if SHOW_AUTOMOVE_FOOTPRINTS
if (IsAutoPF() || m_iDestType == DestTypes.DEST_2D)
g_AutoPFFollowPoints.Add(vCurPos);
#endif
m_pHost.m_MoveCtrl.SendMoveCmd(
vCurPos,
2,
GPDataTypeHelper.g_vOrigin,
(cdr.vAbsVelocity),
(int)GPMoveMode.GP_MOVE_SLIDE);
}
}
else if (!m_bMeetSlide)
{
float fSpeed = m_pHost.GetGroundSpeed();
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;
if (m_bReadyCancel && m_pHost.m_GndInfo.bOnGround)
{
Finish();
m_pHost.m_MoveCtrl.SendStopMoveCmd(EC_Utility.ToVector3(vCurPos), fSpeed, iMoveMode);
return true;
}
if ((GetMoveRelDirMask() & (uint)((CECHostPlayer.MOVE_DIR.MD_LEFT | CECHostPlayer.MOVE_DIR.MD_RIGHT | CECHostPlayer.MOVE_DIR.MD_FORWARD | CECHostPlayer.MOVE_DIR.MD_BACK))) != 0)
m_iDestType = DestTypes.DEST_PUSH;
if (m_iDestType == DestTypes.DEST_2D)
{
float fDist;
if (m_pHost.m_GndInfo.bOnGround)
{
m_vCurDir = m_vMoveDest - vCurPos;
m_vCurDir.y = 0.0f;
fDist = m_vCurDir.Normalize();
}
else
{
fDist = (m_vMoveDest - vCurPos).MagnitudeH();
}
vCurPos = m_pHost.m_MoveCtrl.GroundMove(m_vCurDir, fSpeed, fDeltaTime, m_pHost.m_fVertSpeed);
UpdateFacingFromDelta(vCurPos);
if (m_pHost.m_MoveCtrl.MoveBlocked() >= 3)
{
cdr.fYVel = 0.0f;
Finish();
m_pHost.m_MoveCtrl.SendStopMoveCmd(EC_Utility.ToVector3(vCurPos), fSpeed, iMoveMode);
}
else if (cdr.vTPNormal != new A3DVECTOR3(0))
{
A3DVECTOR3 vMoveDelta = vCurPos - m_pHost.GetPos();
vMoveDelta.y = 0.0f;
float fMoveDist = vMoveDelta.Normalize();
if (fMoveDist >= fDist)
{
Finish();
m_bUseAutoMoveDialog = false;
m_pHost.SetPos(EC_Utility.ToVector3(vCurPos));
m_pHost.m_MoveCtrl.SendStopMoveCmd(EC_Utility.ToVector3(vCurPos), fSpeed, iMoveMode);
}
else
{
m_pHost.SetPos(EC_Utility.ToVector3(vCurPos));
m_pHost.m_MoveCtrl.SendMoveCmd(
vCurPos,
0,
m_vMoveDest,
(cdr.vAbsVelocity),
iMoveMode);
}
#if SHOW_AUTOMOVE_FOOTPRINTS
g_AutoPFFollowPoints.Add(vCurPos);
#endif
}
else
{
#if SHOW_AUTOMOVE_FOOTPRINTS
g_AutoPFFollowPoints.Add(vCurPos);
#endif
m_pHost.SetPos(EC_Utility.ToVector3(vCurPos));
m_pHost.m_MoveCtrl.SendMoveCmd(
vCurPos,
1,
m_vMoveDest,
(cdr.vAbsVelocity),
iMoveMode);
}
}
else if (m_iDestType == DestTypes.DEST_DIR)
{
vCurPos = m_pHost.m_MoveCtrl.GroundMove(m_vCurDir, fSpeed -0.5f, fDeltaTime, m_pHost.m_fVertSpeed);
UpdateFacingFromDelta(vCurPos);
m_pHost.SetPos(EC_Utility.ToVector3(vCurPos));
if (m_pHost.m_MoveCtrl.MoveBlocked() >= 3)
{
cdr.fYVel = 0.0f;
Finish();
m_pHost.m_MoveCtrl.SendStopMoveCmd(EC_Utility.ToVector3(vCurPos), fSpeed, iMoveMode);
}
else if (m_pHost.m_GndInfo.bOnGround)
{
m_pHost.m_MoveCtrl.SendMoveCmd(
vCurPos,
2,
GPDataTypeHelper.g_vOrigin,
(cdr.vAbsVelocity),
iMoveMode);
}
else
{
m_pHost.m_MoveCtrl.SendMoveCmd(
vCurPos,
1,
m_vMoveDest,
(cdr.vAbsVelocity),
iMoveMode);
}
}
else if (m_iDestType == DestTypes.DEST_STANDJUMP)
{
if (!m_pHost.IsJumping())
{
Finish();
m_pHost.m_MoveCtrl.SendStopMoveCmd(EC_Utility.ToVector3(vCurPos), fSpeed, iMoveMode);
}
else
{
vCurPos = m_pHost.m_MoveCtrl.GroundMove(GPDataTypeHelper.g_vOrigin, 0.0f, fDeltaTime, m_pHost.m_fVertSpeed);
m_pHost.SetPos(EC_Utility.ToVector3(vCurPos));
if (m_pHost.m_MoveCtrl.MoveBlocked() >= 3)
{
m_pHost.ResetJump();
Finish();
m_pHost.m_MoveCtrl.SendStopMoveCmd(EC_Utility.ToVector3(vCurPos), fSpeed, iMoveMode);
}
else
{
m_pHost.m_MoveCtrl.SendMoveCmd(
vCurPos,
0,
m_vMoveDest,
(cdr.vAbsVelocity),
iMoveMode);
}
}
}
else if (m_iDestType == DestTypes.DEST_PUSH)
{
Vector3 vMoveDir = Vector3.zero;//EC_Utility.ToVector3(GPDataTypeHelper.g_vOrigin);
fSpeed = m_pHost.GetGroundSpeed();
bool bFinish = false;
if (m_pHost.GetPushDir(ref vMoveDir, (uint)(CECHostPlayer.MOVE_DIR.MD_FORWARD | CECHostPlayer.MOVE_DIR.MD_BACK | CECHostPlayer.MOVE_DIR.MD_LEFT | CECHostPlayer.MOVE_DIR.MD_RIGHT), fDeltaTime))
{
if (vMoveDir != Vector3.zero)
{
m_pHost.SetRotationHP(vMoveDir);
}
vCurPos = m_pHost.m_MoveCtrl.GroundMove(EC_Utility.ToA3DVECTOR3(vMoveDir), fSpeed, fDeltaTime, m_pHost.m_fVertSpeed);
//Debug.LogError("vCurPos =" + vCurPos);
m_pHost.SetPos(EC_Utility.ToVector3(vCurPos));
}
else
{
if (!m_bUseAutoMoveDialog)
bFinish = true;
else
m_iDestType = DestTypes.DEST_2D;
}
if (bFinish || m_pHost.m_MoveCtrl.MoveBlocked() >= 3)
{
if (m_pHost.m_MoveCtrl.MoveBlocked() >= 3)
{
cdr.fYVel = 0.0f;
}
Finish();
m_pHost.m_vVelocity.Clear();
m_pHost.m_MoveCtrl.SendStopMoveCmd(EC_Utility.ToVector3(vCurPos), fSpeed, iMoveMode);
}
else
{
m_pHost.m_vVelocity = EC_Utility.ToA3DVECTOR3(vMoveDir) * fSpeed;
m_pHost.m_MoveCtrl.SendMoveCmd(
vCurPos,
2,
GPDataTypeHelper.g_vOrigin,
m_pHost.m_vVelocity,
iMoveMode);
}
}
//else if (m_iDestType == DestTypes.DEST_PUSH)
//{
// m_iDestType = DestTypes.DEST_2D;
//}
#if ENABLE_CEC_INTELLIGENT_ROUTE
else if (IsAutoPF())
{
float fDist = 0.0f;
A3DVECTOR3 vCurDest = CECIntelligentRoute.Instance().GetCurDest();
if (m_pHost.m_GndInfo.bOnGround)
{
m_vCurDir = vCurDest - vCurPos;
m_vCurDir.y = 0.0f;
fDist = m_vCurDir.Normalize();
}
else
{
fDist = (vCurDest - vCurPos).MagnitudeH();
}
vCurPos = m_pHost.m_MoveCtrl.GroundMove(m_vCurDir, fSpeed, fDeltaTime, m_pHost.m_fVertSpeed);
if (!m_vCurDir.IsZero())
{
//m_pHost.StartModelMove(m_vCurDir, GPDataTypeHelper.g_vAxisY, 100);
//m_pHost.ChangeModelTargetDirAndUp(m_vCurDir, GPDataTypeHelper.g_vAxisY);
UpdateFacingFromDelta(vCurPos);
}
if (m_pHost.m_MoveCtrl.MoveBlocked() >= 3)
{
cdr.fYVel = 0.0f;
Finish();
m_pHost.m_MoveCtrl.SendStopMoveCmd(EC_Utility.ToVector3(vCurPos), fSpeed, iMoveMode);
}
else
{
m_pHost.SetPos(EC_Utility.ToVector3(vCurPos));
CECIntelligentRoute.Instance().OnPlayerPosChange(vCurPos);
if (CECIntelligentRoute.Instance().IsPathFinished())
{
Finish();
m_pHost.m_MoveCtrl.SendStopMoveCmd(EC_Utility.ToVector3(vCurPos), fSpeed, iMoveMode);
}
else
{
m_pHost.m_MoveCtrl.SendMoveCmd(
vCurPos,
1,
vCurDest,
EC_Utility.ToA3DVECTOR3(cdr.vAbsVelocity),
iMoveMode);
}
}
}
#else
else if (IsAutoPF())
{
m_bSwitchTo2D = true;
}
#endif
}
else
{
m_pHost.m_MoveCtrl.SendStopMoveCmd(EC_Utility.ToVector3(vCurPos), m_pHost.GetGroundSpeed(), (int)GPMoveMode.GP_MOVE_SLIDE);
Finish();
}
return true;
}
// Tick routine of flying or swimming
protected bool Tick_FlySwim(float fDeltaTime)
{
A3DVECTOR3 vCurPos = m_pHost.GetPos();
int iMoveMode = (m_pHost.m_iMoveEnv == (int)MoveEnvironment.MOVEENV_AIR) ? (int)GPMoveMode.GP_MOVE_AIR : (int)GPMoveMode.GP_MOVE_WATER;
float na, fMaxSpeed;
bool bInAir;
//Debug.LogError("Tick_FlySwim m_pHost.m_dwMoveRelDir = " + m_pHost.m_dwMoveRelDir);
if (m_pHost.m_iMoveEnv == (int)MoveEnvironment.MOVEENV_AIR)
{
bInAir = true;
na = CECHostMove.EC_NACCE_AIR;
fMaxSpeed = m_pHost.GetFlySpeed();
}
else
{
bInAir = false;
na = CECHostMove.EC_NACCE_WATER;
fMaxSpeed = m_pHost.GetSwimSpeedSev();
}
if (m_bReadyCancel || m_bMeetSlide)
{
m_pHost.m_MoveCtrl.SendStopMoveCmd(EC_Utility.ToVector3(vCurPos), fMaxSpeed, iMoveMode | (int)GPMoveMode.GP_MOVE_RUN);
Finish();
return true;
}
// for auto move
if (m_bUseAutoMoveDialog && m_fAutoHeight > 0.0f && m_iDestType != DestTypes.DEST_PUSH)
{
if (m_pHost.m_dwMoveRelDir == 0)
{
if ((int)(vCurPos.y / 10.0f) == (int)m_fAutoHeight)
{
if (!m_bReachedHeight)
{
m_pHost.m_vVelocity.y = 0.0f;
m_pHost.m_dwMoveRelDir &= ~((uint)(CECHostPlayer.MOVE_DIR.MD_ABSUP | CECHostPlayer.MOVE_DIR.MD_ABSDOWN));
m_bReachedHeight = true;
}
}
else
{
if (!m_bReachedHeight)
{
if (vCurPos.y < m_fAutoHeight * 10.0f)
{
m_pHost.m_dwMoveRelDir &= ~((uint)(CECHostPlayer.MOVE_DIR.MD_ABSDOWN));
m_pHost.m_dwMoveRelDir |= ((uint)CECHostPlayer.MOVE_DIR.MD_ABSUP);
}
else if (vCurPos.y > m_fAutoHeight * 10.0f)
{
m_pHost.m_dwMoveRelDir &= ~((uint)(CECHostPlayer.MOVE_DIR.MD_ABSUP));
m_pHost.m_dwMoveRelDir |= (uint)CECHostPlayer.MOVE_DIR.MD_ABSDOWN;
}
}
else // Auto adjust height, so we should refresh move height
{
m_fAutoHeight = vCurPos.y / 10.0f;
}
}
}
else // Player manually set auto move height
{
m_bReachedHeight = true;
m_fAutoHeight = vCurPos.y / 10.0f;
}
}
if ((m_pHost.m_dwMoveRelDir & (uint)(CECHostPlayer.MOVE_DIR.MD_LEFT | CECHostPlayer.MOVE_DIR.MD_RIGHT | CECHostPlayer.MOVE_DIR.MD_FORWARD | CECHostPlayer.MOVE_DIR.MD_BACK)) != 0)
m_iDestType = DestTypes.DEST_PUSH;
ON_AIR_CDR_INFO cdr = m_pHost.m_AirCDRInfo;
if (m_iDestType == DestTypes.DEST_DIR)
{
Vector3 vPushDir = Vector3.zero;
m_pHost.GetPushDir(ref vPushDir, (uint)CECHostPlayer.MOVE_DIR.MD_ALL, 0);
vPushDir.x = vPushDir.z = 0.0f;
float fSpeed1H = m_pHost.m_vVelocity.MagnitudeH();
float fSpeed1V = m_pHost.m_vVelocity.y;
A3DVECTOR3 vMoveDirH = m_vMoveDest;
float pa = CECHostMove.EC_PUSH_ACCE;
float fSpeed2H = fSpeed1H + (pa + na) * fDeltaTime;
if (Math.Abs(pa - 0) < float.Epsilon && fSpeed2H < 0.0f)
fSpeed2H = 0.0f; // Only resistance couldn't generate negative speed
else if (fSpeed2H > fMaxSpeed)
fSpeed2H = fMaxSpeed;
Glide(5.0f, vMoveDirH, fDeltaTime, bInAir);
vMoveDirH = m_pHost.GetModelMoveDir();
vMoveDirH.y = 0;
vMoveDirH.Normalize();
// Vertical speed
float fSpeed2V = CalcFlySwimVertSpeed(fSpeed1V, vPushDir.y, CECHostMove.EC_PUSH_ACCE, fDeltaTime);
A3DVECTOR3 vVel2 = vMoveDirH * fSpeed2H + GPDataTypeHelper.g_vAxisY * fSpeed2V;
// Air/water move
vCurPos = m_pHost.m_MoveCtrl.AirWaterMove(vVel2, fDeltaTime, bInAir);
m_pHost.SetPos(EC_Utility.ToVector3(vCurPos));
m_pHost.m_vVelocity = vVel2;
if (m_pHost.m_MoveCtrl.MoveBlocked() >= 3)
{
Finish();
m_pHost.m_MoveCtrl.SendStopMoveCmd(EC_Utility.ToVector3(vCurPos), fMaxSpeed, iMoveMode | (int)GPMoveMode.GP_MOVE_RUN);
}
else
m_pHost.m_MoveCtrl.SendMoveCmd(vCurPos, 0, m_vMoveDest, vVel2, iMoveMode | (int)GPMoveMode.GP_MOVE_RUN);
}
else if (m_iDestType == DestTypes.DEST_2D)
{
Vector3 vPushDir = Vector3.zero;
m_pHost.GetPushDir(ref vPushDir, (uint)CECHostPlayer.MOVE_DIR.MD_ALL, 0f);
vPushDir.x = vPushDir.z = 0.0f;
float fSpeed1H = m_pHost.m_vVelocity.MagnitudeH();
float fSpeed1V = m_pHost.m_vVelocity.y;
A3DVECTOR3 vMoveDirH = m_vMoveDest - vCurPos;
vMoveDirH.y = 0.0f;
float fDistH = vMoveDirH.Normalize();
float pa = 0.0f;
// Calculate the distance to reduce velocity to 0
float s = -0.5f * fSpeed1H * fSpeed1H / na;
if (fDistH > s - 0.01f)
pa = CECHostMove.EC_PUSH_ACCE;
float fSpeed2H = fSpeed1H + (pa + na) * fDeltaTime;
if (Math.Abs(pa - 0f) < float.Epsilon && fSpeed2H < 0.0f)
fSpeed2H = 0.0f; // Only resistance couldn't generate negative speed
else if (fSpeed2H > fMaxSpeed)
fSpeed2H = fMaxSpeed;
Glide(fDistH / fMaxSpeed, vMoveDirH, fDeltaTime, bInAir);
vMoveDirH = m_pHost.GetModelMoveDir();
vMoveDirH.y = 0;
vMoveDirH.Normalize();
// Vertical speed
float fSpeed2V = CalcFlySwimVertSpeed(fSpeed1V, vPushDir.y, CECHostMove.EC_PUSH_ACCE, fDeltaTime);
A3DVECTOR3 vVel2 = vMoveDirH * fSpeed2H + GPDataTypeHelper.g_vAxisY * fSpeed2V;
// Air/water move
vCurPos = m_pHost.m_MoveCtrl.AirWaterMove(vVel2, fDeltaTime, bInAir);
if (m_pHost.m_MoveCtrl.MoveBlocked() >= 3)
{
vVel2.Clear();
Finish();
}
else
{
// Reached destination ?
A3DVECTOR3 vMoveDelta = vCurPos - m_pHost.GetPos();
vMoveDelta.y = 0.0f;
float fMoveDistH = vMoveDelta.Normalize();
if (fMoveDistH >= fDistH)
{
vVel2.x = vVel2.z = 0.0f;
if (Math.Abs(vVel2.y - 0f) < float.Epsilon)
{
Finish();
}
else
{
if (m_bUseAutoMoveDialog)
{
Finish();
vVel2.y = 0.0f;
}
m_iDestType = DestTypes.DEST_PUSH;
}
}
}
m_pHost.SetPos(EC_Utility.ToVector3(vCurPos));
m_pHost.m_vVelocity = vVel2;
if (m_bFinished)
m_pHost.m_MoveCtrl.SendStopMoveCmd(EC_Utility.ToVector3(vCurPos), vVel2.Magnitude(), iMoveMode | (int)GPMoveMode.GP_MOVE_RUN);
else
m_pHost.m_MoveCtrl.SendMoveCmd(vCurPos, 0, m_vMoveDest, vVel2, iMoveMode | (int)GPMoveMode.GP_MOVE_RUN);
}
else if (m_iDestType == DestTypes.DEST_3D)
{
float fSpeed1 = m_pHost.m_vVelocity.Magnitude();
A3DVECTOR3 vMoveDir = m_vMoveDest - vCurPos;
float fDist = vMoveDir.Normalize();
float pa = 0.0f;
// Calculate the distance to reduce velocity to 0
float s = -0.5f * fSpeed1 * fSpeed1 / na;
if (fDist > s - 0.01f)
pa = CECHostMove.EC_PUSH_ACCE;
float fSpeed2 = fSpeed1 + (pa + na) * fDeltaTime;
if (Math.Abs(pa - 0f) < float.Epsilon && fSpeed2 < 0.0f)
fSpeed2 = 0.0f; // Only resistance couldn't generate negative speed
AAssist.a_Clamp(ref fSpeed2, -fMaxSpeed, fMaxSpeed);
Vector3 vMoveDirH = new Vector3(vMoveDir.x, 0.0f, vMoveDir.z);
if (vMoveDirH != Vector3.zero)
{
//m_pHost.StartModelMove(vMoveDirH, g_vAxisY, 100);
//m_pHost.ChangeModelTargetDirAndUp(vMoveDirH, g_vAxisY);
m_pHost.SetRotationHP(vMoveDirH);
}
// Air/water move
// A3DVECTOR3 vVel1 = vMoveDir * fSpeed1;
A3DVECTOR3 vVel2 = vMoveDir * fSpeed2;
vCurPos = m_pHost.m_MoveCtrl.AirWaterMove(vMoveDir, fSpeed2, fDeltaTime, bInAir, false);
if (m_pHost.m_MoveCtrl.MoveBlocked() >= 3)
{
vVel2.Clear();
Finish();
}
else
{
// Reached destination ?
A3DVECTOR3 vMoveDelta = vCurPos - m_pHost.GetPos();
float fMoveDist = vMoveDelta.Normalize();
if (fMoveDist >= fDist)
{
vVel2.Clear();
Finish();
m_bUseAutoMoveDialog = false;
}
}
m_pHost.SetPos(EC_Utility.ToVector3(vCurPos));
m_pHost.m_vVelocity = vVel2;
if (m_bFinished)
m_pHost.m_MoveCtrl.SendStopMoveCmd(EC_Utility.ToVector3(vCurPos), fMaxSpeed, iMoveMode | (int)GPMoveMode.GP_MOVE_RUN);
else
m_pHost.m_MoveCtrl.SendMoveCmd(vCurPos, 1, m_vMoveDest, vVel2, iMoveMode | (int)GPMoveMode.GP_MOVE_RUN);
}
else if (m_iDestType == DestTypes.DEST_PUSH)
{
Vector3 vPushDir = Vector3.zero, vUp;
bool bPush = m_pHost.GetPushDir(ref vPushDir, (uint)(CECHostPlayer.MOVE_DIR.MD_FORWARD | CECHostPlayer.MOVE_DIR.MD_BACK | CECHostPlayer.MOVE_DIR.MD_LEFT | CECHostPlayer.MOVE_DIR.MD_RIGHT), fDeltaTime);
if (!bPush)
{
//vPushDir = m_pHost.GetCameraCoord().GetDir();
vPushDir.y = 0;
vPushDir.Normalize();
}
int nPitchDir = 0;
if ((m_pHost.m_dwMoveRelDir & (int)(CECHostPlayer.MOVE_DIR.MD_LEFT | CECHostPlayer.MOVE_DIR.MD_RIGHT)) == 0)
{
A3DVECTOR3 vOldDir = m_pHost.GetModelMoveDir();
vOldDir.y = 0;
vOldDir.Normalize();
A3DVECTOR3 vNewDir = EC_Utility.ToA3DVECTOR3(vPushDir);
vNewDir.y = 0;
vNewDir.Normalize();
float fAngle = A3DVECTOR3.DotProduct(vOldDir, vNewDir);
if (fAngle < 1.0f - 1e-4)
{
A3DVECTOR3 vUp_fAngle = A3DVECTOR3.CrossProduct(vOldDir, vNewDir);
if (vUp_fAngle.y > 0) nPitchDir = 1;
else nPitchDir = -1;
if ((m_pHost.m_dwMoveRelDir & (uint)CECHostPlayer.MOVE_DIR.MD_BACK) != 0)
nPitchDir = -nPitchDir;
}
}
if (m_pHost.m_dwMoveRelDir != 0)
{
if ((m_pHost.m_dwMoveRelDir & ~(uint)(CECHostPlayer.MOVE_DIR.MD_ABSDOWN | CECHostPlayer.MOVE_DIR.MD_ABSUP)) != 0)
{
float fPitchDelta = (/*m_pHost.UsingWing()*/m_pHost.GetWingType() == enumWingType.WINGTYPE_WING ? push_pitch_vel_wing : push_pitch_vel_fly_sword) * fDeltaTime;
if ((m_pHost.m_dwMoveRelDir & (uint)CECHostPlayer.MOVE_DIR.MD_LEFT) != 0 || nPitchDir == -1)
{
if ((m_pHost.m_dwMoveRelDir & (uint)CECHostPlayer.MOVE_DIR.MD_BACK) != 0)
m_fPushPitch -= fPitchDelta;
else
m_fPushPitch += fPitchDelta;
}
else if ((m_pHost.m_dwMoveRelDir & (uint)CECHostPlayer.MOVE_DIR.MD_RIGHT) != 0 || nPitchDir == 1)
{
if ((m_pHost.m_dwMoveRelDir & (uint)CECHostPlayer.MOVE_DIR.MD_BACK) != 0)
m_fPushPitch += fPitchDelta;
else
m_fPushPitch -= fPitchDelta;
}
else if (m_fPushPitch > fPitchDelta)
m_fPushPitch -= fPitchDelta;
else if (m_fPushPitch < -fPitchDelta)
m_fPushPitch += fPitchDelta;
else
m_fPushPitch = 0;
// TO DO: fix after
//A3DVECTOR3 vRight = m_pHost.GetCameraCoord().GetRight();
//float fLean = -Math.Asin(m_pHost.GetCameraCoord().GetDir().y);
//AAssist.a_Clamp(ref fLean, -lean_max_ang, lean_max_ang);
//if (Math.Abs(fLean) > DEG2RAD(3.0f))
//{
// vPushDir = a3d_RotatePosAroundAxis(vPushDir, vRight, fLean);
// vUp = a3d_RotatePosAroundAxis(g_vAxisY, vRight, fLean);
//}
//else
// vUp = EC_Utility.ToVector3(GPDataTypeHelper.g_vAxisY);
//float pitch_ang = /*m_pHost.UsingWing()*/ m_pHost.GetWingType() == enumWingType.WINGTYPE_WING ? pitch_ang_wing : pitch_ang_fly_sword;
//AAssist.a_Clamp(ref m_fPushPitch, -pitch_ang, pitch_ang);
//if (Math.Abs(m_fPushPitch) > DEG2RAD(4.0f))
// vUp = a3d_RotatePosAroundAxis(vUp, vPushDir, m_fPushPitch);
//m_pHost.StartModelMove(vPushDir, vUp, 0);
if (vPushDir != Vector3.zero)
{
m_pHost.SetRotationHPWithTime(vPushDir, 0.1f);
}
}
// if (bPush)
if (bPush || (m_pHost.m_dwMoveRelDir & (uint)(CECHostPlayer.MOVE_DIR.MD_ABSDOWN | CECHostPlayer.MOVE_DIR.MD_ABSUP)) != 0)
{
// float pa = bPush ? EC_PUSH_ACCE : 0.0f;
float pa = CECHostMove.EC_PUSH_ACCE;
float na1 = m_pHost.m_iMoveEnv == (int)MoveEnvironment.MOVEENV_AIR ? CECHostMove.EC_NACCE_AIR : CECHostMove.EC_NACCE_WATER;
float fAccel = pa + na1;
float fSpeed1 = m_pHost.m_vVelocity.Magnitude();
float fSpeed2 = fSpeed1 + fAccel * fDeltaTime;
AAssist.a_Clamp(ref fSpeed2, 0.0f, fMaxSpeed);
// Air/water move
Vector3 vVelDir = Vector3.zero;
if (bPush)
vVelDir = vPushDir;
if ((m_pHost.m_dwMoveRelDir & (uint)CECHostPlayer.MOVE_DIR.MD_ABSDOWN) != 0)
{
vVelDir += -EC_Utility.ToVector3(GPDataTypeHelper.g_vAxisY);
vVelDir.Normalize();
}
else if ((m_pHost.m_dwMoveRelDir & (uint)CECHostPlayer.MOVE_DIR.MD_ABSUP) != 0)
{
vVelDir += EC_Utility.ToVector3(GPDataTypeHelper.g_vAxisY);
vVelDir.Normalize();
}
// A3DVECTOR3 vVel = vPushDir * fSpeed2;
Vector3 vVel = vVelDir * fSpeed2;
vCurPos = m_pHost.m_MoveCtrl.AirWaterMove(EC_Utility.ToA3DVECTOR3(vVel), fDeltaTime, bInAir);
Debug.DrawLine(EC_Utility.ToVector3(m_pHost.GetPos()), EC_Utility.ToVector3(vCurPos), Color.red, 0.5f);
if (m_pHost.m_MoveCtrl.MoveBlocked() >= 3)
{
Finish();
m_pHost.m_vVelocity.Clear();
m_pHost.m_MoveCtrl.SendStopMoveCmd(EC_Utility.ToVector3(vCurPos), fMaxSpeed, iMoveMode | (int)GPMoveMode.GP_MOVE_RUN);
}
else
{
m_pHost.SetPos(EC_Utility.ToVector3(vCurPos));
if (m_bUseAutoMoveDialog)
{
m_fAutoHeight = vCurPos.y / 10.0f;
}
m_pHost.m_vVelocity = EC_Utility.ToA3DVECTOR3(vVel);
m_pHost.m_MoveCtrl.SendMoveCmd(vCurPos, 2, GPDataTypeHelper.g_vOrigin, EC_Utility.ToA3DVECTOR3(vVel), iMoveMode | (int)GPMoveMode.GP_MOVE_RUN);
}
}
}
else
{
if (!m_bUseAutoMoveDialog)
Finish();
else
m_iDestType = DestTypes.DEST_2D;
m_fPushPitch = 0;
m_pHost.m_vVelocity.Clear();
m_pHost.m_MoveCtrl.SendStopMoveCmd(EC_Utility.ToVector3(vCurPos), fMaxSpeed, iMoveMode | (int)GPMoveMode.GP_MOVE_RUN);
}
}
else if (m_iDestType == DestTypes.DEST_STANDJUMP)
{
// If host player fly off when jumping up, code will go here. In the
// case, just stop move work is well.
Finish();
}
else if (IsAutoPF())
{
//CECIntelligentRoute::Instance().ResetSearch();
m_bSwitchTo2D = true;
}
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()
{
m_bResetAutoPF = false;
}
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();
}
protected virtual uint GetMoveRelDirMask()
{
// TODO: hook up CECHostPlayer move-direction flags when available.
return 0;
}
private void UpdateFacingFromDelta(A3DVECTOR3 nextPos)
{
A3DVECTOR3 prevPos = m_pHost.GetPos();
Vector3 delta = EC_Utility.ToVector3(nextPos - prevPos);
delta.y = 0.0f;
if (delta.sqrMagnitude > 1e-6f)
{
delta.Normalize();
m_pHost.SetDirAndUp(delta, Vector3.up);
}
}
private A3DVECTOR3 GetCurrentModelDir()
{
Vector3 forward = m_pHost != null ? m_pHost.transform.forward : Vector3.forward;
return new A3DVECTOR3(forward.x, forward.y, forward.z);
}
}
}