Add cutscene system

This commit is contained in:
Mario Martínez 2024-10-07 13:08:29 +02:00
parent 533bc2c60b
commit 142a24a895
17 changed files with 585 additions and 38 deletions

View file

@ -0,0 +1,14 @@
[gd_resource type="Resource" script_class="Cutscene" load_steps=4 format=3 uid="uid://cwfayxsvfvfp3"]
[ext_resource type="Script" path="res://Scripts/Cutscenes/cutscene.gd" id="1_5oimi"]
[ext_resource type="Script" path="res://Scripts/Cutscenes/Commands/show_dialogue.gd" id="1_m28bn"]
[sub_resource type="Resource" id="Resource_eeatu"]
script = ExtResource("1_m28bn")
character = 0
messages = Array[String](["Ha! I won! Told you I kill you!"])
textbox_direction = 0
[resource]
script = ExtResource("1_5oimi")
commands = Array[Resource("res://Scripts/Cutscenes/Commands/base.gd")]([SubResource("Resource_eeatu")])

View file

@ -0,0 +1,37 @@
[gd_resource type="Resource" script_class="Cutscene" load_steps=9 format=3 uid="uid://bj3rm1r1ouq0r"]
[ext_resource type="Script" path="res://Scripts/Cutscenes/cutscene.gd" id="1_ejncn"]
[ext_resource type="Script" path="res://Scripts/Cutscenes/Commands/show_dialogue.gd" id="1_r5tuj"]
[ext_resource type="Script" path="res://Scripts/Cutscenes/Commands/turn_character.gd" id="2_eqfp1"]
[sub_resource type="Resource" id="Resource_o72ak"]
script = ExtResource("2_eqfp1")
character = NodePath("../HiroPlayer")
facing_direction = 3
[sub_resource type="Resource" id="Resource_vdtv6"]
script = ExtResource("2_eqfp1")
character = NodePath("../HiroAI")
facing_direction = 0
[sub_resource type="Resource" id="Resource_r2p8t"]
script = ExtResource("1_r5tuj")
character = 0
messages = Array[String](["This is a test for the cutscene!", "Now I'm going to kill you!"])
textbox_direction = 1
[sub_resource type="Resource" id="Resource_fuu2y"]
script = ExtResource("2_eqfp1")
character = NodePath("../HiroPlayer")
facing_direction = 2
[sub_resource type="Resource" id="Resource_x3xc6"]
script = ExtResource("1_r5tuj")
character = 0
messages = Array[String](["Whaaat? Who are you!?", "You have no chance against me!!"])
textbox_direction = 0
[resource]
resource_name = "prototype_start"
script = ExtResource("1_ejncn")
commands = Array[Resource("res://Scripts/Cutscenes/Commands/base.gd")]([SubResource("Resource_o72ak"), SubResource("Resource_vdtv6"), SubResource("Resource_r2p8t"), SubResource("Resource_fuu2y"), SubResource("Resource_x3xc6")])

15
Hiro/hiro_ai.gdshader Normal file
View file

@ -0,0 +1,15 @@
shader_type canvas_item;
render_mode blend_mix;
uniform vec3 tint_color : source_color = vec3(1.0, 0.0, 0.0);
uniform float intensity : hint_range(0, 1) = 1.0;
void fragment() {
COLOR = vec4(mix(COLOR.rgb, tint_color, intensity), COLOR.a);
}
// bleh, we prolly don't need this
//void light() {
//vec4 color = COLOR;
//LIGHT = vec4(color.rgb * LIGHT_COLOR.rgb * LIGHT_ENERGY, LIGHT_COLOR.a * (1.0 - intensity));
//}

51
Hiro/hiro_ai_shader.tres Normal file
View file

