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 # Regex that matches dialog lines
const REGEX = \ const REGEX = \
'^(\\s*)\\?( (?<type>[^ ]+))?( (?<avatar>[^ ]+))?' +\ '^(\\s*)\\?( (?<avatar>[^ ]+))?' +\
'( (?<timeout>[^ ]+))?( (?<timeout_option>.+))?$' '( (?<timeout>[^ ]+))?( (?<timeout_option>.+))?$'
@@ -14,11 +14,8 @@ const END_REGEX = \
'^(?<indent>\\s*)!.*$' '^(?<indent>\\s*)!.*$'
# Dialog type
var type: String = ""
# Avatar used in the dialog # Avatar used in the dialog
var avatar: String = "" var avatar: String = "-"
# Timeout until the timeout_option option is selected. Use 0 for no timeout # Timeout until the timeout_option option is selected. Use 0 for no timeout
var timeout: int = 0 var timeout: int = 0
@@ -37,8 +34,6 @@ func _init(dialog_string: String):
if dialog_regex.search(dialog_string): if dialog_regex.search(dialog_string):
for result in dialog_regex.search_all(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: if "avatar" in result.names:
self.avatar = escoria.utils.get_re_group(result, "avatar") self.avatar = escoria.utils.get_re_group(result, "avatar")
if "timeout" in result.names: 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: 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 return true

View File

@@ -18,62 +18,41 @@ signal dialog_line_finished
# Wether the player is currently speaking # Wether the player is currently speaking
var is_speaking = false var is_speaking = false
# Reference to the dialog UI # Reference to the dialog UI
var _dialog_ui = null var _dialog_ui = null
# Reference to the dialog chooser UI # 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 # Register the dialog player and load the dialog resources
func _ready(): func _ready():
if !Engine.is_editor_hint(): if !Engine.is_editor_hint():
escoria.dialog_player = self 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 # Trigger the finish fast function on the dialog ui
#
# #### Parameters
#
# - event: The input event
func _input(event): func _input(event):
if event is InputEventMouseButton and \ if event is InputEventMouseButton and \
event.pressed: event.pressed:
finish_fast() 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 # A short one line dialog
# #
# #### Parameters # #### Parameters
@@ -99,20 +78,26 @@ func finish_fast() -> void:
# Display a list of choices # Display a list of choices
#
# #### Parameters
#
# - dialog: The dialog to start
func start_dialog_choices(dialog: ESCDialog): func start_dialog_choices(dialog: ESCDialog):
if dialog.options.empty(): if dialog.options.empty():
escoria.logger.report_errors( escoria.logger.report_errors(
"dialog_player.gd:start_dialog_choices()", "dialog_player.gd:start_dialog_choices()",
["Received answers array was empty."] ["Received answers array was empty."]
) )
_dialog_chooser_ui = get_resource("text_dialog_choice").instance() _dialog_chooser_ui.set_dialog(dialog)
get_parent().add_child(_dialog_chooser_ui) _dialog_chooser_ui.show_chooser()
_dialog_chooser_ui.set_answers(dialog.options)
# 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): func play_dialog_option_chosen(option: ESCDialogOption):
emit_signal("option_chosen", option) 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.")

View File

@@ -26,14 +26,15 @@ func set_escoria_ui_settings():
if !ProjectSettings.has_setting("escoria/ui/tooltip_follows_mouse"): if !ProjectSettings.has_setting("escoria/ui/tooltip_follows_mouse"):
ProjectSettings.set_setting("escoria/ui/tooltip_follows_mouse", true) ProjectSettings.set_setting("escoria/ui/tooltip_follows_mouse", true)
if !ProjectSettings.has_setting("escoria/ui/dialogs_folder"): if !ProjectSettings.has_setting("escoria/ui/dialogs_chooser"):
ProjectSettings.set_setting("escoria/ui/dialogs_folder", "") ProjectSettings.set_setting("escoria/ui/dialogs_chooser", "")
var dialogs_folder_property_info = { var dialogs_chooser_property_info = {
"name": "escoria/ui/dialogs_folder", "name": "escoria/ui/dialogs_chooser",
"type": TYPE_STRING, "type": TYPE_STRING,
"hint": PROPERTY_HINT_DIR "hint": PROPERTY_HINT_FILE,
"hint_string": "*.tscn, *.scn"
} }
ProjectSettings.add_property_info(dialogs_folder_property_info) ProjectSettings.add_property_info(dialogs_chooser_property_info)
if !ProjectSettings.has_setting("escoria/ui/default_dialog_scene"): if !ProjectSettings.has_setting("escoria/ui/default_dialog_scene"):
ProjectSettings.set_setting("escoria/ui/default_dialog_scene", "") ProjectSettings.set_setting("escoria/ui/default_dialog_scene", "")

View File

@@ -1,53 +1,67 @@
tool extends ESCDialogOptionsChooser
extends Control
export(Color, RGB) var color_normal = Color(1.0,1.0,1.0,1.0) 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(Color, RGB) var color_hover = Color(165.0,42.0,42.0, 1.0)
export(Font) var font export(Font) var font
var commands
func _ready(): func _ready() -> void:
for c in $ScrollContainer/VBoxContainer.get_children(): hide_chooser()
c.queue_free()
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
func set_answers(options : Array): func show_chooser():
commands = options var _vbox = $MarginContainer/ScrollContainer/VBoxContainer
for option in commands: for option_node in _vbox.get_children():
var new_answer_label = RichTextLabel.new() _vbox.remove_child(option_node)
new_answer_label.text = option.option
new_answer_label.fit_content_height = true _remove_avatar()
new_answer_label.add_font_override("normal_font", font)
for option in self.dialog.options:
$ScrollContainer/VBoxContainer.add_child(new_answer_label) var _option_node = Button.new()
new_answer_label.fit_content_height = true _option_node.text = (option as ESCDialogOption).option
new_answer_label.connect("focus_entered", self, "_on_answer_focus_entered", [new_answer_label]) # Focus entered _option_node.flat = true
new_answer_label.connect("focus_exited", self, "_on_answer_focus_exited", [new_answer_label]) # Focus exited _option_node.add_color_override("font_color", color_normal)
new_answer_label.connect("mouse_entered", self, "_on_answer_mouse_entered", [new_answer_label]) # Mouse entered _option_node.add_color_override("font_color_hover", color_hover)
new_answer_label.connect("mouse_exited", self, "_on_answer_mouse_exited", [new_answer_label]) # Mouse exited _option_node.add_font_override("font", font)
new_answer_label.connect("gui_input", self, "_on_answer_gui_input", [option]) # Clicks _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)
func _on_answer_gui_input(event : InputEvent, answer : ESCDialogOption):
if event is InputEventMouseButton and event.is_pressed():
escoria.dialog_player.play_dialog_option_chosen(answer)
func _on_answer_mouse_entered(answer_node : Node): func hide_chooser():
var text = answer_node.text $MarginContainer.hide()
answer_node.clear()
answer_node.push_color(color_hover.to_html(false))
answer_node.append_bbcode(text)
answer_node.pop()
func _on_answer_mouse_exited(answer_node : Node): func _option_chosen(option: ESCDialogOption):
var text = answer_node.text _remove_avatar()
answer_node.clear() $TimerProgress.value = 0
answer_node.push_color(color_normal.to_html(false)) emit_signal("option_chosen", option)
answer_node.append_bbcode(text)
answer_node.pop()
func _on_answer_focus_entered(answer_node : Node):
pass
func _on_answer_focus_exited(answer_node : Node): func _on_answer_selected(option: ESCDialogOption):
pass _option_chosen(option)
func _on_Timer_timeout() -> void:
_option_chosen(self.dialog.options[self.dialog.timeout_option - 1])
func _remove_avatar():
if $AvatarContainer.get_child_count() > 0:
$AvatarContainer.remove_child($AvatarContainer.get_child(0))

View File

@@ -1,33 +1,44 @@
[gd_scene load_steps=3 format=2] [gd_scene load_steps=5 format=2]
[ext_resource path="res://addons/escoria-core/template_scenes/dialog_scenes/dialog_choosers/text_dialog_choice.gd" type="Script" id=1] [ext_resource path="res://addons/escoria-core/template_scenes/dialog_scenes/dialog_choosers/text_dialog_choice.gd" type="Script" id=1]
[ext_resource path="res://addons/escoria-core/game/assets/fonts/efmi/efmi_font.tres" type="DynamicFont" id=2] [ext_resource path="res://addons/escoria-core/game/assets/fonts/efmi/efmi_font.tres" type="DynamicFont" id=2]
[node name="text_dialog_choice" type="MarginContainer"] [sub_resource type="Gradient" id=1]
anchor_right = 1.0 colors = PoolColorArray( 1, 0, 0, 1, 1, 0, 0, 1 )
anchor_bottom = 1.0
custom_constants/margin_top = 20 [sub_resource type="GradientTexture" id=2]
custom_constants/margin_left = 20 gradient = SubResource( 1 )
[node name="text_dialog_choice" type="Node"]
script = ExtResource( 1 ) script = ExtResource( 1 )
__meta__ = {
"_edit_use_anchors_": false
}
color_hover = Color( 0.647059, 0.164706, 0.164706, 1 ) color_hover = Color( 0.647059, 0.164706, 0.164706, 1 )
font = ExtResource( 2 ) font = ExtResource( 2 )
[node name="ScrollContainer" type="ScrollContainer" parent="."] [node name="MarginContainer" type="MarginContainer" parent="."]
margin_left = 20.0 margin_left = 20.0
margin_top = 20.0 margin_top = 20.0
margin_right = 1280.0 margin_right = 1280.0
margin_bottom = 800.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 scroll_horizontal_enabled = false
__meta__ = { __meta__ = {
"_edit_use_anchors_": false "_edit_use_anchors_": false
} }
[node name="VBoxContainer" type="VBoxContainer" parent="ScrollContainer"] [node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/ScrollContainer"]
margin_right = 1260.0 margin_right = 1240.0
margin_bottom = 780.0 margin_bottom = 860.0
size_flags_horizontal = 3 size_flags_horizontal = 3
size_flags_vertical = 3 size_flags_vertical = 3
custom_constants/separation = 20 custom_constants/separation = 20
@@ -35,9 +46,19 @@ __meta__ = {
"_edit_use_anchors_": false "_edit_use_anchors_": false
} }
[node name="example" type="RichTextLabel" parent="ScrollContainer/VBoxContainer"] [node name="Timer" type="Timer" parent="."]
margin_right = 1260.0 one_shot = true
margin_bottom = 25.0
custom_fonts/normal_font = ExtResource( 2 ) [node name="TimerProgress" type="TextureProgress" parent="."]
text = "This answer is an example for vizualisation purpose. You can safely keep it in the scene as it will be removed on game launch." anchor_right = 1.0
fit_content_height = true 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"]

View File

@@ -21,25 +21,17 @@ A Regex that matches the end of a dialog
### REGEX ### REGEX
```gdscript ```gdscript
const REGEX: String = "^(\\s*)\\?( (?<type>[^ ]+))?( (?<avatar>[^ ]+))?( (?<timeout>[^ ]+))?( (?<timeout_option>.+))?$" const REGEX: String = "^(\\s*)\\?( (?<avatar>[^ ]+))?( (?<timeout>[^ ]+))?( (?<timeout_option>.+))?$"
``` ```
Regex that matches dialog lines Regex that matches dialog lines
## Property Descriptions ## Property Descriptions
### type
```gdscript
var type: String = ""
```
Dialog type
### avatar ### avatar
```gdscript ```gdscript
var avatar: String = "" var avatar: String = "-"
``` ```
Avatar used in the dialog Avatar used in the dialog
@@ -84,7 +76,7 @@ Construct a dialog from a dialog string
func is_valid() -> bool func is_valid() -> bool
``` ```
Dialogs have no conditions, just return true Check if dialog is valid
### run ### run

View File

@@ -0,0 +1,57 @@
<!-- Auto-generated from JSON by GDScript docs maker. Do not edit this document directly. -->
# ESCDialogOptionsChooser
**Extends:** [Node](../Node)
## Description
Base class for all dialog options implementations
## Property Descriptions
### dialog
```gdscript
var dialog: ESCDialog
```
The dialog to show
## Method Descriptions
### set\_dialog
```gdscript
func set_dialog(new_dialog: ESCDialog) -> void
```
Set the dialog used for the chooser
#### Parameters
- new_dialog: Dialog to set
### show\_chooser
```gdscript
func show_chooser() -> void
```
Show the dialog chooser UI
### hide\_chooser
```gdscript
func hide_chooser() -> void
```
Hide the dialog chooser UI
## Signals
- signal option_chosen(option): An option was chosen
##### Parameters
- option: The dialog option that was chosen

View File

@@ -20,18 +20,6 @@ Wether the player is currently speaking
## Method Descriptions ## Method Descriptions
### preload\_resources
```gdscript
func preload_resources(path: String) -> void
```
Preload the dialog UI resources
#### Parameters
- path: Path where the actual dialog UI resources are located
### say ### say
```gdscript ```gdscript
@@ -62,13 +50,21 @@ func start_dialog_choices(dialog: ESCDialog)
Display a list of choices Display a list of choices
#### Parameters
- dialog: The dialog to start
### play\_dialog\_option\_chosen ### play\_dialog\_option\_chosen
```gdscript ```gdscript
func play_dialog_option_chosen(option: ESCDialogOption) func play_dialog_option_chosen(option: ESCDialogOption)
``` ```
Called when an option was chosen Called when an option was chosen and emits the option_chosen signal
#### Parameters
- option: Option, that was chosen.
## Signals ## Signals

View File

@@ -13,7 +13,7 @@ Logging framework for Escoria
### LOG\_DEBUG ### LOG\_DEBUG
```gdscript ```gdscript
const LOG_WARNING: int = 1 const LOG_ERROR: int = 0
``` ```
Valid log levels Valid log levels
@@ -21,7 +21,7 @@ Valid log levels
### LOG\_ERROR ### LOG\_ERROR
```gdscript ```gdscript
const LOG_WARNING: int = 1 const LOG_ERROR: int = 0
``` ```
Valid log levels Valid log levels
@@ -29,7 +29,7 @@ Valid log levels
### LOG\_INFO ### LOG\_INFO
```gdscript ```gdscript
const LOG_WARNING: int = 1 const LOG_ERROR: int = 0
``` ```
Valid log levels Valid log levels
@@ -37,7 +37,7 @@ Valid log levels
### LOG\_WARNING ### LOG\_WARNING
```gdscript ```gdscript
const LOG_WARNING: int = 1 const LOG_ERROR: int = 0
``` ```
Valid log levels Valid log levels

View File

@@ -2,7 +2,7 @@
# text\_dialog\_choice.gd # text\_dialog\_choice.gd
**Extends:** [Control](../Control) **Extends:** [ESCDialogOptionsChooser](../ESCDialogOptionsChooser) < [Node](../Node)
## Description ## Description
@@ -26,17 +26,17 @@ export var color_hover = "165,42,42,1"
export var font = "[Object:null]" export var font = "[Object:null]"
``` ```
### commands
```gdscript
var commands
```
## Method Descriptions ## Method Descriptions
### set\_answers ### show\_chooser
```gdscript ```gdscript
func set_answers(options: Array) func show_chooser()
```
### hide\_chooser
```gdscript
func hide_chooser()
``` ```

View File

@@ -394,17 +394,16 @@ Dialogs are specified by writing `?` with optional parameters, followed by a lis
The following parameters are available: The following parameters are available:
* type: (default value "default") the type of dialog menu to use. * avatar: the path to a scene displaying an avatar used in the UI. Defaults to no avatar. To only set the remaining options, set this field to "-"
* avatar: (default value "default") the avatar to use in the dialog ui.
* timeout: (default value 0) timeout to select an option. After the time has passed, the "timeout_option" will be selected automatically. If the value is 0, there's no timeout. * timeout: (default value 0) timeout to select an option. After the time has passed, the "timeout_option" will be selected automatically. If the value is 0, there's no timeout.
* timeout_option: (default value 0) option selected when timeout is reached. * timeout_option: (default value 0) index of option (starting from 1) selected when timeout is reached.
Example: Example:
``` ```
# character's "talk" event # character's "talk" event
:talk :talk
? type avatar timeout timeout_option ? avatar timeout timeout_option
- "I'd like to buy a map." [!player_has_map] - "I'd like to buy a map." [!player_has_map]
say player "I'd like to buy a map" say player "I'd like to buy a map"
say map_vendor "Do you know the secret code?" say map_vendor "Do you know the secret code?"

View File

@@ -0,0 +1,34 @@
[gd_scene load_steps=8 format=2]
[ext_resource path="res://game/characters/mark/png/mark_talk_right.png" type="Texture" id=1]
[sub_resource type="AtlasTexture" id=1]
atlas = ExtResource( 1 )
region = Rect2( 0, 0, 24, 70 )
[sub_resource type="AtlasTexture" id=2]
atlas = ExtResource( 1 )
region = Rect2( 24, 0, 24, 70 )
[sub_resource type="AtlasTexture" id=3]
atlas = ExtResource( 1 )
region = Rect2( 48, 0, 24, 70 )
[sub_resource type="AtlasTexture" id=4]
atlas = ExtResource( 1 )
region = Rect2( 72, 0, 24, 70 )
[sub_resource type="AtlasTexture" id=5]
atlas = ExtResource( 1 )
region = Rect2( 96, 0, 24, 70 )
[sub_resource type="SpriteFrames" id=6]
animations = [ {
"frames": [ SubResource( 1 ), SubResource( 2 ), SubResource( 3 ), SubResource( 4 ), SubResource( 5 ) ],
"loop": true,
"name": "default",
"speed": 5.0
} ]
[node name="AnimatedSprite" type="AnimatedSprite"]
frames = SubResource( 6 )

4
game/rooms/room06/esc/worker.esc Executable file → Normal file
View File

@@ -12,7 +12,7 @@ say player "I don't think he'd like that."
say worker "Yeah?" say worker "Yeah?"
set_global talked_once true set_global talked_once true
? option1 1000 option2 true ? res://game/characters/mark/mark_talk.tscn 5 1
- "What are you doing here?" - "What are you doing here?"
say player "What are you doing here?" say player "What are you doing here?"
say worker "I'm working! Can't you see that?" say worker "I'm working! Can't you see that?"
@@ -27,7 +27,7 @@ say player "I don't think he'd like that."
say player "I've got better things to do." say player "I've got better things to do."
say worker "Eh! I'm not asking you anythin'!" say worker "Eh! I'm not asking you anythin'!"
stop stop
! !
- "I'm selling these fine leather jackets." - "I'm selling these fine leather jackets."
say player "I'm selling these fine leather jackets." say player "I'm selling these fine leather jackets."
say worker "Go away, kid." say worker "Go away, kid."

View File

@@ -0,0 +1,67 @@
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
func _ready() -> void:
hide_chooser()
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
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)
func hide_chooser():
$MarginContainer.hide()
func _option_chosen(option: ESCDialogOption):
_remove_avatar()
$TimerProgress.value = 0
emit_signal("option_chosen", option)
func _on_answer_selected(option: ESCDialogOption):
_option_chosen(option)
func _on_Timer_timeout() -> void:
_option_chosen(self.dialog.options[self.dialog.timeout_option - 1])
func _remove_avatar():
if $AvatarContainer.get_child_count() > 0:
$AvatarContainer.remove_child($AvatarContainer.get_child(0))

