MagicNStuff/source/src/core/dialogue/voiceline_component.gd

81 lines
2.2 KiB
GDScript

class_name VoicelineComponent
extends Node
@export_node_path("AudioStreamPlayer", "AudioStreamPlayer2D", "AudioListener3D")
var audio_players: Array[NodePath] = []:
set = set_audio_players
@export var voiceline_chains: Dictionary[StringName, VoicelineChain] = {}
@export var cache_voicelines: bool = false ## TODO: preload all voicelines when they need the be loaded.
var voiceline_players: Array[Node] = []
var next_voicelines: Array[VoicelineChain] = []
var current_voiceline_chain_index: int = 0
var _reference_player: Node
func set_audio_players(players: Array[NodePath]) -> void:
audio_players = players
_update_player_cache()
func push_voiceline(voiceline_chain: VoicelineChain) -> void:
next_voicelines.append(voiceline_chain)
func push_next_voiceline() -> void:
var voiceline: VoicelineChain = next_voicelines.front()
if is_instance_valid(voiceline) and current_voiceline_chain_index < voiceline.voicelines.size():
current_voiceline_chain_index += 1
_play_voiceline(voiceline.voicelines[current_voiceline_chain_index])
return
next_voicelines.remove_at(0)
voiceline = next_voicelines.front()
current_voiceline_chain_index = 0
if is_instance_valid(voiceline):
_play_voiceline(voiceline.voicelines.front())
func play_voiceline(vo_name: StringName) -> void:
if voiceline_chains.has(vo_name):
push_voiceline(voiceline_chains[vo_name])
else:
push_warning("[%s] No voiceline with the name '%s' found." % [self, vo_name])
func is_audio_player(player: Node) -> bool:
return (
is_instance_valid(player)
and (
player is AudioStreamPlayer
or player is AudioStreamPlayer2D
or player is AudioStreamPlayer3D
)
)
func _play_voiceline(voiceline_data: VoicelineData) -> void:
var voice: AudioStream = load(voiceline_data.voiceline_path)
for player: Node in voiceline_players:
player.play(voice)
func _on_voiceline_finished() -> void:
push_next_voiceline()
func _update_player_cache() -> void:
voiceline_players.clear()
for audio_player: NodePath in audio_players:
var player: Node = get_node_or_null(audio_player)
if is_audio_player(player):
voiceline_players.append(player)
_reference_player = player
_reference_player.finished.connect(_on_voiceline_finished)