NPCs/Implementation/Crackhead/BlockingState.cs

namespace Opium.AI;

[Title( "Block" ), Description( "The blocking state." )]
public partial class BlockingState : StateMachine.State
{
	public override List<Type> FromStates => new()
	{
		typeof( AttackingState )
	};

	public override UpperBodyState GetUpperAnimationState()
	{
		if ( TimeInState < 0.25f ) return UpperBodyState.Charge;
		if ( TimeInState < 3f ) return UpperBodyState.Block;
		return UpperBodyState.Charge;
	}

	public override bool ShouldEnterState( StateMachine machine )
	{
		if ( machine.CurrentState is AttackingState )
		{
			if ( machine.TimeInState < 1.5f && machine.TimeInState > 0.5f ) return false;
		}

		if ( Agent.LastStimulus is null || Agent.LastStimulus.HasExpired )
			return false;

		if ( Agent.LastStimulus is AnticipateHitStimulus )
			return true;

		return base.ShouldEnterState( machine );
	}

	public override void OnStateExit( StateMachine.State next )
	{
		if ( Agent.Weapon is MeleeWeapon melee )
		{
			melee.TimeSinceShoot = 0;
			melee.MainAttack.State = AttackState.Inactive;
			melee.MainAttack.OnAttackReleased();

			melee.BlockAttack.State = AttackState.Inactive;
			melee.BlockAttack.OnAttackReleased();
		}
	}

	public override void Tick()
	{
		if ( Agent.Weapon is MeleeWeapon melee )
		{
			if ( melee.CanShoot() )
			{
				melee.TimeSinceShoot = 0;
				melee.BlockAttack.State = AttackState.Windup;
			}

			if ( melee.BlockAttack.State == AttackState.ReadyToAttack )
			{
				melee.BlockAttack.State = AttackState.Swinging;
				melee.BlockAttack.OnAttackReleased();
			}
		}
	}
}