using UnityEngine; using SanAndreasUnity.Utilities; using SanAndreasUnity.Importing.Animation; namespace SanAndreasUnity.Behaviours.Peds.States { /// /// Base class for all movement states. /// public abstract class BaseMovementState : BaseScriptState { public abstract AnimId movementAnim { get; } public abstract AnimId movementWeaponAnim { get; } public virtual float TimeUntilStateCanBeSwitchedToOtherMovementState => PedManager.Instance.timeUntilMovementStateCanBeSwitchedToOtherMovementState; public virtual float TimeUntilStateCanBeEnteredFromOtherMovementState => PedManager.Instance.timeUntilMovementStateCanBeEnteredFromOtherMovementState; public override void UpdateState() { base.UpdateState (); if (!this.IsActiveState) return; if (m_isServer) this.SwitchToMovementState (); if (!this.IsActiveState) return; if (m_isServer) this.SwitchToAimState (); } protected virtual void SwitchToMovementState() { if (this.TimeSinceActivated <= this.TimeUntilStateCanBeSwitchedToOtherMovementState) return; System.Type type = BaseMovementState.GetMovementStateToSwitchToBasedOnInput(m_ped); var state = (BaseMovementState) m_ped.GetStateOrLogError(type); if (state.TimeSinceDeactivated <= state.TimeUntilStateCanBeEnteredFromOtherMovementState) return; m_ped.SwitchState(type); } public static void SwitchToMovementStateBasedOnInput (Ped ped) { System.Type type = GetMovementStateToSwitchToBasedOnInput(ped); ped.SwitchState(type); } public static System.Type GetMovementStateToSwitchToBasedOnInput(Ped ped) { if (ped.IsJumpOn && ped.GetStateOrLogError().CanJump()) { return typeof(JumpState); } else if (ped.IsWalkOn) { return typeof(WalkState); } else if (ped.IsRunOn) { return typeof(RunState); } else if (ped.IsSprintOn) { if (ped.CurrentWeapon != null && !ped.CurrentWeapon.CanSprintWithIt) return typeof(RunState); else return typeof(SprintState); } else { return typeof(StandState); } } protected virtual void SwitchToAimState() { if (m_ped.IsAimOn && m_ped.IsHoldingWeapon && EnoughTimePassedToSwitchToAimState(m_ped)) { BaseAimMovementState.SwitchToAimMovementStateBasedOnInput (m_ped); } } public static bool EnoughTimePassedToSwitchToAimState(Ped ped) { var aimStates = ped.CachedAimStates; for (int i = 0; i < aimStates.Count; i++) { if (Time.time - aimStates[i].LastTimeWhenDeactivated < PedManager.Instance.minTimeToReturnToAimState) return false; } return true; } protected override void UpdateAnims () { if (m_ped.CurrentWeapon != null) { m_ped.PlayerModel.PlayAnim (this.movementWeaponAnim); } else { m_ped.PlayerModel.PlayAnim (this.movementAnim); } } public override void OnSubmitPressed() { // try to enter vehicle if (m_isServer) m_ped.TryEnterVehicleInRange (); else base.OnSubmitPressed(); } public override void OnCrouchButtonPressed () { if (m_isServer) m_ped.SwitchState(); else base.OnCrouchButtonPressed(); } public override void OnFlyButtonPressed () { if (m_isServer) m_ped.GetStateOrLogError ().EnterState (false); } public override void OnFlyThroughButtonPressed () { if (m_isServer) m_ped.GetStateOrLogError ().EnterState (true); } } }