using System; using System.Collections.Generic; using System.Data.Odbc; using System.Linq; using BITFALL.Player.Equip; using BITFALL.Player.Movement; using BITKit; using BITKit.Entities; using BITKit.Selection; using UnityEngine.InputSystem; using BITKit.StateMachine; using UnityEngine; // ReSharper disable UnassignedField.Local namespace BITFALL.Guns.States { [System.Serializable] public sealed class None:GunState { } [System.Serializable] public class Movement : GunState { [SerializeField] private ExpectState _expectRun; [Inject] protected ISelector _selector; private float requestBoltActionElapsedTime; private bool boltActionImmediately; public override void OnStateEntry(IState old) { switch (old) { case Movement: case Equip: break; case Aim: root.animator.CrossFade(BITConstant.Player.Movement, 0.32f); break; default: root.animator.CrossFade(BITConstant.Player.Movement, 0.16f); break; } _selector.OnActive += OnActive; boltActionImmediately = root.RequireBolt; } public override void OnStateExit(IState old, IState newState) { requestBoltActionElapsedTime = 0; base.OnStateExit(old, newState); _selector.OnActive -= OnActive; } public override void OnStateUpdate(float deltaTime) { if (root.RequireBolt) requestBoltActionElapsedTime += deltaTime; if (root.animator[0].stateName is not BITConstant.Player.Movement) return; if (root.expectFiring.shouldBe && root.fireInterval.AllowUpdate) { root.Fire(); } if (root.expectAiming.shouldBe && BITAppForUnity.AllowCursor == false) { root.TransitionState(); return; } if (_expectRun) { root.TransitionState(); return; } switch (root.RequireBolt) { case var _ when boltActionImmediately: case var _ when requestBoltActionElapsedTime > 1f: case var _ when root.animator[4].stateName == BITConstant.Player.Empty && requestBoltActionElapsedTime>0.32f: root.TransitionState(); break; } } public void OnActive(ISelectable selectable) { root.animator.Play(BITConstant.Player.Interactive); } public override void OnMovementStateChanged(IEntityMovementState old, IEntityMovementState newState) { _expectRun = newState is IPlayerRunState or IPlayerSprintState; if (newState is IPlayerSlideState) { root.TransitionState(); root.animator.CrossFade(BITConstant.Player.Slide, 0.32f); } } } [System.Serializable] public sealed class Run : GunState { private ExpectState _expectRun; private ExpectState _expectSprint; public override void OnStateEntry(IState old) { root.animator.CrossFade(BITConstant.Player.Run, 0.16f); root.inputActionGroup.RegisterCallback(root.aimAction, OnAim); } public override void OnStateExit(IState old, IState newState) { root.inputActionGroup.UnRegisterCallback(root.aimAction, OnAim); } public override void OnStateUpdate(float deltaTime) { if (root.animator[0].stateName == BITConstant.Player.Movement) { root.animator.CrossFade(BITConstant.Player.Run, 0.32f); } if(_expectSprint) { root.TransitionState(); } else if(_expectRun == false) { root.TransitionState(); } } private void OnAim(InputAction.CallbackContext context) { if (context.started && BITAppForUnity.AllowCursor == false) { root.TransitionState(); } } public override void OnMovementStateChanged(IEntityMovementState old, IEntityMovementState newState) { _expectRun = newState is IPlayerRunState or IPlayerSprintState; _expectSprint = newState is IPlayerSprintState; } } [System.Serializable] public sealed class Sprint : GunState { private ExpectState _expectSprint; public override void OnStateEntry(IState old) { root.animator.CrossFade(BITConstant.Player.Sprint, 0.32f); root.inputActionGroup.RegisterCallback(root.aimAction, OnAim); } public override void OnStateExit(IState old, IState newState) { root.inputActionGroup.UnRegisterCallback(root.aimAction, OnAim); } public override void OnStateUpdate(float deltaTime) { if(_expectSprint == false) { root.TransitionState(); } } private void OnAim(InputAction.CallbackContext context) { if (context.started && BITAppForUnity.AllowCursor == false) { root.TransitionState(); } } public override void OnMovementStateChanged(IEntityMovementState old, IEntityMovementState newState) { _expectSprint = newState is IPlayerSprintState; } } [System.Serializable] public sealed class Aim : GunState { public override void OnStateEntry(IState old) { switch (old) { case IPlayerRunState: case IPlayerSprintState: root.animator.CrossFade(BITConstant.Player.Aim, 0.32f); break; default: root.animator.CrossFade(BITConstant.Player.Aim, 0.16f); break; } _entityMovement.ExecuteCommand(new(this,true)); _entityMovement.ExecuteCommand(new PlayerLimitMoveSpeedCommand() { Id = BITHash.Player.Aim, Limit =true, Speed = root._gun.InitialAimMovementSpeed, }); } public override void OnStateExit(IState old, IState newState) { base.OnStateExit(old, newState); _entityMovement.ExecuteCommand(new(this,false)); _entityMovement.ExecuteCommand(new PlayerLimitMoveSpeedCommand() { Id = BITHash.Player.Aim, Limit =false, Speed = root._gun.InitialAimMovementSpeed, }); } public override void OnStateUpdate(float deltaTime) { if (root.expectFiring.shouldBe && root.fireInterval.AllowUpdate) { root.Fire(); } if (BITAppForUnity.AllowCursor) { root.TransitionState(); } else if (root.expectAiming.shouldBe) { } else { root.TransitionState(); } } public override void OnMovementStateChanged(IEntityMovementState old, IEntityMovementState newState) { if (Enabled is false) return; if (newState is not (IPlayerRunState or IPlayerSprintState)) return; root.expectAiming.Reset(); root.TransitionState(); } } [System.Serializable] public sealed class Equip : GunState { private bool completed; [Inject] private IPlayerEquipSelector _equipSelector; public override void Initialize() { base.Initialize(); root.animator[0].onStateExit += OnAnimationStateExit; _equipSelector.OnUpdateEquip += OnUpdateEquip; } private readonly List _drawed = new(); private void OnUpdateEquip(IDictionary obj) { foreach (var x in _drawed.ToArray()) { if (obj.Any(pair => _drawed.Contains(pair.Value.Id)) is false) { _drawed.Remove(x); } } } private void OnAnimationStateExit(string obj) { if (obj is BITConstant.Player.Draw) completed = true; } public override void OnStateEntry(IState old) { base.OnStateEntry(old); completed = false; if (_drawed.TryAdd(root.Item.Id)) { root.UnityEntity.Invoke(Constant.Animation.Play, BITConstant.Player.Draw); //root.animator.Play(BITConstant.Player.Draw, -1, 0); } else { root.UnityEntity.Invoke(Constant.Animation.Play, BITConstant.Player.QuickDraw); //root.animator.Play(BITConstant.Player.QuickDraw,-1,0); } _entityMovement.ExecuteCommand(new(this,true)); } public override void OnStateExit(IState old, IState newState) { base.OnStateExit(old, newState); _entityMovement.ExecuteCommand(new(this,false)); } public override void OnStateUpdate(float deltaTime) { if (completed) { root.TransitionState(); } } } [System.Serializable] public sealed class Reload:GunState { public override void Initialize() { base.Initialize(); root.animator[0].onStateExit += OnAnimationStateExit; } private void OnAnimationStateExit(string obj) { if (Enabled is false) return; if(obj is BITConstant.Player.Reload) { root.TransitionState(); } } public override void OnStateEntry(IState old) { base.OnStateEntry(old); _entityMovement.ExecuteCommand(new(this,true)); if (root.RequireBolt) { root.UnityEntity.Invoke(Constant.Animation.Play, BITConstant.Player.BoltAction); } else { root.UnityEntity.Invoke(Constant.Animation.Play, BITConstant.Player.Reload); } } public override void OnMovementStateChanged(IEntityMovementState old, IEntityMovementState newState) { if (Enabled is false) return; if (newState is IPlayerRunState or IPlayerSprintState) { root.TransitionState(); } } public override void OnStateExit(IState old, IState newState) { root.RequireBolt = false; base.OnStateExit(old, newState); _entityMovement.ExecuteCommand(new(this,false)); } } [System.Serializable] public sealed class Melee : GunState { public override void Initialize() { base.Initialize(); root.animator[0].onStateExit += OnAnimationStateExit; } private void OnAnimationStateExit(string obj) { if (Enabled is false) return; if (obj is BITConstant.Player.Melee) { root.TransitionState(); } } public override void OnStateEntry(IState old) { base.OnStateEntry(old); root.UnityEntity.Invoke(Constant.Animation.Play, BITConstant.Player.Melee); _entityMovement.ExecuteCommand(new(this,true)); _entityMovement.ExecuteCommand(new PlayerFocusCommand() { Focus = true, Sender = this }); } public override void OnStateExit(IState old, IState newState) { base.OnStateExit(old,newState); _entityMovement.ExecuteCommand(new(this,false)); _entityMovement.ExecuteCommand(new PlayerFocusCommand() { Focus = false, Sender = this }); } public override void OnStateUpdate(float deltaTime) { _entityMovement.ExecuteCommand(); } public override void OnMovementStateChanged(IEntityMovementState old, IEntityMovementState newState) { if (Enabled is false) return; if (newState is IPlayerRunState or IPlayerSprintState) { root.TransitionState(); } } } [System.Serializable] public sealed class Climb:GunState { public override void OnStateEntry(IState old) { base.OnStateEntry(old); root.animator.Play(BITConstant.Player.Climb); _entityMovement.ExecuteCommand(new(this,true)); } public override void OnStateExit(IState old, IState newState) { base.OnStateExit(old, newState); _entityMovement.ExecuteCommand(new(this,false)); } public override void OnMovementStateChanged(IEntityMovementState old, IEntityMovementState newState) { if(newState is IPlayerClimbState || (newState is IPlayerLinkState linkState && linkState.LinkArea == 4) ) { root.TransitionState(); }else if (Enabled) { root.TransitionState(); } } } [System.Serializable] public sealed class Holster : GunState { public override void OnStateEntry(IState old) { //root.animator.CrossFade(BITConstant.Player.Holster,0.16f); root.UnityEntity.Invoke(Constant.Animation.Play, BITConstant.Player.Holster); } } }