Initial commit

This commit is contained in:
Matthew Barbour
2026-08-30 01:17:38 -05:00
parent f983ab64ce
commit 17cedb8bf1
68 changed files with 2035 additions and 0 deletions
+148
View File
@@ -0,0 +1,148 @@
extends CanvasLayer
@onready var audio_stream_player: AudioStreamPlayer = $AudioStreamPlayer
@onready var dialogue_label: DialogueLabel = $DialogueLabel
@onready var responses_menu: DialogueResponsesMenu = %DialogueResponsesMenu
## The dialogue resource
var resource: DialogueResource
## Temporary game states
var temporary_game_states: Array = []
## See if we are waiting for the player
var is_waiting_for_input: bool = false
# Who is talking
var dialogue_marker: DialogueMarker
## The current line
var dialogue_line: DialogueLine:
set(value):
if not value:
queue_free()
else:
dialogue_line = value
update_dialogue_line()
get:
return dialogue_line
func _ready() -> void:
dialogue_label.hide()
Engine.get_singleton("DialogueManager").mutated.connect(_on_mutated)
func _unhandled_input(_event: InputEvent) -> void:
# Only the balloon is allowed to handle input while it's showing
get_viewport().set_input_as_handled()
## Start some dialogue
func start(dialogue_resource: DialogueResource, title: String, extra_game_states: Array = []) -> void:
if not is_node_ready():
await ready
temporary_game_states = extra_game_states
is_waiting_for_input = false
resource = dialogue_resource
dialogue_line = await resource.get_next_dialogue_line(title, temporary_game_states)
## Go to the next line
func next(next_id: String) -> void:
dialogue_line = await resource.get_next_dialogue_line(next_id, temporary_game_states)
#region Helpers
func update_dialogue_line() -> void:
responses_menu.responses = []
dialogue_line.text = dialogue_line.text
dialogue_label.hide()
dialogue_label.dialogue_line = dialogue_line
# Set the colour and attach the dialogue to the character
dialogue_marker = DialogueMarker.find_for_character(dialogue_line.character)
if is_instance_valid(dialogue_marker):
dialogue_label.set("theme_override_colors/default_color", dialogue_marker.color)
dialogue_label.set("theme_override_colors/font_outline_color", dialogue_marker.color.darkened(0.4))
dialogue_label.global_position = dialogue_marker.global_position - Vector2(dialogue_label.size.x * 0.5, dialogue_label.get_content_height())
dialogue_label.show()
dialogue_label.type_out()
# Play sound and wait for sound to finish
var voice_path: String = "res://l10n/voice/en/%s.ogg" % [dialogue_line.static_id]
if ResourceLoader.exists(voice_path):
var stream = load(voice_path)
audio_stream_player.stream = stream
audio_stream_player.play()
Events.character_started_talking.emit(dialogue_line.character)
await audio_stream_player.finished
Events.character_finished_talking.emit(dialogue_line.character)
else:
printerr("Voice missing: %s" % [voice_path])
Events.character_started_talking.emit(dialogue_line.character)
await get_tree().create_timer(dialogue_line.text.length() * 0.05).timeout
Events.character_finished_talking.emit(dialogue_line.character)
dialogue_label.hide()
if dialogue_line.responses.size() == 0:
next(dialogue_line.next_id)
else:
responses_menu.responses = dialogue_line.responses
for item: RichTextLabel in responses_menu.get_menu_items():
item.mouse_entered.connect(_on_response_mouse_entered.bind(item))
item.focus_entered.connect(_on_response_focus_entered.bind(item))
item.focus_exited.connect(_on_response_focus_exited.bind(item))
item.gui_input.connect(_on_response_gui_input.bind(item))
_on_response_focus_entered(responses_menu.get_menu_items()[0])
#endregion
#region Signals
func _on_mutated(_mutation: Dictionary) -> void:
is_waiting_for_input = false
func _on_response_mouse_entered(item: Control) -> void:
if "Disallowed" in item.name: return
item.grab_focus()
func _on_response_gui_input(event: InputEvent, item: Control) -> void:
if "Disallowed" in item.name: return
get_viewport().set_input_as_handled()
if event is InputEventMouseButton and event.is_pressed() and event.button_index == 1:
next(dialogue_line.responses[item.get_index()].next_id)
elif event.is_action_pressed("ui_accept") and item in responses_menu.get_menu_items():
next(dialogue_line.responses[item.get_index()].next_id)
func _on_response_focus_entered(item):
item.set("theme_override_colors/default_color", DialogueMarker.find_for_character("Jimmy").color)
func _on_response_focus_exited(item):
item.set("theme_override_colors/default_color", Color.WHITE)
func _on_dialogue_label_resized() -> void:
if is_instance_valid(dialogue_marker):
dialogue_label.global_position = dialogue_marker.global_position - Vector2(dialogue_label.size.x * 0.5, dialogue_label.get_content_height())
#endregion