relocate addons
1
addons/escoria-core
Symbolic link
@@ -0,0 +1 @@
|
||||
../../escoria-demo-game/addons/escoria-core
|
||||
@@ -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,61 @@
|
||||
[gd_scene load_steps=5 format=2]
|
||||
|
||||
[ext_resource path="res://gymkhana/addons/escoria-ui-return-monkey-island-dialog-simple/chooser/simple.gd" type="Script" id=1]
|
||||
[ext_resource path="res://gymkhana/addons/escoria-ui-return-monkey-island-dialog-simple/theme.tres" type="Theme" id=2]
|
||||
|
||||
[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
|
||||
margin_top = 560.0
|
||||
margin_right = 7.0
|
||||
theme = ExtResource( 2 )
|
||||
script = ExtResource( 1 )
|
||||
|
||||
[node name="MarginContainer" type="MarginContainer" parent="."]
|
||||
margin_left = 20.0
|
||||
margin_top = 10.0
|
||||
margin_right = 1280.0
|
||||
margin_bottom = 185.0
|
||||
mouse_filter = 2
|
||||
custom_constants/margin_top = 20
|
||||
custom_constants/margin_left = 20
|
||||
|
||||
[node name="ScrollContainer" type="ScrollContainer" parent="MarginContainer"]
|
||||
margin_left = 20.0
|
||||
margin_top = 20.0
|
||||
margin_right = 1260.0
|
||||
margin_bottom = 175.0
|
||||
scroll_horizontal_enabled = false
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/ScrollContainer"]
|
||||
margin_right = 1240.0
|
||||
margin_bottom = 155.0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
custom_constants/separation = 10
|
||||
__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
|
||||
|
||||
[node name="AvatarContainer" type="Node2D" parent="."]
|
||||
position = Vector2( 94, 68 )
|
||||
|
||||
[connection signal="timeout" from="Timer" to="." method="_on_Timer_timeout"]
|
||||
@@ -0,0 +1,50 @@
|
||||
# `say_last_dialog_option`
|
||||
#
|
||||
# Current player says the text of the last selected dialog option.
|
||||
#
|
||||
# @ESC
|
||||
extends ESCBaseCommand
|
||||
class_name SayLastDialogOptionCommand
|
||||
|
||||
|
||||
# Return the descriptor of the arguments of this command
|
||||
func configure() -> ESCCommandArgumentDescriptor:
|
||||
return ESCCommandArgumentDescriptor.new()
|
||||
|
||||
# Run the command
|
||||
func run(_command_params: Array) -> int:
|
||||
escoria.current_state = escoria.GAME_STATE.DIALOG
|
||||
|
||||
if !escoria.dialog_player:
|
||||
escoria.logger.error(
|
||||
self,
|
||||
"[%s]: No dialog player was registered and the say command was encountered."
|
||||
% get_command_name()
|
||||
)
|
||||
escoria.current_state = escoria.GAME_STATE.DEFAULT
|
||||
return ESCExecution.RC_ERROR
|
||||
|
||||
if not escoria.main.current_scene.player:
|
||||
escoria.logger.warn(
|
||||
self,
|
||||
"[%s]: No player item in the current scene was registered and the say command was encountered."
|
||||
% get_command_name()
|
||||
)
|
||||
escoria.current_state = escoria.GAME_STATE.DEFAULT
|
||||
return ESCExecution.RC_CANCEL
|
||||
|
||||
var last_chosen_option = escoria.globals_manager.get_global("ESC_DIALOG_CHOSEN_OPTION")
|
||||
# Surround text with quotes. Required by escoria.dialog_player.say()
|
||||
var text = "\"%s\"" % last_chosen_option
|
||||
|
||||
var speaking_character_global_id = escoria.main.current_scene.player.global_id
|
||||
|
||||
escoria.dialog_player.say(
|
||||
speaking_character_global_id,
|
||||
"",
|
||||
text
|
||||
)
|
||||
yield(escoria.dialog_player, "say_finished")
|
||||
escoria.current_state = escoria.GAME_STATE.DEFAULT
|
||||
|
||||
return ESCExecution.RC_OK
|
||||
@@ -0,0 +1,126 @@
|
||||
# `say_random global_id list_id lenght`
|
||||
#
|
||||
# Displays the specified string as dialog spoken by the player. This command
|
||||
# blocks further event execution until the dialog has finished being 'said'
|
||||
# (either as displayed text or as audible speech from a file).
|
||||
#
|
||||
# Global variables can be substituted into the text by wrapping the global
|
||||
# name in braces.
|
||||
# e.g. say player "I have {coin_count} coins remaining".
|
||||
#
|
||||
# **Parameters**
|
||||
#
|
||||
# - *player*: Global ID of the `ESCPlayer` or `ESCItem` object that is active.
|
||||
# You can specify `current_player` in order to refer to the currently active
|
||||
# player, e.g. in cases where multiple players are playable such as in games
|
||||
# like Maniac Mansion or Day of the Tentacle.
|
||||
# - *randomizer_list_id*: ID for the list of sentences.
|
||||
# - *lenght*: lenght of the list.
|
||||
#
|
||||
# Example: `say_random player random_list 4`
|
||||
#
|
||||
# @ESC
|
||||
extends ESCBaseCommand
|
||||
class_name SayRandomCommand
|
||||
|
||||
|
||||
const CURRENT_PLAYER_KEYWORD = "CURRENT_PLAYER"
|
||||
|
||||
|
||||
var rng: RandomNumberGenerator
|
||||
|
||||
# Constructor
|
||||
func _init() -> void:
|
||||
rng = RandomNumberGenerator.new()
|
||||
|
||||
|
||||
# Return the descriptor of the arguments of this command
|
||||
func configure() -> ESCCommandArgumentDescriptor:
|
||||
return ESCCommandArgumentDescriptor.new(
|
||||
3,
|
||||
[TYPE_STRING, TYPE_STRING, TYPE_INT],
|
||||
[
|
||||
null,
|
||||
null,
|
||||
null
|
||||
],
|
||||
[
|
||||
true,
|
||||
false,
|
||||
false
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
# Validate whether the given arguments match the command descriptor
|
||||
func validate(arguments: Array):
|
||||
if not .validate(arguments):
|
||||
return false
|
||||
|
||||
if arguments[0].to_upper() != CURRENT_PLAYER_KEYWORD \
|
||||
and not escoria.object_manager.has(arguments[0]):
|
||||
escoria.logger.error(
|
||||
self,
|
||||
"[%s]: Invalid object: Object with global id %s not found."
|
||||
% [get_command_name(), arguments[0]]
|
||||
)
|
||||
return false
|
||||
|
||||
return true
|
||||
|
||||
|
||||
# Run the command
|
||||
func run(command_params: Array) -> int:
|
||||
escoria.current_state = escoria.GAME_STATE.DIALOG
|
||||
var param_global_id = command_params[0]
|
||||
var param_list_id = command_params[1]
|
||||
var param_lenght = command_params[2]
|
||||
|
||||
if !escoria.dialog_player:
|
||||
escoria.logger.error(
|
||||
self,
|
||||
"[%s]: No dialog player was registered and the say command was encountered."
|
||||
% get_command_name()
|
||||
)
|
||||
escoria.current_state = escoria.GAME_STATE.DEFAULT
|
||||
return ESCExecution.RC_ERROR
|
||||
|
||||
if not escoria.main.current_scene.player:
|
||||
escoria.logger.warn(
|
||||
self,
|
||||
"[%s]: No player item in the current scene was registered and the say command was encountered."
|
||||
% get_command_name()
|
||||
)
|
||||
escoria.current_state = escoria.GAME_STATE.DEFAULT
|
||||
return ESCExecution.RC_CANCEL
|
||||
|
||||
var text = param_list_id + "_" + String(rng.randi_range(0,param_lenght -1)) + ':" "'
|
||||
|
||||
var speaking_character_global_id = escoria.main.current_scene.player.global_id \
|
||||
if param_global_id.to_upper() == CURRENT_PLAYER_KEYWORD \
|
||||
else param_global_id
|
||||
|
||||
escoria.dialog_player.say(
|
||||
speaking_character_global_id,
|
||||
"",
|
||||
text
|
||||
)
|
||||
yield(escoria.dialog_player, "say_finished")
|
||||
escoria.current_state = escoria.GAME_STATE.DEFAULT
|
||||
|
||||
var current_count_global_key = "%s_count" % [param_list_id]
|
||||
var current_count = escoria.globals_manager.get_global(current_count_global_key)
|
||||
if(current_count == null):
|
||||
current_count = 0
|
||||
|
||||
escoria.globals_manager.set_global(current_count_global_key, current_count + 1)
|
||||
|
||||
return ESCExecution.RC_OK
|
||||
|
||||
|
||||
# Function called when the command is interrupted.
|
||||
func interrupt():
|
||||
escoria.logger.debug(
|
||||
self,
|
||||
"[%s] interrupt() function not implemented." % get_command_name()
|
||||
)
|
||||
@@ -0,0 +1,140 @@
|
||||
# `say_random global_id list_id lenght [loop]`
|
||||
#
|
||||
# Displays the specified string as dialog spoken by the player. This command
|
||||
# blocks further event execution until the dialog has finished being 'said'
|
||||
# (either as displayed text or as audible speech from a file).
|
||||
#
|
||||
# Global variables can be substituted into the text by wrapping the global
|
||||
# name in braces.
|
||||
# e.g. say player "I have {coin_count} coins remaining".
|
||||
#
|
||||
# **Parameters**
|
||||
#
|
||||
# - *global_id*: Global ID of the `ESCPlayer` or `ESCItem` object that is active.
|
||||
# You can specify `current_player` in order to refer to the currently active
|
||||
# player, e.g. in cases where multiple players are playable such as in games
|
||||
# like Maniac Mansion or Day of the Tentacle.
|
||||
# - *randomizer_list_id*: ID for the list of sentences.
|
||||
# - *lenght*: lenght of the list.
|
||||
# - *loop*: . Loop the list.Can be true or false. Default: false
|
||||
#
|
||||
# Example: `say_random player random_list 4 false`
|
||||
#
|
||||
# @ESC
|
||||
extends ESCBaseCommand
|
||||
class_name SaySequenceCommand
|
||||
|
||||
|
||||
const CURRENT_PLAYER_KEYWORD = "CURRENT_PLAYER"
|
||||
|
||||
|
||||
|
||||
|
||||
# Return the descriptor of the arguments of this command
|
||||
func configure() -> ESCCommandArgumentDescriptor:
|
||||
return ESCCommandArgumentDescriptor.new(
|
||||
3,
|
||||
[TYPE_STRING, TYPE_STRING, TYPE_INT, TYPE_BOOL],
|
||||
[
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
false
|
||||
],
|
||||
[
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
# Validate whether the given arguments match the command descriptor
|
||||
func validate(arguments: Array):
|
||||
if not .validate(arguments):
|
||||
return false
|
||||
|
||||
if arguments[0].to_upper() != CURRENT_PLAYER_KEYWORD \
|
||||
and not escoria.object_manager.has(arguments[0]):
|
||||
escoria.logger.error(
|
||||
self,
|
||||
"[%s]: Invalid object: Object with global id %s not found."
|
||||
% [get_command_name(), arguments[0]]
|
||||
)
|
||||
return false
|
||||
|
||||
return true
|
||||
|
||||
|
||||
# Run the command
|
||||
func run(command_params: Array) -> int:
|
||||
escoria.current_state = escoria.GAME_STATE.DIALOG
|
||||
var param_global_id = command_params[0]
|
||||
var param_list_id = command_params[1]
|
||||
var param_lenght = command_params[2]
|
||||
var loop = command_params[3]
|
||||
|
||||
if !escoria.dialog_player:
|
||||
escoria.logger.error(
|
||||
self,
|
||||
"[%s]: No dialog player was registered and the say command was encountered."
|
||||
% get_command_name()
|
||||
)
|
||||
escoria.current_state = escoria.GAME_STATE.DEFAULT
|
||||
return ESCExecution.RC_ERROR
|
||||
|
||||
if not escoria.main.current_scene.player:
|
||||
escoria.logger.warn(
|
||||
self,
|
||||
"[%s]: No player item in the current scene was registered and the say command was encountered."
|
||||
% get_command_name()
|
||||
)
|
||||
escoria.current_state = escoria.GAME_STATE.DEFAULT
|
||||
return ESCExecution.RC_CANCEL
|
||||
|
||||
var current_index_global_key = "%s_current_iteration" % [param_list_id]
|
||||
var current_index = escoria.globals_manager.get_global(current_index_global_key)
|
||||
if(current_index == null):
|
||||
current_index = 0
|
||||
var text = '%s_%s:" "' % [param_list_id,current_index]
|
||||
|
||||
|
||||
var speaking_character_global_id = escoria.main.current_scene.player.global_id \
|
||||
if param_global_id.to_upper() == CURRENT_PLAYER_KEYWORD \
|
||||
else param_global_id
|
||||
|
||||
escoria.dialog_player.say(
|
||||
speaking_character_global_id,
|
||||
"",
|
||||
text
|
||||
)
|
||||
yield(escoria.dialog_player, "say_finished")
|
||||
escoria.current_state = escoria.GAME_STATE.DEFAULT
|
||||
|
||||
current_index += 1
|
||||
if(current_index == param_lenght):
|
||||
if loop:
|
||||
current_index = 0
|
||||
else:
|
||||
current_index = param_lenght -1 #Don't like it but for now it works.
|
||||
|
||||
escoria.globals_manager.set_global(current_index_global_key, current_index)
|
||||
|
||||
|
||||
var current_count_global_key = "%s_count" % [param_list_id]
|
||||
var current_count = escoria.globals_manager.get_global(current_count_global_key)
|
||||
if(current_count == null):
|
||||
current_count = 0
|
||||
|
||||
escoria.globals_manager.set_global(current_count_global_key, current_count + 1)
|
||||
|
||||
return ESCExecution.RC_OK
|
||||
|
||||
|
||||
# Function called when the command is interrupted.
|
||||
func interrupt():
|
||||
escoria.logger.debug(
|
||||
self,
|
||||
"[%s] interrupt() function not implemented." % get_command_name()
|
||||
)
|
||||
@@ -0,0 +1,31 @@
|
||||
"""
|
||||
Base interface for all states: it doesn't do anything in itself
|
||||
but forces us to pass the right arguments to the methods below
|
||||
and makes sure every State object had all of these methods.
|
||||
"""
|
||||
extends Node
|
||||
|
||||
|
||||
signal finished(next_state_name)
|
||||
|
||||
|
||||
# Initialize the state. E.g. change the animation
|
||||
func enter():
|
||||
return
|
||||
|
||||
|
||||
# Clean up the state. Reinitialize values like a timer
|
||||
func exit():
|
||||
return
|
||||
|
||||
|
||||
func handle_input(_event):
|
||||
return
|
||||
|
||||
|
||||
func update(_delta):
|
||||
return
|
||||
|
||||
|
||||
func _on_animation_finished(_anim_name):
|
||||
return
|
||||
@@ -0,0 +1,92 @@
|
||||
"""
|
||||
Base interface for a generic state machine
|
||||
It handles initializing, setting the machine active or not
|
||||
delegating _physics_process, _input calls to the State nodes,
|
||||
and changing the current/active state.
|
||||
"""
|
||||
extends Node
|
||||
|
||||
|
||||
signal state_changed(current_state)
|
||||
|
||||
|
||||
"""
|
||||
You must set a starting node from the inspector or on
|
||||
the node that inherits from this state machine interface
|
||||
If you don't the game will crash (on purpose, so you won't
|
||||
forget to initialize the state machine)
|
||||
"""
|
||||
export(NodePath) var START_STATE
|
||||
var states_map = {}
|
||||
|
||||
var states_stack = [] # can also be used as a pushdown automaton
|
||||
var current_state = null
|
||||
var current_state_name = ""
|
||||
var _active = false setget set_active
|
||||
|
||||
|
||||
func initialize(start_state):
|
||||
for child in get_children():
|
||||
child.connect("finished", self, "_change_state")
|
||||
|
||||
set_active(true)
|
||||
states_stack.push_front(start_state)
|
||||
current_state = states_stack[0]
|
||||
current_state.enter()
|
||||
|
||||
|
||||
func set_active(value):
|
||||
_active = value
|
||||
set_physics_process(value)
|
||||
set_process_input(value)
|
||||
if not _active:
|
||||
states_stack = []
|
||||
current_state = null
|
||||
|
||||
|
||||
func _input(event):
|
||||
current_state.handle_input(event)
|
||||
|
||||
|
||||
func _physics_process(delta):
|
||||
current_state.update(delta)
|
||||
|
||||
|
||||
func _on_animation_finished(anim_name):
|
||||
if not _active:
|
||||
return
|
||||
current_state._on_animation_finished(anim_name)
|
||||
|
||||
|
||||
func _change_state(state_name):
|
||||
if not _active:
|
||||
return
|
||||
|
||||
escoria.logger.trace(
|
||||
self,
|
||||
"Dialog State Machine: Changing state from '%s' to '%s'." % [current_state_name, state_name]
|
||||
)
|
||||
|
||||
current_state.exit()
|
||||
|
||||
if state_name == "previous":
|
||||
states_stack.pop_front()
|
||||
else:
|
||||
states_stack[0] = states_map[state_name]
|
||||
|
||||
current_state = states_stack[0]
|
||||
|
||||
emit_signal("state_changed", current_state)
|
||||
|
||||
#if state_name != "previous":
|
||||
current_state.enter()
|
||||
|
||||
current_state_name = state_name
|
||||
|
||||
|
||||
func get_current_state_name():
|
||||
for key in states_map.keys():
|
||||
if states_map[key] == current_state:
|
||||
return key
|
||||
|
||||
return null
|
||||
@@ -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"
|
||||
149
addons/escoria-ui-return-monkey-island-dialog-simple/plugin.gd
Normal file
@@ -0,0 +1,149 @@
|
||||
# A simple dialog manager for Escoria
|
||||
tool
|
||||
extends EditorPlugin
|
||||
class_name RTMISimpleDialogPlugin
|
||||
|
||||
|
||||
const MANAGER_CLASS="res://gymkhana/addons/escoria-ui-return-monkey-island-dialog-simple/rtmi_dialog_simple.gd"
|
||||
const SETTINGS_ROOT="escoria/rtmi_dialog_simple"
|
||||
|
||||
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 = [
|
||||
RTMISimpleDialogSettings.LEFT_CLICK_ACTION_SPEED_UP,
|
||||
RTMISimpleDialogSettings.LEFT_CLICK_ACTION_INSTANT_FINISH,
|
||||
RTMISimpleDialogSettings.LEFT_CLICK_ACTION_NOTHING
|
||||
]
|
||||
|
||||
var stop_talking_animation_on_options: PoolStringArray = [
|
||||
RTMISimpleDialogSettings.STOP_TALKING_ANIMATION_ON_END_OF_TEXT,
|
||||
RTMISimpleDialogSettings.STOP_TALKING_ANIMATION_ON_END_OF_AUDIO
|
||||
]
|
||||
|
||||
# Override function to return the plugin name.
|
||||
func get_plugin_name():
|
||||
return "escoria-rtmi-dialog-simple"
|
||||
|
||||
# Unregister ourselves
|
||||
func disable_plugin():
|
||||
print("Disabling plugin Escoria Dialog Simple")
|
||||
ESCProjectSettingsManager.remove_setting(
|
||||
ESCProjectSettingsManager.DEFAULT_DIALOG_TYPE
|
||||
)
|
||||
|
||||
ESCProjectSettingsManager.remove_setting(
|
||||
RTMISimpleDialogSettings.AVATARS_PATH
|
||||
)
|
||||
|
||||
ESCProjectSettingsManager.remove_setting(
|
||||
RTMISimpleDialogSettings.TEXT_TIME_PER_LETTER_MS
|
||||
)
|
||||
|
||||
ESCProjectSettingsManager.remove_setting(
|
||||
RTMISimpleDialogSettings.TEXT_TIME_PER_LETTER_MS_FAST
|
||||
)
|
||||
|
||||
ESCProjectSettingsManager.remove_setting(
|
||||
RTMISimpleDialogSettings.CLEAR_TEXT_BY_CLICK_ONLY
|
||||
)
|
||||
|
||||
ESCProjectSettingsManager.remove_setting(
|
||||
RTMISimpleDialogSettings.READING_SPEED_IN_WPM
|
||||
)
|
||||
|
||||
ESCProjectSettingsManager.remove_setting(
|
||||
RTMISimpleDialogSettings.LEFT_CLICK_ACTION
|
||||
)
|
||||
|
||||
ESCProjectSettingsManager.remove_setting(
|
||||
RTMISimpleDialogSettings.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(
|
||||
RTMISimpleDialogSettings.AVATARS_PATH,
|
||||
"res://game/dialog_avatars",
|
||||
{
|
||||
"type": TYPE_STRING,
|
||||
"hint": PROPERTY_HINT_DIR
|
||||
}
|
||||
)
|
||||
|
||||
ESCProjectSettingsManager.register_setting(
|
||||
RTMISimpleDialogSettings.TEXT_TIME_PER_LETTER_MS,
|
||||
TEXT_TIME_PER_LETTER_MS_DEFAULT_VALUE,
|
||||
{
|
||||
"type": TYPE_REAL
|
||||
}
|
||||
)
|
||||
|
||||
ESCProjectSettingsManager.register_setting(
|
||||
RTMISimpleDialogSettings.TEXT_TIME_PER_LETTER_MS_FAST,
|
||||
TEXT_TIME_PER_LETTER_MS_FAST_DEFAULT_VALUE,
|
||||
{
|
||||
"type": TYPE_REAL
|
||||
}
|
||||
)
|
||||
|
||||
ESCProjectSettingsManager.register_setting(
|
||||
RTMISimpleDialogSettings.CLEAR_TEXT_BY_CLICK_ONLY,
|
||||
false,
|
||||
{
|
||||
"type": TYPE_BOOL
|
||||
}
|
||||
)
|
||||
|
||||
ESCProjectSettingsManager.register_setting(
|
||||
RTMISimpleDialogSettings.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(
|
||||
RTMISimpleDialogSettings.LEFT_CLICK_ACTION,
|
||||
RTMISimpleDialogSettings.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(
|
||||
RTMISimpleDialogSettings.STOP_TALKING_ANIMATION_ON,
|
||||
RTMISimpleDialogSettings.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,212 @@
|
||||
# A simple dialog manager for Escoria
|
||||
extends ESCDialogManager
|
||||
class_name ESCReturnToMonekyIslandDialogs
|
||||
|
||||
|
||||
# State machine that governs how the dialog manager behaves
|
||||
var state_machine = preload("res://gymkhana/addons/escoria-ui-return-monkey-island-dialog-simple/rtmi_dialog_simple_state_machine.gd").new()
|
||||
|
||||
# The currently running player
|
||||
var _type_player: Node = null
|
||||
var _preserved_type_player_type: String = ""
|
||||
|
||||
# Reference to the dialog player
|
||||
var _dialog_player: Node = null
|
||||
|
||||
# Basic state tracking
|
||||
var _is_saying: bool = false
|
||||
|
||||
# Whether to preserve the next dialog box used by `say`, or, if already
|
||||
# preserving a dialog box, whether to continue using that dialog box
|
||||
var _should_preserve_dialog_box: bool = false
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
add_child(state_machine)
|
||||
|
||||
|
||||
# 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"] 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
|
||||
|
||||
# Instructs the dialog manager to preserve the next dialog box used by a `say`
|
||||
# command until a call to `disable_preserve_dialog_box` is made.
|
||||
#
|
||||
# This method should be idempotent, i.e. if called after the first time and
|
||||
# prior to `disable_preserve_dialog_box` being called, the result should be the
|
||||
# same.
|
||||
func enable_preserve_dialog_box() -> void:
|
||||
_should_preserve_dialog_box = true
|
||||
|
||||
|
||||
# Instructs the dialog manager to no longer preserve the currently-preserved
|
||||
# dialog box or to not preserve the next dialog box used by a `say` command
|
||||
# (this is the default state).
|
||||
#
|
||||
# This method should be idempotent, i.e. if called after the first time and
|
||||
# prior to `enable_preserve_dialog_box` being called, the result should be the
|
||||
# same.
|
||||
func disable_preserve_dialog_box() -> void:
|
||||
_should_preserve_dialog_box = false
|
||||
|
||||
if is_instance_valid(_dialog_player) and _dialog_player.get_children().has(_type_player):
|
||||
_dialog_player.remove_child(_type_player)
|
||||
_preserved_type_player_type = ""
|
||||
|
||||
# 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
|
||||
|
||||
_initialize_say_states(global_id, text, type)
|
||||
|
||||
if _should_preserve_dialog_box:
|
||||
# If the dialog box type doesn't match what's currently being reused (if anything),
|
||||
# we want to remove the old one (if it exists) and then initialize and add the new dialog
|
||||
# box type to the dialog player
|
||||
if type != _preserved_type_player_type:
|
||||
if _dialog_player.get_children().has(_type_player):
|
||||
_dialog_player.remove_child(_type_player)
|
||||
|
||||
_init_type_player(type)
|
||||
|
||||
_preserved_type_player_type = type
|
||||
else:
|
||||
_init_type_player(type)
|
||||
|
||||
state_machine._change_state("say")
|
||||
|
||||
|
||||
func do_say(global_id: String, text: String) -> void:
|
||||
# Only add_child here in order to prevent _type_player from running its _process method
|
||||
# before we're ready, and only if it's necessary
|
||||
if not _dialog_player.get_children().has(_type_player):
|
||||
_dialog_player.add_child(_type_player)
|
||||
|
||||
_type_player.say(global_id, text)
|
||||
|
||||
|
||||
|
||||
|
||||
func _init_type_player(type: String) -> void:
|
||||
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")
|
||||
_type_player.connect("say_visible", self, "_on_say_visible")
|
||||
|
||||
func _initialize_say_states(global_id: String, text: String, type: String) -> void:
|
||||
state_machine.states_map["say"].initialize(self, global_id, text, type)
|
||||
state_machine.states_map["finish"].initialize(_dialog_player)
|
||||
state_machine.states_map["say_fast"].initialize(self)
|
||||
state_machine.states_map["say_finish"].initialize(self)
|
||||
state_machine.states_map["visible"].initialize(self)
|
||||
state_machine.states_map["interrupt"].initialize(self)
|
||||
|
||||
|
||||
func _on_say_finished():
|
||||
if not _should_preserve_dialog_box and _dialog_player.get_children().has(_type_player):
|
||||
_dialog_player.remove_child(_type_player)
|
||||
|
||||
_is_saying = false
|
||||
|
||||
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
|
||||
# - type: The dialog chooser type to use
|
||||
func choose(dialog_player: Node, dialog: ESCDialog, type: String):
|
||||
_dialog_player = dialog_player
|
||||
|
||||
state_machine.states_map["choices"].initialize(dialog_player, self, dialog, type)
|
||||
state_machine._change_state("choices")
|
||||
|
||||
|
||||
func do_choose(dialog_player: Node, dialog: ESCDialog, type: String = "simple"):
|
||||
var chooser
|
||||
|
||||
if type == "simple" or type == "":
|
||||
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)
|
||||
# MODIFIED FOR RETURN TO MONKEY UI
|
||||
if option is ESCDialogOption:
|
||||
escoria.globals_manager.set_global("ESC_DIALOG_CHOSEN_OPTION", option.option)
|
||||
# END MODIFIED FOR RETURN TO MONKEY UI
|
||||
emit_signal("option_chosen", option)
|
||||
|
||||
|
||||
# Trigger running the dialogue faster
|
||||
func speedup():
|
||||
if is_instance_valid(_type_player):
|
||||
_type_player.speedup()
|
||||
|
||||
|
||||
# Trigger an instant finish of the current dialog
|
||||
func finish():
|
||||
if is_instance_valid(_type_player):
|
||||
_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")
|
||||
|
||||
if not _should_preserve_dialog_box and _dialog_player.get_children().has(_type_player):
|
||||
_dialog_player.remove_child(_type_player)
|
||||
|
||||
emit_signal("say_finished")
|
||||
|
||||
|
||||
# To be called if voice audio has finished.
|
||||
func voice_audio_finished():
|
||||
if is_instance_valid(_type_player):
|
||||
_type_player.voice_audio_finished()
|
||||
@@ -0,0 +1,20 @@
|
||||
extends Resource
|
||||
class_name RTMISimpleDialogSettings
|
||||
|
||||
const SETTINGS_ROOT = "escoria/rtmi_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"
|
||||
@@ -0,0 +1,31 @@
|
||||
extends "res://gymkhana/addons/escoria-ui-return-monkey-island-dialog-simple/patterns/state_machine/state_machine.gd"
|
||||
|
||||
|
||||
func _init():
|
||||
_create_states()
|
||||
_add_states_to_machine()
|
||||
|
||||
current_state_name = "idle"
|
||||
START_STATE = states_map[current_state_name]
|
||||
|
||||
initialize(START_STATE)
|
||||
|
||||
|
||||
# Creates the states for this state machine.
|
||||
func _create_states() -> void:
|
||||
states_map = {
|
||||
"idle": preload("res://gymkhana/addons/escoria-ui-return-monkey-island-dialog-simple/states/dialog_idle.gd").new(),
|
||||
"say": preload("res://gymkhana/addons/escoria-ui-return-monkey-island-dialog-simple/states/dialog_say.gd").new(),
|
||||
"say_fast": preload("res://gymkhana/addons/escoria-ui-return-monkey-island-dialog-simple/states/dialog_say_fast.gd").new(),
|
||||
"say_finish": preload("res://gymkhana/addons/escoria-ui-return-monkey-island-dialog-simple/states/dialog_say_finish.gd").new(),
|
||||
"visible": preload("res://gymkhana/addons/escoria-ui-return-monkey-island-dialog-simple/states/dialog_visible.gd").new(),
|
||||
"finish": preload("res://gymkhana/addons/escoria-ui-return-monkey-island-dialog-simple/states/dialog_finish.gd").new(),
|
||||
"interrupt": preload("res://gymkhana/addons/escoria-ui-return-monkey-island-dialog-simple/states/dialog_interrupt.gd").new(),
|
||||
"choices": preload("res://gymkhana/addons/escoria-ui-return-monkey-island-dialog-simple/states/dialog_choices.gd").new(),
|
||||
}
|
||||
|
||||
|
||||
# Adds any created states into the state machine as children.
|
||||
func _add_states_to_machine() -> void:
|
||||
for key in states_map:
|
||||
add_child(states_map[key])
|
||||
@@ -0,0 +1,44 @@
|
||||
extends "res://addons/escoria-dialog-simple/patterns/state_machine/state.gd"
|
||||
|
||||
|
||||
# The owning dialog player.
|
||||
var _dialog_player
|
||||
|
||||
# The dialog to start.
|
||||
var _dialog: ESCDialog
|
||||
var _type: String = "simple"
|
||||
|
||||
var _dialog_chooser_ui: ESCDialogManager = null
|
||||
|
||||
var _ready_to_choose: bool
|
||||
|
||||
|
||||
func initialize(dialog_player, dialog_chooser_ui: ESCDialogManager, dialog: ESCDialog, type: String) -> void:
|
||||
_dialog_player = dialog_player
|
||||
_dialog_chooser_ui = dialog_chooser_ui
|
||||
_dialog = dialog
|
||||
_type = type
|
||||
|
||||
|
||||
func enter():
|
||||
escoria.logger.trace(self, "Dialog State Machine: Entered 'choices'.")
|
||||
|
||||
if _dialog.options.empty():
|
||||
escoria.logger.error(
|
||||
self,
|
||||
"Received dialog options array was empty."
|
||||
)
|
||||
|
||||
_ready_to_choose = true
|
||||
|
||||
|
||||
func update(_delta):
|
||||
if _ready_to_choose:
|
||||
_ready_to_choose = false
|
||||
_dialog_chooser_ui.do_choose(_dialog_player, _dialog, _type)
|
||||
var option = yield(_dialog_chooser_ui, "option_chosen")
|
||||
|
||||
escoria.logger.trace(self, "Dialog State Machine: 'choices' -> 'idle'")
|
||||
|
||||
emit_signal("finished", "idle")
|
||||
_dialog_player.emit_signal("option_chosen", option)
|
||||
@@ -0,0 +1,19 @@
|
||||
extends "res://addons/escoria-dialog-simple/patterns/state_machine/state.gd"
|
||||
|
||||
|
||||
# Owning dialog player
|
||||
var _dialog_player
|
||||
|
||||
|
||||
func initialize(dialog_player) -> void:
|
||||
_dialog_player = dialog_player
|
||||
|
||||
|
||||
func enter():
|
||||
escoria.logger.trace(self, "Dialog State Machine: Entered 'finish'.")
|
||||
|
||||
|
||||
func update(_delta):
|
||||
escoria.logger.trace(self, "Dialog State Machine: 'finish' -> 'idle'")
|
||||
emit_signal("finished", "idle")
|
||||
_dialog_player.emit_signal("say_finished")
|
||||
@@ -0,0 +1,5 @@
|
||||
extends "res://addons/escoria-dialog-simple/patterns/state_machine/state.gd"
|
||||
|
||||
|
||||
func enter():
|
||||
escoria.logger.trace(self, "Dialog State Machine: Entered 'idle'.")
|
||||
@@ -0,0 +1,25 @@
|
||||
extends "res://addons/escoria-dialog-simple/patterns/state_machine/state.gd"
|
||||
|
||||
|
||||
# Reference to the currently playing dialog manager
|
||||
var _dialog_manager: ESCDialogManager = null
|
||||
|
||||
|
||||
func initialize(dialog_manager: ESCDialogManager) -> void:
|
||||
_dialog_manager = dialog_manager
|
||||
|
||||
|
||||
func enter():
|
||||
escoria.logger.trace(self, "Dialog State Machine: Entered 'interrupt'.")
|
||||
|
||||
if _dialog_manager != null:
|
||||
if not _dialog_manager.is_connected("say_finished", self, "_on_say_finished"):
|
||||
_dialog_manager.connect("say_finished", self, "_on_say_finished")
|
||||
|
||||
_dialog_manager.interrupt()
|
||||
|
||||
|
||||
func _on_say_finished() -> void:
|
||||
escoria.logger.trace(self, "Dialog State Machine: 'interrupt' -> 'finish'")
|
||||
emit_signal("finished", "finish")
|
||||
|
||||
@@ -0,0 +1,181 @@
|
||||
extends "res://addons/escoria-dialog-simple/patterns/state_machine/state.gd"
|
||||
|
||||
|
||||
# A regular expression that separates the translation key from the text
|
||||
const KEYTEXT_REGEX = "^((?<key>[^:]+):)?\"(?<text>.+)\""
|
||||
|
||||
|
||||
# Reference to the currently playing dialog manager
|
||||
var _dialog_manager: ESCDialogManager = null
|
||||
|
||||
# Character that is talking
|
||||
var _character: String
|
||||
|
||||
# UI to use for the dialog
|
||||
var _type: String
|
||||
|
||||
# Text to say
|
||||
var _text: String
|
||||
|
||||
# Regular expression object for the separation of key and text
|
||||
var _keytext_regex: RegEx = RegEx.new()
|
||||
|
||||
var _ready_to_say: bool
|
||||
|
||||
var _stop_talking_animation_on_option: String
|
||||
|
||||
|
||||
# Constructor
|
||||
func _init() -> void:
|
||||
_keytext_regex.compile(KEYTEXT_REGEX)
|
||||
|
||||
|
||||
func initialize(dialog_manager: ESCDialogManager, character: String, text: String, type: String) -> void:
|
||||
_dialog_manager = dialog_manager
|
||||
_character = character
|
||||
_text = text
|
||||
_type = type
|
||||
_stop_talking_animation_on_option = \
|
||||
ESCProjectSettingsManager.get_setting(RTMISimpleDialogSettings.STOP_TALKING_ANIMATION_ON)
|
||||
|
||||
|
||||
func handle_input(_event):
|
||||
if _event is InputEventMouseButton and _event.pressed:
|
||||
if escoria.inputs_manager.input_mode != \
|
||||
escoria.inputs_manager.INPUT_NONE and \
|
||||
_dialog_manager != null:
|
||||
|
||||
var left_click_action = ESCProjectSettingsManager.get_setting(RTMISimpleDialogSettings.LEFT_CLICK_ACTION)
|
||||
|
||||
_handle_left_click_action(left_click_action)
|
||||
|
||||
|
||||
func _handle_left_click_action(left_click_action: String) -> void:
|
||||
match left_click_action:
|
||||
RTMISimpleDialogSettings.LEFT_CLICK_ACTION_SPEED_UP:
|
||||
if _dialog_manager.is_connected("say_visible", self, "_on_say_visible"):
|
||||
_dialog_manager.disconnect("say_visible", self, "_on_say_visible")
|
||||
|
||||
escoria.logger.trace(self, "Dialog State Machine: 'say' -> 'say_fast'")
|
||||
emit_signal("finished", "say_fast")
|
||||
RTMISimpleDialogSettings.LEFT_CLICK_ACTION_INSTANT_FINISH:
|
||||
if _dialog_manager.is_connected("say_visible", self, "_on_say_visible"):
|
||||
_dialog_manager.disconnect("say_visible", self, "_on_say_visible")
|
||||
|
||||
escoria.logger.trace(self, "Dialog State Machine: 'say' -> 'say_finish'")
|
||||
emit_signal("finished", "say_finish")
|
||||
|
||||
get_tree().set_input_as_handled()
|
||||
|
||||
|
||||
func enter():
|
||||
escoria.logger.trace(self, "Dialog State Machine: Entered 'say'.")
|
||||
|
||||
if not _dialog_manager.is_connected("say_visible", self, "_on_say_visible"):
|
||||
_dialog_manager.connect("say_visible", self, "_on_say_visible")
|
||||
|
||||
var matches = _keytext_regex.search(_text)
|
||||
|
||||
if not matches:
|
||||
escoria.logger.error(
|
||||
self,
|
||||
"Unexpected text encountered: %s." % _text
|
||||
)
|
||||
|
||||
var key = matches.get_string("key")
|
||||
|
||||
if matches.get_string("key") != "":
|
||||
var _speech_resource = _get_voice_file(
|
||||
matches.get_string("key")
|
||||
)
|
||||
|
||||
if _speech_resource == "":
|
||||
escoria.logger.warn(
|
||||
self,
|
||||
"Unable to find voice file with key '%s'." % matches.get_string("key")
|
||||
)
|
||||
else:
|
||||
(
|
||||
escoria.object_manager.get_object(escoria.object_manager.SPEECH).node\
|
||||
as ESCSpeechPlayer
|
||||
).set_state(_speech_resource)
|
||||
|
||||
if _stop_talking_animation_on_option == RTMISimpleDialogSettings.STOP_TALKING_ANIMATION_ON_END_OF_AUDIO:
|
||||
if not (
|
||||
escoria.object_manager.get_object(escoria.object_manager.SPEECH).node\
|
||||
as ESCSpeechPlayer
|
||||
).stream.is_connected("finished", self, "_on_audio_finished"):
|
||||
|
||||
(
|
||||
escoria.object_manager.get_object(escoria.object_manager.SPEECH).node\
|
||||
as ESCSpeechPlayer
|
||||
).stream.connect("finished", self, "_on_audio_finished")
|
||||
|
||||
var translated_text: String = tr(matches.get_string("key"))
|
||||
|
||||
# Only update the text if the translated text was found; otherwise, raise
|
||||
# a warning and use the original, untranslated text.
|
||||
if translated_text == matches.get_string("key"):
|
||||
escoria.logger.warn(
|
||||
self,
|
||||
"Unable to find translation key '%s'. Using untranslated text." % matches.get_string("key")
|
||||
)
|
||||
_text = matches.get_string("text")
|
||||
else:
|
||||
_text = translated_text
|
||||
else:
|
||||
_text = matches.get_string("text")
|
||||
|
||||
_ready_to_say = true
|
||||
|
||||
|
||||
func update(_delta):
|
||||
if _ready_to_say:
|
||||
_dialog_manager.do_say(_character, _text)
|
||||
_ready_to_say = false
|
||||
|
||||
|
||||
# Find the matching voice output file for the given key
|
||||
#
|
||||
# #### Parameters
|
||||
#
|
||||
# - key: Text key provided
|
||||
# - start: Starting folder to search for voices
|
||||
#
|
||||
# *Returns* The path to the matching voice file
|
||||
func _get_voice_file(key: String, start: String = "") -> String:
|
||||
if start == "":
|
||||
start = ESCProjectSettingsManager.get_setting(
|
||||
ESCProjectSettingsManager.SPEECH_FOLDER
|
||||
)
|
||||
var _dir = Directory.new()
|
||||
if _dir.open(start) == OK:
|
||||
_dir.list_dir_begin(true, true)
|
||||
var file_name = _dir.get_next()
|
||||
while file_name != "":
|
||||
if _dir.current_is_dir():
|
||||
var _voice_file = _get_voice_file(
|
||||
key,
|
||||
start.plus_file(file_name)
|
||||
)
|
||||
if _voice_file != "":
|
||||
return _voice_file
|
||||
else:
|
||||
if file_name == "%s.%s.import" % [
|
||||
key,
|
||||
ESCProjectSettingsManager.get_setting(
|
||||
ESCProjectSettingsManager.SPEECH_EXTENSION
|
||||
)
|
||||
]:
|
||||
return start.plus_file(file_name.trim_suffix(".import"))
|
||||
file_name = _dir.get_next()
|
||||
return ""
|
||||
|
||||
|
||||
func _on_say_visible() -> void:
|
||||
escoria.logger.trace(self, "Dialog State Machine: 'say' -> 'visible'")
|
||||
emit_signal("finished", "visible")
|
||||
|
||||
|
||||
func _on_audio_finished() -> void:
|
||||
_dialog_manager.voice_audio_finished()
|
||||
@@ -0,0 +1,29 @@
|
||||
extends "res://addons/escoria-dialog-simple/patterns/state_machine/state.gd"
|
||||
|
||||
|
||||
# Reference to the currently playing dialog manager
|
||||
var _dialog_manager: ESCDialogManager = null
|
||||
|
||||
|
||||
func initialize(dialog_manager: ESCDialogManager) -> void:
|
||||
_dialog_manager = dialog_manager
|
||||
|
||||
|
||||
func enter():
|
||||
escoria.logger.trace(self, "Dialog State Machine: Entered 'say_fast'.")
|
||||
|
||||
if escoria.inputs_manager.input_mode != \
|
||||
escoria.inputs_manager.INPUT_NONE and \
|
||||
_dialog_manager != null:
|
||||
|
||||
if not _dialog_manager.is_connected("say_visible", self, "_on_say_visible"):
|
||||
_dialog_manager.connect("say_visible", self, "_on_say_visible")
|
||||
|
||||
_dialog_manager.speedup()
|
||||
else:
|
||||
escoria.logger.error(self, "Illegal state.")
|
||||
|
||||
|
||||
func _on_say_visible() -> void:
|
||||
escoria.logger.trace(self, "Dialog State Machine: 'say_fast' -> 'visible'")
|
||||
emit_signal("finished", "visible")
|
||||
@@ -0,0 +1,29 @@
|
||||
extends "res://addons/escoria-dialog-simple/patterns/state_machine/state.gd"
|
||||
|
||||
|
||||
# Reference to the currently playing dialog manager
|
||||
var _dialog_manager: ESCDialogManager = null
|
||||
|
||||
|
||||
func initialize(dialog_manager: ESCDialogManager) -> void:
|
||||
_dialog_manager = dialog_manager
|
||||
|
||||
|
||||
func enter():
|
||||
escoria.logger.trace(self, "Dialog State Machine: Entered 'say_finish'.")
|
||||
|
||||
if escoria.inputs_manager.input_mode != \
|
||||
escoria.inputs_manager.INPUT_NONE and \
|
||||
_dialog_manager != null:
|
||||
|
||||
if not _dialog_manager.is_connected("say_visible", self, "_on_say_visible"):
|
||||
_dialog_manager.connect("say_visible", self, "_on_say_visible")
|
||||
|
||||
_dialog_manager.finish()
|
||||
else:
|
||||
escoria.logger.error(self, "Illegal state.")
|
||||
|
||||
|
||||
func _on_say_visible() -> void:
|
||||
escoria.logger.trace(self, "Dialog State Machine: 'say_finish' -> 'visible'")
|
||||
emit_signal("finished", "visible")
|
||||
@@ -0,0 +1,34 @@
|
||||
extends "res://addons/escoria-dialog-simple/patterns/state_machine/state.gd"
|
||||
|
||||
|
||||
# Reference to the currently playing dialog manager
|
||||
var _dialog_manager: ESCDialogManager = null
|
||||
|
||||
|
||||
func initialize(dialog_manager: ESCDialogManager) -> void:
|
||||
_dialog_manager = dialog_manager
|
||||
|
||||
|
||||
func enter():
|
||||
escoria.logger.trace(self, "Dialog State Machine: Entered 'visible'.")
|
||||
|
||||
if not _dialog_manager.is_connected("say_finished", self, "_on_say_finished"):
|
||||
_dialog_manager.connect("say_finished", self, "_on_say_finished")
|
||||
|
||||
|
||||
func handle_input(_event):
|
||||
if _event is InputEventMouseButton and _event.pressed:
|
||||
if escoria.inputs_manager.input_mode != \
|
||||
escoria.inputs_manager.INPUT_NONE:
|
||||
|
||||
if _dialog_manager.is_connected("say_finished", self, "_on_say_finished"):
|
||||
_dialog_manager.disconnect("say_finished", self, "_on_say_finished")
|
||||
|
||||
emit_signal("finished", "interrupt")
|
||||
get_tree().set_input_as_handled()
|
||||
|
||||
|
||||
# Handles the end of a say function after it has emitted say_finished.
|
||||
func _on_say_finished():
|
||||
escoria.logger.trace(self, "Dialog State Machine: 'visible' -> 'finish'")
|
||||
emit_signal("finished", "finish")
|
||||
@@ -0,0 +1,19 @@
|
||||
[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.815686 )
|
||||
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 )
|
||||
VBoxContainer/constants/separation = 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(
|
||||
RTMISimpleDialogPlugin.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." %
|
||||
[
|
||||
RTMISimpleDialogPlugin.TEXT_TIME_PER_LETTER_MS,
|
||||
RTMISimpleDialogPlugin.TEXT_TIME_PER_LETTER_MS_DEFAULT_VALUE
|
||||
]
|
||||
)
|
||||
|
||||
_text_time_per_character = RTMISimpleDialogPlugin.TEXT_TIME_PER_LETTER_MS_DEFAULT_VALUE
|
||||
|
||||
_fast_text_time_per_character = ProjectSettings.get_setting(
|
||||
RTMISimpleDialogPlugin.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." %
|
||||
[
|
||||
RTMISimpleDialogPlugin.TEXT_TIME_PER_LETTER_MS_FAST,
|
||||
RTMISimpleDialogPlugin.TEXT_TIME_PER_LETTER_MS_FAST_DEFAULT_VALUE
|
||||
]
|
||||
)
|
||||
|
||||
_fast_text_time_per_character = RTMISimpleDialogPlugin.TEXT_TIME_PER_LETTER_MS_FAST_DEFAULT_VALUE
|
||||
|
||||
_reading_speed_in_wpm = ProjectSettings.get_setting(
|
||||
RTMISimpleDialogPlugin.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." %
|
||||
[
|
||||
RTMISimpleDialogPlugin.READING_SPEED_IN_WPM,
|
||||
RTMISimpleDialogPlugin.READING_SPEED_IN_WPM_DEFAULT_VALUE
|
||||
]
|
||||
)
|
||||
|
||||
_reading_speed_in_wpm = RTMISimpleDialogPlugin.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(RTMISimpleDialogPlugin.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="."]
|
||||
20
addons/escoria-ui-return-monkey-island/MusicButton.gd
Normal file
@@ -0,0 +1,20 @@
|
||||
extends TextureButton
|
||||
|
||||
export(Texture) var musicEnabledTexture: Texture
|
||||
export(Texture) var musicEnabledHoverTexture: Texture
|
||||
|
||||
export(Texture) var musicDisabledTexture: Texture
|
||||
export(Texture) var musicDisabledHoverTexture: Texture
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
pass # Replace with function body.
|
||||
|
||||
func _process(delta: float):
|
||||
if escoria.game_scene.musicEnabled == true:
|
||||
texture_normal = musicEnabledTexture
|
||||
texture_hover = musicEnabledHoverTexture
|
||||
else:
|
||||
texture_normal = musicDisabledTexture
|
||||
texture_hover = musicDisabledHoverTexture
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
extends Button
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
pass # Replace with function body.
|
||||
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
#func _process(delta):
|
||||
# pass
|
||||
BIN
addons/escoria-ui-return-monkey-island/cursors/mouse_left.png
Normal file
|
After Width: | Height: | Size: 144 B |
BIN
addons/escoria-ui-return-monkey-island/cursors/mouse_right.png
Normal file
|
After Width: | Height: | Size: 145 B |
|
After Width: | Height: | Size: 5.5 KiB |
|
After Width: | Height: | Size: 5.5 KiB |
@@ -0,0 +1,39 @@
|
||||
# `item_count_add item_id value`
|
||||
#
|
||||
# Add value to the count in a item.
|
||||
# - item_id: string: id of the item to apply
|
||||
# - value: int: number to add
|
||||
#
|
||||
# @ESC
|
||||
extends ESCBaseCommand
|
||||
class_name ItemCountAddCommand
|
||||
|
||||
|
||||
var item_count_manager = ESCItemCountManager.new()
|
||||
|
||||
# Return the descriptor of the arguments of this command
|
||||
func configure() -> ESCCommandArgumentDescriptor:
|
||||
return ESCCommandArgumentDescriptor.new(
|
||||
1,
|
||||
[TYPE_STRING, TYPE_INT],
|
||||
[null, 1]
|
||||
)
|
||||
|
||||
|
||||
# Validate wether the given arguments match the command descriptor
|
||||
func validate(arguments: Array):
|
||||
if not escoria.object_manager.has(arguments[0]):
|
||||
escoria.logger.error(
|
||||
self,
|
||||
"Object %s not registered" % arguments[0]
|
||||
)
|
||||
return false
|
||||
|
||||
return .validate(arguments)
|
||||
|
||||
|
||||
# Run the command
|
||||
func run(command_params: Array) -> int:
|
||||
item_count_manager.add(command_params[0], command_params[1])
|
||||
|
||||
return ESCExecution.RC_OK
|
||||
@@ -0,0 +1,57 @@
|
||||
# `play_lib_snd filename namespace`
|
||||
#
|
||||
# Plays a sound from the library.
|
||||
#
|
||||
# **Parameters**
|
||||
#
|
||||
# - *file_name*: File name withot extension
|
||||
# - *namespace*: Subfolder
|
||||
#
|
||||
# @ESC
|
||||
extends ESCBaseCommand
|
||||
class_name PlayLibSound
|
||||
|
||||
|
||||
# Return the descriptor of the arguments of this command
|
||||
func configure() -> ESCCommandArgumentDescriptor:
|
||||
return ESCCommandArgumentDescriptor.new(
|
||||
1,
|
||||
[TYPE_STRING,TYPE_STRING],
|
||||
[null,""]
|
||||
)
|
||||
|
||||
|
||||
# Validate whether the given arguments match the command descriptor
|
||||
func validate(arguments: Array):
|
||||
if not .validate(arguments):
|
||||
return false
|
||||
|
||||
var subFolder = arguments[1]
|
||||
if(arguments[1] != ""):
|
||||
subFolder += "/"
|
||||
var resourceFile = "res://gymkhana/sounds/" + subFolder + arguments[0] + ".ogg"
|
||||
if not ResourceLoader.exists(resourceFile):
|
||||
escoria.logger.error(
|
||||
self,
|
||||
"[%s]: invalid parameter. File %s not found."
|
||||
% [get_command_name(), resourceFile]
|
||||
)
|
||||
return false
|
||||
|
||||
return true
|
||||
|
||||
|
||||
# Run the command
|
||||
func run(command_params: Array) -> int:
|
||||
var resourceFile = "res://gymkhana/sounds/" + command_params[0] + ".ogg"
|
||||
escoria.object_manager.get_object("_sound").node.set_state(
|
||||
resourceFile
|
||||
)
|
||||
return ESCExecution.RC_OK
|
||||
|
||||
|
||||
# Function called when the command is interrupted.
|
||||
func interrupt():
|
||||
# Do nothing
|
||||
pass
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
# `play_video file`
|
||||
#
|
||||
# Plays the specified video blocking the currently running event .
|
||||
#
|
||||
# **Parameters**
|
||||
#
|
||||
# - *file*: Video file to play
|
||||
#
|
||||
# @ESC
|
||||
extends ESCBaseCommand
|
||||
class_name PlayVideoCommand
|
||||
|
||||
# Return the descriptor of the arguments of this command
|
||||
func configure() -> ESCCommandArgumentDescriptor:
|
||||
return ESCCommandArgumentDescriptor.new(
|
||||
1,
|
||||
[TYPE_STRING, TYPE_STRING]
|
||||
)
|
||||
|
||||
|
||||
# Validate whether the given arguments match the command descriptor
|
||||
func validate(arguments: Array):
|
||||
if not .validate(arguments):
|
||||
return false
|
||||
|
||||
if not ResourceLoader.exists(arguments[0]):
|
||||
escoria.logger.error(
|
||||
self,
|
||||
"[%s]: invalid parameter. File %s not found."
|
||||
% [get_command_name(), arguments[0]]
|
||||
)
|
||||
return false
|
||||
return true
|
||||
|
||||
|
||||
# Run the command
|
||||
func run(command_params: Array) -> int:
|
||||
escoria.game_scene.play_video(command_params[0])
|
||||
#We wait for the video to emit "finished" signal with yield
|
||||
yield(escoria.game_scene.get_video_player(),"finished")
|
||||
return ESCExecution.RC_OK
|
||||
@@ -0,0 +1,52 @@
|
||||
# `set_tooltip global_id action text`
|
||||
#
|
||||
# Sets the tooltip text for the given `ESCItemWithTooltip` and action.
|
||||
#
|
||||
# **Parameters**
|
||||
#
|
||||
# - *object*: Global ID of the object whose toolitp is to be updated
|
||||
# - *action*: ID of the action, action1, action2, action3 or action4.
|
||||
# - *toolip*: The tooltip text string
|
||||
#
|
||||
# @ESC
|
||||
extends ESCBaseCommand
|
||||
class_name SetTooltipCommand
|
||||
|
||||
|
||||
# Return the descriptor of the arguments of this command
|
||||
func configure() -> ESCCommandArgumentDescriptor:
|
||||
return ESCCommandArgumentDescriptor.new(
|
||||
2,
|
||||
[TYPE_STRING,TYPE_STRING, TYPE_STRING],
|
||||
[null, "action1", ""]
|
||||
)
|
||||
|
||||
|
||||
# Validate whether the given arguments match the command descriptor
|
||||
func validate(arguments: Array):
|
||||
if not .validate(arguments):
|
||||
return false
|
||||
|
||||
if not escoria.object_manager.has(arguments[0]):
|
||||
escoria.logger.error(
|
||||
self,
|
||||
"[%s]: invalid object. Object with global id %s not found."
|
||||
% [get_command_name(), arguments[0]]
|
||||
)
|
||||
return false
|
||||
|
||||
return true
|
||||
|
||||
|
||||
# Run the command
|
||||
func run(command_params: Array) -> int:
|
||||
(escoria.object_manager.get_object(command_params[0]).node as ESCItemWithTooltip)\
|
||||
.set_tooltip(command_params[1],command_params[2])
|
||||
return ESCExecution.RC_OK
|
||||
|
||||
|
||||
# Function called when the command is interrupted.
|
||||
func interrupt():
|
||||
# Do nothing
|
||||
pass
|
||||
|
||||
@@ -0,0 +1,352 @@
|
||||
# Manages currently carried out actions
|
||||
# MODIFIED FOR RETURN TO MONKEY UI
|
||||
extends ESCActionManager
|
||||
class_name ESCActionManagerMonkey
|
||||
|
||||
# Set the current action verb
|
||||
#
|
||||
# ## Parameters
|
||||
# - action: The action verb to set
|
||||
func set_current_action(action: String):
|
||||
# MODIFIED FOR RETURN TO MONKEY UI
|
||||
if (action != current_action) && (action_state != ACTION_INPUT_STATE.AWAITING_TARGET_ITEM):
|
||||
clear_current_tool()
|
||||
|
||||
current_action = action
|
||||
|
||||
if action_state == ACTION_INPUT_STATE.AWAITING_VERB_OR_ITEM:
|
||||
set_action_input_state(ACTION_INPUT_STATE.AWAITING_ITEM)
|
||||
elif action_state == ACTION_INPUT_STATE.AWAITING_VERB:
|
||||
set_action_input_state(ACTION_INPUT_STATE.AWAITING_VERB_CONFIRM)
|
||||
|
||||
emit_signal("action_changed")
|
||||
|
||||
|
||||
# Checks if the specified action is valid and returns the associated event;
|
||||
# otherwise, we see if there's a "fallback" event and use that if necessary and,
|
||||
# if not, we return no event as there's nothing to do.
|
||||
#
|
||||
# #### Parameters
|
||||
#
|
||||
# - action: Action to execute (defined in attached ESC file and in
|
||||
# action verbs UI) eg: arrived, use, look, pickup...
|
||||
# - target: Target ESC object
|
||||
# - combine_with: ESC object to combine with
|
||||
#
|
||||
# *Returns* the appropriate ESCEvent to queue/run, or null if none can be found
|
||||
# or there's a reason not to run an event.
|
||||
func _get_event_to_queue(
|
||||
action: String,
|
||||
target: ESCObject,
|
||||
combine_with: ESCObject = null
|
||||
) -> ESCEvent:
|
||||
|
||||
escoria.logger.info(
|
||||
self,
|
||||
"Checking if action '%s' on '%s' is valid..." % [action, target]
|
||||
)
|
||||
|
||||
var event_to_return: ESCEvent = null
|
||||
|
||||
# If we're using an action which item requires to combine
|
||||
if target.node is ESCItem \
|
||||
and (action in target.node.combine_when_selected_action_is_in
|
||||
# MODIFIED FOR RETURN TO MONKEY UI
|
||||
or combine_with):
|
||||
# or (combine_with && action in combine_with.node.combine_when_selected_action_is_in)):
|
||||
|
||||
# Player has item in inventory, we check the element to use on
|
||||
if escoria.inventory_manager.inventory_has(target.global_id):
|
||||
if combine_with:
|
||||
var target_event = "%s %s" % [
|
||||
action,
|
||||
combine_with.global_id
|
||||
]
|
||||
var combine_with_event = "%s %s" % [
|
||||
action,
|
||||
target.global_id
|
||||
]
|
||||
|
||||
if target.events.has(target_event):
|
||||
event_to_return = target.events[target_event]
|
||||
elif combine_with.events.has(combine_with_event)\
|
||||
and not combine_with.node.combine_is_one_way:
|
||||
|
||||
event_to_return = combine_with.events[combine_with_event]
|
||||
else:
|
||||
# Check to see if there isn't a "fallback" action to
|
||||
# run before we declare this a failure.
|
||||
if escoria.action_default_script \
|
||||
and escoria.action_default_script.events.has(action):
|
||||
|
||||
event_to_return = escoria.action_default_script.events[action]
|
||||
else:
|
||||
var errors = [
|
||||
"Attempted to execute action %s between item %s and item %s" % [
|
||||
action,
|
||||
target.global_id,
|
||||
combine_with.global_id
|
||||
]
|
||||
]
|
||||
|
||||
if combine_with.node.combine_is_one_way:
|
||||
errors.append(
|
||||
("Reason: %s's item interaction " + \
|
||||
"is one-way.") % combine_with.global_id
|
||||
)
|
||||
|
||||
escoria.logger.warn(
|
||||
self,
|
||||
"Invalid action: " + str(errors)
|
||||
)
|
||||
else:
|
||||
if target.events.has(action):
|
||||
event_to_return = target.events[action]
|
||||
elif escoria.action_default_script \
|
||||
and escoria.action_default_script.events.has(action):
|
||||
|
||||
# If there's a "fallback" action to run, return it
|
||||
event_to_return = escoria.action_default_script.events[action]
|
||||
else:
|
||||
escoria.logger.warn(
|
||||
self,
|
||||
"Invalid action: " +
|
||||
"Event for action %s on object %s not found." % [
|
||||
action,
|
||||
target.global_id
|
||||
]
|
||||
)
|
||||
|
||||
return event_to_return
|
||||
|
||||
|
||||
# Event handler when an object/item was clicked
|
||||
#
|
||||
# #### Parameters
|
||||
#
|
||||
# - obj: Object that was left clicked
|
||||
# - event: Input event that was received
|
||||
# - default_action: if true, run the inventory default action
|
||||
func perform_inputevent_on_object(
|
||||
obj: ESCObject,
|
||||
event: InputEvent,
|
||||
default_action: bool = false
|
||||
):
|
||||
"""
|
||||
This algorithm:
|
||||
- validates the requested action
|
||||
- grabs the corresponding event for the action, if available
|
||||
- makes the player move to the clicked object location, if needed
|
||||
(if it is located in the room for example) and wait for reaching.
|
||||
- when reached, performs an action depending on current defined action
|
||||
* no current action defined: do nothing else
|
||||
* current action defined:
|
||||
* item requires no combination: perform the current action
|
||||
on the item
|
||||
* item requires combination: check the status of the combination
|
||||
A combination requires 3 elements to fulfill:
|
||||
1/ a verb action
|
||||
2/ a first "tool" (item to use)
|
||||
3/ a second "tool" (item to use ON)
|
||||
Whatever the user inputs to fulfill the combination (this is
|
||||
determined by gamedev in his game.gd script)
|
||||
- combination not fulfilled: no not perform until fulfilled
|
||||
- combination fulfilled: perform the combination.
|
||||
* else do nothing, except if default_action is requested.
|
||||
In this case, perform the default_action on the item.
|
||||
"""
|
||||
|
||||
escoria.logger.info(
|
||||
self,
|
||||
"%s to perform event %s." % [obj.global_id, event]
|
||||
)
|
||||
|
||||
# Don't interact after player movement towards object
|
||||
# (because object is inactive for example)
|
||||
var dont_interact = false
|
||||
|
||||
# We need to have the new action input state BEFORE initiating the player
|
||||
# move so we determine now if the object clicked will require a combination
|
||||
# depending on the used action verb.
|
||||
var tool_just_set = _set_tool_and_action(obj, default_action)
|
||||
# MODIFIED FOR RETURN TO MONKEY UI
|
||||
var need_combine = _check_item_needs_combine_obj(obj)
|
||||
|
||||
# If the current tool was not set, this is our first item, make it the tool
|
||||
if not current_tool or (current_tool and not need_combine):
|
||||
current_tool = obj
|
||||
# Else, if we have a tool and combination required, this is our second item,
|
||||
# make it the target.
|
||||
elif need_combine and not tool_just_set:
|
||||
current_target = obj
|
||||
|
||||
# Update the action input state
|
||||
if action_state == ACTION_INPUT_STATE.AWAITING_TARGET_ITEM and current_target:
|
||||
set_action_input_state(ACTION_INPUT_STATE.COMPLETED)
|
||||
elif action_state == ACTION_INPUT_STATE.AWAITING_ITEM and \
|
||||
not need_combine:
|
||||
set_action_input_state(ACTION_INPUT_STATE.COMPLETED)
|
||||
elif action_state == ACTION_INPUT_STATE.AWAITING_ITEM and need_combine and not tool_just_set:
|
||||
set_action_input_state(ACTION_INPUT_STATE.AWAITING_TARGET_ITEM)
|
||||
|
||||
var event_to_queue: ESCEvent = null
|
||||
|
||||
# Manage exits
|
||||
if obj.node.is_exit and current_action in ["", ACTION_WALK]:
|
||||
event_to_queue = _get_event_to_queue(ACTION_EXIT_SCENE, obj)
|
||||
else:
|
||||
# Manage movements towards object before activating it
|
||||
if current_action in ["", ACTION_WALK] and \
|
||||
not escoria.inventory_manager.inventory_has(obj.global_id):
|
||||
event_to_queue = _get_event_to_queue(ACTION_ARRIVED, obj)
|
||||
# Manage action on object
|
||||
elif not current_action in ["", ACTION_WALK]:
|
||||
if need_combine and current_target:
|
||||
event_to_queue = _get_event_to_queue(
|
||||
current_action,
|
||||
current_tool,
|
||||
current_target
|
||||
)
|
||||
else:
|
||||
if need_combine:
|
||||
# We're missing a target here for our tool to be used on
|
||||
current_tool = obj
|
||||
set_action_input_state(
|
||||
ACTION_INPUT_STATE.AWAITING_TARGET_ITEM
|
||||
)
|
||||
|
||||
# We need to wait for that target
|
||||
return
|
||||
else:
|
||||
event_to_queue = _get_event_to_queue(
|
||||
current_action,
|
||||
obj
|
||||
)
|
||||
|
||||
# Get out of here if there's a specified action but an event couldn't be found.
|
||||
# Note that `event_to_queue` may still be null, but we do need to start the
|
||||
# player walking towards the destination.
|
||||
if current_action and not event_to_queue:
|
||||
clear_current_action()
|
||||
emit_signal("action_finished")
|
||||
return
|
||||
|
||||
var event_flags = event_to_queue.flags if event_to_queue else 0
|
||||
|
||||
if escoria.main.current_scene.player:
|
||||
var destination_position: Vector2 = escoria.main.current_scene.player \
|
||||
.global_position
|
||||
|
||||
# If clicked object not in inventory, player walks towards it
|
||||
if not obj.node is ESCPlayer and \
|
||||
not escoria.inventory_manager.inventory_has(obj.global_id) and \
|
||||
not event_flags & ESCEvent.FLAG_TK:
|
||||
var context = _walk_towards_object(
|
||||
obj,
|
||||
event.position,
|
||||
event.doubleclick
|
||||
)
|
||||
|
||||
if context is GDScriptFunctionState:
|
||||
context = yield(context, "completed")
|
||||
|
||||
# In case of an interrupted walk, we don't want to proceed.
|
||||
if context == null:
|
||||
return
|
||||
|
||||
destination_position = context.target_position
|
||||
dont_interact = context.dont_interact_on_arrival
|
||||
|
||||
var player_global_pos = escoria.main.current_scene.player.global_position
|
||||
# var clicked_position = event.position
|
||||
|
||||
# Using this instead of is_equal_approx due to
|
||||
# https://github.com/godotengine/godot/issues/65257
|
||||
if (player_global_pos - destination_position).length() > 1:
|
||||
dont_interact = true
|
||||
escoria.logger.info(
|
||||
self,
|
||||
"Player could not reach destination coordinates %s. " % str(destination_position) \
|
||||
+ "Any requested action for %s will not fire." % obj.global_id
|
||||
)
|
||||
if escoria.event_manager.EVENT_CANT_REACH in obj.events:
|
||||
escoria.event_manager.queue_event(obj.events[escoria.event_manager.EVENT_CANT_REACH])
|
||||
else:
|
||||
escoria.logger.info(
|
||||
self,
|
||||
"%s event not found for object %s so nothing to do." % \
|
||||
[escoria.event_manager.EVENT_CANT_REACH, obj.global_id]
|
||||
)
|
||||
|
||||
# If no interaction should happen after player has arrived, leave
|
||||
# immediately.
|
||||
if not dont_interact and event_to_queue:
|
||||
_run_event(event_to_queue)
|
||||
|
||||
# Prepare the "obj" object for current_action: if required, set the object as
|
||||
# current tool.
|
||||
#
|
||||
# #### Parameters
|
||||
#
|
||||
# - obj: the ESCObject to prepare
|
||||
# - default_action: if true, the default action set on the item is used
|
||||
#
|
||||
# *Returns* True if the tool was set in this function
|
||||
func _set_tool_and_action(obj: ESCObject, default_action: bool):
|
||||
var tool_just_set: bool = false
|
||||
# Check if current_action and current_tool are already set
|
||||
if current_action and current_tool:
|
||||
# MODIFIED FOR RETURN TO MONKEY UI
|
||||
if (not current_action in escoria.action_manager\
|
||||
.current_tool.node.combine_when_selected_action_is_in and not current_action in obj.node.target_when_selected_action_is_in):
|
||||
current_tool = obj
|
||||
tool_just_set = true
|
||||
elif default_action:
|
||||
if escoria.inventory_manager.inventory_has(obj.global_id):
|
||||
current_action = obj.node.default_action_inventory
|
||||
else:
|
||||
current_action = obj.node.default_action
|
||||
elif current_action in obj.node.combine_when_selected_action_is_in:
|
||||
current_tool = obj
|
||||
tool_just_set = true
|
||||
return tool_just_set
|
||||
|
||||
|
||||
# Checks if object requires a combination with another, according to
|
||||
# currently selected action verb (or check with default action of the item).
|
||||
#
|
||||
# *Returns* True if current action on "obj" requires a combination
|
||||
# MODIFIED FOR RETURN TO MONKEY UI
|
||||
func _check_item_needs_combine_obj(obj: ESCObject) -> bool:
|
||||
return current_action \
|
||||
and current_tool \
|
||||
and (current_action in current_tool.node.combine_when_selected_action_is_in
|
||||
# MODIFIED FOR RETURN TO MONKEY UI
|
||||
or current_action in obj.node.target_when_selected_action_is_in)
|
||||
|
||||
|
||||
func has_actions(current_target_object):
|
||||
if(current_target_object == null):
|
||||
return
|
||||
|
||||
var item_in_inventory = escoria.inventory_manager.inventory_has(current_target_object.global_id)
|
||||
var waiting_for_target_item = escoria.action_manager.action_state == ESCActionManager.ACTION_INPUT_STATE.AWAITING_TARGET_ITEM
|
||||
|
||||
var action1_text = get_action_target_text(current_target_object.action3_target_texts) if waiting_for_target_item else get_tooltip_from_current_target("action3",current_target_object) if item_in_inventory else get_tooltip_from_current_target("action1",current_target_object)
|
||||
if(action1_text != ""):
|
||||
return true
|
||||
|
||||
var action2_text = get_action_target_text(current_target_object.action4_target_texts) if waiting_for_target_item else get_tooltip_from_current_target("action4",current_target_object) if item_in_inventory else get_tooltip_from_current_target("action2",current_target_object)
|
||||
if(action2_text != ""):
|
||||
return true
|
||||
return false
|
||||
|
||||
func get_tooltip_from_current_target(verb,current_target_object):
|
||||
var tooltips = current_target_object.get('tooltips')
|
||||
if(tooltips.has(verb)):
|
||||
return tooltips.get(verb)
|
||||
return ""
|
||||
func get_action_target_text(action_target_texts: Dictionary):
|
||||
var action_target_text = action_target_texts.get(escoria.action_manager.current_tool.global_id)
|
||||
return action_target_text if action_target_text else ""
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
# A manager for inventory objects
|
||||
extends Resource
|
||||
class_name ESCItemCountManager
|
||||
|
||||
|
||||
func add(global_id: String, value:= 1) -> void:
|
||||
var item = get_item(global_id)
|
||||
set(global_id, item.count + value)
|
||||
|
||||
|
||||
func remove(global_id: String, value:= 1) -> void:
|
||||
var item = get_item(global_id)
|
||||
set(global_id, item.count - value)
|
||||
|
||||
|
||||
func set(global_id: String, value: int) -> void:
|
||||
var item = get_item(global_id)
|
||||
item.count = value
|
||||
escoria.globals_manager.set_global("count/%s" % global_id, value)
|
||||
updateSprite(item)
|
||||
|
||||
|
||||
func removeFromInventoryIfCountLessThan(global_id: String, value:= 1) -> void:
|
||||
var item = get_item(global_id)
|
||||
if item.count < value:
|
||||
escoria.inventory_manager.remove_item(global_id)
|
||||
|
||||
|
||||
func get_item(global_id: String) -> ESCItem:
|
||||
var node = escoria.object_manager.get_object(global_id).node
|
||||
if not node is ESCItem:
|
||||
escoria.logger.error(
|
||||
"item_count_add: invalid object",
|
||||
["Object is not an ESCItem"]
|
||||
)
|
||||
return null
|
||||
|
||||
return node
|
||||
|
||||
|
||||
func updateSprite(item: ESCItemWithTooltip) -> void:
|
||||
var child_node = item.get_node("Sprite") as Sprite
|
||||
if not child_node is Sprite:
|
||||
escoria.logger.error(
|
||||
self,
|
||||
"No Sprite node found"
|
||||
)
|
||||
|
||||
var texture_path = getCountTexturePath(item)
|
||||
var texture = load(texture_path)
|
||||
|
||||
# Update texture in scene
|
||||
var sprite = child_node as Sprite
|
||||
sprite.texture = texture
|
||||
|
||||
# Update texture in scene
|
||||
# TODO optional inventory_texture
|
||||
# TODO change inventory texture without removing and adding the item
|
||||
# https://github.com/godot-escoria/escoria-issues/issues/364
|
||||
# https://discord.com/channels/884336424780984330/1124614097917460584/1127151969614696548
|
||||
item.inventory_texture = texture
|
||||
if escoria.inventory_manager.inventory_has(item.global_id):
|
||||
escoria.inventory_manager.remove_item(item.global_id)
|
||||
escoria.inventory_manager.add_item(item.global_id)
|
||||
|
||||
|
||||
func getCountTexturePath(item: ESCItemWithTooltip) -> String:
|
||||
var count = item.count
|
||||
var textures = item.count_textures # TODO sort dictionaries by start key
|
||||
var i = 0
|
||||
|
||||
while (i < textures.size() - 1) and count >= textures[i + 1].start:
|
||||
i = i + 1
|
||||
|
||||
return textures[i].texture
|
||||
@@ -0,0 +1,72 @@
|
||||
tool
|
||||
extends ESCItem
|
||||
class_name ESCItemWithTooltip, "res://addons/escoria-core/design/esc_item.svg"
|
||||
|
||||
# Action 1 Label text
|
||||
export(String) var action1_text = ""
|
||||
|
||||
# Action 2 Label text
|
||||
export(String) var action2_text = ""
|
||||
|
||||
# Action 3 tooltip text if item in inventory
|
||||
export(String) var action3_text = ""
|
||||
|
||||
# Action 4 tooltip text if item in inventory
|
||||
export(String) var action4_text = ""
|
||||
|
||||
export(Dictionary) var tooltips = {}
|
||||
|
||||
# Action 3 tooltip texts if item is target. Dictionary with tool's global id as key.
|
||||
export(Dictionary) var action3_target_texts = {}
|
||||
|
||||
# Action 4 tooltip texts if item is target. Dictionary with tool's global id as key
|
||||
export(Dictionary) var action4_target_texts = {}
|
||||
|
||||
# If action used by player is in this list, this is a valid target (second item in combination)
|
||||
export(Array) var target_when_selected_action_is_in = []
|
||||
|
||||
# If item is countable (E.g. money) marks the quantity
|
||||
export(int) var count = 0
|
||||
|
||||
# ESCItemComponents children of this node
|
||||
var components: Dictionary = {}
|
||||
|
||||
var custom_data: Dictionary = {}
|
||||
|
||||
# If item is countable (E.g. money) marks which texture to use depending of count value.
|
||||
# Each element is a Dictionary with start and texture keys:
|
||||
# [
|
||||
# { "start": 0, "texture": "res://gymkhana/items/inventory/assets/no_money.png"},
|
||||
# { "start": 1, "texture": "res://gymkhana/items/inventory/assets/one_coin.png"},
|
||||
# { "start": 2, "texture": "res://gymkhana/items/inventory/assets/two_coins.png"},
|
||||
# { "start": 3, "texture": "res://gymkhana/items/inventory/assets/coins.png"},
|
||||
# { "start": 10, "texture": "res://gymkhana/items/inventory/assets/bills.png"},
|
||||
# ]
|
||||
export(Array) var count_textures = []
|
||||
|
||||
|
||||
func _ready():
|
||||
register_components()
|
||||
|
||||
func set_tooltip(action: String, text: String):
|
||||
tooltips[action] = text
|
||||
|
||||
func has_component(key: String)->bool:
|
||||
return components.has(key)
|
||||
|
||||
func get_component(key: String):
|
||||
if(has_component(key)):
|
||||
return components[key]
|
||||
return null
|
||||
|
||||
func register_components():
|
||||
autoload_components()
|
||||
for child in get_children():
|
||||
if(child is ESCItemComponent):
|
||||
child = child as ESCItemComponent
|
||||
components[child.get_component_type()] = child
|
||||
child.register(custom_data)
|
||||
|
||||
func autoload_components():
|
||||
add_child(ESCItemComponentOutline.new())
|
||||
add_child(ESCItemComponentInventoryChecker.new())
|
||||
@@ -0,0 +1,23 @@
|
||||
tool
|
||||
extends ESCItemWithTooltip
|
||||
class_name ESCPlayerWithTooltip, "res://addons/escoria-core/design/esc_player.svg"
|
||||
|
||||
# Whether the player can be selected like an item
|
||||
export(bool) var selectable = false
|
||||
|
||||
|
||||
# A player is always movable
|
||||
func _init():
|
||||
._init()
|
||||
is_movable = true
|
||||
_force_registration = true
|
||||
|
||||
|
||||
|
||||
# Ready function
|
||||
func _ready():
|
||||
if selectable:
|
||||
._ready()
|
||||
else:
|
||||
tooltip_name = ""
|
||||
|
||||
309
addons/escoria-ui-return-monkey-island/esc_rich_tooltip.gd
Normal file
@@ -0,0 +1,309 @@
|
||||
# A tooltip displaying <verb> <item1> [<item2>]
|
||||
tool
|
||||
extends Node2D
|
||||
class_name ESCRichTooltip
|
||||
|
||||
|
||||
# Maximum width of the label
|
||||
const MAX_WIDTH = 200
|
||||
|
||||
# Minimum height of the label
|
||||
const MIN_HEIGHT = 30
|
||||
|
||||
# Maximum height of the label
|
||||
const MAX_HEIGHT = 500
|
||||
|
||||
# Height of one line in the label
|
||||
const ONE_LINE_HEIGHT = 16
|
||||
|
||||
|
||||
# Color of the label
|
||||
export(Color) var color setget set_color
|
||||
|
||||
# Vector2 defining the offset from the cursor
|
||||
export(Vector2) var offset_from_cursor_action1 = Vector2(0,3)
|
||||
|
||||
export(Vector2) var offset_from_cursor_action2 = Vector2(0,-2)
|
||||
|
||||
export(Vector2) var offset_from_cursor_action3 = Vector2(0,3)
|
||||
|
||||
export(Vector2) var offset_from_cursor_action4 = Vector2(0,-2)
|
||||
|
||||
# Activates debug mode. If enabled, shows the label with a white background.
|
||||
export(bool) var debug_mode = false setget set_debug_mode
|
||||
|
||||
# Infinitive verb
|
||||
var current_action: String
|
||||
|
||||
# Target item/hotspot
|
||||
var current_target: String setget set_target
|
||||
|
||||
var current_target_object: Object = null setget set_target_object
|
||||
|
||||
# Preposition: on, with...
|
||||
var current_prep: String = "with"
|
||||
|
||||
# Target 2 item/hotspot
|
||||
var current_target2: String
|
||||
|
||||
var current_size: Vector2 = Vector2(0,0) setget _set_current_size
|
||||
|
||||
# True if tooltip is waiting for a click on second target (use x with y)
|
||||
var waiting_for_target2 = false
|
||||
|
||||
# Node containing the debug white background
|
||||
var debug_texturerect_node: TextureRect
|
||||
|
||||
# Indicates whether the current room is loaded and ready
|
||||
var _room_is_ready: bool = false
|
||||
|
||||
# Tooltips are hidden
|
||||
var hidden: bool = false
|
||||
|
||||
signal tooltip_size_updated
|
||||
|
||||
# Connect relevant functions
|
||||
func _ready():
|
||||
if escoria.main.connect("room_ready", self, "_on_room_ready") != 0:
|
||||
escoria.logger.error(self, "Error connecting room_ready with _on_room_ready")
|
||||
|
||||
if escoria.action_manager.connect("action_changed", self, "_on_action_selected") != 0:
|
||||
escoria.logger.error(self, "Error connecting action_changed with _on_action_selected")
|
||||
|
||||
|
||||
# Set the color of the label
|
||||
#
|
||||
# ## Parameters
|
||||
# - p_color: the color to set the label
|
||||
func set_color(p_color: Color):
|
||||
color = p_color
|
||||
if _room_is_ready:
|
||||
update_tooltip_text()
|
||||
|
||||
|
||||
# Enable/disable debug mode of the label. If enabled, the label is displayed
|
||||
# with a white background.
|
||||
#
|
||||
# ## Parameters
|
||||
# - p_debug_mode: if true, enable debug mode. False to disable
|
||||
func set_debug_mode(p_debug_mode: bool):
|
||||
debug_mode = p_debug_mode
|
||||
if debug_mode:
|
||||
# Add a white TextureRect behind the RTL to see its actual size
|
||||
debug_texturerect_node = TextureRect.new()
|
||||
add_child(debug_texturerect_node)
|
||||
debug_texturerect_node.texture = load("res://addons/escoria-core/game/assets/images/white.png")
|
||||
debug_texturerect_node.expand = true
|
||||
debug_texturerect_node.stretch_mode = TextureRect.STRETCH_TILE
|
||||
#debug_texturerect_node.size_flags_horizontal = SIZE_EXPAND_FILL
|
||||
#debug_texturerect_node.size_flags_vertical = SIZE_EXPAND_FILL
|
||||
debug_texturerect_node.show_behind_parent = true
|
||||
debug_texturerect_node.anchor_right = 1.0
|
||||
debug_texturerect_node.anchor_bottom = 1.0
|
||||
debug_texturerect_node.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
move_child(debug_texturerect_node, 2)
|
||||
else:
|
||||
if debug_texturerect_node:
|
||||
remove_child(debug_texturerect_node)
|
||||
debug_texturerect_node.queue_free()
|
||||
|
||||
func set_target_object(target: Object, needs_second_target: bool = false) -> void:
|
||||
current_target_object = target
|
||||
waiting_for_target2 = needs_second_target
|
||||
if _room_is_ready:
|
||||
if(target == null):
|
||||
hide()
|
||||
return
|
||||
# show()
|
||||
update_tooltip_text()
|
||||
|
||||
|
||||
# Set the first target of the label.
|
||||
#
|
||||
# ## Parameters
|
||||
# - target: String the target to add to the label
|
||||
# - needs_second_target: if true, the label will prepare for a second target
|
||||
func set_target(target: String, needs_second_target: bool = false) -> void:
|
||||
current_target = target
|
||||
waiting_for_target2 = needs_second_target
|
||||
if _room_is_ready:
|
||||
if(target == ""):
|
||||
hide()
|
||||
return
|
||||
update_tooltip_text()
|
||||
# show()
|
||||
|
||||
|
||||
# Set the second target of the label
|
||||
#
|
||||
# ## Parameters
|
||||
# - target2: String the second target to add to the label
|
||||
func set_target2(target2: String) -> void:
|
||||
current_target2 = target2
|
||||
if _room_is_ready:
|
||||
if(target2 == ""):
|
||||
hide()
|
||||
return
|
||||
update_tooltip_text()
|
||||
# show()
|
||||
|
||||
|
||||
# Update the tooltip text.
|
||||
# * If waiting for target item: get text from action*_target_texts dictionaries using current_tool as key
|
||||
# * If item is in inventory: use action3_text and action4_text variables
|
||||
# * Else: use action1_text and action2_text variables
|
||||
func update_tooltip_text():
|
||||
if(current_target_object == null):
|
||||
return
|
||||
|
||||
var action1_text = "";
|
||||
var action2_text = "";
|
||||
|
||||
if current_target_object.is_interactive and escoria.current_state == escoria.GAME_STATE.DEFAULT:
|
||||
var item_in_inventory = escoria.inventory_manager.inventory_has(current_target_object.global_id)
|
||||
var waiting_for_target_item = escoria.action_manager.action_state == ESCActionManager.ACTION_INPUT_STATE.AWAITING_TARGET_ITEM
|
||||
|
||||
action1_text = get_action_target_text(current_target_object.action3_target_texts) if waiting_for_target_item else get_tooltip_from_current_target("action3") if item_in_inventory else get_tooltip_from_current_target("action1")
|
||||
action2_text = get_action_target_text(current_target_object.action4_target_texts) if waiting_for_target_item else get_tooltip_from_current_target("action4") if item_in_inventory else get_tooltip_from_current_target("action2")
|
||||
|
||||
$tooltip1/label.text = action1_text
|
||||
$tooltip1.visible = !hidden and action1_text != "";
|
||||
$tooltip2/label.text = action2_text
|
||||
$tooltip2.visible = !hidden and action2_text != "";
|
||||
|
||||
func get_tooltip_from_current_target(verb):
|
||||
var tooltips = current_target_object.get('tooltips')
|
||||
if(tooltips.has(verb)):
|
||||
return tooltips.get(verb)
|
||||
return ""
|
||||
func get_action_target_text(action_target_texts: Dictionary):
|
||||
var action_target_text = action_target_texts.get(escoria.action_manager.current_tool.global_id)
|
||||
return action_target_text if action_target_text else ""
|
||||
|
||||
# Update the tooltip size according to the text.
|
||||
func update_size():
|
||||
if not get_tree():
|
||||
# We're not in the tree anymore. Return
|
||||
return
|
||||
current_size = $tooltip1/label.get_font("normal_font").get_string_size(current_target)
|
||||
|
||||
func get_tooltip1_size():
|
||||
if not get_tree():
|
||||
# We're not in the tree anymore. Return
|
||||
return
|
||||
return Vector2(150,20);
|
||||
# escoria.logger.info(self, "get_string_size: " + String($tooltip1/label.get_font("normal_font").get_string_size(current_target)))
|
||||
#return $tooltip1/label.get_font("normal_font").get_string_size(current_target)
|
||||
|
||||
func get_tooltip2_size():
|
||||
if not get_tree():
|
||||
# We're not in the tree anymore. Return
|
||||
return
|
||||
return Vector2(150,20);
|
||||
#return $tooltip2/label.get_font("normal_font").get_string_size(current_target)
|
||||
|
||||
# Calculate the offset of the label depending on its position.
|
||||
#
|
||||
# ## Parameters
|
||||
# - position: the position to test
|
||||
#
|
||||
# **Return**
|
||||
# The calculated offset
|
||||
func _offset(position: Vector2) -> Vector2:
|
||||
#var center_offset_x = current_size.x / 2
|
||||
#var offset_y = 5
|
||||
|
||||
#position.x -= center_offset_x
|
||||
#position.y += offset_y
|
||||
|
||||
return position
|
||||
|
||||
|
||||
# Return the tooltip distance to top edge.
|
||||
#
|
||||
# ## Parameters
|
||||
# - position: the position to test
|
||||
#
|
||||
# **Return**
|
||||
# The distance to the edge.
|
||||
func tooltip_distance_to_edge_top(position: Vector2):
|
||||
return position.y
|
||||
|
||||
|
||||
# Return the tooltip distance to bottom edge.
|
||||
#
|
||||
# ## Parameters
|
||||
# - position: the position to test
|
||||
#
|
||||
# **Return**
|
||||
# The distance to the edge.
|
||||
func tooltip_distance_to_edge_bottom(position: Vector2):
|
||||
return escoria.game_size.y - position.y
|
||||
|
||||
|
||||
# Return the tooltip distance to left edge.
|
||||
#
|
||||
# ## Parameters
|
||||
# - position: the position to test
|
||||
#
|
||||
# **Return**
|
||||
# The distance to the edge.
|
||||
func tooltip_distance_to_edge_left(position: Vector2):
|
||||
return position.x
|
||||
|
||||
|
||||
# Return the tooltip distance to right edge.
|
||||
#
|
||||
# ## Parameters
|
||||
# - position: the position to test
|
||||
#
|
||||
# **Return**
|
||||
# The distance to the edge.
|
||||
func tooltip_distance_to_edge_right(position: Vector2):
|
||||
return escoria.game_size.x - position.x
|
||||
|
||||
func show():
|
||||
escoria.logger.info(self, "show")
|
||||
hidden = false
|
||||
update_tooltip_text()
|
||||
# if _room_is_ready:
|
||||
# $tooltip1.visible = true;
|
||||
# $tooltip2.visible = true;
|
||||
#$icon.visible = true;
|
||||
#$label.visible = true;
|
||||
#$background.visible = true;
|
||||
|
||||
func hide():
|
||||
if _room_is_ready:
|
||||
$tooltip1.visible = false;
|
||||
$tooltip2.visible = false;
|
||||
#$icon.visible = false;
|
||||
#$label.visible = false;
|
||||
#$background.visible = false;
|
||||
|
||||
func setHidden():
|
||||
hidden = true
|
||||
hide()
|
||||
|
||||
# Clear the tooltip targets texts
|
||||
func clear():
|
||||
waiting_for_target2 = false
|
||||
set_target("")
|
||||
set_target2("")
|
||||
|
||||
func _set_current_size(size: Vector2):
|
||||
current_size = size
|
||||
|
||||
# Called when the room is loaded to setup the label.
|
||||
func _on_room_ready():
|
||||
escoria.main.current_scene.game.tooltip_node = self
|
||||
_room_is_ready = true
|
||||
|
||||
|
||||
# Called when an action is selected in Escoria
|
||||
func _on_action_selected() -> void:
|
||||
current_action = escoria.action_manager.current_action
|
||||
|
||||
if _room_is_ready:
|
||||
update_tooltip_text()
|
||||
hide()
|
||||
41
addons/escoria-ui-return-monkey-island/esc_rich_tooltip.tscn
Normal file
@@ -0,0 +1,41 @@
|
||||
[gd_scene load_steps=5 format=2]
|
||||
|
||||
[ext_resource path="res://gymkhana/addons/escoria-ui-return-monkey-island/esc_rich_tooltip.gd" type="Script" id=1]
|
||||
[ext_resource path="res://gymkhana/addons/escoria-ui-return-monkey-island/cursors/rounded_mouse_right.png" type="Texture" id=2]
|
||||
[ext_resource path="res://gymkhana/addons/escoria-ui-return-monkey-island/cursors/rounded_mouse_left.png" type="Texture" id=3]
|
||||
[ext_resource path="res://gymkhana/addons/escoria-ui-return-monkey-island/theme.tres" type="Theme" id=4]
|
||||
|
||||
[node name="tooltipManager" type="Node2D"]
|
||||
script = ExtResource( 1 )
|
||||
|
||||
[node name="tooltip1" type="Node2D" parent="."]
|
||||
visible = false
|
||||
|
||||
[node name="label" type="Label" parent="tooltip1"]
|
||||
margin_left = 9.0
|
||||
margin_top = -6.0
|
||||
margin_right = 119.0
|
||||
margin_bottom = 8.0
|
||||
theme = ExtResource( 4 )
|
||||
text = "Text place holder"
|
||||
|
||||
[node name="icon" type="Sprite" parent="tooltip1"]
|
||||
position = Vector2( 1, 8 )
|
||||
scale = Vector2( 0.583333, 0.583333 )
|
||||
texture = ExtResource( 3 )
|
||||
|
||||
[node name="tooltip2" type="Node2D" parent="."]
|
||||
visible = false
|
||||
|
||||
[node name="label" type="Label" parent="tooltip2"]
|
||||
margin_left = 9.0
|
||||
margin_top = 35.0
|
||||
margin_right = 144.0
|
||||
margin_bottom = 64.0
|
||||
theme = ExtResource( 4 )
|
||||
text = "Text place holder"
|
||||
|
||||
[node name="icon" type="Sprite" parent="tooltip2"]
|
||||
position = Vector2( 1, 49.5 )
|
||||
scale = Vector2( 0.583333, 0.583333 )
|
||||
texture = ExtResource( 2 )
|
||||
@@ -0,0 +1,7 @@
|
||||
[gd_resource type="DynamicFont" load_steps=2 format=2]
|
||||
|
||||
[ext_resource path="res://gymkhana/addons/escoria-ui-return-monkey-island/fonts/caslonantique.ttf" type="DynamicFontData" id=1]
|
||||
|
||||
[resource]
|
||||
size = 21
|
||||
font_data = ExtResource( 1 )
|
||||
BIN
addons/escoria-ui-return-monkey-island/fonts/caslonantique.ttf
Executable file
517
addons/escoria-ui-return-monkey-island/game.gd
Normal file
@@ -0,0 +1,517 @@
|
||||
extends ESCGame
|
||||
|
||||
# Left mouse button on item
|
||||
const ACTION1 = "action1"
|
||||
# Right mouse button on item
|
||||
const ACTION2 = "action2"
|
||||
# Left mouse button on inventory item
|
||||
const ACTION3 = "action3"
|
||||
# Right mouse button on inventory item
|
||||
const ACTION4 = "action4"
|
||||
|
||||
const VERB_USE = "use"
|
||||
const VERB_WALK = "walk"
|
||||
|
||||
|
||||
"""
|
||||
Implement methods to react to inputs.
|
||||
|
||||
- left_click_on_bg(position: Vector2)
|
||||
- right_click_on_bg(position: Vector2)
|
||||
- left_double_click_on_bg(position: Vector2)
|
||||
|
||||
- element_focused(element_id: String)
|
||||
- element_unfocused()
|
||||
|
||||
- left_click_on_item(item_global_id: String, event: InputEvent)
|
||||
- right_click_on_item(item_global_id: String, event: InputEvent)
|
||||
- left_double_click_on_item(item_global_id: String, event: InputEvent)
|
||||
|
||||
- left_click_on_inventory_item(inventory_item_global_id: String, event: InputEvent)
|
||||
- right_click_on_inventory_item(inventory_item_global_id: String, event: InputEvent)
|
||||
- left_double_click_on_inventory_item(inventory_item_global_id: String, event: InputEvent)
|
||||
- inventory_item_focused(inventory_item_global_id: String)
|
||||
- inventory_item_unfocused()
|
||||
- open_inventory()
|
||||
- close_inventory()
|
||||
|
||||
- mousewheel_action(direction: int)
|
||||
|
||||
- hide_ui()
|
||||
- show_ui()
|
||||
|
||||
- pause_game()
|
||||
- unpause_game()
|
||||
- show_main_menu()
|
||||
- hide_main_menu()
|
||||
|
||||
- apply_custom_settings()
|
||||
|
||||
- _on_event_done(event_name: String)
|
||||
"""
|
||||
|
||||
# Value to use for `device` argument to various `Input.get_joy` methods.
|
||||
const JOY_DEVICE = 0
|
||||
|
||||
# See https://docs.godotengine.org/en/stable/tutorials/inputs/controllers_gamepads_joysticks.html?#dead-zone
|
||||
const DEADZONE = 0.2
|
||||
|
||||
# Multiplier to apply to axis when it exceeds DEADZONE.
|
||||
const AXIS_WEIGHT = 50.0
|
||||
|
||||
# JOY_BUTTON_2 corresponds to the "X" button on an XBox controller
|
||||
# or the Square button on a Playstation controller. These appear to
|
||||
# map to the "primary action," in practice, so we treat it like a left click.
|
||||
const PRIMARY_ACTION_BUTTON = JOY_BUTTON_2
|
||||
|
||||
# JOY_BUTTON_3 corresponds to the "Y" button on an XBox controller
|
||||
# or the Triangle button on a Playstation controller. These appear to
|
||||
# map to the "secondary action," in practice, so we treat it like a right click.
|
||||
const CHANGE_VERB_BUTTON = JOY_BUTTON_3
|
||||
|
||||
# Input action for use by InputMap
|
||||
const ESC_UI_CHANGE_VERB_ACTION = "esc_change_verb"
|
||||
|
||||
# true when a gamepad is connected.
|
||||
var _is_gamepad_connected = false
|
||||
|
||||
# Tracks the mouse's current position onscreen.
|
||||
var _current_mouse_pos = Vector2.ZERO
|
||||
|
||||
# A reference to the node handling tooltip2
|
||||
var tooltip2_node: Object
|
||||
var last_target: Object
|
||||
|
||||
var video_player: Object
|
||||
|
||||
func _ready():
|
||||
# We need a slightly modified version of Action Manager to combine items with different actions.
|
||||
escoria.action_manager = ESCActionManagerMonkey.new()
|
||||
|
||||
if $tooltip_layer/tooltip.connect("tooltip_size_updated", self, "update_tooltip_following_mouse_position", [tooltip_node]) != 0:
|
||||
escoria.logger.error(self, "Error connecting tooltip_size_updated with update_tooltip_following_mouse_position")
|
||||
# We get current day and month
|
||||
var time = OS.get_datetime()
|
||||
var day = time["day"]
|
||||
var month = time["month"]
|
||||
if( day == 8 and month ==2 ):
|
||||
escoria.globals_manager.set_global('zorionak_eneko', true)
|
||||
|
||||
|
||||
|
||||
func _enter_tree():
|
||||
var room_selector_parent = $CanvasLayer/ui/menu_button/HBoxContainer
|
||||
|
||||
if ESCProjectSettingsManager.get_setting(ESCProjectSettingsManager.ENABLE_ROOM_SELECTOR) \
|
||||
and room_selector_parent.get_node_or_null("room_select") == null:
|
||||
|
||||
room_selector_parent.add_child(
|
||||
preload(
|
||||
"res://addons/escoria-core/ui_library/tools/room_select" +\
|
||||
"/room_select.tscn"
|
||||
).instance()
|
||||
)
|
||||
var room_selector = room_selector_parent.get_node_or_null("room_select")
|
||||
if(room_selector != null):
|
||||
room_selector.visible = false
|
||||
|
||||
|
||||
var input_handler = funcref(self, "_process_input")
|
||||
escoria.inputs_manager.register_custom_input_handler(input_handler)
|
||||
|
||||
_is_gamepad_connected = Input.is_joy_known(JOY_DEVICE)
|
||||
if _is_gamepad_connected:
|
||||
_on_gamepad_connected()
|
||||
|
||||
if Input.connect("joy_connection_changed", self, "_on_joy_connection_changed") != 0:
|
||||
escoria.logger.error(self, "Error connecting joy_connection_changed")
|
||||
|
||||
|
||||
func _exit_tree():
|
||||
escoria.inputs_manager.register_custom_input_handler(null)
|
||||
Input.disconnect("joy_connection_changed", self, "_on_joy_connection_changed")
|
||||
if _is_gamepad_connected:
|
||||
_on_gamepad_disconnected()
|
||||
|
||||
|
||||
func toggle_room_selector_visibility():
|
||||
var room_selector_parent = $CanvasLayer/ui/menu_button/VBoxContainer
|
||||
var room_selector = room_selector_parent.get_node_or_null("room_select")
|
||||
if(room_selector != null):
|
||||
room_selector.visible = !room_selector.visible
|
||||
|
||||
|
||||
func _input(event: InputEvent) -> void:
|
||||
if escoria.get_escoria().is_ready_for_inputs():
|
||||
if event.is_action_pressed("ui_show_room_selector"):
|
||||
toggle_room_selector_visibility()
|
||||
|
||||
if event is InputEventMouseMotion:
|
||||
#_current_mouse_pos = get_global_mouse_position() # Escoria core
|
||||
_current_mouse_pos = get_viewport().get_mouse_position()
|
||||
update_tooltip_following_mouse_position(tooltip_node)
|
||||
update_tooltip_following_mouse_position(tooltip2_node)
|
||||
|
||||
|
||||
|
||||
# https://github.com/godotengine/godot-demo-projects/blob/3.4-585455e/misc/joypads/joypads.gd
|
||||
# was informative in wiring up the gamepad properly.
|
||||
|
||||
func _on_gamepad_connected():
|
||||
set_physics_process(true)
|
||||
|
||||
var primary_event = InputEventJoypadButton.new()
|
||||
primary_event.button_index = PRIMARY_ACTION_BUTTON
|
||||
InputMap.add_action(escoria.inputs_manager.ESC_UI_PRIMARY_ACTION)
|
||||
InputMap.action_add_event(escoria.inputs_manager.ESC_UI_PRIMARY_ACTION, primary_event)
|
||||
|
||||
var verb_event = InputEventJoypadButton.new()
|
||||
verb_event.button_index = CHANGE_VERB_BUTTON
|
||||
InputMap.add_action(ESC_UI_CHANGE_VERB_ACTION)
|
||||
InputMap.action_add_event(ESC_UI_CHANGE_VERB_ACTION, verb_event)
|
||||
|
||||
|
||||
func _on_gamepad_disconnected():
|
||||
InputMap.action_erase_events(escoria.inputs_manager.ESC_UI_PRIMARY_ACTION)
|
||||
InputMap.erase_action(escoria.inputs_manager.ESC_UI_PRIMARY_ACTION)
|
||||
|
||||
InputMap.action_erase_events(ESC_UI_CHANGE_VERB_ACTION)
|
||||
InputMap.erase_action(ESC_UI_CHANGE_VERB_ACTION)
|
||||
|
||||
set_physics_process(false)
|
||||
_is_gamepad_connected = false
|
||||
|
||||
|
||||
func _on_joy_connection_changed(device: int, connected: bool) -> void:
|
||||
if device != JOY_DEVICE:
|
||||
return
|
||||
elif connected:
|
||||
_on_gamepad_connected()
|
||||
else:
|
||||
_on_gamepad_disconnected()
|
||||
|
||||
|
||||
func _process(_delta) -> void:
|
||||
if !_is_gamepad_connected:
|
||||
return
|
||||
|
||||
var x = Input.get_joy_axis(JOY_DEVICE, JOY_AXIS_0)
|
||||
var y = Input.get_joy_axis(JOY_DEVICE, JOY_AXIS_1)
|
||||
var delta_x = int(x * AXIS_WEIGHT) if abs(x) > DEADZONE else 0
|
||||
var delta_y = int(y * AXIS_WEIGHT) if abs(y) > DEADZONE else 0
|
||||
if delta_x or delta_y:
|
||||
var direction = Vector2(delta_x, delta_y)
|
||||
escoria.logger.trace("gamepad direction:", [direction])
|
||||
var viewport = get_viewport()
|
||||
viewport.warp_mouse(viewport.get_mouse_position() + direction)
|
||||
|
||||
|
||||
func _process_input(event: InputEvent, is_default_state: bool) -> bool:
|
||||
if not is_default_state:
|
||||
# ESCBackground is not guaranteed to be set, as we may be on
|
||||
# the "New Game" screen.
|
||||
return false
|
||||
elif _is_gamepad_connected and event is InputEventJoypadButton:
|
||||
escoria.logger.trace("InputEventJoypadButton:", [event.as_text()])
|
||||
if event.is_action_pressed(escoria.inputs_manager.ESC_UI_PRIMARY_ACTION):
|
||||
# Admittedly, this breaks abstraction barriers and is completely
|
||||
# inappropriate, but it's what works right now.
|
||||
escoria.inputs_manager._on_left_click_on_bg(get_global_mouse_position())
|
||||
return true
|
||||
elif event.is_action_pressed(ESC_UI_CHANGE_VERB_ACTION):
|
||||
escoria.logger.error("Someone invoked ESC_UI_CHANGE_VERB_ACTION:", [event.as_text()])
|
||||
return true
|
||||
return false
|
||||
|
||||
|
||||
## BACKGROUND ##
|
||||
|
||||
func click_on_bg(position: Vector2) -> void:
|
||||
# If we are using an inventory item reset mouse cursor and cancel action
|
||||
if escoria.action_manager.action_state == ESCActionManager.ACTION_INPUT_STATE.AWAITING_TARGET_ITEM:
|
||||
Input.set_custom_mouse_cursor(null)
|
||||
escoria.action_manager.clear_current_tool()
|
||||
|
||||
if escoria.main.current_scene.player:
|
||||
escoria.action_manager.do(
|
||||
escoria.action_manager.ACTION.BACKGROUND_CLICK,
|
||||
[escoria.main.current_scene.player.global_id, position],
|
||||
true
|
||||
)
|
||||
|
||||
func left_click_on_bg(position: Vector2) -> void:
|
||||
click_on_bg(position)
|
||||
|
||||
func right_click_on_bg(position: Vector2) -> void:
|
||||
click_on_bg(position)
|
||||
|
||||
func left_double_click_on_bg(position: Vector2) -> void:
|
||||
if escoria.main.current_scene.player:
|
||||
escoria.action_manager.do(
|
||||
escoria.action_manager.ACTION.BACKGROUND_CLICK,
|
||||
[escoria.main.current_scene.player.global_id, position, true],
|
||||
true
|
||||
)
|
||||
|
||||
## ITEM/HOTSPOT FOCUS ##
|
||||
|
||||
func element_focused(element_id: String) -> void:
|
||||
var target_obj = escoria.object_manager.get_object(element_id).node
|
||||
if target_obj is ESCItem or ESCItemWithTooltip:
|
||||
$tooltip_layer/tooltip.set_target(target_obj.tooltip_name)
|
||||
$tooltip_layer/tooltip.set_target_object(target_obj)
|
||||
|
||||
if is_instance_valid(last_target):
|
||||
last_target.get_component('outline').highlight(false)
|
||||
|
||||
if(escoria.action_manager.has_actions(target_obj)):
|
||||
target_obj.get_component('outline').highlight(true)
|
||||
last_target = target_obj
|
||||
|
||||
|
||||
func element_unfocused() -> void:
|
||||
$tooltip_layer/tooltip.set_target("")
|
||||
$tooltip_layer/tooltip.set_target_object(null)
|
||||
if(last_target != null):
|
||||
last_target.get_component('outline').highlight(false)
|
||||
last_target = null
|
||||
|
||||
|
||||
|
||||
## ITEMS ##
|
||||
func click_on_item(item_global_id: String, event: InputEvent, action: String) -> void:
|
||||
# If we are using an inventory item reset mouse cursor and use inventory actions (change action1 for action3 and action2 for action4)
|
||||
if escoria.action_manager.action_state == ESCActionManager.ACTION_INPUT_STATE.AWAITING_TARGET_ITEM:
|
||||
Input.set_custom_mouse_cursor(null)
|
||||
action = ACTION3 if action == ACTION1 else ACTION4
|
||||
|
||||
escoria.action_manager.set_current_action(action)
|
||||
escoria.action_manager.do(
|
||||
escoria.action_manager.ACTION.ITEM_LEFT_CLICK,
|
||||
[item_global_id, event],
|
||||
true
|
||||
)
|
||||
|
||||
# Hide tooltip if some action is being performed
|
||||
if escoria.action_manager.action_state == ESCActionManager.ACTION_INPUT_STATE.COMPLETED:
|
||||
$tooltip_layer/tooltip.setHidden()
|
||||
|
||||
func left_click_on_item(item_global_id: String, event: InputEvent) -> void:
|
||||
click_on_item(item_global_id, event, ACTION1)
|
||||
|
||||
func right_click_on_item(item_global_id: String, event: InputEvent) -> void:
|
||||
click_on_item(item_global_id, event, ACTION2)
|
||||
|
||||
func left_double_click_on_item(item_global_id: String, event: InputEvent) -> void:
|
||||
escoria.action_manager.do(
|
||||
escoria.action_manager.ACTION.ITEM_LEFT_CLICK,
|
||||
[item_global_id, event],
|
||||
true
|
||||
)
|
||||
|
||||
|
||||
## INVENTORY ##
|
||||
func click_on_inventory_item(item_global_id: String, event: InputEvent, action: String) -> void:
|
||||
# If we are using an inventory item reset mouse cursor
|
||||
if escoria.action_manager.action_state == ESCActionManager.ACTION_INPUT_STATE.AWAITING_TARGET_ITEM:
|
||||
Input.set_custom_mouse_cursor(null)
|
||||
|
||||
escoria.action_manager.set_current_action(action)
|
||||
var target_obj = escoria.object_manager.get_object(item_global_id).node
|
||||
|
||||
# If item needs combination with this action, use the item texture as mouse cursor
|
||||
if action in target_obj.combine_when_selected_action_is_in:
|
||||
var texture = target_obj.inventory_texture
|
||||
var cursor = ImageTexture.new()
|
||||
var texture_image: Image = texture.get_data()
|
||||
texture_image.resize(texture_image.get_width()/2,texture_image.get_height()/2)
|
||||
cursor.create_from_image(texture_image)
|
||||
var middleOfTheTexture = Vector2(texture_image.get_width() / 2, texture_image.get_height() / 2)
|
||||
Input.set_custom_mouse_cursor(cursor, 0, middleOfTheTexture)
|
||||
|
||||
escoria.action_manager.do(
|
||||
escoria.action_manager.ACTION.ITEM_LEFT_CLICK,
|
||||
[item_global_id, event],
|
||||
true
|
||||
)
|
||||
|
||||
# Hide tooltip if some action is being performed
|
||||
if escoria.action_manager.action_state == ESCActionManager.ACTION_INPUT_STATE.COMPLETED:
|
||||
$tooltip_layer/tooltip.setHidden()
|
||||
|
||||
func left_click_on_inventory_item(inventory_item_global_id: String, event: InputEvent) -> void:
|
||||
click_on_inventory_item(inventory_item_global_id, event, ACTION3)
|
||||
|
||||
func right_click_on_inventory_item(inventory_item_global_id: String, event: InputEvent) -> void:
|
||||
click_on_inventory_item(inventory_item_global_id, event, ACTION4)
|
||||
|
||||
|
||||
|
||||
func inventory_item_focused(inventory_item_global_id: String) -> void:
|
||||
var target_obj = escoria.object_manager.get_object(inventory_item_global_id).node
|
||||
if target_obj is ESCItemWithTooltip:
|
||||
$tooltip_layer/tooltip.set_target(target_obj.action3_text)
|
||||
$tooltip_layer/tooltip.set_target_object(target_obj)
|
||||
|
||||
|
||||
func inventory_item_unfocused() -> void:
|
||||
element_unfocused()
|
||||
|
||||
func open_inventory():
|
||||
$CanvasLayer/ui/HBoxContainer/inventory_ui.show_inventory()
|
||||
|
||||
func close_inventory():
|
||||
$CanvasLayer/ui/HBoxContainer/inventory_ui.hide_inventory()
|
||||
|
||||
func hide_ui():
|
||||
$CanvasLayer/ui/HBoxContainer/inventory_ui.hide()
|
||||
$CanvasLayer/ui.hide()
|
||||
|
||||
func show_ui():
|
||||
$CanvasLayer/ui/HBoxContainer/inventory_ui.show()
|
||||
$CanvasLayer/ui.show()
|
||||
|
||||
|
||||
func hide_main_menu():
|
||||
if get_node(main_menu).visible:
|
||||
get_node(main_menu).hide()
|
||||
|
||||
func show_main_menu():
|
||||
if not get_node(main_menu).visible:
|
||||
get_node(main_menu).reset()
|
||||
get_node(main_menu).show()
|
||||
|
||||
func unpause_game():
|
||||
if get_node(pause_menu).visible:
|
||||
get_node(pause_menu).hide()
|
||||
escoria.object_manager.get_object(ESCObjectManager.CAMERA).node.current = true
|
||||
escoria.object_manager.get_object(ESCObjectManager.SPEECH).node.resume()
|
||||
escoria.main.current_scene.game.show_ui()
|
||||
escoria.main.current_scene.show()
|
||||
|
||||
func pause_game():
|
||||
if get_video_player().is_playing():
|
||||
get_video_player().skip()
|
||||
return
|
||||
if not get_node(pause_menu).visible:
|
||||
get_node(main_menu).reset()
|
||||
get_node(pause_menu).reset()
|
||||
get_node(pause_menu).set_save_enabled(
|
||||
escoria.save_manager.save_enabled
|
||||
)
|
||||
get_node(pause_menu).show()
|
||||
escoria.object_manager.get_object(ESCObjectManager.CAMERA).node.current = false
|
||||
escoria.object_manager.get_object(ESCObjectManager.SPEECH).node.pause()
|
||||
escoria.main.current_scene.game.hide_ui()
|
||||
escoria.main.current_scene.hide()
|
||||
|
||||
|
||||
func apply_custom_settings(custom_settings: Dictionary):
|
||||
if custom_settings.has("a_custom_setting"):
|
||||
escoria.logger.info(
|
||||
self,
|
||||
"custom setting value loaded: %s."
|
||||
% str(custom_settings["a_custom_setting"])
|
||||
)
|
||||
|
||||
|
||||
func get_custom_data() -> Dictionary:
|
||||
return {
|
||||
"ui_type": "simplemouse"
|
||||
}
|
||||
|
||||
|
||||
# Update the tooltip position
|
||||
func update_tooltip_following_mouse_position(tooltip: ESCRichTooltip):
|
||||
if tooltip == null:
|
||||
return
|
||||
if(escoria.action_manager.current_tool == null):
|
||||
set_tooltip_position("tooltip1", tooltip, tooltip.get_tooltip1_size(), tooltip.offset_from_cursor_action1)
|
||||
set_tooltip_position("tooltip2", tooltip, tooltip.get_tooltip2_size(), tooltip.offset_from_cursor_action2)
|
||||
return
|
||||
set_tooltip_position("tooltip1", tooltip, tooltip.get_tooltip1_size(), tooltip.offset_from_cursor_action3)
|
||||
set_tooltip_position("tooltip2", tooltip, tooltip.get_tooltip2_size(), tooltip.offset_from_cursor_action4)
|
||||
|
||||
|
||||
func set_tooltip_position(nodeId: String, tooltip: ESCRichTooltip, size: Vector2, offset: Vector2):
|
||||
var mouse_position = calculateMousePosition(size)
|
||||
var corrected_position = correctPosition(tooltip, size, mouse_position, offset)
|
||||
tooltip.get_node(nodeId).position = corrected_position
|
||||
#tooltip.get_node(nodeId).position = mouse_position
|
||||
|
||||
|
||||
func calculateMousePosition(size: Vector2):
|
||||
size.x / 2
|
||||
size.y / 2
|
||||
#escoria.logger.info(self, "_current_mouse_pos" + String(_current_mouse_pos.x) + " gameSize: " + escoria.game_size.x)
|
||||
|
||||
#return _current_mouse_pos - size
|
||||
return _current_mouse_pos
|
||||
|
||||
func correctPosition(tooltip: ESCRichTooltip, size: Vector2, mouse_position: Vector2, offset: Vector2):
|
||||
|
||||
# clamp TOP
|
||||
if tooltip.tooltip_distance_to_edge_top(_current_mouse_pos) <= mouse_tooltip_margin:
|
||||
mouse_position.y = mouse_tooltip_margin
|
||||
|
||||
# clamp BOTTOM
|
||||
if tooltip.tooltip_distance_to_edge_bottom(_current_mouse_pos + size) <= mouse_tooltip_margin:
|
||||
mouse_position.y = escoria.game_size.y - mouse_tooltip_margin - size.y
|
||||
|
||||
# clamp LEFT
|
||||
if tooltip.tooltip_distance_to_edge_left(_current_mouse_pos - size/2) <= mouse_tooltip_margin:
|
||||
mouse_position.x = mouse_tooltip_margin
|
||||
|
||||
# clamp RIGHT
|
||||
if tooltip.tooltip_distance_to_edge_right(_current_mouse_pos + size/2) <= mouse_tooltip_margin:
|
||||
mouse_position.x = escoria.game_size.x - mouse_tooltip_margin - size.x
|
||||
|
||||
|
||||
return mouse_position - offset
|
||||
|
||||
func _on_event_done(return_code: int, _event_name: String):
|
||||
escoria.logger.info(self, "EVENT DONE! code=" + String(return_code))
|
||||
|
||||
# Reset mouse cursor (should be not needed, but avoids not resetting the cursor on bugs)
|
||||
Input.set_custom_mouse_cursor(null)
|
||||
|
||||
# Show tooltips, they were hidden while performing action
|
||||
$tooltip_layer/tooltip.show()
|
||||
|
||||
|
||||
func _on_MenuButton_pressed() -> void:
|
||||
pause_game()
|
||||
|
||||
func get_video_player() -> Node:
|
||||
return $CanvasLayer/video_player
|
||||
|
||||
func play_video(video_file: String) -> void:
|
||||
$CanvasLayer/video_player.visible = true
|
||||
$CanvasLayer/video_player.play(video_file)
|
||||
|
||||
# Clears the tooltip content (if an ESCTooltip node exists in UI)
|
||||
# MODIFIED FOR RTMIUI
|
||||
func clear_tooltip():
|
||||
if tooltip_node != null:
|
||||
(tooltip_node as ESCRichTooltip).clear()
|
||||
|
||||
|
||||
var musicEnabled = true
|
||||
|
||||
func _on_MusicButton_pressed():
|
||||
if musicEnabled:
|
||||
AudioServer.set_bus_volume_db(
|
||||
AudioServer.get_bus_index(escoria.BUS_MUSIC),
|
||||
linear2db(0)
|
||||
)
|
||||
musicEnabled = false
|
||||
else:
|
||||
AudioServer.set_bus_volume_db(
|
||||
AudioServer.get_bus_index(escoria.BUS_MUSIC),
|
||||
linear2db(
|
||||
ESCProjectSettingsManager.get_setting(
|
||||
ESCProjectSettingsManager.MUSIC_VOLUME
|
||||
)
|
||||
)
|
||||
)
|
||||
musicEnabled = true
|
||||
122
addons/escoria-ui-return-monkey-island/game.tscn
Normal file
@@ -0,0 +1,122 @@
|
||||
[gd_scene load_steps=17 format=2]
|
||||
|
||||
[ext_resource path="res://gymkhana/addons/escoria-ui-return-monkey-island/inventory/inventory_ui.tscn" type="PackedScene" id=1]
|
||||
[ext_resource path="res://addons/escoria-core/game/scenes/dialogs/esc_dialog_player.gd" type="Script" id=2]
|
||||
[ext_resource path="res://addons/escoria-core/game/scenes/camera_player/camera.tscn" type="PackedScene" id=3]
|
||||
[ext_resource path="res://gymkhana/addons/escoria-ui-return-monkey-island/esc_rich_tooltip.tscn" type="PackedScene" id=4]
|
||||
[ext_resource path="res://gymkhana/addons/escoria-ui-return-monkey-island/game.gd" type="Script" id=5]
|
||||
[ext_resource path="res://gymkhana/addons/escoria-ui-return-monkey-island/icons/music-double-note.svg" type="Texture" id=6]
|
||||
[ext_resource path="res://gymkhana/addons/escoria-ui-return-monkey-island/menus/main_menu/main_menu.tscn" type="PackedScene" id=7]
|
||||
[ext_resource path="res://addons/escoria-core/ui_library/menus/pause_menu/pause_menu.tscn" type="PackedScene" id=8]
|
||||
[ext_resource path="res://gymkhana/addons/escoria-ui-return-monkey-island/theme.tres" type="Theme" id=9]
|
||||
[ext_resource path="res://gymkhana/addons/escoria-ui-return-monkey-island/icons/cog-64-hover.svg" type="Texture" id=10]
|
||||
[ext_resource path="res://gymkhana/addons/escoria-ui-return-monkey-island/icons/cog-64.svg" type="Texture" id=11]
|
||||
[ext_resource path="res://gymkhana/addons/escoria-ui-return-monkey-island/video_player/video_player.tscn" type="PackedScene" id=12]
|
||||
[ext_resource path="res://gymkhana/addons/escoria-ui-return-monkey-island/icons/music-double-note-hover.svg" type="Texture" id=13]
|
||||
[ext_resource path="res://gymkhana/addons/escoria-ui-return-monkey-island/MusicButton.gd" type="Script" id=14]
|
||||
[ext_resource path="res://gymkhana/addons/escoria-ui-return-monkey-island/icons/music-double-note-hover-disabled.svg" type="Texture" id=15]
|
||||
[ext_resource path="res://gymkhana/addons/escoria-ui-return-monkey-island/icons/music-double-note-disabled.svg" type="Texture" id=16]
|
||||
|
||||
[node name="game" type="Node2D"]
|
||||
script = ExtResource( 5 )
|
||||
main_menu = NodePath("CanvasLayer/main_menu")
|
||||
pause_menu = NodePath("CanvasLayer/pause_menu")
|
||||
mouse_tooltip_margin = 70.0
|
||||
editor_debug_mode = 1
|
||||
ui_parent_control_node = NodePath("CanvasLayer/ui")
|
||||
|
||||
[node name="camera" parent="." instance=ExtResource( 3 )]
|
||||
|
||||
[node name="dialog_layer" type="CanvasLayer" parent="."]
|
||||
layer = 3
|
||||
|
||||
[node name="ESCDialogsPlayer" type="Control" parent="dialog_layer"]
|
||||
theme = ExtResource( 9 )
|
||||
script = ExtResource( 2 )
|
||||
|
||||
[node name="CanvasLayer" type="CanvasLayer" parent="."]
|
||||
|
||||
[node name="ui" type="Control" parent="CanvasLayer"]
|
||||
anchor_top = 0.9
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
margin_top = -26.0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
theme = ExtResource( 9 )
|
||||
|
||||
[node name="menu_button" type="Control" parent="CanvasLayer/ui"]
|
||||
margin_left = 1245.0
|
||||
margin_top = -643.0
|
||||
margin_right = 1245.0
|
||||
margin_bottom = -643.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="CanvasLayer/ui/menu_button"]
|
||||
margin_left = -135.0
|
||||
margin_top = 6.0
|
||||
margin_right = 21.0
|
||||
margin_bottom = 76.0
|
||||
alignment = 1
|
||||
|
||||
[node name="MusicButton" type="TextureButton" parent="CanvasLayer/ui/menu_button/HBoxContainer"]
|
||||
margin_left = 44.0
|
||||
margin_right = 44.0
|
||||
margin_bottom = 70.0
|
||||
script = ExtResource( 14 )
|
||||
musicEnabledTexture = ExtResource( 6 )
|
||||
musicEnabledHoverTexture = ExtResource( 13 )
|
||||
musicDisabledTexture = ExtResource( 16 )
|
||||
musicDisabledHoverTexture = ExtResource( 15 )
|
||||
|
||||
[node name="MenuButton" type="TextureButton" parent="CanvasLayer/ui/menu_button/HBoxContainer"]
|
||||
margin_left = 48.0
|
||||
margin_right = 112.0
|
||||
margin_bottom = 70.0
|
||||
texture_normal = ExtResource( 11 )
|
||||
texture_hover = ExtResource( 10 )
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="CanvasLayer/ui"]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
margin_top = 18.0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="Spacer" type="Control" parent="CanvasLayer/ui/HBoxContainer"]
|
||||
margin_right = 1186.0
|
||||
margin_bottom = 90.0
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="inventory_ui" parent="CanvasLayer/ui/HBoxContainer" instance=ExtResource( 1 )]
|
||||
anchor_right = 0.0
|
||||
anchor_bottom = 0.0
|
||||
margin_left = 1190.0
|
||||
margin_right = 1280.0
|
||||
margin_bottom = 90.0
|
||||
rect_scale = Vector2( 1, 1 )
|
||||
|
||||
[node name="pause_menu" parent="CanvasLayer" instance=ExtResource( 8 )]
|
||||
visible = false
|
||||
theme = ExtResource( 9 )
|
||||
|
||||
[node name="main_menu" parent="CanvasLayer" instance=ExtResource( 7 )]
|
||||
visible = false
|
||||
|
||||
[node name="video_player" parent="CanvasLayer" instance=ExtResource( 12 )]
|
||||
visible = false
|
||||
|
||||
[node name="tooltip_layer" type="CanvasLayer" parent="."]
|
||||
layer = 2
|
||||
|
||||
[node name="tooltip" parent="tooltip_layer" instance=ExtResource( 4 )]
|
||||
z_index = 10
|
||||
color = Color( 1, 1, 1, 1 )
|
||||
offset_from_cursor_action1 = Vector2( 0, 30 )
|
||||
offset_from_cursor_action2 = Vector2( 0, -20 )
|
||||
offset_from_cursor_action3 = Vector2( 0, 55 )
|
||||
offset_from_cursor_action4 = Vector2( 0, -55 )
|
||||
|
||||
[connection signal="pressed" from="CanvasLayer/ui/menu_button/HBoxContainer/MusicButton" to="." method="_on_MusicButton_pressed"]
|
||||
[connection signal="pressed" from="CanvasLayer/ui/menu_button/HBoxContainer/MenuButton" to="." method="_on_MenuButton_pressed"]
|
||||
98
addons/escoria-ui-return-monkey-island/icons/cog-32.svg
Normal file
@@ -0,0 +1,98 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 32 32"
|
||||
version="1.1"
|
||||
id="svg3"
|
||||
sodipodi:docname="cog-32.svg"
|
||||
width="32"
|
||||
height="32"
|
||||
inkscape:version="1.3 (1:1.3+202307231459+0e150ed6c4)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview3"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:zoom="10.219903"
|
||||
inkscape:cx="46.918255"
|
||||
inkscape:cy="11.497174"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1171"
|
||||
inkscape:window-x="1920"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="g3" />
|
||||
<defs
|
||||
id="defs3">
|
||||
<filter
|
||||
id="shadow-1"
|
||||
height="1.1503132"
|
||||
width="1.150627"
|
||||
x="-0.075313492"
|
||||
y="-0.075156576">
|
||||
<feFlood
|
||||
flood-color="rgba(255, 255, 255, 1)"
|
||||
result="flood"
|
||||
id="feFlood1" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="atop"
|
||||
result="composite"
|
||||
id="feComposite1" />
|
||||
<feGaussianBlur
|
||||
in="composite"
|
||||
stdDeviation="15"
|
||||
result="blur"
|
||||
id="feGaussianBlur1" />
|
||||
<feOffset
|
||||
dx="0"
|
||||
dy="0"
|
||||
result="offset"
|
||||
id="feOffset1" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
id="feComposite2" />
|
||||
</filter>
|
||||
<radialGradient
|
||||
id="lorc-cog-gradient-1"
|
||||
gradientTransform="scale(0.99909393,1.0009069)"
|
||||
cx="256.8287"
|
||||
cy="258.04602"
|
||||
fx="256.8287"
|
||||
fy="258.04602"
|
||||
r="275.2504"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop
|
||||
offset="0%"
|
||||
stop-color="#828080"
|
||||
stop-opacity="1"
|
||||
id="stop2" />
|
||||
<stop
|
||||
offset="100%"
|
||||
stop-color="#000000"
|
||||
stop-opacity="1"
|
||||
id="stop3" />
|
||||
</radialGradient>
|
||||
</defs>
|
||||
<g
|
||||
class=""
|
||||
id="g3"
|
||||
transform="matrix(0.05818161,0,0,0.05818161,1.0708312,0.97285232)">
|
||||
<path
|
||||
d="m 234.875,18.78 c -26.087,2.367 -51.557,8.56 -74.875,18.782 15.37,32.763 14.222,66.706 -6.72,82.407 -20.835,15.617 -54.055,7.965 -81.124,-15.69 -16.246,19.452 -29.336,41.36 -38.875,65.626 33.83,12.333 56.635,37.665 52.94,63.5 -3.698,25.835 -32.697,43.74 -68.626,46.094 2.338,25.796 8.91,50.778 18.937,73.875 17.81,-8.182 35.793,-11.09 51.095,-8.938 13.032,1.87 23.927,7.015 31.156,16.657 15.817,21.097 7.603,54.713 -16.78,81.97 19.516,16.35 42.216,29.444 66.594,39.03 12.33,-33.828 37.655,-56.634 63.5,-52.938 25.844,3.697 43.74,32.696 46.094,68.625 26.087,-2.365 51.557,-8.555 74.875,-18.78 -15.766,-32.997 -14.26,-67.588 6.843,-83.406 9.64,-7.23 22.568,-9.022 35.594,-7.125 15.112,2.16 31.19,10.25 45.563,22.78 16.088,-19.345 29.4,-41.51 38.875,-65.594 -33.83,-12.332 -56.635,-37.653 -52.938,-63.5 3.697,-25.846 32.665,-43.772 68.594,-46.125 -2.36,-25.944 -8.774,-50.663 -18.906,-73.874 -32.612,15.117 -66.66,13.145 -82.282,-7.687 -15.696,-20.944 -7.252,-53.86 16.688,-81 C 391.577,57.117 368.849,44.022 344.472,34.437 332.14,68.265 306.815,91.097 280.972,87.405 255.126,83.712 237.228,54.709 234.877,18.78 Z m 21.656,95.126 c 79.626,0 144.376,64.752 144.376,144.375 0,79.626 -64.75,144.376 -144.375,144.376 -79.624,0 -144.374,-64.75 -144.374,-144.375 0,-79.624 64.75,-144.374 144.375,-144.374 z m 0,18.688 c -69.524,0 -125.686,56.162 -125.686,125.687 0,69.526 56.162,125.69 125.687,125.69 69.526,0 125.69,-56.164 125.69,-125.69 0,-69.522 -56.164,-125.686 -125.69,-125.686 z m 0.033,15.125 c 61.094,0 110.625,49.53 110.625,110.624 0,61.095 -49.53,110.625 -110.625,110.625 -61.095,0 -110.625,-49.53 -110.625,-110.626 0,-61.095 49.53,-110.625 110.625,-110.625 z"
|
||||
fill="url(#lorc-cog-gradient-1)"
|
||||
filter="url(#shadow-1)"
|
||||
id="path3"
|
||||
style="fill:url(#lorc-cog-gradient-1)" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.1 KiB |
100
addons/escoria-ui-return-monkey-island/icons/cog-64-hover.svg
Normal file
@@ -0,0 +1,100 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 64 64"
|
||||
version="1.1"
|
||||
id="svg3"
|
||||
sodipodi:docname="cog-64-hover.svg"
|
||||
width="64"
|
||||
height="64"
|
||||
inkscape:version="1.3 (1:1.3+202307231459+0e150ed6c4)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview3"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:zoom="5.1099513"
|
||||
inkscape:cx="-8.5128012"
|
||||
inkscape:cy="1.4677243"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1171"
|
||||
inkscape:window-x="1920"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="g3" />
|
||||
<defs
|
||||
id="defs3">
|
||||
<filter
|
||||
id="shadow-1"
|
||||
height="1.1524932"
|
||||
width="1.1529045"
|
||||
x="-0.076452048"
|
||||
y="-0.076200418">
|
||||
<feFlood
|
||||
flood-color="rgba(255, 255, 255, 1)"
|
||||
result="flood"
|
||||
id="feFlood1" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="atop"
|
||||
result="composite"
|
||||
id="feComposite1" />
|
||||
<feGaussianBlur
|
||||
in="composite"
|
||||
stdDeviation="15"
|
||||
result="blur"
|
||||
id="feGaussianBlur1" />
|
||||
<feOffset
|
||||
dx="0"
|
||||
dy="0"
|
||||
result="offset"
|
||||
id="feOffset1" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
id="feComposite2" />
|
||||
</filter>
|
||||
<radialGradient
|
||||
id="lorc-cog-gradient-1"
|
||||
gradientTransform="scale(0.99909393,1.0009069)"
|
||||
cx="256.8287"
|
||||
cy="258.04602"
|
||||
fx="256.8287"
|
||||
fy="258.04602"
|
||||
r="275.2504"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop
|
||||
offset="0"
|
||||
stop-color="#828080"
|
||||
stop-opacity="1"
|
||||
id="stop2"
|
||||
style="stop-color:#d131c1;stop-opacity:1;" />
|
||||
<stop
|
||||
offset="100%"
|
||||
stop-color="#000000"
|
||||
stop-opacity="1"
|
||||
id="stop3" />
|
||||
</radialGradient>
|
||||
</defs>
|
||||
<g
|
||||
class=""
|
||||
id="g3"
|
||||
transform="matrix(0.05818161,0,0,0.05818161,1.0708312,0.97285232)">
|
||||
<path
|
||||
d="m 234.875,18.78 c -26.087,2.367 -51.557,8.56 -74.875,18.782 15.37,32.763 14.222,66.706 -6.72,82.407 -20.835,15.617 -54.055,7.965 -81.124,-15.69 -16.246,19.452 -29.336,41.36 -38.875,65.626 33.83,12.333 56.635,37.665 52.94,63.5 -3.698,25.835 -32.697,43.74 -68.626,46.094 2.338,25.796 8.91,50.778 18.937,73.875 17.81,-8.182 35.793,-11.09 51.095,-8.938 13.032,1.87 23.927,7.015 31.156,16.657 15.817,21.097 7.603,54.713 -16.78,81.97 19.516,16.35 42.216,29.444 66.594,39.03 12.33,-33.828 37.655,-56.634 63.5,-52.938 25.844,3.697 43.74,32.696 46.094,68.625 26.087,-2.365 51.557,-8.555 74.875,-18.78 -15.766,-32.997 -14.26,-67.588 6.843,-83.406 9.64,-7.23 22.568,-9.022 35.594,-7.125 15.112,2.16 31.19,10.25 45.563,22.78 16.088,-19.345 29.4,-41.51 38.875,-65.594 -33.83,-12.332 -56.635,-37.653 -52.938,-63.5 3.697,-25.846 32.665,-43.772 68.594,-46.125 -2.36,-25.944 -8.774,-50.663 -18.906,-73.874 -32.612,15.117 -66.66,13.145 -82.282,-7.687 -15.696,-20.944 -7.252,-53.86 16.688,-81 C 391.577,57.117 368.849,44.022 344.472,34.437 332.14,68.265 306.815,91.097 280.972,87.405 255.126,83.712 237.228,54.709 234.877,18.78 Z m 21.656,95.126 c 79.626,0 144.376,64.752 144.376,144.375 0,79.626 -64.75,144.376 -144.375,144.376 -79.624,0 -144.374,-64.75 -144.374,-144.375 0,-79.624 64.75,-144.374 144.375,-144.374 z m 0,18.688 c -69.524,0 -125.686,56.162 -125.686,125.687 0,69.526 56.162,125.69 125.687,125.69 69.526,0 125.69,-56.164 125.69,-125.69 0,-69.522 -56.164,-125.686 -125.69,-125.686 z m 0.033,15.125 c 61.094,0 110.625,49.53 110.625,110.624 0,61.095 -49.53,110.625 -110.625,110.625 -61.095,0 -110.625,-49.53 -110.625,-110.626 0,-61.095 49.53,-110.625 110.625,-110.625 z"
|
||||
fill="url(#lorc-cog-gradient-1)"
|
||||
filter="url(#shadow-1)"
|
||||
id="path3"
|
||||
style="fill:url(#lorc-cog-gradient-1);stroke:#ffffff;stroke-opacity:1"
|
||||
transform="matrix(1.9999999,0,0,1.9999999,18.404999,17.219999)" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.3 KiB |
101
addons/escoria-ui-return-monkey-island/icons/cog-64-press.svg
Normal file
@@ -0,0 +1,101 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 64 64"
|
||||
version="1.1"
|
||||
id="svg3"
|
||||
sodipodi:docname="cog-64-press.svg"
|
||||
width="64"
|
||||
height="64"
|
||||
inkscape:version="1.3 (1:1.3+202307231459+0e150ed6c4)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview3"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:zoom="5.1099513"
|
||||
inkscape:cx="-8.5128012"
|
||||
inkscape:cy="1.4677243"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1171"
|
||||
inkscape:window-x="1920"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="g3" />
|
||||
<defs
|
||||
id="defs3">
|
||||
<filter
|
||||
id="shadow-1"
|
||||
height="1.1524932"
|
||||
width="1.1529045"
|
||||
x="-0.076452048"
|
||||
y="-0.076200418">
|
||||
<feFlood
|
||||
flood-color="rgba(255, 255, 255, 1)"
|
||||
result="flood"
|
||||
id="feFlood1" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="atop"
|
||||
result="composite"
|
||||
id="feComposite1" />
|
||||
<feGaussianBlur
|
||||
in="composite"
|
||||
stdDeviation="15"
|
||||
result="blur"
|
||||
id="feGaussianBlur1" />
|
||||
<feOffset
|
||||
dx="0"
|
||||
dy="0"
|
||||
result="offset"
|
||||
id="feOffset1" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
id="feComposite2" />
|
||||
</filter>
|
||||
<radialGradient
|
||||
id="lorc-cog-gradient-1"
|
||||
gradientTransform="scale(0.99909393,1.0009069)"
|
||||
cx="256.8287"
|
||||
cy="258.04602"
|
||||
fx="256.8287"
|
||||
fy="258.04602"
|
||||
r="275.2504"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop
|
||||
offset="0"
|
||||
stop-color="#828080"
|
||||
stop-opacity="1"
|
||||
id="stop2"
|
||||
style="stop-color:#d131c1;stop-opacity:1;" />
|
||||
<stop
|
||||
offset="1"
|
||||
stop-color="#000000"
|
||||
stop-opacity="1"
|
||||
id="stop3"
|
||||
style="stop-color:#bebebe;stop-opacity:1;" />
|
||||
</radialGradient>
|
||||
</defs>
|
||||
<g
|
||||
class=""
|
||||
id="g3"
|
||||
transform="matrix(0.05818161,0,0,0.05818161,1.0708312,0.97285232)">
|
||||
<path
|
||||
d="m 234.875,18.78 c -26.087,2.367 -51.557,8.56 -74.875,18.782 15.37,32.763 14.222,66.706 -6.72,82.407 -20.835,15.617 -54.055,7.965 -81.124,-15.69 -16.246,19.452 -29.336,41.36 -38.875,65.626 33.83,12.333 56.635,37.665 52.94,63.5 -3.698,25.835 -32.697,43.74 -68.626,46.094 2.338,25.796 8.91,50.778 18.937,73.875 17.81,-8.182 35.793,-11.09 51.095,-8.938 13.032,1.87 23.927,7.015 31.156,16.657 15.817,21.097 7.603,54.713 -16.78,81.97 19.516,16.35 42.216,29.444 66.594,39.03 12.33,-33.828 37.655,-56.634 63.5,-52.938 25.844,3.697 43.74,32.696 46.094,68.625 26.087,-2.365 51.557,-8.555 74.875,-18.78 -15.766,-32.997 -14.26,-67.588 6.843,-83.406 9.64,-7.23 22.568,-9.022 35.594,-7.125 15.112,2.16 31.19,10.25 45.563,22.78 16.088,-19.345 29.4,-41.51 38.875,-65.594 -33.83,-12.332 -56.635,-37.653 -52.938,-63.5 3.697,-25.846 32.665,-43.772 68.594,-46.125 -2.36,-25.944 -8.774,-50.663 -18.906,-73.874 -32.612,15.117 -66.66,13.145 -82.282,-7.687 -15.696,-20.944 -7.252,-53.86 16.688,-81 C 391.577,57.117 368.849,44.022 344.472,34.437 332.14,68.265 306.815,91.097 280.972,87.405 255.126,83.712 237.228,54.709 234.877,18.78 Z m 21.656,95.126 c 79.626,0 144.376,64.752 144.376,144.375 0,79.626 -64.75,144.376 -144.375,144.376 -79.624,0 -144.374,-64.75 -144.374,-144.375 0,-79.624 64.75,-144.374 144.375,-144.374 z m 0,18.688 c -69.524,0 -125.686,56.162 -125.686,125.687 0,69.526 56.162,125.69 125.687,125.69 69.526,0 125.69,-56.164 125.69,-125.69 0,-69.522 -56.164,-125.686 -125.69,-125.686 z m 0.033,15.125 c 61.094,0 110.625,49.53 110.625,110.624 0,61.095 -49.53,110.625 -110.625,110.625 -61.095,0 -110.625,-49.53 -110.625,-110.626 0,-61.095 49.53,-110.625 110.625,-110.625 z"
|
||||
fill="url(#lorc-cog-gradient-1)"
|
||||
filter="url(#shadow-1)"
|
||||
id="path3"
|
||||
style="fill:url(#lorc-cog-gradient-1);stroke:#ffffff;stroke-opacity:1"
|
||||
transform="matrix(1.9999999,0,0,1.9999999,18.404999,17.219999)" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.3 KiB |
99
addons/escoria-ui-return-monkey-island/icons/cog-64.svg
Normal file
@@ -0,0 +1,99 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 64 64"
|
||||
version="1.1"
|
||||
id="svg3"
|
||||
sodipodi:docname="cog-64.svg"
|
||||
width="64"
|
||||
height="64"
|
||||
inkscape:version="1.3 (1:1.3+202307231459+0e150ed6c4)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview3"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:zoom="5.1099513"
|
||||
inkscape:cx="-8.5128012"
|
||||
inkscape:cy="1.4677243"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1171"
|
||||
inkscape:window-x="1920"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="g3" />
|
||||
<defs
|
||||
id="defs3">
|
||||
<filter
|
||||
id="shadow-1"
|
||||
height="1.1524932"
|
||||
width="1.1529045"
|
||||
x="-0.076452048"
|
||||
y="-0.076200418">
|
||||
<feFlood
|
||||
flood-color="rgba(255, 255, 255, 1)"
|
||||
result="flood"
|
||||
id="feFlood1" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="atop"
|
||||
result="composite"
|
||||
id="feComposite1" />
|
||||
<feGaussianBlur
|
||||
in="composite"
|
||||
stdDeviation="15"
|
||||
result="blur"
|
||||
id="feGaussianBlur1" />
|
||||
<feOffset
|
||||
dx="0"
|
||||
dy="0"
|
||||
result="offset"
|
||||
id="feOffset1" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
id="feComposite2" />
|
||||
</filter>
|
||||
<radialGradient
|
||||
id="lorc-cog-gradient-1"
|
||||
gradientTransform="scale(0.99909393,1.0009069)"
|
||||
cx="256.8287"
|
||||
cy="258.04602"
|
||||
fx="256.8287"
|
||||
fy="258.04602"
|
||||
r="275.2504"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop
|
||||
offset="0%"
|
||||
stop-color="#828080"
|
||||
stop-opacity="1"
|
||||
id="stop2" />
|
||||
<stop
|
||||
offset="100%"
|
||||
stop-color="#000000"
|
||||
stop-opacity="1"
|
||||
id="stop3" />
|
||||
</radialGradient>
|
||||
</defs>
|
||||
<g
|
||||
class=""
|
||||
id="g3"
|
||||
transform="matrix(0.05818161,0,0,0.05818161,1.0708312,0.97285232)">
|
||||
<path
|
||||
d="m 234.875,18.78 c -26.087,2.367 -51.557,8.56 -74.875,18.782 15.37,32.763 14.222,66.706 -6.72,82.407 -20.835,15.617 -54.055,7.965 -81.124,-15.69 -16.246,19.452 -29.336,41.36 -38.875,65.626 33.83,12.333 56.635,37.665 52.94,63.5 -3.698,25.835 -32.697,43.74 -68.626,46.094 2.338,25.796 8.91,50.778 18.937,73.875 17.81,-8.182 35.793,-11.09 51.095,-8.938 13.032,1.87 23.927,7.015 31.156,16.657 15.817,21.097 7.603,54.713 -16.78,81.97 19.516,16.35 42.216,29.444 66.594,39.03 12.33,-33.828 37.655,-56.634 63.5,-52.938 25.844,3.697 43.74,32.696 46.094,68.625 26.087,-2.365 51.557,-8.555 74.875,-18.78 -15.766,-32.997 -14.26,-67.588 6.843,-83.406 9.64,-7.23 22.568,-9.022 35.594,-7.125 15.112,2.16 31.19,10.25 45.563,22.78 16.088,-19.345 29.4,-41.51 38.875,-65.594 -33.83,-12.332 -56.635,-37.653 -52.938,-63.5 3.697,-25.846 32.665,-43.772 68.594,-46.125 -2.36,-25.944 -8.774,-50.663 -18.906,-73.874 -32.612,15.117 -66.66,13.145 -82.282,-7.687 -15.696,-20.944 -7.252,-53.86 16.688,-81 C 391.577,57.117 368.849,44.022 344.472,34.437 332.14,68.265 306.815,91.097 280.972,87.405 255.126,83.712 237.228,54.709 234.877,18.78 Z m 21.656,95.126 c 79.626,0 144.376,64.752 144.376,144.375 0,79.626 -64.75,144.376 -144.375,144.376 -79.624,0 -144.374,-64.75 -144.374,-144.375 0,-79.624 64.75,-144.374 144.375,-144.374 z m 0,18.688 c -69.524,0 -125.686,56.162 -125.686,125.687 0,69.526 56.162,125.69 125.687,125.69 69.526,0 125.69,-56.164 125.69,-125.69 0,-69.522 -56.164,-125.686 -125.69,-125.686 z m 0.033,15.125 c 61.094,0 110.625,49.53 110.625,110.624 0,61.095 -49.53,110.625 -110.625,110.625 -61.095,0 -110.625,-49.53 -110.625,-110.626 0,-61.095 49.53,-110.625 110.625,-110.625 z"
|
||||
fill="url(#lorc-cog-gradient-1)"
|
||||
filter="url(#shadow-1)"
|
||||
id="path3"
|
||||
style="fill:url(#lorc-cog-gradient-1);stroke:#ffffff;stroke-opacity:1"
|
||||
transform="matrix(1.9999999,0,0,1.9999999,18.404999,17.219999)" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.2 KiB |
1
addons/escoria-ui-return-monkey-island/icons/cog.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="height: 512px; width: 512px;"><defs><filter id="shadow-1" height="300%" width="300%" x="-100%" y="-100%"><feFlood flood-color="rgba(255, 255, 255, 1)" result="flood"></feFlood><feComposite in="flood" in2="SourceGraphic" operator="atop" result="composite"></feComposite><feGaussianBlur in="composite" stdDeviation="15" result="blur"></feGaussianBlur><feOffset dx="0" dy="0" result="offset"></feOffset><feComposite in="SourceGraphic" in2="offset" operator="over"></feComposite></filter><radialGradient id="lorc-cog-gradient-1"><stop offset="0%" stop-color="#828080" stop-opacity="1"></stop><stop offset="100%" stop-color="#000000" stop-opacity="1"></stop></radialGradient></defs><g class="" transform="translate(0,0)" style=""><path d="M234.875 18.78c-26.087 2.367-51.557 8.56-74.875 18.782 15.37 32.763 14.222 66.706-6.72 82.407-20.835 15.617-54.055 7.965-81.124-15.69-16.246 19.452-29.336 41.36-38.875 65.626 33.83 12.333 56.635 37.665 52.94 63.5-3.698 25.835-32.697 43.74-68.626 46.094 2.338 25.796 8.91 50.778 18.937 73.875 17.81-8.182 35.793-11.09 51.095-8.938 13.032 1.87 23.927 7.015 31.156 16.657 15.817 21.097 7.603 54.713-16.78 81.97 19.516 16.35 42.216 29.444 66.594 39.03 12.33-33.828 37.655-56.634 63.5-52.938 25.844 3.697 43.74 32.696 46.094 68.625 26.087-2.365 51.557-8.555 74.875-18.78-15.766-32.997-14.26-67.588 6.843-83.406 9.64-7.23 22.568-9.022 35.594-7.125 15.112 2.16 31.19 10.25 45.563 22.78 16.088-19.345 29.4-41.51 38.875-65.594-33.83-12.332-56.635-37.653-52.938-63.5 3.697-25.846 32.665-43.772 68.594-46.125-2.36-25.944-8.774-50.663-18.906-73.874-32.612 15.117-66.66 13.145-82.282-7.687-15.696-20.944-7.252-53.86 16.688-81-19.52-16.352-42.248-29.447-66.625-39.032-12.332 33.828-37.657 56.66-63.5 52.968-25.846-3.693-43.744-32.696-46.095-68.625zm21.656 95.126c79.626 0 144.376 64.752 144.376 144.375 0 79.626-64.75 144.376-144.375 144.376-79.624 0-144.374-64.75-144.374-144.375 0-79.624 64.75-144.374 144.375-144.374zm0 18.688c-69.524 0-125.686 56.162-125.686 125.687 0 69.526 56.162 125.69 125.687 125.69 69.526 0 125.69-56.164 125.69-125.69 0-69.522-56.164-125.686-125.69-125.686zm.033 15.125c61.094 0 110.625 49.53 110.625 110.624 0 61.095-49.53 110.625-110.625 110.625s-110.625-49.53-110.625-110.626c0-61.095 49.53-110.625 110.625-110.625z" fill="url(#lorc-cog-gradient-1)" filter="url(#shadow-1)"></path></g></svg>
|
||||
|
After Width: | Height: | Size: 2.4 KiB |
@@ -0,0 +1,69 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
width="64"
|
||||
height="64"
|
||||
stroke-width="1.5"
|
||||
viewBox="0 0 64 64"
|
||||
fill="none"
|
||||
color="#000000"
|
||||
version="1.1"
|
||||
id="svg3"
|
||||
sodipodi:docname="music-double-note-disabled.svg"
|
||||
inkscape:version="1.3.2 (1:1.3.2+202311252150+091e20ef0f)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs3" />
|
||||
<sodipodi:namedview
|
||||
id="namedview3"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:zoom="5.3401293"
|
||||
inkscape:cx="51.215988"
|
||||
inkscape:cy="36.984123"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="971"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg3" />
|
||||
<path
|
||||
d="M 61.401264,38.533592 V 2.5986797 L 20.974521,9.1322999 V 45.067212"
|
||||
stroke="#000000"
|
||||
stroke-width="5.19747"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
id="path1"
|
||||
style="fill:none;fill-opacity:1;stroke-width:5.197;stroke-dasharray:none;stroke:#000000;stroke-opacity:1" />
|
||||
<path
|
||||
d="m 50.375792,54.867641 h 3.675155 c 4.059581,0 7.350317,-2.925101 7.350317,-6.533623 V 38.533592 H 50.375792 c -4.059585,0 -7.350321,2.925101 -7.350321,6.53362 v 3.266806 c 0,3.608522 3.290736,6.533623 7.350321,6.533623 z"
|
||||
stroke="#000000"
|
||||
stroke-width="5.19747"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
id="path2"
|
||||
style="fill:none;fill-opacity:1;stroke-width:5.197;stroke-dasharray:none;stroke:#000000;stroke-opacity:1" />
|
||||
<path
|
||||
d="m 9.9490451,61.401264 h 3.6751589 c 4.05947,0 7.350317,-2.925104 7.350317,-6.533623 V 45.067212 H 9.9490451 c -4.0594695,0 -7.3503171,2.925104 -7.3503171,6.533619 v 3.26681 c 0,3.608519 3.2908476,6.533623 7.3503171,6.533623 z"
|
||||
stroke="#000000"
|
||||
stroke-width="5.19747"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
id="path3"
|
||||
style="fill:none;fill-opacity:1;stroke-width:5.197;stroke-dasharray:none;stroke:#000000;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:#ff0000;stroke:#f40a09;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="M 7.4308899,51.792606 53.261256,12.207394"
|
||||
id="path6" />
|
||||
<path
|
||||
style="fill:#ff0000;stroke:#f40a09;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 53.261256,51.792606 7.4308899,12.207394"
|
||||
id="path6-3" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.7 KiB |
@@ -0,0 +1,69 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
width="64"
|
||||
height="64"
|
||||
stroke-width="1.5"
|
||||
viewBox="0 0 64 64"
|
||||
fill="none"
|
||||
color="#000000"
|
||||
version="1.1"
|
||||
id="svg3"
|
||||
sodipodi:docname="music-double-note-hover-disabled.svg"
|
||||
inkscape:version="1.3.2 (1:1.3.2+202311252150+091e20ef0f)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs3" />
|
||||
<sodipodi:namedview
|
||||
id="namedview3"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:zoom="5.3401293"
|
||||
inkscape:cx="51.215988"
|
||||
inkscape:cy="36.984123"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="971"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg3" />
|
||||
<path
|
||||
d="M 61.401264,38.533592 V 2.5986797 L 20.974521,9.1322999 V 45.067212"
|
||||
stroke="#000000"
|
||||
stroke-width="5.19747"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
id="path1"
|
||||
style="fill:none;fill-opacity:1;stroke-width:5.197;stroke-dasharray:none;stroke:#bd2ab0;stroke-opacity:1" />
|
||||
<path
|
||||
d="m 50.375792,54.867641 h 3.675155 c 4.059581,0 7.350317,-2.925101 7.350317,-6.533623 V 38.533592 H 50.375792 c -4.059585,0 -7.350321,2.925101 -7.350321,6.53362 v 3.266806 c 0,3.608522 3.290736,6.533623 7.350321,6.533623 z"
|
||||
stroke="#000000"
|
||||
stroke-width="5.19747"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
id="path2"
|
||||
style="fill:none;fill-opacity:1;stroke-width:5.197;stroke-dasharray:none;stroke:#bd2ab0;stroke-opacity:1" />
|
||||
<path
|
||||
d="m 9.9490451,61.401264 h 3.6751589 c 4.05947,0 7.350317,-2.925104 7.350317,-6.533623 V 45.067212 H 9.9490451 c -4.0594695,0 -7.3503171,2.925104 -7.3503171,6.533619 v 3.26681 c 0,3.608519 3.2908476,6.533623 7.3503171,6.533623 z"
|
||||
stroke="#000000"
|
||||
stroke-width="5.19747"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
id="path3"
|
||||
style="fill:none;fill-opacity:1;stroke-width:5.197;stroke-dasharray:none;stroke:#bd2ab0;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:#ff0000;stroke:#f40a09;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="M 7.4308899,51.792606 53.261256,12.207394"
|
||||
id="path6" />
|
||||
<path
|
||||
style="fill:#ff0000;stroke:#f40a09;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 53.261256,51.792606 7.4308899,12.207394"
|
||||
id="path6-3" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.8 KiB |
@@ -0,0 +1,61 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
width="64"
|
||||
height="64"
|
||||
stroke-width="1.5"
|
||||
viewBox="0 0 64 64"
|
||||
fill="none"
|
||||
color="#000000"
|
||||
version="1.1"
|
||||
id="svg3"
|
||||
sodipodi:docname="music-double-note-hover.svg"
|
||||
inkscape:version="1.3.2 (1:1.3.2+202311252150+091e20ef0f)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs3" />
|
||||
<sodipodi:namedview
|
||||
id="namedview3"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:zoom="3.7760417"
|
||||
inkscape:cx="88.055172"
|
||||
inkscape:cy="40.915862"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="971"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg3" />
|
||||
<path
|
||||
d="M 61.401264,38.533592 V 2.5986797 L 20.974521,9.1322999 V 45.067212"
|
||||
stroke="#000000"
|
||||
stroke-width="5.19747"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
id="path1"
|
||||
style="fill:none;fill-opacity:1;stroke-width:5.197;stroke-dasharray:none;stroke:#bd2ab0;stroke-opacity:1" />
|
||||
<path
|
||||
d="m 50.375792,54.867641 h 3.675155 c 4.059581,0 7.350317,-2.925101 7.350317,-6.533623 V 38.533592 H 50.375792 c -4.059585,0 -7.350321,2.925101 -7.350321,6.53362 v 3.266806 c 0,3.608522 3.290736,6.533623 7.350321,6.533623 z"
|
||||
stroke="#000000"
|
||||
stroke-width="5.19747"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
id="path2"
|
||||
style="fill:none;fill-opacity:1;stroke-width:5.197;stroke-dasharray:none;stroke:#bd2ab0;stroke-opacity:1" />
|
||||
<path
|
||||
d="m 9.9490451,61.401264 h 3.6751589 c 4.05947,0 7.350317,-2.925104 7.350317,-6.533623 V 45.067212 H 9.9490451 c -4.0594695,0 -7.3503171,2.925104 -7.3503171,6.533619 v 3.26681 c 0,3.608519 3.2908476,6.533623 7.3503171,6.533623 z"
|
||||
stroke="#000000"
|
||||
stroke-width="5.19747"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
id="path3"
|
||||
style="fill:none;fill-opacity:1;stroke-width:5.197;stroke-dasharray:none;stroke:#bd2ab0;stroke-opacity:1" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
@@ -0,0 +1,58 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
width="64"
|
||||
height="64"
|
||||
stroke-width="1.5"
|
||||
viewBox="0 0 64 64"
|
||||
fill="none"
|
||||
color="#000000"
|
||||
version="1.1"
|
||||
id="svg3"
|
||||
sodipodi:docname="music-double-note.svg"
|
||||
inkscape:version="1.3.2 (1:1.3.2+202311252150+091e20ef0f)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs3" />
|
||||
<sodipodi:namedview
|
||||
id="namedview3"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:zoom="3.7760417"
|
||||
inkscape:cx="109.50621"
|
||||
inkscape:cy="128.57379"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="971"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg3" />
|
||||
<path
|
||||
d="M 61.401264,38.533592 V 2.5986797 L 20.974521,9.1322999 V 45.067212"
|
||||
stroke="#000000"
|
||||
stroke-width="5.19747"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
id="path1" />
|
||||
<path
|
||||
d="m 50.375792,54.867641 h 3.675155 c 4.059581,0 7.350317,-2.925101 7.350317,-6.533623 V 38.533592 H 50.375792 c -4.059585,0 -7.350321,2.925101 -7.350321,6.53362 v 3.266806 c 0,3.608522 3.290736,6.533623 7.350321,6.533623 z"
|
||||
stroke="#000000"
|
||||
stroke-width="5.19747"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
id="path2" />
|
||||
<path
|
||||
d="m 9.9490451,61.401264 h 3.6751589 c 4.05947,0 7.350317,-2.925104 7.350317,-6.533623 V 45.067212 H 9.9490451 c -4.0594695,0 -7.3503171,2.925104 -7.3503171,6.533619 v 3.26681 c 0,3.608519 3.2908476,6.533623 7.3503171,6.533623 z"
|
||||
stroke="#000000"
|
||||
stroke-width="5.19747"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
id="path3" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.0 KiB |
BIN
addons/escoria-ui-return-monkey-island/images/grey.png
Normal file
|
After Width: | Height: | Size: 102 B |
BIN
addons/escoria-ui-return-monkey-island/images/inventory-bg.png
Normal file
|
After Width: | Height: | Size: 5.6 KiB |
BIN
addons/escoria-ui-return-monkey-island/images/inventory_bg.png
Executable file
|
After Width: | Height: | Size: 58 KiB |
@@ -0,0 +1,56 @@
|
||||
extends ESCInventory
|
||||
|
||||
|
||||
# Whether the inventory is visible currently
|
||||
var inventory_visible: bool = false
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
$FloatingInventory/panel.rect_position.x = ProjectSettings.get_setting("display/window/size/width") - $FloatingInventory/panel.rect_size.x
|
||||
# Hide inventory by default
|
||||
# $FloatingInventory/panel.rect_position.x = \
|
||||
# ProjectSettings.get_setting("display/window/size/width")
|
||||
|
||||
func _on_inventory_button_pressed():
|
||||
if $FloatingInventory/InventoryTween.is_active():
|
||||
return
|
||||
if inventory_visible:
|
||||
hide_inventory()
|
||||
else:
|
||||
show_inventory()
|
||||
|
||||
|
||||
func show_inventory():
|
||||
$FloatingInventory/InventoryTween.stop_all()
|
||||
$FloatingInventory/InventoryTween.remove_all()
|
||||
$FloatingInventory/InventoryTween.interpolate_property(
|
||||
$FloatingInventory/panel,
|
||||
"rect_position:x",
|
||||
$FloatingInventory/panel.rect_position.x,
|
||||
$FloatingInventory/panel.rect_position.x - \
|
||||
$FloatingInventory/panel.rect_size.x - \
|
||||
$HBoxContainer/inventory_button.rect_size.x,
|
||||
0.6
|
||||
)
|
||||
$FloatingInventory/InventoryTween.start()
|
||||
yield($FloatingInventory/InventoryTween,"tween_all_completed")
|
||||
$FloatingInventory/InventoryTween.stop_all()
|
||||
inventory_visible = true
|
||||
|
||||
|
||||
func hide_inventory():
|
||||
$FloatingInventory/InventoryTween.stop_all()
|
||||
$FloatingInventory/InventoryTween.remove_all()
|
||||
$FloatingInventory/InventoryTween.interpolate_property(
|
||||
$FloatingInventory/panel,
|
||||
"rect_position:x",
|
||||
$FloatingInventory/panel.rect_position.x,
|
||||
$FloatingInventory/panel.rect_position.x + \
|
||||
$FloatingInventory/panel.rect_size.x + \
|
||||
$HBoxContainer/inventory_button.rect_size.x,
|
||||
0.6
|
||||
)
|
||||
$FloatingInventory/InventoryTween.start()
|
||||
yield($FloatingInventory/InventoryTween,"tween_all_completed")
|
||||
$FloatingInventory/InventoryTween.stop_all()
|
||||
inventory_visible = false
|
||||
@@ -0,0 +1,68 @@
|
||||
[gd_scene load_steps=3 format=2]
|
||||
|
||||
[ext_resource path="res://gymkhana/addons/escoria-ui-return-monkey-island/inventory/inventory_ui.gd" type="Script" id=1]
|
||||
[ext_resource path="res://addons/escoria-core/ui_library/inventory/esc_inventory_container.gd" type="Script" id=3]
|
||||
|
||||
[node name="inventory_ui" type="Control"]
|
||||
anchor_right = 0.5
|
||||
anchor_bottom = 0.5
|
||||
margin_right = 768.0
|
||||
margin_bottom = 540.0
|
||||
rect_min_size = Vector2( 90, 90 )
|
||||
rect_scale = Vector2( 0.4, 0.4 )
|
||||
size_flags_horizontal = 0
|
||||
size_flags_vertical = 3
|
||||
script = ExtResource( 1 )
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": true
|
||||
}
|
||||
inventory_ui_container = NodePath("FloatingInventory/panel/MarginContainer/ScrollContainer/container")
|
||||
|
||||
[node name="FloatingInventory" type="CanvasLayer" parent="."]
|
||||
|
||||
[node name="Polygon2D" type="Polygon2D" parent="FloatingInventory"]
|
||||
color = Color( 0.156863, 0.0627451, 0, 1 )
|
||||
polygon = PoolVector2Array( -3, 578, 1280, 578, 1280, 752, -3, 757 )
|
||||
|
||||
[node name="panel" type="TextureRect" parent="FloatingInventory"]
|
||||
anchor_left = 1.0
|
||||
anchor_top = 1.0
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
margin_left = -1276.0
|
||||
margin_top = -160.0
|
||||
rect_min_size = Vector2( 0, 160 )
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
expand = true
|
||||
|
||||
[node name="MarginContainer" type="MarginContainer" parent="FloatingInventory/panel"]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
margin_left = -4.0
|
||||
margin_top = 2.0
|
||||
margin_right = -16.0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
custom_constants/margin_right = 20
|
||||
custom_constants/margin_top = 20
|
||||
custom_constants/margin_left = 20
|
||||
custom_constants/margin_bottom = 20
|
||||
|
||||
[node name="ScrollContainer" type="ScrollContainer" parent="FloatingInventory/panel/MarginContainer"]
|
||||
margin_left = 20.0
|
||||
margin_top = 79.0
|
||||
margin_right = 1244.0
|
||||
margin_bottom = 79.0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 6
|
||||
scroll_vertical_enabled = false
|
||||
|
||||
[node name="container" type="HBoxContainer" parent="FloatingInventory/panel/MarginContainer/ScrollContainer"]
|
||||
margin_right = 1224.0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
custom_constants/separation = 20
|
||||
script = ExtResource( 3 )
|
||||
|
||||
[node name="InventoryTween" type="Tween" parent="FloatingInventory"]
|
||||
@@ -0,0 +1,13 @@
|
||||
extends Node
|
||||
class_name ESCItemComponent
|
||||
|
||||
var _custom_data: Dictionary
|
||||
|
||||
func get_global_id():
|
||||
return self.get_parent().global_id
|
||||
|
||||
func get_component_type():
|
||||
pass
|
||||
|
||||
func register(custom_data: Dictionary):
|
||||
pass
|
||||
@@ -0,0 +1,9 @@
|
||||
extends ESCItemComponent
|
||||
class_name ESCItemComponentInventoryChecker
|
||||
|
||||
func get_component_type():
|
||||
return "auto-inventory-checker"
|
||||
|
||||
func _enter_tree():
|
||||
if escoria.inventory_manager.inventory_has(get_global_id()):
|
||||
escoria.object_manager.get_object(get_global_id()).active = false
|
||||
@@ -0,0 +1,41 @@
|
||||
extends ESCItemComponent
|
||||
class_name ESCItemComponentOutline
|
||||
|
||||
var outline: ItemOutline
|
||||
|
||||
var isHighlighted: bool
|
||||
var lastHighlightState: bool
|
||||
|
||||
func get_component_type():
|
||||
return "outline"
|
||||
|
||||
func _ready():
|
||||
var collision = get_parent().collision
|
||||
if collision is CollisionPolygon2D:
|
||||
outline = ItemOutline.new()
|
||||
outline.polygon = collision.get("polygon")
|
||||
outline.color = Color(1,1,1,0.2)
|
||||
outline.set_outline_width(2.0)
|
||||
outline.set_outline_color(Color(1,1,1,1))
|
||||
collision.add_child(outline)
|
||||
outline.hide()
|
||||
|
||||
|
||||
func highlight(value: bool):
|
||||
isHighlighted = value
|
||||
|
||||
func _process(_delta: float):
|
||||
if not outline is ItemOutline:
|
||||
return
|
||||
if isHighlighted != lastHighlightState:
|
||||
if isHighlighted and escoria.current_state == escoria.GAME_STATE.DEFAULT and get_parent().is_interactive:
|
||||
outline.show()
|
||||
else:
|
||||
outline.hide()
|
||||
lastHighlightState = isHighlighted
|
||||
|
||||
func _input(event):
|
||||
if event.is_action_pressed("ui_show_hints") and escoria.current_state == escoria.GAME_STATE.DEFAULT:
|
||||
highlight(true)
|
||||
elif (event.is_action_released("ui_show_hints")):
|
||||
highlight(false)
|
||||
21
addons/escoria-ui-return-monkey-island/item_outline.gd
Normal file
@@ -0,0 +1,21 @@
|
||||
tool
|
||||
extends Polygon2D
|
||||
class_name ItemOutline, "res://addons/escoria-core/design/esc_item.svg"
|
||||
|
||||
export(Color) var OutLine = Color(0,0,0) setget set_outline_color
|
||||
export(float) var Width = 2.0 setget set_outline_width
|
||||
|
||||
func _draw():
|
||||
var poly = get_polygon()
|
||||
for i in range(1 , poly.size()):
|
||||
draw_line(poly[i-1] , poly[i], OutLine , Width)
|
||||
draw_line(poly[poly.size() - 1] , poly[0], OutLine , Width)
|
||||
|
||||
func set_outline_color(color):
|
||||
OutLine = color
|
||||
update()
|
||||
|
||||
func set_outline_width(new_width):
|
||||
Width = new_width
|
||||
update()
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
# A simple main menu
|
||||
extends Control
|
||||
|
||||
|
||||
# Start the game
|
||||
func _on_new_game_pressed():
|
||||
escoria.new_game()
|
||||
|
||||
|
||||
# Show the load slots
|
||||
func _on_load_game_pressed():
|
||||
$main.hide()
|
||||
$load_game.refresh_savegames()
|
||||
$load_game.show()
|
||||
|
||||
|
||||
# Show the options panel
|
||||
func _on_options_pressed():
|
||||
$main.hide()
|
||||
$options.show()
|
||||
|
||||
|
||||
# Quit the game
|
||||
func _on_quit_pressed():
|
||||
escoria.quit()
|
||||
|
||||
|
||||
# Hide the options panel again
|
||||
func _on_options_back_button_pressed():
|
||||
reset()
|
||||
|
||||
|
||||
# Hide the load panel
|
||||
func _on_load_game_back_button_pressed():
|
||||
reset()
|
||||
|
||||
|
||||
# Resets the UI to initial state
|
||||
func reset():
|
||||
$load_game.hide()
|
||||
$options.hide()
|
||||
$main.show()
|
||||
|
||||
func _on_new_without_intro_pressed():
|
||||
escoria.globals_manager.set_global("cocina_delante_intro_played",true)
|
||||
escoria.globals_manager.set_global("cocina_intro_played",true)
|
||||
escoria.new_game()
|
||||
@@ -0,0 +1,111 @@
|
||||
[gd_scene load_steps=5 format=2]
|
||||
|
||||
[ext_resource path="res://gymkhana/addons/escoria-ui-return-monkey-island/menus/main_menu/main_menu.gd" type="Script" id=1]
|
||||
[ext_resource path="res://gymkhana/logo-small.png" type="Texture" id=3]
|
||||
[ext_resource path="res://addons/escoria-core/ui_library/menus/options/options.tscn" type="PackedScene" id=4]
|
||||
[ext_resource path="res://addons/escoria-core/ui_library/menus/load_save/load/load_game.tscn" type="PackedScene" id=5]
|
||||
|
||||
[node name="main_menu" type="Control"]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
script = ExtResource( 1 )
|
||||
|
||||
[node name="load_game" parent="." instance=ExtResource( 5 )]
|
||||
visible = false
|
||||
|
||||
[node name="options" parent="." instance=ExtResource( 4 )]
|
||||
visible = false
|
||||
|
||||
[node name="main" type="Control" parent="."]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
|
||||
[node name="Panel" type="Panel" parent="main"]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false,
|
||||
"_editor_description_": ""
|
||||
}
|
||||
|
||||
[node name="main" type="VBoxContainer" parent="main"]
|
||||
anchor_left = 0.5
|
||||
anchor_right = 0.5
|
||||
anchor_bottom = 1.0
|
||||
margin_left = -308.0
|
||||
margin_right = 308.0
|
||||
custom_constants/separation = 100
|
||||
alignment = 1
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="TextureRect" type="TextureRect" parent="main/main"]
|
||||
margin_top = 55.0
|
||||
margin_right = 616.0
|
||||
margin_bottom = 355.0
|
||||
texture = ExtResource( 3 )
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="buttons" type="VBoxContainer" parent="main/main"]
|
||||
margin_top = 455.0
|
||||
margin_right = 616.0
|
||||
margin_bottom = 695.0
|
||||
custom_constants/separation = 10
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="new_game" type="Button" parent="main/main/buttons"]
|
||||
margin_right = 616.0
|
||||
margin_bottom = 150.0
|
||||
rect_min_size = Vector2( 0, 150 )
|
||||
size_flags_vertical = 3
|
||||
text = "NEW_GAME"
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
[node name="new_game_without_intro" type="Button" parent="main/main/buttons"]
|
||||
margin_right = 616.0
|
||||
margin_bottom = 270.0
|
||||
size_flags_vertical = 3
|
||||
text = "NEW_GAME (without intro)"
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="load_game" type="Button" parent="main/main/buttons"]
|
||||
margin_top = 160.0
|
||||
margin_right = 616.0
|
||||
margin_bottom = 180.0
|
||||
text = "LOAD_GAME"
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="options" type="Button" parent="main/main/buttons"]
|
||||
margin_top = 190.0
|
||||
margin_right = 616.0
|
||||
margin_bottom = 210.0
|
||||
text = "OPTIONS"
|
||||
|
||||
[node name="quit" type="Button" parent="main/main/buttons"]
|
||||
margin_top = 220.0
|
||||
margin_right = 616.0
|
||||
margin_bottom = 240.0
|
||||
text = "QUIT"
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
|
||||
|
||||
[connection signal="back_button_pressed" from="load_game" to="." method="_on_load_game_back_button_pressed"]
|
||||
[connection signal="back_button_pressed" from="options" to="." method="_on_options_back_button_pressed"]
|
||||
[connection signal="pressed" from="main/main/buttons/new_game" to="." method="_on_new_game_pressed"]
|
||||
[connection signal="pressed" from="main/main/buttons/load_game" to="." method="_on_load_game_pressed"]
|
||||
[connection signal="pressed" from="main/main/buttons/options" to="." method="_on_options_pressed"]
|
||||
[connection signal="pressed" from="main/main/buttons/quit" to="." method="_on_quit_pressed"]
|
||||
[connection signal="pressed" from="main/main/buttons/new_game_without_intro" to="." method="_on_new_without_intro_pressed"]
|
||||
@@ -0,0 +1,16 @@
|
||||
# Basic information about an inventory item
|
||||
class_name ESCInventoryItem
|
||||
|
||||
|
||||
# Global ID of the ESCItem that uses this ESCInventoryItem
|
||||
var global_id: String = ""
|
||||
|
||||
# The texture for the item
|
||||
var texture: Texture = null
|
||||
|
||||
|
||||
func _init(p_item: ESCItem) -> void:
|
||||
global_id = p_item.global_id
|
||||
texture = p_item._get_inventory_texture()
|
||||
p_item.register_components()
|
||||
|
||||
7
addons/escoria-ui-return-monkey-island/plugin.cfg
Normal file
@@ -0,0 +1,7 @@
|
||||
[plugin]
|
||||
|
||||
name="Escoria Return to Monkey Island UI"
|
||||
description="Return to Monkey Island like UI for the Escoria Framework"
|
||||
author="Arkitekt"
|
||||
version="0.1.0"
|
||||
script="plugin.gd"
|
||||
37
addons/escoria-ui-return-monkey-island/plugin.gd
Normal file
@@ -0,0 +1,37 @@
|
||||
# Plugin script to initialize Escoria simple mouse UI
|
||||
tool
|
||||
extends EditorPlugin
|
||||
|
||||
|
||||
# Override function to return the plugin name.
|
||||
func get_plugin_name():
|
||||
return "escoria-ui-return-monkey-island"
|
||||
|
||||
|
||||
# Deregister UI
|
||||
func disable_plugin():
|
||||
print("Disabling plugin Escoria UI Return to Monkey Island.")
|
||||
EscoriaPlugin.deregister_ui("res://gymkhana/addons/escoria-ui-return-monkey-island/game.tscn")
|
||||
ESCProjectSettingsManager.remove_setting(
|
||||
RTMIUiSettings.SOUND_LIBRARY_FOLDER
|
||||
)
|
||||
|
||||
|
||||
|
||||
# Register UI with Escoria
|
||||
func enable_plugin():
|
||||
print("Enabling plugin Escoria Dialog Simple")
|
||||
|
||||
if EscoriaPlugin.register_ui(self, "res://gymkhana/addons/escoria-ui-return-monkey-island/game.tscn"):
|
||||
ESCProjectSettingsManager.register_setting(
|
||||
RTMIUiSettings.SOUND_LIBRARY_FOLDER,
|
||||
"res://game/sounds",
|
||||
{
|
||||
"type": TYPE_STRING
|
||||
}
|
||||
)
|
||||
else:
|
||||
get_editor_interface().set_plugin_enabled(
|
||||
get_plugin_name(),
|
||||
false
|
||||
)
|
||||
@@ -0,0 +1,7 @@
|
||||
extends Resource
|
||||
class_name RTMIUiSettings
|
||||
|
||||
const SETTINGS_ROOT = "escoria/rtmi_ui"
|
||||
|
||||
|
||||
const SOUND_LIBRARY_FOLDER = "%s/sound_library_folder" % SETTINGS_ROOT
|
||||
41
addons/escoria-ui-return-monkey-island/theme.tres
Normal file
@@ -0,0 +1,41 @@
|
||||
[gd_resource type="Theme" load_steps=5 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 = 4.0
|
||||
content_margin_right = 4.0
|
||||
content_margin_top = 4.0
|
||||
content_margin_bottom = 4.0
|
||||
bg_color = Color( 0, 0, 0, 0.462745 )
|
||||
corner_radius_top_right = 5
|
||||
corner_radius_bottom_right = 5
|
||||
expand_margin_left = 19.0
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id=2]
|
||||
bg_color = Color( 0, 0, 0, 0.509804 )
|
||||
corner_radius_top_left = 5
|
||||
corner_radius_top_right = 5
|
||||
corner_radius_bottom_right = 5
|
||||
corner_radius_bottom_left = 5
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id=3]
|
||||
bg_color = Color( 0, 0, 0, 0.388235 )
|
||||
corner_radius_top_left = 5
|
||||
corner_radius_top_right = 5
|
||||
corner_radius_bottom_right = 5
|
||||
corner_radius_bottom_left = 5
|
||||
expand_margin_left = 5.0
|
||||
expand_margin_right = 5.0
|
||||
expand_margin_top = 5.0
|
||||
expand_margin_bottom = 5.0
|
||||
|
||||
[resource]
|
||||
default_font = ExtResource( 1 )
|
||||
Label/colors/font_color = Color( 1, 1, 1, 1 )
|
||||
Label/colors/font_color_shadow = Color( 0, 0, 0, 0 )
|
||||
Label/colors/font_outline_modulate = Color( 1, 0, 0, 1 )
|
||||
Label/colors/label_box_bg = Color( 0, 0, 0, 0.745098 )
|
||||
Label/styles/normal = SubResource( 1 )
|
||||
RichTextLabel/styles/focus = SubResource( 2 )
|
||||
RichTextLabel/styles/normal = SubResource( 3 )
|
||||
@@ -0,0 +1,27 @@
|
||||
tool
|
||||
extends Node
|
||||
|
||||
signal finished
|
||||
|
||||
func play(video_file: String):
|
||||
$VideoPlayer.set_stream(load(video_file))
|
||||
$VideoPlayer.play()
|
||||
|
||||
func _on_VideoPlayer_finished():
|
||||
self.visible = false
|
||||
emit_signal("finished")
|
||||
|
||||
|
||||
func skip():
|
||||
$VideoPlayer.stop()
|
||||
self.visible = false
|
||||
emit_signal("finished")
|
||||
|
||||
func get_player():
|
||||
return $VideoPlayer
|
||||
|
||||
func is_playing() -> bool:
|
||||
var play = $VideoPlayer.is_playing()
|
||||
return play
|
||||
func _on_Skip_pressed():
|
||||
skip()
|
||||
@@ -0,0 +1,39 @@
|
||||
[gd_scene load_steps=5 format=2]
|
||||
|
||||
[ext_resource path="res://gymkhana/addons/escoria-ui-return-monkey-island/video_player/video_player.gd" type="Script" id=1]
|
||||
|
||||
[sub_resource type="VideoStreamTheora" id=1]
|
||||
|
||||
[sub_resource type="InputEventAction" id=2]
|
||||
action = "ui_cancel"
|
||||
|
||||
[sub_resource type="ShortCut" id=3]
|
||||
shortcut = SubResource( 2 )
|
||||
|
||||
[node name="video_player" type="Control"]
|
||||
margin_right = 1285.0
|
||||
margin_bottom = 753.0
|
||||
script = ExtResource( 1 )
|
||||
|
||||
[node name="ColorRect" type="ColorRect" parent="."]
|
||||
margin_right = 1275.0
|
||||
margin_bottom = 744.0
|
||||
color = Color( 0, 0, 0, 1 )
|
||||
|
||||
[node name="VideoPlayer" type="VideoPlayer" parent="."]
|
||||
margin_right = 1279.0
|
||||
margin_bottom = 747.0
|
||||
stream = SubResource( 1 )
|
||||
expand = false
|
||||
|
||||
[node name="Skip" type="Button" parent="."]
|
||||
margin_left = 1163.0
|
||||
margin_top = 680.0
|
||||
margin_right = 1250.0
|
||||
margin_bottom = 712.0
|
||||
shortcut = SubResource( 3 )
|
||||
text = "Saltar video"
|
||||
flat = true
|
||||
|
||||
[connection signal="finished" from="VideoPlayer" to="." method="_on_VideoPlayer_finished"]
|
||||
[connection signal="pressed" from="Skip" to="." method="_on_Skip_pressed"]
|
||||