@ -0,0 +1,51 @@
[gd_resource type="VisualShader" load_steps=4 format=3 uid="uid://dmoh1f7aoriyv"]
[sub_resource type="VisualShaderNodeInput" id="VisualShaderNodeInput_jknad"]
expanded_output_ports = [0]
input_name = "color"
[sub_resource type="VisualShaderNodeColorParameter" id="VisualShaderNodeColorParameter_bpbi7"]
expanded_output_ports = [0]
parameter_name = "Tint_Color"
[sub_resource type="VisualShaderNodeMix" id="VisualShaderNodeMix_rbqa7"]
default_input_values = [0, Vector3(0, 0, 0), 1, Vector3(1, 1, 1), 2, Vector3(0.5, 0.5, 0.5)]
op_type = 3
[resource]
code = "shader_type canvas_item;
render_mode blend_mix;
uniform vec4 Tint_Color : source_color;
void fragment() {
// Input:2
vec4 n_out2p0 = COLOR;
// ColorParameter:3
vec4 n_out3p0 = Tint_Color;
float n_out3p4 = n_out3p0.a;
// Mix:4
vec3 n_out4p0 = mix(vec3(n_out2p0.xyz), vec3(n_out3p0.xyz), vec3(n_out3p4));
// Output:0
COLOR.rgb = n_out4p0;
}
"
mode = 1
flags/light_only = false
nodes/fragment/2/node = SubResource("VisualShaderNodeInput_jknad")
nodes/fragment/2/position = Vector2(-340, 60)
nodes/fragment/3/node = SubResource("VisualShaderNodeColorParameter_bpbi7")
nodes/fragment/3/position = Vector2(-280, 260)
nodes/fragment/4/node = SubResource("VisualShaderNodeMix_rbqa7")
nodes/fragment/4/position = Vector2(140, 100)
nodes/fragment/connections = PackedInt32Array(2, 0, 4, 0, 3, 0, 4, 1, 3, 4, 4, 2, 4, 0, 0, 0)

View file

@ -0,0 +1,5 @@
extends Resource
class_name CutsceneCommand
func validate() -> bool:
return true

View file

@ -0,0 +1,3 @@
class_name EmitMessageCommand extends CutsceneCommand
@export var message: StringName = ""

View file

@ -0,0 +1,5 @@
class_name SetFlagCommand extends CutsceneCommand
@export var target: NodePath
@export var property: String
@export var value = false

View file

@ -0,0 +1,11 @@
extends CutsceneCommand
class_name ShowDialogueCommand
enum TextboxDirection {
LEFT,
RIGHT
}
@export var character: Util.CastCharacter
@export var messages: Array[String] = []
@export var textbox_direction = TextboxDirection.LEFT

View file

@ -0,0 +1,15 @@
extends CutsceneCommand
class_name TurnCharacterCommand
@export_node_path("CharacterBody2D") var character: NodePath
@export var facing_direction: Util.CardinalDirection
var _directions = [
Vector2.UP,
Vector2.LEFT,
Vector2.DOWN,
Vector2.RIGHT
]
func get_direction() -> Vector2:
return _directions[facing_direction]

View file

@ -0,0 +1,4 @@
extends Resource
class_name Cutscene
@export var commands: Array[CutsceneCommand] = []

View file

@ -0,0 +1,33 @@
extends Node
class_name CutsceneManager
signal loaded(cutscene_name: String)
signal started(cutscene_name: String)
signal issued_command(command: CutsceneCommand, manager: CutsceneManager)
signal finished(cutscene_name: String)
@export var cutscene: Cutscene
@onready var _step = -1
var _current_command: CutsceneCommand: get = get_current_command
func get_current_command() -> CutsceneCommand:
return _current_command
func step() -> void:
_step += 1
if(_step == 0):
started.emit(cutscene.resource_name)
if(_step >= cutscene.commands.size()):
finished.emit(cutscene.resource_name)
else:
_current_command = cutscene.commands[_step]
issued_command.emit(_current_command, self)
func load_cutscene(new_cutscene: Cutscene) -> void:
cutscene = new_cutscene
_step = -1
loaded.emit(cutscene.resource_name)
func _on_ui_dialogue_completed():
step()

View file

@ -9,11 +9,35 @@ func _ready():
battle_ui.initialize(player.health, ai.health)
battle_ui.set_player_health(player.health)
battle_ui.set_enemy_health(ai.health)
$CutsceneManager.step()
func _on_player_defeated():
if Globals.nsfw == true:
explosion_generator.spawn(player.position)
var cutscene = load("res://Cutscenes/prototype_defeated.tres")
$CutsceneManager.load_cutscene(cutscene)
$CutsceneManager.step()
func _on_ai_defeated():
if Globals.nsfw == true:
explosion_generator.spawn(ai.position)
func _on_cutscene_started(cutscene_name):
$HiroPlayer.can_move = false
if cutscene_name == "prototype_start":
$HiroAI.set_ai_enabled(false)
func _on_cutscene_finished(cutscene_name: String):
print("Cutscene " + cutscene_name + " finished")
$HiroPlayer.can_move = true
if cutscene_name == "prototype_start":
$HiroAI.set_ai_enabled(true)
func _on_cutscene_manager_issued_command(command: CutsceneCommand, manager: CutsceneManager):
if command is TurnCharacterCommand:
var character = manager.get_node(command.character)
# TODO: We need to set a common class for character nodes.
assert(character is CharacterBody2D and character.has_method("set_animation_direction"))
character.set_animation_direction(command.get_direction())
manager.step()

