Fight rework premature merge #22

Merged
Jonathan merged 16 commits from feature/fight_rework into develop 2025-11-04 10:25:14 +01:00
42 changed files with 889 additions and 251 deletions
Showing only changes of commit 0e315396c9 - Show all commits
+5
View File
@@ -1,6 +1,7 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AArea2D_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FSourcesCache_003Fefbd3244e8e427e388f389cc304f90548d56b58a375097a197ac2eb8259990bb_003FArea2D_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AArea3D_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F8a54226fa2e1c9371a8091f24cfd744aef11fe6869527dc23b9b837623a29b9_003FArea3D_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AArray_00601_002Ecs_002Fl_003AC_0021_003FUsers_003FJonathan_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fe37dc1faf08a4d5ea030ad59bdf77522523400_003Fa3_003Fe272a3a7_003FArray_00601_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AAudioStreamPlayer2D_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003F848324b1c23114c3f5e8bbb5a42c4ade394c59a7a7a133a66b76581ca571_003FAudioStreamPlayer2D_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ABabushka_002Escripts_002ECSharp_002ECommon_002EFarming_002EFieldBehaviour2D_005FScriptMethods_002Egenerated_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FSourcesCache_003F75d11718f1abbc2572fd32e4b83acbec9d79ac_003FBabushka_002Escripts_002ECSharp_002ECommon_002EFarming_002EFieldBehaviour2D_005FScriptMethods_002Egenerated_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ABabushka_002Escripts_002ECSharp_002ECommon_002EFarming_002EVesnaBehaviour2D_005FScriptMethods_002Egenerated_002Ecs_002Fl_003AC_0021_003FUsers_003FJonathan_003FAppData_003FLocal_003FTemp_003FSourceGeneratedDocuments_003F9509A9D00FD8A232B5E86A84_003FGodot_002ESourceGenerators_003FGodot_002ESourceGenerators_002EScriptMethodsGenerator_003FBabushka_002Escripts_002ECSharp_002ECommon_002EFarming_002EVesnaBehaviour2D_005FScriptMethods_002Egenerated_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
@@ -9,9 +10,11 @@
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ABabushka_002Escripts_002ECSharp_002ECommon_002EFarming_002EVesnaBehaviour2D_005FScriptProperties_002Egenerated_002Ecs_002Fl_003AC_0021_003FUsers_003FJonathan_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003F4298b0f293f987511fc1b7956ee691fd778f8378_003FBabushka_002Escripts_002ECSharp_002ECommon_002EFarming_002EVesnaBehaviour2D_005FScriptProperties_002Egenerated_002Ecs_002Fz_003A2_002D1/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ABabushka_002Escripts_002ECSharp_002ECommon_002EQuest_002EQuestListItemUi_005FScriptMethods_002Egenerated_002Ecs_002Fl_003AC_0021_003FUsers_003FJonathan_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003F48fad7e7f3c9e292b3fdbddf9d363f0d1752aa_003FBabushka_002Escripts_002ECSharp_002ECommon_002EQuest_002EQuestListItemUi_005FScriptMethods_002Egenerated_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ABabushka_002Escripts_002ECSharp_002ECommon_002EQuest_002EQuestManager_005FScriptSignals_002Egenerated_002Ecs_002Fl_003AC_0021_003FUsers_003FJonathan_003FAppData_003FLocal_003FTemp_003FSourceGeneratedDocuments_003F9509A9D00FD8A232B5E86A84_003FGodot_002ESourceGenerators_003FGodot_002ESourceGenerators_002EScriptSignalsGenerator_003FBabushka_002Escripts_002ECSharp_002ECommon_002EQuest_002EQuestManager_005FScriptSignals_002Egenerated_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ACanvasItem_002Ecs_002Fl_003AC_0021_003FUsers_003FJonathan_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003Fef7b819b226fab796d1dfe66d415dd7510bcac87675020ddb8f03a828e763_003FCanvasItem_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ACastHelpers_002Ecs_002Fl_003AC_0021_003FUsers_003FJonathan_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003F3c92637ae2e83da0a63791071c41eae291d594156062866d8621b7ed7245c_003FCastHelpers_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ACastHelpers_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fd111abf504bf42b5968a609b168fd093b2e200_003Fbb_003F1c116fcd_003FCastHelpers_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ACharacterBody2D_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003Fbba0bbd7a98ee58286e9484fbe86e01afff6232283f6efd3556eb7116453_003FCharacterBody2D_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ACount_002Ecs_002Fl_003AC_0021_003FUsers_003FJonathan_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003Ffe5a7cee5a1771b89077bd73292de84439b4f816799e2ad6c2615c6ff5bd748e_003FCount_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ADictionary_00602_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003Fhome_003Fjonathan_003F_002Econfig_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fe37dc1faf08a4d5ea030ad59bdf77522523400_003Fd4_003Fbd338aeb_003FDictionary_00602_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AExportToolButtonAttribute_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fe37dc1faf08a4d5ea030ad59bdf77522523400_003F31_003F3e05ef15_003FExportToolButtonAttribute_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AMustBeVariantAttribute_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fe37dc1faf08a4d5ea030ad59bdf77522523400_003Fda_003Fbb06d681_003FMustBeVariantAttribute_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
@@ -23,8 +26,10 @@
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AEnumerable_002Ecs_002Fl_003AC_0021_003FUsers_003FJonathan_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F76fabf6f8acf4a0099cae0bcf8b218467f10_003F7e_003F28cee476_003FEnumerable_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AGD_005Fconstants_002Ecs_002Fl_003AC_0021_003FUsers_003FJonathan_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003F4ef0bac6437b6a9567d44f62ae567d854fa7b8513ef7139ef349b49768bc9df_003FGD_005Fconstants_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ANode_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003Ff1d69ec2da76ccf9bc8a75c8e0fdca9a7ba1adf8c8c9d5047e2fa5991c02eca_003FNode_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ANullable_002Ecs_002Fl_003AC_0021_003FUsers_003FJonathan_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003F5acc345db3c207bc9d886a36ff14867ef8d65557432172c2a42f19aeac04d1b_003FNullable_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AResourceLoader_002Ecs_002Fl_003AC_0021_003FUsers_003FJonathan_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003F9f4e8eb124d11f8219cb513a19bed22b2120ed29f9d6785ba56e3367b48d581_003FResourceLoader_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ASceneTree_002Ecs_002Fl_003AC_0021_003FUsers_003FJonathan_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003F8d6960554e939a669841b1ece03d27df4ab42f92bb80be3767eaec8cdaccf84b_003FSceneTree_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AShape2D_002Ecs_002Fl_003AC_0021_003FUsers_003FJonathan_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003F3671dbbd9b17cdf2bf9075b468b6bd7e3ab13fc3be7a116484085d3b6cc9fe_003FShape2D_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AThrowHelper_002Ecs_002Fl_003AC_0021_003FUsers_003FJonathan_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003Fc7102cd0ffb8973777e61b1942c3fffac7e14016a511d055c3adf73ff91748_003FThrowHelper_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=bc5a80e4_002D7ba6_002D4f7d_002Db896_002Dc591eec7ab12/@EntryIndexedValue">&lt;SessionState ContinuousTestingMode="0" IsActive="True" Name="Tests" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"&gt;&#xD;
&lt;TestAncestor&gt;&#xD;
@@ -0,0 +1,18 @@
[gd_scene load_steps=4 format=3 uid="uid://0vm3jb1hnkkb"]
[ext_resource type="PackedScene" uid="uid://7jsxokx67gpq" path="res://prefabs/fight/fighterVisuals/vesna_fighter_visual.tscn" id="1_80xdf"]
[ext_resource type="Texture2D" uid="uid://ccrnmx6bd842k" path="res://art/characters/farm fäulnis blobs.png" id="2_ba6tr"]
[sub_resource type="AtlasTexture" id="AtlasTexture_ane0o"]
atlas = ExtResource("2_ba6tr")
region = Rect2(1133.19, 93.65, 460.526, 347.391)
[node name="BlobFighterVisual" instance=ExtResource("1_80xdf")]
[node name="Sprite2D" parent="Visuals" index="0"]
position = Vector2(23, -96)
scale = Vector2(0.547474, 0.547474)
texture = SubResource("AtlasTexture_ane0o")
[node name="ChacacterSizeIndicator" parent="Visuals" index="1"]
visible = true
@@ -0,0 +1,58 @@
[gd_scene load_steps=8 format=3 uid="uid://7jsxokx67gpq"]
[ext_resource type="Script" uid="uid://by88f32fou7lh" path="res://scripts/CSharp/Common/Fight/FighterVisual.cs" id="1_hai27"]
[ext_resource type="Texture2D" uid="uid://f7htcxiwvuup" path="res://art/animation/vesna/Side/S01-Idle/0001.png" id="2_6l7g5"]
[ext_resource type="Script" uid="uid://boprnfciqgixf" path="res://scripts/CSharp/Common/Fight/UI/TargetSelectionClick.cs" id="3_wil2y"]
[ext_resource type="Texture2D" uid="uid://qlfwuakhe57t" path="res://art/ui/UI/attack_select_wheel.png" id="4_8ldlc"]
[sub_resource type="AtlasTexture" id="AtlasTexture_wil2y"]
atlas = ExtResource("2_6l7g5")
region = Rect2(60.818, 51.0213, 660.226, 945.537)
[sub_resource type="RectangleShape2D" id="RectangleShape2D_6l7g5"]
size = Vector2(250, 401)
[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_6l7g5"]
radius = 173.0
height = 588.0
[node name="VesnaFighterVisual" type="Node2D" node_paths=PackedStringArray("_visualParent", "_targetSelectionParent")]
script = ExtResource("1_hai27")
_visualParent = NodePath("Visuals")
_targetSelectionParent = NodePath("TargetSelection")
[node name="Visuals" type="Node2D" parent="."]
[node name="Sprite2D" type="Sprite2D" parent="Visuals"]
position = Vector2(-31, -199)
scale = Vector2(0.451719, 0.451719)
texture = SubResource("AtlasTexture_wil2y")
[node name="ChacacterSizeIndicator" type="CollisionShape2D" parent="Visuals"]
editor_description = "This is a reference to the space, a normal sized humanoid character should occupy"
visible = false
position = Vector2(0, -200.5)
shape = SubResource("RectangleShape2D_6l7g5")
[node name="TargetSelection" type="Node2D" parent="."]
process_mode = 4
visible = false
[node name="Click" type="Area2D" parent="TargetSelection"]
script = ExtResource("3_wil2y")
[node name="CollisionShape2D" type="CollisionShape2D" parent="TargetSelection/Click"]
position = Vector2(-3, -195)
shape = SubResource("CapsuleShape2D_6l7g5")
[node name="HoverIndicator" type="Node2D" parent="TargetSelection"]
visible = false
[node name="Sprite2D" type="Sprite2D" parent="TargetSelection/HoverIndicator"]
position = Vector2(-3, -227)
scale = Vector2(1.65625, 1.65625)
texture = ExtResource("4_8ldlc")
[connection signal="TargetSelected" from="TargetSelection/Click" to="." method="ClickedTarget"]
[connection signal="mouse_entered" from="TargetSelection/Click" to="TargetSelection/HoverIndicator" method="show"]
[connection signal="mouse_exited" from="TargetSelection/Click" to="TargetSelection/HoverIndicator" method="hide"]
+41
View File
@@ -0,0 +1,41 @@
[gd_scene load_steps=8 format=3 uid="uid://qfdiudt3vpai"]
[ext_resource type="Script" uid="uid://lequnojtar76" path="res://scripts/CSharp/Common/Fight/RoamingEnemyGroup.cs" id="1_t3mrx"]
[ext_resource type="Texture2D" uid="uid://ccrnmx6bd842k" path="res://art/characters/farm fäulnis blobs.png" id="2_6ftwg"]
[ext_resource type="Texture2D" uid="uid://bexymddkb6l0o" path="res://art/characters/Mavka/mavkha.png" id="3_xi5g8"]
[ext_resource type="PackedScene" uid="uid://cqc72e4hq6bcd" path="res://prefabs/interactions/interaction_area_2d.tscn" id="4_xi5g8"]
[sub_resource type="AtlasTexture" id="AtlasTexture_c8fs8"]
atlas = ExtResource("2_6ftwg")
region = Rect2(1747.17, 156.157, 311.249, 280.596)
[sub_resource type="AtlasTexture" id="AtlasTexture_kbgcx"]
atlas = ExtResource("3_xi5g8")
region = Rect2(774.378, 151.512, 1097.48, 1412.67)
[sub_resource type="AtlasTexture" id="AtlasTexture_6fvcb"]
atlas = ExtResource("2_6ftwg")
region = Rect2(1149.47, 92.492, 445.652, 353.692)
[node name="RoamingEnemyGroup" type="Node2D"]
script = ExtResource("1_t3mrx")
[node name="Visuals" type="Node2D" parent="."]
[node name="Sprite2D" type="Sprite2D" parent="Visuals"]
position = Vector2(99, -222)
texture = SubResource("AtlasTexture_c8fs8")
[node name="Sprite2D3" type="Sprite2D" parent="Visuals"]
position = Vector2(-108, -337)
scale = Vector2(0.43, 0.43)
texture = SubResource("AtlasTexture_kbgcx")
[node name="Sprite2D2" type="Sprite2D" parent="Visuals"]
position = Vector2(-41, -109)
texture = SubResource("AtlasTexture_6fvcb")
[node name="InteractionArea" parent="." node_paths=PackedStringArray("_spriteToOutline") instance=ExtResource("4_xi5g8")]
_spriteToOutline = [NodePath("../Visuals/Sprite2D"), NodePath("../Visuals/Sprite2D3"), NodePath("../Visuals/Sprite2D2")]
[connection signal="Interacted" from="InteractionArea" to="." method="StartFight"]
+1 -1
View File
@@ -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/fight/fighters/vesna_fighter.tscn" id="2_ak1vo"]
[ext_resource type="PackedScene" uid="uid://cpanatqdjjpa3" path="res://prefabs/fightOld/fighters/vesna_fighter.tscn" id="2_ak1vo"]
[node name="FightManagerAutoload" type="Node"]
script = ExtResource("1_8p7ev")
+1
View File
@@ -28,6 +28,7 @@ buses/default_bus_layout="uid://b6dwkmkyb0axk"
SceneTransition="*res://scenes/SceneTransition.tscn"
Dialogic="*res://addons/dialogic/Core/DialogicGameHandler.gd"
InventoryManager="*res://scripts/CSharp/Common/Inventory/InventoryManager.cs"
InputService="*res://scripts/CSharp/Common/Services/InputService.cs"
QuestManager="*res://prefabs/quests/quest_manager_autoload.tscn"
FightManagerAutoload="*res://prefabs/fight/fight_manager_autoload.tscn"
InputService="*res://scripts/CSharp/Common/Services/InputService.cs"
+1
View File
@@ -5,5 +5,6 @@
[node name="BabushkaSceneBootstrap" type="Node2D"]
[node name="BabushkaSceneStartMenu" parent="." instance=ExtResource("1_15ton")]
_sceneNamesToLoad = PackedStringArray("res://scenes/Babushka_scene_fight_world_room.tscn")
[node name="SceneParent" type="Node" parent="."]
+50 -4
View File
@@ -1,19 +1,33 @@
[gd_scene load_steps=4 format=3 uid="uid://cjshlwk8ajpnp"]
[gd_scene load_steps=10 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="Script" uid="uid://c76mhhqyk4lgh" path="res://scripts/CSharp/Common/Fight/FightHappening.cs" id="1_gsk03"]
[ext_resource type="Script" uid="uid://dwsqst8fhhqlc" path="res://scripts/CSharp/Common/Fight/AllFightersVisual.cs" id="2_lu4y4"]
[ext_resource type="PackedScene" uid="uid://bcld43daavmrn" path="res://prefabs/fight/fight_scene_switcher.tscn" id="2_phrlx"]
[ext_resource type="PackedScene" uid="uid://7jsxokx67gpq" path="res://prefabs/fight/fighterVisuals/vesna_fighter_visual.tscn" id="4_qo0gi"]
[ext_resource type="PackedScene" uid="uid://0vm3jb1hnkkb" path="res://prefabs/fight/fighterVisuals/blob_fighter_visual.tscn" id="4_vp8s0"]
[ext_resource type="Script" uid="uid://buiwuf7pjfq8" path="res://scripts/CSharp/Common/Fight/FightHappeningStateReaction.cs" id="4_ydj1i"]
[ext_resource type="Script" uid="uid://byf2ywov34g0x" path="res://scripts/CSharp/Common/Fight/UI/ActionSelectUiSetup.cs" id="8_bkwsr"]
[ext_resource type="Script" uid="uid://d2ugtb3dalrg3" path="res://scripts/CSharp/Common/Fight/FightHappeningStateDebugger.cs" id="8_tv7cl"]
[node name="BabushkaSceneFightHappening" type="Node2D"]
[node name="FightHappening" type="Node" parent="."]
script = ExtResource("1_gsk03")
[node name="Camera2D" type="Camera2D" parent="."]
[node name="FightSetup" type="Node2D" parent="."]
script = ExtResource("1_fiutj")
[node name="FightVisuals" type="Node2D" parent="."]
[node name="FightVisuals" type="Node2D" parent="." node_paths=PackedStringArray("_allyFighters", "_enemyFighters")]
position = Vector2(0, 259)
script = ExtResource("2_lu4y4")
_allyFighters = NodePath("AllyFighters")
_enemyFighters = NodePath("EnemyFighters")
_blobFighterVisual = ExtResource("4_vp8s0")
_vesnaFighterVisual = ExtResource("4_qo0gi")
_positionDistanceFromCenter = PackedFloat32Array(200, 400, 600)
[node name="AllyFighters" type="Node2D" parent="FightVisuals"]
@@ -23,7 +37,13 @@ script = ExtResource("2_lu4y4")
[node name="FightSceneSwitcher" parent="." instance=ExtResource("2_phrlx")]
[node name="ActionSelect" type="CanvasLayer" parent="."]
[node name="ActionSelect" type="CanvasLayer" parent="." node_paths=PackedStringArray("_attackActionButton", "_summonActionButton", "_talkActionButton", "_fleeActionButton")]
visible = false
script = ExtResource("8_bkwsr")
_attackActionButton = NodePath("BottomPanel/VBoxContainer/MarginContainer/HBoxContainer/MarginContainer/AttackButton")
_summonActionButton = NodePath("BottomPanel/VBoxContainer/MarginContainer/HBoxContainer/MarginContainer2/Summon Button")
_talkActionButton = NodePath("BottomPanel/VBoxContainer/MarginContainer/HBoxContainer/MarginContainer3/Talk Button")
_fleeActionButton = NodePath("BottomPanel/VBoxContainer/MarginContainer/HBoxContainer/MarginContainer4/Flee Button")
[node name="BottomPanel" type="Control" parent="ActionSelect"]
custom_minimum_size = Vector2(0, 200)
@@ -134,3 +154,29 @@ 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"
[node name="StateReactionInputActionSelect" type="Node" parent="ActionSelect"]
script = ExtResource("4_ydj1i")
_fightState = 6
[node name="StateMachineDebugger" type="Node" parent="." node_paths=PackedStringArray("_label")]
script = ExtResource("8_tv7cl")
_label = NodePath("Label")
[node name="Label" type="Label" parent="StateMachineDebugger"]
offset_left = -973.0
offset_top = -500.0
offset_right = -523.0
offset_bottom = 444.0
text = "Hello world"
[connection signal="SignalTransitionState" from="FightHappening" to="FightVisuals" method="FightHappeningStateChange"]
[connection signal="SignalTransitionState" from="FightHappening" to="ActionSelect/StateReactionInputActionSelect" method="FightHappeningStateTransitioned"]
[connection signal="SignalTransitionState" from="FightHappening" to="StateMachineDebugger" method="StateChange"]
[connection signal="pressed" from="ActionSelect/BottomPanel/VBoxContainer/MarginContainer/HBoxContainer/MarginContainer/AttackButton" to="ActionSelect" method="SelectAction" binds= [1]]
[connection signal="pressed" from="ActionSelect/BottomPanel/VBoxContainer/MarginContainer/HBoxContainer/MarginContainer2/Summon Button" to="ActionSelect" method="SelectAction" binds= [2]]
[connection signal="pressed" from="ActionSelect/BottomPanel/VBoxContainer/MarginContainer/HBoxContainer/MarginContainer3/Talk Button" to="ActionSelect" method="SelectAction" binds= [3]]
[connection signal="pressed" from="ActionSelect/BottomPanel/VBoxContainer/MarginContainer/HBoxContainer/MarginContainer4/Flee Button" to="ActionSelect" method="SelectAction" binds= [4]]
[connection signal="OnStateEntered" from="ActionSelect/StateReactionInputActionSelect" to="ActionSelect" method="show"]
[connection signal="OnStateEntered" from="ActionSelect/StateReactionInputActionSelect" to="ActionSelect" method="StateEntered"]
[connection signal="OnStateExited" from="ActionSelect/StateReactionInputActionSelect" to="ActionSelect" method="hide"]
+22 -17
View File
@@ -1,4 +1,4 @@
[gd_scene load_steps=52 format=3 uid="uid://cacnapfv7w567"]
[gd_scene load_steps=53 format=3 uid="uid://cacnapfv7w567"]
[ext_resource type="Script" uid="uid://bqomwxclsbhd3" path="res://scripts/CSharp/Common/Camera/CameraController.cs" id="1_pi6ua"]
[ext_resource type="Texture2D" uid="uid://8sr11ex30n0m" path="res://art/mockups/Kenney_Backgrounds/Samples/uncolored_hills.png" id="2_hqa4k"]
@@ -38,8 +38,9 @@
[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" path="res://scripts/CSharp/Common/Fight/FightSceneSetup.cs" id="37_hqa4k"]
[ext_resource type="Script" uid="uid://dbu8afaiohpdh" path="res://scripts/CSharp/Common/Fight/FightRoomSceneSetup.cs" id="40_cvg1r"]
[ext_resource type="PackedScene" uid="uid://bcld43daavmrn" path="res://prefabs/fight/fight_scene_switcher.tscn" id="40_elhbh"]
[ext_resource type="PackedScene" uid="uid://qfdiudt3vpai" path="res://prefabs/fight/roaming_enemy_group.tscn" id="41_cvg1r"]
[sub_resource type="ShaderMaterial" id="ShaderMaterial_ruj2u"]
shader = ExtResource("16_0fard")
@@ -1998,7 +1999,6 @@ y_sort_enabled = true
[node name="Visuals" type="Node2D" parent="YSorted/Paths/Path0/PathVariants/Closed"]
y_sort_enabled = true
scale = Vector2(1, 1)
[node name="bush14" type="Sprite2D" parent="YSorted/Paths/Path0/PathVariants/Closed/Visuals"]
y_sort_enabled = true
@@ -2022,7 +2022,6 @@ y_sort_enabled = true
[node name="Visuals" type="Node2D" parent="YSorted/Paths/Path0/PathVariants/OpenToFightRoom"]
y_sort_enabled = true
scale = Vector2(1, 1)
[node name="bush14" type="Sprite2D" parent="YSorted/Paths/Path0/PathVariants/OpenToFightRoom/Visuals"]
z_index = 100
@@ -2074,7 +2073,6 @@ y_sort_enabled = true
[node name="Visuals" type="Node2D" parent="YSorted/Paths/Path1/PathVariants/Closed"]
y_sort_enabled = true
scale = Vector2(1, 1)
[node name="bush14" type="Sprite2D" parent="YSorted/Paths/Path1/PathVariants/Closed/Visuals"]
y_sort_enabled = true
@@ -2112,7 +2110,6 @@ y_sort_enabled = true
[node name="Visuals" type="Node2D" parent="YSorted/Paths/Path1/PathVariants/OpenToFightRoom"]
y_sort_enabled = true
scale = Vector2(1, 1)
[node name="bush14" type="Sprite2D" parent="YSorted/Paths/Path1/PathVariants/OpenToFightRoom/Visuals"]
z_index = 100
@@ -2136,20 +2133,28 @@ pathIndex = 1
position = Vector2(-335, 18)
shape = SubResource("RectangleShape2D_ir2xa")
[node name="FightSceneSetup" type="Node" parent="." node_paths=PackedStringArray("debugLabel")]
unique_name_in_owner = true
script = ExtResource("37_hqa4k")
debugLabel = NodePath("../Debug Label")
[node name="EnemyGroupSpawns" type="Node2D" parent="YSorted"]
position = Vector2(11116, 2546)
[node name="Spawn1" type="Node2D" parent="YSorted/EnemyGroupSpawns"]
position = Vector2(-1008, -358)
[node name="Spawn2" type="Node2D" parent="YSorted/EnemyGroupSpawns"]
position = Vector2(1679, -434)
[node name="Spawn3" type="Node2D" parent="YSorted/EnemyGroupSpawns"]
position = Vector2(1560, 422)
[node name="Spawn4" type="Node2D" parent="YSorted/EnemyGroupSpawns"]
position = Vector2(-1127, 671)
[node name="FightSceneSwitcher" parent="." instance=ExtResource("40_elhbh")]
unique_name_in_owner = true
[node name="Debug Label" type="Label" parent="."]
offset_left = 10485.0
offset_top = 1606.0
offset_right = 12476.0
offset_bottom = 3583.0
theme_override_font_sizes/font_size = 80
text = "hello world"
[node name="FightSceneSetup" type="Node" parent="." node_paths=PackedStringArray("_enemyGroupSpawns", "_fightSceneSwitcher")]
script = ExtResource("40_cvg1r")
_enemyGroupSpawns = [NodePath("../YSorted/EnemyGroupSpawns/Spawn1"), NodePath("../YSorted/EnemyGroupSpawns/Spawn2"), NodePath("../YSorted/EnemyGroupSpawns/Spawn3"), NodePath("../YSorted/EnemyGroupSpawns/Spawn4")]
_roamingEnemyGroupPrefab = ExtResource("41_cvg1r")
_fightSceneSwitcher = NodePath("../FightSceneSwitcher")
[editable path="YSorted/Vesna"]
+2 -2
View File
@@ -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/fight/fighters/enemy_blob_fighter.tscn" id="27_hfhye"]
[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://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/fight/fighters/enemy_mavkha_fighter.tscn" id="29_hfhye"]
[ext_resource type="PackedScene" uid="uid://cr66tpdr5rma5" path="res://prefabs/fightOld/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"]
@@ -0,0 +1,39 @@
using System;
namespace Babushka.scripts.CSharp.Common.Fight.ActionDetails;
public class TargetSelectActionDetail : FighterAction.FighterActionDetail
{
public enum VisualRange
{
Single
Jonathan marked this conversation as resolved Outdated
Outdated
Review

Ein Enum mit nur einem Eintrag? Was soll da voraussichtlich noch kommen? Vielleicht

  • Single und Multiple oder vielleicht
  • Single, Double, Triple usw.?
Ein Enum mit nur einem Eintrag? Was soll da voraussichtlich noch kommen? Vielleicht - Single und Multiple oder vielleicht - Single, Double, Triple usw.?
}
// settings
public required bool selectEnemy;
public required bool selectAlly;
public VisualRange visualRange = VisualRange.Single;
// result
private FightWorld.Fighter? target;
public override bool DetailComplete()
{
return target != null;
}
public void ResetResult()
{
target = null;
}
public void SetTarget(FightWorld.Fighter fighter)
{
target = fighter;
}
public FightWorld.Fighter GetTarget()
{
return target ?? throw new InvalidOperationException("No target selected");
Jonathan marked this conversation as resolved Outdated
Outdated
Review

Muss das immer ne Exception werfen? Also kann es keinen Fall geben, wo es keine Selection gibt? ISt es dann für die Praxis nicht vielleicht nicer, wenn man nen Default definiert? Oder passiert das auf den höheren Detailebenen?

Muss das immer ne Exception werfen? Also kann es keinen Fall geben, wo es keine Selection gibt? ISt es dann für die Praxis nicht vielleicht nicer, wenn man nen Default definiert? Oder passiert das auf den höheren Detailebenen?
Outdated
Review

GetTarget sollte nur im ActionExecute und ActionAnimate state aufgerufen werden. Die states werden nur erreicht, nach dem alle action details completed sind. Das heißt es muss ein target gesetzt worden sein.

GetTarget sollte nur im ActionExecute und ActionAnimate state aufgerufen werden. Die states werden nur erreicht, nach dem alle action details completed sind. Das heißt es muss ein target gesetzt worden sein.
}
}
@@ -0,0 +1 @@
uid://e8c8ym0fyprn
@@ -0,0 +1,46 @@
using System;
using Babushka.scripts.CSharp.Common.Fight.ActionDetails;
using Babushka.scripts.CSharp.Common.Util;
using Godot;
namespace Babushka.scripts.CSharp.Common.Fight.Actions;
public class AllyAttackAction : FighterAction
{
// details
public TargetSelectActionDetail targetSelect = new()
{
selectEnemy = true,
selectAlly = false
};
public override Variant<float, Func<bool>> GetAnimationEnd()
{
return 1;
}
public override bool NextDetail()
{
return !targetSelect.DetailComplete();
}
public override FighterActionDetail CurrentDetail()
{
return targetSelect;
}
public override AllyActionButton BindToActionButton()
{
return AllyActionButton.Attack;
}
public override void Reset()
{
targetSelect.ResetResult();
}
public override void ExecuteAction()
{
targetSelect.GetTarget().AddHealth(-5);
}
}
@@ -0,0 +1 @@
uid://c8c4t80bqsja5
+114 -23
View File
@@ -1,34 +1,125 @@
using Godot;
using System;
using System.Collections.Generic;
using System.Linq;
using Babushka.scripts.CSharp.Common.Fight;
using Babushka.scripts.CSharp.Common.Fight.ActionDetails;
using Babushka.scripts.CSharp.Common.Util;
public partial class AllFightersVisual : Node
{
Jonathan marked this conversation as resolved Outdated
Outdated
Review

Diese Klasse managed das Layout der Kampfszene, oder? Das Naming hatte mich etwas verwirrt.

Diese Klasse managed das Layout der Kampfszene, oder? Das Naming hatte mich etwas verwirrt.
[Export] private Node2D _allyFighters;
[Export] private Node2D _enemyFighters;
[ExportCategory("References")] [Export]
private Node2D _allyFighters = null!;
[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)
[Export] private Node2D _enemyFighters = null!;
[ExportCategory("Fighter Visual Scenes")]
[Export] private PackedScene _blobFighterVisual = null!;
[Export] private PackedScene _bigBlobFighterVisual = null!;
[Export] private PackedScene _mavkaFighterVisual = null!;
[Export] private PackedScene _yourMomFighterVisual = null!;
[Export] private PackedScene _vesnaFighterVisual = null!;
[ExportCategory("Settings")]
[Export(PropertyHint.ArrayType)] private float[] _positionDistanceFromCenter = [10, 20, 30];
private Dictionary<FightWorld.Fighter, FighterVisual> _fighterVisuals = new();
#region Shortcuts
private FightWorld.FightHappeningData HappeningData =>
FightWorld.Instance.fightHappeningData ?? throw new NoFightHappeningException();
#endregion
#region State Reactions
public void FightHappeningStateChange(FightHappening.FightState from, FightHappening.FightState to)
{
var parent = isEnemy ? _enemyFighters : _allyFighters;
var packedScene = fighter.type switch
if (to == FightHappening.FightState.FightersEnterAnim)
{
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()
};
EnterFighter();
}
var fighterVisual = packedScene.Instantiate<FighterVisual>();
fighterVisual.Initialize(fighter);
parent.AddChild(fighterVisual);
if (to == FightHappening.FightState.InputActionDetail)
{
if (HappeningData.actionStaging!.CurrentDetail() is TargetSelectActionDetail targetDetail)
{
ShowTargetSelect(targetDetail);
}
}
if (from == FightHappening.FightState.InputActionDetail)
{
HideTargetSelect();
}
}
}
public void EnterFighter()
{
if (HappeningData.fightersEnterStaging == null)
return;
if (!HappeningData.fightersEnterStaging.HasAnyToExecute())
return;
foreach (var fighter in HappeningData.fightersEnterStaging.enteringEnemyFighters)
{
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>();
fighterVisual.Initialize(fighter);
_enemyFighters.AddChild(fighterVisual);
fighterVisual.Position = new Vector2(_positionDistanceFromCenter[_enemyFighters.GetChildCount() - 1], 0);
_fighterVisuals.Add(fighter, fighterVisual);
}
foreach (var fighter in HappeningData.fightersEnterStaging.enteringAllyFighters)
{
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>();
fighterVisual.Initialize(fighter);
_allyFighters.AddChild(fighterVisual);
fighterVisual.Position = new Vector2(-_positionDistanceFromCenter[_allyFighters.GetChildCount() - 1], 0);
_fighterVisuals.Add(fighter, fighterVisual);
}
}
private void ShowTargetSelect(TargetSelectActionDetail targetDetail)
{
if (targetDetail.selectEnemy)
_fighterVisuals.Where(kv => kv.Key.isEnemy).ForEach(kv => kv.Value.SetTargetSelectionActive(true));
if (targetDetail.selectAlly)
_fighterVisuals.Where(kv => !kv.Key.isEnemy).ForEach(kv => kv.Value.SetTargetSelectionActive(true));
}
private void HideTargetSelect()
{
foreach (var visual in _fighterVisuals.Values)
{
visual.SetTargetSelectionActive(false);
}
}
#endregion
}
@@ -0,0 +1,32 @@
using Babushka.scripts.CSharp.Common.Fight.Actions;
namespace Babushka.scripts.CSharp.Common.Fight;
public class AllyFighters
{
public FightWorld.Fighter vesnaFighter = new()
{
type = FightWorld.Fighter.Type.Vesna,
maxHealth = 20,
isEnemy = false,
availableActions =
[
new AllyAttackAction()
]
};
public FightWorld.Fighter chuhaFighter = new()
{
type = FightWorld.Fighter.Type.Chuha,
maxHealth = 15,
isEnemy = false,
availableActions =
[
new FighterAction.Skip()
]
};
public bool IsAlive()
{
return vesnaFighter.IsAlive();
}
}
@@ -0,0 +1 @@
uid://dst8xcyiw18uc
+101 -54
View File
@@ -9,7 +9,7 @@ using Godot;
namespace Babushka.scripts.CSharp.Common.Fight;
public class FightHappening
public partial class FightHappening : Node
{
/*
To get a visual overview of the FightHappening state machine, refer to the graph on miro:
@@ -36,14 +36,14 @@ public class FightHappening
EnemyWin,
}
private class FightersEnterStaging
public class FightersEnterStaging
{
public required List<FightWorld.Fighter> enteringAllyFighters;
public required List<FightWorld.Fighter> enteringEnemyFighters;
public bool HasAnyToExecute()
{
return enteringAllyFighters.Count != 0 || enteringEnemyFighters.Count != 0;
return enteringAllyFighters.Any() || enteringEnemyFighters.Any();
}
}
@@ -56,7 +56,7 @@ public class FightHappening
#endregion
#region ShortCuts
#region Shortcuts
private static FightWorld.FightHappeningData HappeningData =>
FightWorld.Instance.fightHappeningData ?? throw new NoFightHappeningException();
@@ -67,18 +67,33 @@ public class FightHappening
#region Events
public event Action<FightState>? transitionFromState;
public event Action<FightState, FightState>? transitionState;
public event Action<FightState>? transitionToState;
[Signal]
public delegate void SignalTransitionFromStateEventHandler(FightState state);
[Signal]
public delegate void SignalTransitionStateEventHandler(FightState from, FightState to);
[Signal]
public delegate void SignalTransitionToStateEventHandler(FightState state);
#endregion
#region Staging
#region Singleton
private FightersEnterStaging? _fightersEnterStaging;
private FighterAction? _actionStaging;
public static FightHappening Instance = null!;
private void SetupInstance()
{
Instance = this;
}
#endregion
public override void _Ready()
{
SetupInstance();
StartFight();
}
#region Public Methods
@@ -88,17 +103,51 @@ public class FightHappening
ChangeState(FightState.FightStartAnim);
}
public void ActionSelect(FighterAction action)
{
RequireState(FightState.InputActionSelect);
HappeningData.actionStaging = action;
action.Reset();
ChangeState(FightState.ActionCheckDetails);
}
public void DetailFilled()
{
RequireState(FightState.InputActionDetail);
ChangeState(FightState.ActionCheckDetails);
}
#endregion
#region State Machine
private bool _inTransition = false;
private FightState? _changeToAfterTransition = null;
private void ChangeState(FightState nextState)
{
_changeToAfterTransition = null;
if (_inTransition)
{
_changeToAfterTransition = nextState;
return;
}
_inTransition = true;
TransitionFromState();
var lastState = HappeningData.fightState;
HappeningData.fightState = nextState;
TransitionFromToState(nextState, lastState);
TransitionToState(nextState);
EmitSignalSignalTransitionFromState(lastState);
EmitSignalSignalTransitionState(lastState, nextState);
EmitSignalSignalTransitionToState(nextState);
_inTransition = false;
if (_changeToAfterTransition.HasValue)
{
ChangeState(_changeToAfterTransition.Value);
}
}
private void TransitionFromState()
@@ -108,21 +157,10 @@ public class FightHappening
{
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)
{
@@ -130,8 +168,8 @@ public class FightHappening
AdvanceToStateInSeconds(FightState.FightersEnter, StartAnimationTime);
break;
case FightState.FightersEnter:
_fightersEnterStaging = StageFightersEnter();
if (_fightersEnterStaging.HasAnyToExecute())
HappeningData.fightersEnterStaging = StageFightersEnter();
if (HappeningData.fightersEnterStaging.HasAnyToExecute())
{
ExecuteFightersEnter();
ChangeState(FightState.FightersEnterAnim);
@@ -150,10 +188,11 @@ public class FightHappening
ChangeState(FightState.StateCheck);
break;
case FightState.StateCheck:
// restest action staging
_actionStaging = null;
// restest action staging and fighter enter staging
HappeningData.actionStaging = null;
HappeningData.fightersEnterStaging = null;
if ( /*TODO: are all allys dead*/ false)
if (!FightWorld.Instance.allyFighters.IsAlive())
{
ChangeState(FightState.EnemyWin);
}
@@ -161,7 +200,7 @@ public class FightHappening
{
ChangeState(FightState.PlayerWin);
}
else if (CurrentFighter.actionsLeft <= 0)
else if (CurrentFighter.actionPointsLeft <= 0)
{
ChangeState(FightState.FightersEnter);
}
@@ -179,9 +218,11 @@ public class FightHappening
// wait for player input
break;
case FightState.ActionCheckDetails:
RequireNotNull(HappeningData.actionStaging);
if (ActionAbort())
ChangeState(FightState.InputActionSelect);
else if (ActionNeededDetail() != null)
else if (ActionNeededDetail())
ChangeState(FightState.InputActionDetail);
else
ChangeState(FightState.ActionExecute);
@@ -190,7 +231,7 @@ public class FightHappening
// wait for player input
break;
case FightState.EnemyActionSelect:
_actionStaging = CurrentFighter.AutoSelectAction();
HappeningData.actionStaging = CurrentFighter.AutoSelectAction();
ChangeState(FightState.ActionExecute);
break;
case FightState.ActionExecute:
@@ -212,7 +253,6 @@ public class FightHappening
default: break;
}
}
#endregion
#region Game Logic
@@ -221,38 +261,33 @@ public class FightHappening
{
// ally
var enteringAllyFighters = new List<FightWorld.Fighter>();
//TODO
var allyFighters = FightWorld.Instance.allyFighters;
if (!allyFighters.vesnaFighter.entered)
{
enteringAllyFighters.Add(allyFighters.vesnaFighter);
}
// enemy
const int totalEnemySpace = 3;
var enemySpaceLeft = totalEnemySpace - HappeningData.enemyGroup.GetEnteredAmount();
var enterEnemyFighters = new List<FightWorld.Fighter>();
for (var i = 0; i < enemySpaceLeft; i++)
{
if (HappeningData.enemyGroup.TryGetFirstUnenteredFighter(out var fighter))
{
enterEnemyFighters.Add(fighter);
}
}
return new FightersEnterStaging
{
enteringAllyFighters = enteringAllyFighters,
enteringEnemyFighters = enterEnemyFighters
enteringEnemyFighters = HappeningData.enemyGroup.GetUptoUnenteredFighters(enemySpaceLeft).ToList()
};
}
private void ExecuteFightersEnter()
{
Debug.Assert(_fightersEnterStaging != null);
foreach (var fighter in _fightersEnterStaging.enteringAllyFighters)
Debug.Assert(HappeningData.fightersEnterStaging != null);
foreach (var fighter in HappeningData.fightersEnterStaging.enteringAllyFighters)
{
fighter.entered = true;
HappeningData.fighterStack.AddAsLast(fighter);
}
foreach (var fighter in _fightersEnterStaging.enteringEnemyFighters)
foreach (var fighter in HappeningData.fightersEnterStaging.enteringEnemyFighters)
{
fighter.entered = true;
HappeningData.fighterStack.AddAsLast(fighter);
@@ -262,30 +297,32 @@ public class FightHappening
private void ExecuteNextFighter()
{
HappeningData.fighterStack.Next();
CurrentFighter.actionPointsLeft = CurrentFighter.maxActionPoints;
}
private void ExecuteAction()
{
Debug.Assert(_actionStaging != null);
_actionStaging.ExecuteAction();
Debug.Assert(HappeningData.actionStaging != null);
HappeningData.actionStaging.ExecuteAction();
CurrentFighter.actionPointsLeft -= HappeningData.actionStaging.GetActionPointCost();
}
private Variant<float, Func<bool>> GetActionAnimationEnd()
{
Debug.Assert(_actionStaging != null);
return _actionStaging.GetAnimationEnd();
Debug.Assert(HappeningData.actionStaging != null);
return HappeningData.actionStaging.GetAnimationEnd();
}
private bool ActionAbort()
{
Debug.Assert(_actionStaging != null);
return _actionStaging.MarkedForAbort();
Debug.Assert(HappeningData.actionStaging != null);
return HappeningData.actionStaging.MarkedForAbort();
}
private FighterAction.FighterActionDetail? ActionNeededDetail()
private bool ActionNeededDetail()
{
Debug.Assert(_actionStaging != null);
return _actionStaging.NeededDetail();
Debug.Assert(HappeningData.actionStaging != null);
return HappeningData.actionStaging.NextDetail();
}
#endregion // Game Logic
@@ -300,6 +337,14 @@ public class FightHappening
throw new Exception(
$"Can not call this Method while in state {HappeningData.fightState}. Only available in {string.Join(" ,", states)}");
}
private void RequireNotNull(Object? o)
{
if (o != null)
return;
throw new Exception("Object must not be null to call this method");
}
private void AdvanceToStateInSeconds(FightState nextState, float seconds)
{
@@ -317,4 +362,6 @@ public class FightHappening
}
#endregion
}
@@ -0,0 +1,53 @@
using Godot;
using System;
using System.Linq;
using Babushka.scripts.CSharp.Common.Fight;
public partial class FightHappeningStateDebugger : Node
{
[Export] private Label _label;
private FightWorld.FightHappeningData Data => FightWorld.Instance.fightHappeningData!;
public void StateChange(FightHappening.FightState from, FightHappening.FightState to)
{
_label.Text += $"State changed from {from} to {to}\n";
switch (to)
{
case FightHappening.FightState.None:
break;
case FightHappening.FightState.FightStartAnim:
break;
case FightHappening.FightState.FightersEnter:
break;
case FightHappening.FightState.FightersEnterAnim:
_label.Text +=
$" {Data.fightersEnterStaging!.enteringAllyFighters.Count} allies " +
$"and {Data.fightersEnterStaging.enteringEnemyFighters.Count} enemies are entering the fight.\n";
break;
case FightHappening.FightState.NextFighter:
break;
case FightHappening.FightState.StateCheck:
break;
case FightHappening.FightState.InputActionSelect:
break;
case FightHappening.FightState.ActionCheckDetails:
break;
case FightHappening.FightState.InputActionDetail:
break;
case FightHappening.FightState.ActionExecute:
_label.Text += $" Executing action: {Data.actionStaging!.GetType()}\n";
break;
case FightHappening.FightState.ActionAnim:
break;
case FightHappening.FightState.EnemyActionSelect:
break;
case FightHappening.FightState.PlayerWin:
break;
case FightHappening.FightState.EnemyWin:
break;
default:
throw new ArgumentOutOfRangeException(nameof(to), to, null);
}
}
}
@@ -0,0 +1 @@
uid://d2ugtb3dalrg3
@@ -0,0 +1,27 @@
using Godot;
namespace Babushka.scripts.CSharp.Common.Fight;
public partial class FightHappeningStateReaction : Node
{
[Export] private FightHappening.FightState _fightState;
[Signal]
public delegate void OnStateEnteredEventHandler();
[Signal]
public delegate void OnStateExitedEventHandler();
public void FightHappeningStateTransitioned(FightHappening.FightState fromState, FightHappening.FightState toState)
{
if (fromState == _fightState)
{
EmitSignalOnStateExited();
}
if (toState == _fightState)
{
EmitSignalOnStateEntered();
}
}
}
@@ -0,0 +1 @@
uid://buiwuf7pjfq8
@@ -1,21 +1,29 @@
using System.Collections.Generic;
using Babushka.scripts.CSharp.Common.Util;
using Godot;
namespace Babushka.scripts.CSharp.Common.Fight;
public partial class FightRoomSceneSetup : Node
{
[Export] private Label debugLabel;
[Export(PropertyHint.ArrayType)] private Node2D[] _enemyGroupSpawns;
[Export] private PackedScene _roamingEnemyGroupPrefab;
[Export] private FightSceneSwitcher _fightSceneSwitcher;
public override void _Ready()
{
var room = FightWorld.Instance.currentRoom!;
debugLabel.Text = $"Room Debug:\n{room.paths.Count} paths out of this room\n{room.enemyGroups.Count} enemy groups:\n";
foreach (var enemyGroup in room.enemyGroups)
var i = 0;
foreach (var availableParent in _enemyGroupSpawns.Shuffle())
{
debugLabel.Text += $" {enemyGroup.enemies.Count} enemies:\n";
foreach (var enemy in enemyGroup.enemies)
{
debugLabel.Text += $" {enemy.type}\n";
}
var enemyGroup = room.enemyGroups[i];
var roamingEnemyGroup = _roamingEnemyGroupPrefab.Instantiate<RoamingEnemyGroup>();
roamingEnemyGroup.Initialize(enemyGroup, _fightSceneSwitcher);
availableParent.AddChild(roamingEnemyGroup);
if (i >= room.enemyGroups.Count - 1) break;
i++;
}
}
}
@@ -25,7 +25,7 @@ public partial class FightSceneSwitcher : Node
private async void UnloadAfterDelay()
{
await ToSignal(GetTree().CreateTimer(1.0f), "timeout"); // 1.0f seconds
sceneRoot.QueueFree();
//sceneRoot.QueueFree();
}
public void SwitchRoom(int pathIndex)
@@ -38,4 +38,16 @@ public partial class FightSceneSwitcher : Node
FightWorld.Instance.currentRoom = nextRoom;
LoadNext();
}
public void SwitchToFight(FightWorld.FighterGroup enemyGroup)
{
if (FightWorld.Instance.fightHappeningData != null)
throw new Exception("Trying to start a fight while already in a fight");
FightWorld.Instance.fightHappeningData = new FightWorld.FightHappeningData
{
enemyGroup = enemyGroup,
};
LoadNext();
}
}
+18 -13
View File
@@ -5,41 +5,46 @@ namespace Babushka.scripts.CSharp.Common.Fight;
public static class FightUtils
{
public static int GetEnteredAmount(this FightWorld.EnemyGroup self)
public static int GetEnteredAmount(this FightWorld.FighterGroup self)
{
return self.enemies.Count(e => e.IsAlive() && e.entered);
}
public static bool TryGetFirstUnenteredFighter(this FightWorld.EnemyGroup self, out FightWorld.Fighter fighter)
public static IEnumerable<FightWorld.Fighter> GetUptoUnenteredFighters(
this FightWorld.FighterGroup self,
int maxFighters)
{
foreach (var f in self.enemies.Where(e=>!e.entered && e.IsAlive()))
{
fighter = f;
return true;
}
if (maxFighters <= self.enemies.Count)
return self.enemies
.Where(e => !e.entered && e.IsAlive());
fighter = null!;
return false;
return self.enemies
.Where(e => !e.entered && e.IsAlive())
.Take(maxFighters);
}
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)
public static void AddHealth(this FightWorld.Fighter self, int addHealth)
{
self.health = self.GetHealth() + addHealth;
}
public static bool AreAllDead(this FightWorld.FighterGroup self)
{
return self.enemies.All(e => e.IsDead());
}
}
+24 -17
View File
@@ -14,10 +14,10 @@ public partial class FightWorld : Node
public class Room
{
public required Dictionary<int, Room> paths;
public required List<EnemyGroup> enemyGroups;
public required List<FighterGroup> enemyGroups;
}
public class EnemyGroup
public class FighterGroup
{
public required List<Fighter> enemies;
}
@@ -26,7 +26,9 @@ public partial class FightWorld : Node
{
public FightHappening.FightState fightState = FightHappening.FightState.None;
public FighterStack fighterStack = new();
public required EnemyGroup enemyGroup;
public required FighterGroup enemyGroup;
public FightHappening.FightersEnterStaging? fightersEnterStaging;
public FighterAction? actionStaging;
}
public class Fighter
@@ -37,16 +39,18 @@ public partial class FightWorld : Node
BigBlob,
Mavka,
YourMom,
Vesna
Vesna,
Chuha
}
public required Type type;
public required int maxHealth;
public required bool isEnemy;
public required List<FighterAction> availableActions;
public int maxActionPoints = 1;
public int? health = null; // null => initialize to full health on spawn
public bool entered = false;
public int actionsLeft;
public int actionPointsLeft;
public FighterAction AutoSelectAction()
{
@@ -69,6 +73,7 @@ public partial class FightWorld : Node
public World? world = null;
public Room? currentRoom = null;
public FightHappeningData? fightHappeningData = null;
public AllyFighters allyFighters = new();
public void MyEnterTree()
{
@@ -123,9 +128,9 @@ public partial class FightWorld : Node
return room;
}
private List<EnemyGroup> GenerateEnemyGroups()
private List<FighterGroup> GenerateEnemyGroups()
{
var enemyGroups = new List<EnemyGroup>();
var enemyGroups = new List<FighterGroup>();
var enemyGroupCount = GD.RandRange(1, 3);
@@ -137,9 +142,9 @@ public partial class FightWorld : Node
return enemyGroups;
}
private EnemyGroup GenerateSingleEnemyGroup()
private FighterGroup GenerateSingleEnemyGroup()
{
var enemyGroup = new EnemyGroup
var enemyGroup = new FighterGroup
{
enemies = []
};
@@ -158,13 +163,14 @@ public partial class FightWorld : Node
{
var typeRoll = GD.RandRange(0, 99);
var type = typeRoll switch
{
< 50 => Fighter.Type.Blob,
< 75 => Fighter.Type.BigBlob,
< 90 => Fighter.Type.Mavka,
_ => Fighter.Type.YourMom
};
//var type = typeRoll switch
//{
// < 50 => Fighter.Type.Blob,
// < 75 => Fighter.Type.BigBlob,
// < 90 => Fighter.Type.Mavka,
// _ => Fighter.Type.YourMom
//};
var type = Fighter.Type.Blob;
var enemy = new Fighter
{
@@ -172,7 +178,8 @@ public partial class FightWorld : Node
health = null,
isEnemy = true,
maxHealth = 12,
availableActions = [
availableActions =
[
new FighterAction.Skip()
]
};
+56 -5
View File
@@ -7,13 +7,24 @@ namespace Babushka.scripts.CSharp.Common.Fight;
public abstract class FighterAction
{
// enum has explicit values, because they are set in godot signals as integers
// e.g. here: BabushkaSceneFightHappening => ActionSelect/BottomPanel/VBoxContainer/MarginContainer/HBoxContainer/MarginContainer/AttackButton
public enum AllyActionButton
{
None,
Attack = 1,
Summon = 2,
Talk = 3,
Flee = 4,
}
public class TargetSelection
{
// ReSharper disable once MemberHidesStaticFromOuterClass
public static readonly TargetSelection Skip = new() { skipTargetSelection = () => true };
public Func<bool> skipTargetSelection = () => false;
}
public abstract class FighterActionDetail
{
public abstract bool DetailComplete();
@@ -63,7 +74,46 @@ public abstract class FighterAction
return _abort;
}
public abstract FighterActionDetail? NeededDetail();
/// <summary>
/// Returns the FighterActionDetail, that is currently handled.
/// </summary>
/// <returns></returns>
public virtual FighterActionDetail CurrentDetail()
{
throw new Exception("Action has no details to handle");
}
/// <summary>
/// Sets the next Detail to be handled. Returns false, when there are no more details to handle.
/// </summary>
/// <returns></returns>
public abstract bool NextDetail();
/// <summary>
/// Returns the action point cost of this action.
/// Right now, only the values 1 and 0 make sense.
/// </summary>
/// <returns></returns>
public virtual int GetActionPointCost()
{
return 1;
}
/// <summary>
/// Will be called right after the action is selected by the player. Can be used to reset the state of the details
/// </summary>
public virtual void Reset()
{
}
/// <summary>
/// If this action should be bound to an action button in the UI, return the corresponding enum value here.
/// </summary>
/// <returns></returns>
public virtual AllyActionButton BindToActionButton()
{
return AllyActionButton.None;
}
public class Skip : FighterAction
{
@@ -72,9 +122,10 @@ public abstract class FighterAction
return 0f;
}
public override FighterActionDetail? NeededDetail()
public override bool NextDetail()
{
return null;
return false;
}
}
}
}
@@ -0,0 +1 @@
uid://c60jugfee0bpv
@@ -0,0 +1 @@
uid://bahm4ukspymm2
+46 -106
View File
@@ -1,131 +1,72 @@
using Godot;
using System;
using Babushka.scripts.CSharp.Common.Fight.ActionDetails;
using Godot;
using Godot.Collections;
namespace Babushka.scripts.CSharp.Common.Fight;
[Tool]
public partial class FighterVisual : Node2D
{
//[Export] public string name;
//[Export] public int maxHealth;
//[Export] public int attackStrength;
//[Export] public int maxActions = 1;
[Export] public FightWorld.Fighter.Type type;
#region Shortcuts
[ExportCategory("References")]
[Export] private Node2D _attackButtons;
[Export] private Node2D _targetButtons;
[Export] private Node2D _targetMarker;
[Export] private Label _healthText;
[Export] private Node2D _visualSprite;
private FightWorld.FightHappeningData HappeningData =>
FightWorld.Instance.fightHappeningData ?? throw new NoFightHappeningException();
[Signal] public delegate void DamageTakenEventHandler();
[Signal] public delegate void AttackingEventHandler();
[Signal] public delegate void DyingEventHandler();
[Signal] public delegate void HealedEventHandler();
#endregion
[ExportCategory("References")]
[Export] private Node2D _visualParent;
[Export] private Node2D _targetSelectionParent;
[Signal]
public delegate void DamageTakenEventHandler();
[Signal]
public delegate void AttackingEventHandler();
[Signal]
public delegate void DyingEventHandler();
[Signal]
public delegate void HealedEventHandler();
private FightWorld.Fighter _boundFighter;
//private void Die()
//{
// _visualSprite.Scale = new Vector2(1, 0.3f);
// EmitSignalDying();
//}
//public override void _Ready()
//{
// UpdateHealthVisual();
// ResetActions();
//}
public void Initialize(FightWorld.Fighter fighter)
{
_boundFighter = fighter;
UpdateHealthVisual();
UpdateMirrorState();
}
public void Attack()
/// <summary>
/// fighter visuals should always look to the right in the scene.
/// This function flips the sprites horizontally, when the fighter is an enemy.
/// </summary>
private void UpdateMirrorState()
{
//FightHappening.SelectAttack(this);
_visualParent.Scale = new Vector2(_boundFighter.isEnemy ? -1 : 1, 1);
}
public void HideAttackButton()
public void SetTargetSelectionActive(bool value)
{
_attackButtons.Hide();
_targetSelectionParent.Visible = value;
_targetSelectionParent.ProcessMode = value ? ProcessModeEnum.Inherit : ProcessModeEnum.Disabled;
}
public void ShowAttackButton()
// listen from inside
public void ClickedTarget()
{
_attackButtons.Show();
}
if (HappeningData.actionStaging!.CurrentDetail() is not TargetSelectActionDetail targetDetail)
throw new InvalidOperationException("No target selection needed right now");
public void HideTargetButtons()
{
_targetButtons.Hide();
targetDetail.SetTarget(_boundFighter);
FightHappening.Instance.DetailFilled();
}
public void ShowTargetButtons()
{
_targetButtons.Show();
}
public void TargetMouseEvent(Node viewport, InputEvent inputEvent, int shapeIdx)
{
if (inputEvent.IsPressed())
ClickedTarget();
}
public void AttackMouseEvent(Node viewport, InputEvent inputEvent, int shapeIdx)
{
if (inputEvent.IsPressed())
ClickedAttack();
}
public void HealMouseEvent(Node viewport, InputEvent inputEvent, int shapeIdx)
{
if (inputEvent.IsPressed())
ClickedHeal();
}
private void ClickedAttack()
{
//FightHappening.SelectAttack(this);
}
private void ClickedHeal()
{
//FightHappening.SelectHeal(this);
}
private void ClickedTarget()
{
//FightHappening.SelectTargetAndAttack(this);
}
public void StartHoverTarget()
{
_targetMarker.Visible = true;
}
public void EndHoverTarget()
{
_targetMarker.Visible = false;
}
public void UpdateHealthVisual()
{
_healthText.Text = $"{_boundFighter.health}";
}
public bool IsDead()
{
//return Health <= 0;
return true;
}
public void ResetActions()
{
//_actions = maxActions;
}
// Animations
public void AttackAnimation(FightAttack attack)
{
EmitSignalAttacking();
@@ -134,7 +75,6 @@ public partial class FighterVisual : Node2D
tween.TweenCallback(Callable.From(() => attack.target?.HitAnimation(attack)));
tween.TweenProperty(this, "position", new Vector2(0, 0), 0.7)
.SetTrans(Tween.TransitionType.Cubic).SetEase(Tween.EaseType.Out);
}
private void HitAnimation(FightAttack attack)
@@ -154,4 +94,4 @@ public partial class FighterVisual : Node2D
tween.TweenProperty(this, "scale", new Vector2(1, 1), 0.4)
.SetTrans(Tween.TransitionType.Cubic).SetEase(Tween.EaseType.Out);
}
}
}
@@ -0,0 +1 @@
uid://b2n37glcxm8wv
@@ -0,0 +1,20 @@
using Godot;
namespace Babushka.scripts.CSharp.Common.Fight;
public partial class RoamingEnemyGroup : Node2D
{
private FightWorld.FighterGroup _boundEnemyGroup;
private FightSceneSwitcher _fightSceneSwitcher;
public void Initialize(FightWorld.FighterGroup enemyGroup, FightSceneSwitcher fightSceneSwitcher)
{
_boundEnemyGroup = enemyGroup;
_fightSceneSwitcher = fightSceneSwitcher;
}
public void StartFight()
{
_fightSceneSwitcher.SwitchToFight(_boundEnemyGroup);
}
}
@@ -0,0 +1 @@
uid://lequnojtar76
@@ -0,0 +1,35 @@
using System.Linq;
using Godot;
namespace Babushka.scripts.CSharp.Common.Fight.UI;
public partial class ActionSelectUiSetup : CanvasLayer
{
// shortcuts
private FightWorld.FightHappeningData HappeningData =>
FightWorld.Instance.fightHappeningData ?? throw new NoFightHappeningException();
private FightWorld.Fighter CurrentFighter => HappeningData.fighterStack.Current;
// references
[Export] private Button _attackActionButton = null!;
[Export] private Button _summonActionButton = null!;
[Export] private Button _talkActionButton = null!;
[Export] private Button _fleeActionButton = null!;
// gets called from a state reaction enter (InputActionSelect)
public void StateEntered()
{
var actions = CurrentFighter.availableActions;
_attackActionButton.Visible = actions.Any(a => a.BindToActionButton() == FighterAction.AllyActionButton.Attack);
_summonActionButton.Visible = actions.Any(a => a.BindToActionButton() == FighterAction.AllyActionButton.Summon);
_talkActionButton.Visible = actions.Any(a => a.BindToActionButton() == FighterAction.AllyActionButton.Talk);
_fleeActionButton.Visible = actions.Any(a => a.BindToActionButton() == FighterAction.AllyActionButton.Flee);
}
public void SelectAction(FighterAction.AllyActionButton actionButton)
{
var action = CurrentFighter.availableActions.First(a => a.BindToActionButton() == actionButton);
FightHappening.Instance.ActionSelect(action);
}
}
@@ -0,0 +1 @@
uid://byf2ywov34g0x
@@ -0,0 +1,16 @@
using Godot;
using System;
public partial class TargetSelectionClick : Area2D
{
[Signal]
public delegate void TargetSelectedEventHandler();
public override void _InputEvent(Viewport viewport, InputEvent @event, int shapeIdx)
{
if (@event is InputEventMouseButton { Pressed: true, ButtonIndex: MouseButton.Left })
{
EmitSignalTargetSelected();
}
}
}
@@ -0,0 +1 @@
uid://boprnfciqgixf
+22
View File
@@ -16,6 +16,16 @@ public static class LinqExtras
}
}
public static void ForEach<T>(this IEnumerable<T> self, Action<T, int> action)
{
var i = 0;
foreach (var t in self)
{
action.Invoke(t, i);
i++;
}
}
public static T? Random<T>(this IEnumerable<T> self)
{
var selfList = self.ToList();
@@ -24,4 +34,16 @@ public static class LinqExtras
var randomIndex = new Random().Next(0, selfList.Count);
return selfList[randomIndex];
}
public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> self)
{
var selfList = self.ToList();
var random = new Random();
for (var i = 0; i < selfList.Count; i++)
{
var j = random.Next(i, selfList.Count);
(selfList[i], selfList[j]) = (selfList[j], selfList[i]);
}
return selfList;
}
}
@@ -0,0 +1 @@
uid://bxs7sn7j3vd0n