Made fight fightable

test/music_setup
jonathan 3 months ago
parent daabcdc5ee
commit 8055381478

@ -1,5 +1,6 @@
<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"> <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_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_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_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_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> <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>
<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_003FLocal_003FTemp_003FSourceGeneratedDocuments_003F9509A9D00FD8A232B5E86A84_003FGodot_002ESourceGenerators_003FGodot_002ESourceGenerators_002EScriptPropertiesGenerator_003FBabushka_002Escripts_002ECSharp_002ECommon_002EFarming_002EVesnaBehaviour2D_005FScriptProperties_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_005FScriptProperties_002Egenerated_002Ecs_002Fl_003AC_0021_003FUsers_003FJonathan_003FAppData_003FLocal_003FTemp_003FSourceGeneratedDocuments_003F9509A9D00FD8A232B5E86A84_003FGodot_002ESourceGenerators_003FGodot_002ESourceGenerators_002EScriptPropertiesGenerator_003FBabushka_002Escripts_002ECSharp_002ECommon_002EFarming_002EVesnaBehaviour2D_005FScriptProperties_002Egenerated_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
@ -7,15 +8,19 @@
<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_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_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_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_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_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_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_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_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_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_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_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_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_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/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; <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; &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"]

@ -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,7 +1,7 @@
[gd_scene load_steps=3 format=3 uid="uid://cnjsepvaqdbyq"] [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="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"] [node name="FightManagerAutoload" type="Node"]
script = ExtResource("1_8p7ev") script = ExtResource("1_8p7ev")

@ -28,7 +28,6 @@ buses/default_bus_layout="uid://b6dwkmkyb0axk"
SceneTransition="*res://scenes/SceneTransition.tscn" SceneTransition="*res://scenes/SceneTransition.tscn"
Dialogic="*res://addons/dialogic/Core/DialogicGameHandler.gd" Dialogic="*res://addons/dialogic/Core/DialogicGameHandler.gd"
InventoryManager="*res://scripts/CSharp/Common/Inventory/InventoryManager.cs" InventoryManager="*res://scripts/CSharp/Common/Inventory/InventoryManager.cs"
FightManagerAutoload="*res://prefabs/fightOld/fight_manager_autoload.tscn"
InputService="*res://scripts/CSharp/Common/Services/InputService.cs" InputService="*res://scripts/CSharp/Common/Services/InputService.cs"
QuestManager="*res://prefabs/quests/quest_manager_autoload.tscn" QuestManager="*res://prefabs/quests/quest_manager_autoload.tscn"
Signal_Debugger="*res://addons/SignalVisualizer/Debugger/SignalDebugger.gd" Signal_Debugger="*res://addons/SignalVisualizer/Debugger/SignalDebugger.gd"

@ -5,5 +5,6 @@
[node name="BabushkaSceneBootstrap" type="Node2D"] [node name="BabushkaSceneBootstrap" type="Node2D"]
[node name="BabushkaSceneStartMenu" parent="." instance=ExtResource("1_15ton")] [node name="BabushkaSceneStartMenu" parent="." instance=ExtResource("1_15ton")]
_sceneNamesToLoad = PackedStringArray("res://scenes/Babushka_scene_fight_world_room.tscn")
[node name="SceneParent" type="Node" parent="."] [node name="SceneParent" type="Node" parent="."]

@ -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://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://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="BabushkaSceneFightHappening" type="Node2D"]
[node name="FightHappening" type="Node" parent="."]
script = ExtResource("1_gsk03")
[node name="Camera2D" type="Camera2D" parent="."] [node name="Camera2D" type="Camera2D" parent="."]
[node name="FightSetup" type="Node2D" parent="."] [node name="FightSetup" type="Node2D" parent="."]
script = ExtResource("1_fiutj") 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) position = Vector2(0, 259)
script = ExtResource("2_lu4y4") 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"] [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="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"] [node name="BottomPanel" type="Control" parent="ActionSelect"]
custom_minimum_size = Vector2(0, 200) 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_colors/font_color = Color(0, 0, 0, 1)
theme_override_font_sizes/font_size = 41 theme_override_font_sizes/font_size = 41
text = "This text explains the currently hovered button" 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"]

