Compare commits

...

4 Commits

Author SHA1 Message Date
7c6d7f0729 oier animation tweaks, say_to_camera command 2025-09-07 20:01:39 +02:00
2b7d57c802 speak animations 2025-09-07 19:37:21 +02:00
d987b6a03c Merge branch 'main' into speak-animations 2025-09-07 19:32:16 +02:00
021b5a0491 WIP 2025-09-06 23:09:48 +02:00
7 changed files with 214 additions and 16 deletions

View File

@@ -0,0 +1,139 @@
# `say_to_camera player text [type]`
#
# 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.
# - *text*: Text to display.
# - *key*: Translation key (default: nil)
# - *type*: Dialog type to use. One of `floating` or `avatar`.
# (default: the value set in the setting "Escoria/UI/Default Dialog Type")
#
# The text supports translation keys by prepending the key followed by
# a colon (`:`) to the text.
# For more details see: https://docs.escoria-framework.org/en/devel/getting_started/dialogs.html#translations
#
# Playing an audio file while the text is being
# displayed is also supported by this mechanism.
# For more details see: https://docs.escoria-framework.org/en/devel/getting_started/dialogs.html#recorded_speech
#
# Example: `say(player, "Picture's looking good.", "ROOM1_PICTURE")`
#
# @ESC
extends ESCBaseCommand
class_name SayToCameraCommand
const CURRENT_PLAYER_KEYWORD = "CURRENT_PLAYER"
const DEFAULT_CAMERA_DIRECTION = 4
var globals_regex : RegEx # Regex to match global variables in strings
# Constructor
func _init() -> void:
globals_regex = RegEx.new()
# Use look-ahead/behind to capture the term (i.e. global) in braces
globals_regex.compile("(?<=\\{)(.*)(?=\\})")
# Return the descriptor of the arguments of this command
func configure() -> ESCCommandArgumentDescriptor:
return ESCCommandArgumentDescriptor.new(
2,
[TYPE_STRING, TYPE_STRING, TYPE_STRING, TYPE_STRING],
[
null,
null,
"",
""
],
[
true,
false,
false,
true
]
)
# Validate whether the given arguments match the command descriptor
func validate(arguments: Array):
if not super.validate(arguments):
return false
if arguments[0].to_upper() != CURRENT_PLAYER_KEYWORD \
and not escoria.object_manager.has(arguments[0]):
raise_invalid_object_error(self, arguments[0])
return false
return true
# Run the command
func run(command_params: Array) -> int:
var dict: Dictionary
escoria.current_state = escoria.GAME_STATE.DIALOG
if !escoria.dialog_player:
raise_error(
self,
"No dialog player was registered and the 'say' command was encountered."
)
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
# Replace the names of any globals in "{ }" with their value
command_params[1] = escoria.globals_manager.replace_globals(command_params[1])
var speaking_character_global_id = escoria.main.current_scene.player.global_id \
if command_params[0].to_upper() == CURRENT_PLAYER_KEYWORD \
else command_params[0]
var node = escoria.object_manager.get_object(command_params[0]).node
escoria.object_manager.get_object(command_params[0]).node\
.set_direction(DEFAULT_CAMERA_DIRECTION)
escoria.dialog_player.say(
speaking_character_global_id,
command_params[3],
command_params[1],
command_params[2]
)
await escoria.dialog_player.say_finished
escoria.current_state = escoria.GAME_STATE.DEFAULT
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()
)

View File

@@ -0,0 +1 @@
uid://d0sdlkjqr8f67

View File

@@ -13,6 +13,8 @@ layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1")
[node name="Panel" type="Panel" parent="."]

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 MiB

After

Width:  |  Height:  |  Size: 3.6 MiB

View File

