feat: Made dialogs pluggable (#424)

Co-authored-by: Dennis Ploeger <develop@dieploegers.de>
This commit is contained in:
Dennis Ploeger
2021-10-27 08:34:13 +02:00
committed by GitHub
parent 29dffbcf32
commit 57ce7fbcae
26 changed files with 633 additions and 305 deletions

View File

@@ -62,6 +62,8 @@ func run(command_params: Array) -> int:
)
escoria.event_manager.interrupt_running_event()
if escoria.dialog_player:
escoria.dialog_player.interrupt()
if !command_params[1]:
escoria.main.scene_transition.transition(

View File

@@ -1,6 +1,6 @@
# `say object text [type] [avatar]`
# `say player text [type]`
#
# Runs the specified string as a dialog said by the object. Blocks execution
# Runs the specified string as a dialog said by the player. Blocks execution
# until the dialog finishes playing.
#
# The text supports translation keys by prepending the key and separating
@@ -11,8 +11,6 @@
# Optional parameters:
#
# * "type" determines the type of dialog UI to use. Default value is "default"
# * "avatar" determines the avatar to use for the dialog. Default value is
# "default"
#
# @ESC
extends ESCBaseCommand
@@ -23,42 +21,41 @@ class_name SayCommand
func configure() -> ESCCommandArgumentDescriptor:
return ESCCommandArgumentDescriptor.new(
2,
[TYPE_STRING, TYPE_STRING, TYPE_STRING, TYPE_STRING],
[TYPE_STRING, TYPE_STRING, TYPE_STRING],
[
null,
null,
ProjectSettings.get_setting("escoria/ui/default_dialog_scene")\
.get_file().get_basename(),
"default"
ProjectSettings.get_setting("escoria/ui/default_dialog_type")
]
)
# Validate wether the given arguments match the command descriptor
func validate(arguments: Array):
if not escoria.object_manager.objects.has(arguments[0]):
escoria.logger.report_errors(
"anim: invalid object",
[
"Object with global id %s not found." % arguments[0]
]
)
return false
if ProjectSettings.get_setting("escoria/ui/default_dialog_type") == "" \
and arguments[2] == "":
escoria.logger.report_errors(
"say()",
[
"Project setting 'escoria/ui/default_dialog_type' is not set.",
"Please set a default dialog type."
]
)
return .validate(arguments)
# Run the command
func run(command_params: Array) -> int:
var dict: Dictionary
var dialog_scene_name = ProjectSettings.get_setting(
"escoria/ui/default_dialog_scene"
)
if dialog_scene_name.empty():
escoria.logger.report_errors(
"say()",
[
"Project setting 'escoria/ui/default_dialog_scene' is not set.",
"Please set a default dialog scene."
]
)
return ESCExecution.RC_ERROR
var file = dialog_scene_name.get_file()
var extension = dialog_scene_name.get_extension()
dialog_scene_name = file.rstrip("." + extension)
# Manage specific dialog scene
if command_params.size() > 2:
dialog_scene_name = command_params[2]
escoria.current_state = escoria.GAME_STATE.DIALOG
@@ -74,9 +71,9 @@ func run(command_params: Array) -> int:
escoria.dialog_player.say(
command_params[0],
dialog_scene_name,
command_params[2],
command_params[1]
)
yield(escoria.dialog_player, "dialog_line_finished")
yield(escoria.dialog_player, "say_finished")
escoria.current_state = escoria.GAME_STATE.DEFAULT
return ESCExecution.RC_OK

View File

@@ -53,7 +53,7 @@ var resource_cache: ESCResourceCache
var room_terrain
# Dialog player instantiator. This instance is called directly for dialogs.
var dialog_player: ESCDialogsPlayer
var dialog_player: ESCDialogPlayer
# Inventory scene
var inventory

View File

@@ -0,0 +1,63 @@
# A base class for dialog plugins to work with Escoria
extends Control
class_name ESCDialogManager
# Emitted when the say function has completed showing the text
signal say_finished
# Emitted when the player has chosen an option
signal option_chosen(option)
# Check wether a specific type is supported by the
# dialog plugin
#
# #### Parameters
# - type: required type
# *Returns* Wether the type is supported or not
func has_type(type: String) -> bool:
return false
# Check wether a specific chooser type is supported by the
# dialog plugin
#
# #### Parameters
# - type: required chooser type
# *Returns* Wether the type is supported or not
func has_chooser_type(type: String) -> bool:
return false
# Output a text said by the item specified by the global id. Emit
# `say_finished` after finishing displaying the text.
#
# #### Parameters
# - dialog_player: Node of the dialog player in the UI
# - global_id: Global id of the item that is speaking
# - text: Text to say, optional prefixed by a translation key separated
# by a ":"
# - type: Type of dialog box to use
func say(dialog_player: Node, global_id: String, text: String, type: String):
pass
# Present an option chooser to the player and sends the signal
# `option_chosen` with the chosen dialog option
#
# #### Parameters
# - dialog_player: Node of the dialog player in the UI
# - dialog: Information about the dialog to display
func choose(dialog_player: Node, dialog: ESCDialog):
pass
# Trigger running the dialog faster
func speedup():
pass
# The say command has been interrupted, cancel the dialog display
func interrupt():
pass

View File

@@ -1,5 +1,5 @@
# Base class for all dialog options implementations
extends Node
extends Control
class_name ESCDialogOptionsChooser

View File

@@ -1,6 +1,6 @@
# Escoria dialog player
extends ResourcePreloader
class_name ESCDialogsPlayer
extends Node
class_name ESCDialogPlayer
# Emitted when an answer as chosem
@@ -10,38 +10,25 @@ class_name ESCDialogsPlayer
# - option: The dialog option that was chosen
signal option_chosen(option)
# Emitted when a dialog line was finished
signal dialog_line_finished
# Emitted when a say command finished
signal say_finished
# Wether the player is currently speaking
var is_speaking = false
var is_speaking: bool = false
# Reference to the dialog UI
var _dialog_ui = null
# Reference to the dialog chooser UI
var _dialog_chooser_ui: ESCDialogOptionsChooser = null
# Reference to the currently playing dialog manager
var _dialog_manager: ESCDialogManager = null
# Register the dialog player and load the dialog resources
func _ready():
if !Engine.is_editor_hint():
escoria.dialog_player = self
_dialog_chooser_ui = ResourceLoader.load(
ProjectSettings.get_setting("escoria/ui/dialogs_chooser")
).instance()
assert(_dialog_chooser_ui is ESCDialogOptionsChooser)
_dialog_chooser_ui.connect(
"option_chosen",
self,
"play_dialog_option_chosen"
)
get_parent().call_deferred("add_child", _dialog_chooser_ui)
# Trigger the finish fast function on the dialog ui
# Trigger the speedup function in the dialog manager
#
# #### Parameters
#
@@ -49,9 +36,17 @@ func _ready():
func _input(event):
if event is InputEventMouseButton and \
event.pressed:
finish_fast()
speedup()
# Find the matching voice output file for the given key
#
# #### Parameters
#
# - key: Text key provided
# - start: Starting folder to search for voices
#
# *Returns* The path to the matching voice file
func _get_voice_file(key: String, start: String = "") -> String:
if start == "":
start = ProjectSettings.get("escoria/sound/speech_folder")
@@ -77,40 +72,54 @@ func _get_voice_file(key: String, start: String = "") -> String:
return ""
# A short one line dialog
# Make a character say a text
#
# #### Parameters
#
# - character: Character that is talking
# - ui: UI to use for the dialog
# - line: Line to say
func say(character: String, ui: String, line: String) -> void:
# - type: UI to use for the dialog
# - text: Text to say
func say(character: String, type: String, text: String) -> void:
is_speaking = true
_dialog_ui = get_resource(ui).instance()
get_parent().add_child(_dialog_ui)
var _key_line = line.split(":")
if _key_line.size() == 1:
line = _key_line[0]
elif _key_line.size() >= 2:
var _speech_resource = _get_voice_file(_key_line[0])
for _manager_class in ProjectSettings.get_setting(
"escoria/ui/dialog_managers"
):
if ResourceLoader.exists(_manager_class):
var _manager: ESCDialogManager = load(_manager_class).new()
if _manager.has_type(type):
_dialog_manager = _manager
if _dialog_manager == null:
escoria.logger.report_errors(
"esc_dialog_player.gd: Unknown type",
[
"No dialog manager supports the type %s" % type
]
)
var _key_text = text.split(":")
if _key_text.size() == 1:
text = _key_text[0]
elif _key_text.size() >= 2:
var _speech_resource = _get_voice_file(_key_text[0])
if _speech_resource != "":
(
escoria.object_manager.get_object("_speech").node\
as ESCSpeechPlayer
).set_state(_speech_resource)
line = tr(_key_line[0])
_dialog_ui.say(character, line)
yield(_dialog_ui, "dialog_line_finished")
text = tr(_key_text[0])
_dialog_manager.say(self, character, text, type)
yield(_dialog_manager, "say_finished")
is_speaking = false
emit_signal("dialog_line_finished")
emit_signal("say_finished")
# Called when a dialog line is skipped
func finish_fast() -> void:
if is_speaking and\
escoria.inputs_manager.input_mode != escoria.inputs_manager.INPUT_NONE:
_dialog_ui.finish_fast()
func speedup() -> void:
if is_speaking and escoria.inputs_manager.input_mode != \
escoria.inputs_manager.INPUT_NONE and \
_dialog_manager != null:
_dialog_manager.speedup()
# Display a list of choices
@@ -118,22 +127,37 @@ func finish_fast() -> void:
# #### Parameters
#
# - dialog: The dialog to start
func start_dialog_choices(dialog: ESCDialog):
func start_dialog_choices(dialog: ESCDialog, type: String = "simple"):
if dialog.options.empty():
escoria.logger.report_errors(
"dialog_player.gd:start_dialog_choices()",
["Received answers array was empty."]
)
_dialog_chooser_ui.set_dialog(dialog)
_dialog_chooser_ui.show_chooser()
# Called when an option was chosen and emits the option_chosen signal
#
# #### Parameters
#
# - option: Option, that was chosen.
func play_dialog_option_chosen(option: ESCDialogOption):
var _dialog_chooser_ui: ESCDialogManager = null
for _manager_class in ProjectSettings.get_setting(
"escoria/ui/dialog_managers"
):
if ResourceLoader.exists(_manager_class):
var _manager: ESCDialogManager = load(_manager_class).new()
if _manager.has_chooser_type(type):
_dialog_chooser_ui = _manager
if _dialog_chooser_ui == null:
escoria.logger.report_errors(
"esc_dialog_player.gd: Unknown chooser type",
[
"No dialog manager supports the chooser type %s" % type
]
)
_dialog_chooser_ui.choose(self, dialog)
var option = yield(_dialog_chooser_ui, "option_chosen")
emit_signal("option_chosen", option)
_dialog_chooser_ui.hide_chooser()
# Interrupt the currently running dialog
func interrupt():
if _dialog_manager != null:
_dialog_manager.interrupt()

View File

@@ -1,10 +0,0 @@
[gd_scene load_steps=5 format=2]
[ext_resource path="res://addons/escoria-core/ui_library/dialogs/floating_dialog_player.tscn" type="PackedScene" id=1]
[ext_resource path="res://addons/escoria-core/ui_library/dialogs/text_dialog_chooser.tscn" type="PackedScene" id=2]
[ext_resource path="res://addons/escoria-core/game/scenes/dialogs/esc_dialog_player.gd" type="Script" id=3]
[ext_resource path="res://addons/escoria-core/ui_library/dialogs/avatar_dialog_player.tscn" type="PackedScene" id=4]
[node name="dialog_player" type="ResourcePreloader"]
resources = [ PoolStringArray( "avatar_dialog_player", "floating_dialog_player", "text_dialog_choice" ), [ ExtResource( 4 ), ExtResource( 1 ), ExtResource( 2 ) ] ]
script = ExtResource( 3 )

View File

@@ -34,25 +34,13 @@ func set_escoria_ui_settings():
if !ProjectSettings.has_setting("escoria/ui/tooltip_follows_mouse"):
ProjectSettings.set_setting("escoria/ui/tooltip_follows_mouse", true)
if !ProjectSettings.has_setting("escoria/ui/dialogs_chooser"):
ProjectSettings.set_setting("escoria/ui/dialogs_chooser", "")
var dialogs_chooser_property_info = {
"name": "escoria/ui/dialogs_chooser",
"type": TYPE_STRING,
"hint": PROPERTY_HINT_FILE,
"hint_string": "*.tscn, *.scn"
_register_setting(
"escoria/ui/default_dialog_type",
"",
{
"type": TYPE_STRING
}
ProjectSettings.add_property_info(dialogs_chooser_property_info)
if !ProjectSettings.has_setting("escoria/ui/default_dialog_scene"):
ProjectSettings.set_setting("escoria/ui/default_dialog_scene", "")
var default_dialog_scene_property_info = {
"name": "escoria/ui/default_dialog_scene",
"type": TYPE_STRING,
"hint": PROPERTY_HINT_FILE,
"hint_string": "*.tscn, *.scn"
}
ProjectSettings.add_property_info(default_dialog_scene_property_info)
)
if !ProjectSettings.has_setting("escoria/ui/game_scene"):
ProjectSettings.set_setting("escoria/ui/game_scene", "")
@@ -109,6 +97,13 @@ func set_escoria_ui_settings():
"type": TYPE_VECTOR2
})
_register_setting(
"escoria/ui/dialog_managers",
[],
{
"type": TYPE_STRING_ARRAY
}
)
# Prepare the settings in the Escoria main category
func set_escoria_main_settings():
@@ -277,32 +272,47 @@ func set_escoria_sound_settings():
}
ProjectSettings.add_property_info(speech_data_property_info)
if !ProjectSettings.has_setting("escoria/sound/speech_enabled"):
ProjectSettings.set_setting("escoria/sound/speech_enabled", 1)
var speech_enabled_property_info = {
"name": "escoria/sound/speech_enabled",
_register_setting(
"escoria/sound/speech_enabled",
1,
{
"type": TYPE_BOOL
}
ProjectSettings.add_property_info(speech_enabled_property_info)
if !ProjectSettings.has_setting("escoria/sound/speech_folder"):
ProjectSettings.set_setting(
"escoria/sound/speech_folder",
"res://speech"
)
ProjectSettings.add_property_info({
"name": "escoria/sound/speech_folder",
)
_register_setting(
"escoria/sound/speech_folder",
"res://speech",
{
"type": TYPE_STRING,
"hint": PROPERTY_HINT_DIR
})
if !ProjectSettings.has_setting("escoria/sound/speech_extension"):
ProjectSettings.set_setting(
"escoria/sound/speech_extension",
"ogg"
)
ProjectSettings.add_property_info({
"name": "escoria/sound/speech_extension",
}
)
_register_setting(
"escoria/sound/speech_extension",
"ogg",
{
"type": TYPE_STRING
})
}
)
# Register a new project setting if it hasn't been defined already
#
# #### Parameters
#
# - name: Name of the project setting
# - default: Default value
# - info: Property info for the setting
func _register_setting(name: String, default, info: Dictionary):
if not ProjectSettings.has_setting(name):
ProjectSettings.set_setting(
name,
default
)
info.name = name
ProjectSettings.add_property_info(info)
# Prepare the settings in the Escoria platform category and may need special

View File

@@ -1,111 +0,0 @@
# A dialog GUI showing a dialog box and character portraits
extends Popup
# Signal emitted when a dialog line has started
signal dialog_line_started
# Signal emitted when a dialog line has finished
signal dialog_line_finished
# The currently speaking character
export(String) var current_character setget set_current_character
# The text speed per character for normal display
export(float, 0.0, 0.3) var text_speed_per_character = 0.1
# The text speed per character if the dialog line is skipped
export(float) var fast_text_speed_per_character = 0.25
# The time to wait before the dialog is finished
export(float) var max_time_to_text_disappear = 1.0
# The node holding the avatar
onready var avatar_node = $Panel/MarginContainer/HSplitContainer/VBoxContainer\
/avatar
# The node holding the player name
onready var name_node = $Panel/MarginContainer/HSplitContainer/VBoxContainer\
/name
# The node showing the text
onready var text_node = $Panel/MarginContainer/HSplitContainer/text
# The tween node for text animations
onready var tween = text_node.get_node("Tween")
# Build up the UI
func _ready():
var centered_position_on_screen = Vector2(
ProjectSettings.get_setting("display/window/size/width") / 2,
ProjectSettings.get_setting("display/window/size/height") / 2
) - rect_size / 2
rect_position = centered_position_on_screen
text_node.bbcode_enabled = true
$Panel/MarginContainer/HSplitContainer/text/Tween.connect(
"tween_completed",
self,
"_on_dialog_line_typed"
)
# Switch the current character
#
# #### Parameters
# - name: The name of the current character
func set_current_character(name: String):
# TODO: Make this configurable in #47
var avatar = "res://game/dialog_avatars/%s.tres" % name
if ResourceLoader.exists(avatar):
$Panel/MarginContainer/HSplitContainer/VBoxContainer/avatar.texture = \
ResourceLoader.load(avatar)
current_character = name
# Make a character say something
#
# #### Parameters
# - character: The global id of the character speaking
# - line: Line to say
func say(character: String, line: String) :
popup_centered()
emit_signal("dialog_line_started")
set_current_character(character)
text_node.bbcode_text = tr(line)
text_node.percent_visible = 0.0
var time_show_full_text = text_speed_per_character * len(line)
tween.interpolate_property(text_node, "percent_visible",
0.0, 1.0, time_show_full_text,
Tween.TRANS_LINEAR, Tween.EASE_IN_OUT)
tween.start()
# Called by the dialog player when the
func finish_fast():
tween.stop(text_node)
tween.interpolate_property(text_node, "percent_visible",
text_node.percent_visible, 1.0, fast_text_speed_per_character,
Tween.TRANS_LINEAR, Tween.EASE_IN_OUT)
tween.start()
# The dialog line was printed, start the waiting time and then finish
# the dialog
func _on_dialog_line_typed(object, key):
text_node.visible_characters = -1
$Timer.start(max_time_to_text_disappear)
$Timer.connect("timeout", self, "_on_dialog_finished")
# Ending the dialog
func _on_dialog_finished():
emit_signal("dialog_line_finished")
queue_free()

View File

@@ -1,74 +0,0 @@
[gd_scene load_steps=2 format=2]
[ext_resource path="res://addons/escoria-core/ui_library/dialogs/avatar_dialog_player.gd" type="Script" id=1]
[node name="dialog_box" type="Popup"]
anchor_right = 1.0
anchor_bottom = 1.0
margin_right = -782.0
margin_bottom = -734.0
script = ExtResource( 1 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="Timer" type="Timer" parent="."]
[node name="Panel" type="Panel" parent="."]
anchor_right = 1.0
anchor_bottom = 1.0
__meta__ = {
"_edit_use_anchors_": false
}
[node name="MarginContainer" type="MarginContainer" parent="Panel"]
anchor_right = 1.0
anchor_bottom = 1.0
custom_constants/margin_right = 20
custom_constants/margin_top = 20
custom_constants/margin_left = 20
custom_constants/margin_bottom = 20
__meta__ = {
"_edit_use_anchors_": false
}
[node name="HSplitContainer" type="HSplitContainer" parent="Panel/MarginContainer"]
margin_left = 20.0
margin_top = 20.0
margin_right = 478.0
margin_bottom = 146.0
custom_constants/separation = 35
dragger_visibility = 1
[node name="VBoxContainer" type="VBoxContainer" parent="Panel/MarginContainer/HSplitContainer"]
margin_right = 88.0
margin_bottom = 126.0
size_flags_horizontal = 3
size_flags_stretch_ratio = 0.3
[node name="avatar" type="TextureRect" parent="Panel/MarginContainer/HSplitContainer/VBoxContainer"]
margin_right = 88.0
margin_bottom = 108.0
size_flags_horizontal = 3
size_flags_vertical = 3
expand = true
[node name="name" type="Label" parent="Panel/MarginContainer/HSplitContainer/VBoxContainer"]
margin_top = 112.0
margin_right = 88.0
margin_bottom = 126.0
valign = 1
[node name="text" type="RichTextLabel" parent="Panel/MarginContainer/HSplitContainer"]
margin_left = 123.0
margin_right = 458.0
margin_bottom = 126.0
size_flags_horizontal = 3
bbcode_enabled = true
bbcode_text = "Here be some text"
text = "Here be some text"
__meta__ = {
"_edit_use_anchors_": false
}
[node name="Tween" type="Tween" parent="Panel/MarginContainer/HSplitContainer/text"]

View File

@@ -1,94 +0,0 @@
# A dialog UI using a label above the head of the character
extends RichTextLabel
# Signal emitted when a dialog line has started
signal dialog_line_started
# Signal emitted when a dialog line has finished
signal dialog_line_finished
# The text speed per character for normal display
export(float, 0.0, 0.3) var text_speed_per_character = 0.1
# The text speed per character if the dialog line is skipped
export(float) var fast_text_speed_per_character = 0.25
# The time to wait before the dialog is finished
export(float) var max_time_to_text_disappear = 2.0
# Current character speaking, to keep track of reference for animation purposes
var current_character
# Tween node for text animation
onready var tween = $Tween
# The node showing the text
onready var text_node = self
# Enable bbcode and catch the signal when a tween completed
func _ready():
bbcode_enabled = true
$Tween.connect("tween_completed", self, "_on_dialog_line_typed")
# Make a character say something
#
# #### Parameters
# - character: The global id of the character speaking
# - line: Line to say
func say(character: String, line: String) :
show()
emit_signal("dialog_line_started")
# Position the RichTextLabel on the character's dialog position, if any.
current_character = escoria.object_manager.get_object(character).node
rect_position = current_character.get_node("dialog_position").get_global_transform_with_canvas().origin
rect_position.x -= rect_size.x / 2
current_character.start_talking()
# Set text color to color set in the actor
var text_color = current_character.dialog_color
var text_color_html = text_color.to_html(false)
text_node.bbcode_text = "[center][color=#" + text_color_html + "]" \
.format([text_color_html]) + tr(line) + "[/color][center]"
text_node.percent_visible = 0.0
var time_show_full_text = text_speed_per_character * len(line)
tween.interpolate_property(text_node, "percent_visible",
0.0, 1.0, time_show_full_text,
Tween.TRANS_LINEAR, Tween.EASE_IN_OUT)
tween.start()
# Called by the dialog player when the
func finish_fast():
tween.stop(text_node)
tween.interpolate_property(text_node, "percent_visible",
text_node.percent_visible, 1.0, fast_text_speed_per_character,
Tween.TRANS_LINEAR, Tween.EASE_IN_OUT)
tween.start()
# The dialog line was printed, start the waiting time and then finish
# the dialog
func _on_dialog_line_typed(object, key):
text_node.visible_characters = -1
$Timer.start(max_time_to_text_disappear)
$Timer.connect("timeout", self, "_on_dialog_finished")
# Ending the dialog
func _on_dialog_finished():
current_character.stop_talking()
emit_signal("dialog_line_finished")
escoria.dialog_player.is_speaking = false
queue_free()

View File

@@ -1,20 +0,0 @@
[gd_scene load_steps=2 format=2]
[ext_resource path="res://addons/escoria-core/ui_library/dialogs/floating_dialog_player.gd" type="Script" id=2]
[node name="dialog_label" type="RichTextLabel"]
margin_right = 643.0
margin_bottom = 60.0
bbcode_enabled = true
bbcode_text = "[center]Here be some text.[/center]"
text = "Here be some text."
fit_content_height = true
script = ExtResource( 2 )
__meta__ = {
"_edit_use_anchors_": false
}
text_speed_per_character = 0.0
[node name="Tween" type="Tween" parent="."]
[node name="Timer" type="Timer" parent="."]

View File

@@ -1,83 +0,0 @@
# A simple dialog chooser that shows selectable lines of text
# Supports timeout and avatar display
extends ESCDialogOptionsChooser
export(Color, RGB) var color_normal = Color(1.0,1.0,1.0,1.0)
export(Color, RGB) var color_hover = Color(165.0,42.0,42.0, 1.0)
export(Font) var font
# Hide the chooser at the start just to be safe
func _ready() -> void:
hide_chooser()
# Process the timeout display
func _process(delta: float) -> void:
if $MarginContainer.visible and self.dialog and self.dialog.timeout > 0:
$TimerProgress.value = (
self.dialog.timeout - $Timer.time_left
) / self.dialog.timeout * 100
# Show the chooser
func show_chooser():
var _vbox = $MarginContainer/ScrollContainer/VBoxContainer
for option_node in _vbox.get_children():
_vbox.remove_child(option_node)
_remove_avatar()
for option in self.dialog.options:
var _option_node = Button.new()
_option_node.text = (option as ESCDialogOption).option
_option_node.flat = true
_option_node.add_color_override("font_color", color_normal)
_option_node.add_color_override("font_color_hover", color_hover)
_option_node.add_font_override("font", font)
_vbox.add_child(_option_node)
_option_node.connect("pressed", self, "_on_answer_selected", [option])
if self.dialog.avatar != "-":
$AvatarContainer.add_child(
ResourceLoader.load(self.dialog.avatar).instance()
)
$MarginContainer.show()
if self.dialog.timeout > 0:
$Timer.start(self.dialog.timeout)
# Hide the chooser
func hide_chooser():
$MarginContainer.hide()
# An option was choosen, emit the option
#
# #### Parameters
# - option: Option that was chosen
func _option_chosen(option: ESCDialogOption):
_remove_avatar()
$TimerProgress.value = 0
emit_signal("option_chosen", option)
# An option was chosen directly from the list
#
# #### Parameters
# - option: Option that was chosen
func _on_answer_selected(option: ESCDialogOption):
_option_chosen(option)
# The timeout came and a option was selected
func _on_Timer_timeout() -> void:
_option_chosen(self.dialog.options[self.dialog.timeout_option - 1])
# Remove the avatar
func _remove_avatar():
if $AvatarContainer.get_child_count() > 0:
$AvatarContainer.remove_child($AvatarContainer.get_child(0))

View File

@@ -1,61 +0,0 @@
[gd_scene load_steps=4 format=2]
[ext_resource path="res://addons/escoria-core/ui_library/dialogs/text_dialog_chooser.gd" type="Script" id=1]
[sub_resource type="Gradient" id=1]
colors = PoolColorArray( 1, 0, 0, 1, 1, 0, 0, 1 )
[sub_resource type="GradientTexture" id=2]
gradient = SubResource( 1 )
[node name="text_dialog_choice" type="Node"]
script = ExtResource( 1 )
[node name="MarginContainer" type="MarginContainer" parent="."]
margin_left = 20.0
margin_top = 20.0
margin_right = 1280.0
margin_bottom = 900.0
mouse_filter = 2
custom_constants/margin_top = 20
custom_constants/margin_left = 20
__meta__ = {
"_edit_use_anchors_": false
}
[node name="ScrollContainer" type="ScrollContainer" parent="MarginContainer"]
margin_left = 20.0
margin_top = 20.0
margin_right = 1260.0
margin_bottom = 880.0
scroll_horizontal_enabled = false
__meta__ = {
"_edit_use_anchors_": false
}
[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/ScrollContainer"]
margin_right = 1240.0
margin_bottom = 860.0
size_flags_horizontal = 3
size_flags_vertical = 3
custom_constants/separation = 20
__meta__ = {
"_edit_use_anchors_": false
}
[node name="Timer" type="Timer" parent="."]
one_shot = true
[node name="TimerProgress" type="TextureProgress" parent="."]
anchor_right = 1.0
rect_min_size = Vector2( 0, 20 )
texture_progress = SubResource( 2 )
nine_patch_stretch = true
__meta__ = {
"_edit_use_anchors_": false
}
[node name="AvatarContainer" type="Node2D" parent="."]
position = Vector2( 29.1458, 120.012 )
[connection signal="timeout" from="Timer" to="." method="_on_Timer_timeout"]