using Godot; using RobotAndDonkey.Game; using RobotAndDonkey.Game.Board; using RobotAndDonkey.Game.Modifiers; using RobotAndDonkey.Game.Pois; using System; using System.Diagnostics; public class MusicManager { public enum ESong { MetaGame, Shop, CoreLoop, Scoring } public enum ESound { Energy, Carry, Delivery, TapeLength, Hand, Program, Card, Rest } public void Init(Main main) { m_Player1 = new() { Bus = "Music" }; main.AddChild(m_Player1); m_Player2 = new() { Bus = "Music" }; main.AddChild(m_Player2); m_SfxPlayer = new() { Bus = "Sfx" }; main.AddChild(m_SfxPlayer); m_Tree = main.GetTree(); } public void PlaySong(ESong song) { if (m_Song == song) return; var tween = m_Tree.CreateTween(); tween.SetParallel(); m_Song = song; if (m_CurrentPlayer) CrossFade(m_Player1, m_Player2, song, tween); else CrossFade(m_Player2, m_Player1, song, tween); m_CurrentPlayer = !m_CurrentPlayer; } private static void EnableLooping(AudioStream stream) { if (stream is AudioStreamOggVorbis ogg) { ogg.Loop = true; } else if (stream is AudioStreamMP3 mp3) { mp3.Loop = true; } else if (stream is AudioStreamWav wav) { wav.LoopMode = AudioStreamWav.LoopModeEnum.Forward; } } public void Play(EModifierId modifier) { m_SfxPlayer.Stream = ResourceLoader.Load(modifier switch { EModifierId.Corrupt => "uid://dnc8ksbbt8rxg", EModifierId.Unreliable => "uid://b8cgqw2meefkw", EModifierId.RaceCondition => "uid://c5061hog183xe", EModifierId.Throttled => "uid://djkcjn5niyhje", EModifierId.Effective => "uid://7toyoaj4xv5t", EModifierId.Optimized => "uid://cij77w63o5ahu", EModifierId.Efficient => "uid://iccli4sklikc", EModifierId.Persistent => "uid://bmkqvi2y64wxk", _ => null }); if (m_SfxPlayer.Stream != null) m_SfxPlayer.Play(); } public void Play(ESound sound) { m_SfxPlayer.Stream = ResourceLoader.Load(sound switch { ESound.Energy => "uid://prjkw6o6m53s", ESound.Carry => "uid://taabst8vqf07", ESound.Delivery => "uid://cr7ajk4lac6e0", ESound.TapeLength => "uid://bvt2nl4geonil", ESound.Hand => "uid://bu2tncw11cgqt", ESound.Program => "uid://6cqu6nualhm2", ESound.Card => "uid://b7508mnlvtm26", ESound.Rest => "uid://bp1dme3dnek76", _ => throw new ArgumentOutOfRangeException(nameof(sound), sound, null) }); m_SfxPlayer.Play(); } public void Play(ECellType cellType) { m_SfxPlayer.Stream = ResourceLoader.Load(cellType switch { ECellType.Grass => "uid://xc27unw7jisd", ECellType.Dry => "uid://b1licxrv5a5kx", ECellType.Fertile => "uid://ufefxts5f0op", ECellType.Mud => "uid://bkr83d0ylrgoh", ECellType.Blocked => "uid://fvia4q78bwmj", ECellType.Rocky => "uid://c22k1uvleut6w", _ => throw new ArgumentOutOfRangeException(nameof(cellType), cellType, null) }); m_SfxPlayer.Play(); } public void Play(Poi poi) { m_SfxPlayer.Stream = ResourceLoader.Load(poi switch { Crate => "uid://2g4nuqy03if5", Shed => "uid://bv03vbh5us6ym", Tower => "uid://dqolgkxab6gfy", Donkey => "uid://bg8eu2auayu2k", Avatar => "uid://nw8iofm1vaj8", _ => throw new NotImplementedException() }); m_SfxPlayer.Play(); } private void CrossFade(AudioStreamPlayer player1, AudioStreamPlayer player2, ESong song, Tween tween) { var stream = GetStream(song); EnableLooping(stream); player2.Stream = stream; player2.Play(); tween.TweenProperty(player1, "volume_db", -80.0f, 1.0).SetEase(Tween.EaseType.In).SetTrans(Tween.TransitionType.Sine); tween.TweenProperty(player2, "volume_db", 0.0f, 1.0).SetEase(Tween.EaseType.Out).SetTrans(Tween.TransitionType.Expo); } private AudioStream GetStream(ESong song) { return ResourceLoader.Load(song switch { ESong.MetaGame => "uid://bnrm544axjxoi", ESong.Shop => "uid://62fyj028yf7w", ESong.CoreLoop => "uid://5w305h2two2l", ESong.Scoring => "uid://b4qv7oicdvqg6", _ => throw new NotImplementedException() }); } private bool m_CurrentPlayer; private AudioStreamPlayer m_Player1; private AudioStreamPlayer m_Player2; private AudioStreamPlayer m_SfxPlayer; private ESong m_Song = (ESong)(-1); private SceneTree m_Tree; }