custom dialog plugin styled
This commit is contained in:
@@ -0,0 +1,100 @@
|
|||||||
|
# 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)
|
||||||
|
|
||||||
|
|
||||||
|
var _no_more_options: bool = false
|
||||||
|
|
||||||
|
|
||||||
|
# Hide the chooser at the start just to be safe
|
||||||
|
func _ready() -> void:
|
||||||
|
hide_chooser()
|
||||||
|
pause_mode = PAUSE_MODE_STOP
|
||||||
|
|
||||||
|
|
||||||
|
# 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:
|
||||||
|
if option.is_valid():
|
||||||
|
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)
|
||||||
|
_vbox.add_child(_option_node)
|
||||||
|
_option_node.connect("pressed", self, "_on_answer_selected", [
|
||||||
|
option
|
||||||
|
])
|
||||||
|
|
||||||
|
# If we've no options left, signify as much and start the timer with a
|
||||||
|
# very short interval so the appropriate signal can be fired. Note that
|
||||||
|
# we have to fire the signal AFTER this method returns as the caller
|
||||||
|
# is almost certainly yielding after this method returns.
|
||||||
|
if _vbox.get_child_count() == 0:
|
||||||
|
_no_more_options = true
|
||||||
|
$Timer.start(0.05)
|
||||||
|
return
|
||||||
|
|
||||||
|
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:
|
||||||
|
var option_chosen = null if _no_more_options else self.dialog.options[self.dialog.timeout_option - 1]
|
||||||
|
_no_more_options = false
|
||||||
|
_option_chosen(option_chosen)
|
||||||
|
|
||||||
|
|
||||||
|
# Remove the avatar
|
||||||
|
func _remove_avatar():
|
||||||
|
if $AvatarContainer.get_child_count() > 0:
|
||||||
|
$AvatarContainer.remove_child($AvatarContainer.get_child(0))
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
[gd_scene load_steps=4 format=2]
|
||||||
|
|
||||||
|
[ext_resource path="res://addons/escoria-dialog-simple/chooser/simple.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="Control"]
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
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( 94, 68 )
|
||||||
|
|
||||||
|
[connection signal="timeout" from="Timer" to="." method="_on_Timer_timeout"]
|
||||||
@@ -0,0 +1,120 @@
|
|||||||
|
# A simple dialog manager for Escoria
|
||||||
|
extends ESCDialogManager
|
||||||
|
class_name ESCReturnToMonekyIslandDialogs
|
||||||
|
|
||||||
|
|
||||||
|
# The currently running player
|
||||||
|
var _type_player: Node = null
|
||||||
|
|
||||||
|
# Reference to the dialog player
|
||||||
|
var _dialog_player: Node = null
|
||||||
|
|
||||||
|
|
||||||
|
# Check whether a specific type is supported by the
|
||||||
|
# dialog plugin
|
||||||
|
#
|
||||||
|
# #### Parameters
|
||||||
|
# - type: required type
|
||||||
|
# *Returns* Whether the type is supported or not
|
||||||
|
func has_type(type: String) -> bool:
|
||||||
|
return true if type in ["floating", "avatar"] else false
|
||||||
|
|
||||||
|
|
||||||
|
# Check whether a specific chooser type is supported by the
|
||||||
|
# dialog plugin
|
||||||
|
#
|
||||||
|
# #### Parameters
|
||||||
|
# - type: required chooser type
|
||||||
|
# *Returns* Whether the type is supported or not
|
||||||
|
func has_chooser_type(type: String) -> bool:
|
||||||
|
return true if type == "simple" else 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):
|
||||||
|
_dialog_player = dialog_player
|
||||||
|
|
||||||
|
if type == "floating":
|
||||||
|
_type_player = preload(\
|
||||||
|
"res://gymkhana/addons/escoria-ui-return-monkey-island-dialog-simple/types/floating.tscn"\
|
||||||
|
).instance()
|
||||||
|
else:
|
||||||
|
_type_player = preload(\
|
||||||
|
"res://gymkhana/addons/escoria-ui-return-monkey-island-dialog-simple/types/avatar.tscn"\
|
||||||
|
).instance()
|
||||||
|
|
||||||
|
_type_player.connect("say_finished", self, "_on_say_finished", [], CONNECT_ONESHOT)
|
||||||
|
_type_player.connect("say_visible", self, "_on_say_visible", [], CONNECT_ONESHOT)
|
||||||
|
|
||||||
|
_dialog_player.add_child(_type_player)
|
||||||
|
_type_player.say(global_id, text)
|
||||||
|
# yield(_type_player, "say_finished")
|
||||||
|
# if _dialog_player.get_children().has(_type_player):
|
||||||
|
# _dialog_player.remove_child(_type_player)
|
||||||
|
# emit_signal("say_finished")
|
||||||
|
|
||||||
|
|
||||||
|
func _on_say_finished():
|
||||||
|
if _dialog_player.get_children().has(_type_player):
|
||||||
|
_dialog_player.remove_child(_type_player)
|
||||||
|
emit_signal("say_finished")
|
||||||
|
|
||||||
|
|
||||||
|
func _on_say_visible():
|
||||||
|
emit_signal("say_visible")
|
||||||
|
|
||||||
|
|
||||||
|
# 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):
|
||||||
|
var chooser = preload(\
|
||||||
|
"res://gymkhana/addons/escoria-ui-return-monkey-island-dialog-simple/chooser/simple.tscn"\
|
||||||
|
).instance()
|
||||||
|
dialog_player.add_child(chooser)
|
||||||
|
chooser.set_dialog(dialog)
|
||||||
|
chooser.show_chooser()
|
||||||
|
var option = yield(chooser, "option_chosen")
|
||||||
|
dialog_player.remove_child(chooser)
|
||||||
|
emit_signal("option_chosen", option)
|
||||||
|
|
||||||
|
|
||||||
|
# Trigger running the dialogue faster
|
||||||
|
func speedup():
|
||||||
|
if _type_player != null:
|
||||||
|
_type_player.speedup()
|
||||||
|
|
||||||
|
|
||||||
|
# Trigger an instant finish of the current dialog
|
||||||
|
func finish():
|
||||||
|
if _type_player != null:
|
||||||
|
_type_player.finish()
|
||||||
|
|
||||||
|
|
||||||
|
# The say command has been interrupted, cancel the dialog display
|
||||||
|
func interrupt():
|
||||||
|
if _dialog_player.get_children().has(_type_player):
|
||||||
|
(
|
||||||
|
escoria.object_manager.get_object(escoria.object_manager.SPEECH).node\
|
||||||
|
as ESCSpeechPlayer
|
||||||
|
).set_state("off")
|
||||||
|
|
||||||
|
_dialog_player.remove_child(_type_player)
|
||||||
|
emit_signal("say_finished")
|
||||||
|
|
||||||
|
|
||||||
|
# To be called if voice audio has finished.
|
||||||
|
func voice_audio_finished():
|
||||||
|
if _type_player != null:
|
||||||
|
_type_player.voice_audio_finished()
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
[plugin]
|
||||||
|
|
||||||
|
name="Escoria Return to Monkey Island UI Dialog Simple"
|
||||||
|
description="Return to Monkey Island like UI for the Escoria Framework (Dialogs)"
|
||||||
|
author="Arkitekt"
|
||||||
|
version="0.1.0"
|
||||||
|
script="plugin.gd"
|
||||||
@@ -0,0 +1,167 @@
|
|||||||
|
# A simple dialog manager for Escoria
|
||||||
|
tool
|
||||||
|
extends EditorPlugin
|
||||||
|
class_name SimpleDialogPlugin
|
||||||
|
|
||||||
|
|
||||||
|
const MANAGER_CLASS="res://gymkhana/addons/escoria-ui-return-monkey-island-dialog-simple/esc_dialog_simple.gd"
|
||||||
|
const SETTINGS_ROOT="escoria/dialog_simple"
|
||||||
|
|
||||||
|
const AVATARS_PATH = "%s/avatars_path" % SETTINGS_ROOT
|
||||||
|
const TEXT_TIME_PER_LETTER_MS = "%s/text_time_per_letter_ms" % SETTINGS_ROOT
|
||||||
|
const TEXT_TIME_PER_LETTER_MS_FAST = "%s/text_time_per_fast_letter_ms" % SETTINGS_ROOT
|
||||||
|
const READING_SPEED_IN_WPM = "%s/reading_speed_in_wpm" % SETTINGS_ROOT
|
||||||
|
const CLEAR_TEXT_BY_CLICK_ONLY = "%s/clear_text_by_click_only" % SETTINGS_ROOT
|
||||||
|
const LEFT_CLICK_ACTION = "%s/left_click_action" % SETTINGS_ROOT
|
||||||
|
const STOP_TALKING_ANIMATION_ON = "%s/stop_talking_animation_on" % SETTINGS_ROOT
|
||||||
|
|
||||||
|
const LEFT_CLICK_ACTION_SPEED_UP = "Speed up"
|
||||||
|
const LEFT_CLICK_ACTION_INSTANT_FINISH = "Instant finish"
|
||||||
|
const LEFT_CLICK_ACTION_NOTHING = "None"
|
||||||
|
|
||||||
|
const STOP_TALKING_ANIMATION_ON_END_OF_TEXT = "End of text"
|
||||||
|
const STOP_TALKING_ANIMATION_ON_END_OF_AUDIO = "End of audio"
|
||||||
|
|
||||||
|
const READING_SPEED_IN_WPM_DEFAULT_VALUE = 200
|
||||||
|
const TEXT_TIME_PER_LETTER_MS_DEFAULT_VALUE = 100
|
||||||
|
const TEXT_TIME_PER_LETTER_MS_FAST_DEFAULT_VALUE = 25
|
||||||
|
|
||||||
|
|
||||||
|
var left_click_actions: PoolStringArray = [
|
||||||
|
LEFT_CLICK_ACTION_SPEED_UP,
|
||||||
|
LEFT_CLICK_ACTION_INSTANT_FINISH,
|
||||||
|
LEFT_CLICK_ACTION_NOTHING
|
||||||
|
]
|
||||||
|
|
||||||
|
var stop_talking_animation_on_options: PoolStringArray = [
|
||||||
|
STOP_TALKING_ANIMATION_ON_END_OF_TEXT,
|
||||||
|
STOP_TALKING_ANIMATION_ON_END_OF_AUDIO
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
# Override function to return the plugin name.
|
||||||
|
func get_plugin_name():
|
||||||
|
return "escoria-dialog-simple"
|
||||||
|
|
||||||
|
|
||||||
|
# Unregister ourselves
|
||||||
|
func disable_plugin():
|
||||||
|
print("Disabling plugin Escoria Dialog Simple")
|
||||||
|
ESCProjectSettingsManager.remove_setting(
|
||||||
|
ESCProjectSettingsManager.DEFAULT_DIALOG_TYPE
|
||||||
|
)
|
||||||
|
|
||||||
|
ESCProjectSettingsManager.remove_setting(
|
||||||
|
AVATARS_PATH
|
||||||
|
)
|
||||||
|
|
||||||
|
ESCProjectSettingsManager.remove_setting(
|
||||||
|
TEXT_TIME_PER_LETTER_MS
|
||||||
|
)
|
||||||
|
|
||||||
|
ESCProjectSettingsManager.remove_setting(
|
||||||
|
TEXT_TIME_PER_LETTER_MS_FAST
|
||||||
|
)
|
||||||
|
|
||||||
|
ESCProjectSettingsManager.remove_setting(
|
||||||
|
CLEAR_TEXT_BY_CLICK_ONLY
|
||||||
|
)
|
||||||
|
|
||||||
|
ESCProjectSettingsManager.remove_setting(
|
||||||
|
READING_SPEED_IN_WPM
|
||||||
|
)
|
||||||
|
|
||||||
|
ESCProjectSettingsManager.remove_setting(
|
||||||
|
LEFT_CLICK_ACTION
|
||||||
|
)
|
||||||
|
|
||||||
|
ESCProjectSettingsManager.remove_setting(
|
||||||
|
STOP_TALKING_ANIMATION_ON
|
||||||
|
)
|
||||||
|
|
||||||
|
EscoriaPlugin.deregister_dialog_manager(MANAGER_CLASS)
|
||||||
|
|
||||||
|
|
||||||
|
# Add ourselves to the list of dialog managers
|
||||||
|
func enable_plugin():
|
||||||
|
print("Enabling plugin Escoria Dialog Simple")
|
||||||
|
|
||||||
|
if EscoriaPlugin.register_dialog_manager(self, MANAGER_CLASS):
|
||||||
|
ESCProjectSettingsManager.register_setting(
|
||||||
|
ESCProjectSettingsManager.DEFAULT_DIALOG_TYPE,
|
||||||
|
"floating",
|
||||||
|
{
|
||||||
|
"type": TYPE_STRING
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
ESCProjectSettingsManager.register_setting(
|
||||||
|
AVATARS_PATH,
|
||||||
|
"res://game/dialog_avatars",
|
||||||
|
{
|
||||||
|
"type": TYPE_STRING,
|
||||||
|
"hint": PROPERTY_HINT_DIR
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
ESCProjectSettingsManager.register_setting(
|
||||||
|
TEXT_TIME_PER_LETTER_MS,
|
||||||
|
TEXT_TIME_PER_LETTER_MS_DEFAULT_VALUE,
|
||||||
|
{
|
||||||
|
"type": TYPE_REAL
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
ESCProjectSettingsManager.register_setting(
|
||||||
|
TEXT_TIME_PER_LETTER_MS_FAST,
|
||||||
|
TEXT_TIME_PER_LETTER_MS_FAST_DEFAULT_VALUE,
|
||||||
|
{
|
||||||
|
"type": TYPE_REAL
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
ESCProjectSettingsManager.register_setting(
|
||||||
|
CLEAR_TEXT_BY_CLICK_ONLY,
|
||||||
|
false,
|
||||||
|
{
|
||||||
|
"type": TYPE_BOOL
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
ESCProjectSettingsManager.register_setting(
|
||||||
|
READING_SPEED_IN_WPM,
|
||||||
|
READING_SPEED_IN_WPM_DEFAULT_VALUE,
|
||||||
|
{
|
||||||
|
"type": TYPE_INT
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
var left_click_actions_string: String = left_click_actions.join(",")
|
||||||
|
|
||||||
|
ESCProjectSettingsManager.register_setting(
|
||||||
|
LEFT_CLICK_ACTION,
|
||||||
|
LEFT_CLICK_ACTION_SPEED_UP,
|
||||||
|
{
|
||||||
|
"type": TYPE_STRING,
|
||||||
|
"hint": PROPERTY_HINT_ENUM,
|
||||||
|
"hint_string": left_click_actions_string
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
var stop_talking_animation_on_options_string: String = stop_talking_animation_on_options.join(",")
|
||||||
|
|
||||||
|
ESCProjectSettingsManager.register_setting(
|
||||||
|
STOP_TALKING_ANIMATION_ON,
|
||||||
|
STOP_TALKING_ANIMATION_ON_END_OF_AUDIO,
|
||||||
|
{
|
||||||
|
"type": TYPE_STRING,
|
||||||
|
"hint": PROPERTY_HINT_ENUM,
|
||||||
|
"hint_string": stop_talking_animation_on_options_string
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
else:
|
||||||
|
get_editor_interface().set_plugin_enabled(
|
||||||
|
get_plugin_name(),
|
||||||
|
false
|
||||||
|
)
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
[gd_resource type="Theme" load_steps=3 format=2]
|
||||||
|
|
||||||
|
[ext_resource path="res://gymkhana/addons/escoria-ui-return-monkey-island/fonts/caslonantique.tres" type="DynamicFont" id=1]
|
||||||
|
|
||||||
|
[sub_resource type="StyleBoxFlat" id=1]
|
||||||
|
content_margin_left = 5.0
|
||||||
|
content_margin_right = 5.0
|
||||||
|
content_margin_top = 5.0
|
||||||
|
content_margin_bottom = 5.0
|
||||||
|
bg_color = Color( 0, 0, 0, 0.25098 )
|
||||||
|
corner_radius_top_left = 8
|
||||||
|
corner_radius_top_right = 8
|
||||||
|
corner_radius_bottom_right = 8
|
||||||
|
corner_radius_bottom_left = 8
|
||||||
|
|
||||||
|
[resource]
|
||||||
|
default_font = ExtResource( 1 )
|
||||||
|
RichTextLabel/styles/normal = SubResource( 1 )
|
||||||
@@ -0,0 +1,229 @@
|
|||||||
|
# A dialog GUI showing a dialog box and character portraits
|
||||||
|
extends Popup
|
||||||
|
|
||||||
|
|
||||||
|
# Signal emitted when text has been said
|
||||||
|
signal say_finished
|
||||||
|
|
||||||
|
# Signal emitted when text has just become fully visible
|
||||||
|
signal say_visible
|
||||||
|
|
||||||
|
|
||||||
|
# The text speed per character for normal display
|
||||||
|
var _text_time_per_character: float
|
||||||
|
|
||||||
|
# The text speed per character if the dialog line is skipped
|
||||||
|
var _fast_text_time_per_character: float
|
||||||
|
|
||||||
|
# The reading speed to be used in determining the length of time text remains
|
||||||
|
# on the screen.
|
||||||
|
var _reading_speed_in_wpm: int
|
||||||
|
|
||||||
|
# Used to extract words from lines of text.
|
||||||
|
var _word_regex: RegEx = RegEx.new()
|
||||||
|
|
||||||
|
# Whether the current dialog is speeding up
|
||||||
|
var _is_speeding_up: bool = false
|
||||||
|
|
||||||
|
# The current line of text being displayed.
|
||||||
|
var _current_line: String
|
||||||
|
|
||||||
|
|
||||||
|
# The node holding the avatar
|
||||||
|
onready var avatar_node = $Panel/MarginContainer/HSplitContainer/VBoxContainer\
|
||||||
|
/avatar
|
||||||
|
|
||||||
|
# The node showing the text
|
||||||
|
onready var text_node = $Panel/MarginContainer/HSplitContainer/text
|
||||||
|
|
||||||
|
# The tween node for text animations
|
||||||
|
onready var tween = $Panel/MarginContainer/HSplitContainer/text/Tween
|
||||||
|
|
||||||
|
# Whether the dialog manager is paused
|
||||||
|
onready var is_paused: bool = true
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Build up the UI
|
||||||
|
func _ready():
|
||||||
|
_text_time_per_character = ProjectSettings.get_setting(
|
||||||
|
SimpleDialogPlugin.TEXT_TIME_PER_LETTER_MS
|
||||||
|
)
|
||||||
|
|
||||||
|
if _text_time_per_character < 0:
|
||||||
|
escoria.logger.warn(
|
||||||
|
self,
|
||||||
|
"%s setting must be a non-negative number. Will use default value of %s." %
|
||||||
|
[
|
||||||
|
SimpleDialogPlugin.TEXT_TIME_PER_LETTER_MS,
|
||||||
|
SimpleDialogPlugin.TEXT_TIME_PER_LETTER_MS_DEFAULT_VALUE
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
_text_time_per_character = SimpleDialogPlugin.TEXT_TIME_PER_LETTER_MS_DEFAULT_VALUE
|
||||||
|
|
||||||
|
_fast_text_time_per_character = ProjectSettings.get_setting(
|
||||||
|
SimpleDialogPlugin.TEXT_TIME_PER_LETTER_MS_FAST
|
||||||
|
)
|
||||||
|
|
||||||
|
if _fast_text_time_per_character < 0:
|
||||||
|
escoria.logger.warn(
|
||||||
|
self,
|
||||||
|
"%s setting must be a non-negative number. Will use default value of %s." %
|
||||||
|
[
|
||||||
|
SimpleDialogPlugin.TEXT_TIME_PER_LETTER_MS_FAST,
|
||||||
|
SimpleDialogPlugin.TEXT_TIME_PER_LETTER_MS_FAST_DEFAULT_VALUE
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
_fast_text_time_per_character = SimpleDialogPlugin.TEXT_TIME_PER_LETTER_MS_FAST_DEFAULT_VALUE
|
||||||
|
|
||||||
|
_reading_speed_in_wpm = ProjectSettings.get_setting(
|
||||||
|
SimpleDialogPlugin.READING_SPEED_IN_WPM
|
||||||
|
)
|
||||||
|
|
||||||
|
if _reading_speed_in_wpm <= 0:
|
||||||
|
escoria.logger.warn(
|
||||||
|
self,
|
||||||
|
"%s setting must be a positive number. Will use default value of %s." %
|
||||||
|
[
|
||||||
|
SimpleDialogPlugin.READING_SPEED_IN_WPM,
|
||||||
|
SimpleDialogPlugin.READING_SPEED_IN_WPM_DEFAULT_VALUE
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
_reading_speed_in_wpm = SimpleDialogPlugin.READING_SPEED_IN_WPM_DEFAULT_VALUE
|
||||||
|
|
||||||
|
_word_regex.compile("\\S+")
|
||||||
|
|
||||||
|
text_node.bbcode_enabled = true
|
||||||
|
tween.connect(
|
||||||
|
"tween_completed",
|
||||||
|
self,
|
||||||
|
"_on_dialog_line_typed"
|
||||||
|
)
|
||||||
|
|
||||||
|
escoria.connect("paused", self, "_on_paused")
|
||||||
|
escoria.connect("resumed", self, "_on_resumed")
|
||||||
|
|
||||||
|
|
||||||
|
# Switch the current character
|
||||||
|
#
|
||||||
|
# #### Parameters
|
||||||
|
# - name: The name of the current character
|
||||||
|
func set_current_character(name: String):
|
||||||
|
if ProjectSettings.get_setting("escoria/dialog_simple/avatars_path").empty():
|
||||||
|
escoria.logger.warn(self, "Unable to load avatar '%s': Avatar path not specified" % name)
|
||||||
|
return
|
||||||
|
|
||||||
|
var avatar = "%s/%s.tres" % [
|
||||||
|
ProjectSettings.get_setting("escoria/dialog_simple/avatars_path"),
|
||||||
|
name
|
||||||
|
]
|
||||||
|
if ResourceLoader.exists(avatar):
|
||||||
|
avatar_node.texture = ResourceLoader.load(avatar)
|
||||||
|
|
||||||
|
if avatar_node.texture is AnimatedTexture:
|
||||||
|
avatar_node.texture.current_frame = 0
|
||||||
|
avatar_node.texture.pause = false
|
||||||
|
else:
|
||||||
|
escoria.logger.warn(self, "Unable to load avatar '%s': Resource not found in path '%s'" %
|
||||||
|
[name, ProjectSettings.get_setting("escoria/dialog_simple/avatars_path")])
|
||||||
|
|
||||||
|
|
||||||
|
# Make a character say something
|
||||||
|
#
|
||||||
|
# #### Parameters
|
||||||
|
# - character: The global id of the character speaking
|
||||||
|
# - line: Line to say
|
||||||
|
func say(character: String, line: String):
|
||||||
|
_current_line = line
|
||||||
|
|
||||||
|
_is_speeding_up = false
|
||||||
|
popup_centered()
|
||||||
|
set_current_character(character)
|
||||||
|
|
||||||
|
text_node.bbcode_text = tr(line)
|
||||||
|
|
||||||
|
text_node.percent_visible = 0.0
|
||||||
|
var time_show_full_text = _text_time_per_character / 1000 * 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 speedup():
|
||||||
|
if not _is_speeding_up:
|
||||||
|
_is_speeding_up = true
|
||||||
|
var time_show_full_text = _fast_text_time_per_character / 1000 * len(_current_line)
|
||||||
|
tween.remove_all()
|
||||||
|
tween.interpolate_property(text_node, "percent_visible",
|
||||||
|
text_node.percent_visible, 1.0, time_show_full_text,
|
||||||
|
Tween.TRANS_LINEAR, Tween.EASE_IN_OUT)
|
||||||
|
tween.start()
|
||||||
|
|
||||||
|
|
||||||
|
# Called by the dialog player when user wants to finish dialogue immediately.
|
||||||
|
func finish():
|
||||||
|
tween.remove_all()
|
||||||
|
tween.interpolate_property(text_node, "percent_visible",
|
||||||
|
text_node.percent_visible, 1.0, 0.0)
|
||||||
|
tween.start()
|
||||||
|
|
||||||
|
|
||||||
|
# To be called if voice audio has finished.
|
||||||
|
func voice_audio_finished():
|
||||||
|
if avatar_node and avatar_node.texture:
|
||||||
|
avatar_node.texture.current_frame = 0
|
||||||
|
avatar_node.texture.pause = true
|
||||||
|
|
||||||
|
|
||||||
|
# The dialog line was printed, start the waiting time and then finish
|
||||||
|
# the dialog
|
||||||
|
func _on_dialog_line_typed(object, key):
|
||||||
|
if avatar_node.texture is AnimatedTexture:
|
||||||
|
avatar_node.texture.current_frame = 0
|
||||||
|
avatar_node.texture.pause = true
|
||||||
|
|
||||||
|
text_node.visible_characters = -1
|
||||||
|
|
||||||
|
var time_to_disappear: float = _calculate_time_to_disappear()
|
||||||
|
$Timer.start(time_to_disappear)
|
||||||
|
$Timer.connect("timeout", self, "_on_dialog_finished")
|
||||||
|
|
||||||
|
emit_signal("say_visible")
|
||||||
|
|
||||||
|
|
||||||
|
func _calculate_time_to_disappear() -> float:
|
||||||
|
return (_get_number_of_words() / _reading_speed_in_wpm as float) * 60
|
||||||
|
|
||||||
|
|
||||||
|
func _get_number_of_words() -> int:
|
||||||
|
return _word_regex.search_all(text_node.get_text()).size()
|
||||||
|
|
||||||
|
|
||||||
|
# Ending the dialog
|
||||||
|
func _on_dialog_finished():
|
||||||
|
# Only trigger to clear the text if we aren't limiting the clearing trigger to a click.
|
||||||
|
if not ESCProjectSettingsManager.get_setting(SimpleDialogPlugin.CLEAR_TEXT_BY_CLICK_ONLY):
|
||||||
|
emit_signal("say_finished")
|
||||||
|
queue_free()
|
||||||
|
|
||||||
|
|
||||||
|
# Handler managing pause notification from Escoria
|
||||||
|
func _on_paused():
|
||||||
|
if tween.is_active():
|
||||||
|
is_paused = true
|
||||||
|
tween.stop_all()
|
||||||
|
|
||||||
|
|
||||||
|
# Handler managing resume notification from Escoria
|
||||||
|
func _on_resumed():
|
||||||
|
if not tween.is_active():
|
||||||
|
is_paused = false
|
||||||
|
tween.resume_all()
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
[gd_scene load_steps=2 format=2]
|
||||||
|
|
||||||
|
[ext_resource path="res://addons/escoria-dialog-simple/types/avatar.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="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"]
|
||||||
@@ -0,0 +1,256 @@
|
|||||||
|
# A dialog UI using a label above the head of the character
|
||||||
|
extends RichTextLabel
|
||||||
|
|
||||||
|
|
||||||
|
# Signal emitted when text has been said
|
||||||
|
signal say_finished
|
||||||
|
|
||||||
|
# Signal emitted when text has just become fully visible
|
||||||
|
signal say_visible
|
||||||
|
|
||||||
|
|
||||||
|
# The text speed per character for normal display
|
||||||
|
var _text_time_per_character: float
|
||||||
|
|
||||||
|
# The text speed per character if the dialog line is skipped
|
||||||
|
var _fast_text_time_per_character: float
|
||||||
|
|
||||||
|
# The reading speed to be used in determining the length of time text remains
|
||||||
|
# on the screen.
|
||||||
|
var _reading_speed_in_wpm: int
|
||||||
|
|
||||||
|
# Used to extract words from lines of text.
|
||||||
|
var _word_regex: RegEx = RegEx.new()
|
||||||
|
|
||||||
|
|
||||||
|
# Current character speaking, to keep track of reference for animation purposes
|
||||||
|
var _current_character
|
||||||
|
|
||||||
|
# Whether the current dialog is speeding up
|
||||||
|
var _is_speeding_up: bool = false
|
||||||
|
|
||||||
|
# The current line of text being displayed.
|
||||||
|
var _current_line: String
|
||||||
|
|
||||||
|
|
||||||
|
# Tween node for text animation
|
||||||
|
onready var tween: Tween = $Tween
|
||||||
|
|
||||||
|
# The node showing the text
|
||||||
|
onready var text_node: RichTextLabel = self
|
||||||
|
|
||||||
|
# Whether the dialog manager is paused
|
||||||
|
onready var is_paused: bool = true
|
||||||
|
|
||||||
|
|
||||||
|
# Enable bbcode and catch the signal when a tween completed
|
||||||
|
func _ready():
|
||||||
|
_text_time_per_character = ProjectSettings.get_setting(
|
||||||
|
SimpleDialogPlugin.TEXT_TIME_PER_LETTER_MS
|
||||||
|
)
|
||||||
|
|
||||||
|
if _text_time_per_character < 0:
|
||||||
|
escoria.logger.warn(
|
||||||
|
self,
|
||||||
|
"%s setting must be a non-negative number. Will use default value of %s." %
|
||||||
|
[
|
||||||
|
SimpleDialogPlugin.TEXT_TIME_PER_LETTER_MS,
|
||||||
|
SimpleDialogPlugin.TEXT_TIME_PER_LETTER_MS_DEFAULT_VALUE
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
_text_time_per_character = SimpleDialogPlugin.TEXT_TIME_PER_LETTER_MS_DEFAULT_VALUE
|
||||||
|
|
||||||
|
_fast_text_time_per_character = ProjectSettings.get_setting(
|
||||||
|
SimpleDialogPlugin.TEXT_TIME_PER_LETTER_MS_FAST
|
||||||
|
)
|
||||||
|
|
||||||
|
if _fast_text_time_per_character < 0:
|
||||||
|
escoria.logger.warn(
|
||||||
|
self,
|
||||||
|
"%s setting must be a non-negative number. Will use default value of %s." %
|
||||||
|
[
|
||||||
|
SimpleDialogPlugin.TEXT_TIME_PER_LETTER_MS_FAST,
|
||||||
|
SimpleDialogPlugin.TEXT_TIME_PER_LETTER_MS_FAST_DEFAULT_VALUE
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
_fast_text_time_per_character = SimpleDialogPlugin.TEXT_TIME_PER_LETTER_MS_FAST_DEFAULT_VALUE
|
||||||
|
|
||||||
|
_reading_speed_in_wpm = ProjectSettings.get_setting(
|
||||||
|
SimpleDialogPlugin.READING_SPEED_IN_WPM
|
||||||
|
)
|
||||||
|
|
||||||
|
if _reading_speed_in_wpm <= 0:
|
||||||
|
escoria.logger.warn(
|
||||||
|
self,
|
||||||
|
"%s setting must be a positive number. Will use default value of %s." %
|
||||||
|
[
|
||||||
|
SimpleDialogPlugin.READING_SPEED_IN_WPM,
|
||||||
|
SimpleDialogPlugin.READING_SPEED_IN_WPM_DEFAULT_VALUE
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
_reading_speed_in_wpm = SimpleDialogPlugin.READING_SPEED_IN_WPM_DEFAULT_VALUE
|
||||||
|
|
||||||
|
_word_regex.compile("\\S+")
|
||||||
|
|
||||||
|
bbcode_enabled = true
|
||||||
|
$Tween.connect("tween_completed", self, "_on_dialog_line_typed")
|
||||||
|
|
||||||
|
connect("tree_exiting", self, "_on_tree_exiting")
|
||||||
|
|
||||||
|
escoria.connect("paused", self, "_on_paused")
|
||||||
|
escoria.connect("resumed", self, "_on_resumed")
|
||||||
|
|
||||||
|
_current_line = ""
|
||||||
|
|
||||||
|
|
||||||
|
func _process(delta):
|
||||||
|
if _current_character.is_inside_tree() and \
|
||||||
|
_current_character.has_node("dialog_position"):
|
||||||
|
# Position the RichTextLabel on the character's dialog position, if any.
|
||||||
|
rect_position = _current_character.get_node("dialog_position") \
|
||||||
|
.get_global_transform_with_canvas().origin
|
||||||
|
rect_position.x -= rect_size.x / 2
|
||||||
|
|
||||||
|
if rect_position.x < 0:
|
||||||
|
rect_position.x = 0
|
||||||
|
|
||||||
|
var screen_margin = rect_position.x + rect_size.x - \
|
||||||
|
ProjectSettings.get("display/window/size/width")
|
||||||
|
|
||||||
|
if screen_margin > 0:
|
||||||
|
rect_position.x -= screen_margin
|
||||||
|
|
||||||
|
|
||||||
|
# Make a character say something
|
||||||
|
#
|
||||||
|
# #### Parameters
|
||||||
|
# - character: The global id of the character speaking
|
||||||
|
# - line: Line to say
|
||||||
|
func say(character: String, line: String) :
|
||||||
|
_current_line = line
|
||||||
|
|
||||||
|
show()
|
||||||
|
|
||||||
|
_is_speeding_up = false
|
||||||
|
|
||||||
|
# Position the RichTextLabel on the character's dialog position, if any.
|
||||||
|
_current_character = escoria.object_manager.get_object(character).node
|
||||||
|
|
||||||
|
# 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]"
|
||||||
|
|
||||||
|
if _current_character.is_inside_tree() and \
|
||||||
|
_current_character.has_node("dialog_position"):
|
||||||
|
rect_position = _current_character.get_node(
|
||||||
|
"dialog_position"
|
||||||
|
).get_global_transform_with_canvas().origin
|
||||||
|
rect_position.x -= rect_size.x / 2
|
||||||
|
else:
|
||||||
|
rect_position.x = 0
|
||||||
|
rect_size.x = ProjectSettings.get_setting("display/window/size/width")
|
||||||
|
|
||||||
|
if rect_position.x < 0:
|
||||||
|
rect_position.x = 0
|
||||||
|
|
||||||
|
var screen_margin = rect_position.x + rect_size.x - \
|
||||||
|
ProjectSettings.get("display/window/size/width")
|
||||||
|
|
||||||
|
if screen_margin > 0:
|
||||||
|
rect_position.x -= screen_margin
|
||||||
|
|
||||||
|
_current_character.start_talking()
|
||||||
|
|
||||||
|
text_node.percent_visible = 0.0
|
||||||
|
var time_show_full_text = _text_time_per_character / 1000 * len(_current_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()
|
||||||
|
set_process(true)
|
||||||
|
|
||||||
|
|
||||||
|
# Called by the dialog player when user wants to finish dialogue fast.
|
||||||
|
func speedup():
|
||||||
|
if not _is_speeding_up:
|
||||||
|
_is_speeding_up = true
|
||||||
|
var time_show_full_text = _fast_text_time_per_character / 1000 * len(_current_line)
|
||||||
|
|
||||||
|
tween.remove_all()
|
||||||
|
tween.interpolate_property(text_node, "percent_visible",
|
||||||
|
text_node.percent_visible, 1.0, time_show_full_text,
|
||||||
|
Tween.TRANS_LINEAR, Tween.EASE_IN_OUT)
|
||||||
|
tween.start()
|
||||||
|
|
||||||
|
|
||||||
|
# Called by the dialog player when user wants to finish dialogue immediately.
|
||||||
|
func finish():
|
||||||
|
tween.remove_all()
|
||||||
|
tween.interpolate_property(text_node, "percent_visible",
|
||||||
|
text_node.percent_visible, 1.0, 0.0)
|
||||||
|
tween.start()
|
||||||
|
|
||||||
|
|
||||||
|
# To be called if voice audio has finished.
|
||||||
|
func voice_audio_finished():
|
||||||
|
_stop_character_talking()
|
||||||
|
|
||||||
|
|
||||||
|
# The dialog line was printed, start the waiting time and then finish
|
||||||
|
# the dialog
|
||||||
|
func _on_dialog_line_typed(object, key):
|
||||||
|
_stop_character_talking()
|
||||||
|
text_node.visible_characters = -1
|
||||||
|
|
||||||
|
var time_to_disappear: float = _calculate_time_to_disappear()
|
||||||
|
$Timer.start(time_to_disappear)
|
||||||
|
$Timer.connect("timeout", self, "_on_dialog_finished")
|
||||||
|
|
||||||
|
emit_signal("say_visible")
|
||||||
|
|
||||||
|
|
||||||
|
func _calculate_time_to_disappear() -> float:
|
||||||
|
return (_get_number_of_words() / _reading_speed_in_wpm as float) * 60
|
||||||
|
|
||||||
|
|
||||||
|
func _get_number_of_words() -> int:
|
||||||
|
return _word_regex.search_all(text_node.get_text()).size()
|
||||||
|
|
||||||
|
|
||||||
|
# Ending the dialog
|
||||||
|
func _on_dialog_finished():
|
||||||
|
# Only trigger to clear the text if we aren't limiting the clearing trigger to a click.
|
||||||
|
if not ESCProjectSettingsManager.get_setting(SimpleDialogPlugin.CLEAR_TEXT_BY_CLICK_ONLY):
|
||||||
|
emit_signal("say_finished")
|
||||||
|
|
||||||
|
|
||||||
|
# Handler managing pause notification from Escoria
|
||||||
|
func _on_paused():
|
||||||
|
if tween.is_active():
|
||||||
|
is_paused = true
|
||||||
|
tween.stop_all()
|
||||||
|
|
||||||
|
|
||||||
|
# Handler managing resume notification from Escoria
|
||||||
|
func _on_resumed():
|
||||||
|
if not tween.is_active():
|
||||||
|
is_paused = false
|
||||||
|
tween.resume_all()
|
||||||
|
|
||||||
|
|
||||||
|
# Handler to deal with this node being removed
|
||||||
|
func _on_tree_exiting() -> void:
|
||||||
|
_stop_character_talking()
|
||||||
|
|
||||||
|
|
||||||
|
func _stop_character_talking():
|
||||||
|
# Make the speaking item animation stop talking, if it is still alive
|
||||||
|
if is_instance_valid(_current_character) and _current_character != null:
|
||||||
|
_current_character.stop_talking()
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
[gd_scene load_steps=3 format=2]
|
||||||
|
|
||||||
|
[ext_resource path="res://addons/escoria-dialog-simple/types/floating.gd" type="Script" id=1]
|
||||||
|
[ext_resource path="res://gymkhana/addons/escoria-ui-return-monkey-island-dialog-simple/theme.tres" type="Theme" id=2]
|
||||||
|
|
||||||
|
[node name="dialog_label" type="RichTextLabel"]
|
||||||
|
margin_right = 672.0
|
||||||
|
margin_bottom = 97.0
|
||||||
|
theme = ExtResource( 2 )
|
||||||
|
bbcode_enabled = true
|
||||||
|
bbcode_text = "[center]Here be some text.[/center]"
|
||||||
|
text = "Here be some text."
|
||||||
|
fit_content_height = true
|
||||||
|
script = ExtResource( 1 )
|
||||||
|
|
||||||
|
[node name="Tween" type="Tween" parent="."]
|
||||||
|
|
||||||
|
[node name="Timer" type="Timer" parent="."]
|
||||||
@@ -384,6 +384,11 @@ _global_script_classes=[ {
|
|||||||
"language": "GDScript",
|
"language": "GDScript",
|
||||||
"path": "res://addons/escoria-core/game/core-scripts/resources/esc_resource_descriptor.gd"
|
"path": "res://addons/escoria-core/game/core-scripts/resources/esc_resource_descriptor.gd"
|
||||||
}, {
|
}, {
|
||||||
|
"base": "ESCDialogManager",
|
||||||
|
"class": "ESCReturnToMonekyIslandDialogs",
|
||||||
|
"language": "GDScript",
|
||||||
|
"path": "res://gymkhana/addons/escoria-ui-return-monkey-island-dialog-simple/esc_dialog_simple.gd"
|
||||||
|
}, {
|
||||||
"base": "Node2D",
|
"base": "Node2D",
|
||||||
"class": "ESCRoom",
|
"class": "ESCRoom",
|
||||||
"language": "GDScript",
|
"language": "GDScript",
|
||||||
@@ -607,7 +612,7 @@ _global_script_classes=[ {
|
|||||||
"base": "EditorPlugin",
|
"base": "EditorPlugin",
|
||||||
"class": "SimpleDialogPlugin",
|
"class": "SimpleDialogPlugin",
|
||||||
"language": "GDScript",
|
"language": "GDScript",
|
||||||
"path": "res://addons/escoria-dialog-simple/plugin.gd"
|
"path": "res://gymkhana/addons/escoria-ui-return-monkey-island-dialog-simple/plugin.gd"
|
||||||
}, {
|
}, {
|
||||||
"base": "SlideCommand",
|
"base": "SlideCommand",
|
||||||
"class": "SlideBlockCommand",
|
"class": "SlideBlockCommand",
|
||||||
@@ -765,6 +770,7 @@ _global_script_class_icons={
|
|||||||
"ESCProjectSettingsManager": "",
|
"ESCProjectSettingsManager": "",
|
||||||
"ESCResourceCache": "",
|
"ESCResourceCache": "",
|
||||||
"ESCResourceDescriptor": "",
|
"ESCResourceDescriptor": "",
|
||||||
|
"ESCReturnToMonekyIslandDialogs": "",
|
||||||
"ESCRoom": "res://addons/escoria-core/design/esc_room.svg",
|
"ESCRoom": "res://addons/escoria-core/design/esc_room.svg",
|
||||||
"ESCRoomManager": "",
|
"ESCRoomManager": "",
|
||||||
"ESCRoomObjects": "",
|
"ESCRoomObjects": "",
|
||||||
@@ -888,7 +894,7 @@ ui/inventory_items_path="res://gymkhana/items/inventory"
|
|||||||
ui/default_transition="instant"
|
ui/default_transition="instant"
|
||||||
ui/transition_paths=[ "res://addons/escoria-core/game/scenes/transitions/shaders/" ]
|
ui/transition_paths=[ "res://addons/escoria-core/game/scenes/transitions/shaders/" ]
|
||||||
ui/inventory_item_size=Vector2( 72, 72 )
|
ui/inventory_item_size=Vector2( 72, 72 )
|
||||||
ui/dialog_managers=[ "res://addons/escoria-dialog-simple/esc_dialog_simple.gd" ]
|
ui/dialog_managers=[ "res://gymkhana/addons/escoria-ui-return-monkey-island-dialog-simple/esc_dialog_simple.gd" ]
|
||||||
sound/master_volume=1
|
sound/master_volume=1
|
||||||
sound/music_volume=1
|
sound/music_volume=1
|
||||||
sound/sfx_volume=1
|
sound/sfx_volume=1
|
||||||
@@ -900,7 +906,7 @@ platform/skip_cache.mobile=true
|
|||||||
sound/speech_enabled=1
|
sound/speech_enabled=1
|
||||||
ui/tooltip_follows_mouse=false
|
ui/tooltip_follows_mouse=false
|
||||||
main/escoria_version=""
|
main/escoria_version=""
|
||||||
ui/dialogs_chooser="res://addons/escoria-core/ui_library/dialogs/text_dialog_chooser.tscn"
|
ui/dialogs_chooser="res://gymkhana/addons/escoria-ui-return-monkey-island-dialog-simple/text_dialog_chooser.tscn"
|
||||||
ui/default_dialog_scene="res://addons/escoria-core/ui_library/dialogs/floating_dialog_player.tscn"
|
ui/default_dialog_scene="res://addons/escoria-core/ui_library/dialogs/floating_dialog_player.tscn"
|
||||||
main/action_default_script="res://action_defaults.esc"
|
main/action_default_script="res://action_defaults.esc"
|
||||||
dialog_simple/text_speed_per_character=0.1
|
dialog_simple/text_speed_per_character=0.1
|
||||||
|
|||||||
Reference in New Issue
Block a user