Player/Immersion/BreathingController.cs
namespace Opium;
public enum BreathingType
{
Normal,
Exerted,
NoStamina,
DyingHealth
}
public struct BreathingSound
{
public BreathingType Type { get; set; }
public SoundEvent Sound { get; set; }
public override string ToString()
{
return $"{Type} - {Sound?.ResourceName ?? "No sound"}";
}
}
public partial class BreathingController : Component
{
[Property, ReadOnly] public BreathingType BreathingType { get; private set; }
[Property] public List<BreathingSound> SoundEvents { get; set; }
public Dictionary<BreathingType, SoundHandle> Handles { get; set; } = new();
public Opium.PlayerController PlayerController => Components.Get<Opium.PlayerController>( FindMode.EverythingInSelfAndDescendants );
public PlayerInformation PlayerInfo => Components.Get<PlayerInformation>( FindMode.EverythingInSelfAndDescendants );
public float Health => PlayerController.Health;
protected override void OnStart()
{
foreach ( var snd in SoundEvents )
{
var handle = Sound.Play( snd.Sound );
handle.Volume = 0f;
Handles[snd.Type] = handle;
}
}
void UpdateHandles()
{
foreach ( var snd in Handles )
{
snd.Value.Position = Transform.Position;
// We're favouring this sound.
if ( BreathingType == snd.Key )
{
snd.Value.Volume = 1f;
}
else
{
snd.Value.Volume = 0f;
}
}
}
void UpdateState()
{
if ( PlayerController.IsMechanicActive<TakeoverAnimationMechanic>() )
{
BreathingType = BreathingType.Normal;
return;
}
if ( Health <= 30f )
{
BreathingType = BreathingType.DyingHealth;
}
else if ( PlayerController.MechanicTags.Has( "exhausted" ) )
{
BreathingType = BreathingType.NoStamina;
}
else if ( PlayerController.Tags.Has( "exerted" ) )
{
BreathingType = BreathingType.Exerted;
}
else
{
BreathingType = BreathingType.Normal;
}
}
protected override void OnUpdate()
{
UpdateState();
UpdateHandles();
}
}