aboutsummaryrefslogtreecommitdiff
path: root/game/src/Game
diff options
context:
space:
mode:
author Nemrav <>2024-04-22 22:30:21 +0200
committer Nemrav <>2024-08-06 01:40:34 +0200
commit9506f4160f0bd351f0853e6e8263ea927d9ec771 (patch)
tree0a9bd4f52c01315c3b38ce641a78c33bd8562be2 /game/src/Game
parentfde15e554dc9ed458a838683c69d10262764db12 (diff)
Music and Sound Effect loading and playing
almost working music loading music list sent to godot wav loading not working mp3 metadata load wav initial load and play title theme first fix errors not related to nodetools working wav define loading and music playlists fixup error handling and playlist load song chances code style progress switch mp3 metadata addon to MusicMetadata add id3v1 mp3 metadata handling to MusicMetadata remove commented code from id3v1 sounds gd styling fix dataloader conflicts clean up commented code move MusicChance to dataloader remove reference to old addon move sfx defines loader add self to credits feedback on soundSingleton include subfolders in sound singleton sfx map replace space tabs replace std_view_to_godot_string with std_to_godot_string revise singleton files revise gd side sound final revisions
Diffstat (limited to 'game/src/Game')
-rw-r--r--game/src/Game/Autoload/SoundManager.gd20
-rw-r--r--game/src/Game/GameSession/GameSession.gd2
-rw-r--r--game/src/Game/GameStart.gd26
-rw-r--r--game/src/Game/MusicConductor/MusicConductor.gd82
-rw-r--r--game/src/Game/MusicConductor/SongInfo.gd11
-rw-r--r--game/src/Game/Theme/StyleBoxWithSound.gd2
6 files changed, 130 insertions, 13 deletions
diff --git a/game/src/Game/Autoload/SoundManager.gd b/game/src/Game/Autoload/SoundManager.gd
index 35c715c..01562f8 100644
--- a/game/src/Game/Autoload/SoundManager.gd
+++ b/game/src/Game/Autoload/SoundManager.gd
@@ -18,7 +18,7 @@ func _ready() -> void:
"ogg", "wav", "mp3":
_loaded_sound[fname.get_basename()] = load(_audio_directory_path.path_join(fname)) # SND-10
-func play_stream(sound : AudioStream, bus_type : String) -> void:
+func play_stream(sound : AudioStream, bus_type : String, volume : float = 1.0) -> void:
var player : AudioStreamPlayer = _bus_to_stream_player.get(bus_type)
if player == null:
player = AudioStreamPlayer.new()
@@ -28,6 +28,7 @@ func play_stream(sound : AudioStream, bus_type : String) -> void:
add_child(player)
player.play()
var poly_playback : AudioStreamPlaybackPolyphonic = player.get_stream_playback()
+ player.volume_db = linear_to_db(volume)
poly_playback.play_stream(sound)
func play(sound : String, bus_type : String) -> void:
@@ -35,8 +36,21 @@ func play(sound : String, bus_type : String) -> void:
# REQUIREMENTS:
# * SND-7
-func play_effect_stream(sound : AudioStream) -> void:
- play_stream(sound, "SFX")
+func play_effect_stream(sound : AudioStream, volume : float = 1.0) -> void:
+ play_stream(sound, "SFX", volume)
func play_effect(sound : String) -> void:
play(sound, "SFX")
+
+func play_effect_compat(sfx : String, fallback : AudioStream=null) -> void:
+ var sound:AudioStreamWAV = SoundSingleton.get_sound_stream(sfx)
+ var volume:float = SoundSingleton.get_sound_base_volume(sfx)
+
+ if sound != null:
+ play_effect_stream(sound,volume)
+ elif fallback != null:
+ push_warning("Failed to find sound %s, playing fallback instead" % sfx)
+ play_effect_stream(fallback)
+ else:
+ push_warning("Failed to find sound %s" % sfx)
+
diff --git a/game/src/Game/GameSession/GameSession.gd b/game/src/Game/GameSession/GameSession.gd
index 0158b3a..30e6c1c 100644
--- a/game/src/Game/GameSession/GameSession.gd
+++ b/game/src/Game/GameSession/GameSession.gd
@@ -10,6 +10,8 @@ func _ready() -> void:
_model_manager.generate_units()
_model_manager.generate_buildings()
+ MusicConductor.generate_playlist()
+ MusicConductor.select_next_song()
func _process(_delta : float) -> void:
GameSingleton.try_tick()
diff --git a/game/src/Game/GameStart.gd b/game/src/Game/GameStart.gd
index 6074df8..3c046a0 100644
--- a/game/src/Game/GameStart.gd
+++ b/game/src/Game/GameStart.gd
@@ -105,8 +105,32 @@ func _setup_compatibility_mode_paths() -> void:
_compatibility_path_list.push_back(actual_base_path + "/mod/" + mod_name)
func _load_compatibility_mode() -> void:
- if GameSingleton.load_defines_compatibility_mode(_compatibility_path_list) != OK:
+ if GameSingleton.set_compatibility_mode_roots(_compatibility_path_list) != OK:
+ push_error("Errors setting game roots!")
+
+ setup_title_theme()
+
+ if GameSingleton.load_defines_compatibility_mode() != OK:
push_error("Errors loading game defines!")
+
+ SoundSingleton.load_sounds()
+ SoundSingleton.load_music()
+ MusicConductor.add_compat_songs()
+
+func setup_title_theme() -> void:
+ SoundSingleton.load_title_theme()
+
+ MusicConductor.setup_compat_song(SoundSingleton.title_theme)
+
+ var song_paths = MusicConductor.get_all_song_paths()
+ var title_index = song_paths.find(SoundSingleton.title_theme)
+ if title_index != -1:
+ MusicConductor.call_deferred("start_song_by_index",title_index)
+ if len(MusicConductor._available_songs) <= 0:
+ push_error("No song available to play")
+ else:
+ MusicConductor.call_deferred("start_current_song")
+
# REQUIREMENTS
# * FS-333, FS-334, FS-335, FS-341
diff --git a/game/src/Game/MusicConductor/MusicConductor.gd b/game/src/Game/MusicConductor/MusicConductor.gd
index b4b660a..7103aff 100644
--- a/game/src/Game/MusicConductor/MusicConductor.gd
+++ b/game/src/Game/MusicConductor/MusicConductor.gd
@@ -17,6 +17,12 @@ var _selected_track := 0
var _available_songs : Array[SongInfo] = []
var _auto_play_next_song : bool = true
+var playlist: Array[int] = []
+var playlist_index:int = 0
+var preferred_playlist_len: int = 7
+var last_played: int = -1
+
+
## True if music player should be visible.
## Used to keep keep consistency between scene changes
var is_music_player_visible : bool = true
@@ -28,6 +34,12 @@ func get_all_song_names() -> PackedStringArray:
for si : SongInfo in _available_songs:
songNames.append(si.song_name)
return songNames
+
+func get_all_song_paths() -> PackedStringArray:
+ var songPaths : PackedStringArray = []
+ for si : SongInfo in _available_songs:
+ songPaths.append(si.song_path)
+ return songPaths
func get_current_song_index() -> int:
return _selected_track
@@ -67,24 +79,82 @@ func start_song_by_index(id: int) -> void:
# REQUIREMENTS
# * SS-69
func select_next_song() -> void:
- _selected_track = (_selected_track + 1) % len(_available_songs)
+ #_selected_track = (_selected_track + 1) % len(_available_songs)
+ if playlist_index >= preferred_playlist_len or playlist_index >= len(playlist):
+ generate_playlist()
+ playlist_index = 0
+ _selected_track = playlist[playlist_index]
+ playlist_index += 1
+ last_played = playlist_index
start_current_song()
func select_previous_song() -> void:
_selected_track = (len(_available_songs) - 1) if (_selected_track == 0) else (_selected_track - 1)
start_current_song()
-# REQUIREMENTS
-# * SND-2, SND-3
-func _ready() -> void:
+func setup_compat_song(file_name) -> void:
+ var song = SongInfo.new()
+ var stream = SoundSingleton.get_song(file_name)
+
+ var metadata = MusicMetadata.new()
+ metadata.set_from_stream(stream)
+ var title = metadata.title
+ if title == "":
+ #use the file name without the extension if there's no metadata
+ title = file_name.split(".")[0]
+ song.init_stream(file_name,title,stream)
+ _available_songs.append(song)
+
+func add_compat_songs() -> void:
+ for file_name : String in SoundSingleton.song_list:
+ setup_compat_song(file_name)
+
+func add_ootb_music() -> void:
var dir := DirAccess.open(music_directory)
for fname : String in dir.get_files():
if fname.ends_with(".import"):
fname = fname.get_basename()
if fname.get_basename() == first_song_name:
_selected_track = _available_songs.size()
- _available_songs.append(SongInfo.new(music_directory, fname))
- start_current_song()
+ var song = SongInfo.new()
+ song.init_file_path(music_directory, fname)
+ _available_songs.append(song)
+
+func generate_playlist() -> void:
+ var song_names = MusicConductor.get_all_song_paths()
+ var possible_indices = range(len(song_names)-1)
+
+ var title_index = song_names.find(SoundSingleton.title_theme)
+ possible_indices.remove_at(title_index)
+
+ var actual_playlist_len = min(preferred_playlist_len,len(possible_indices))
+
+ #if the playlist size is too large or small, make it the same size as what we
+ #need to support
+ if len(playlist) != actual_playlist_len:
+ playlist.resize(actual_playlist_len)
+ playlist.fill(0)
+
+ #The song we just played can be in the playlist, just not the first one
+ if last_played != -1:
+ possible_indices.remove_at(last_played)
+
+ #essentially shuffle-bag randomness, picking from a list of song indices
+ for i in range(actual_playlist_len):
+ var ind = randi_range(0,len(possible_indices)-1)
+ #add back the last song we just played as an option
+ if i==2:
+ possible_indices.append(last_played)
+
+ playlist[i] = possible_indices[ind]
+ possible_indices.remove_at(ind)
+
+# REQUIREMENTS
+# * SND-2, SND-3
+func _ready() -> void:
+ add_ootb_music()
+ #don't start the current song for compat mode, do that from
+ #GameStart so we can wait until the music is loaded
func set_startup_music(play : bool) -> void:
if not _has_startup_happened:
diff --git a/game/src/Game/MusicConductor/SongInfo.gd b/game/src/Game/MusicConductor/SongInfo.gd
index abcf120..527f618 100644
--- a/game/src/Game/MusicConductor/SongInfo.gd
+++ b/game/src/Game/MusicConductor/SongInfo.gd
@@ -3,9 +3,16 @@ class_name SongInfo
var song_path : String = ""
var song_name : String = ""
-var song_stream : Resource
+var song_stream : AudioStream
-func _init(dirname:String, fname:String) -> void:
+#Initialize from a file path
+func init_file_path(dirname : String, fname : String) -> void:
song_path = dirname.path_join(fname)
song_name = fname.get_basename().replace("_", " ")
song_stream = load(song_path)
+
+#Initialize from an audio stream
+func init_stream(dirpath : String, name : String, stream : AudioStream) -> void:
+ song_path = dirpath
+ song_name = name
+ song_stream = stream
diff --git a/game/src/Game/Theme/StyleBoxWithSound.gd b/game/src/Game/Theme/StyleBoxWithSound.gd
index 8c29b34..75a181a 100644
--- a/game/src/Game/Theme/StyleBoxWithSound.gd
+++ b/game/src/Game/Theme/StyleBoxWithSound.gd
@@ -29,6 +29,6 @@ func _draw(to_canvas_item : RID, rect : Rect2) -> void:
# Is there any other reason aside from release sounds (might be useful for toggles?)
# This should be fast enough to not cause draw issues
if sound != null:
- SoundManager.play_effect_stream(sound)
+ SoundManager.play_effect_compat("click",sound)
if style_box != null:
style_box.draw(to_canvas_item, rect)