99
Scripts/UI/textbox.gd Normal file
View file

@ -0,0 +1,99 @@
extends CanvasLayer
enum TextboxDirection {
LEFT,
RIGHT
}
# CPS = Characters per second
@export var cps = 3.0
@onready var animation_player = $AnimationPlayer
@onready var _textboxes = [
$LeftTextbox/ChatboxContainer/Chatbox/PlacementContainer/MarginContainer/Text,
$RightTextbox/ChatboxContainer/Chatbox/PlacementContainer/MarginContainer/Text
]
@onready var _portraits = [
$LeftTextbox/ChatboxContainer/Portrait,
$RightTextbox/ChatboxContainer/Portrait
]
@onready var _indicators = [
$LeftTextbox/ChatboxContainer/Chatbox/PlacementContainer/NextIndicator,
$RightTextbox/ChatboxContainer/Chatbox/PlacementContainer/NextIndicator
]
signal display_completed
signal dialogue_continued
signal dialogue_completed
var _direction = TextboxDirection.LEFT
var _directions = ["left", "right"]
var _dialogue: Array[String] = []
var _next = 0
var _text = ""
var _display_text = ""
var _displaying = false
var frames = 0.0
func _ready():
for textbox in _textboxes:
textbox.size = Vector2(720, 480)
func _process(delta):
if _displaying:
if _display_text == _text:
_displaying = false
display_completed.emit()
else:
frames += delta
if frames >= 1/cps:
frames = 0.0
_display_text = _display_text + _text.substr(_display_text.length(), 1)
_textboxes[_direction].text = _display_text
for i in _indicators.size():
var indicator = _indicators[i]
indicator.visible = i == _direction && !_displaying && !animation_player.is_playing()
func _input(event):
if event.is_action_pressed("ui_accept"):
if _displaying:
_display_text = _text
_displaying = false
get_viewport().set_input_as_handled()
elif _display_text == _text:
dialogue_continued.emit()
_dialogue_continue()
get_viewport().set_input_as_handled()
func _dialogue_start(_who: Util.CastCharacter, dialogue: Array[String], direction: TextboxDirection):
_next = 0
_direction = direction
_dialogue = dialogue
_text = _dialogue[_next]
_display_text = ""
animation_player.play("show_" + _directions[_direction])
func _dialogue_continue():
_next += 1
if _next >= _dialogue.size():
_end_dialogue()
else:
_text = _dialogue[_next]
_display_text = ""
_displaying = true
func _end_dialogue():
_text = ""
_display_text = ""
_displaying = false # just in case
animation_player.play("hide_" + _directions[_direction])
func _on_animation_finished(anim_name: StringName):
if anim_name.contains("show"):
_displaying = true
elif anim_name.contains("hide"):
dialogue_completed.emit()
func _on_cutscene_command_issued(command: CutsceneCommand, _manager: CutsceneManager):
if command is ShowDialogueCommand:
_dialogue_start(command.character, command.messages, command.textbox_direction)

View file

@ -54,6 +54,12 @@ func _physics_process(_delta):
func _on_player_attack_did_hit(other, attack_power: int, attack_direction: Vector2):
if other.get_parent().get_instance_id() == get_instance_id() :
_on_ai_got_hurt(attack_power, attack_direction)
func set_ai_process_mode(mode: ProcessMode):
$StateMachine.process_mode = mode
func set_ai_enabled(enabled: bool):
set_ai_process_mode(Node.PROCESS_MODE_INHERIT if enabled else Node.PROCESS_MODE_DISABLED)
func _on_ai_got_hurt(attack_power: int, attack_direction: Vector2):
attacked_from = attack_direction

15
Scripts/util.gd Normal file
View file

@ -0,0 +1,15 @@
extends Object
class_name Util
enum CastCharacter {
hiro,
reed,
nem
}
enum CardinalDirection {
North,
West,
South,
East
}

View file

