Player/Mechanics/SprintMechanic.cs
namespace Opium;

public partial class SprintMechanic : PlayerMechanic
{
	[Property] public float Speed { get; set; } = 150f;

	public override bool ShouldBecomeActive()
	{
		if ( !Player.CharacterController.IsOnGround ) return false;

		if ( Player.MechanicTags.Has( "exhausted" ) ) return false;

		var wish = Player.WishMove;

		// Can't sprint backward
		if ( wish.x < 0.0f ) return false;

		// Don't sprint if we're not moving
		if ( wish.Length.AlmostEqual( 0 ) ) return false;

		// Don't sprint if we're only moving horizontally
		if ( wish.y != 0.0f && wish.x.AlmostEqual( 0 ) ) return false;

		return Player.Input.WantsToSprint && !HasTag( "crouch" ) && !HasTag( "takeover" );
	}

	public override IEnumerable<string> GetTags()
	{
		yield return "sprint";
	}

	public override void BuildWishInput( ref Vector3 wish )
	{
		// Clamp the horizontal wish direction by half if we're sprinting
		wish.y *= 0.5f;
	}

	public override float? GetSpeed() => Speed;
}