BITFALL/Assets/Artists/Scripts/Equip/BITGunStates.cs

442 lines
14 KiB
C#

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<bool> _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<Aim>();
return;
}
if (_expectRun)
{
root.TransitionState<Run>();
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<Reload>();
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<Movement>();
root.animator.CrossFade(BITConstant.Player.Slide, 0.32f);
}
}
}
[System.Serializable]
public sealed class Run : GunState
{
private ExpectState<bool> _expectRun;
private ExpectState<bool> _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<Sprint>();
}
else if(_expectRun == false)
{
root.TransitionState<Movement>();
}
}
private void OnAim(InputAction.CallbackContext context)
{
if (context.started && BITAppForUnity.AllowCursor == false)
{
root.TransitionState<Aim>();
}
}
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<bool> _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<Movement>();
}
}
private void OnAim(InputAction.CallbackContext context)
{
if (context.started && BITAppForUnity.AllowCursor == false)
{
root.TransitionState<Aim>();
}
}
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<PlayerPauseRunCommand>(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<PlayerPauseRunCommand>(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<Movement>();
}
else if (root.expectAiming.shouldBe)
{
}
else
{
root.TransitionState<Movement>();
}
}
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<Movement>();
}
}
[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<int> _drawed = new();
private void OnUpdateEquip(IDictionary<int, IBasicItem> 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<PlayerPauseRunCommand>(new(this,true));
}
public override void OnStateExit(IState old, IState newState)
{
base.OnStateExit(old, newState);
_entityMovement.ExecuteCommand<PlayerPauseRunCommand>(new(this,false));
}
public override void OnStateUpdate(float deltaTime)
{
if (completed)
{
root.TransitionState<Movement>();
}
}
}
[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<Movement>();
}
}
public override void OnStateEntry(IState old)
{
base.OnStateEntry(old);
_entityMovement.ExecuteCommand<PlayerPauseRunCommand>(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<Movement>();
}
}
public override void OnStateExit(IState old, IState newState)
{
root.RequireBolt = false;
base.OnStateExit(old, newState);
_entityMovement.ExecuteCommand<PlayerPauseRunCommand>(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<Movement>();
}
}
public override void OnStateEntry(IState old)
{
base.OnStateEntry(old);
root.UnityEntity.Invoke(Constant.Animation.Play, BITConstant.Player.Melee);
_entityMovement.ExecuteCommand<PlayerPauseRunCommand>(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<PlayerPauseRunCommand>(new(this,false));
_entityMovement.ExecuteCommand(new PlayerFocusCommand()
{
Focus = false,
Sender = this
});
}
public override void OnStateUpdate(float deltaTime)
{
_entityMovement.ExecuteCommand<PlayerCancelRunCommand>();
}
public override void OnMovementStateChanged(IEntityMovementState old, IEntityMovementState newState)
{
if (Enabled is false) return;
if (newState is IPlayerRunState or IPlayerSprintState)
{
root.TransitionState<Movement>();
}
}
}
[System.Serializable]
public sealed class Climb:GunState
{
public override void OnStateEntry(IState old)
{
base.OnStateEntry(old);
root.animator.Play(BITConstant.Player.Climb);
_entityMovement.ExecuteCommand<PlayerPauseRunCommand>(new(this,true));
}
public override void OnStateExit(IState old, IState newState)
{
base.OnStateExit(old, newState);
_entityMovement.ExecuteCommand<PlayerPauseRunCommand>(new(this,false));
}
public override void OnMovementStateChanged(IEntityMovementState old, IEntityMovementState newState)
{
if(newState is IPlayerClimbState || (newState is IPlayerLinkState linkState && linkState.LinkArea == 4) )
{
root.TransitionState<Climb>();
}else if (Enabled)
{
root.TransitionState<Movement>();
}
}
}
[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);
}
}
}