@ -1,5 +1,6 @@
[gd_scene load_steps=4 format=3 uid="uid://7oi3hcf5q4o7"]
[gd_scene load_steps=11 format=3 uid="uid://7oi3hcf5q4o7"]
[ext_resource type="Script" path="res://Scripts/UI/textbox.gd" id="1_nbji8"]
[ext_resource type="FontFile" uid="uid://bgqotudi6bifk" path="res://UI/Gundam 00 font gaufont.ttf" id="1_p6ypw"]
[ext_resource type="Texture2D" uid="uid://b7opep16uyb5r" path="res://Hiro/testportrait.png" id="2_6wmjm"]
@ -7,15 +8,120 @@
font = ExtResource("1_p6ypw")
font_size = 18
[node name="TextboxUI" type="Control"]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
[sub_resource type="Animation" id="Animation_pk8my"]
length = 0.001
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("LeftTextbox:position")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Vector2(-720, 0)]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("RightTextbox:position")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Vector2(720, 0)]
}
[node name="ChatboxContainer" type="Control" parent="."]
[sub_resource type="Animation" id="Animation_eq77b"]
resource_name = "hide"
length = 0.266668
step = 0.0166667
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("LeftTextbox:position")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 0.266667),
"transitions": PackedFloat32Array(1, 1),
"update": 0,
"values": [Vector2(0, 0), Vector2(-720, 0)]
}
[sub_resource type="Animation" id="Animation_o6mf0"]
resource_name = "hide_right"
length = 0.250002
step = 0.0166667
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("RightTextbox:position")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 0.25),
"transitions": PackedFloat32Array(1, 1),
"update": 0,
"values": [Vector2(0, 0), Vector2(720, 0)]
}
[sub_resource type="Animation" id="Animation_cb4qc"]
resource_name = "show"
length = 0.266668
step = 0.0166667
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("LeftTextbox:position")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 0.266667),
"transitions": PackedFloat32Array(1, 1),
"update": 0,
"values": [Vector2(-720, 0), Vector2(0, 0)]
}
[sub_resource type="Animation" id="Animation_ucf3h"]
resource_name = "show_right"
length = 0.250002
step = 0.0166667
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("RightTextbox:position")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 0.25),
"transitions": PackedFloat32Array(1, 1),
"update": 0,
"values": [Vector2(720, 0), Vector2(0, 0)]
}
[sub_resource type="AnimationLibrary" id="AnimationLibrary_c2uka"]
_data = {
"RESET": SubResource("Animation_pk8my"),
"hide_left": SubResource("Animation_eq77b"),
"hide_right": SubResource("Animation_o6mf0"),
"show_left": SubResource("Animation_cb4qc"),
"show_right": SubResource("Animation_ucf3h")
}
[node name="TextboxUI" type="CanvasLayer"]
script = ExtResource("1_nbji8")
[node name="LeftTextbox" type="Control" parent="."]
layout_mode = 3
anchors_preset = 0
offset_left = -720.0
offset_bottom = 480.0
[node name="ChatboxContainer" type="Control" parent="LeftTextbox"]
layout_mode = 1
anchor_top = 0.55
anchor_right = 1.0
@ -23,7 +129,7 @@ anchor_bottom = 0.95
grow_horizontal = 2
grow_vertical = 0
[node name="Chatbox" type="PanelContainer" parent="ChatboxContainer"]
[node name="Chatbox" type="PanelContainer" parent="LeftTextbox/ChatboxContainer"]
layout_mode = 1
anchors_preset = -1
anchor_top = 0.358
@ -33,10 +139,11 @@ grow_horizontal = 2
grow_vertical = 2
size_flags_horizontal = 3
[node name="PlacementContainer" type="Control" parent="ChatboxContainer/Chatbox"]
[node name="PlacementContainer" type="Control" parent="LeftTextbox/ChatboxContainer/Chatbox"]
layout_mode = 2
[node name="NextIndicator" type="Label" parent="ChatboxContainer/Chatbox/PlacementContainer"]
[node name="NextIndicator" type="Label" parent="LeftTextbox/ChatboxContainer/Chatbox/PlacementContainer"]
visible = false
layout_mode = 1
anchors_preset = -1
anchor_left = 1.0
@ -50,7 +157,7 @@ grow_vertical = 0
text = ">"
label_settings = SubResource("LabelSettings_ydgvr")
[node name="MarginContainer" type="MarginContainer" parent="ChatboxContainer/Chatbox/PlacementContainer"]
[node name="MarginContainer" type="MarginContainer" parent="LeftTextbox/ChatboxContainer/Chatbox/PlacementContainer"]
layout_mode = 1
anchors_preset = -1
anchor_left = 0.269
@ -63,16 +170,15 @@ theme_override_constants/margin_top = 16
theme_override_constants/margin_right = 16
theme_override_constants/margin_bottom = 16
[node name="Text" type="Label" parent="ChatboxContainer/Chatbox/PlacementContainer/MarginContainer"]
[node name="Text" type="Label" parent="LeftTextbox/ChatboxContainer/Chatbox/PlacementContainer/MarginContainer"]
custom_minimum_size = Vector2(100, 0)
layout_mode = 2
size_flags_vertical = 1
text = "Hello my name is Hiro Toyama, you destroyed my gunpla. Now I'm going to kill you."
label_settings = SubResource("LabelSettings_ydgvr")
autowrap_mode = 2
text_overrun_behavior = 3
[node name="Portrait" type="TextureRect" parent="ChatboxContainer"]
[node name="Portrait" type="TextureRect" parent="LeftTextbox/ChatboxContainer"]
layout_mode = 1
anchors_preset = -1
anchor_right = 0.286
@ -81,3 +187,94 @@ grow_vertical = 0
texture = ExtResource("2_6wmjm")
expand_mode = 1
stretch_mode = 5
[node name="RightTextbox" type="Control" parent="."]
layout_mode = 3
anchors_preset = 1
anchor_left = 1.0
anchor_right = 1.0
offset_left = 720.0
offset_right = 1440.0
offset_bottom = 480.0
grow_horizontal = 0
[node name="ChatboxContainer" type="Control" parent="RightTextbox"]
layout_mode = 1
anchor_top = 0.55
anchor_right = 1.0
anchor_bottom = 0.95
grow_horizontal = 2
grow_vertical = 0
[node name="Chatbox" type="PanelContainer" parent="RightTextbox/ChatboxContainer"]
layout_mode = 1
anchors_preset = -1
anchor_top = 0.358
anchor_right = 0.9
anchor_bottom = 1.0
offset_left = 72.0
offset_right = 72.0
grow_horizontal = 2
grow_vertical = 2
size_flags_horizontal = 3
[node name="PlacementContainer" type="Control" parent="RightTextbox/ChatboxContainer/Chatbox"]
layout_mode = 2
[node name="NextIndicator" type="Label" parent="RightTextbox/ChatboxContainer/Chatbox/PlacementContainer"]
layout_mode = 1
anchors_preset = -1
anchor_left = 1.0
anchor_top = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
offset_right = -16.0
offset_bottom = -16.0
grow_horizontal = 0
grow_vertical = 0
text = ">"
label_settings = SubResource("LabelSettings_ydgvr")
[node name="MarginContainer" type="MarginContainer" parent="RightTextbox/ChatboxContainer/Chatbox/PlacementContainer"]
layout_mode = 1
anchors_preset = -1
anchor_left = 0.269
anchor_right = 0.919
anchor_bottom = 1.0
offset_left = -137.312
offset_right = -137.312
grow_vertical = 2
size_flags_horizontal = 0
theme_override_constants/margin_left = 16
theme_override_constants/margin_top = 16
theme_override_constants/margin_right = 16
theme_override_constants/margin_bottom = 16
[node name="Text" type="Label" parent="RightTextbox/ChatboxContainer/Chatbox/PlacementContainer/MarginContainer"]
custom_minimum_size = Vector2(100, 0)
layout_mode = 2
size_flags_vertical = 1
text = "Lorem ipsum dolor sit amet
Quantiscat et sigmus dolmen romani ite domus
......."
label_settings = SubResource("LabelSettings_ydgvr")
autowrap_mode = 2
text_overrun_behavior = 3
[node name="Portrait" type="TextureRect" parent="RightTextbox/ChatboxContainer"]
layout_mode = 1
anchors_preset = -1
anchor_left = 0.65
anchor_right = 1.0
anchor_bottom = 1.0
grow_vertical = 0
texture = ExtResource("2_6wmjm")
expand_mode = 1
stretch_mode = 5
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
libraries = {
"": SubResource("AnimationLibrary_c2uka")
}
[connection signal="animation_finished" from="AnimationPlayer" to="." method="_on_animation_finished"]

