extends Node const SND_HIT: AudioStream = preload("res://assets/audio/sfx/hit.wav") const SND_DEATH: AudioStream = preload("res://assets/audio/sfx/death.wav") const SND_ABILITY: AudioStream = preload("res://assets/audio/sfx/ability_cast.wav") const SND_PORTAL: AudioStream = preload("res://assets/audio/sfx/portal_spawn.wav") const SND_LEVEL: AudioStream = preload("res://assets/audio/sfx/level_up.wav") const SND_INVASION: AudioStream = preload("res://assets/audio/sfx/invasion_alarm.wav") const SND_VILLAGE: AudioStream = preload("res://assets/audio/sfx/tavern_damage.wav") const MUS_TAVERN: AudioStream = preload("res://assets/audio/music/tavern.wav") const MUS_BATTLE: AudioStream = preload("res://assets/audio/music/battle.wav") const MUS_INVASION: AudioStream = preload("res://assets/audio/music/invasion.wav") var music_player: AudioStreamPlayer func _ready() -> void: music_player = AudioStreamPlayer.new() music_player.bus = "Master" music_player.volume_db = -10.0 add_child(music_player) EventBus.damage_dealt.connect(_on_damage_dealt) EventBus.entity_died.connect(_on_died) EventBus.ability_used.connect(_on_ability_used) EventBus.portal_spawned.connect(_on_portal_spawned) EventBus.level_up.connect(_on_level_up) EventBus.invasion_started.connect(_on_invasion_started) EventBus.village_damaged.connect(_on_village_damaged) EventBus.wave_started.connect(_on_wave_started) call_deferred("_play_music", MUS_TAVERN) func _on_damage_dealt(_a: Node, target: Node, _amount: float) -> void: _play_at(target, SND_HIT, -8.0) func _on_died(entity: Node) -> void: _play_at(entity, SND_DEATH, -4.0) func _on_ability_used(player: Node, _i: int, _a: Resource) -> void: _play_at(player, SND_ABILITY, -10.0) func _on_portal_spawned(p: Node) -> void: _play_at(p, SND_PORTAL, -4.0) func _on_level_up(_p: Node, _l: int) -> void: _play_global(SND_LEVEL, -4.0) func _on_invasion_started() -> void: _play_global(SND_INVASION, -2.0) _play_music(MUS_INVASION) func _on_village_damaged(_c: float, _m: float) -> void: _play_global(SND_VILLAGE, -8.0) func _on_wave_started(_n: int) -> void: _play_music(MUS_BATTLE) func _play_at(node: Node, stream: AudioStream, vol: float) -> void: if not is_instance_valid(node) or not (node is Node3D): return var p := AudioStreamPlayer3D.new() p.stream = stream p.volume_db = vol p.max_distance = 30.0 get_tree().current_scene.add_child(p) p.global_position = (node as Node3D).global_position p.play() p.finished.connect(func(): p.queue_free()) func _play_global(stream: AudioStream, vol: float) -> void: var p := AudioStreamPlayer.new() p.stream = stream p.volume_db = vol add_child(p) p.play() p.finished.connect(func(): p.queue_free()) func _play_music(stream: AudioStream) -> void: if music_player.stream == stream and music_player.playing: return music_player.stream = stream music_player.play()