Co-authored-by: Dennis Ploeger <develop@dieploegers.de> Co-authored-by: dploeger <dploeger@users.noreply.github.com>
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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.")
|
||||
@@ -26,14 +26,15 @@ 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_folder"):
|
||||
ProjectSettings.set_setting("escoria/ui/dialogs_folder", "")
|
||||
var dialogs_folder_property_info = {
|
||||
"name": "escoria/ui/dialogs_folder",
|
||||
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_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"):
|
||||
ProjectSettings.set_setting("escoria/ui/default_dialog_scene", "")
|
||||
|
||||
@@ -1,53 +1,67 @@
|
||||
tool
|
||||
extends Control
|
||||
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
|
||||
|
||||
var commands
|
||||
|
||||
func _ready():
|
||||
for c in $ScrollContainer/VBoxContainer.get_children():
|
||||
c.queue_free()
|
||||
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 set_answers(options : Array):
|
||||
commands = options
|
||||
for option in commands:
|
||||
var new_answer_label = RichTextLabel.new()
|
||||
new_answer_label.text = option.option
|
||||
new_answer_label.fit_content_height = true
|
||||
new_answer_label.add_font_override("normal_font", font)
|
||||
|
||||
$ScrollContainer/VBoxContainer.add_child(new_answer_label)
|
||||
new_answer_label.fit_content_height = true
|
||||
new_answer_label.connect("focus_entered", self, "_on_answer_focus_entered", [new_answer_label]) # Focus entered
|
||||
new_answer_label.connect("focus_exited", self, "_on_answer_focus_exited", [new_answer_label]) # Focus exited
|
||||
new_answer_label.connect("mouse_entered", self, "_on_answer_mouse_entered", [new_answer_label]) # Mouse entered
|
||||
new_answer_label.connect("mouse_exited", self, "_on_answer_mouse_exited", [new_answer_label]) # Mouse exited
|
||||
new_answer_label.connect("gui_input", self, "_on_answer_gui_input", [option]) # Clicks
|
||||
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 _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):
|
||||
var text = answer_node.text
|
||||
answer_node.clear()
|
||||
answer_node.push_color(color_hover.to_html(false))
|
||||
answer_node.append_bbcode(text)
|
||||
answer_node.pop()
|
||||
func hide_chooser():
|
||||
$MarginContainer.hide()
|
||||
|
||||
|
||||
func _on_answer_mouse_exited(answer_node : Node):
|
||||
var text = answer_node.text
|
||||
answer_node.clear()
|
||||
answer_node.push_color(color_normal.to_html(false))
|
||||
answer_node.append_bbcode(text)
|
||||
answer_node.pop()
|
||||
func _option_chosen(option: ESCDialogOption):
|
||||
_remove_avatar()
|
||||
$TimerProgress.value = 0
|
||||
emit_signal("option_chosen", option)
|
||||
|
||||
func _on_answer_focus_entered(answer_node : Node):
|
||||
pass
|
||||
|
||||
func _on_answer_focus_exited(answer_node : Node):
|
||||
pass
|
||||
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))
|
||||
|
||||
@@ -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/game/assets/fonts/efmi/efmi_font.tres" type="DynamicFont" id=2]
|
||||
|
||||
[node name="text_dialog_choice" type="MarginContainer"]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
custom_constants/margin_top = 20
|
||||
custom_constants/margin_left = 20
|
||||
[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 )
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
color_hover = Color( 0.647059, 0.164706, 0.164706, 1 )
|
||||
font = ExtResource( 2 )
|
||||
|
||||
[node name="ScrollContainer" type="ScrollContainer" parent="."]
|
||||
[node name="MarginContainer" type="MarginContainer" parent="."]
|
||||
margin_left = 20.0
|
||||
margin_top = 20.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
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="ScrollContainer"]
|
||||
margin_right = 1260.0
|
||||
margin_bottom = 780.0
|
||||
[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
|
||||
@@ -35,9 +46,19 @@ __meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="example" type="RichTextLabel" parent="ScrollContainer/VBoxContainer"]
|
||||
margin_right = 1260.0
|
||||
margin_bottom = 25.0
|
||||
custom_fonts/normal_font = ExtResource( 2 )
|
||||
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."
|
||||
fit_content_height = true
|
||||
[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"]
|
||||
|
||||
@@ -21,25 +21,17 @@ A Regex that matches the end of a dialog
|
||||
### REGEX
|
||||
|
||||
```gdscript
|
||||
const REGEX: String = "^(\\s*)\\?( (?<type>[^ ]+))?( (?<avatar>[^ ]+))?( (?<timeout>[^ ]+))?( (?<timeout_option>.+))?$"
|
||||
const REGEX: String = "^(\\s*)\\?( (?<avatar>[^ ]+))?( (?<timeout>[^ ]+))?( (?<timeout_option>.+))?$"
|
||||
```
|
||||
|
||||
Regex that matches dialog lines
|
||||
|
||||
## Property Descriptions
|
||||
|
||||
### type
|
||||
|
||||
```gdscript
|
||||
var type: String = ""
|
||||
```
|
||||
|
||||
Dialog type
|
||||
|
||||
### avatar
|
||||
|
||||
```gdscript
|
||||
var avatar: String = ""
|
||||
var avatar: String = "-"
|
||||
```
|
||||
|
||||
Avatar used in the dialog
|
||||
@@ -84,7 +76,7 @@ Construct a dialog from a dialog string
|
||||
func is_valid() -> bool
|
||||
```
|
||||
|
||||
Dialogs have no conditions, just return true
|
||||
Check if dialog is valid
|
||||
|
||||
### run
|
||||
|
||||
|
||||
57
docs/api/ESCDialogOptionsChooser.md
Normal file
57
docs/api/ESCDialogOptionsChooser.md
Normal 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
|
||||
@@ -20,18 +20,6 @@ Wether the player is currently speaking
|
||||
|
||||
## 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
|
||||
|
||||
```gdscript
|
||||
@@ -62,13 +50,21 @@ func start_dialog_choices(dialog: ESCDialog)
|
||||
|
||||
Display a list of choices
|
||||
|
||||
#### Parameters
|
||||
|
||||
- dialog: The dialog to start
|
||||
|
||||
### play\_dialog\_option\_chosen
|
||||
|
||||
```gdscript
|
||||
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
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ Logging framework for Escoria
|
||||
### LOG\_DEBUG
|
||||
|
||||
```gdscript
|
||||
const LOG_WARNING: int = 1
|
||||
const LOG_ERROR: int = 0
|
||||
```
|
||||
|
||||
Valid log levels
|
||||
@@ -21,7 +21,7 @@ Valid log levels
|
||||
### LOG\_ERROR
|
||||
|
||||
```gdscript
|
||||
const LOG_WARNING: int = 1
|
||||
const LOG_ERROR: int = 0
|
||||
```
|
||||
|
||||
Valid log levels
|
||||
@@ -29,7 +29,7 @@ Valid log levels
|
||||
### LOG\_INFO
|
||||
|
||||
```gdscript
|
||||
const LOG_WARNING: int = 1
|
||||
const LOG_ERROR: int = 0
|
||||
```
|
||||
|
||||
Valid log levels
|
||||
@@ -37,7 +37,7 @@ Valid log levels
|
||||
### LOG\_WARNING
|
||||
|
||||
```gdscript
|
||||
const LOG_WARNING: int = 1
|
||||
const LOG_ERROR: int = 0
|
||||
```
|
||||
|
||||
Valid log levels
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
# text\_dialog\_choice.gd
|
||||
|
||||
**Extends:** [Control](../Control)
|
||||
**Extends:** [ESCDialogOptionsChooser](../ESCDialogOptionsChooser) < [Node](../Node)
|
||||
|
||||
## Description
|
||||
|
||||
@@ -26,17 +26,17 @@ export var color_hover = "165,42,42,1"
|
||||
export var font = "[Object:null]"
|
||||
```
|
||||
|
||||
### commands
|
||||
|
||||
```gdscript
|
||||
var commands
|
||||
```
|
||||
|
||||
## Method Descriptions
|
||||
|
||||
### set\_answers
|
||||
### show\_chooser
|
||||
|
||||
```gdscript
|
||||
func set_answers(options: Array)
|
||||
func show_chooser()
|
||||
```
|
||||
|
||||
### hide\_chooser
|
||||
|
||||
```gdscript
|
||||
func hide_chooser()
|
||||
```
|
||||
|
||||
|
||||
@@ -394,17 +394,16 @@ Dialogs are specified by writing `?` with optional parameters, followed by a lis
|
||||
|
||||
The following parameters are available:
|
||||
|
||||
* type: (default value "default") the type of dialog menu to use.
|
||||
* avatar: (default value "default") the avatar to use in the dialog ui.
|
||||
* 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 "-"
|
||||
* 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:
|
||||
|
||||
```
|
||||
# character's "talk" event
|
||||
:talk
|
||||
? type avatar timeout timeout_option
|
||||
? avatar timeout timeout_option
|
||||
- "I'd like to buy a map." [!player_has_map]
|
||||
say player "I'd like to buy a map"
|
||||
say map_vendor "Do you know the secret code?"
|
||||
|
||||
34
game/characters/mark/mark_talk.tscn
Normal file
34
game/characters/mark/mark_talk.tscn
Normal 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
4
game/rooms/room06/esc/worker.esc
Executable file → Normal file
@@ -12,7 +12,7 @@ say player "I don't think he'd like that."
|
||||
say worker "Yeah?"
|
||||
set_global talked_once true
|
||||
|
||||
? option1 1000 option2 true
|
||||
? res://game/characters/mark/mark_talk.tscn 5 1
|
||||
- "What are you doing here?"
|
||||
say player "What are you doing here?"
|
||||
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 worker "Eh! I'm not asking you anythin'!"
|
||||
stop
|
||||
!
|
||||
!
|
||||
- "I'm selling these fine leather jackets."
|
||||
say player "I'm selling these fine leather jackets."
|
||||
say worker "Go away, kid."
|
||||
|
||||
Binary file not shown.
Binary file not shown.
67
game/ui/commons/dialogs/text_dialog_choice.gd
Normal file
67
game/ui/commons/dialogs/text_dialog_choice.gd
Normal 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))
|
||||
@@ -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/game/assets/fonts/efmi/efmi_font.tres" type="DynamicFont" id=2]
|
||||
|
||||
[node name="text_dialog_choice" type="MarginContainer"]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
custom_constants/margin_top = 20
|
||||
custom_constants/margin_left = 20
|
||||
[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 )
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
color_hover = Color( 0.647059, 0.164706, 0.164706, 1 )
|
||||
font = ExtResource( 2 )
|
||||
|
||||
[node name="ScrollContainer" type="ScrollContainer" parent="."]
|
||||
[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="ScrollContainer"]
|
||||
margin_right = 1260.0
|
||||
[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"]
|
||||
|
||||
@@ -169,6 +169,11 @@ _global_script_classes=[ {
|
||||
"language": "GDScript",
|
||||
"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",
|
||||
"class": "ESCDialogsPlayer",
|
||||
"language": "GDScript",
|
||||
@@ -512,6 +517,7 @@ _global_script_class_icons={
|
||||
"ESCController": "",
|
||||
"ESCDialog": "",
|
||||
"ESCDialogOption": "",
|
||||
"ESCDialogOptionsChooser": "",
|
||||
"ESCDialogsPlayer": "",
|
||||
"ESCDirectionAngle": "",
|
||||
"ESCEvent": "",
|
||||
@@ -635,6 +641,7 @@ main/settings_path="user://"
|
||||
main/escoria_version=""
|
||||
sound/speech_enabled=1
|
||||
ui/game_scene="res://addons/escoria-ui-9verbs/game.tscn"
|
||||
ui/dialogs_chooser="res://game/ui/commons/dialogs/text_dialog_choice.tscn"
|
||||
|
||||
[input]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user