Player/Mechanics/SingleUseWeaponMechanic.cs
namespace Opium;

public partial class SingleUseWeaponMechanic : PlayerMechanic
{
	[Property] public float Duration { get; set; } = 1.0f;
	[Property] public GameObject WeaponPrefab { get; set; }
	[Property] public TagSet MechanicTags { get; set; } = new TagSet();
	[Property, InputAction] public string InputAction { get; set; } = "Kick";
	[Property] public Vector3 SpeedClamping { get; set; } = 1f;

	[Property] public Action OnEnd { get; set; }

	[Property] public Func<bool> ShouldBecomeActiveAction { get; set; }

	public BaseWeapon WeaponInstance { get; set; }

	public override bool ShouldBecomeActive()
	{
		if ( Player.Inventory.Current is SingleUseWeapon )
		{
			return false;
		}

		if ( ShouldBecomeActiveAction is not null )
		{
			return ShouldBecomeActiveAction.Invoke() && Input.Pressed( InputAction );
		}

		return Input.Pressed( InputAction );
	}

	public override bool ShouldBecomeInactive()
	{
		if ( IsActive )
		{
			return TimeSinceActiveChanged > Duration;
		}

		return base.ShouldBecomeInactive();
	}

	void Begin()
	{
		var weapon = Player.Inventory.CreateWeaponFromPrefab( WeaponPrefab );
		WeaponInstance = weapon;
		Player.Inventory.SetCurrent( weapon, true );
	}

	void End()
	{
		if ( Player.Inventory.Previous.IsValid()|| Player.Inventory.Weapons.Count > 0 )
		{
			Player.Inventory.SetCurrent( Player.Inventory.Previous ?? Player.Inventory.Weapons.First(), true );
		}

		OnEnd?.Invoke();
	}

	protected override void OnActiveChanged( bool before, bool after )
	{
		if ( after )
		{
			Begin();
		}
		else
		{
			End();
		}
	}

	public override IEnumerable<string> GetTags()
	{
		return MechanicTags.TryGetAll();
	}

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