DVN/addons/dvn/label/dvn_label.gd
2025-03-01 16:39:50 -05:00

134 lines
4.8 KiB
GDScript

@icon("res://addons/dialogue_manager/assets/icon.svg")
class_name DVNLabel extends DialogueLabel
## The DVNLabel Class takes care of dialogue related functions on the label-level
## ToneTypes for the Talktone player.
## [br][param NONE] plays no sound when text is outputted
## [br][param VOICE] plays a [AudioStream] from [member voice_clips] at the beginning of each dialogue box,
## the index of [member voice clips] increases with each dialogue box. Use this for full voice acting.
## [br][param HALF_BEEP] plays a [member beep_noise] for every other letter outputted
## [br][param BEEP] plays a [member beep_noise] for every letter outputted
## [br][param BLABBER] plays a random [AudioStream] from [member blabber_noises] for every letter outputted.
## Its pitch is a random value between [member blabber_pitch_minumum] and [member blabber_pitch_maximum]
## [br][param MARISESE] uses rudimentary voice synthesis (a specific sound is mapped to each letter aka each [AudioStream] from values 0-25, with every other symbol being represented by value 26)
## ## Its pitch is a random value between [member marisese_pitch_minumum] and [member marisese_pitch_maximum]
enum ToneTypes{NONE,VOICE,HALF_BEEP,BEEP,BLABBER,MARISESE}
@export var talktone_player_path: NodePath
var talktone_player = null
var current_voice_line:int = 0
# Current TalkType
@export_enum("None","Voice","Half Beep","Beep","Blabber","Marisese") var tone_type: int
# Tone Noises
@export var voice_clips: Array[Resource] = []
@export var beep_noise: Resource
@export var blabber_noises: Array[Resource] = []
@export var blabber_pitch_minumum: float = 1.0
@export var blabber_pitch_maximum: float = 1.0
@export var marisese_noises: Array[Resource] = []
@export var marisese_pitch_minumum: float = 0.9
@export var marisese_pitch_maximum: float = 1.1
@export var can_speak: bool = true
@onready var scene = get_owner().get_parent()
@onready var balloon = get_owner()
func _init() -> void:
bbcode_enabled = true
fit_content = true
scroll_active = false
shortcut_keys_enabled = false
meta_underlined = false
hint_underlined = false
deselect_on_focus_loss_enabled = false
visible_characters_behavior = TextServer.VisibleCharactersBehavior.VC_CHARS_AFTER_SHAPING
set_anchors_preset(Control.PRESET_TOP_WIDE)
size.x = 640.0
mouse_filter = MOUSE_FILTER_PASS
func _ready() -> void:
talktone_player = get_node(talktone_player_path)
talktone_player.finished.connect(on_talktone_finished)
spoke.connect(_on_spoke)
finished_typing.connect(_on_finished_typing)
func type_out():
super()
if tone_type == ToneTypes.VOICE && can_speak:
if current_voice_line <= voice_clips.size() - 1:
talktone_player.stream = voice_clips[current_voice_line]
talktone_player.play()
current_voice_line += 1
func play_beep_tone(sound:Resource = beep_noise,pitch_minimum:float = 1.0,pitch_maximum:float = 1.0,player:Node = talktone_player):
var r = randf_range(pitch_minimum,pitch_maximum)
player.stream = sound
player.pitch_scale = r
player.play()
func play_blabber_tone(sounds:Array = blabber_noises,volume:float = 0.0,pitch_minimum:float = blabber_pitch_minumum,pitch_maximum:float = blabber_pitch_maximum,player:Node = talktone_player):
var r = randi_range(0,sounds.size() - 1)
player.stream = sounds[r]
var r2 = randf_range(pitch_minimum,pitch_maximum)
player.pitch_scale = r2
player.play()
func play_marisese(letter:String = "A",sounds:Array = marisese_noises,volume:float = 0.0,pitch_minimum:float = marisese_pitch_minumum,pitch_maximum:float = marisese_pitch_maximum,player:Node = talktone_player):
var snd = 26
#region check every letter
match letter.to_upper():
"A": snd = 0
"B": snd = 1
"C": snd = 2
"D": snd = 3
"E": snd = 4
"F": snd = 5
"G": snd = 6
"H": snd = 7
"I": snd = 8
"J": snd = 9
"K": snd = 10
"L": snd = 11
"M": snd = 12
"N": snd = 13
"O": snd = 14
"P": snd = 15
"Q": snd = 16
"R": snd = 17
"S": snd = 18
"T": snd = 19
"U": snd = 20
"V": snd = 21
"W": snd = 22
"X": snd = 23
"Y": snd = 24
"Z": snd = 25
#endregion
player.stream = sounds[snd]
var r = randf_range(pitch_minimum,pitch_maximum)
player.pitch_scale = r
player.play()
func _on_spoke(letter: String, letter_index: int, speed: float) -> void:
if can_speak:
match tone_type:
ToneTypes.HALF_BEEP:
if letter_index % 2 == 0:
play_beep_tone()
ToneTypes.BEEP:
play_beep_tone()
ToneTypes.BLABBER:
play_blabber_tone()
ToneTypes.MARISESE:
play_marisese(letter)
func on_talktone_finished():
if scene.dialogue_automation_type == scene.DialogueAutomationTypes.AUTO_VOICE:
balloon.next(balloon.dialogue_line.next_id)
func _on_finished_typing():
if scene.dialogue_automation_type == scene.DialogueAutomationTypes.AUTO_TEXT:
await get_tree().create_timer(scene.auto_text_delay).timeout
if balloon.dialogue_line.responses.size() == 0:
balloon.next(balloon.dialogue_line.next_id)