feat: Implemented all dialog features. Fixes #345 (#376)

Co-authored-by: Dennis Ploeger <develop@dieploegers.de>
Co-authored-by: dploeger <dploeger@users.noreply.github.com>
This commit is contained in:
Dennis Ploeger
2021-08-27 08:15:52 +02:00
committed by GitHub
parent 2ed184ad4a
commit 1f28fdc8f3
19 changed files with 418 additions and 172 deletions

View File

@@ -5,7 +5,7 @@ class_name ESCDialog
# Regex that matches dialog lines
const REGEX = \
'^(\\s*)\\?( (?<type>[^ ]+))?( (?<avatar>[^ ]+))?' +\
'^(\\s*)\\?( (?<avatar>[^ ]+))?' +\
'( (?<timeout>[^ ]+))?( (?<timeout_option>.+))?$'
@@ -14,11 +14,8 @@ const END_REGEX = \
'^(?<indent>\\s*)!.*$'
# Dialog type
var type: String = ""
# Avatar used in the dialog
var avatar: String = ""
var avatar: String = "-"
# Timeout until the timeout_option option is selected. Use 0 for no timeout
var timeout: int = 0
@@ -37,8 +34,6 @@ func _init(dialog_string: String):
if dialog_regex.search(dialog_string):
for result in dialog_regex.search_all(dialog_string):
if "type" in result.names:
self.type = escoria.utils.get_re_group(result, "type")
if "avatar" in result.names:
self.avatar = escoria.utils.get_re_group(result, "avatar")
if "timeout" in result.names:
@@ -58,8 +53,22 @@ func _init(dialog_string: String):
)
# Dialogs have no conditions, just return true
# Check if dialog is valid
func is_valid() -> bool:
if self.avatar != "-" and not ResourceLoader.exists(self.avatar):
escoria.logger.report_errors(
"Avatar scene not found: %s" % self.avatar,
[]
)
return false
if self.timeout_option > self.options.size() \
or self.timeout_option < 0:
escoria.logger.report_errors(
"Invalid timeout_option parameter given: %d" % self.timeout_option,
[]
)
return false
return true

View File

@@ -18,62 +18,41 @@ signal dialog_line_finished
# Wether the player is currently speaking
var is_speaking = false
# Reference to the dialog UI
var _dialog_ui = null
# Reference to the dialog chooser UI
var _dialog_chooser_ui = null
var _dialog_chooser_ui: ESCDialogOptionsChooser = null
# Register the dialog player and load the dialog resources
func _ready():
if !Engine.is_editor_hint():
escoria.dialog_player = self
preload_resources(ProjectSettings.get_setting("escoria/ui/dialogs_folder"))
_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
#
# #### Parameters
#
# - event: The input event
func _input(event):
if event is InputEventMouseButton and \
event.pressed:
finish_fast()
# Preload the dialog UI resources
#
# #### Parameters
#
# - path: Path where the actual dialog UI resources are located
func preload_resources(path: String) -> void:
var dialog_folder := Directory.new()
if !path.empty() and dialog_folder.open(path) == OK:
dialog_folder.list_dir_begin()
var file_name = dialog_folder.get_next()
while file_name != "":
if !dialog_folder.current_is_dir() \
and file_name.get_extension() == "tscn":
var extension = "." + file_name.get_extension()
var basename = file_name.replace(extension, "")
if !has_resource(basename):
var file_path = "%s/%s" % [
dialog_folder.get_current_dir(),
file_name
]
var dialog_scene = load(file_path)
if dialog_scene != null:
add_resource(basename, dialog_scene)
file_name = dialog_folder.get_next()
else:
escoria.logger.report_errors(
"dialog_player.gd:preload_resources()",
[
"An error occurred when trying to access the path: %s." % path
]
)
# A short one line dialog
#
# #### Parameters
@@ -99,20 +78,26 @@ func finish_fast() -> void:
# Display a list of choices
#
# #### Parameters
#
# - dialog: The dialog to start
func start_dialog_choices(dialog: ESCDialog):
if dialog.options.empty():
escoria.logger.report_errors(
"dialog_player.gd:start_dialog_choices()",
["Received answers array was empty."]
)
_dialog_chooser_ui = get_resource("text_dialog_choice").instance()
get_parent().add_child(_dialog_chooser_ui)
_dialog_chooser_ui.set_answers(dialog.options)
_dialog_chooser_ui.set_dialog(dialog)
_dialog_chooser_ui.show_chooser()
# Called when an option was chosen
# 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):
emit_signal("option_chosen", option)
_dialog_chooser_ui.hide()
_dialog_chooser_ui.hide_chooser()

View File

@@ -0,0 +1,34 @@
# Base class for all dialog options implementations
extends Node
class_name ESCDialogOptionsChooser
# An option was chosen
#
# ##### Parameters
#
# - option: The dialog option that was chosen
signal option_chosen(option)
# The dialog to show
var dialog: ESCDialog
# Set the dialog used for the chooser
#
# #### Parameters
#
# - new_dialog: Dialog to set
func set_dialog(new_dialog: ESCDialog) -> void:
self.dialog = new_dialog
# Show the dialog chooser UI
func show_chooser() -> void:
escoria.logger.error("Dialog chooser did not implement the show method.")
# Hide the dialog chooser UI
func hide_chooser() -> void:
escoria.logger.error("Dialog chooser did not implement the hide method.")