View File

@@ -1,34 +1,64 @@
[gd_scene load_steps=3 format=2] [gd_scene load_steps=5 format=2]
[ext_resource path="res://addons/escoria-core/template_scenes/dialog_scenes/dialog_choosers/text_dialog_choice.gd" type="Script" id=1] [ext_resource path="res://addons/escoria-core/template_scenes/dialog_scenes/dialog_choosers/text_dialog_choice.gd" type="Script" id=1]
[ext_resource path="res://addons/escoria-core/game/assets/fonts/efmi/efmi_font.tres" type="DynamicFont" id=2] [ext_resource path="res://addons/escoria-core/game/assets/fonts/efmi/efmi_font.tres" type="DynamicFont" id=2]
[node name="text_dialog_choice" type="MarginContainer"] [sub_resource type="Gradient" id=1]
anchor_right = 1.0 colors = PoolColorArray( 1, 0, 0, 1, 1, 0, 0, 1 )
anchor_bottom = 1.0
custom_constants/margin_top = 20 [sub_resource type="GradientTexture" id=2]
custom_constants/margin_left = 20 gradient = SubResource( 1 )
[node name="text_dialog_choice" type="Node"]
script = ExtResource( 1 ) script = ExtResource( 1 )
__meta__ = {
"_edit_use_anchors_": false
}
color_hover = Color( 0.647059, 0.164706, 0.164706, 1 ) color_hover = Color( 0.647059, 0.164706, 0.164706, 1 )
font = ExtResource( 2 ) font = ExtResource( 2 )
[node name="ScrollContainer" type="ScrollContainer" parent="."] [node name="MarginContainer" type="MarginContainer" parent="."]
margin_left = 20.0 margin_left = 20.0
margin_top = 20.0 margin_top = 20.0
margin_right = 1280.0 margin_right = 1280.0
margin_bottom = 900.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 scroll_horizontal_enabled = false
__meta__ = { __meta__ = {
"_edit_use_anchors_": false "_edit_use_anchors_": false
} }
[node name="VBoxContainer" type="VBoxContainer" parent="ScrollContainer"] [node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/ScrollContainer"]
margin_right = 1260.0 margin_right = 1240.0
margin_bottom = 860.0
size_flags_horizontal = 3 size_flags_horizontal = 3
size_flags_vertical = 3
custom_constants/separation = 20 custom_constants/separation = 20
__meta__ = { __meta__ = {
"_edit_use_anchors_": false "_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"]

View File

@@ -169,6 +169,11 @@ _global_script_classes=[ {
"language": "GDScript", "language": "GDScript",
"path": "res://addons/escoria-core/game/core-scripts/esc/types/esc_dialog_option.gd" "path": "res://addons/escoria-core/game/core-scripts/esc/types/esc_dialog_option.gd"
}, { }, {
"base": "Node",
"class": "ESCDialogOptionsChooser",
"language": "GDScript",
"path": "res://addons/escoria-core/game/scenes/dialogs/esc_dialog_options_chooser.gd"
}, {
"base": "ResourcePreloader", "base": "ResourcePreloader",
"class": "ESCDialogsPlayer", "class": "ESCDialogsPlayer",
"language": "GDScript", "language": "GDScript",
@@ -512,6 +517,7 @@ _global_script_class_icons={
"ESCController": "", "ESCController": "",
"ESCDialog": "", "ESCDialog": "",
"ESCDialogOption": "", "ESCDialogOption": "",
"ESCDialogOptionsChooser": "",
"ESCDialogsPlayer": "", "ESCDialogsPlayer": "",
"ESCDirectionAngle": "", "ESCDirectionAngle": "",
"ESCEvent": "", "ESCEvent": "",
@@ -635,6 +641,7 @@ main/settings_path="user://"
main/escoria_version="" main/escoria_version=""
sound/speech_enabled=1 sound/speech_enabled=1
ui/game_scene="res://addons/escoria-ui-9verbs/game.tscn" ui/game_scene="res://addons/escoria-ui-9verbs/game.tscn"
ui/dialogs_chooser="res://game/ui/commons/dialogs/text_dialog_choice.tscn"
[input] [input]