Files
test/Assets/PerfectWorld/Scripts/Managers/EC_HPWorkFall.cs
2026-03-06 17:33:20 +07:00

498 lines
19 KiB
C#

using CSNetwork.GPDataType;
using System;
using System.Runtime.ConstrainedExecution;
using UnityEngine;
namespace BrewMonster.Scripts
{
public class CECHPWorkFall : CECHPWork
{
protected A3DVECTOR3 m_vDirH;
protected float m_fSpeedH;
protected bool m_bEnterWater;
protected int m_iFallMode;
protected int m_nCurStage;
protected int m_iFallType;
protected bool m_fForceDown;
Vector3 g_vOrigin = Vector3.zero;
const float EC_NACCE_WATER = -5.0f;
public static class FlyFallStage
{
public const int enumStageNone = 0,
enumStageUpperAir = 1,
enumStageLowerAir = 2,
enumStageShallowWater = 3,
enumStageDeepWater = 4,
enumStageLandOn = 5;
};
// Fall type
public static class Fall_type
{
public const int TYPE_FREEFALL = 0,
TYPE_FLYFALL = 1;
};
// This work is do player moving ?
// public override bool IsMoving() { return true; }
// Copy work data
// Set fall type
public void SetFallType(int iType) { m_iFallType = iType; }
public int GetFallType() { return m_iFallType; }
public CECHPWorkFall(CECHPWorkMan pWorkMan) : base(Host_work_ID.WORK_FREEFALL, pWorkMan)
{
m_dwMask = Work_mask.MASK_FREEFALL;
m_dwTransMask = Work_mask.MASK_STAND;
Reset();
}
// Reset work
public override void Reset()
{
base.Reset();
m_bEnterWater = false;
m_nCurStage = FlyFallStage.enumStageNone;
m_iFallType = Fall_type.TYPE_FREEFALL;
m_fForceDown = false;
}
// Copy work data
public override bool CopyData(CECHPWork pWork)
{
if (!base.CopyData(pWork))
return false;
CECHPWorkFall pSrc = (CECHPWorkFall)pWork;
m_bEnterWater = pSrc.m_bEnterWater;
m_nCurStage = pSrc.m_nCurStage;
m_iFallType = pSrc.m_iFallType;
m_fForceDown = pSrc.m_fForceDown;
return true;
}
// On first tick
protected override void OnFirstTick()
{
m_pHost.m_iMoveEnv = (int)MoveEnvironment.MOVEENV_GROUND;
m_pHost.m_iMoveMode = (int)MoveMode.MOVE_FREEFALL;
m_vDirH = m_pHost.m_vVelocity;
m_vDirH.y = 0.0f;
m_fSpeedH = m_vDirH.Normalize();
if (m_fSpeedH > m_pHost.GetGroundSpeed())
m_fSpeedH = m_pHost.GetGroundSpeed();
// Clear N
m_pHost.m_CDRInfo.vTPNormal = new A3DVECTOR3(0);
}
// Work is cancel
public override void Cancel()
{
m_pHost.m_CDRInfo.vAbsVelocity = new A3DVECTOR3(0);
if (m_pHost.m_CDRInfo.vTPNormal == new A3DVECTOR3(0))
{
m_pHost.m_CDRInfo.fYVel = 0.0f;
}
base.Cancel();
}
// Tick routine
public override bool Tick(float dwDeltaTime)
{
base.Tick(dwDeltaTime);
var m_pEquipPack = m_pHost.GetInventory(InventoryConst.IVTRTYPE_EQUIPPACK);
if (m_pEquipPack.GetItem(InventoryConst.EQUIPIVTR_FLYSWORD, false) == null)
m_iFallMode = (int)GPMoveMode.GP_MOVE_FALL;
else
m_iFallMode = (int)GPMoveMode.GP_MOVE_FLYFALL;
if (m_pHost.IsDead())
m_iFallMode |= (int)GPMoveMode.GP_MOVE_DEAD;
if (!m_pHost.IsRooting())
{
float fDeltaTime = dwDeltaTime;
if (m_pHost.m_iMoveEnv == (int)MoveEnvironment.MOVEENV_GROUND ||
m_pHost.m_iMoveEnv == (int)MoveEnvironment.MOVEENV_AIR)
{
if (m_iFallType == Fall_type.TYPE_FLYFALL)
Fall_Air(fDeltaTime);
else
FreeFall_Air(fDeltaTime);
}
else // m_pHost.m_iMoveEnv == CECPlayer::MOVEENV_WATER
{
if (m_iFallType == Fall_type.TYPE_FLYFALL)
Fall_Water(fDeltaTime);
else
FreeFall_Water(fDeltaTime);
}
}
return true;
}
// Free fall in air
public bool Fall_Air(float fDeltaTime)
{
A3DVECTOR3 vCurPos = m_pHost.GetPos();
// A3DVECTOR3 vCurVel = m_pHost.m_vVelocity;
CDR_INFO cdr = m_pHost.m_CDRInfo;
bool bWorkEnd = false;
if (m_pHost.m_GndInfo.bOnGround)
{
bWorkEnd = true;
//if (m_pHost.UsingWing())
if (m_pHost.GetWingType() == enumWingType.WINGTYPE_WING)
m_pHost.PlayAction((int)PLAYER_ACTION_TYPE.ACT_LANDON, false);
else
m_pHost.PlayAction((int)PLAYER_ACTION_TYPE.ACT_LANDON_SWORD, false);
}
else
{
vCurPos = m_pHost.m_MoveCtrl.GroundMove(m_vDirH, m_fSpeedH, fDeltaTime);
if (m_pHost.m_MoveCtrl.MoveBlocked() >= 3)
{
bWorkEnd = true;
//if (m_pHost.UsingWing())
if (m_pHost.GetWingType() == enumWingType.WINGTYPE_WING)
m_pHost.PlayAction((int)PLAYER_ACTION_TYPE.ACT_LANDON, false);
else
m_pHost.PlayAction((int)PLAYER_ACTION_TYPE.ACT_LANDON_SWORD, false);
}
else
{
float fHei = vCurPos.y - m_pHost.m_GndInfo.fGndHei;
if (fHei > 25f)
{
if (m_nCurStage == FlyFallStage.enumStageNone)
{
m_nCurStage = FlyFallStage.enumStageUpperAir;
//if (m_pHost.UsingWing())
if (m_pHost.GetWingType() == enumWingType.WINGTYPE_WING)
m_pHost.PlayAction((int)PLAYER_ACTION_TYPE.ACT_FLYDOWN, false);
else
m_pHost.PlayAction((int)PLAYER_ACTION_TYPE.ACT_FLYDOWN_SWORD_HIGH, false);
}
}
else if (fHei > 20f)
{
if (m_nCurStage == FlyFallStage.enumStageNone)
{
m_nCurStage = FlyFallStage.enumStageLowerAir;
//if (m_pHost.UsingWing())
if (m_pHost.GetWingType() == enumWingType.WINGTYPE_WING)
m_pHost.PlayAction((int)PLAYER_ACTION_TYPE.ACT_FLYDOWN_WING_LOW, false);
else
m_pHost.PlayAction((int)PLAYER_ACTION_TYPE.ACT_FLYDOWN_SWORD_LOW, false);
}
}
else if (fHei > 3.0f)
{
if (m_nCurStage == FlyFallStage.enumStageNone
|| m_nCurStage == FlyFallStage.enumStageUpperAir)
{
m_nCurStage = FlyFallStage.enumStageLowerAir;
//if (m_pHost.UsingWing())
if (m_pHost.GetWingType() == enumWingType.WINGTYPE_WING)
m_pHost.PlayAction((int)PLAYER_ACTION_TYPE.ACT_FLYDOWN_WING_LOW, false);
else
m_pHost.PlayAction((int)PLAYER_ACTION_TYPE.ACT_FLYDOWN_SWORD_LOW, false);
}
}
else
{
if (m_nCurStage != FlyFallStage.enumStageLandOn)
{
m_nCurStage = FlyFallStage.enumStageLandOn;
//if (m_pHost.UsingWing())
if (m_pHost.GetWingType() == enumWingType.WINGTYPE_WING)
m_pHost.PlayAction((int)PLAYER_ACTION_TYPE.ACT_LANDON, false);
else
m_pHost.PlayAction((int)PLAYER_ACTION_TYPE.ACT_LANDON_SWORD, false);
}
}
}
m_pHost.SetPos(EC_Utility.ToVector3(vCurPos));
}
if (bWorkEnd)
{
Finish();
m_pHost.SetPos(EC_Utility.ToVector3(vCurPos));
float fSpeed = EC_Utility.ToVector3(cdr.vAbsVelocity).magnitude;
if (Math.Abs(fSpeed - 0) < float.Epsilon)
fSpeed = m_pHost.GetFlySpeed();
m_pHost.m_MoveCtrl.SendStopMoveCmd(EC_Utility.ToVector3(vCurPos), fSpeed, m_iFallMode);
m_pHost.m_vVelocity.Clear();
return true;
}
else
{
m_pHost.m_MoveCtrl.SendMoveCmd(vCurPos, 2, EC_Utility.ToA3DVECTOR3(g_vOrigin), (cdr.vAbsVelocity), m_iFallMode);
}
return true;
}
// Free fall in air
public bool FreeFall_Air(float fDeltaTime)
{
A3DVECTOR3 vCurPos = m_pHost.GetPos();
// A3DVECTOR3 vCurVel = m_pHost.m_vVelocity;
CDR_INFO cdr = m_pHost.m_CDRInfo;
if (m_pHost.m_GndInfo.bOnGround)
{
Finish();
m_pHost.SetPos(EC_Utility.ToVector3(vCurPos));
float fSpeed = EC_Utility.ToVector3(cdr.vAbsVelocity).magnitude;
if (Math.Abs(fSpeed - 0) < float.Epsilon)
fSpeed = m_pHost.GetFlySpeed();
m_pHost.m_MoveCtrl.SendStopMoveCmd(EC_Utility.ToVector3(vCurPos), fSpeed, m_iFallMode);
m_pHost.m_vVelocity.Clear();
}
else
{
vCurPos = m_pHost.m_MoveCtrl.GroundMove(m_vDirH, m_fSpeedH, fDeltaTime);
// If player is blocked, add disturb speed at random direction
if (m_pHost.m_MoveCtrl.MoveBlocked() >= 3)
{
cdr.fYVel = 0.0f;
Finish();
m_pHost.SetPos(EC_Utility.ToVector3(vCurPos));
m_pHost.m_MoveCtrl.SendStopMoveCmd(EC_Utility.ToVector3(vCurPos), 5.0f, m_iFallMode);
}
/* {
m_fSpeedH = 3.0f;
m_vDirH = glb_RandomVectorH();
}
else
{
m_fSpeedH = 0.0f;
m_vDirH.Clear();
} */
m_pHost.SetPos(EC_Utility.ToVector3(vCurPos));
m_pHost.m_MoveCtrl.SendMoveCmd(vCurPos, 2, EC_Utility.ToA3DVECTOR3(g_vOrigin), (cdr.vAbsVelocity), m_iFallMode);
m_pHost.PlayAction((int)PLAYER_ACTION_TYPE.ACT_JUMP_LOOP, false);
}
return true;
}
private float A3d_Magnitude(A3DVECTOR3 v)
{
return Mathf.Sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
}
// Finish
public void Finish()
{
m_bFinished = true;
m_pHost.m_CDRInfo.vAbsVelocity = new A3DVECTOR3(0);
// m_pHost.m_CDRInfo.fYVel = 0.0f;
if (m_iFallType == Fall_type.TYPE_FLYFALL)
m_pHost.ShowWing(false);
}
// Free fall in water
bool Fall_Water(float fDeltaTime)
{
A3DVECTOR3 vCurPos = m_pHost.GetPos();
A3DVECTOR3 vCurVel = m_pHost.m_vVelocity;
float fGndHei = m_pHost.m_GndInfo.fGndHei;
if (!m_bEnterWater)
{
m_bEnterWater = true;
vCurVel = m_pHost.m_CDRInfo.vAbsVelocity;
float fWaterHei = m_pHost.m_GndInfo.fWaterHei;
if (fWaterHei - fGndHei > 1.5f)
m_nCurStage = FlyFallStage.enumStageDeepWater;
else
m_nCurStage = FlyFallStage.enumStageShallowWater;
}
float fSpeed1 = vCurVel.Normalize();
float na = -fSpeed1 * 0.7f + EC_NACCE_WATER * 4.0f;
float fSpeed2 = fSpeed1 + na * fDeltaTime;
if (fSpeed2 * fSpeed1 < 0.0f)
fSpeed2 = 0.0f;
if (m_fForceDown)
{
// Note: When speed=0 we should check whether a special case: EstimateMoveEnv find
// we are in water but we stop at a underwater position which is very close
// to water surface.
// if (vCurPos.y < m_pHost.m_GndInfo.fWaterHei &&
// m_pHost.m_GndInfo.fWaterHei - m_pHost.m_GndInfo.fGndHei > m_pHost.m_MoveConst.fShoreDepth &&
if (m_pHost.CheckWaterMoveEnv(vCurPos, m_pHost.m_GndInfo.fWaterHei, m_pHost.m_GndInfo.fGndHei) &&
m_pHost.m_GndInfo.fWaterHei - vCurPos.y < m_pHost.m_MoveConst.fShoreDepth)
{
vCurPos = m_pHost.m_MoveCtrl.GroundMove(m_vDirH, m_fSpeedH, fDeltaTime, -5.0f);
m_pHost.SetPos(EC_Utility.ToVector3(vCurPos));
if (m_pHost.m_MoveCtrl.MoveBlocked() >= 3)
{
// Fall on ground
Finish();
m_pHost.m_MoveCtrl.SendStopMoveCmd(EC_Utility.ToVector3(vCurPos), m_pHost.m_vVelocity.Magnitude(), (int)GPMoveMode.GP_MOVE_WATER | m_iFallMode);
m_pHost.m_vVelocity.Clear();
}
return true;
}
}
if (Math.Abs(fSpeed2 - 0f) > float.Epsilon)
{
A3DVECTOR3 vOldPos = vCurPos;
vCurPos = m_pHost.m_MoveCtrl.AirWaterMove(vCurVel, fSpeed2, fDeltaTime, false, false);
vCurVel *= fSpeed2;
if (m_nCurStage == FlyFallStage.enumStageShallowWater)
{
if (vCurPos.y - fGndHei < 1.0f)
{
//if (m_pHost.UsingWing())
if (m_pHost.GetWingType() == enumWingType.WINGTYPE_WING)
m_pHost.PlayAction((int)PLAYER_ACTION_TYPE.ACT_LANDON, false);
else
m_pHost.PlayAction((int)PLAYER_ACTION_TYPE.ACT_LANDON_SWORD, false);
m_nCurStage = FlyFallStage.enumStageLandOn;
}
}
else if (m_nCurStage == FlyFallStage.enumStageDeepWater)
{
if (vCurVel.y > -9.0f)
m_pHost.PlayAction((int)PLAYER_ACTION_TYPE.ACT_HANGINWATER, false);
}
if (m_pHost.m_MoveCtrl.MoveBlocked() >= 3 ||
vCurPos.y - m_pHost.m_MoveConst.fMinWaterHei <= fGndHei)
{
// Fall on ground
Finish();
m_pHost.m_MoveCtrl.SendStopMoveCmd(EC_Utility.ToVector3(vCurPos), m_pHost.m_vVelocity.Magnitude(), (int)GPMoveMode.GP_MOVE_WATER | m_iFallMode);
m_pHost.SetPos(EC_Utility.ToVector3(vCurPos));
m_pHost.m_vVelocity.Clear();
}
else
{
m_pHost.m_MoveCtrl.SendMoveCmd(vCurPos, 2, EC_Utility.ToA3DVECTOR3(g_vOrigin), vCurVel, (int)GPMoveMode.GP_MOVE_WATER | m_iFallMode);
m_pHost.SetPos(EC_Utility.ToVector3(vCurPos));
m_pHost.m_vVelocity = vCurVel;
}
// If moving too small
if (A3d_Magnitude(vCurPos - vOldPos) < 0.001f)
m_fForceDown = true;
}
else
{
Finish();
m_pHost.m_MoveCtrl.SendStopMoveCmd(EC_Utility.ToVector3(vCurPos), fSpeed1, (int)GPMoveMode.GP_MOVE_WATER | m_iFallMode);
m_pHost.SetPos(EC_Utility.ToVector3(vCurPos));
m_pHost.m_vVelocity.Clear();
}
return true;
}
// Free fall in water
bool FreeFall_Water(float fDeltaTime)
{
A3DVECTOR3 vCurPos = m_pHost.GetPos();
A3DVECTOR3 vCurVel = m_pHost.m_vVelocity;
float fGndHei = m_pHost.m_GndInfo.fGndHei;
if (!m_bEnterWater)
{
m_bEnterWater = true;
vCurVel = m_pHost.m_CDRInfo.vAbsVelocity;
float fWaterHei = m_pHost.m_GndInfo.fWaterHei;
if (fWaterHei - fGndHei > 1.5f)
m_nCurStage = FlyFallStage.enumStageDeepWater;
else
m_nCurStage = FlyFallStage.enumStageShallowWater;
}
float fSpeed1 = vCurVel.Normalize();
float na = EC_NACCE_WATER * 4.0f;
float fSpeed2 = fSpeed1 + na * fDeltaTime;
if (fSpeed2 * fSpeed1 < 0.0f)
fSpeed2 = 0.0f;
if (Math.Abs(fSpeed2 - 0f) > float.Epsilon)
{
vCurPos = m_pHost.m_MoveCtrl.AirWaterMove(vCurVel, fSpeed2, fDeltaTime, false, false);
vCurVel *= fSpeed2;
if (m_pHost.m_MoveCtrl.MoveBlocked() >= 3 ||
vCurPos.y - m_pHost.m_MoveConst.fMinWaterHei <= fGndHei)
{
// Fall on ground
Finish();
m_pHost.m_MoveCtrl.SendStopMoveCmd(EC_Utility.ToVector3(vCurPos), m_pHost.m_vVelocity.Magnitude(), (int)GPMoveMode.GP_MOVE_WATER | m_iFallMode);
m_pHost.SetPos(EC_Utility.ToVector3(vCurPos));
m_pHost.m_vVelocity.Clear();
}
else
{
m_pHost.m_MoveCtrl.SendMoveCmd(vCurPos, 2, EC_Utility.ToA3DVECTOR3(g_vOrigin), vCurVel, (int)GPMoveMode.GP_MOVE_WATER | m_iFallMode);
m_pHost.SetPos(EC_Utility.ToVector3(vCurPos));
m_pHost.m_vVelocity = vCurVel;
if (m_nCurStage == FlyFallStage.enumStageDeepWater)
m_pHost.PlayAction((int)PLAYER_ACTION_TYPE.ACT_HANGINWATER, false);
else
m_pHost.PlayAction((int)PLAYER_ACTION_TYPE.ACT_JUMP_LOOP, false);
}
}
else
{
Finish();
m_pHost.m_MoveCtrl.SendStopMoveCmd(EC_Utility.ToVector3(vCurPos), fSpeed1, (int)GPMoveMode.GP_MOVE_WATER | m_iFallMode);
m_pHost.SetPos(EC_Utility.ToVector3(vCurPos));
m_pHost.m_vVelocity.Clear();
}
return true;
}
}
}