Player/Mechanics/StaminaMechanic.cs
namespace Opium;
public partial class StaminaMechanic : PlayerMechanic
{
public float Stamina { get; set; } = 100f;
[Property] public float SprintStaminaDrain { get; set; } = 10f;
[Property] public float StaminaReplenishTime { get; set; } = 5f;
[Property, Category( "Stamina" )] public float StaminaDrainSpeed { get; set; } = 10f;
[Property, Category( "Stamina" )] public float StaminaRegenerateSpeed { get; set; } = 5f;
public bool CanUseStamina { get; set; }
public TimeSince TimeSinceStaminaWasEmpty { get; private set; }
public TimeSince TimeSinceLastUsedStamina { get; private set; }
public TimeUntil TimeUntilRegenerate { get; private set; }
/// <summary>
/// Stamina is ALWAYS active.
/// </summary>
/// <returns></returns>
public override bool ShouldBecomeActive()
{
return true;
}
public void RemoveStamina( float staminaUsed, float timeUntilNextRegenerate = 0.0f )
{
Stamina = Stamina.Clamp( 0, 100 ) - staminaUsed;
TimeSinceLastUsedStamina = 0;
if ( timeUntilNextRegenerate != 0f )
{
TimeUntilRegenerate = timeUntilNextRegenerate;
}
}
public void AddStamina( float staminaAdded )
{
Stamina = Stamina.Clamp( 0, 100 ) + staminaAdded;
if ( Stamina <= 100 )
{
TimeSinceLastUsedStamina = 0;
}
}
public override void OnActiveUpdate()
{
Stamina = Stamina.Clamp( 0, 100 );
if ( Stamina <= 1 )
{
CanUseStamina = false;
TimeSinceStaminaWasEmpty = 0;
}
if ( TimeSinceStaminaWasEmpty > StaminaReplenishTime )
{
CanUseStamina = true;
}
if ( Player.MechanicTags.Has( "sprint" ) )
{
RemoveStamina( Time.Delta * SprintStaminaDrain, 1f );
}
if ( TimeUntilRegenerate )
{
AddStamina( Time.Delta * StaminaRegenerateSpeed );
}
}
public override IEnumerable<string> GetTags()
{
if ( Stamina <= 0 ) yield return "exhausted";
}
}