@ -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="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"] [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="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://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://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://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"] [sub_resource type="ShaderMaterial" id="ShaderMaterial_ruj2u"]
shader = ExtResource("16_0fard") shader = ExtResource("16_0fard")
@ -1998,7 +1999,6 @@ y_sort_enabled = true
[node name="Visuals" type="Node2D" parent="YSorted/Paths/Path0/PathVariants/Closed"] [node name="Visuals" type="Node2D" parent="YSorted/Paths/Path0/PathVariants/Closed"]
y_sort_enabled = true y_sort_enabled = true
scale = Vector2(1, 1)
[node name="bush14" type="Sprite2D" parent="YSorted/Paths/Path0/PathVariants/Closed/Visuals"] [node name="bush14" type="Sprite2D" parent="YSorted/Paths/Path0/PathVariants/Closed/Visuals"]
y_sort_enabled = true y_sort_enabled = true
@ -2022,7 +2022,6 @@ y_sort_enabled = true
[node name="Visuals" type="Node2D" parent="YSorted/Paths/Path0/PathVariants/OpenToFightRoom"] [node name="Visuals" type="Node2D" parent="YSorted/Paths/Path0/PathVariants/OpenToFightRoom"]
y_sort_enabled = true y_sort_enabled = true
scale = Vector2(1, 1)
[node name="bush14" type="Sprite2D" parent="YSorted/Paths/Path0/PathVariants/OpenToFightRoom/Visuals"] [node name="bush14" type="Sprite2D" parent="YSorted/Paths/Path0/PathVariants/OpenToFightRoom/Visuals"]
z_index = 100 z_index = 100
@ -2074,7 +2073,6 @@ y_sort_enabled = true
[node name="Visuals" type="Node2D" parent="YSorted/Paths/Path1/PathVariants/Closed"] [node name="Visuals" type="Node2D" parent="YSorted/Paths/Path1/PathVariants/Closed"]
y_sort_enabled = true y_sort_enabled = true
scale = Vector2(1, 1)
[node name="bush14" type="Sprite2D" parent="YSorted/Paths/Path1/PathVariants/Closed/Visuals"] [node name="bush14" type="Sprite2D" parent="YSorted/Paths/Path1/PathVariants/Closed/Visuals"]
y_sort_enabled = true y_sort_enabled = true
@ -2112,7 +2110,6 @@ y_sort_enabled = true
[node name="Visuals" type="Node2D" parent="YSorted/Paths/Path1/PathVariants/OpenToFightRoom"] [node name="Visuals" type="Node2D" parent="YSorted/Paths/Path1/PathVariants/OpenToFightRoom"]
y_sort_enabled = true y_sort_enabled = true
scale = Vector2(1, 1)
[node name="bush14" type="Sprite2D" parent="YSorted/Paths/Path1/PathVariants/OpenToFightRoom/Visuals"] [node name="bush14" type="Sprite2D" parent="YSorted/Paths/Path1/PathVariants/OpenToFightRoom/Visuals"]
z_index = 100 z_index = 100
@ -2136,20 +2133,28 @@ pathIndex = 1
position = Vector2(-335, 18) position = Vector2(-335, 18)
shape = SubResource("RectangleShape2D_ir2xa") shape = SubResource("RectangleShape2D_ir2xa")
[node name="FightSceneSetup" type="Node" parent="." node_paths=PackedStringArray("debugLabel")] [node name="EnemyGroupSpawns" type="Node2D" parent="YSorted"]
unique_name_in_owner = true position = Vector2(11116, 2546)
script = ExtResource("37_hqa4k")
debugLabel = NodePath("../Debug Label") [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")] [node name="FightSceneSwitcher" parent="." instance=ExtResource("40_elhbh")]
unique_name_in_owner = true unique_name_in_owner = true
[node name="Debug Label" type="Label" parent="."] [node name="FightSceneSetup" type="Node" parent="." node_paths=PackedStringArray("_enemyGroupSpawns", "_fightSceneSwitcher")]
offset_left = 10485.0 script = ExtResource("40_cvg1r")
offset_top = 1606.0 _enemyGroupSpawns = [NodePath("../YSorted/EnemyGroupSpawns/Spawn1"), NodePath("../YSorted/EnemyGroupSpawns/Spawn2"), NodePath("../YSorted/EnemyGroupSpawns/Spawn3"), NodePath("../YSorted/EnemyGroupSpawns/Spawn4")]
offset_right = 12476.0 _roamingEnemyGroupPrefab = ExtResource("41_cvg1r")
offset_bottom = 3583.0 _fightSceneSwitcher = NodePath("../FightSceneSwitcher")
theme_override_font_sizes/font_size = 80
text = "hello world"
[editable path="YSorted/Vesna"] [editable path="YSorted/Vesna"]

@ -26,10 +26,10 @@
[ext_resource type="Shader" uid="uid://xnky830dtfsn" path="res://shader/repeat_texture.gdshader" id="25_sgom5"] [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="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://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://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://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://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="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"] [ext_resource type="Texture2D" uid="uid://dyueumlr5ltvr" path="res://art/nature/baum märz 2025/megaeichel megaast.png" id="37_gg38r"]

@ -1,4 +1,6 @@
using System; using System;
using System.Linq;
using Babushka.scripts.CSharp.Common.Util;
using Godot; using Godot;
namespace Babushka.scripts.CSharp.Common.CharacterControls; namespace Babushka.scripts.CSharp.Common.CharacterControls;
@ -10,80 +12,89 @@ public partial class InteractionArea2D : Node2D
[Export] private bool _active = true; [Export] private bool _active = true;
[Export] private bool _useOutline = true; [Export] private bool _useOutline = true;
[Export] private ShaderMaterial _outlineMaterial; [Export] private ShaderMaterial _outlineMaterial;
[Export] private bool _useSprite = true; //[Export] private bool _useSprite = true;
[Export] private CanvasItem _spriteToOutline; [Export(PropertyHint.ArrayType)] private CanvasItem[] _spriteToOutline = [];
[Export] private bool _showLabel = true; [Export] private bool _showLabel = true;
[Export] private int _id = -1; // TODO: remove [Export] private int _id = -1; // TODO: remove
private Material _backupMaterial; private Material[] _backupMaterial;
[Signal] public delegate void InteractedToolEventHandler(int id); // TODO: remove [Signal] public delegate void InteractedToolEventHandler(int id); // TODO: remove
[Signal] public delegate void InteractedEventHandler(); [Signal] public delegate void InteractedEventHandler();
public bool IsActive public bool IsActive
{ {
get => _active; get => _active;
set => _active = value; set => _active = value;
} }
public override void _Ready() public override void _Ready()
{ {
if (_useOutline)
if (_useSprite && _useOutline)
{ {
try try
{ {
_backupMaterial = _spriteToOutline.Material; _backupMaterial = _spriteToOutline.Select(s => s.Material).ToArray();
} }
catch(Exception exception) catch (Exception exception)
{ {
GD.PrintErr($"No sprite to outline found on: {GetParent().Name}" + exception.Message); GD.PrintErr($"No sprite to outline found on: {GetParent().Name}" + exception.Message);
} }
} }
} }
public void OnPlayerEntered(Node2D player) public void OnPlayerEntered(Node2D player)
{ {
if (!_active) if (!_active)
return; return;
if(_showLabel) if (_showLabel)
_label.Show(); _label.Show();
if (!_useSprite || !_useOutline) if (!_useOutline)
return; return;
_spriteToOutline.Material = _outlineMaterial; _spriteToOutline.ForEach(s => s.Material = _outlineMaterial);
} }
public void OnPlayerExited(Node2D player) public void OnPlayerExited(Node2D player)
{ {
if (!_active) if (!_active)
return; return;
_label.Hide(); _label.Hide();
if (!_useSprite || !_useOutline) if (!_useOutline)
return; return;
_spriteToOutline.Material = _backupMaterial; //_spriteToOutline.Material = _backupMaterial;
for (var i = 0; i < _spriteToOutline.Length; i++)
{
_spriteToOutline[i].Material = _backupMaterial[i];
}
} }
public override void _Input(InputEvent @event) public override void _Input(InputEvent @event)
{ {
if (!_active) if (!_active)
return; return;
if (@event.IsAction("interact") && @event.IsPressed()) if (@event.IsAction("interact") && @event.IsPressed())
{ {
if (_area.HasOverlappingBodies()) if (_area.HasOverlappingBodies())
{ {
_label.Hide(); _label.Hide();
if (_useSprite && _useOutline) if (_useOutline)
_spriteToOutline.Material = _backupMaterial; {
for (var i = 0; i < _spriteToOutline.Length; i++)
{
_spriteToOutline[i].Material = _backupMaterial[i];
}
}
EmitSignal(SignalName.InteractedTool, _id); EmitSignal(SignalName.InteractedTool, _id);
EmitSignal(SignalName.Interacted); EmitSignal(SignalName.Interacted);
} }
@ -93,7 +104,7 @@ public partial class InteractionArea2D : Node2D
public void SetSpriteActiveState(bool success, int id) // TODO: remove public void SetSpriteActiveState(bool success, int id) // TODO: remove
{ {
GD.PrintErr("SetSpriteActiveState is being called."); GD.PrintErr("SetSpriteActiveState is being called.");
if(!_active) if (!_active)
return; return;
} }

@ -0,0 +1,39 @@
using System;
namespace Babushka.scripts.CSharp.Common.Fight.ActionDetails;
public class TargetSelectActionDetail : FighterAction.FighterActionDetail
{
public enum VisualRange
{
Single
}
// 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");
}
}

@ -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);
}
}

@ -1,34 +1,125 @@
using Godot; using Godot;
using System; using System;
using System.Collections.Generic;
using System.Linq;
using Babushka.scripts.CSharp.Common.Fight; using Babushka.scripts.CSharp.Common.Fight;
using Babushka.scripts.CSharp.Common.Fight.ActionDetails;
using Babushka.scripts.CSharp.Common.Util;
public partial class AllFightersVisual : Node public partial class AllFightersVisual : Node
{ {
[Export] private Node2D _allyFighters; [ExportCategory("References")] [Export]
[Export] private Node2D _enemyFighters; private Node2D _allyFighters = null!;
[Export] private PackedScene _blobFighterVisual; [Export] private Node2D _enemyFighters = null!;
[Export] private PackedScene _bigBlobFighterVisual;
[Export] private PackedScene _mavkaFighterVisual; [ExportCategory("Fighter Visual Scenes")]
[Export] private PackedScene _yourMomFighterVisual; [Export] private PackedScene _blobFighterVisual = null!;
[Export] private PackedScene _vesnaFighterVisual; [Export] private PackedScene _bigBlobFighterVisual = null!;
[Export] private PackedScene _mavkaFighterVisual = null!;
public void EnterFighter(FightWorld.Fighter fighter, bool isEnemy) [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; if (to == FightHappening.FightState.FightersEnterAnim)
{
EnterFighter();
}
if (to == FightHappening.FightState.InputActionDetail)
{
if (HappeningData.actionStaging!.CurrentDetail() is TargetSelectActionDetail targetDetail)
{
ShowTargetSelect(targetDetail);
}
}
var packedScene = fighter.type switch if (from == FightHappening.FightState.InputActionDetail)
{ {
FightWorld.Fighter.Type.Blob => _blobFighterVisual, HideTargetSelect();
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);
parent.AddChild(fighterVisual);
} }
}
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();
}
}

@ -9,7 +9,7 @@ using Godot;
namespace Babushka.scripts.CSharp.Common.Fight; 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: To get a visual overview of the FightHappening state machine, refer to the graph on miro:
@ -36,14 +36,14 @@ public class FightHappening
EnemyWin, EnemyWin,
} }
private class FightersEnterStaging public class FightersEnterStaging
{ {
public required List<FightWorld.Fighter> enteringAllyFighters; public required List<FightWorld.Fighter> enteringAllyFighters;
public required List<FightWorld.Fighter> enteringEnemyFighters; public required List<FightWorld.Fighter> enteringEnemyFighters;
public bool HasAnyToExecute() public bool HasAnyToExecute()
{ {
return enteringAllyFighters.Count != 0 || enteringEnemyFighters.Count != 0; return enteringAllyFighters.Any() || enteringEnemyFighters.Any();
} }
} }
@ -56,7 +56,7 @@ public class FightHappening
#endregion #endregion
#region ShortCuts #region Shortcuts
private static FightWorld.FightHappeningData HappeningData => private static FightWorld.FightHappeningData HappeningData =>
FightWorld.Instance.fightHappeningData ?? throw new NoFightHappeningException(); FightWorld.Instance.fightHappeningData ?? throw new NoFightHappeningException();
@ -67,18 +67,33 @@ public class FightHappening
#region Events #region Events
public event Action<FightState>? transitionFromState; [Signal]
public event Action<FightState, FightState>? transitionState; public delegate void SignalTransitionFromStateEventHandler(FightState state);
public event Action<FightState>? transitionToState;
[Signal]
public delegate void SignalTransitionStateEventHandler(FightState from, FightState to);
[Signal]
public delegate void SignalTransitionToStateEventHandler(FightState state);
#endregion #endregion
#region Staging #region Singleton
public static FightHappening Instance = null!;
private FightersEnterStaging? _fightersEnterStaging; private void SetupInstance()
private FighterAction? _actionStaging; {
Instance = this;
}
#endregion #endregion
public override void _Ready()
{
SetupInstance();
StartFight();
}
#region Public Methods #region Public Methods
@ -88,17 +103,51 @@ public class FightHappening
ChangeState(FightState.FightStartAnim); 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 #endregion
#region State Machine #region State Machine
private bool _inTransition = false;
private FightState? _changeToAfterTransition = null;
private void ChangeState(FightState nextState) private void ChangeState(FightState nextState)
{ {
_changeToAfterTransition = null;
if (_inTransition)
{
_changeToAfterTransition = nextState;
return;
}
_inTransition = true;
TransitionFromState(); TransitionFromState();
var lastState = HappeningData.fightState; var lastState = HappeningData.fightState;
HappeningData.fightState = nextState; HappeningData.fightState = nextState;
TransitionFromToState(nextState, lastState);
TransitionToState(nextState); TransitionToState(nextState);
EmitSignalSignalTransitionFromState(lastState);
EmitSignalSignalTransitionState(lastState, nextState);
EmitSignalSignalTransitionToState(nextState);
_inTransition = false;
if (_changeToAfterTransition.HasValue)
{
ChangeState(_changeToAfterTransition.Value);
}
} }
private void TransitionFromState() private void TransitionFromState()
@ -108,21 +157,10 @@ public class FightHappening
{ {
default: break; 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) private void TransitionToState(FightState nextState)
{ {
// notify everyone else
transitionToState?.Invoke(nextState);
// fixed behaviour // fixed behaviour
switch (HappeningData.fightState) switch (HappeningData.fightState)
{ {
@ -130,8 +168,8 @@ public class FightHappening
AdvanceToStateInSeconds(FightState.FightersEnter, StartAnimationTime); AdvanceToStateInSeconds(FightState.FightersEnter, StartAnimationTime);
break; break;
case FightState.FightersEnter: case FightState.FightersEnter:
_fightersEnterStaging = StageFightersEnter(); HappeningData.fightersEnterStaging = StageFightersEnter();
if (_fightersEnterStaging.HasAnyToExecute()) if (HappeningData.fightersEnterStaging.HasAnyToExecute())
{ {
ExecuteFightersEnter(); ExecuteFightersEnter();
ChangeState(FightState.FightersEnterAnim); ChangeState(FightState.FightersEnterAnim);
@ -150,10 +188,11 @@ public class FightHappening
ChangeState(FightState.StateCheck); ChangeState(FightState.StateCheck);
break; break;
case FightState.StateCheck: case FightState.StateCheck:
// restest action staging // restest action staging and fighter enter staging
_actionStaging = null; HappeningData.actionStaging = null;
HappeningData.fightersEnterStaging = null;
if ( /*TODO: are all allys dead*/ false) if (!FightWorld.Instance.allyFighters.IsAlive())
{ {
ChangeState(FightState.EnemyWin); ChangeState(FightState.EnemyWin);
} }
@ -161,7 +200,7 @@ public class FightHappening
{ {
ChangeState(FightState.PlayerWin); ChangeState(FightState.PlayerWin);
} }
else if (CurrentFighter.actionsLeft <= 0) else if (CurrentFighter.actionPointsLeft <= 0)
{ {
ChangeState(FightState.FightersEnter); ChangeState(FightState.FightersEnter);
} }
@ -179,9 +218,11 @@ public class FightHappening
// wait for player input // wait for player input
break; break;
case FightState.ActionCheckDetails: case FightState.ActionCheckDetails:
RequireNotNull(HappeningData.actionStaging);
if (ActionAbort()) if (ActionAbort())
ChangeState(FightState.InputActionSelect); ChangeState(FightState.InputActionSelect);
else if (ActionNeededDetail() != null) else if (ActionNeededDetail())
ChangeState(FightState.InputActionDetail); ChangeState(FightState.InputActionDetail);
else else
ChangeState(FightState.ActionExecute); ChangeState(FightState.ActionExecute);
@ -190,7 +231,7 @@ public class FightHappening
// wait for player input // wait for player input
break; break;
case FightState.EnemyActionSelect: case FightState.EnemyActionSelect:
_actionStaging = CurrentFighter.AutoSelectAction(); HappeningData.actionStaging = CurrentFighter.AutoSelectAction();
ChangeState(FightState.ActionExecute); ChangeState(FightState.ActionExecute);
break; break;
case FightState.ActionExecute: case FightState.ActionExecute:
@ -212,7 +253,6 @@ public class FightHappening
default: break; default: break;
} }
} }
#endregion #endregion
#region Game Logic #region Game Logic
@ -221,38 +261,33 @@ public class FightHappening
{ {
// ally // ally
var enteringAllyFighters = new List<FightWorld.Fighter>(); var enteringAllyFighters = new List<FightWorld.Fighter>();
//TODO var allyFighters = FightWorld.Instance.allyFighters;
if (!allyFighters.vesnaFighter.entered)
{
enteringAllyFighters.Add(allyFighters.vesnaFighter);
}
// enemy // enemy
const int totalEnemySpace = 3; const int totalEnemySpace = 3;
var enemySpaceLeft = totalEnemySpace - HappeningData.enemyGroup.GetEnteredAmount(); 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 return new FightersEnterStaging
{ {
enteringAllyFighters = enteringAllyFighters, enteringAllyFighters = enteringAllyFighters,
enteringEnemyFighters = enterEnemyFighters enteringEnemyFighters = HappeningData.enemyGroup.GetUptoUnenteredFighters(enemySpaceLeft).ToList()
}; };
} }
private void ExecuteFightersEnter() private void ExecuteFightersEnter()
{ {
Debug.Assert(_fightersEnterStaging != null); Debug.Assert(HappeningData.fightersEnterStaging != null);
foreach (var fighter in _fightersEnterStaging.enteringAllyFighters) foreach (var fighter in HappeningData.fightersEnterStaging.enteringAllyFighters)
{ {
fighter.entered = true; fighter.entered = true;
HappeningData.fighterStack.AddAsLast(fighter); HappeningData.fighterStack.AddAsLast(fighter);
} }
foreach (var fighter in _fightersEnterStaging.enteringEnemyFighters) foreach (var fighter in HappeningData.fightersEnterStaging.enteringEnemyFighters)
{ {
fighter.entered = true; fighter.entered = true;
HappeningData.fighterStack.AddAsLast(fighter); HappeningData.fighterStack.AddAsLast(fighter);
@ -262,30 +297,32 @@ public class FightHappening
private void ExecuteNextFighter() private void ExecuteNextFighter()
{ {
HappeningData.fighterStack.Next(); HappeningData.fighterStack.Next();
CurrentFighter.actionPointsLeft = CurrentFighter.maxActionPoints;
} }
private void ExecuteAction() private void ExecuteAction()
{ {
Debug.Assert(_actionStaging != null); Debug.Assert(HappeningData.actionStaging != null);
_actionStaging.ExecuteAction(); HappeningData.actionStaging.ExecuteAction();
CurrentFighter.actionPointsLeft -= HappeningData.actionStaging.GetActionPointCost();
} }
private Variant<float, Func<bool>> GetActionAnimationEnd() private Variant<float, Func<bool>> GetActionAnimationEnd()
{ {
Debug.Assert(_actionStaging != null); Debug.Assert(HappeningData.actionStaging != null);
return _actionStaging.GetAnimationEnd(); return HappeningData.actionStaging.GetAnimationEnd();
} }
private bool ActionAbort() private bool ActionAbort()
{ {
Debug.Assert(_actionStaging != null); Debug.Assert(HappeningData.actionStaging != null);
return _actionStaging.MarkedForAbort(); return HappeningData.actionStaging.MarkedForAbort();
} }
private FighterAction.FighterActionDetail? ActionNeededDetail() private bool ActionNeededDetail()
{ {
Debug.Assert(_actionStaging != null); Debug.Assert(HappeningData.actionStaging != null);
return _actionStaging.NeededDetail(); return HappeningData.actionStaging.NextDetail();
} }
#endregion // Game Logic #endregion // Game Logic
@ -300,6 +337,14 @@ public class FightHappening
throw new Exception( throw new Exception(
$"Can not call this Method while in state {HappeningData.fightState}. Only available in {string.Join(" ,", states)}"); $"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) private void AdvanceToStateInSeconds(FightState nextState, float seconds)
{ {
@ -317,4 +362,6 @@ public class FightHappening
} }
#endregion #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,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();
}
}
}

@ -1,21 +1,29 @@
using System.Collections.Generic;
using Babushka.scripts.CSharp.Common.Util;
using Godot; using Godot;
namespace Babushka.scripts.CSharp.Common.Fight; namespace Babushka.scripts.CSharp.Common.Fight;
public partial class FightRoomSceneSetup : Node 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() public override void _Ready()
{ {
var room = FightWorld.Instance.currentRoom!; 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"; var enemyGroup = room.enemyGroups[i];
foreach (var enemy in enemyGroup.enemies) var roamingEnemyGroup = _roamingEnemyGroupPrefab.Instantiate<RoamingEnemyGroup>();
{ roamingEnemyGroup.Initialize(enemyGroup, _fightSceneSwitcher);
debugLabel.Text += $" {enemy.type}\n"; availableParent.AddChild(roamingEnemyGroup);
} if (i >= room.enemyGroups.Count - 1) break;
i++;
} }
} }
} }

@ -25,7 +25,7 @@ public partial class FightSceneSwitcher : Node
private async void UnloadAfterDelay() private async void UnloadAfterDelay()
{ {
await ToSignal(GetTree().CreateTimer(1.0f), "timeout"); // 1.0f seconds await ToSignal(GetTree().CreateTimer(1.0f), "timeout"); // 1.0f seconds
sceneRoot.QueueFree(); //sceneRoot.QueueFree();
} }
public void SwitchRoom(int pathIndex) public void SwitchRoom(int pathIndex)
@ -38,4 +38,16 @@ public partial class FightSceneSwitcher : Node
FightWorld.Instance.currentRoom = nextRoom; FightWorld.Instance.currentRoom = nextRoom;
LoadNext(); 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();
}
} }

