diff --git a/Hiro/hiro_player.tscn b/Hiro/hiro_player.tscn index d710564..cfda319 100644 --- a/Hiro/hiro_player.tscn +++ b/Hiro/hiro_player.tscn @@ -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 diff --git a/Reed/reed_ai.tscn b/Reed/reed_ai.tscn new file mode 100644 index 0000000..1846e5d --- /dev/null +++ b/Reed/reed_ai.tscn @@ -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"] diff --git a/Scripts/Characters/base.gd b/Scripts/Characters/base.gd new file mode 100644 index 0000000..4ca400d --- /dev/null +++ b/Scripts/Characters/base.gd @@ -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) diff --git a/Scripts/Cutscenes/Commands/lookat_character.gd b/Scripts/Cutscenes/Commands/lookat_character.gd index e90c2c8..0af37ce 100644 --- a/Scripts/Cutscenes/Commands/lookat_character.gd +++ b/Scripts/Cutscenes/Commands/lookat_character.gd @@ -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: diff --git a/Scripts/Cutscenes/Commands/move_character.gd b/Scripts/Cutscenes/Commands/move_character.gd index c3ce5c8..769bb98 100644 --- a/Scripts/Cutscenes/Commands/move_character.gd +++ b/Scripts/Cutscenes/Commands/move_character.gd @@ -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 diff --git a/Scripts/Cutscenes/Commands/turn_character.gd b/Scripts/Cutscenes/Commands/turn_character.gd index 5b32705..0c98ddc 100644 --- a/Scripts/Cutscenes/Commands/turn_character.gd +++ b/Scripts/Cutscenes/Commands/turn_character.gd @@ -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 = [ diff --git a/Scripts/Levels/arena_level.gd b/Scripts/Levels/arena_level.gd index c77afe1..489b8af 100644 --- a/Scripts/Levels/arena_level.gd +++ b/Scripts/Levels/arena_level.gd @@ -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() diff --git a/Scripts/hiro_ai.gd b/Scripts/hiro_ai.gd index 29155a7..8ce278c 100644 --- a/Scripts/hiro_ai.gd +++ b/Scripts/hiro_ai.gd @@ -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) diff --git a/Scripts/hiro_player.gd b/Scripts/hiro_player.gd index 652aa4d..b3fd9b7 100644 --- a/Scripts/hiro_player.gd +++ b/Scripts/hiro_player.gd @@ -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) diff --git a/world/world.tscn b/world/world.tscn index de74510..f1c96a5 100644 --- a/world/world.tscn +++ b/world/world.tscn @@ -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"]