aboutsummaryrefslogtreecommitdiff
path: root/game/src
diff options
context:
space:
mode:
author Nemrav <50055236+Nemrav@users.noreply.github.com>2024-08-06 01:48:36 +0200
committer GitHub <noreply@github.com>2024-08-06 01:48:36 +0200
commit82b16bcca7c74607a8885b882ec36f5202e7ef70 (patch)
tree0a9bd4f52c01315c3b38ce641a78c33bd8562be2 /game/src
parentfde15e554dc9ed458a838683c69d10262764db12 (diff)
parent9506f4160f0bd351f0853e6e8263ea927d9ec771 (diff)
Merge pull request #243 from Nemrav/music
Music and sound effects
Diffstat (limited to 'game/src')
-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)