@ -5,41 +5,46 @@ namespace Babushka.scripts.CSharp.Common.Fight;
public static class FightUtils 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); 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())) if (maxFighters <= self.enemies.Count)
{ return self.enemies
fighter = f; .Where(e => !e.entered && e.IsAlive());
return true;
} return self.enemies
.Where(e => !e.entered && e.IsAlive())
fighter = null!; .Take(maxFighters);
return false;
} }
public static bool IsAlive(this FightWorld.Fighter self) public static bool IsAlive(this FightWorld.Fighter self)
{ {
return self.GetHealth() >= 0; return self.GetHealth() >= 0;
} }
public static bool IsDead(this FightWorld.Fighter self) public static bool IsDead(this FightWorld.Fighter self)
{ {
return !self.IsAlive(); return !self.IsAlive();
} }
public static int GetHealth(this FightWorld.Fighter self) public static int GetHealth(this FightWorld.Fighter self)
{ {
return self.health ?? self.maxHealth; 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()); return self.enemies.All(e => e.IsDead());
} }
} }

@ -14,10 +14,10 @@ public partial class FightWorld : Node
public class Room public class Room
{ {
public required Dictionary<int, Room> paths; 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; public required List<Fighter> enemies;
} }
@ -26,7 +26,9 @@ public partial class FightWorld : Node
{ {
public FightHappening.FightState fightState = FightHappening.FightState.None; public FightHappening.FightState fightState = FightHappening.FightState.None;
public FighterStack fighterStack = new(); public FighterStack fighterStack = new();
public required EnemyGroup enemyGroup; public required FighterGroup enemyGroup;
public FightHappening.FightersEnterStaging? fightersEnterStaging;
public FighterAction? actionStaging;
} }
public class Fighter public class Fighter
@ -37,16 +39,18 @@ public partial class FightWorld : Node
BigBlob, BigBlob,
Mavka, Mavka,
YourMom, YourMom,
Vesna Vesna,
Chuha
} }
public required Type type; public required Type type;
public required int maxHealth; public required int maxHealth;
public required bool isEnemy; public required bool isEnemy;
public required List<FighterAction> availableActions; public required List<FighterAction> availableActions;
public int maxActionPoints = 1;
public int? health = null; // null => initialize to full health on spawn public int? health = null; // null => initialize to full health on spawn
public bool entered = false; public bool entered = false;
public int actionsLeft; public int actionPointsLeft;
public FighterAction AutoSelectAction() public FighterAction AutoSelectAction()
{ {
@ -69,6 +73,7 @@ public partial class FightWorld : Node
public World? world = null; public World? world = null;
public Room? currentRoom = null; public Room? currentRoom = null;
public FightHappeningData? fightHappeningData = null; public FightHappeningData? fightHappeningData = null;
public AllyFighters allyFighters = new();
public void MyEnterTree() public void MyEnterTree()
{ {
@ -123,9 +128,9 @@ public partial class FightWorld : Node
return room; 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); var enemyGroupCount = GD.RandRange(1, 3);
@ -137,9 +142,9 @@ public partial class FightWorld : Node
return enemyGroups; return enemyGroups;
} }
private EnemyGroup GenerateSingleEnemyGroup() private FighterGroup GenerateSingleEnemyGroup()
{ {
var enemyGroup = new EnemyGroup var enemyGroup = new FighterGroup
{ {
enemies = [] enemies = []
}; };
@ -158,13 +163,14 @@ public partial class FightWorld : Node
{ {
var typeRoll = GD.RandRange(0, 99); var typeRoll = GD.RandRange(0, 99);
var type = typeRoll switch //var type = typeRoll switch
{ //{
< 50 => Fighter.Type.Blob, // < 50 => Fighter.Type.Blob,
< 75 => Fighter.Type.BigBlob, // < 75 => Fighter.Type.BigBlob,
< 90 => Fighter.Type.Mavka, // < 90 => Fighter.Type.Mavka,
_ => Fighter.Type.YourMom // _ => Fighter.Type.YourMom
}; //};
var type = Fighter.Type.Blob;
var enemy = new Fighter var enemy = new Fighter
{ {
@ -172,7 +178,8 @@ public partial class FightWorld : Node
health = null, health = null,
isEnemy = true, isEnemy = true,
maxHealth = 12, maxHealth = 12,
availableActions = [ availableActions =
[
new FighterAction.Skip() new FighterAction.Skip()
] ]
}; };

@ -7,13 +7,24 @@ namespace Babushka.scripts.CSharp.Common.Fight;
public abstract class FighterAction 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 public class TargetSelection
{ {
// ReSharper disable once MemberHidesStaticFromOuterClass // ReSharper disable once MemberHidesStaticFromOuterClass
public static readonly TargetSelection Skip = new() { skipTargetSelection = () => true }; public static readonly TargetSelection Skip = new() { skipTargetSelection = () => true };
public Func<bool> skipTargetSelection = () => false; public Func<bool> skipTargetSelection = () => false;
} }
public abstract class FighterActionDetail public abstract class FighterActionDetail
{ {
public abstract bool DetailComplete(); public abstract bool DetailComplete();
@ -63,7 +74,46 @@ public abstract class FighterAction
return _abort; 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 public class Skip : FighterAction
{ {
@ -72,9 +122,10 @@ public abstract class FighterAction
return 0f; return 0f;
} }
public override FighterActionDetail? NeededDetail() public override bool NextDetail()
{ {
return null; return false;
} }
} }
}
}

@ -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; namespace Babushka.scripts.CSharp.Common.Fight;
[Tool]
public partial class FighterVisual : Node2D public partial class FighterVisual : Node2D
{ {
//[Export] public string name; #region Shortcuts
//[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;
[Export] private Node2D _targetButtons;
[Export] private Node2D _targetMarker;
[Export] private Label _healthText;
[Export] private Node2D _visualSprite;
[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();
}
public void Attack()
{
//FightHappening.SelectAttack(this);
}
public void HideAttackButton()
{
_attackButtons.Hide();
}
public void ShowAttackButton() private FightWorld.FightHappeningData HappeningData =>
{ FightWorld.Instance.fightHappeningData ?? throw new NoFightHappeningException();
_attackButtons.Show();
}
public void HideTargetButtons() #endregion
{
_targetButtons.Hide(); [ExportCategory("References")]
} [Export] private Node2D _visualParent;
[Export] private Node2D _targetSelectionParent;
public void ShowTargetButtons() [Signal]
{ public delegate void DamageTakenEventHandler();
_targetButtons.Show();
}
public void TargetMouseEvent(Node viewport, InputEvent inputEvent, int shapeIdx) [Signal]
{ public delegate void AttackingEventHandler();
if (inputEvent.IsPressed())
ClickedTarget();
}
public void AttackMouseEvent(Node viewport, InputEvent inputEvent, int shapeIdx) [Signal]
{ public delegate void DyingEventHandler();
if (inputEvent.IsPressed())
ClickedAttack();
}
public void HealMouseEvent(Node viewport, InputEvent inputEvent, int shapeIdx)
{
if (inputEvent.IsPressed())
ClickedHeal();
}
private void ClickedAttack() [Signal]
{ public delegate void HealedEventHandler();
//FightHappening.SelectAttack(this);
}
private void ClickedHeal()
{
//FightHappening.SelectHeal(this);
}
private void ClickedTarget() private FightWorld.Fighter _boundFighter;
{
//FightHappening.SelectTargetAndAttack(this);
}
public void StartHoverTarget() public void Initialize(FightWorld.Fighter fighter)
{ {
_targetMarker.Visible = true; _boundFighter = fighter;
UpdateMirrorState();
} }
public void EndHoverTarget() /// <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()
{ {
_targetMarker.Visible = false; _visualParent.Scale = new Vector2(_boundFighter.isEnemy ? -1 : 1, 1);
} }
public void UpdateHealthVisual() public void SetTargetSelectionActive(bool value)
{ {
_healthText.Text = $"{_boundFighter.health}"; _targetSelectionParent.Visible = value;
_targetSelectionParent.ProcessMode = value ? ProcessModeEnum.Inherit : ProcessModeEnum.Disabled;
} }
public bool IsDead() // listen from inside
public void ClickedTarget()
{ {
//return Health <= 0; if (HappeningData.actionStaging!.CurrentDetail() is not TargetSelectActionDetail targetDetail)
return true; throw new InvalidOperationException("No target selection needed right now");
}
public void ResetActions() targetDetail.SetTarget(_boundFighter);
{ FightHappening.Instance.DetailFilled();
//_actions = maxActions;
} }
// Animations
public void AttackAnimation(FightAttack attack) public void AttackAnimation(FightAttack attack)
{ {
EmitSignalAttacking(); EmitSignalAttacking();
@ -134,7 +75,6 @@ public partial class FighterVisual : Node2D
tween.TweenCallback(Callable.From(() => attack.target?.HitAnimation(attack))); tween.TweenCallback(Callable.From(() => attack.target?.HitAnimation(attack)));
tween.TweenProperty(this, "position", new Vector2(0, 0), 0.7) tween.TweenProperty(this, "position", new Vector2(0, 0), 0.7)
.SetTrans(Tween.TransitionType.Cubic).SetEase(Tween.EaseType.Out); .SetTrans(Tween.TransitionType.Cubic).SetEase(Tween.EaseType.Out);
} }
private void HitAnimation(FightAttack attack) private void HitAnimation(FightAttack attack)
@ -154,4 +94,4 @@ public partial class FighterVisual : Node2D
tween.TweenProperty(this, "scale", new Vector2(1, 1), 0.4) tween.TweenProperty(this, "scale", new Vector2(1, 1), 0.4)
.SetTrans(Tween.TransitionType.Cubic).SetEase(Tween.EaseType.Out); .SetTrans(Tween.TransitionType.Cubic).SetEase(Tween.EaseType.Out);
} }
} }

@ -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,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,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();
}
}
}

@ -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) public static T? Random<T>(this IEnumerable<T> self)
{ {
var selfList = self.ToList(); var selfList = self.ToList();
@ -24,4 +34,16 @@ public static class LinqExtras
var randomIndex = new Random().Next(0, selfList.Count); var randomIndex = new Random().Next(0, selfList.Count);
return selfList[randomIndex]; 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;
}
} }

Loading…
Cancel
Save