@@ -1,9 +1,9 @@
[gd_scene load_steps=33 format=3 uid="uid://cjmsexhyhi4vs"]
[gd_scene load_steps=37 format=3 uid="uid://cjmsexhyhi4vs"]
[ext_resource type="Script" uid="uid://clg4yrj7v7eae" path="res://addons/escoria-ui-return-monkey-island/esc_player_with_tooltip.gd" id="1"]
[ext_resource type="Texture2D" uid="uid://b2msjygw7oyi0" path="res://gymkhana/characters/oier/oier-mod.png" id="2"]
[ext_resource type="Texture2D" uid="uid://da1kd8lccd24" path="res://gymkhana/characters/oier/oier-mod.png" id="2"]
[ext_resource type="Resource" uid="uid://cyjo7aq0e4hbe" path="res://gymkhana/characters/oier/oier_animations.tres" id="3"]
[ext_resource type="Texture2D" uid="uid://bcs6kqj5w23vk" path="res://gymkhana/characters/oier/oier-mod-talk.png" id="4"]
[ext_resource type="Texture2D" uid="uid://dayds4a0t1ldv" path="res://gymkhana/characters/oier/oier-mod-talk.png" id="4"]
[ext_resource type="Script" uid="uid://85bledusisk1" path="res://addons/escoria-core/game/core-scripts/esc_dialog_location.gd" id="5_10x32"]
[sub_resource type="AtlasTexture" id="22"]
@@ -38,6 +38,22 @@ region = Rect2(5733, 0, 273, 795)
atlas = ExtResource("4")
region = Rect2(5733, 0, 273, 795)
[sub_resource type="AtlasTexture" id="AtlasTexture_10x32"]
atlas = ExtResource("4")
region = Rect2(5460, 0, 273, 795)
[sub_resource type="AtlasTexture" id="AtlasTexture_b64d8"]
atlas = ExtResource("4")
region = Rect2(4368, 0, 273, 795)
[sub_resource type="AtlasTexture" id="AtlasTexture_c4eys"]
atlas = ExtResource("4")
region = Rect2(5187, 0, 273, 795)
[sub_resource type="AtlasTexture" id="AtlasTexture_obf0k"]
atlas = ExtResource("4")
region = Rect2(4641, 0, 273, 795)
[sub_resource type="AtlasTexture" id="46"]
atlas = ExtResource("2")
region = Rect2(3549, 0, 273, 795)
@@ -169,6 +185,50 @@ animations = [{
}, {
"frames": [{
"duration": 1.0,
"texture": SubResource("23")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_10x32")
}],
"loop": true,
"name": &"speak_down_left",
"speed": 5.0
}, {
"frames": [{
"duration": 1.0,
"texture": SubResource("24")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_b64d8")
}],
"loop": true,
"name": &"speak_down_right",
"speed": 5.0
}, {
"frames": [{
"duration": 1.0,
"texture": SubResource("25")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_c4eys")
}],
"loop": true,
"name": &"speak_left",
"speed": 5.0
}, {
"frames": [{
"duration": 1.0,
"texture": SubResource("26")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_obf0k")
}],
"loop": true,
"name": &"speak_right",
"speed": 5.0
}, {
"frames": [{
"duration": 1.0,
"texture": SubResource("46")
}, {
"duration": 1.0,

View File

@@ -136,27 +136,27 @@ mirrored = false
[sub_resource type="Resource" id="27"]
script = ExtResource("3")
animation = "idle_right"
animation = "speak_right"
mirrored = false
[sub_resource type="Resource" id="28"]
script = ExtResource("3")
animation = "speak_down"
animation = "speak_down_right"
mirrored = false
[sub_resource type="Resource" id="29"]
script = ExtResource("3")
animation = "idle_left"
animation = "speak_down"
mirrored = false
[sub_resource type="Resource" id="30"]
script = ExtResource("3")
animation = "idle_down"
animation = "speak_down_left"
mirrored = false
[sub_resource type="Resource" id="31"]
script = ExtResource("3")
animation = "idle_right"
animation = "speak_left"
mirrored = true
[sub_resource type="Resource" id="32"]

View File

@@ -1,20 +1,16 @@
:action1
set_angle($player, 270)
say($player, "Mi mechero, que bien!!", "mechero_action1_say_1")
set_angle($player,270)
say($player, "Ayer lo dejé un segundo encima de la mesa y desapareció.", "mechero_action1_say_2")
say_to_camera($player, "Mi mechero, que bien!!", "mechero_action1_say_1")
say_to_camera($player, "Ayer lo dejé un segundo encima de la mesa y desapareció.", "mechero_action1_say_2")
:action2
set_angle($player,270)
say($player, "A la saca!", "mechero_action2_say")
say_to_camera($player, "A la saca!", "mechero_action2_say")
set_active($turno_cocina_mechero, false)
inventory_add("turno_cocina_mechero")
:action3
say($player, "Parece que no tiene gas.", "mechero_action3_say_1")
say($player, "Eso explica que lo hayan abandonado.", "mechero_action3_say_2")
set_angle($player, 180)
say($player, "Si vienes a Uli vigila tu mechero.", "mechero_action3_say_3")
say_to_camera($player, "Si vienes a Uli vigila tu mechero.", "mechero_action3_say_3")
:action4 "turno_cocina_carton"
say($player, "Fuego!", "mechero_action4") #ToDo: tiene sentido?