use godot::{ classes::{AudioStream, AudioStreamPlayer}, prelude::*, tools::get_autoload_by_name, }; use crate::game::GameManager; pub const MUSIC_MANAGER_GLOBAL: &str = "MusicManagerGlobal"; #[derive(Debug, PartialEq, PartialOrd, Clone, Copy)] pub enum Music { MainMenu, Map(u8), } #[derive(GodotClass)] #[class(base=Node3D, init)] pub struct MusicManager { #[export] player: Option>, #[export] main_menu_songs: Array>, currently_playing: Option, base: Base, } #[godot_api] impl INode3D for MusicManager { fn ready(&mut self) { if let Some(player) = self.player.clone() { player.signals().finished().connect_other(self, |s| { if let Some(playing) = s.currently_playing { s.play(Some(playing), true); } }); } } } impl MusicManager { pub fn singleton() -> Gd { get_autoload_by_name::(MUSIC_MANAGER_GLOBAL) } pub fn play(&mut self, music: Option, force: bool) { if self.currently_playing == music && !force { return; } self.currently_playing = music; if let Some(player) = &mut self.player { match music { Some(music) => { let songs = match music { Music::MainMenu => self.main_menu_songs.clone(), Music::Map(idx) => { if let Some(map) = GameManager::singleton().bind().maps.get(idx as usize) { map.bind().music.clone() } else { Array::new() } } }; if let Some(song) = songs.pick_random() { player.set_stream(&song); player.play(); } else { player.stop(); } } None => player.stop(), } } } }