Core/RunMusic.cs
namespace Prototype;

// One local soundtrack per scene, driven by this client's party/run state.
public sealed class RunMusic : Component
{
    private SoundHandle _music;
    private SoundHandle _ready;
    private string _mode = "";
    private string _countdownKey = "";
    private int _runTrack;

    protected override void OnStart()
    {
        Sound.Preload("sounds/music/dasher_5sec_ready.sound");
    }

    protected override void OnUpdate()
    {
        var game = PrototypeGame.Instance;
        if (game is null) return;
        var mode = game.LocalPhase == RunPhase.Lobby ? "lobby" : "run";
        var key = "";
        if (mode == "lobby" && game.LobbyCountdown.TryGetValue(game.LocalPartyId, out var deadline))
            key = game.LocalPartyId + ":" + deadline.ToString(System.Globalization.CultureInfo.InvariantCulture);
        if (key != _countdownKey)
        {
            _ready?.Stop(.08f);
            _ready = null;
            _countdownKey = key;
            if (key.Length > 0)
            {
                _ready = Sound.Play("sounds/music/dasher_5sec_ready.sound");
                if (_ready is not null) _ready.Volume = .65f * GameProfile.Settings.EffectsVolume;
            }
        }
        if (mode != _mode)
        {
            _music?.Stop(.5f);
            _music = null;
            _mode = mode;
            _runTrack = 0;
        }
        if (_music is null || !_music.IsPlaying)
        {
            var name = mode == "lobby" ? "dasher_lobby_music" : (++_runTrack % 2 == 1 ? "dasher_inrun_1" : "dasher_inrun_2");
            _music = Sound.Play("sounds/music/" + name + ".sound", Vector3.Zero, .5f);
            if (_music is not null) _music.Volume = (_countdownKey.Length > 0 ? .48f : 1.8f) * GameProfile.Settings.MusicVolume;
        }
        if (_music is not null)
        {
            var target = (_countdownKey.Length > 0 ? .48f : 1.8f) * GameProfile.Settings.MusicVolume;
            _music.Volume += System.Math.Clamp(target - _music.Volume, -Time.Delta, Time.Delta);
        }
    }

    protected override void OnDisabled() => Stop();
    protected override void OnDestroy() => Stop();
    private void Stop()
    {
        _music?.Stop(.15f);
        _ready?.Stop(.05f);
        _music = null;
        _ready = null;
        _mode = "";
        _countdownKey = "";
    }
}