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; } } }