Explosion_der_Spiele/scripts/autoload/audio_director.gd

134 lines
3.4 KiB
GDScript3
Raw Permalink Normal View History

extends Node
## Music / SFX / Voice (Piper lines under assets/audio/voice/{lang}/{dialog_key}.wav).
signal burger_cham_triggered
const BURGER_INTERVAL := 120.0
const MUSIC_TITLE := "res://assets/audio/placeholders/music_title.wav"
const SFX_EXPLOSION := "res://assets/audio/placeholders/sfx_explosion.wav"
const SFX_HIT := "res://assets/audio/placeholders/sfx_hit.wav"
const SFX_BURGER := "res://assets/audio/placeholders/sfx_burger.wav"
## Fallback language-picker clips if keyed Piper files missing
const VOICE_DE := "res://assets/audio/placeholders/voice_de.wav"
const VOICE_EN := "res://assets/audio/placeholders/voice_en.wav"
const VOICE_BY := "res://assets/audio/placeholders/voice_by.wav"
var _music: AudioStreamPlayer
var _sfx: AudioStreamPlayer
var _voice: AudioStreamPlayer
var _burger_timer: float = 0.0
var burger_cham_enabled: bool = true
var _last_voice_length: float = 0.0
func _ready() -> void:
process_mode = Node.PROCESS_MODE_ALWAYS
_music = AudioStreamPlayer.new()
_music.bus = "Music"
_music.volume_db = 12.0 # intentionally painfully loud
add_child(_music)
_sfx = AudioStreamPlayer.new()
_sfx.bus = "SFX"
add_child(_sfx)
_voice = AudioStreamPlayer.new()
_voice.bus = "Voice"
add_child(_voice)
func _process(delta: float) -> void:
if not burger_cham_enabled:
return
if GameState.current_scene_id != "title_screen":
return
_burger_timer += delta
if _burger_timer >= BURGER_INTERVAL:
_burger_timer = 0.0
trigger_burger_cham()
func play_title_music() -> void:
var stream := _load_stream(MUSIC_TITLE)
if stream == null:
return
_music.stream = stream
_music.volume_db = 12.0
if not _music.playing:
_music.play()
func stop_music() -> void:
_music.stop()
func play_sfx(path: String) -> void:
var stream := _load_stream(path)
if stream == null:
return
_sfx.stream = stream
_sfx.play()
func play_explosion() -> void:
play_sfx(SFX_EXPLOSION)
func play_hit() -> void:
play_sfx(SFX_HIT)
func play_language_voice(lang: String) -> void:
var key := "lang_voice_%s" % lang
if play_dialog_line(key) > 0.0:
return
var path := VOICE_DE
match lang:
"en":
path = VOICE_EN
"by":
path = VOICE_BY
var stream := _load_stream(path)
if stream == null:
return
_voice.stream = stream
_voice.play()
_last_voice_length = _stream_length(stream)
## Plays Piper line for locale key. Returns clip length in seconds (0 if missing).
func play_dialog_line(key: String) -> float:
if key == "":
return 0.0
if not (key.begins_with("dialog_") or key.begins_with("lang_voice_")):
return 0.0
var lang := "de"
if Settings:
lang = Settings.language
var path := "res://assets/audio/voice/%s/%s.wav" % [lang, key]
var stream := _load_stream(path)
if stream == null and lang != "de":
path = "res://assets/audio/voice/de/%s.wav" % key
stream = _load_stream(path)
if stream == null:
_last_voice_length = 0.0
return 0.0
_voice.stop()
_voice.stream = stream
_voice.play()
_last_voice_length = _stream_length(stream)
return _last_voice_length
func last_voice_length() -> float:
return _last_voice_length
func stop_voice() -> void:
_voice.stop()
func trigger_burger_cham() -> void:
play_sfx(SFX_BURGER)
burger_cham_triggered.emit()
func _stream_length(stream: AudioStream) -> float:
if stream == null:
return 0.0
if stream.has_method("get_length"):
return float(stream.get_length())
return 0.0
func _load_stream(path: String) -> AudioStream:
if ResourceLoader.exists(path):
return load(path)
return null