extends Node @onready var bubbles: HBoxContainer = %Bubbles @onready var bubbles_back: TileMapLayer = %BubblesBack @onready var bubbles_interior: TileMapLayer = %BubblesInterior @onready var bubble_label: RichTextLabel = %BubbleLabel @onready var left_speaker: TextureRect = %LeftSpeaker @onready var right_speaker: TextureRect = %RightSpeaker @onready var time_between_letters: Timer = $TimeBetweenLetters @onready var ui_flicker_timer: Timer = $UIFlickerTimer @onready var e_ui_button: TextureRect = %E @onready var next_label: Label = %NextLabel @export_multiline var dialogue = "" @export var start_with_left = false @export var left_picture: Texture2D @export var right_picture: Texture2D signal dialogue_ended var dialogue_steps = [] var current_dialogue = "" var current_dialogue_split: PackedStringArray = [] var is_dialogue_ongoing = false var is_left_speaking = false func _ready() -> void: is_left_speaking = start_with_left left_speaker.texture = left_picture right_speaker.texture = right_picture display_profiles() e_ui_button.visible = false next_label.visible = false var steps = dialogue.split("---") for step: String in steps: dialogue_steps.append(step.strip_edges()) func display_profiles(): left_speaker.visible = is_left_speaking right_speaker.visible = not is_left_speaking func toggle_ui(): e_ui_button.visible = not e_ui_button.visible func _process(delta: float) -> void: if not is_dialogue_ongoing: return if Input.is_action_just_pressed("interact"): if not current_dialogue_split.is_empty(): return if dialogue_steps.is_empty(): end_dialogue() return else: # toggle speakers is_left_speaking = not is_left_speaking display_profiles() load_next_dialogue() func load_next_dialogue(): var next_dialogue = dialogue_steps.pop_front() current_dialogue = "" current_dialogue_split = next_dialogue.split("") func on_dialogue_started(): bubbles.visible = true bubbles_back.visible = true bubbles_interior.visible = true is_dialogue_ongoing = true time_between_letters.start() load_next_dialogue() func end_dialogue(): bubbles.visible = false bubbles_back.visible = false bubbles_interior.visible = false e_ui_button.visible = false next_label.visible = false is_dialogue_ongoing = false time_between_letters.stop() ui_flicker_timer.stop() dialogue_ended.emit() func _on_next_letter() -> void: if not current_dialogue_split.is_empty(): ui_flicker_timer.stop() e_ui_button.visible = false next_label.visible = false var next_letter = current_dialogue_split.get(0) current_dialogue_split.remove_at(0) current_dialogue += next_letter bubble_label.text = current_dialogue else: if next_label.visible: return next_label.visible = true ui_flicker_timer.start()