using System; using System.Collections.Generic; using System.Data.Odbc; using System.Linq; using Animancer; using BITFALL.Player.Equip; using BITFALL.Player.Movement; using BITKit; using BITKit.Animations; 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 sealed class Movement : GunState { [SerializeField] private ExpectState _expectRun; [Inject] private ISelector _selector; private float requestBoltActionElapsedTime; private bool boltActionImmediately; private AnimancerState inspectState; private AnimancerState crouchState; public override void OnStateEntry(IState old) { switch (old) { case Movement: case Equip: break; default: if (_entityMovement.CurrentState is IPlayerWalkState) PlayAnimation(); else OnMovementStateChanged(null, _entityMovement.CurrentState); break; } _selector.OnActive += OnActive; boltActionImmediately = root.RequireBolt; root.inputActionGroup.RegisterCallback(root.inspectAction, OnInspect); } private void OnInspect(InputAction.CallbackContext obj) { PlayAnimation("Inspect"); // if (root.MotionMatchingService.TryMatch(out var value, SearchKey.Append(BITConstant.Player.Inspect).ToArray()) is false) // { // Debug.LogWarning("No inspect animation found"); // return; // } // Debug.Log(value); // switch (value) // { // case IMotionMatchingClip clip: // inspectState = animancerComponent.Layers[1].Play(clip.Clip); // inspectState.Events.OnEnd = () => { animancerComponent.Layers[1].Stop(); }; // break; // } } public override void OnStateExit(IState old, IState newState) { requestBoltActionElapsedTime = 0; base.OnStateExit(old, newState); _selector.OnActive -= OnActive; root.inputActionGroup.UnRegisterCallback(root.inspectAction, OnInspect); if (inspectState != null) { inspectState.Events.OnEnd = null; inspectState.Stop(); } } 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); PlayAnimation(root.SearchKey.Append(nameof(BITConstant.Player.Interactive)).ToArray()); } public override void OnMovementStateChanged(IEntityMovementState old, IEntityMovementState newState) { _expectRun = newState is IPlayerRunState or IPlayerSprintState; if (newState is IPlayerSlideState) { if (root.CurrentState != this) root.TransitionState(); PlayAnimation(BITConstant.Player.Slide); //root.animator.CrossFade(BITConstant.Player.Slide, 0.32f); } else if (newState is IPlayerDodgeState) { if (root.CurrentState != this) root.TransitionState(); PlayAnimation(BITConstant.Player.Dodge); } else if (Enabled) { switch (newState) { case IPlayerCrouchState: PlayAnimation(root.SearchKey.Append(nameof(BITConstant.Player.Crouch)).ToArray()); break; case IPlayerMovementState: PlayAnimation(); break; } } } } [System.Serializable] public sealed class Run : GunState { private ExpectState _expectRun; private ExpectState _expectSprint; public override void OnStateEntry(IState old) { PlayAnimation(root.SearchKey.Append(nameof(BITConstant.Player.Run)).ToArray()); 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); // PlayAnimation(SearchKey.Append(nameof(BITConstant.Player.Run)).ToArray()); // } if(_expectSprint) { root.TransitionState(); } else if(_expectRun == false) { root.TransitionState(); } else { currentState.Speed = _entityMovement.LocomotionBasedVelocity.GetLength() / _entityMovement.ReferenceSpeed; } } 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) { base.OnStateEntry(old); //root.animator.CrossFade(BITConstant.Player.Sprint, 0.32f); //PlayAnimation(root.SearchKey.Append(nameof(BITConstant.Player.Sprint)).ToArray()); 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(); } else { currentState.Speed = _entityMovement.LocomotionBasedVelocity.GetLength() / _entityMovement.ReferenceSpeed; } } 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); // PlayAnimation(root.SearchKey.Append(nameof(BITConstant.Player.Aim)).ToArray()); // break; // default: // PlayAnimation(root.SearchKey.Append(nameof(BITConstant.Player.Aim)).ToArray()); // break; // } base.OnStateEntry(old); _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(); } equipService.Aim = currentState.Weight; 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 { [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); } } } protected override void OnEnd() { root.TransitionState(); } public override void OnStateEntry(IState old) { base.OnStateEntry(old); 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)); } } [System.Serializable] public sealed class Reload:GunState { protected override void OnEnd() { 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 { protected override void OnEnd() { 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); _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) { switch (newState) { case IPlayerClimbState: case IPlayerLinkState { LinkArea: 44 }: case IPlayerVaultState: root.TransitionState(); break; default: if (Enabled) { root.TransitionState(); } break; } } } [System.Serializable] public sealed class Holster : GunState { protected override void OnEnd() { animancerComponent.Stop(); } } }