View file

@ -1,4 +1,4 @@
[gd_scene load_steps=21 format=3 uid="uid://bxuxjqxxqy7ce"]
[gd_scene load_steps=23 format=3 uid="uid://bxuxjqxxqy7ce"]
[ext_resource type="PackedScene" uid="uid://di21xheryhp0k" path="res://Hiro/hiro_player.tscn" id="1_c1gpq"]
[ext_resource type="PackedScene" uid="uid://b8sfype1vx5ad" path="res://Nem/nem_npc.tscn" id="1_sqt7d"]
@ -18,6 +18,8 @@
[ext_resource type="Texture2D" uid="uid://jnub86bpiebw" path="res://NPCs/npc4.png" id="14_46hs3"]
[ext_resource type="Texture2D" uid="uid://baw6gijyxv1fv" path="res://NPCs/npc5.png" id="15_ppm1i"]
[ext_resource type="Texture2D" uid="uid://bcvxfjlg8mmjr" path="res://NPCs/npc6.png" id="16_cgyrp"]
[ext_resource type="Script" path="res://Scripts/Cutscenes/manager.gd" id="19_5yvrq"]
[ext_resource type="Resource" uid="uid://bj3rm1r1ouq0r" path="res://Cutscenes/prototype_start.tres" id="20_elypl"]
[sub_resource type="Gradient" id="Gradient_3ox2i"]
colors = PackedColorArray(0, 0, 0, 1, 0, 0, 0, 1)
@ -29,6 +31,29 @@ gradient = SubResource("Gradient_3ox2i")
y_sort_enabled = true
script = ExtResource("1_y634h")
[node name="TextboxUI" parent="." instance=ExtResource("12_8pgvx")]
layer = 2
cps = 100.0
[node name="CanvasLayer" type="CanvasLayer" parent="."]
[node name="BattleUI" parent="CanvasLayer" instance=ExtResource("10_hxn8m")]
[node name="Debug" type="Control" parent="CanvasLayer"]
visible = false
layout_mode = 3
anchor_left = 0.667
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 0
grow_vertical = 2
[node name="StateChartDebugger" parent="CanvasLayer/Debug" instance=ExtResource("2_o5str")]
layout_mode = 1
size_flags_horizontal = 0
enabled = false
initial_node_to_watch = NodePath("../../../HiroAI")
[node name="MapElements" type="Node2D" parent="."]
y_sort_enabled = true
position = Vector2(-136, -190)
@ -123,27 +148,6 @@ MELEE_RADIUS = 300
[node name="ExplosionGenerator" type="Node" parent="."]
script = ExtResource("9_df2wo")
[node name="CanvasLayer" type="CanvasLayer" parent="."]
[node name="BattleUI" parent="CanvasLayer" instance=ExtResource("10_hxn8m")]
[node name="Debug" type="Control" parent="CanvasLayer"]
visible = false
layout_mode = 3
anchor_left = 0.667
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 0
grow_vertical = 2
[node name="StateChartDebugger" parent="CanvasLayer/Debug" instance=ExtResource("2_o5str")]
layout_mode = 1
size_flags_horizontal = 0
enabled = false
initial_node_to_watch = NodePath("../../../HiroAI")
[node name="TextboxUI" parent="CanvasLayer" instance=ExtResource("12_8pgvx")]
[node name="NPCs" type="Node2D" parent="."]
visible = false
@ -177,6 +181,11 @@ texture_filter = 1
position = Vector2(285, -102)
texture = ExtResource("16_cgyrp")
[node name="CutsceneManager" type="Node" parent="."]
script = ExtResource("19_5yvrq")
cutscene = ExtResource("20_elypl")
[connection signal="dialogue_completed" from="TextboxUI" to="CutsceneManager" method="_on_ui_dialogue_completed"]
[connection signal="attack_did_hit" from="HiroPlayer" to="HiroAI" method="_on_player_attack_did_hit"]
[connection signal="defeated" from="HiroPlayer" to="." method="_on_player_defeated"]
[connection signal="defeated" from="HiroPlayer" to="HiroAI" method="_on_player_been_defeated"]
@ -184,3 +193,7 @@ texture = ExtResource("16_cgyrp")
[connection signal="attack_did_hit" from="HiroAI" to="HiroPlayer" method="_on_enemy_attack_did_hit"]
[connection signal="defeated" from="HiroAI" to="." method="_on_ai_defeated"]
[connection signal="got_hurt" from="HiroAI" to="CanvasLayer/BattleUI" method="_on_enemy_got_hurt"]
[connection signal="finished" from="CutsceneManager" to="." method="_on_cutscene_finished"]
[connection signal="issued_command" from="CutsceneManager" to="." method="_on_cutscene_manager_issued_command"]
[connection signal="issued_command" from="CutsceneManager" to="TextboxUI" method="_on_cutscene_command_issued"]
[connection signal="started" from="CutsceneManager" to="." method="_on_cutscene_started"]