initial shit

This commit is contained in:
2026-06-04 16:53:41 -05:00
parent f019615187
commit d3779cff20
828 changed files with 512567 additions and 0 deletions

View File

@@ -0,0 +1,135 @@
## This file is part of the Godot Orchestrator project.
##
## Copyright (c) 2023-present Crater Crash Studios LLC and its contributors.
##
## Licensed under the Apache License, Version 2.0 (the "License");
## you may not use this file except in compliance with the License.
## You may obtain a copy of the License at
##
## http://www.apache.org/licenses/LICENSE-2.0
##
## Unless required by applicable law or agreed to in writing, software
## distributed under the License is distributed on an "AS IS" BASIS,
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
## See the License for the specific language governing permissions and
## limitations under the License.
##
extends CanvasLayer
## A required signal that should be emitted when the Dialogue UI completes
## all its user interactions. This informs Orchestrator that it is then
## safe to proceed to the next node/step in the visual script workflow.
signal show_message_finished()
## The speed that the text will be rendered, i.e. typewriter
const TEXT_SPEED = 0.03
## Holds data passed by Orchestrator the Dialogue UI
##
## By default attributes are passed into this dictionary as:
## "character_name" -> the name of the character speaking
## "message" -> the text to be shown
## "options" -> an array of text to be shown as choices
##
var dialogue_data : Dictionary
## Requirede by Orchestrator, passes the selected choice from
## the Dialogue UI back to the OrchestratorScript.
var selection : int
var _current_tween : Tween
var _current_choices : Dictionary
var _mouse_mode : Input.MouseMode
@onready var speaker = $MarginContainer/PanelContainer/MarginContainer/VBoxContainer/Speaker
@onready var speaker_text = $MarginContainer/PanelContainer/MarginContainer/VBoxContainer/SpeakerText
@onready var response_tpl = $MarginContainer/PanelContainer/MarginContainer/VBoxContainer/ResponseTemplate
@onready var next_button = $MarginContainer/PanelContainer/MarginContainer/VBoxContainer/NextButton
func _ready() -> void:
response_tpl.visible = false
next_button.visible = false
visible = false
## If the mouse is currently hidden, make it visible until the
## player makes a selection in the dialog scene
_mouse_mode = Input.mouse_mode
if _mouse_mode == Input.MOUSE_MODE_HIDDEN:
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
## Setup what to do if there are no options and the next button
## is shown, which is "Continue". In this case the selection is
## set as -1 and the signal gets emitted.
var button_handler := func():
selection = -1
_dialogue_finished()
next_button.pressed.connect(button_handler)
## Grab data from Orchestrator dictionary to present the UI
var character_name = dialogue_data["character_name"]
var message = dialogue_data["message"]
var options = dialogue_data["options"]
show_message(character_name, message, options)
func _unhandled_input(event: InputEvent) -> void:
if event is InputEventKey:
if event.is_pressed() and _should_end_typing(event.keycode):
if _current_tween.is_running():
_current_tween.stop()
speaker_text.visible_characters = speaker_text.text.length()
_on_tween_finished(_current_choices)
get_viewport().set_input_as_handled()
# ShowMessage is only allowed to process input when visible
_disable_player_movement()
func show_message(speaker_name: String, message: String, choices: Dictionary) -> void:
speaker.text = speaker_name
speaker_text.text = message
_current_choices = choices
await get_tree().process_frame
var duration = speaker_text.text.length() * TEXT_SPEED
_current_tween = get_tree().create_tween()
_current_tween.tween_property(speaker_text, "visible_characters", speaker_text.text.length(), duration)
_current_tween.finished.connect(Callable(_on_tween_finished).bind(choices))
show()
## Callback when the tween typing has finished.
## This allows presenting the user choice options or Continue button.
func _on_tween_finished(choices: Dictionary) -> void:
if choices.size() > 0:
for key in choices.keys():
var button = response_tpl.duplicate()
button.text = choices[key]
button.visible = true
speaker_text.get_parent().add_child(button)
var button_handler := func():
selection = key
_dialogue_finished()
button.pressed.connect(button_handler)
else:
next_button.show()
## Handles canceling the typing effect based on key codes
func _should_end_typing(keycode:int) -> bool:
return keycode == KEY_ESCAPE or keycode == KEY_SPACE
## Prevent user movement when the dialogue UI is shown
func _disable_player_movement() -> void:
var actions = InputMap.get_actions()
for action in actions:
Input.action_release(action)
func _dialogue_finished():
## If the mouse was previously hidden, restore state
if _mouse_mode == Input.MOUSE_MODE_HIDDEN:
Input.mouse_mode = _mouse_mode
show_message_finished.emit()
queue_free()