diff --git a/Babushka.sln.DotSettings b/Babushka.sln.DotSettings
index ed91201..a4c6213 100644
--- a/Babushka.sln.DotSettings
+++ b/Babushka.sln.DotSettings
@@ -1,4 +1,5 @@
+ <Policy><Descriptor Staticness="Instance" AccessRightKinds="Protected, ProtectedInternal, Internal, Public, PrivateProtected" Description="Instance fields (not private)"><ElementKinds><Kind Name="FIELD" /><Kind Name="READONLY_FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="aaBb" /></Policy>
Godot Signal
[Signal]
public delegate void $SignalName$EventHandler($END$);
diff --git a/Babushka.sln.DotSettings.user b/Babushka.sln.DotSettings.user
index 274a05f..770ca7c 100644
--- a/Babushka.sln.DotSettings.user
+++ b/Babushka.sln.DotSettings.user
@@ -19,4 +19,15 @@
ForceIncluded
ForceIncluded
ForceIncluded
- ForceIncluded
\ No newline at end of file
+ ForceIncluded
+ ForceIncluded
+ ForceIncluded
+ ForceIncluded
+ ForceIncluded
+ ForceIncluded
+ ForceIncluded
+ <SessionState ContinuousTestingMode="0" IsActive="True" Name="Tests" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session">
+ <TestAncestor>
+ <TestId>NUnit3x::A6EF2269-9E64-40D4-BA0A-33CB234E2503::net9.0::BabushkaTest.Tests</TestId>
+ </TestAncestor>
+</SessionState>
diff --git a/prefabs/fight/fight_scene_switcher.tscn b/prefabs/fight/fight_scene_switcher.tscn
new file mode 100644
index 0000000..7a89541
--- /dev/null
+++ b/prefabs/fight/fight_scene_switcher.tscn
@@ -0,0 +1,9 @@
+[gd_scene load_steps=2 format=3 uid="uid://bcld43daavmrn"]
+
+[ext_resource type="Script" uid="uid://cql8mt5jsmcdl" path="res://scripts/CSharp/Common/Fight/FightSceneSwitcher.cs" id="1_5dt1r"]
+
+[node name="FightSceneSwitcher" type="Node" node_paths=PackedStringArray("sceneRoot")]
+script = ExtResource("1_5dt1r")
+sceneRoot = NodePath("")
+fightRoomScenePath = "res://scenes/Babushka_scene_fight_world_room.tscn"
+fightHappeningScene = "res://scenes/Babushka_scene_fight_happening.tscn"
diff --git a/prefabs/fightOld/fighters/enemy_blob_fighter.tscn b/prefabs/fight/fighters/enemy_blob_fighter.tscn
similarity index 91%
rename from prefabs/fightOld/fighters/enemy_blob_fighter.tscn
rename to prefabs/fight/fighters/enemy_blob_fighter.tscn
index 23f6c9e..bab5781 100644
--- a/prefabs/fightOld/fighters/enemy_blob_fighter.tscn
+++ b/prefabs/fight/fighters/enemy_blob_fighter.tscn
@@ -1,7 +1,7 @@
[gd_scene load_steps=10 format=3 uid="uid://bp64p6y72j71w"]
[ext_resource type="Texture2D" uid="uid://ccrnmx6bd842k" path="res://art/characters/farm fäulnis blobs.png" id="1_vem8k"]
-[ext_resource type="Script" uid="uid://by88f32fou7lh" path="res://scripts/CSharp/Common/FightOld/Fighter.cs" id="2_4w1ab"]
+[ext_resource type="Script" path="res://scripts/CSharp/Common/FightOld/Fighter.cs" id="2_4w1ab"]
[ext_resource type="Texture2D" uid="uid://qlfwuakhe57t" path="res://art/ui/UI/attack_select_wheel.png" id="3_v4f83"]
[ext_resource type="AudioStream" uid="uid://x7cc5woop5ec" path="res://audio/sfx/Battle/Enemies/SFX_Slime_Hit_V2_03.wav" id="5_v4f83"]
[ext_resource type="Texture2D" uid="uid://bn56p0ytuo060" path="res://art/ui/UI/AttackButton.png" id="5_vbkts"]
@@ -19,6 +19,7 @@ script = ExtResource("2_4w1ab")
name = "Blob"
maxHealth = 20
attackStrength = 10
+maxActions = null
_attackButtons = NodePath("FightButtons")
_targetButtons = NodePath("TargetButtons")
_targetMarker = NodePath("TargetButtons/TargetMarker")
@@ -95,9 +96,6 @@ stream = ExtResource("6_vbkts")
[node name="AttackAudio" type="AudioStreamPlayer" parent="."]
stream = ExtResource("6_oykh8")
-[connection signal="Attacking" from="." to="AttackAudio" method="play" binds= [0.0]]
-[connection signal="DamageTaken" from="." to="HitAudio" method="play" binds= [0.0]]
-[connection signal="Dying" from="." to="DieAudio" method="play" binds= [0.0]]
[connection signal="input_event" from="TargetButtons/Area2D" to="." method="TargetMouseEvent"]
[connection signal="mouse_entered" from="TargetButtons/Area2D" to="." method="StartHoverTarget"]
[connection signal="mouse_exited" from="TargetButtons/Area2D" to="." method="EndHoverTarget"]
diff --git a/prefabs/fightOld/fighters/enemy_mavkha_fighter.tscn b/prefabs/fight/fighters/enemy_mavkha_fighter.tscn
similarity index 88%
rename from prefabs/fightOld/fighters/enemy_mavkha_fighter.tscn
rename to prefabs/fight/fighters/enemy_mavkha_fighter.tscn
index 6c78582..d68c61d 100644
--- a/prefabs/fightOld/fighters/enemy_mavkha_fighter.tscn
+++ b/prefabs/fight/fighters/enemy_mavkha_fighter.tscn
@@ -1,6 +1,6 @@
[gd_scene load_steps=10 format=3 uid="uid://cr66tpdr5rma5"]
-[ext_resource type="Script" uid="uid://by88f32fou7lh" path="res://scripts/CSharp/Common/FightOld/Fighter.cs" id="1_t6th8"]
+[ext_resource type="Script" uid="uid://by88f32fou7lh" path="res://scripts/CSharp/Common/Fight/FighterVisual.cs" id="1_t6th8"]
[ext_resource type="Texture2D" uid="uid://bexymddkb6l0o" path="res://art/characters/Mavka/mavkha.png" id="2_shg7p"]
[ext_resource type="Texture2D" uid="uid://qlfwuakhe57t" path="res://art/ui/UI/attack_select_wheel.png" id="3_nkuei"]
[ext_resource type="Texture2D" uid="uid://bn56p0ytuo060" path="res://art/ui/UI/AttackButton.png" id="4_u3hw3"]
@@ -14,16 +14,8 @@ radius = 388.063
[sub_resource type="CircleShape2D" id="CircleShape2D_s74nc"]
radius = 173.44
-[node name="EnemyMavkhaFighter" type="Node2D" node_paths=PackedStringArray("_attackButtons", "_targetButtons", "_targetMarker", "_healthText", "_visualSprite")]
+[node name="EnemyMavkhaFighter" type="Node2D"]
script = ExtResource("1_t6th8")
-name = "Mavkha"
-maxHealth = 40
-attackStrength = 10
-_attackButtons = NodePath("FightButtons")
-_targetButtons = NodePath("TargetButtons")
-_targetMarker = NodePath("TargetButtons/TargetMarker")
-_healthText = NodePath("HealthShow")
-_visualSprite = NodePath("Visual")
[node name="Visual" type="Node2D" parent="."]
diff --git a/prefabs/fight/fighters/vesna_fighter.tscn b/prefabs/fight/fighters/vesna_fighter.tscn
new file mode 100644
index 0000000..35bfa8f
--- /dev/null
+++ b/prefabs/fight/fighters/vesna_fighter.tscn
@@ -0,0 +1,64 @@
+[gd_scene load_steps=7 format=3 uid="uid://cpanatqdjjpa3"]
+
+[ext_resource type="Script" path="res://scripts/CSharp/Common/FightOld/Fighter.cs" id="1_f3j2x"]
+[ext_resource type="Texture2D" uid="uid://om2axn1vfa5o" path="res://art/animation/Vesna2D/Vesna Anims Sequences/S01-Idle/0001.png" id="2_2ud32"]
+[ext_resource type="Texture2D" uid="uid://qlfwuakhe57t" path="res://art/ui/UI/attack_select_wheel.png" id="3_80knd"]
+[ext_resource type="AudioStream" uid="uid://ch4c1wh4ghxyo" path="res://audio/sfx/Battle/Vesna/SFX_Battle_Vesna_Defense_08.wav" id="5_4r2vf"]
+[ext_resource type="AudioStream" uid="uid://ccionrfr6e3lb" path="res://audio/sfx/Battle/Vesna/SFX_Battle_Vesna_Attack_04.wav" id="6_u1ayv"]
+
+[sub_resource type="CircleShape2D" id="CircleShape2D_0tqnl"]
+radius = 291.58
+
+[node name="VesnaFighter" type="Node2D" node_paths=PackedStringArray("_attackButtons", "_targetButtons", "_targetMarker", "_healthText", "_visualSprite")]
+script = ExtResource("1_f3j2x")
+name = "Vesna"
+maxHealth = 100
+attackStrength = 10
+maxActions = null
+_attackButtons = NodePath("")
+_targetButtons = NodePath("TargetButtons")
+_targetMarker = NodePath("TargetButtons/TargetMarker")
+_healthText = NodePath("HealthShow")
+_visualSprite = NodePath("Sprite2D")
+
+[node name="Sprite2D" type="Sprite2D" parent="."]
+texture = ExtResource("2_2ud32")
+offset = Vector2(43, -379)
+
+[node name="TargetButtons" type="Node2D" parent="."]
+visible = false
+
+[node name="TargetMarker" type="Sprite2D" parent="TargetButtons"]
+visible = false
+z_index = 200
+position = Vector2(8, -122)
+scale = Vector2(4.245, 4.245)
+texture = ExtResource("3_80knd")
+
+[node name="Area2D" type="Area2D" parent="TargetButtons"]
+position = Vector2(3, -76)
+
+[node name="CollisionShape2D" type="CollisionShape2D" parent="TargetButtons/Area2D"]
+shape = SubResource("CircleShape2D_0tqnl")
+
+[node name="HealthShow" type="Label" parent="."]
+z_index = 200
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+offset_left = -197.0
+offset_top = -947.0
+offset_right = 207.0
+offset_bottom = -801.0
+grow_horizontal = 2
+grow_vertical = 2
+theme_override_font_sizes/font_size = 106
+text = "100/100"
+horizontal_alignment = 1
+vertical_alignment = 1
+
+[node name="HitAudio" type="AudioStreamPlayer" parent="."]
+stream = ExtResource("5_4r2vf")
+
+[node name="AttackAudio" type="AudioStreamPlayer" parent="."]
+stream = ExtResource("6_u1ayv")
diff --git a/prefabs/fightOld/fight_manager_autoload.tscn b/prefabs/fightOld/fight_manager_autoload.tscn
index a7d72f2..6f6385b 100644
--- a/prefabs/fightOld/fight_manager_autoload.tscn
+++ b/prefabs/fightOld/fight_manager_autoload.tscn
@@ -1,7 +1,7 @@
[gd_scene load_steps=3 format=3 uid="uid://cnjsepvaqdbyq"]
[ext_resource type="Script" uid="uid://j5ge24rk25wm" path="res://scripts/CSharp/Common/FightOld/FightManager.cs" id="1_8p7ev"]
-[ext_resource type="PackedScene" uid="uid://cpanatqdjjpa3" path="res://prefabs/fightOld/fighters/vesna_fighter.tscn" id="2_ak1vo"]
+[ext_resource type="PackedScene" uid="uid://cpanatqdjjpa3" path="res://prefabs/fight/fighters/vesna_fighter.tscn" id="2_ak1vo"]
[node name="FightManagerAutoload" type="Node"]
script = ExtResource("1_8p7ev")
diff --git a/prefabs/fightOld/fighters/vesna_fighter.tscn b/prefabs/fightOld/fighters/vesna_fighter.tscn
deleted file mode 100644
index 841ac03..0000000
--- a/prefabs/fightOld/fighters/vesna_fighter.tscn
+++ /dev/null
@@ -1,123 +0,0 @@
-[gd_scene load_steps=11 format=3 uid="uid://cpanatqdjjpa3"]
-
-[ext_resource type="Script" uid="uid://by88f32fou7lh" path="res://scripts/CSharp/Common/FightOld/Fighter.cs" id="1_f3j2x"]
-[ext_resource type="Texture2D" uid="uid://om2axn1vfa5o" path="res://art/animation/Vesna2D/Vesna Anims Sequences/S01-Idle/0001.png" id="2_2ud32"]
-[ext_resource type="Texture2D" uid="uid://qlfwuakhe57t" path="res://art/ui/UI/attack_select_wheel.png" id="3_80knd"]
-[ext_resource type="AudioStream" uid="uid://ch4c1wh4ghxyo" path="res://audio/sfx/Battle/Vesna/SFX_Battle_Vesna_Defense_08.wav" id="5_4r2vf"]
-[ext_resource type="Texture2D" uid="uid://6h85o7fj7gmu" path="res://art/animation/Vesna3D/vesna-more-tools.png" id="5_l04qi"]
-[ext_resource type="Texture2D" uid="uid://crak7ton4lab0" path="res://art/ui/UI/EmptyFightButton.png" id="5_rjjub"]
-[ext_resource type="Texture2D" uid="uid://c3wht0nakaki1" path="res://art/ui/UI/icons/icon-fruit-tomatoe.png" id="6_l04qi"]
-[ext_resource type="AudioStream" uid="uid://ccionrfr6e3lb" path="res://audio/sfx/Battle/Vesna/SFX_Battle_Vesna_Attack_04.wav" id="6_u1ayv"]
-
-[sub_resource type="CircleShape2D" id="CircleShape2D_0tqnl"]
-radius = 291.58
-
-[sub_resource type="CircleShape2D" id="CircleShape2D_4r2vf"]
-radius = 173.44
-
-[node name="VesnaFighter" type="Node2D" node_paths=PackedStringArray("_attackButtons", "_targetButtons", "_targetMarker", "_healthText", "_visualSprite")]
-script = ExtResource("1_f3j2x")
-name = "Vesna"
-maxHealth = 100
-attackStrength = 10
-_attackButtons = NodePath("FightButtons")
-_targetButtons = NodePath("TargetButtons")
-_targetMarker = NodePath("TargetButtons/TargetMarker")
-_healthText = NodePath("HealthShow")
-_visualSprite = NodePath("Sprite2D")
-
-[node name="Sprite2D" type="Sprite2D" parent="."]
-texture = ExtResource("2_2ud32")
-offset = Vector2(43, -379)
-
-[node name="TargetButtons" type="Node2D" parent="."]
-visible = false
-
-[node name="TargetMarker" type="Sprite2D" parent="TargetButtons"]
-visible = false
-z_index = 200
-position = Vector2(8, -122)
-scale = Vector2(4.245, 4.245)
-texture = ExtResource("3_80knd")
-
-[node name="Area2D" type="Area2D" parent="TargetButtons"]
-position = Vector2(3, -76)
-
-[node name="CollisionShape2D" type="CollisionShape2D" parent="TargetButtons/Area2D"]
-shape = SubResource("CircleShape2D_0tqnl")
-
-[node name="FightButtons" type="Node2D" parent="."]
-position = Vector2(3, -714)
-
-[node name="CircleBackground" type="Sprite2D" parent="FightButtons"]
-z_index = 200
-scale = Vector2(4.245, 4.245)
-texture = ExtResource("3_80knd")
-
-[node name="AttackButton" type="Node2D" parent="FightButtons"]
-position = Vector2(0, -536)
-
-[node name="ButtonBackground" type="Sprite2D" parent="FightButtons/AttackButton"]
-z_index = 200
-scale = Vector2(2.48, 2.48)
-texture = ExtResource("5_rjjub")
-
-[node name="Sprite2D" type="Sprite2D" parent="FightButtons/AttackButton/ButtonBackground"]
-position = Vector2(6.04839, -10.0806)
-rotation = -1.0088
-scale = Vector2(0.249373, 0.25079)
-texture = ExtResource("5_l04qi")
-region_enabled = true
-region_rect = Rect2(291.897, 15.8974, 272.82, 479.385)
-
-[node name="Area2D" type="Area2D" parent="FightButtons/AttackButton"]
-collision_layer = 16
-
-[node name="CollisionShape2D" type="CollisionShape2D" parent="FightButtons/AttackButton/Area2D"]
-shape = SubResource("CircleShape2D_4r2vf")
-
-[node name="HealButton" type="Node2D" parent="FightButtons"]
-position = Vector2(427, -334)
-
-[node name="ButtonBackground" type="Sprite2D" parent="FightButtons/HealButton"]
-z_index = 200
-scale = Vector2(2.48, 2.48)
-texture = ExtResource("5_rjjub")
-
-[node name="Sprite2D" type="Sprite2D" parent="FightButtons/HealButton/ButtonBackground"]
-position = Vector2(4.83871, 0)
-scale = Vector2(0.279343, 0.279343)
-texture = ExtResource("6_l04qi")
-
-[node name="Area2D" type="Area2D" parent="FightButtons/HealButton"]
-collision_layer = 16
-
-[node name="CollisionShape2D" type="CollisionShape2D" parent="FightButtons/HealButton/Area2D"]
-shape = SubResource("CircleShape2D_4r2vf")
-
-[node name="HealthShow" type="Label" parent="."]
-z_index = 200
-anchors_preset = 15
-anchor_right = 1.0
-anchor_bottom = 1.0
-offset_left = -197.0
-offset_top = -947.0
-offset_right = 207.0
-offset_bottom = -801.0
-grow_horizontal = 2
-grow_vertical = 2
-theme_override_font_sizes/font_size = 106
-text = "100/100"
-horizontal_alignment = 1
-vertical_alignment = 1
-
-[node name="HitAudio" type="AudioStreamPlayer" parent="."]
-stream = ExtResource("5_4r2vf")
-
-[node name="AttackAudio" type="AudioStreamPlayer" parent="."]
-stream = ExtResource("6_u1ayv")
-
-[connection signal="Attacking" from="." to="AttackAudio" method="play" binds= [0.0]]
-[connection signal="DamageTaken" from="." to="HitAudio" method="play" binds= [0.0]]
-[connection signal="input_event" from="FightButtons/AttackButton/Area2D" to="." method="AttackMouseEvent"]
-[connection signal="input_event" from="FightButtons/HealButton/Area2D" to="." method="HealMouseEvent"]
diff --git a/scenes/Babushka_scene_fight_happening.tscn b/scenes/Babushka_scene_fight_happening.tscn
new file mode 100644
index 0000000..7aa492f
--- /dev/null
+++ b/scenes/Babushka_scene_fight_happening.tscn
@@ -0,0 +1,136 @@
+[gd_scene load_steps=4 format=3 uid="uid://cjshlwk8ajpnp"]
+
+[ext_resource type="Script" uid="uid://cnhpnn8o0gybd" path="res://scripts/CSharp/Common/Fight/FightHappeningSceneSetup.cs" id="1_fiutj"]
+[ext_resource type="Script" uid="uid://dwsqst8fhhqlc" path="res://scripts/CSharp/Common/Fight/FighterEntryVisual.cs" id="2_lu4y4"]
+[ext_resource type="PackedScene" uid="uid://bcld43daavmrn" path="res://prefabs/fight/fight_scene_switcher.tscn" id="2_phrlx"]
+
+[node name="BabushkaSceneFightHappening" type="Node2D"]
+
+[node name="Camera2D" type="Camera2D" parent="."]
+
+[node name="FightSetup" type="Node2D" parent="."]
+script = ExtResource("1_fiutj")
+
+[node name="FightVisuals" type="Node2D" parent="."]
+position = Vector2(0, 259)
+script = ExtResource("2_lu4y4")
+
+[node name="AllyFighters" type="Node2D" parent="FightVisuals"]
+
+[node name="EnemyFighters" type="Node2D" parent="FightVisuals"]
+
+[node name="EnvironmentVisuals" type="Node2D" parent="."]
+
+[node name="FightSceneSwitcher" parent="." instance=ExtResource("2_phrlx")]
+
+[node name="ActionSelect" type="CanvasLayer" parent="."]
+
+[node name="BottomPanel" type="Control" parent="ActionSelect"]
+custom_minimum_size = Vector2(0, 200)
+layout_mode = 3
+anchors_preset = 12
+anchor_top = 1.0
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 0
+size_flags_vertical = 8
+
+[node name="background" type="ColorRect" parent="ActionSelect/BottomPanel"]
+layout_mode = 1
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+color = Color(1, 1, 1, 0.27451)
+
+[node name="VBoxContainer" type="VBoxContainer" parent="ActionSelect/BottomPanel"]
+layout_mode = 1
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+
+[node name="MarginContainer" type="MarginContainer" parent="ActionSelect/BottomPanel/VBoxContainer"]
+layout_mode = 2
+size_flags_vertical = 3
+theme_override_constants/margin_left = 200
+theme_override_constants/margin_right = 200
+
+[node name="HBoxContainer" type="HBoxContainer" parent="ActionSelect/BottomPanel/VBoxContainer/MarginContainer"]
+layout_mode = 2
+alignment = 1
+
+[node name="MarginContainer" type="MarginContainer" parent="ActionSelect/BottomPanel/VBoxContainer/MarginContainer/HBoxContainer"]
+layout_mode = 2
+size_flags_horizontal = 3
+theme_override_constants/margin_left = 10
+theme_override_constants/margin_top = 10
+theme_override_constants/margin_right = 10
+theme_override_constants/margin_bottom = 10
+
+[node name="AttackButton" type="Button" parent="ActionSelect/BottomPanel/VBoxContainer/MarginContainer/HBoxContainer/MarginContainer"]
+layout_mode = 2
+theme_override_font_sizes/font_size = 41
+text = "Attack"
+
+[node name="MarginContainer2" type="MarginContainer" parent="ActionSelect/BottomPanel/VBoxContainer/MarginContainer/HBoxContainer"]
+layout_mode = 2
+size_flags_horizontal = 3
+theme_override_constants/margin_left = 10
+theme_override_constants/margin_top = 10
+theme_override_constants/margin_right = 10
+theme_override_constants/margin_bottom = 10
+
+[node name="Summon Button" type="Button" parent="ActionSelect/BottomPanel/VBoxContainer/MarginContainer/HBoxContainer/MarginContainer2"]
+layout_mode = 2
+theme_override_font_sizes/font_size = 41
+text = "Summon"
+
+[node name="MarginContainer3" type="MarginContainer" parent="ActionSelect/BottomPanel/VBoxContainer/MarginContainer/HBoxContainer"]
+layout_mode = 2
+size_flags_horizontal = 3
+theme_override_constants/margin_left = 10
+theme_override_constants/margin_top = 10
+theme_override_constants/margin_right = 10
+theme_override_constants/margin_bottom = 10
+
+[node name="Talk Button" type="Button" parent="ActionSelect/BottomPanel/VBoxContainer/MarginContainer/HBoxContainer/MarginContainer3"]
+layout_mode = 2
+theme_override_font_sizes/font_size = 41
+text = "Talk"
+
+[node name="MarginContainer4" type="MarginContainer" parent="ActionSelect/BottomPanel/VBoxContainer/MarginContainer/HBoxContainer"]
+layout_mode = 2
+size_flags_horizontal = 3
+theme_override_constants/margin_left = 10
+theme_override_constants/margin_top = 10
+theme_override_constants/margin_right = 10
+theme_override_constants/margin_bottom = 10
+
+[node name="Flee Button" type="Button" parent="ActionSelect/BottomPanel/VBoxContainer/MarginContainer/HBoxContainer/MarginContainer4"]
+layout_mode = 2
+theme_override_font_sizes/font_size = 41
+text = "Flee"
+
+[node name="MarginContainer2" type="MarginContainer" parent="ActionSelect/BottomPanel/VBoxContainer"]
+layout_mode = 2
+size_flags_vertical = 3
+theme_override_constants/margin_left = 200
+theme_override_constants/margin_right = 200
+
+[node name="MarginContainer" type="MarginContainer" parent="ActionSelect/BottomPanel/VBoxContainer/MarginContainer2"]
+layout_mode = 2
+theme_override_constants/margin_left = 10
+theme_override_constants/margin_top = 10
+theme_override_constants/margin_right = 10
+theme_override_constants/margin_bottom = 10
+
+[node name="Label" type="Label" parent="ActionSelect/BottomPanel/VBoxContainer/MarginContainer2/MarginContainer"]
+layout_mode = 2
+size_flags_vertical = 1
+theme_override_colors/font_color = Color(0, 0, 0, 1)
+theme_override_font_sizes/font_size = 41
+text = "This text explains the currently hovered button"
diff --git a/scenes/Babushka_scene_fight_world_room.tscn b/scenes/Babushka_scene_fight_world_room.tscn
index f041d8f..9dc77c7 100644
--- a/scenes/Babushka_scene_fight_world_room.tscn
+++ b/scenes/Babushka_scene_fight_world_room.tscn
@@ -38,8 +38,8 @@
[ext_resource type="Texture2D" uid="uid://bely5cfbf2x52" path="res://art/nature/baum märz 2025/umgeknackst.png" id="36_vwtyh"]
[ext_resource type="Script" uid="uid://bryibv73x5iwr" path="res://scripts/CSharp/Common/Fight/NextRoomTrigger.cs" id="37_3y3c4"]
[ext_resource type="Script" uid="uid://dpkx2gbg7b5xh" path="res://scripts/CSharp/Common/Fight/PathSetup.cs" id="37_elhbh"]
-[ext_resource type="Script" uid="uid://dbu8afaiohpdh" path="res://scripts/CSharp/Common/Fight/FightSceneSetup.cs" id="37_hqa4k"]
-[ext_resource type="Script" uid="uid://cql8mt5jsmcdl" path="res://scripts/CSharp/Common/Fight/FightSceneSwitcher.cs" id="38_ir2xa"]
+[ext_resource type="Script" path="res://scripts/CSharp/Common/Fight/FightSceneSetup.cs" id="37_hqa4k"]
+[ext_resource type="PackedScene" uid="uid://bcld43daavmrn" path="res://prefabs/fight/fight_scene_switcher.tscn" id="40_elhbh"]
[sub_resource type="ShaderMaterial" id="ShaderMaterial_ruj2u"]
shader = ExtResource("16_0fard")
@@ -89,15 +89,15 @@ noise = SubResource("FastNoiseLite_wgikv")
[sub_resource type="ShaderMaterial" id="ShaderMaterial_yvxfs"]
shader = ExtResource("27_txtka")
-shader_parameter/speed = 1.0
-shader_parameter/minStrength = 0.05
-shader_parameter/maxStrength = 0.187
-shader_parameter/strengthScale = 100.0
-shader_parameter/interval = 3.5
-shader_parameter/detail = 2.095
+shader_parameter/speed = 0.4
+shader_parameter/minStrength = 0.101
+shader_parameter/maxStrength = 0.392
+shader_parameter/strengthScale = 270.22
+shader_parameter/interval = 36.75
+shader_parameter/detail = 3.68
shader_parameter/distortion = 1.0
-shader_parameter/heightOffset = 0.51
-shader_parameter/offset = 1.0
+shader_parameter/heightOffset = 0.49
+shader_parameter/offset = 0.2
[sub_resource type="RectangleShape2D" id="RectangleShape2D_ir2xa"]
size = Vector2(608, 1256)
@@ -729,6 +729,34 @@ position = Vector2(3888, 2688)
scale = Vector2(16, 5.48)
texture = SubResource("NoiseTexture2D_pjpt5")
+[node name="ParalaxForeground" type="ParallaxBackground" parent="."]
+layer = 1
+
+[node name="fg1" type="ParallaxLayer" parent="ParalaxForeground"]
+position = Vector2(-897, -245)
+motion_scale = Vector2(1.2, 1.2)
+motion_mirroring = Vector2(8192, 0)
+
+[node name="TreeA4" type="Sprite2D" parent="ParalaxForeground/fg1"]
+z_index = 120
+material = SubResource("ShaderMaterial_yvxfs")
+position = Vector2(9188, 5991)
+scale = Vector2(3.26718, 4.50965)
+texture = ExtResource("35_g3bna")
+region_enabled = true
+region_rect = Rect2(0, 0, 1405.76, 1244)
+
+[node name="TreeA5" type="Sprite2D" parent="ParalaxForeground/fg1"]
+modulate = Color(0.865081, 0.854544, 0.930309, 1)
+z_index = 120
+material = SubResource("ShaderMaterial_yvxfs")
+position = Vector2(14366, 5831)
+scale = Vector2(3.26718, 4.50965)
+texture = ExtResource("35_g3bna")
+flip_h = true
+region_enabled = true
+region_rect = Rect2(0, 0, 1405.76, 1244)
+
[node name="YSorted" type="Node2D" parent="."]
z_index = 1
y_sort_enabled = true
@@ -1846,15 +1874,6 @@ texture = ExtResource("35_g3bna")
region_enabled = true
region_rect = Rect2(0, 0, 1405.76, 1244)
-[node name="TreeA4" type="Sprite2D" parent="YSorted/ForestVisuals/Static/greenery/trees"]
-z_index = 120
-material = SubResource("ShaderMaterial_yvxfs")
-position = Vector2(23840, 5685)
-scale = Vector2(3.26718, 4.50965)
-texture = ExtResource("35_g3bna")
-region_enabled = true
-region_rect = Rect2(0, 0, 1405.76, 1244)
-
[node name="TreeA2" type="Sprite2D" parent="YSorted/ForestVisuals/Static/greenery/trees"]
z_index = -1
material = SubResource("ShaderMaterial_yvxfs")
@@ -2009,7 +2028,7 @@ scale = Vector2(1, 1)
z_index = 100
y_sort_enabled = true
material = SubResource("ShaderMaterial_yvxfs")
-position = Vector2(411, 868)
+position = Vector2(304, 1029)
rotation = 3.14159
scale = Vector2(5.54387, -3.80466)
texture = ExtResource("19_edja8")
@@ -2099,7 +2118,7 @@ scale = Vector2(1, 1)
z_index = 100
y_sort_enabled = true
material = SubResource("ShaderMaterial_yvxfs")
-position = Vector2(653, -450)
+position = Vector2(559, -459)
rotation = 3.14159
scale = Vector2(5.54387, -3.80466)
texture = ExtResource("19_edja8")
@@ -2122,11 +2141,8 @@ unique_name_in_owner = true
script = ExtResource("37_hqa4k")
debugLabel = NodePath("../Debug Label")
-[node name="FightSceneSwitcher" type="Node" parent="." node_paths=PackedStringArray("sceneRoot")]
+[node name="FightSceneSwitcher" parent="." instance=ExtResource("40_elhbh")]
unique_name_in_owner = true
-script = ExtResource("38_ir2xa")
-sceneRoot = NodePath("..")
-fightRoomScenePath = "res://scenes/Babushka_scene_fight_world_room.tscn"
[node name="Debug Label" type="Label" parent="."]
offset_left = 10485.0
diff --git a/scenes/Babushka_scene_forest_fight_1_2d.tscn b/scenes/Babushka_scene_forest_fight_1_2d.tscn
index 860d079..ba1e6b3 100644
--- a/scenes/Babushka_scene_forest_fight_1_2d.tscn
+++ b/scenes/Babushka_scene_forest_fight_1_2d.tscn
@@ -26,10 +26,10 @@
[ext_resource type="Shader" uid="uid://xnky830dtfsn" path="res://shader/repeat_texture.gdshader" id="25_sgom5"]
[ext_resource type="Script" uid="uid://di0xxwfw43m0i" path="res://scripts/CSharp/Common/FightOld/FightStarter.cs" id="26_gg38r"]
[ext_resource type="PackedScene" uid="uid://hk8ahyp6dgl6" path="res://prefabs/fightOld/fight_base_scene.tscn" id="27_55b52"]
-[ext_resource type="PackedScene" uid="uid://bp64p6y72j71w" path="res://prefabs/fightOld/fighters/enemy_blob_fighter.tscn" id="27_hfhye"]
+[ext_resource type="PackedScene" uid="uid://bp64p6y72j71w" path="res://prefabs/fight/fighters/enemy_blob_fighter.tscn" id="27_hfhye"]
[ext_resource type="PackedScene" uid="uid://c25udixd5m6l0" path="res://prefabs/characters/Player2D.tscn" id="29_3jjxs"]
[ext_resource type="PackedScene" uid="uid://ddpl8cbck7e6s" path="res://prefabs/characters/Chugar.tscn" id="29_26tkn"]
-[ext_resource type="PackedScene" uid="uid://cr66tpdr5rma5" path="res://prefabs/fightOld/fighters/enemy_mavkha_fighter.tscn" id="29_hfhye"]
+[ext_resource type="PackedScene" uid="uid://cr66tpdr5rma5" path="res://prefabs/fight/fighters/enemy_mavkha_fighter.tscn" id="29_hfhye"]
[ext_resource type="Resource" uid="uid://dlcmqfjvgphqu" path="res://resources/items/rake.tres" id="30_l10vl"]
[ext_resource type="Resource" uid="uid://cndd64batns31" path="res://resources/items/wateringcan.tres" id="31_c2gvt"]
[ext_resource type="Texture2D" uid="uid://dyueumlr5ltvr" path="res://art/nature/baum märz 2025/megaeichel megaast.png" id="37_gg38r"]
diff --git a/scenes/SceneTransition.tscn b/scenes/SceneTransition.tscn
index 6073ff3..226f888 100644
--- a/scenes/SceneTransition.tscn
+++ b/scenes/SceneTransition.tscn
@@ -105,6 +105,7 @@ _data = {
}
[node name="SceneTransition" type="CanvasLayer" node_paths=PackedStringArray("animationPlayer")]
+layer = 100
script = ExtResource("1_e0bkc")
animationPlayer = NodePath("SceneFadeAnimation")
diff --git a/scripts/CSharp/Common/Camera/CameraController.cs b/scripts/CSharp/Common/Camera/CameraController.cs
index 4a590b3..661e65c 100644
--- a/scripts/CSharp/Common/Camera/CameraController.cs
+++ b/scripts/CSharp/Common/Camera/CameraController.cs
@@ -18,10 +18,13 @@ public partial class CameraController : Camera2D
[Export] private Node2D _followNode;
- public FightInstance? fightToShow;
+ public FightHappening? fightToShow;
+
public override void _Process(double delta)
{
- this.GlobalPosition = fightToShow?.camPositionNode.GlobalPosition ?? _followNode.GlobalPosition;
+ this.GlobalPosition = /*fightToShow?.camPositionNode.GlobalPosition ??*/ _followNode.GlobalPosition;
+
}
+
}
diff --git a/scripts/CSharp/Common/Fight/AllFightersVisual.cs b/scripts/CSharp/Common/Fight/AllFightersVisual.cs
new file mode 100644
index 0000000..e99b836
--- /dev/null
+++ b/scripts/CSharp/Common/Fight/AllFightersVisual.cs
@@ -0,0 +1,34 @@
+using Godot;
+using System;
+using Babushka.scripts.CSharp.Common.Fight;
+
+public partial class AllFightersVisual : Node
+{
+ [Export] private Node2D _allyFighters;
+ [Export] private Node2D _enemyFighters;
+
+ [Export] private PackedScene _blobFighterVisual;
+ [Export] private PackedScene _bigBlobFighterVisual;
+ [Export] private PackedScene _mavkaFighterVisual;
+ [Export] private PackedScene _yourMomFighterVisual;
+ [Export] private PackedScene _vesnaFighterVisual;
+
+ public void EnterFighter(FightWorld.Fighter fighter, bool isEnemy)
+ {
+ var parent = isEnemy ? _enemyFighters : _allyFighters;
+
+ var packedScene = fighter.type switch
+ {
+ FightWorld.Fighter.Type.Blob => _blobFighterVisual,
+ FightWorld.Fighter.Type.BigBlob => _bigBlobFighterVisual,
+ FightWorld.Fighter.Type.Mavka => _mavkaFighterVisual,
+ FightWorld.Fighter.Type.YourMom => _yourMomFighterVisual,
+ FightWorld.Fighter.Type.Vesna => _vesnaFighterVisual,
+ _ => throw new ArgumentOutOfRangeException()
+ };
+
+ var fighterVisual = packedScene.Instantiate();
+ fighterVisual.Initialize(fighter);
+ parent.AddChild(fighterVisual);
+ }
+}
diff --git a/scripts/CSharp/Common/Fight/AllFightersVisual.cs.uid b/scripts/CSharp/Common/Fight/AllFightersVisual.cs.uid
new file mode 100644
index 0000000..acfca36
--- /dev/null
+++ b/scripts/CSharp/Common/Fight/AllFightersVisual.cs.uid
@@ -0,0 +1 @@
+uid://dwsqst8fhhqlc
diff --git a/scripts/CSharp/Common/Fight/FightHappening.cs b/scripts/CSharp/Common/Fight/FightHappening.cs
new file mode 100644
index 0000000..3910ea0
--- /dev/null
+++ b/scripts/CSharp/Common/Fight/FightHappening.cs
@@ -0,0 +1,320 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Runtime.ExceptionServices;
+using System.Threading.Tasks;
+using Babushka.scripts.CSharp.Common.Util;
+using Godot;
+
+namespace Babushka.scripts.CSharp.Common.Fight;
+
+public class FightHappening
+{
+ /*
+ To get a visual overview of the FightHappening state machine, refer to the graph on miro:
+ https://miro.com/app/board/uXjVK8YEprM=/?moveToWidget=3458764640805655262&cot=14
+ */
+
+ #region Internal Types
+
+ public enum FightState
+ {
+ None,
+ FightStartAnim,
+ FightersEnter,
+ FightersEnterAnim,
+ NextFighter,
+ StateCheck,
+ InputActionSelect,
+ ActionCheckDetails,
+ InputActionDetail,
+ ActionExecute,
+ ActionAnim,
+ EnemyActionSelect,
+ PlayerWin,
+ EnemyWin,
+ }
+
+ private class FightersEnterStaging
+ {
+ public required List enteringAllyFighters;
+ public required List enteringEnemyFighters;
+
+ public bool HasAnyToExecute()
+ {
+ return enteringAllyFighters.Count != 0 || enteringEnemyFighters.Count != 0;
+ }
+ }
+
+ #endregion
+
+ #region Settings
+
+ private const float StartAnimationTime = 1;
+ private const float FightersEnterAnimationTime = 1;
+
+ #endregion
+
+ #region ShortCuts
+
+ private static FightWorld.FightHappeningData HappeningData =>
+ FightWorld.Instance.fightHappeningData ?? throw new NoFightHappeningException();
+
+ private static FightWorld.Fighter CurrentFighter => HappeningData.fighterStack.Current;
+
+ #endregion
+
+ #region Events
+
+ public event Action? transitionFromState;
+ public event Action? transitionState;
+ public event Action? transitionToState;
+
+ #endregion
+
+ #region Staging
+
+ private FightersEnterStaging? _fightersEnterStaging;
+ private FighterAction? _actionStaging;
+
+ #endregion
+
+ #region Public Methods
+
+ public void StartFight()
+ {
+ RequireState(FightState.None);
+ ChangeState(FightState.FightStartAnim);
+ }
+
+ #endregion
+
+ #region State Machine
+
+ private void ChangeState(FightState nextState)
+ {
+ TransitionFromState();
+ var lastState = HappeningData.fightState;
+ HappeningData.fightState = nextState;
+ TransitionFromToState(nextState, lastState);
+ TransitionToState(nextState);
+ }
+
+ private void TransitionFromState()
+ {
+ // fixed behaviour
+ switch (HappeningData.fightState)
+ {
+ default: break;
+ }
+
+ // notify everyone else
+ transitionFromState?.Invoke(HappeningData.fightState);
+ }
+
+ private void TransitionFromToState(FightState nextState, FightState lastState)
+ {
+ transitionState?.Invoke(lastState, nextState);
+ }
+
+ private void TransitionToState(FightState nextState)
+ {
+ // notify everyone else
+ transitionToState?.Invoke(nextState);
+
+ // fixed behaviour
+ switch (HappeningData.fightState)
+ {
+ case FightState.FightStartAnim:
+ AdvanceToStateInSeconds(FightState.FightersEnter, StartAnimationTime);
+ break;
+ case FightState.FightersEnter:
+ _fightersEnterStaging = StageFightersEnter();
+ if (_fightersEnterStaging.HasAnyToExecute())
+ {
+ ExecuteFightersEnter();
+ ChangeState(FightState.FightersEnterAnim);
+ }
+ else
+ {
+ ChangeState(FightState.NextFighter);
+ }
+
+ break;
+ case FightState.FightersEnterAnim:
+ AdvanceToStateInSeconds(FightState.NextFighter, FightersEnterAnimationTime);
+ break;
+ case FightState.NextFighter:
+ ExecuteNextFighter();
+ ChangeState(FightState.StateCheck);
+ break;
+ case FightState.StateCheck:
+ // restest action staging
+ _actionStaging = null;
+
+ if ( /*TODO: are all allys dead*/ false)
+ {
+ ChangeState(FightState.EnemyWin);
+ }
+ else if (HappeningData.enemyGroup.AreAllDead())
+ {
+ ChangeState(FightState.PlayerWin);
+ }
+ else if (CurrentFighter.actionsLeft <= 0)
+ {
+ ChangeState(FightState.FightersEnter);
+ }
+ else if (CurrentFighter.isEnemy)
+ {
+ ChangeState(FightState.EnemyActionSelect);
+ }
+ else
+ {
+ ChangeState(FightState.InputActionSelect);
+ }
+
+ break;
+ case FightState.InputActionSelect:
+ // wait for player input
+ break;
+ case FightState.ActionCheckDetails:
+ if (ActionAbort())
+ ChangeState(FightState.InputActionSelect);
+ else if (ActionNeededDetail() != null)
+ ChangeState(FightState.InputActionDetail);
+ else
+ ChangeState(FightState.ActionExecute);
+ break;
+ case FightState.InputActionDetail:
+ // wait for player input
+ break;
+ case FightState.EnemyActionSelect:
+ _actionStaging = CurrentFighter.AutoSelectAction();
+ ChangeState(FightState.ActionExecute);
+ break;
+ case FightState.ActionExecute:
+ ExecuteAction();
+ ChangeState(FightState.ActionAnim);
+ break;
+ case FightState.ActionAnim:
+ var actionTime = GetActionAnimationEnd();
+ if (actionTime.IsType())
+ {
+ AdvanceToStateInSeconds(FightState.StateCheck, actionTime);
+ }
+ else
+ {
+ _ = AdvanceToStateWhenDone(FightState.StateCheck, actionTime);
+ }
+
+ break;
+ default: break;
+ }
+ }
+
+ #endregion
+
+ #region Game Logic
+
+ private FightersEnterStaging StageFightersEnter()
+ {
+ // ally
+ var enteringAllyFighters = new List();
+ //TODO
+
+ // enemy
+ const int totalEnemySpace = 3;
+ var enemySpaceLeft = totalEnemySpace - HappeningData.enemyGroup.GetEnteredAmount();
+ var enterEnemyFighters = new List();
+
+ for (var i = 0; i < enemySpaceLeft; i++)
+ {
+ if (HappeningData.enemyGroup.TryGetFirstUnenteredFighter(out var fighter))
+ {
+ enterEnemyFighters.Add(fighter);
+ }
+ }
+
+ return new FightersEnterStaging
+ {
+ enteringAllyFighters = enteringAllyFighters,
+ enteringEnemyFighters = enterEnemyFighters
+ };
+ }
+
+ private void ExecuteFightersEnter()
+ {
+ Debug.Assert(_fightersEnterStaging != null);
+ foreach (var fighter in _fightersEnterStaging.enteringAllyFighters)
+ {
+ fighter.entered = true;
+ HappeningData.fighterStack.AddAsLast(fighter);
+ }
+
+ foreach (var fighter in _fightersEnterStaging.enteringEnemyFighters)
+ {
+ fighter.entered = true;
+ HappeningData.fighterStack.AddAsLast(fighter);
+ }
+ }
+
+ private void ExecuteNextFighter()
+ {
+ HappeningData.fighterStack.Next();
+ }
+
+ private void ExecuteAction()
+ {
+ Debug.Assert(_actionStaging != null);
+ _actionStaging.ExecuteAction();
+ }
+
+ private Variant> GetActionAnimationEnd()
+ {
+ Debug.Assert(_actionStaging != null);
+ return _actionStaging.GetAnimationEnd();
+ }
+
+ private bool ActionAbort()
+ {
+ Debug.Assert(_actionStaging != null);
+ return _actionStaging.MarkedForAbort();
+ }
+
+ private FighterAction.FighterActionDetail? ActionNeededDetail()
+ {
+ Debug.Assert(_actionStaging != null);
+ return _actionStaging.NeededDetail();
+ }
+
+ #endregion // Game Logic
+
+ #region Utility
+
+ private void RequireState(params FightState[] states)
+ {
+ if (states.Contains(HappeningData.fightState))
+ return;
+
+ throw new Exception(
+ $"Can not call this Method while in state {HappeningData.fightState}. Only available in {string.Join(" ,", states)}");
+ }
+
+ private void AdvanceToStateInSeconds(FightState nextState, float seconds)
+ {
+ FightWorld.Instance.GetTree().CreateTimer(seconds).Timeout += () => ChangeState(nextState);
+ }
+
+ private async Task AdvanceToStateWhenDone(FightState nextState, Func isDone)
+ {
+ while (!isDone())
+ {
+ await FightWorld.Instance.ToSignal(FightWorld.Instance.GetTree(), SceneTree.SignalName.ProcessFrame);
+ }
+
+ ChangeState(nextState);
+ }
+
+ #endregion
+}
\ No newline at end of file
diff --git a/scripts/CSharp/Common/FightOld/FightInstance.cs.uid b/scripts/CSharp/Common/Fight/FightHappening.cs.uid
similarity index 100%
rename from scripts/CSharp/Common/FightOld/FightInstance.cs.uid
rename to scripts/CSharp/Common/Fight/FightHappening.cs.uid
diff --git a/scripts/CSharp/Common/Fight/FightHappeningSceneSetup.cs b/scripts/CSharp/Common/Fight/FightHappeningSceneSetup.cs
new file mode 100644
index 0000000..293806e
--- /dev/null
+++ b/scripts/CSharp/Common/Fight/FightHappeningSceneSetup.cs
@@ -0,0 +1,15 @@
+using Godot;
+using System;
+using System.Diagnostics;
+using Babushka.scripts.CSharp.Common.Fight;
+
+public partial class FightHappeningSceneSetup : Node2D
+{
+ public override void _Ready()
+ {
+ var fightHappening = FightWorld.Instance.fightHappeningData;
+ Debug.Assert(fightHappening != null, "Fight happening scene loaded, without a fight happening");
+
+
+ }
+}
diff --git a/scripts/CSharp/Common/Fight/FightHappeningSceneSetup.cs.uid b/scripts/CSharp/Common/Fight/FightHappeningSceneSetup.cs.uid
new file mode 100644
index 0000000..1ac025e
--- /dev/null
+++ b/scripts/CSharp/Common/Fight/FightHappeningSceneSetup.cs.uid
@@ -0,0 +1 @@
+uid://cnhpnn8o0gybd
diff --git a/scripts/CSharp/Common/Fight/FightSceneSetup.cs b/scripts/CSharp/Common/Fight/FightRoomSceneSetup.cs
similarity index 92%
rename from scripts/CSharp/Common/Fight/FightSceneSetup.cs
rename to scripts/CSharp/Common/Fight/FightRoomSceneSetup.cs
index 7e46e20..3df9eec 100644
--- a/scripts/CSharp/Common/Fight/FightSceneSetup.cs
+++ b/scripts/CSharp/Common/Fight/FightRoomSceneSetup.cs
@@ -2,7 +2,7 @@ using Godot;
namespace Babushka.scripts.CSharp.Common.Fight;
-public partial class FightSceneSetup : Node
+public partial class FightRoomSceneSetup : Node
{
[Export] private Label debugLabel;
public override void _Ready()
diff --git a/scripts/CSharp/Common/Fight/FightSceneSetup.cs.uid b/scripts/CSharp/Common/Fight/FightRoomSceneSetup.cs.uid
similarity index 100%
rename from scripts/CSharp/Common/Fight/FightSceneSetup.cs.uid
rename to scripts/CSharp/Common/Fight/FightRoomSceneSetup.cs.uid
diff --git a/scripts/CSharp/Common/Fight/FightSceneSwitcher.cs b/scripts/CSharp/Common/Fight/FightSceneSwitcher.cs
index a6fdcb2..5b31b1c 100644
--- a/scripts/CSharp/Common/Fight/FightSceneSwitcher.cs
+++ b/scripts/CSharp/Common/Fight/FightSceneSwitcher.cs
@@ -9,15 +9,15 @@ public partial class FightSceneSwitcher : Node
{
[Export] private Node sceneRoot;
[Export] private string fightRoomScenePath;
- [Export] private string fightingGroupScene;
+ [Export] private string fightHappeningScene;
private void LoadNext()
{
var nextRoom = FightWorld.Instance.currentRoom;
Debug.Assert(nextRoom != null, "nextRoom!=null");
- var nextEnemyGroup = FightWorld.Instance.inFightWith;
- SceneTransitionThreaded.Instance.ChangeSceneToFile(nextEnemyGroup != null
- ? fightingGroupScene
+ var nextFightHappening = FightWorld.Instance.fightHappeningData;
+ SceneTransitionThreaded.Instance.ChangeSceneToFile(nextFightHappening != null
+ ? fightHappeningScene
: fightRoomScenePath);
UnloadAfterDelay();
}
diff --git a/scripts/CSharp/Common/Fight/FightUtils.cs b/scripts/CSharp/Common/Fight/FightUtils.cs
new file mode 100644
index 0000000..25fc961
--- /dev/null
+++ b/scripts/CSharp/Common/Fight/FightUtils.cs
@@ -0,0 +1,45 @@
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Babushka.scripts.CSharp.Common.Fight;
+
+public static class FightUtils
+{
+ public static int GetEnteredAmount(this FightWorld.EnemyGroup self)
+ {
+ return self.enemies.Count(e => e.IsAlive() && e.entered);
+ }
+
+ public static bool TryGetFirstUnenteredFighter(this FightWorld.EnemyGroup self, out FightWorld.Fighter fighter)
+ {
+ foreach (var f in self.enemies.Where(e=>!e.entered && e.IsAlive()))
+ {
+ fighter = f;
+ return true;
+ }
+
+ fighter = null!;
+ return false;
+ }
+
+ public static bool IsAlive(this FightWorld.Fighter self)
+ {
+ return self.GetHealth() >= 0;
+ }
+
+ public static bool IsDead(this FightWorld.Fighter self)
+ {
+ return !self.IsAlive();
+ }
+
+ public static int GetHealth(this FightWorld.Fighter self)
+ {
+ return self.health ?? self.maxHealth;
+ }
+
+ public static bool AreAllDead(this FightWorld.EnemyGroup self)
+ {
+ return self.enemies.All(e => e.IsDead());
+ }
+
+}
\ No newline at end of file
diff --git a/scripts/CSharp/Common/Fight/FightUtils.cs.uid b/scripts/CSharp/Common/Fight/FightUtils.cs.uid
new file mode 100644
index 0000000..87c1ce4
--- /dev/null
+++ b/scripts/CSharp/Common/Fight/FightUtils.cs.uid
@@ -0,0 +1 @@
+uid://beuhpltb84pf
diff --git a/scripts/CSharp/Common/Fight/FightWorld.cs b/scripts/CSharp/Common/Fight/FightWorld.cs
index cf1ff9f..b27c6d4 100644
--- a/scripts/CSharp/Common/Fight/FightWorld.cs
+++ b/scripts/CSharp/Common/Fight/FightWorld.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
+using Babushka.scripts.CSharp.Common.Util;
using Godot;
namespace Babushka.scripts.CSharp.Common.Fight;
@@ -18,21 +19,39 @@ public partial class FightWorld : Node
public class EnemyGroup
{
- public required List enemies;
+ public required List enemies;
}
- public class Enemy
+ public class FightHappeningData
+ {
+ public FightHappening.FightState fightState = FightHappening.FightState.None;
+ public FighterStack fighterStack = new();
+ public required EnemyGroup enemyGroup;
+ }
+
+ public class Fighter
{
public enum Type
{
Blob,
BigBlob,
Mavka,
- YourMom
+ YourMom,
+ Vesna
}
public required Type type;
- public required int? health = null; // null => initialize to full health on spawn
+ public required int maxHealth;
+ public required bool isEnemy;
+ public required List availableActions;
+ public int? health = null; // null => initialize to full health on spawn
+ public bool entered = false;
+ public int actionsLeft;
+
+ public FighterAction AutoSelectAction()
+ {
+ return availableActions.Random() ?? new FighterAction.Skip();
+ }
}
#region AutoLoad ( Contains _EnterTree() )
@@ -46,10 +65,10 @@ public partial class FightWorld : Node
}
#endregion
-
+
public World? world = null;
public Room? currentRoom = null;
- public EnemyGroup? inFightWith = null;
+ public FightHappeningData? fightHappeningData = null;
public void MyEnterTree()
{
@@ -135,22 +154,27 @@ public partial class FightWorld : Node
return enemyGroup;
}
- private Enemy GenerateSingleEnemy()
+ private Fighter GenerateSingleEnemy()
{
var typeRoll = GD.RandRange(0, 99);
var type = typeRoll switch
{
- < 50 => Enemy.Type.Blob,
- < 75 => Enemy.Type.BigBlob,
- < 90 => Enemy.Type.Mavka,
- _ => Enemy.Type.YourMom
+ < 50 => Fighter.Type.Blob,
+ < 75 => Fighter.Type.BigBlob,
+ < 90 => Fighter.Type.Mavka,
+ _ => Fighter.Type.YourMom
};
- var enemy = new Enemy
+ var enemy = new Fighter
{
type = type,
- health = null
+ health = null,
+ isEnemy = true,
+ maxHealth = 12,
+ availableActions = [
+ new FighterAction.Skip()
+ ]
};
return enemy;
diff --git a/scripts/CSharp/Common/Fight/FighterAction.cs b/scripts/CSharp/Common/Fight/FighterAction.cs
new file mode 100644
index 0000000..b18ed6b
--- /dev/null
+++ b/scripts/CSharp/Common/Fight/FighterAction.cs
@@ -0,0 +1,80 @@
+using System;
+using System.Threading.Tasks;
+using Babushka.scripts.CSharp.Common.Util;
+using Godot;
+
+namespace Babushka.scripts.CSharp.Common.Fight;
+
+public abstract class FighterAction
+{
+ public class TargetSelection
+ {
+ // ReSharper disable once MemberHidesStaticFromOuterClass
+ public static readonly TargetSelection Skip = new() { skipTargetSelection = () => true };
+ public Func skipTargetSelection = () => false;
+ }
+
+ public abstract class FighterActionDetail
+ {
+ public abstract bool DetailComplete();
+ }
+
+ private bool _abort = false;
+
+ #region Shortcuts
+
+ protected static FightWorld.FightHappeningData HappeningData =>
+ FightWorld.Instance.fightHappeningData ?? throw new NoFightHappeningException();
+
+ #endregion
+
+ ///
+ /// Executes the data modification for the action. This must happen instantly and not via a coroutines or callbacks.
+ /// To get a multiple hit effect for one action, use appropriate Visual Manipulation functions in AnimateAction.
+ ///
+ public virtual void ExecuteAction()
+ {
+ }
+
+ ///
+ /// Returns a way to determine, when an action animation is done
+ ///
+ ///
+ /// A variant that can be float or Func<bool>.
+ /// When the return type is float, the animation will take the return value amount of seconds.
+ /// When the return type is Func<bool>, the animation will be done, when the function returns true.
+ ///
+ public abstract Variant> GetAnimationEnd();
+
+ ///
+ /// Animates the action.
+ ///
+ public virtual async Task AnimateAction()
+ {
+ }
+
+ public void MarkAbort()
+ {
+ _abort = true;
+ }
+
+ public bool MarkedForAbort()
+ {
+ return _abort;
+ }
+
+ public abstract FighterActionDetail? NeededDetail();
+
+ public class Skip : FighterAction
+ {
+ public override Variant> GetAnimationEnd()
+ {
+ return 0f;
+ }
+
+ public override FighterActionDetail? NeededDetail()
+ {
+ return null;
+ }
+ }
+}
diff --git a/scripts/CSharp/Common/Fight/FighterStack.cs b/scripts/CSharp/Common/Fight/FighterStack.cs
new file mode 100644
index 0000000..aceb67e
--- /dev/null
+++ b/scripts/CSharp/Common/Fight/FighterStack.cs
@@ -0,0 +1,95 @@
+using System.Collections.Generic;
+using Godot.NativeInterop;
+
+namespace Babushka.scripts.CSharp.Common.Fight;
+
+public class FighterStack
+{
+ private class Node
+ {
+ public Node next;
+ public FightWorld.Fighter fighter;
+ }
+
+ private Node? currentNode;
+
+ public FightWorld.Fighter Current => currentNode.fighter;
+
+ public void Next()
+ {
+ currentNode = currentNode.next;
+ }
+
+ public FightWorld.Fighter PeekNext()
+ {
+ return currentNode.next.fighter;
+ }
+
+ public void AddAsLast(FightWorld.Fighter value)
+ {
+ // if first node
+ if (currentNode == null)
+ {
+ currentNode = new Node { fighter = value };
+ currentNode.next = currentNode;
+ return;
+ }
+
+ var newNode = new Node { fighter = value, next = currentNode };
+ var node = currentNode;
+ while (node.next != currentNode)
+ {
+ node = node.next;
+ }
+
+ node.next = newNode;
+ }
+
+ public void AddAsNext(FightWorld.Fighter value)
+ {
+ // if first node
+ if (currentNode == null)
+ {
+ AddAsLast(value);
+ return;
+ }
+
+ var newNode = new Node { fighter = value, next = currentNode.next };
+ currentNode.next = newNode;
+ }
+
+ public bool Remove(FightWorld.Fighter value)
+ {
+ if (currentNode == null) return false;
+
+ // if only one node
+ if (currentNode.next == currentNode)
+ {
+ if (currentNode.fighter == value)
+ {
+ currentNode = null;
+ return true;
+ }
+
+ return false;
+ }
+
+ var node = currentNode;
+ do
+ {
+ // next is the fighter to remove
+ if (node.next.fighter == value)
+ {
+ // if removing current, keep current
+ // it will be implicitly deleted on the next Next() call
+
+ node.next = node.next.next;
+ return true;
+ }
+
+ node = node.next;
+ } while (node != currentNode);
+
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/scripts/CSharp/Common/FightOld/Fighter.cs b/scripts/CSharp/Common/Fight/FighterVisual.cs
similarity index 71%
rename from scripts/CSharp/Common/FightOld/Fighter.cs
rename to scripts/CSharp/Common/Fight/FighterVisual.cs
index 31afcf4..c092191 100644
--- a/scripts/CSharp/Common/FightOld/Fighter.cs
+++ b/scripts/CSharp/Common/Fight/FighterVisual.cs
@@ -1,12 +1,13 @@
using Godot;
namespace Babushka.scripts.CSharp.Common.Fight;
-public partial class Fighter : Node2D
+public partial class FighterVisual : Node2D
{
- [Export] public string name;
- [Export] public int maxHealth;
- [Export] public int attackStrength;
- [Export] public int maxActions = 1;
+ //[Export] public string name;
+ //[Export] public int maxHealth;
+ //[Export] public int attackStrength;
+ //[Export] public int maxActions = 1;
+ [Export] public FightWorld.Fighter.Type type;
[ExportCategory("References")]
[Export] private Node2D _attackButtons;
@@ -21,45 +22,29 @@ public partial class Fighter : Node2D
[Signal] public delegate void HealedEventHandler();
- private int _health;
- private int _actions;
+ private FightWorld.Fighter _boundFighter;
+ //private void Die()
+ //{
+ // _visualSprite.Scale = new Vector2(1, 0.3f);
+ // EmitSignalDying();
+ //}
- public FightInstance fightInstance;
- public int Health
- {
- get => _health;
- set
- {
- _health = value;
- if (_health <= 0)
- {
- _health = 0;
- Die();
- }
- if (_health > maxHealth)
- {
- _health = maxHealth;
- }
- }
- }
+ //public override void _Ready()
+ //{
+ // UpdateHealthVisual();
+ // ResetActions();
+ //}
- private void Die()
+ public void Initialize(FightWorld.Fighter fighter)
{
- _visualSprite.Scale = new Vector2(1, 0.3f);
- EmitSignalDying();
- }
-
- public override void _Ready()
- {
- Health = maxHealth;
+ _boundFighter = fighter;
UpdateHealthVisual();
- ResetActions();
}
public void Attack()
{
- fightInstance.SelectAttack(this);
+ //FightHappening.SelectAttack(this);
}
public void HideAttackButton()
@@ -102,17 +87,17 @@ public partial class Fighter : Node2D
private void ClickedAttack()
{
- fightInstance.SelectAttack(this);
+ //FightHappening.SelectAttack(this);
}
private void ClickedHeal()
{
- fightInstance.SelectHeal(this);
+ //FightHappening.SelectHeal(this);
}
private void ClickedTarget()
{
- fightInstance.SelectTargetAndAttack(this);
+ //FightHappening.SelectTargetAndAttack(this);
}
public void StartHoverTarget()
@@ -127,7 +112,18 @@ public partial class Fighter : Node2D
public void UpdateHealthVisual()
{
- _healthText.Text = $"{Health}/{maxHealth}";
+ _healthText.Text = $"{_boundFighter.health}";
+ }
+
+ public bool IsDead()
+ {
+ //return Health <= 0;
+ return true;
+ }
+
+ public void ResetActions()
+ {
+ //_actions = maxActions;
}
public void AttackAnimation(FightAttack attack)
@@ -150,26 +146,6 @@ public partial class Fighter : Node2D
.SetTrans(Tween.TransitionType.Cubic).SetEase(Tween.EaseType.Out);
}
- public bool IsDead()
- {
- return Health <= 0;
- }
-
- public void ResetActions()
- {
- _actions = maxActions;
- }
-
- public bool HasActionsLeft()
- {
- return _actions > 0;
- }
-
- public void DecrementActions()
- {
- _actions--;
- }
-
public void HealAnimation()
{
EmitSignalHealed();
diff --git a/scripts/CSharp/Common/FightOld/Fighter.cs.uid b/scripts/CSharp/Common/Fight/FighterVisual.cs.uid
similarity index 100%
rename from scripts/CSharp/Common/FightOld/Fighter.cs.uid
rename to scripts/CSharp/Common/Fight/FighterVisual.cs.uid
diff --git a/scripts/CSharp/Common/Fight/NoFightHappeningException.cs b/scripts/CSharp/Common/Fight/NoFightHappeningException.cs
new file mode 100644
index 0000000..12587dd
--- /dev/null
+++ b/scripts/CSharp/Common/Fight/NoFightHappeningException.cs
@@ -0,0 +1,7 @@
+using System;
+
+namespace Babushka.scripts.CSharp.Common.Fight;
+
+public class NoFightHappeningException() : Exception("No fight happening right now")
+{
+}
\ No newline at end of file
diff --git a/scripts/CSharp/Common/FightOld/FightAttack.cs b/scripts/CSharp/Common/FightOld/FightAttack.cs
index 0c1248f..0397486 100644
--- a/scripts/CSharp/Common/FightOld/FightAttack.cs
+++ b/scripts/CSharp/Common/FightOld/FightAttack.cs
@@ -4,6 +4,6 @@ public class FightAttack
{
public int damage;
public bool needsSelectedTarget;
- public Fighter? target;
- public Fighter attacker;
+ public FighterVisual? target;
+ public FighterVisual attacker;
}
\ No newline at end of file
diff --git a/scripts/CSharp/Common/FightOld/FightInstance.cs b/scripts/CSharp/Common/FightOld/FightInstance.cs
deleted file mode 100644
index 28d608f..0000000
--- a/scripts/CSharp/Common/FightOld/FightInstance.cs
+++ /dev/null
@@ -1,351 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using Babushka.scripts.CSharp.Common.Camera;
-using Babushka.scripts.CSharp.Common.Util;
-using Godot;
-namespace Babushka.scripts.CSharp.Common.Fight;
-
-public partial class FightInstance : Node2D //TODO: remake
-{
- [Export(PropertyHint.ArrayType)] private Node2D[] _friendlyFightSpots;
- [Export(PropertyHint.ArrayType)] private Node2D[] _enemyFightSpots;
- [Export] public Node2D camPositionNode;
- [Export] private FightStateManager _fightStateManager;
- [Export] private Label _fightEndText;
-
-
- [Signal]
- public delegate void FightStartedEventHandler();
-
- [Signal]
- public delegate void FightEndedEventHandler();
-
- private List _friendlyFighters = new();
- private List _enemyFighters = new();
-
- private FightAttack? _stagedAttack = null;
-
- public override void _Ready()
- {
- //_fightStateManager.CurrentFightState = FightStateManager.FightState.FightStartAnim;
- _fightStateManager.ExitingTransition += from =>
- {
- switch (from)
- {
- case FightStateManager.FightState.None:
- CaptureCamera();
- Show();
- EmitSignalFightStarted();
- break;
- case FightStateManager.FightState.Input:
- HideAttackButtons();
- break;
- case FightStateManager.FightState.InputTargetSelect:
- HideTargetButtons();
- break;
- case FightStateManager.FightState.FriendAttackAnim:
- _stagedAttack = null;
- break;
- case FightStateManager.FightState.PlayerWinAnim:
- case FightStateManager.FightState.EnemyWinAnim:
- _fightEndText.Text = "";
- break;
- }
- };
-
- _fightStateManager.EnteringTransition += to =>
- {
- switch (to)
- {
- case FightStateManager.FightState.None:
- EmitSignalFightEnded();
- CleanUp();
- Hide();
- ReleaseCamera();
- break;
- case FightStateManager.FightState.Input:
- if (CheckWinAndSetState())
- break;
- if (CheckFriendlyActionsLeftAndSetState())
- break;
- ShowAttackButtons();
- break;
- case FightStateManager.FightState.InputTargetSelect:
- ShowTargetButtons();
- break;
- case FightStateManager.FightState.FriendAttackAnim:
- ExecuteAttack();
- GetTree().CreateTimer(1).Timeout += () => _fightStateManager.CurrentFightState = FightStateManager.FightState.Input;
- break;
- case FightStateManager.FightState.Enemy:
- if (CheckWinAndSetState())
- break;
- if (CheckEnemyActionsLeftAndSetState())
- break;
- DecideEnemyAttack();
- _fightStateManager.CurrentFightState = FightStateManager.FightState.EnemyAttackAnim;
- break;
- case FightStateManager.FightState.EnemyAttackAnim:
- ExecuteAttack();
- GetTree().CreateTimer(1).Timeout += () => _fightStateManager.CurrentFightState = FightStateManager.FightState.Enemy;
- break;
- case FightStateManager.FightState.PlayerWinAnim:
- _fightEndText.Text = "You Win!";
- GetTree().CreateTimer(1.5).Timeout += () => _fightStateManager.CurrentFightState = FightStateManager.FightState.None;
- break;
- case FightStateManager.FightState.EnemyWinAnim:
- _fightEndText.Text = "You Died :(";
- GetTree().CreateTimer(3).Timeout += () => _fightStateManager.CurrentFightState = FightStateManager.FightState.None;
- break;
- case FightStateManager.FightState.ChangeSideToEnemy:
- ResetEnemyActions();
- _fightStateManager.CurrentFightState = FightStateManager.FightState.Enemy;
- break;
- case FightStateManager.FightState.ChangeSideToFriendly:
- ResetFriendlyActions();
- _fightStateManager.CurrentFightState = FightStateManager.FightState.Input;
- break;
- case FightStateManager.FightState.Heal:
- Heal();
- GetTree().CreateTimer(1).Timeout += () => _fightStateManager.CurrentFightState = FightStateManager.FightState.Input;
- break;
- }
- };
- }
- private void Heal()
- {
- // TODO: make heal staging system
- _friendlyFighters.Where(f => !f.IsDead()).ForEach(f =>
- {
- f.Health += 50;
- f.HealAnimation();
- f.DecrementActions();
- });
- UpdateHealthVisual();
- }
- private void ResetEnemyActions()
- {
- _enemyFighters.ForEach(f => f.ResetActions());
- }
-
- private void ResetFriendlyActions()
- {
- _friendlyFighters.ForEach(f => f.ResetActions());
- }
-
- /**
- *
- * true if the state was changed
- *
- */
- private bool CheckFriendlyActionsLeftAndSetState()
- {
- var hasActionsLeft = _friendlyFighters.Where(f => !f.IsDead()).Any(f => f.HasActionsLeft());
- if (hasActionsLeft)
- {
- return false;
- } // else
- _fightStateManager.CurrentFightState = FightStateManager.FightState.ChangeSideToEnemy;
- return true;
- }
-
- /**
- *
- * true if the state was changed
- *
- */
- private bool CheckEnemyActionsLeftAndSetState()
- {
- var hasActionsLeft = _enemyFighters.Where(f => !f.IsDead()).Any(f => f.HasActionsLeft());
- if (hasActionsLeft)
- {
- return false;
- } // else
- _fightStateManager.CurrentFightState = FightStateManager.FightState.ChangeSideToFriendly;
- return true;
- }
-
- private void CleanUp()
- {
- _enemyFighters.ForEach(f => f.QueueFree());
- _friendlyFighters.ForEach(f => f.QueueFree());
- _enemyFighters = new();
- _friendlyFighters = new();
- }
- private void DecideEnemyAttack()
- {
- var availableEnemyFighters =
- _enemyFighters
- .Where(f => !f.IsDead())
- .Where(f=>f.HasActionsLeft())
- .ToList();
- var aliveFriendlyFighters =
- _friendlyFighters
- .Where(f => !f.IsDead())
- .ToList();
-
- if (availableEnemyFighters.Count <= 0)
- throw new InvalidOperationException("No enemy fighters available for attack.");
-
- if (aliveFriendlyFighters.Count <= 0)
- throw new InvalidOperationException("No friendly fighters available to target.");
-
- var fighter = availableEnemyFighters.Random();
- var target = aliveFriendlyFighters.Random();
-
- _stagedAttack = new FightAttack
- {
- attacker = fighter!,
- needsSelectedTarget = true,
- damage = fighter!.attackStrength,
- target = target!
- };
- }
-
- private void ExecuteAttack()
- {
- if (_stagedAttack == null)
- throw new InvalidOperationException("No staged attack to execute.");
-
- if (!_stagedAttack.needsSelectedTarget)
- throw new NotImplementedException("Non-targeted attacks are not implemented yet.");
-
- if (_stagedAttack.needsSelectedTarget && _stagedAttack.target == null)
- throw new InvalidOperationException("No target selected for the staged attack.");
-
- _stagedAttack.target!.Health -= _stagedAttack.damage;
- _stagedAttack.attacker.DecrementActions();
- _stagedAttack.attacker.AttackAnimation(_stagedAttack);
-
- UpdateHealthVisual();
- }
-
- private void UpdateHealthVisual()
- {
- _friendlyFighters
- .Concat(_enemyFighters)
- .ForEach(f => f.UpdateHealthVisual());
- }
-
- private void ReleaseCamera()
- {
- CameraController.Instance.fightToShow = null;
- }
-
- private void CaptureCamera()
- {
- CameraController.Instance.fightToShow = this;
- }
-
- public void Start(FightParty fightParty, PackedScene?[] enemies)
- {
- if (_fightStateManager.IsRunning())
- {
- GD.PushWarning("Can not start a running fight");
- return;
- }
-
- if (fightParty.vesna)
- {
- InstantiateFighter(_friendlyFightSpots[1], FightManager.Instance.fightingVesnaScene);
- }
-
- for (var i = 0; i < Math.Min(_enemyFightSpots.Length, enemies.Length); i++)
- {
- var enemy = enemies[i];
- if (enemy == null)
- continue;
-
- InstantiateFighter(_enemyFightSpots[i], enemy, true);
- }
-
- _fightStateManager.ToStartAnim();
- }
-
- private void InstantiateFighter(Node2D parent, PackedScene fighterScene, bool isEnemy = false)
- {
- var fighter = fighterScene.Instantiate();
- fighter.fightInstance = this;
- parent.AddChild(fighter);
-
- if (isEnemy)
- {
- _enemyFighters.Add(fighter);
- }
- else
- {
- _friendlyFighters.Add(fighter);
- }
- }
-
- public void SelectAttack(Fighter fighter)
- {
- _stagedAttack = new FightAttack
- {
- attacker = fighter,
- damage = fighter.attackStrength,
- needsSelectedTarget = true
- };
-
- if (_stagedAttack.needsSelectedTarget)
- {
- _fightStateManager.CurrentFightState = FightStateManager.FightState.InputTargetSelect;
- }
- else
- {
- _fightStateManager.CurrentFightState = FightStateManager.FightState.FriendAttackAnim;
- }
- }
-
- private void HideAttackButtons()
- {
- _friendlyFighters.ForEach(f => f.HideAttackButton());
- }
-
- private void ShowAttackButtons()
- {
- _friendlyFighters.ForEach(f => f.ShowAttackButton());
- }
-
- private void HideTargetButtons()
- {
- _enemyFighters.ForEach(f => f.HideTargetButtons());
- }
-
- private void ShowTargetButtons()
- {
- _enemyFighters.Where(f => !f.IsDead()).ForEach(f => f.ShowTargetButtons());
- }
-
- public void SelectTargetAndAttack(Fighter fighter)
- {
- if (_stagedAttack == null)
- throw new InvalidOperationException("No staged attack to select target for.");
-
- _stagedAttack.target = fighter;
-
- _fightStateManager.CurrentFightState = FightStateManager.FightState.FriendAttackAnim;
- }
-
- public void SelectHeal(Fighter fighter)
- {
- _fightStateManager.CurrentFightState = FightStateManager.FightState.Heal;
- }
-
- public bool CheckWinAndSetState()
- {
- if (_enemyFighters.All(f => f.IsDead()))
- {
- _fightStateManager.CurrentFightState = FightStateManager.FightState.PlayerWinAnim;
- return true;
- }
- if (_friendlyFighters.All(f => f.IsDead()))
- {
- _fightStateManager.CurrentFightState = FightStateManager.FightState.EnemyWinAnim;
- return true;
- }
- return false;
- }
-}
-
diff --git a/scripts/CSharp/Common/FightOld/FightManager.cs b/scripts/CSharp/Common/FightOld/FightManager.cs
index ef0652c..8376864 100644
--- a/scripts/CSharp/Common/FightOld/FightManager.cs
+++ b/scripts/CSharp/Common/FightOld/FightManager.cs
@@ -19,10 +19,10 @@ public partial class FightManager : Node
public FightParty fightParty = new();
- public void StartFight(PackedScene[] enemies, FightInstance instance)
+ public void StartFight(PackedScene[] enemies, FightHappening happening)
{
GD.Print("Starting Fight");
- instance.Start(fightParty, enemies);
+ //happening.Start(fightParty, enemies);
}
}
diff --git a/scripts/CSharp/Common/FightOld/FightStarter.cs b/scripts/CSharp/Common/FightOld/FightStarter.cs
index 0fd6ae8..780aef0 100644
--- a/scripts/CSharp/Common/FightOld/FightStarter.cs
+++ b/scripts/CSharp/Common/FightOld/FightStarter.cs
@@ -4,7 +4,7 @@ namespace Babushka.scripts.CSharp.Common.Fight;
public partial class FightStarter : Node
{
[Export(PropertyHint.ArrayType)] private PackedScene[] enemies;
- [Export] private FightInstance _fightInstance;
+ //[Export] private FightHappening _fightHappening;
[Export] private bool _once = true;
private bool hasBeenStarted = false;
@@ -14,6 +14,6 @@ public partial class FightStarter : Node
return;
hasBeenStarted = true;
- FightManager.Instance.StartFight(enemies, _fightInstance);
+ //FightManager.Instance.StartFight(enemies, _fightHappening);
}
}
diff --git a/scripts/CSharp/Common/FightOld/FightStateManager.cs b/scripts/CSharp/Common/FightOld/FightStateManager.cs
deleted file mode 100644
index 5ea800f..0000000
--- a/scripts/CSharp/Common/FightOld/FightStateManager.cs
+++ /dev/null
@@ -1,76 +0,0 @@
-using Godot;
-namespace Babushka.scripts.CSharp.Common.Fight;
-
-public partial class FightStateManager : Node
-{
- [Signal]
- public delegate void ExitingTransitionEventHandler(FightState exitingState);
-
- [Signal]
- public delegate void EnteringTransitionEventHandler(FightState enteringState);
-
- public enum FightState
- {
- None,
- FightStartAnim,
- Input,
- InputTargetSelect,
- FriendAttackAnim,
- Enemy,
- EnemyAttackAnim,
- PlayerWinAnim,
- EnemyWinAnim,
- ChangeSideToEnemy,
- ChangeSideToFriendly,
- Heal,
- }
-
- private FightState _fightStateBacking = FightState.None;
-
- public FightState CurrentFightState
- {
- set => Transition(_fightStateBacking, value);
- get => _fightStateBacking;
- }
-
- private void Transition(FightState from, FightState to)
- {
- if(from == to)
- return;
-
- GD.Print($"Transitioning from {from} to {to}");
- ExitTransition(from);
- _fightStateBacking = to;
- EnterTransition(to);
- }
-
- private void ExitTransition(FightState from)
- {
- EmitSignalExitingTransition(from);
- }
-
- private void EnterTransition(FightState to)
- {
- EmitSignalEnteringTransition(to);
- switch (to)
- {
- case FightState.FightStartAnim:
- EnterFightStartAnim();
- break;
- }
- }
- private void EnterFightStartAnim()
- {
- GetTree().CreateTimer(1).Timeout += () => CurrentFightState = FightState.Input;
- }
-
- public void ToStartAnim()
- {
- CurrentFightState = FightState.FightStartAnim;
- }
-
- public bool IsRunning()
- {
- return CurrentFightState != FightState.None;
- }
-}
diff --git a/scripts/CSharp/Common/FightOld/FightStateManager.cs.uid b/scripts/CSharp/Common/FightOld/FightStateManager.cs.uid
deleted file mode 100644
index 1527d8c..0000000
--- a/scripts/CSharp/Common/FightOld/FightStateManager.cs.uid
+++ /dev/null
@@ -1 +0,0 @@
-uid://oe1uypehqvr7
diff --git a/scripts/CSharp/Common/Util/Variant.cs b/scripts/CSharp/Common/Util/Variant.cs
new file mode 100644
index 0000000..7ef303b
--- /dev/null
+++ b/scripts/CSharp/Common/Util/Variant.cs
@@ -0,0 +1,63 @@
+using System;
+using System.Diagnostics;
+
+namespace Babushka.scripts.CSharp.Common.Util;
+
+public class Variant
+{
+ private Type _type;
+ private Object _value;
+
+ public Type GetVariantType()
+ {
+ return _type;
+ }
+
+ public T GetValue()
+ {
+ if (_type != typeof(T))
+ throw new ArgumentOutOfRangeException(
+ $"The Variant does not store a {typeof(T)}. The current type is {_type}");
+
+ return (T)_value;
+ }
+
+ public void SetValue(T value)
+ {
+ if (typeof(T1) != typeof(T) && typeof(T2) != typeof(T))
+ throw new ArgumentOutOfRangeException(
+ $"The Variant does not support type {typeof(T)}. Supported types are {typeof(T1)} and {typeof(T2)}");
+
+ _type = typeof(T);
+ _value = value!;
+ }
+
+ public static implicit operator T1(Variant v)
+ {
+ return v.GetValue();
+ }
+
+ public static implicit operator T2(Variant v)
+ {
+ return v.GetValue();
+ }
+
+ public static implicit operator Variant(T1 t)
+ {
+ return new Variant { _type = typeof(T1), _value = t! };
+ }
+
+ public static implicit operator Variant(T2 t)
+ {
+ return new Variant { _type = typeof(T2), _value = t! };
+ }
+
+ public bool IsType()
+ {
+ if (typeof(T1) != typeof(T) && typeof(T2) != typeof(T))
+ throw new ArgumentOutOfRangeException(
+ $"The Variant does not support type {typeof(T)}. Supported types are {typeof(T1)} and {typeof(T2)}");
+
+ return _type == typeof(T);
+ }
+}
\ No newline at end of file
diff --git a/shader/swaying_plant.gdshader b/shader/swaying_plant.gdshader
index 01c04ce..42a0f76 100644
--- a/shader/swaying_plant.gdshader
+++ b/shader/swaying_plant.gdshader
@@ -26,7 +26,6 @@ uniform float heightOffset : hint_range(0.0, 1.0);
// With the offset value, you can if you want different moves for each asset. Just put a random value (1, 2, 3) in the editor. Don't forget to mark the material as unique if you use this
uniform float offset = 0;
-
float getWind(vec2 vertex, vec2 uv, float time){
float diff = pow(maxStrength - minStrength, 2.0);
float strength = clamp(minStrength + diff + sin(time / interval) * diff, minStrength, maxStrength) * strengthScale;