Refactor character classes

This commit is contained in:
Mario Martínez 2024-10-07 19:29:53 +02:00
parent 077d367a7f
commit 4cb9e96ed8
10 changed files with 643 additions and 92 deletions

View file

@ -220,7 +220,7 @@ states/nsfw_defeated_start/position = Vector2(646, 176.354)
states/walk/node = SubResource("AnimationNodeBlendSpace2D_vunsg")
states/walk/position = Vector2(520, 108)
transitions = ["Start", "idle", SubResource("AnimationNodeStateMachineTransition_akmuq"), "idle", "walk", SubResource("AnimationNodeStateMachineTransition_sn1tm"), "walk", "idle", SubResource("AnimationNodeStateMachineTransition_5i3fu"), "idle", "melee", SubResource("AnimationNodeStateMachineTransition_y8p74"), "melee", "idle", SubResource("AnimationNodeStateMachineTransition_l17k0"), "hurt", "idle", SubResource("AnimationNodeStateMachineTransition_ln3pc"), "defeated", "End", SubResource("AnimationNodeStateMachineTransition_ouche"), "nsfw_defeated_start", "nsfw_defeated", SubResource("AnimationNodeStateMachineTransition_aa2bq"), "nsfw_defeated", "End", SubResource("AnimationNodeStateMachineTransition_vxker")]
graph_offset = Vector2(12, 21.3541)
graph_offset = Vector2(15, 40.3541)
[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_vm050"]
radius = 9.0

508
Reed/reed_ai.tscn Normal file
View file

@ -0,0 +1,508 @@
[gd_scene load_steps=64 format=3 uid="uid://bwrwh5of0jw4a"]
[ext_resource type="Script" path="res://Scripts/hiro_ai.gd" id="1_yavbv"]
[ext_resource type="Shader" uid="uid://bcnip762rd6yj" path="res://Shaders/character.tres" id="2_y6nd7"]
[ext_resource type="Texture2D" uid="uid://cm7tgomrcvq30" path="res://Hiro/Hiro Walk Sprite Cycle Line Up.png" id="3_mgryv"]
[ext_resource type="AnimationLibrary" uid="uid://dincs5x4qucal" path="res://Hiro/hiro_animation.tres" id="4_tcpux"]
[ext_resource type="Script" path="res://addons/godot_state_charts/state_chart.gd" id="5_pgbft"]
[ext_resource type="Script" path="res://addons/godot_state_charts/compound_state.gd" id="6_a7x4q"]
[ext_resource type="Script" path="res://addons/godot_state_charts/atomic_state.gd" id="7_jc1pg"]
[ext_resource type="Script" path="res://addons/godot_state_charts/transition.gd" id="8_713tw"]
[ext_resource type="Script" path="res://addons/godot_state_charts/expression_guard.gd" id="9_nipdn"]
[sub_resource type="ShaderMaterial" id="ShaderMaterial_7ckhc"]
shader = ExtResource("2_y6nd7")
shader_parameter/FlashColor = Color(1, 0, 0, 0)
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_vk5j3"]
animation = &"walking_south"
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_87pv0"]
animation = &"walking_west"
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_4xdsu"]
animation = &"walking_east"
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_tmboi"]
animation = &"walking_north"
[sub_resource type="AnimationNodeBlendSpace2D" id="AnimationNodeBlendSpace2D_h2456"]
blend_point_0/node = SubResource("AnimationNodeAnimation_vk5j3")
blend_point_0/pos = Vector2(0, 1)
blend_point_1/node = SubResource("AnimationNodeAnimation_87pv0")
blend_point_1/pos = Vector2(-1, 0)
blend_point_2/node = SubResource("AnimationNodeAnimation_4xdsu")
blend_point_2/pos = Vector2(1, 0)
blend_point_3/node = SubResource("AnimationNodeAnimation_tmboi")
blend_point_3/pos = Vector2(0, -1)
blend_mode = 1
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_8ov0j"]
animation = &"player_defeated"
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_tyc74"]
animation = &"hurt_west"
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_0vb6l"]
animation = &"hurt_south"
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_rm4rl"]
animation = &"hurt_east"
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_ob16h"]
animation = &"hurt_north"
[sub_resource type="AnimationNodeBlendSpace2D" id="AnimationNodeBlendSpace2D_h2vkc"]
blend_point_0/node = SubResource("AnimationNodeAnimation_tyc74")
blend_point_0/pos = Vector2(-1, 0)
blend_point_1/node = SubResource("AnimationNodeAnimation_0vb6l")
blend_point_1/pos = Vector2(0, 1)
blend_point_2/node = SubResource("AnimationNodeAnimation_rm4rl")
blend_point_2/pos = Vector2(1, 0)
blend_point_3/node = SubResource("AnimationNodeAnimation_ob16h")
blend_point_3/pos = Vector2(0, -1)
blend_mode = 1
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_6ohpw"]
animation = &"idle_west"
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_330gg"]
animation = &"idle_east"
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_lsntm"]
animation = &"idle_north"
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_g1i0e"]
animation = &"idle_south"
[sub_resource type="AnimationNodeBlendSpace2D" id="AnimationNodeBlendSpace2D_bd8j1"]
blend_point_0/node = SubResource("AnimationNodeAnimation_6ohpw")
blend_point_0/pos = Vector2(-1, 0)
blend_point_1/node = SubResource("AnimationNodeAnimation_330gg")
blend_point_1/pos = Vector2(1, 0)
blend_point_2/node = SubResource("AnimationNodeAnimation_lsntm")
blend_point_2/pos = Vector2(0, -1)
blend_point_3/node = SubResource("AnimationNodeAnimation_g1i0e")
blend_point_3/pos = Vector2(0, 1)
blend_mode = 1
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_f740i"]
animation = &"punch_south_rigth"
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_bwovr"]
animation = &"punch_west_rigth"
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_qqbt6"]
animation = &"punch_east_rigth"
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_y3tw5"]
animation = &"punch_north_rigth"
[sub_resource type="AnimationNodeBlendSpace2D" id="AnimationNodeBlendSpace2D_2orb0"]
blend_point_0/node = SubResource("AnimationNodeAnimation_f740i")
blend_point_0/pos = Vector2(0, 1)
blend_point_1/node = SubResource("AnimationNodeAnimation_bwovr")
blend_point_1/pos = Vector2(-1, 0)
blend_point_2/node = SubResource("AnimationNodeAnimation_qqbt6")
blend_point_2/pos = Vector2(1, 0)
blend_point_3/node = SubResource("AnimationNodeAnimation_y3tw5")
blend_point_3/pos = Vector2(0, -1)
blend_mode = 1
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_ruw2d"]
animation = &"punch_west_left"
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_iu52b"]
animation = &"punch_north_left"
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_sotly"]
animation = &"punch_east_left"
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_ryihd"]
animation = &"punch_south_left"
[sub_resource type="AnimationNodeBlendSpace2D" id="AnimationNodeBlendSpace2D_dd6tw"]
blend_point_0/node = SubResource("AnimationNodeAnimation_ruw2d")
blend_point_0/pos = Vector2(-1, 0)
blend_point_1/node = SubResource("AnimationNodeAnimation_iu52b")
blend_point_1/pos = Vector2(0, -1)
blend_point_2/node = SubResource("AnimationNodeAnimation_sotly")
blend_point_2/pos = Vector2(1, 0)
blend_point_3/node = SubResource("AnimationNodeAnimation_ryihd")
blend_point_3/pos = Vector2(0, 1)
blend_mode = 1
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_p4b5o"]
animation = &"kick_east"
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_vay80"]
animation = &"kick_north"
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_1svn8"]
animation = &"kick_west"
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_awga0"]
animation = &"kick_south"
[sub_resource type="AnimationNodeBlendSpace2D" id="AnimationNodeBlendSpace2D_mr7t3"]
blend_point_0/node = SubResource("AnimationNodeAnimation_p4b5o")
blend_point_0/pos = Vector2(1, 0)
blend_point_1/node = SubResource("AnimationNodeAnimation_vay80")
blend_point_1/pos = Vector2(0, -1)
blend_point_2/node = SubResource("AnimationNodeAnimation_1svn8")
blend_point_2/pos = Vector2(-1, 0)
blend_point_3/node = SubResource("AnimationNodeAnimation_awga0")
blend_point_3/pos = Vector2(0, 1)
blend_mode = 1
[sub_resource type="AnimationNodeBlendSpace1D" id="AnimationNodeBlendSpace1D_dc3kp"]
blend_point_0/node = SubResource("AnimationNodeBlendSpace2D_2orb0")
blend_point_0/pos = 0.0
blend_point_1/node = SubResource("AnimationNodeBlendSpace2D_dd6tw")
blend_point_1/pos = 0.5
blend_point_2/node = SubResource("AnimationNodeBlendSpace2D_mr7t3")
blend_point_2/pos = 1.0
blend_mode = 1
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_0ny5g"]
animation = &"ai_defeated"
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_kgin3"]
animation = &"ai_defeated_start"
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_17wsb"]
animation = &"walking_north"
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_j520c"]
animation = &"walking_south"
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_srrrs"]
animation = &"walking_west"
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_4ypsn"]
animation = &"walking_east"
[sub_resource type="AnimationNodeBlendSpace2D" id="AnimationNodeBlendSpace2D_vunsg"]
blend_point_0/node = SubResource("AnimationNodeAnimation_17wsb")
blend_point_0/pos = Vector2(0, -1)
blend_point_1/node = SubResource("AnimationNodeAnimation_j520c")
blend_point_1/pos = Vector2(0, 1)
blend_point_2/node = SubResource("AnimationNodeAnimation_srrrs")
blend_point_2/pos = Vector2(-1, 0)
blend_point_3/node = SubResource("AnimationNodeAnimation_4ypsn")
blend_point_3/pos = Vector2(1, 0)
blend_mode = 1
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_akmuq"]
advance_mode = 2
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_sn1tm"]
advance_mode = 2
advance_condition = &"is_moving"
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_5i3fu"]
advance_mode = 2
advance_expression = "get(\"parameters/conditions/is_moving\") == false"
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_y8p74"]
advance_mode = 2
advance_condition = &"melee"
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_l17k0"]
switch_mode = 2
advance_mode = 2
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_ln3pc"]
switch_mode = 2
advance_mode = 2
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_l5ng5"]
switch_mode = 2
advance_mode = 2
[sub_resource type="AnimationNodeStateMachine" id="AnimationNodeStateMachine_b0avg"]
allow_transition_to_self = true
states/End/position = Vector2(1026, 108)
states/Start/position = Vector2(197, 108)
states/cut_walk/node = SubResource("AnimationNodeBlendSpace2D_h2456")
states/cut_walk/position = Vector2(563, 400)
states/defeated/node = SubResource("AnimationNodeAnimation_8ov0j")
states/defeated/position = Vector2(734, 74)
states/hurt/node = SubResource("AnimationNodeBlendSpace2D_h2vkc")
states/hurt/position = Vector2(329, -13)
states/idle/node = SubResource("AnimationNodeBlendSpace2D_bd8j1")
states/idle/position = Vector2(329, 108)
states/melee/node = SubResource("AnimationNodeBlendSpace1D_dc3kp")
states/melee/position = Vector2(329, 224)
states/naked/node = SubResource("AnimationNodeAnimation_0ny5g")
states/naked/position = Vector2(895, 202)
states/naked_start/node = SubResource("AnimationNodeAnimation_kgin3")
states/naked_start/position = Vector2(734, 202)
states/walk/node = SubResource("AnimationNodeBlendSpace2D_vunsg")
states/walk/position = Vector2(519, 108)
transitions = ["Start", "idle", SubResource("AnimationNodeStateMachineTransition_akmuq"), "idle", "walk", SubResource("AnimationNodeStateMachineTransition_sn1tm"), "walk", "idle", SubResource("AnimationNodeStateMachineTransition_5i3fu"), "idle", "melee", SubResource("AnimationNodeStateMachineTransition_y8p74"), "melee", "idle", SubResource("AnimationNodeStateMachineTransition_l17k0"), "hurt", "idle", SubResource("AnimationNodeStateMachineTransition_ln3pc"), "naked_start", "naked", SubResource("AnimationNodeStateMachineTransition_l5ng5")]
graph_offset = Vector2(20, 231)
[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_vm050"]
radius = 9.0
height = 36.0
[sub_resource type="RectangleShape2D" id="RectangleShape2D_bdqvd"]
size = Vector2(13, 8)
[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_m3ug4"]
height = 20.0
[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_hxosv"]
radius = 13.0
height = 36.0
[sub_resource type="Resource" id="Resource_ri8lv"]
script = ExtResource("9_nipdn")
expression = "melee_stage == 0"
[sub_resource type="Resource" id="Resource_gtfv8"]
script = ExtResource("9_nipdn")
expression = "melee_stage == 1"
[node name="ReedAI" type="CharacterBody2D"]
y_sort_enabled = true
collision_layer = 5
motion_mode = 1
script = ExtResource("1_yavbv")
[node name="Sprite2D" type="Sprite2D" parent="."]
modulate = Color(0.498039, 0.498039, 0.498039, 1)
texture_filter = 1
material = SubResource("ShaderMaterial_7ckhc")
position = Vector2(0, -13)
texture = ExtResource("3_mgryv")
hframes = 20
[node name="AnimationTree" type="AnimationTree" parent="."]
libraries = {
"": ExtResource("4_tcpux")
}
tree_root = SubResource("AnimationNodeStateMachine_b0avg")
parameters/conditions/is_moving = false
parameters/conditions/melee = false
parameters/cut_walk/blend_position = Vector2(0.116751, -1.05556)
parameters/hurt/blend_position = Vector2(0.949916, -0.0132159)
parameters/idle/blend_position = Vector2(-0.0243112, 0.73545)
parameters/melee/blend_position = 0.0
parameters/melee/0/blend_position = Vector2(0.66778, -0.765217)
parameters/melee/1/blend_position = Vector2(-0.218698, 0.0434783)
parameters/melee/2/blend_position = Vector2(0, 0)
parameters/walk/blend_position = Vector2(-0.0100167, -0.0729166)
[node name="Hitbox" type="Area2D" parent="."]
position = Vector2(0, 1)
collision_layer = 2
collision_mask = 10
metadata/_edit_lock_ = true
[node name="Collider" type="CollisionShape2D" parent="Hitbox"]
position = Vector2(0, -13)
shape = SubResource("CapsuleShape2D_vm050")
debug_color = Color(1, 0.133333, 0.321569, 0.419608)
[node name="MovementCollider" type="CollisionShape2D" parent="."]
position = Vector2(-0.5, -1)
shape = SubResource("RectangleShape2D_bdqvd")
[node name="Attackbox" type="Area2D" parent="."]
position = Vector2(0, 1)
collision_layer = 8
collision_mask = 2
input_pickable = false
[node name="Collider" type="CollisionShape2D" parent="Attackbox"]
position = Vector2(0, -10)
shape = SubResource("CapsuleShape2D_m3ug4")
disabled = true
debug_color = Color(0.745098, 0.462745, 0, 0.419608)
[node name="Meleebox" type="Area2D" parent="."]
collision_layer = 4
[node name="DetectionArea" type="CollisionShape2D" parent="Meleebox"]
position = Vector2(0, -12)
shape = SubResource("CapsuleShape2D_hxosv")
debug_color = Color(0.784314, 0.423529, 0.27451, 0.419608)
[node name="StateMachine" type="Node" parent="."]
script = ExtResource("5_pgbft")
[node name="Root" type="Node" parent="StateMachine"]
script = ExtResource("6_a7x4q")
initial_state = NodePath("Think")
[node name="Think" type="Node" parent="StateMachine/Root"]
script = ExtResource("7_jc1pg")
[node name="ToVictory" type="Node" parent="StateMachine/Root/Think"]
script = ExtResource("8_713tw")
to = NodePath("../../Victory")
event = &"has_won"
delay_in_seconds = "0.0"
[node name="ToHurt" type="Node" parent="StateMachine/Root/Think"]
script = ExtResource("8_713tw")
to = NodePath("../../Hurt")
event = &"been_hurt"
delay_in_seconds = "0.0"
[node name="ToMelee" type="Node" parent="StateMachine/Root/Think"]
script = ExtResource("8_713tw")
to = NodePath("../../Melee")
event = &"will_melee"
delay_in_seconds = "0.0"
[node name="ToApproach" type="Node" parent="StateMachine/Root/Think"]
script = ExtResource("8_713tw")
to = NodePath("../../Approach")
event = &"wants_tomelee"
guard = SubResource("Resource_ri8lv")
delay_in_seconds = "0.0"
[node name="ToChase" type="Node" parent="StateMachine/Root/Think"]
script = ExtResource("8_713tw")
to = NodePath("../../Chase")
event = &"wants_tomelee"
guard = SubResource("Resource_gtfv8")
delay_in_seconds = "0.0"
[node name="Approach" type="Node" parent="StateMachine/Root"]
script = ExtResource("7_jc1pg")
[node name="ToVictory" type="Node" parent="StateMachine/Root/Approach"]
script = ExtResource("8_713tw")
to = NodePath("../../Victory")
event = &"has_won"
delay_in_seconds = "0.0"
[node name="ToHurt" type="Node" parent="StateMachine/Root/Approach"]
script = ExtResource("8_713tw")
to = NodePath("../../Hurt")
event = &"been_hurt"
delay_in_seconds = "0.0"
[node name="ToMelee" type="Node" parent="StateMachine/Root/Approach"]
script = ExtResource("8_713tw")
to = NodePath("../../Melee")
event = &"will_melee"
delay_in_seconds = "0.0"
[node name="ToThink" type="Node" parent="StateMachine/Root/Approach"]
script = ExtResource("8_713tw")
to = NodePath("../../Think")
event = &"approach_complete"
delay_in_seconds = "0.0"
[node name="Chase" type="Node" parent="StateMachine/Root"]
script = ExtResource("7_jc1pg")
[node name="ToVictory" type="Node" parent="StateMachine/Root/Chase"]
script = ExtResource("8_713tw")
to = NodePath("../../Victory")
event = &"has_won"
delay_in_seconds = "0.0"
[node name="ToHurt" type="Node" parent="StateMachine/Root/Chase"]
script = ExtResource("8_713tw")
to = NodePath("../../Hurt")
event = &"been_hurt"
delay_in_seconds = "0.0"
[node name="ToMelee" type="Node" parent="StateMachine/Root/Chase"]
script = ExtResource("8_713tw")
to = NodePath("../../Melee")
event = &"will_melee"
delay_in_seconds = "0.0"
[node name="ToThink" type="Node" parent="StateMachine/Root/Chase"]
script = ExtResource("8_713tw")
to = NodePath("../../Think")
event = &"melee_aborted"
delay_in_seconds = "0.0"
[node name="Melee" type="Node" parent="StateMachine/Root"]
script = ExtResource("7_jc1pg")
[node name="ToVictory" type="Node" parent="StateMachine/Root/Melee"]
script = ExtResource("8_713tw")
to = NodePath("../../Victory")
event = &"has_won"
delay_in_seconds = "0.0"
[node name="ToHurt" type="Node" parent="StateMachine/Root/Melee"]
script = ExtResource("8_713tw")
to = NodePath("../../Hurt")
event = &"been_hurt"
delay_in_seconds = "0.0"
[node name="ToThink" type="Node" parent="StateMachine/Root/Melee"]
script = ExtResource("8_713tw")
to = NodePath("../../Think")
event = &"melee_complete"
delay_in_seconds = "0.0"
[node name="Hurt" type="Node" parent="StateMachine/Root"]
script = ExtResource("7_jc1pg")
[node name="ToDefeat" type="Node" parent="StateMachine/Root/Hurt"]
script = ExtResource("8_713tw")
to = NodePath("../../Defeat")
event = &"been_defeated"
delay_in_seconds = "0.0"
[node name="ToThink" type="Node" parent="StateMachine/Root/Hurt"]
script = ExtResource("8_713tw")
to = NodePath("../../Think")
event = &"hurt_complete"
delay_in_seconds = "0.0"
[node name="ToHurtReposition" type="Node" parent="StateMachine/Root/Hurt"]
script = ExtResource("8_713tw")
to = NodePath("../../HurtReposition")
event = &"will_reposition"
delay_in_seconds = "0.0"
[node name="HurtReposition" type="Node" parent="StateMachine/Root"]
script = ExtResource("7_jc1pg")
[node name="ToThink" type="Node" parent="StateMachine/Root/HurtReposition"]
script = ExtResource("8_713tw")
to = NodePath("../../Think")
event = &"hurt_complete"
delay_in_seconds = "0.0"
[node name="Defeat" type="Node" parent="StateMachine/Root"]
script = ExtResource("7_jc1pg")
[node name="Victory" type="Node" parent="StateMachine/Root"]
script = ExtResource("7_jc1pg")
[connection signal="animation_finished" from="AnimationTree" to="." method="_on_animation_tree_animation_finished"]
[connection signal="area_entered" from="Attackbox" to="." method="_on_attackbox_area_entered"]
[connection signal="body_entered" from="Meleebox" to="." method="_on_meleebox_body_entered"]
[connection signal="body_exited" from="Meleebox" to="." method="_on_meleebox_body_exited"]
[connection signal="state_entered" from="StateMachine/Root/Think" to="." method="_on_think_state_entered"]
[connection signal="state_processing" from="StateMachine/Root/Think" to="." method="_on_think_state_processing"]
[connection signal="state_entered" from="StateMachine/Root/Approach" to="." method="_on_approach_state_entered"]
[connection signal="state_exited" from="StateMachine/Root/Approach" to="." method="_on_approach_state_exited"]
[connection signal="state_processing" from="StateMachine/Root/Approach" to="." method="_on_approach_state_processing"]
[connection signal="taken" from="StateMachine/Root/Approach/ToThink" to="." method="_on_approach_to_think_taken"]
[connection signal="state_entered" from="StateMachine/Root/Chase" to="." method="_on_chase_state_entered"]
[connection signal="state_exited" from="StateMachine/Root/Chase" to="." method="_on_chase_state_exited"]
[connection signal="state_processing" from="StateMachine/Root/Chase" to="." method="_on_chase_state_processing"]
[connection signal="taken" from="StateMachine/Root/Chase/ToThink" to="." method="_on_chase_to_think_taken"]
[connection signal="state_entered" from="StateMachine/Root/Melee" to="." method="_on_melee_state_entered"]
[connection signal="state_exited" from="StateMachine/Root/Melee" to="." method="_on_melee_state_exited"]
[connection signal="state_processing" from="StateMachine/Root/Melee" to="." method="_on_melee_state_processing"]
[connection signal="state_entered" from="StateMachine/Root/Hurt" to="." method="_on_hurt_state_entered"]
[connection signal="state_exited" from="StateMachine/Root/Hurt" to="." method="_on_hurt_state_exited"]
[connection signal="state_entered" from="StateMachine/Root/HurtReposition" to="." method="_on_hurt_reposition_state_entered"]
[connection signal="state_exited" from="StateMachine/Root/HurtReposition" to="." method="_on_hurt_reposition_state_exited"]
[connection signal="state_entered" from="StateMachine/Root/Defeat" to="." method="_on_defeat_state_entered"]
[connection signal="state_entered" from="StateMachine/Root/Victory" to="." method="_on_victory_state_entered"]

View file

@ -0,0 +1,52 @@
extends CharacterBody2D
class_name CharacterBase
@export_group("Movement")
@export_range(1.0, 999999.9, 0.1) var speed: float = 100.0
@export_group("Combat")
@export var max_health: int = 100
@export_range(0, 999999, 1) var health: int = 100
@export var attack_power: int = 30
@export var KNOCKBACK_POWER: float = 40
@export var KNOCKBACK_RANDOMNESS: float = 50
signal attack_did_hit(other: Area2D, power: int, attack_direction: Vector2)
signal got_hurt(new_health: int)
signal defeated
# Related nodes
@onready var anim_tree: AnimationTree = $AnimationTree
@onready var anim_playback: AnimationNodeStateMachinePlayback = anim_tree["parameters/playback"]
# Cutscene movement
var movement_scripted_by: CutsceneManager = null
var movement_scripted_target: Vector2
var movement_scripted_speed = 0.0
func set_animation_direction(direction: Vector2):
pass
func _physics_process(_delta):
move_and_slide()
func _on_animation_tree_animation_finished(anim_name):
pass
func _on_enemy_attack_did_hit(other: Area2D, power: int, attack_direction: Vector2):
pass
func _on_attackbox_area_entered(area: Area2D):
pass
func _on_cutscene_issued_command(command: CutsceneCommand, manager: CutsceneManager):
if command is MoveCharacterCommand:
var target_character = manager.get_node(command.target_character)
if target_character != self:
return
movement_scripted_target = command.target_vector if command.target_type == "Vector" else manager.get_node(command.target_node).global_position
var approach_direction = global_position.direction_to(movement_scripted_target)
set_animation_direction(approach_direction)
velocity = command.speed * approach_direction
movement_scripted_by = manager
movement_scripted_speed = command.speed
anim_playback.travel(command.animation_state)

View file

@ -1,6 +1,6 @@
class_name LookAtTargetCommand extends CutsceneCommand
@export_node_path("CharacterBody2D") var character: NodePath
@export_node_path("CharacterBase") var character: NodePath
@export_node_path("Node2D") var lookat_target: NodePath
func get_direction(manager: CutsceneManager) -> Vector2:

View file

@ -3,7 +3,7 @@ extends CutsceneCommand
class_name MoveCharacterCommand
@export_group("Setup")
@export_node_path("CharacterBody2D") var target_character: NodePath
@export_node_path("CharacterBase") var target_character: NodePath
@export_enum("Node", "Vector") var target_type = "Node":
set(value):
target_type = value

View file

@ -1,7 +1,7 @@
extends CutsceneCommand
class_name TurnCharacterCommand
@export_node_path("CharacterBody2D") var character: NodePath
@export_node_path("CharacterBase") var character: NodePath
@export var facing_direction: Util.CardinalDirection
var _directions = [

View file

@ -4,19 +4,20 @@ extends Node2D
@onready var battle_ui = $CanvasLayer/BattleUI
@onready var player = $HiroPlayer
@onready var ai = $HiroAI
@onready var cutscene_manager = $CutsceneManager
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()
cutscene_manager.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()
cutscene_manager.load_cutscene(cutscene)
cutscene_manager.step()
func _on_ai_defeated():
if Globals.nsfw == true:
@ -26,19 +27,20 @@ func _on_cutscene_started(cutscene_name):
$HiroPlayer.can_move = false
if cutscene_name == "prototype_start":
$HiroAI.set_ai_enabled(false)
$ReedAI.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)
$ReedAI.set_ai_enabled(true)
func _on_cutscene_manager_issued_command(command: CutsceneCommand, manager: CutsceneManager):
if command is TurnCharacterCommand or command is LookAtTargetCommand:
var character = manager.get_node(command.character)
# TODO: We need to set a common class for character nodes.
var face_direction = command.get_direction(manager)
assert(character is CharacterBody2D and character.has_method("set_animation_direction"))
var character: CharacterBase = manager.get_node(command.character)
var face_direction: Vector2 = command.get_direction(manager)
assert(character is CharacterBase)
character.set_animation_direction(face_direction)
manager.step()

View file

@ -1,20 +1,22 @@
class_name AICharacter
extends CharacterBody2D
extends CharacterBase
@export_group("Combat")
@export var player_character: PlayableCharacter
@export var health = 100
@export var attack_power = 30
@export var KNOCKBACK_POWER = 40
@export var KNOCKBACK_REPOSITION_POWER = 75
@export var KNOCKBACK_RANDOMNESS = 50
@export var MELEE_RADIUS = 75
@export var chase_speed = 65
@export var approach_speed = 40
@export var min_recoil_time = 3.0/60.0
@export var max_recoil_time = 1.0
@export var reduce_recoil_time_threshold = 58.0/60.0
@onready var anim_tree: AnimationTree = $AnimationTree
@onready var anim_playback: AnimationNodeStateMachinePlayback = anim_tree["parameters/playback"]
# Node components
@onready var hitbox = $Hitbox
@onready var attack_hitbox = $Attackbox
@onready var attack_hitbox_collider = $Attackbox/Collider
@onready var hitbox_collider = $Attackbox/Collider
@onready var state_machine: StateChart = $StateMachine
var timer = 0
@ -28,15 +30,6 @@ var attack_counter_limit = 0
var wants_to_melee = false
# Cutscene movement
var movement_scripted_by: CutsceneManager = null
var movement_scripted_target: Vector2
var movement_scripted_speed = 0.0
signal got_hurt(new_health: int)
signal attack_did_hit(other: Area2D, power: int, attack_direction: Vector2)
signal defeated
func _ready():
state_machine.set_expression_property("melee_stage", 0)
@ -47,7 +40,7 @@ func set_animation_direction(facing_direction: Vector2):
anim_tree.set("parameters/melee/1/blend_position", facing_direction)
anim_tree.set("parameters/melee/2/blend_position", facing_direction)
anim_tree.set("parameters/hurt/blend_position", facing_direction)
anim_tree.set("parameters/walk_cutscene/blend_position", facing_direction)
anim_tree.set("parameters/cut_walk/blend_position", facing_direction)
func follow_player(speed: float):
var approach_direction = global_position.direction_to(player_character.global_position)
@ -72,7 +65,7 @@ func _on_player_attack_did_hit(other, attack_power: int, attack_direction: Vecto
_on_ai_got_hurt(attack_power, attack_direction)
func set_ai_process_mode(mode: ProcessMode):
$StateMachine.process_mode = mode
state_machine.process_mode = mode
func set_ai_enabled(enabled: bool):
set_ai_process_mode(Node.PROCESS_MODE_INHERIT if enabled else Node.PROCESS_MODE_DISABLED)
@ -80,7 +73,7 @@ func set_ai_enabled(enabled: bool):
func _on_ai_got_hurt(attack_power: int, attack_direction: Vector2):
attacked_from = attack_direction
received_damage = attack_power
$Attackbox/Collider.set_deferred("disabled", true)
attack_hitbox_collider.set_deferred("disabled", true)
state_machine.send_event("been_hurt")
## Thinking state
@ -146,7 +139,6 @@ func _on_hurt_reposition_state_entered():
set_collision_layer_value(1, false)
set_collision_mask_value(5, true)
set_collision_mask_value(1, false)
#$MovementCollider.set_deferred("disabled", true)
set_animation_direction(facing_direction)
anim_playback.travel("hurt")
velocity = attacked_from * KNOCKBACK_REPOSITION_POWER * -1
@ -157,7 +149,6 @@ func _on_hurt_reposition_state_exited():
set_collision_layer_value(1, true)
set_collision_mask_value(5, false)
set_collision_mask_value(1, true)
#$MovementCollider.set_deferred("disabled", false)
hit_counter = 0
func _on_animation_tree_animation_finished(anim_name):
@ -238,31 +229,14 @@ func _on_melee_state_processing(_delta):
func _on_melee_state_exited():
anim_tree.set("parameters/conditions/melee", false)
func _on_attackbox_area_entered(area):
attack_did_hit.emit(area, attack_power, anim_tree.get("parameters/melee/0/blend_position"))
func _on_victory_state_entered():
wants_to_melee = false
anim_tree.set("parameters/conditions/melee", false)
state_machine.set_expression_property("melee_stage", 0)
velocity = Vector2.ZERO
func _on_player_been_defeated():
state_machine.send_event("has_won")
func _on_cutscene_issued_command(command: CutsceneCommand, manager: CutsceneManager):
if command is MoveCharacterCommand:
var target_character = manager.get_node(command.target_character)
if target_character != self:
return
movement_scripted_target = command.target_vector if command.target_type == "Vector" else manager.get_node(command.target_node).global_position
var approach_direction = global_position.direction_to(movement_scripted_target)
set_animation_direction(approach_direction)
velocity = command.speed * approach_direction
movement_scripted_by = manager
movement_scripted_speed = command.speed
anim_playback.travel(command.animation_state)

View file

@ -1,40 +1,45 @@
class_name PlayableCharacter
extends CharacterBody2D
extends CharacterBase
@export var health = 100
@export var speed = 100
@export var KNOCKBACK_POWER = 40
@export var KNOCKBACK_RANDOMNESS = 50
var last_dpad: Array[Vector2] = [Vector2.ZERO,Vector2.ZERO]
const FACING_ANGLE_EPSILON = 15
# Node components
@onready var hitbox = $Hitbox
@onready var attack_hitbox = $Attackbox
@onready var attack_hitbox_collider = $Attackbox/Collider
@onready var hitbox_collider = $Attackbox/Collider
var can_move = true
@onready var animation_playback: AnimationNodeStateMachinePlayback = $AnimationTree.get("parameters/playback")
signal attack_did_hit(other: Area2D, power: int, attack_direction: Vector2)
signal got_hurt(new_health: int)
signal defeated
func _unhandled_input(event):
if event.is_action_pressed("melee") and can_move:
var animation_rng = randf_range(0, 1)
$AnimationTree.set("parameters/melee/blend_position", animation_rng)
$AnimationTree.set("parameters/conditions/melee", true)
anim_tree.set("parameters/melee/blend_position", animation_rng)
anim_tree.set("parameters/conditions/melee", true)
can_move = false
velocity = Vector2.ZERO
func _physics_process(_delta):
func _process(_delta):
if movement_scripted_by != null:
var distance_to_target = movement_scripted_target.distance_to(global_position)
if distance_to_target <= movement_scripted_speed/100.0:
global_position = movement_scripted_target
velocity = Vector2.ZERO
movement_scripted_by.step()
movement_scripted_by = null
anim_playback.travel("idle")
func _physics_process(delta):
get_input()
move_and_slide()
super._physics_process(delta)
func set_animation_direction(direction: Vector2):
$AnimationTree.set("parameters/idle/blend_position", direction)
$AnimationTree.set("parameters/walk/blend_position", direction)
$AnimationTree.set("parameters/melee/0/blend_position", direction)
$AnimationTree.set("parameters/melee/1/blend_position", direction)
$AnimationTree.set("parameters/melee/2/blend_position", direction)
$AnimationTree.set("parameters/hurt/blend_position", direction)
anim_tree.set("parameters/idle/blend_position", direction)
anim_tree.set("parameters/walk/blend_position", direction)
anim_tree.set("parameters/melee/0/blend_position", direction)
anim_tree.set("parameters/melee/1/blend_position", direction)
anim_tree.set("parameters/melee/2/blend_position", direction)
anim_tree.set("parameters/hurt/blend_position", direction)
func xor(a:bool, b:bool):
return a != b
@ -64,31 +69,26 @@ func get_input():
velocity = input_direction * speed
if input_direction == Vector2.ZERO:
$AnimationTree.set("parameters/conditions/is_moving", false)
anim_tree.set("parameters/conditions/is_moving", false)
else:
$AnimationTree.set("parameters/conditions/is_moving", true)
anim_tree.set("parameters/conditions/is_moving", true)
set_animation_direction(last_dpad[0])
func _on_attackbox_area_entered(area: Area2D):
var attack_vector: Vector2 = $AnimationTree.get("parameters/melee/0/blend_position")
var attack_vector: Vector2 = anim_tree.get("parameters/melee/0/blend_position")
attack_did_hit.emit(area, 15, attack_vector)
func _on_hiro_dummy_defeated():
print("Yaaaaay!!")
func _on_enemy_attack_did_hit(other, power, attack_direction):
if other.get_parent().get_instance_id() == get_instance_id() :
$Attackbox/Collider.set_deferred("disabled", true)
attack_hitbox_collider.set_deferred("disabled", true)
health = health - power
can_move = false
if health <= 0:
if Globals.nsfw:
animation_playback.travel("nsfw_defeated_start")
anim_playback.travel("nsfw_defeated_start")
else:
animation_playback.travel("defeated")
anim_playback.travel("defeated")
defeated.emit()
velocity = Vector2.ZERO
else:
@ -96,13 +96,13 @@ func _on_enemy_attack_did_hit(other, power, attack_direction):
set_animation_direction(facing_direction)
var knockback_direction = attack_direction.rotated(deg_to_rad(randf_range(-1, 1) * KNOCKBACK_RANDOMNESS))
velocity = KNOCKBACK_POWER * knockback_direction.normalized()
animation_playback.travel("hurt")
$AnimationTree.set("parameters/conditions/melee", false)
anim_playback.travel("hurt")
anim_tree.set("parameters/conditions/melee", false)
got_hurt.emit(health)
func _on_animation_tree_animation_finished(anim_name):
if anim_name.contains("hurt") or anim_name.contains("kick") or anim_name.contains("punch"):
can_move = true
$AnimationTree.set("parameters/conditions/melee", false)
anim_tree.set("parameters/conditions/melee", false)
if anim_name.contains("kick") or anim_name.contains("punch"):
$Attackbox/Collider.set_deferred("disabled", true)
attack_hitbox_collider.set_deferred("disabled", true)

View file

@ -1,4 +1,4 @@
[gd_scene load_steps=23 format=3 uid="uid://bxuxjqxxqy7ce"]
[gd_scene load_steps=24 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"]
@ -20,6 +20,7 @@
[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"]
[ext_resource type="PackedScene" uid="uid://bwrwh5of0jw4a" path="res://Reed/reed_ai.tscn" id="21_dioix"]
[sub_resource type="Gradient" id="Gradient_3ox2i"]
colors = PackedColorArray(0, 0, 0, 1, 0, 0, 0, 1)
@ -50,6 +51,9 @@ grow_vertical = 2
[node name="StateChartDebugger" parent="CanvasLayer/Debug" instance=ExtResource("2_o5str")]
layout_mode = 1
offset_right = 81.24
offset_bottom = 155.0
scale = Vector2(0.75, 0.75)
size_flags_horizontal = 0
enabled = false
initial_node_to_watch = NodePath("../../../HiroAI")
@ -110,7 +114,6 @@ texture = ExtResource("7_pp5dn")
[node name="HiroPlayer" parent="." instance=ExtResource("1_c1gpq")]
position = Vector2(-44, -12)
speed = 70
[node name="Camera2D" type="Camera2D" parent="HiroPlayer"]
texture_filter = 1
@ -139,11 +142,10 @@ polygon = PackedVector2Array(158.522, 76.9076, 161.916, 75.961, 172.213, 75.961,
[node name="HiroAI" parent="." node_paths=PackedStringArray("player_character") instance=ExtResource("5_r7nw4")]
position = Vector2(-1, 67)
player_character = NodePath("../HiroPlayer")
health = 400
attack_power = 10
KNOCKBACK_POWER = 60
KNOCKBACK_REPOSITION_POWER = 90
MELEE_RADIUS = 300
health = 400
attack_power = 10
[node name="ExplosionGenerator" type="Node" parent="."]
script = ExtResource("9_df2wo")
@ -189,10 +191,20 @@ texture = ExtResource("16_cgyrp")
script = ExtResource("19_5yvrq")
cutscene = ExtResource("20_elypl")
[node name="ReedAI" parent="." node_paths=PackedStringArray("player_character") instance=ExtResource("21_dioix")]
position = Vector2(64, -16)
player_character = NodePath("../HiroPlayer")
KNOCKBACK_REPOSITION_POWER = 90
MELEE_RADIUS = 300
reduce_recoil_time_threshold = 0.75
health = 400
attack_power = 10
[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"]
[connection signal="defeated" from="HiroPlayer" to="ReedAI" method="_on_player_been_defeated"]
[connection signal="got_hurt" from="HiroPlayer" to="CanvasLayer/BattleUI" method="_on_player_got_hurt"]
[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"]
@ -203,3 +215,6 @@ cutscene = ExtResource("20_elypl")
[connection signal="issued_command" from="CutsceneManager" to="HiroAI" method="_on_cutscene_issued_command"]
[connection signal="issued_command" from="CutsceneManager" to="CutsceneManager" method="_on_issued_command"]
[connection signal="started" from="CutsceneManager" to="." method="_on_cutscene_started"]
[connection signal="attack_did_hit" from="ReedAI" to="HiroPlayer" method="_on_enemy_attack_did_hit"]
[connection signal="defeated" from="ReedAI" to="." method="_on_ai_defeated"]
[connection signal="got_hurt" from="ReedAI" to="CanvasLayer/BattleUI" method="_on_enemy_got_hurt"]