Files
Blockline/scripts/music_director.gd
T

64 lines
2.5 KiB
GDScript
Raw Normal View History

2026-09-12 11:01:37 +02:00
class_name MusicDirector
extends Node
static var volume := 0.65
var layers: Array[AudioStreamPlayer] = []
var state := ""
var transition: Tween
var game: Node
var cue: AudioStreamPlayer
const ROOT := "res://assets/audio/assault/"
func _ready() -> void:
if DisplayServer.get_name() == "headless":
set_process(false)
return
if AudioServer.get_bus_index("Music") < 0:
AudioServer.add_bus()
AudioServer.set_bus_name(AudioServer.bus_count-1,"Music")
for instrument in ["Synth","Strings","Percussion","Guitar"]:
var path := ROOT+"Stems/Incoming/MUS_Combat_Incoming_Loop_%s_100BPM.wav" % instrument
if not ResourceLoader.exists(path): continue
var stream := load(path).duplicate() as AudioStreamWAV
stream.loop_mode = AudioStreamWAV.LOOP_FORWARD
stream.loop_begin = 0
stream.loop_end = int(round(stream.get_length()*stream.mix_rate))
var player := AudioStreamPlayer.new()
player.stream = stream
player.bus = "Music"
player.volume_db = -60
add_child(player)
layers.append(player)
# All stems use the same audio mix boundary and keep playing through UI changes.
for player in layers: player.play()
cue = AudioStreamPlayer.new()
cue.bus = "Music"
cue.volume_db = -20
add_child(cue)
func _process(_delta: float) -> void:
AudioServer.set_bus_volume_db(AudioServer.get_bus_index("Music"),linear_to_db(maxf(volume,0.0001)))
AudioServer.set_bus_mute(AudioServer.get_bus_index("Music"),volume <= 0)
var next := "menu"
if is_instance_valid(game):
if game.match_over: next = "results"
elif game.active: next = "pause" if game.paused else "combat"
elif game.connecting: next = "lobby"
if next == state: return
var previous := state
state = next
if state == "combat" and previous != "pause":
play_cue("Loops/Combat_Incoming_Modular/MUS_Combat_Incoming_Intro_Transition_100BPM.wav")
elif state == "results":
var ending := "01" if not is_instance_valid(game) or game.winner != "DRAW" else "02"
play_cue("Loops/Combat_Incoming_Modular/MUS_Combat_Incoming_Outro_Resolve_%s_100BPM.wav" % ending)
if transition: transition.kill()
transition = create_tween().set_parallel(true)
var levels: Array = {"menu":[-16,-23,-60,-60],"lobby":[-16,-20,-28,-60],"combat":[-23,-23,-23,-26],"pause":[-25,-30,-60,-60],"results":[-19,-18,-60,-60]}[state]
for i in layers.size(): transition.tween_property(layers[i],"volume_db",float(levels[i]),1.5)
func play_cue(relative: String) -> void:
if cue and ResourceLoader.exists(ROOT+relative):
cue.stream = load(ROOT+relative)
cue.play()