extends Control class_name DialogBox var dialog: Array var dialog_index := 0 var finished_line := false var is_active := false var letters_per_second = 16 var typing_tween: Tween @onready var window: NinePatchRect = $Window @onready var content: RichTextLabel = $Window/Content signal line_finished(index) signal dialog_finished signal dialog_hidden func _ready() -> void: window.size.y = 0 window.position.x = 2000 content.text = "" func initialize(dialog_lines: Array): print("Initializing dialog box with lines: %s" % dialog_lines) content.text = "" window.size.y = 0 window.position.x = 2000 dialog = dialog_lines.duplicate() dialog_index = 0 finished_line = false $Window/Next/NextIndicator.visible = false var move_tween = get_tree().create_tween() move_tween.tween_property(window, "position", Vector2(0, 0), 0.5).set_trans(Tween.TRANS_CUBIC).set_ease(Tween.EASE_OUT) var scale_tween = get_tree().create_tween() scale_tween.tween_property(window, "size", Vector2(window.size.x, 75), 0.5).set_trans(Tween.TRANS_CUBIC).set_delay(0.25) await scale_tween.finished is_active = true next_line() func next_line(): if dialog_index < dialog.size(): finished_line = false content.text = dialog[dialog_index] content.visible_characters = 0 typing_tween = get_tree().create_tween() var duration = dialog[dialog_index].length() / letters_per_second typing_tween.tween_property(content, "visible_characters", dialog[dialog_index].length(), duration).set_trans(Tween.TRANS_LINEAR) await typing_tween.finished line_finished.emit(dialog_index) finished_line = true else: # Box go bye bye is_active = false dialog_finished.emit() var scale_tween = get_tree().create_tween() scale_tween.tween_property(window, "size", Vector2(window.size.x, 14), 0.5).set_trans(Tween.TRANS_CUBIC) var move_tween = get_tree().create_tween() move_tween.tween_property(window, "position", Vector2(2000, 0), 0.5).set_trans(Tween.TRANS_CUBIC).set_ease(Tween.EASE_IN).set_delay(0.25) await move_tween.finished dialog_hidden.emit() dialog_index += 1 # Called every frame. 'delta' is the elapsed time since the previous frame. func _process(delta: float) -> void: if !is_active: return $Window/Next/NextIndicator.visible = finished_line if Input.is_action_just_pressed('select'): if finished_line: next_line() else: print("Immediately finishing line... (%s)" % content.text) typing_tween.finished.emit() typing_tween.kill() content.visible_characters = content.text.length()