Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f0db6372e5 | |||
| 52f1560c48 | |||
| 8055381478 | |||
| daabcdc5ee | |||
| 2929c5dd25 | |||
| 9bebe1a44d |
@@ -1,4 +1,5 @@
|
|||||||
<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/CodeStyle/Naming/CSharpNaming/UserRules/=53eecf85_002Dd821_002D40e8_002Dac97_002Dfdb734542b84/@EntryIndexedValue"><Policy><Descriptor Staticness="Instance" AccessRightKinds="Protected, ProtectedInternal, Internal, Public, PrivateProtected" Description="Instance fields (not private)"><ElementKinds><Kind Name="FIELD" /><Kind Name="READONLY_FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="aaBb" /></Policy></s:String>
|
||||||
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=0B2502BD29F5EC4798EEFD2950AA7E06/Description/@EntryValue">Godot Signal</s:String>
|
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=0B2502BD29F5EC4798EEFD2950AA7E06/Description/@EntryValue">Godot Signal</s:String>
|
||||||
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=0B2502BD29F5EC4798EEFD2950AA7E06/Text/@EntryValue">[Signal]
|
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=0B2502BD29F5EC4798EEFD2950AA7E06/Text/@EntryValue">[Signal]
|
||||||
public delegate void $SignalName$EventHandler($END$);</s:String>
|
public delegate void $SignalName$EventHandler($END$);</s:String>
|
||||||
|
|||||||
@@ -1,12 +1,29 @@
|
|||||||
<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_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_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003F4298b0f293f987511fc1b7956ee691fd778f8378_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_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003F4298b0f293f987511fc1b7956ee691fd778f8378_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_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_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_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_003AThrowHelper_002Ecs_002Fl_003AC_0021_003FUsers_003FJonathan_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003Fc7102cd0ffb8973777e61b1942c3fffac7e14016a511d055c3adf73ff91748_003FThrowHelper_002Ecs/@EntryIndexedValue">ForceIncluded</s:String></wpf:ResourceDictionary>
|
<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"><SessionState ContinuousTestingMode="0" IsActive="True" Name="Tests" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session">
|
||||||
|
<TestAncestor>
|
||||||
|
<TestId>NUnit3x::A6EF2269-9E64-40D4-BA0A-33CB234E2503::net9.0::BabushkaTest.Tests</TestId>
|
||||||
|
</TestAncestor>
|
||||||
|
</SessionState></s:String></wpf:ResourceDictionary>
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
[gd_scene load_steps=2 format=3 uid="uid://bcld43daavmrn"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" uid="uid://cql8mt5jsmcdl" path="res://scripts/CSharp/Common/Fight/FightSceneSwitcher.cs" id="1_5dt1r"]
|
||||||
|
|
||||||
|
[node name="FightSceneSwitcher" type="Node" node_paths=PackedStringArray("sceneRoot")]
|
||||||
|
script = ExtResource("1_5dt1r")
|
||||||
|
sceneRoot = NodePath("")
|
||||||
|
fightRoomScenePath = "res://scenes/Babushka_scene_fight_world_room.tscn"
|
||||||
|
fightHappeningScene = "res://scenes/Babushka_scene_fight_happening.tscn"
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
[gd_scene load_steps=2 format=3 uid="uid://n5cj71bxxjkk"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" uid="uid://dqe1i2qmpttwf" path="res://scripts/CSharp/Common/Fight/FightWorld.cs" id="1_tnyce"]
|
||||||
|
|
||||||
|
[node name="FightWorldAutoload" type="Node2D"]
|
||||||
|
script = ExtResource("1_tnyce")
|
||||||
@@ -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="Sprite2D" parent="TargetSelection/HoverIndicator" index="0"]
|
||||||
|
position = Vector2(1, -126)
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
[gd_scene load_steps=9 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"]
|
||||||
|
[ext_resource type="Script" uid="uid://b2dx06p6i7pu0" path="res://scripts/CSharp/Common/Fight/UI/FighterHealthBarVisual.cs" id="5_xv37w"]
|
||||||
|
|
||||||
|
[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", "healthBarVisual")]
|
||||||
|
script = ExtResource("1_hai27")
|
||||||
|
_visualParent = NodePath("Visuals")
|
||||||
|
_targetSelectionParent = NodePath("TargetSelection")
|
||||||
|
healthBarVisual = NodePath("HealthBar")
|
||||||
|
|
||||||
|
[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")
|
||||||
|
|
||||||
|
[node name="HealthBar" type="Node2D" parent="." node_paths=PackedStringArray("_tmpHealthLabel")]
|
||||||
|
script = ExtResource("5_xv37w")
|
||||||
|
_tmpHealthLabel = NodePath("tmpLabel")
|
||||||
|
|
||||||
|
[node name="tmpLabel" type="Label" parent="HealthBar"]
|
||||||
|
offset_left = -110.0
|
||||||
|
offset_top = -528.0
|
||||||
|
offset_right = 111.0
|
||||||
|
offset_bottom = -431.0
|
||||||
|
theme_override_font_sizes/font_size = 71
|
||||||
|
text = "xx / xx"
|
||||||
|
|
||||||
|
[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"]
|
||||||
@@ -1,123 +0,0 @@
|
|||||||
[gd_scene load_steps=11 format=3 uid="uid://cpanatqdjjpa3"]
|
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://by88f32fou7lh" path="res://scripts/CSharp/Common/Fight/Fighter.cs" id="1_f3j2x"]
|
|
||||||
[ext_resource type="Texture2D" uid="uid://om2axn1vfa5o" path="res://art/animation/Vesna2D/Vesna Anims Sequences/S01-Idle/0001.png" id="2_2ud32"]
|
|
||||||
[ext_resource type="Texture2D" uid="uid://qlfwuakhe57t" path="res://art/ui/UI/attack_select_wheel.png" id="3_80knd"]
|
|
||||||
[ext_resource type="AudioStream" uid="uid://ch4c1wh4ghxyo" path="res://audio/sfx/Battle/Vesna/SFX_Battle_Vesna_Defense_08.wav" id="5_4r2vf"]
|
|
||||||
[ext_resource type="Texture2D" uid="uid://6h85o7fj7gmu" path="res://art/animation/Vesna3D/vesna-more-tools.png" id="5_l04qi"]
|
|
||||||
[ext_resource type="Texture2D" uid="uid://crak7ton4lab0" path="res://art/ui/UI/EmptyFightButton.png" id="5_rjjub"]
|
|
||||||
[ext_resource type="Texture2D" uid="uid://c3wht0nakaki1" path="res://art/ui/UI/icons/icon-fruit-tomatoe.png" id="6_l04qi"]
|
|
||||||
[ext_resource type="AudioStream" uid="uid://ccionrfr6e3lb" path="res://audio/sfx/Battle/Vesna/SFX_Battle_Vesna_Attack_04.wav" id="6_u1ayv"]
|
|
||||||
|
|
||||||
[sub_resource type="CircleShape2D" id="CircleShape2D_0tqnl"]
|
|
||||||
radius = 291.58
|
|
||||||
|
|
||||||
[sub_resource type="CircleShape2D" id="CircleShape2D_4r2vf"]
|
|
||||||
radius = 173.44
|
|
||||||
|
|
||||||
[node name="VesnaFighter" type="Node2D" node_paths=PackedStringArray("_attackButtons", "_targetButtons", "_targetMarker", "_healthText", "_visualSprite")]
|
|
||||||
script = ExtResource("1_f3j2x")
|
|
||||||
name = "Vesna"
|
|
||||||
maxHealth = 100
|
|
||||||
attackStrength = 10
|
|
||||||
_attackButtons = NodePath("FightButtons")
|
|
||||||
_targetButtons = NodePath("TargetButtons")
|
|
||||||
_targetMarker = NodePath("TargetButtons/TargetMarker")
|
|
||||||
_healthText = NodePath("HealthShow")
|
|
||||||
_visualSprite = NodePath("Sprite2D")
|
|
||||||
|
|
||||||
[node name="Sprite2D" type="Sprite2D" parent="."]
|
|
||||||
texture = ExtResource("2_2ud32")
|
|
||||||
offset = Vector2(43, -379)
|
|
||||||
|
|
||||||
[node name="TargetButtons" type="Node2D" parent="."]
|
|
||||||
visible = false
|
|
||||||
|
|
||||||
[node name="TargetMarker" type="Sprite2D" parent="TargetButtons"]
|
|
||||||
visible = false
|
|
||||||
z_index = 200
|
|
||||||
position = Vector2(8, -122)
|
|
||||||
scale = Vector2(4.245, 4.245)
|
|
||||||
texture = ExtResource("3_80knd")
|
|
||||||
|
|
||||||
[node name="Area2D" type="Area2D" parent="TargetButtons"]
|
|
||||||
position = Vector2(3, -76)
|
|
||||||
|
|
||||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="TargetButtons/Area2D"]
|
|
||||||
shape = SubResource("CircleShape2D_0tqnl")
|
|
||||||
|
|
||||||
[node name="FightButtons" type="Node2D" parent="."]
|
|
||||||
position = Vector2(3, -714)
|
|
||||||
|
|
||||||
[node name="CircleBackground" type="Sprite2D" parent="FightButtons"]
|
|
||||||
z_index = 200
|
|
||||||
scale = Vector2(4.245, 4.245)
|
|
||||||
texture = ExtResource("3_80knd")
|
|
||||||
|
|
||||||
[node name="AttackButton" type="Node2D" parent="FightButtons"]
|
|
||||||
position = Vector2(0, -536)
|
|
||||||
|
|
||||||
[node name="ButtonBackground" type="Sprite2D" parent="FightButtons/AttackButton"]
|
|
||||||
z_index = 200
|
|
||||||
scale = Vector2(2.48, 2.48)
|
|
||||||
texture = ExtResource("5_rjjub")
|
|
||||||
|
|
||||||
[node name="Sprite2D" type="Sprite2D" parent="FightButtons/AttackButton/ButtonBackground"]
|
|
||||||
position = Vector2(6.04839, -10.0806)
|
|
||||||
rotation = -1.0088
|
|
||||||
scale = Vector2(0.249373, 0.25079)
|
|
||||||
texture = ExtResource("5_l04qi")
|
|
||||||
region_enabled = true
|
|
||||||
region_rect = Rect2(291.897, 15.8974, 272.82, 479.385)
|
|
||||||
|
|
||||||
[node name="Area2D" type="Area2D" parent="FightButtons/AttackButton"]
|
|
||||||
collision_layer = 16
|
|
||||||
|
|
||||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="FightButtons/AttackButton/Area2D"]
|
|
||||||
shape = SubResource("CircleShape2D_4r2vf")
|
|
||||||
|
|
||||||
[node name="HealButton" type="Node2D" parent="FightButtons"]
|
|
||||||
position = Vector2(427, -334)
|
|
||||||
|
|
||||||
[node name="ButtonBackground" type="Sprite2D" parent="FightButtons/HealButton"]
|
|
||||||
z_index = 200
|
|
||||||
scale = Vector2(2.48, 2.48)
|
|
||||||
texture = ExtResource("5_rjjub")
|
|
||||||
|
|
||||||
[node name="Sprite2D" type="Sprite2D" parent="FightButtons/HealButton/ButtonBackground"]
|
|
||||||
position = Vector2(4.83871, 0)
|
|
||||||
scale = Vector2(0.279343, 0.279343)
|
|
||||||
texture = ExtResource("6_l04qi")
|
|
||||||
|
|
||||||
[node name="Area2D" type="Area2D" parent="FightButtons/HealButton"]
|
|
||||||
collision_layer = 16
|
|
||||||
|
|
||||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="FightButtons/HealButton/Area2D"]
|
|
||||||
shape = SubResource("CircleShape2D_4r2vf")
|
|
||||||
|
|
||||||
[node name="HealthShow" type="Label" parent="."]
|
|
||||||
z_index = 200
|
|
||||||
anchors_preset = 15
|
|
||||||
anchor_right = 1.0
|
|
||||||
anchor_bottom = 1.0
|
|
||||||
offset_left = -197.0
|
|
||||||
offset_top = -947.0
|
|
||||||
offset_right = 207.0
|
|
||||||
offset_bottom = -801.0
|
|
||||||
grow_horizontal = 2
|
|
||||||
grow_vertical = 2
|
|
||||||
theme_override_font_sizes/font_size = 106
|
|
||||||
text = "100/100"
|
|
||||||
horizontal_alignment = 1
|
|
||||||
vertical_alignment = 1
|
|
||||||
|
|
||||||
[node name="HitAudio" type="AudioStreamPlayer" parent="."]
|
|
||||||
stream = ExtResource("5_4r2vf")
|
|
||||||
|
|
||||||
[node name="AttackAudio" type="AudioStreamPlayer" parent="."]
|
|
||||||
stream = ExtResource("6_u1ayv")
|
|
||||||
|
|
||||||
[connection signal="Attacking" from="." to="AttackAudio" method="play" binds= [0.0]]
|
|
||||||
[connection signal="DamageTaken" from="." to="HitAudio" method="play" binds= [0.0]]
|
|
||||||
[connection signal="input_event" from="FightButtons/AttackButton/Area2D" to="." method="AttackMouseEvent"]
|
|
||||||
[connection signal="input_event" from="FightButtons/HealButton/Area2D" to="." method="HealMouseEvent"]
|
|
||||||
@@ -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://hk8ahyp6dgl6"]
|
[gd_scene load_steps=3 format=3 uid="uid://hk8ahyp6dgl6"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://c76mhhqyk4lgh" path="res://scripts/CSharp/Common/Fight/FightInstance.cs" id="1_ygesl"]
|
[ext_resource type="Script" uid="uid://c76mhhqyk4lgh" path="res://scripts/CSharp/Common/FightOld/FightInstance.cs" id="1_ygesl"]
|
||||||
[ext_resource type="Script" uid="uid://oe1uypehqvr7" path="res://scripts/CSharp/Common/Fight/FightStateManager.cs" id="2_b0ivm"]
|
[ext_resource type="Script" uid="uid://oe1uypehqvr7" path="res://scripts/CSharp/Common/FightOld/FightStateManager.cs" id="2_b0ivm"]
|
||||||
|
|
||||||
[node name="FightBaseScene" type="Node2D" node_paths=PackedStringArray("_friendlyFightSpots", "_enemyFightSpots", "camPositionNode", "_fightStateManager", "_fightEndText")]
|
[node name="FightBaseScene" type="Node2D" node_paths=PackedStringArray("_friendlyFightSpots", "_enemyFightSpots", "camPositionNode", "_fightStateManager", "_fightEndText")]
|
||||||
script = ExtResource("1_ygesl")
|
script = ExtResource("1_ygesl")
|
||||||
+2
-2
@@ -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/Fight/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")
|
||||||
+2
-4
@@ -1,7 +1,7 @@
|
|||||||
[gd_scene load_steps=10 format=3 uid="uid://bp64p6y72j71w"]
|
[gd_scene load_steps=10 format=3 uid="uid://bp64p6y72j71w"]
|
||||||
|
|
||||||
[ext_resource type="Texture2D" uid="uid://ccrnmx6bd842k" path="res://art/characters/farm fäulnis blobs.png" id="1_vem8k"]
|
[ext_resource type="Texture2D" uid="uid://ccrnmx6bd842k" path="res://art/characters/farm fäulnis blobs.png" id="1_vem8k"]
|
||||||
[ext_resource type="Script" uid="uid://by88f32fou7lh" path="res://scripts/CSharp/Common/Fight/Fighter.cs" id="2_4w1ab"]
|
[ext_resource type="Script" path="res://scripts/CSharp/Common/FightOld/Fighter.cs" id="2_4w1ab"]
|
||||||
[ext_resource type="Texture2D" uid="uid://qlfwuakhe57t" path="res://art/ui/UI/attack_select_wheel.png" id="3_v4f83"]
|
[ext_resource type="Texture2D" uid="uid://qlfwuakhe57t" path="res://art/ui/UI/attack_select_wheel.png" id="3_v4f83"]
|
||||||
[ext_resource type="AudioStream" uid="uid://x7cc5woop5ec" path="res://audio/sfx/Battle/Enemies/SFX_Slime_Hit_V2_03.wav" id="5_v4f83"]
|
[ext_resource type="AudioStream" uid="uid://x7cc5woop5ec" path="res://audio/sfx/Battle/Enemies/SFX_Slime_Hit_V2_03.wav" id="5_v4f83"]
|
||||||
[ext_resource type="Texture2D" uid="uid://bn56p0ytuo060" path="res://art/ui/UI/AttackButton.png" id="5_vbkts"]
|
[ext_resource type="Texture2D" uid="uid://bn56p0ytuo060" path="res://art/ui/UI/AttackButton.png" id="5_vbkts"]
|
||||||
@@ -19,6 +19,7 @@ script = ExtResource("2_4w1ab")
|
|||||||
name = "Blob"
|
name = "Blob"
|
||||||
maxHealth = 20
|
maxHealth = 20
|
||||||
attackStrength = 10
|
attackStrength = 10
|
||||||
|
maxActions = null
|
||||||
_attackButtons = NodePath("FightButtons")
|
_attackButtons = NodePath("FightButtons")
|
||||||
_targetButtons = NodePath("TargetButtons")
|
_targetButtons = NodePath("TargetButtons")
|
||||||
_targetMarker = NodePath("TargetButtons/TargetMarker")
|
_targetMarker = NodePath("TargetButtons/TargetMarker")
|
||||||
@@ -95,9 +96,6 @@ stream = ExtResource("6_vbkts")
|
|||||||
[node name="AttackAudio" type="AudioStreamPlayer" parent="."]
|
[node name="AttackAudio" type="AudioStreamPlayer" parent="."]
|
||||||
stream = ExtResource("6_oykh8")
|
stream = ExtResource("6_oykh8")
|
||||||
|
|
||||||
[connection signal="Attacking" from="." to="AttackAudio" method="play" binds= [0.0]]
|
|
||||||
[connection signal="DamageTaken" from="." to="HitAudio" method="play" binds= [0.0]]
|
|
||||||
[connection signal="Dying" from="." to="DieAudio" method="play" binds= [0.0]]
|
|
||||||
[connection signal="input_event" from="TargetButtons/Area2D" to="." method="TargetMouseEvent"]
|
[connection signal="input_event" from="TargetButtons/Area2D" to="." method="TargetMouseEvent"]
|
||||||
[connection signal="mouse_entered" from="TargetButtons/Area2D" to="." method="StartHoverTarget"]
|
[connection signal="mouse_entered" from="TargetButtons/Area2D" to="." method="StartHoverTarget"]
|
||||||
[connection signal="mouse_exited" from="TargetButtons/Area2D" to="." method="EndHoverTarget"]
|
[connection signal="mouse_exited" from="TargetButtons/Area2D" to="." method="EndHoverTarget"]
|
||||||
+2
-10
@@ -1,6 +1,6 @@
|
|||||||
[gd_scene load_steps=10 format=3 uid="uid://cr66tpdr5rma5"]
|
[gd_scene load_steps=10 format=3 uid="uid://cr66tpdr5rma5"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://by88f32fou7lh" path="res://scripts/CSharp/Common/Fight/Fighter.cs" id="1_t6th8"]
|
[ext_resource type="Script" uid="uid://by88f32fou7lh" path="res://scripts/CSharp/Common/Fight/FighterVisual.cs" id="1_t6th8"]
|
||||||
[ext_resource type="Texture2D" uid="uid://bexymddkb6l0o" path="res://art/characters/Mavka/mavkha.png" id="2_shg7p"]
|
[ext_resource type="Texture2D" uid="uid://bexymddkb6l0o" path="res://art/characters/Mavka/mavkha.png" id="2_shg7p"]
|
||||||
[ext_resource type="Texture2D" uid="uid://qlfwuakhe57t" path="res://art/ui/UI/attack_select_wheel.png" id="3_nkuei"]
|
[ext_resource type="Texture2D" uid="uid://qlfwuakhe57t" path="res://art/ui/UI/attack_select_wheel.png" id="3_nkuei"]
|
||||||
[ext_resource type="Texture2D" uid="uid://bn56p0ytuo060" path="res://art/ui/UI/AttackButton.png" id="4_u3hw3"]
|
[ext_resource type="Texture2D" uid="uid://bn56p0ytuo060" path="res://art/ui/UI/AttackButton.png" id="4_u3hw3"]
|
||||||
@@ -14,16 +14,8 @@ radius = 388.063
|
|||||||
[sub_resource type="CircleShape2D" id="CircleShape2D_s74nc"]
|
[sub_resource type="CircleShape2D" id="CircleShape2D_s74nc"]
|
||||||
radius = 173.44
|
radius = 173.44
|
||||||
|
|
||||||
[node name="EnemyMavkhaFighter" type="Node2D" node_paths=PackedStringArray("_attackButtons", "_targetButtons", "_targetMarker", "_healthText", "_visualSprite")]
|
[node name="EnemyMavkhaFighter" type="Node2D"]
|
||||||
script = ExtResource("1_t6th8")
|
script = ExtResource("1_t6th8")
|
||||||
name = "Mavkha"
|
|
||||||
maxHealth = 40
|
|
||||||
attackStrength = 10
|
|
||||||
_attackButtons = NodePath("FightButtons")
|
|
||||||
_targetButtons = NodePath("TargetButtons")
|
|
||||||
_targetMarker = NodePath("TargetButtons/TargetMarker")
|
|
||||||
_healthText = NodePath("HealthShow")
|
|
||||||
_visualSprite = NodePath("Visual")
|
|
||||||
|
|
||||||
[node name="Visual" type="Node2D" parent="."]
|
[node name="Visual" type="Node2D" parent="."]
|
||||||
|
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
[gd_scene load_steps=7 format=3 uid="uid://cpanatqdjjpa3"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://scripts/CSharp/Common/FightOld/Fighter.cs" id="1_f3j2x"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://om2axn1vfa5o" path="res://art/animation/Vesna2D/Vesna Anims Sequences/S01-Idle/0001.png" id="2_2ud32"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://qlfwuakhe57t" path="res://art/ui/UI/attack_select_wheel.png" id="3_80knd"]
|
||||||
|
[ext_resource type="AudioStream" uid="uid://ch4c1wh4ghxyo" path="res://audio/sfx/Battle/Vesna/SFX_Battle_Vesna_Defense_08.wav" id="5_4r2vf"]
|
||||||
|
[ext_resource type="AudioStream" uid="uid://ccionrfr6e3lb" path="res://audio/sfx/Battle/Vesna/SFX_Battle_Vesna_Attack_04.wav" id="6_u1ayv"]
|
||||||
|
|
||||||
|
[sub_resource type="CircleShape2D" id="CircleShape2D_0tqnl"]
|
||||||
|
radius = 291.58
|
||||||
|
|
||||||
|
[node name="VesnaFighter" type="Node2D" node_paths=PackedStringArray("_attackButtons", "_targetButtons", "_targetMarker", "_healthText", "_visualSprite")]
|
||||||
|
script = ExtResource("1_f3j2x")
|
||||||
|
name = "Vesna"
|
||||||
|
maxHealth = 100
|
||||||
|
attackStrength = 10
|
||||||
|
maxActions = null
|
||||||
|
_attackButtons = NodePath("")
|
||||||
|
_targetButtons = NodePath("TargetButtons")
|
||||||
|
_targetMarker = NodePath("TargetButtons/TargetMarker")
|
||||||
|
_healthText = NodePath("HealthShow")
|
||||||
|
_visualSprite = NodePath("Sprite2D")
|
||||||
|
|
||||||
|
[node name="Sprite2D" type="Sprite2D" parent="."]
|
||||||
|
texture = ExtResource("2_2ud32")
|
||||||
|
offset = Vector2(43, -379)
|
||||||
|
|
||||||
|
[node name="TargetButtons" type="Node2D" parent="."]
|
||||||
|
visible = false
|
||||||
|
|
||||||
|
[node name="TargetMarker" type="Sprite2D" parent="TargetButtons"]
|
||||||
|
visible = false
|
||||||
|
z_index = 200
|
||||||
|
position = Vector2(8, -122)
|
||||||
|
scale = Vector2(4.245, 4.245)
|
||||||
|
texture = ExtResource("3_80knd")
|
||||||
|
|
||||||
|
[node name="Area2D" type="Area2D" parent="TargetButtons"]
|
||||||
|
position = Vector2(3, -76)
|
||||||
|
|
||||||
|
[node name="CollisionShape2D" type="CollisionShape2D" parent="TargetButtons/Area2D"]
|
||||||
|
shape = SubResource("CircleShape2D_0tqnl")
|
||||||
|
|
||||||
|
[node name="HealthShow" type="Label" parent="."]
|
||||||
|
z_index = 200
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
offset_left = -197.0
|
||||||
|
offset_top = -947.0
|
||||||
|
offset_right = 207.0
|
||||||
|
offset_bottom = -801.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
theme_override_font_sizes/font_size = 106
|
||||||
|
text = "100/100"
|
||||||
|
horizontal_alignment = 1
|
||||||
|
vertical_alignment = 1
|
||||||
|
|
||||||
|
[node name="HitAudio" type="AudioStreamPlayer" parent="."]
|
||||||
|
stream = ExtResource("5_4r2vf")
|
||||||
|
|
||||||
|
[node name="AttackAudio" type="AudioStreamPlayer" parent="."]
|
||||||
|
stream = ExtResource("6_u1ayv")
|
||||||
+1
-1
@@ -28,10 +28,10 @@ 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/fight/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"
|
||||||
|
FightWorldAutoload="*res://prefabs/fight/fight_world_autoload.tscn"
|
||||||
|
|
||||||
[dialogic]
|
[dialogic]
|
||||||
|
|
||||||
|
|||||||
@@ -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="."]
|
||||||
|
|||||||
@@ -0,0 +1,202 @@
|
|||||||
|
[gd_scene load_steps=11 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://c76mhhqyk4lgh" path="res://scripts/CSharp/Common/Fight/FightHappening.cs" id="1_gsk03"]
|
||||||
|
[ext_resource type="Script" uid="uid://dtf4ejct4m682" path="res://scripts/CSharp/Common/Fight/ActionAnimationController.cs" id="2_7kjgs"]
|
||||||
|
[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="ActionAnimationController" type="Node" parent="." node_paths=PackedStringArray("_allFightersVisual")]
|
||||||
|
script = ExtResource("2_7kjgs")
|
||||||
|
_allFightersVisual = NodePath("../FightVisuals")
|
||||||
|
|
||||||
|
[node name="StateReactionActionAnimation" type="Node" parent="ActionAnimationController"]
|
||||||
|
script = ExtResource("4_ydj1i")
|
||||||
|
_fightState = 10
|
||||||
|
|
||||||
|
[node name="Camera2D" type="Camera2D" parent="."]
|
||||||
|
|
||||||
|
[node name="FightSetup" type="Node2D" parent="."]
|
||||||
|
script = ExtResource("1_fiutj")
|
||||||
|
|
||||||
|
[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"]
|
||||||
|
|
||||||
|
[node name="EnemyFighters" type="Node2D" parent="FightVisuals"]
|
||||||
|
|
||||||
|
[node name="EnvironmentVisuals" type="Node2D" parent="."]
|
||||||
|
|
||||||
|
[node name="FightSceneSwitcher" parent="." instance=ExtResource("2_phrlx")]
|
||||||
|
|
||||||
|
[node name="ActionSelect" type="CanvasLayer" parent="." node_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)
|
||||||
|
layout_mode = 3
|
||||||
|
anchors_preset = 12
|
||||||
|
anchor_top = 1.0
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 0
|
||||||
|
size_flags_vertical = 8
|
||||||
|
|
||||||
|
[node name="background" type="ColorRect" parent="ActionSelect/BottomPanel"]
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
color = Color(1, 1, 1, 0.27451)
|
||||||
|
|
||||||
|
[node name="VBoxContainer" type="VBoxContainer" parent="ActionSelect/BottomPanel"]
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
|
||||||
|
[node name="MarginContainer" type="MarginContainer" parent="ActionSelect/BottomPanel/VBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_vertical = 3
|
||||||
|
theme_override_constants/margin_left = 200
|
||||||
|
theme_override_constants/margin_right = 200
|
||||||
|
|
||||||
|
[node name="HBoxContainer" type="HBoxContainer" parent="ActionSelect/BottomPanel/VBoxContainer/MarginContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
alignment = 1
|
||||||
|
|
||||||
|
[node name="MarginContainer" type="MarginContainer" parent="ActionSelect/BottomPanel/VBoxContainer/MarginContainer/HBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
theme_override_constants/margin_left = 10
|
||||||
|
theme_override_constants/margin_top = 10
|
||||||
|
theme_override_constants/margin_right = 10
|
||||||
|
theme_override_constants/margin_bottom = 10
|
||||||
|
|
||||||
|
[node name="AttackButton" type="Button" parent="ActionSelect/BottomPanel/VBoxContainer/MarginContainer/HBoxContainer/MarginContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
theme_override_font_sizes/font_size = 41
|
||||||
|
text = "Attack"
|
||||||
|
|
||||||
|
[node name="MarginContainer2" type="MarginContainer" parent="ActionSelect/BottomPanel/VBoxContainer/MarginContainer/HBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
theme_override_constants/margin_left = 10
|
||||||
|
theme_override_constants/margin_top = 10
|
||||||
|
theme_override_constants/margin_right = 10
|
||||||
|
theme_override_constants/margin_bottom = 10
|
||||||
|
|
||||||
|
[node name="Summon Button" type="Button" parent="ActionSelect/BottomPanel/VBoxContainer/MarginContainer/HBoxContainer/MarginContainer2"]
|
||||||
|
layout_mode = 2
|
||||||
|
theme_override_font_sizes/font_size = 41
|
||||||
|
text = "Summon"
|
||||||
|
|
||||||
|
[node name="MarginContainer3" type="MarginContainer" parent="ActionSelect/BottomPanel/VBoxContainer/MarginContainer/HBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
theme_override_constants/margin_left = 10
|
||||||
|
theme_override_constants/margin_top = 10
|
||||||
|
theme_override_constants/margin_right = 10
|
||||||
|
theme_override_constants/margin_bottom = 10
|
||||||
|
|
||||||
|
[node name="Talk Button" type="Button" parent="ActionSelect/BottomPanel/VBoxContainer/MarginContainer/HBoxContainer/MarginContainer3"]
|
||||||
|
layout_mode = 2
|
||||||
|
theme_override_font_sizes/font_size = 41
|
||||||
|
text = "Talk"
|
||||||
|
|
||||||
|
[node name="MarginContainer4" type="MarginContainer" parent="ActionSelect/BottomPanel/VBoxContainer/MarginContainer/HBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
theme_override_constants/margin_left = 10
|
||||||
|
theme_override_constants/margin_top = 10
|
||||||
|
theme_override_constants/margin_right = 10
|
||||||
|
theme_override_constants/margin_bottom = 10
|
||||||
|
|
||||||
|
[node name="Flee Button" type="Button" parent="ActionSelect/BottomPanel/VBoxContainer/MarginContainer/HBoxContainer/MarginContainer4"]
|
||||||
|
layout_mode = 2
|
||||||
|
theme_override_font_sizes/font_size = 41
|
||||||
|
text = "Flee"
|
||||||
|
|
||||||
|
[node name="MarginContainer2" type="MarginContainer" parent="ActionSelect/BottomPanel/VBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_vertical = 3
|
||||||
|
theme_override_constants/margin_left = 200
|
||||||
|
theme_override_constants/margin_right = 200
|
||||||
|
|
||||||
|
[node name="MarginContainer" type="MarginContainer" parent="ActionSelect/BottomPanel/VBoxContainer/MarginContainer2"]
|
||||||
|
layout_mode = 2
|
||||||
|
theme_override_constants/margin_left = 10
|
||||||
|
theme_override_constants/margin_top = 10
|
||||||
|
theme_override_constants/margin_right = 10
|
||||||
|
theme_override_constants/margin_bottom = 10
|
||||||
|
|
||||||
|
[node name="Label" type="Label" parent="ActionSelect/BottomPanel/VBoxContainer/MarginContainer2/MarginContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_vertical = 1
|
||||||
|
theme_override_colors/font_color = Color(0, 0, 0, 1)
|
||||||
|
theme_override_font_sizes/font_size = 41
|
||||||
|
text = "This text explains the currently hovered button"
|
||||||
|
|
||||||
|
[node name="StateReactionInputActionSelect" type="Node" parent="ActionSelect"]
|
||||||
|
script = ExtResource("4_ydj1i")
|
||||||
|
_fightState = 6
|
||||||
|
|
||||||
|
[node name="StateMachineDebugger" type="Node" parent="." node_paths=PackedStringArray("_label", "_current")]
|
||||||
|
script = ExtResource("8_tv7cl")
|
||||||
|
_label = NodePath("Label")
|
||||||
|
_current = NodePath("Current")
|
||||||
|
|
||||||
|
[node name="Label" type="Label" parent="StateMachineDebugger"]
|
||||||
|
offset_left = -982.0
|
||||||
|
offset_top = -497.0
|
||||||
|
offset_right = -893.0
|
||||||
|
offset_bottom = -474.0
|
||||||
|
text = "Hello world"
|
||||||
|
|
||||||
|
[node name="Current" type="Label" parent="StateMachineDebugger"]
|
||||||
|
offset_left = 705.0
|
||||||
|
offset_top = -495.0
|
||||||
|
offset_right = 794.0
|
||||||
|
offset_bottom = -472.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="SignalTransitionState" from="FightHappening" to="ActionAnimationController/StateReactionActionAnimation" method="FightHappeningStateTransitioned"]
|
||||||
|
[connection signal="OnStateEntered" from="ActionAnimationController/StateReactionActionAnimation" to="ActionAnimationController" method="StateEnter"]
|
||||||
|
[connection signal="OnStateExited" from="ActionAnimationController/StateReactionActionAnimation" to="ActionAnimationController" method="StateExit"]
|
||||||
|
[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"]
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -24,12 +24,12 @@
|
|||||||
[ext_resource type="Texture2D" uid="uid://bmjjfd5ngptxe" path="res://art/nature/baum märz 2025/backtreebois team kennedy.png" id="23_uhyft"]
|
[ext_resource type="Texture2D" uid="uid://bmjjfd5ngptxe" path="res://art/nature/baum märz 2025/backtreebois team kennedy.png" id="23_uhyft"]
|
||||||
[ext_resource type="Texture2D" uid="uid://bcw6oeovkmiup" path="res://art/nature/baum märz 2025/sonnenblumeseamless.png" id="24_3fmyy"]
|
[ext_resource type="Texture2D" uid="uid://bcw6oeovkmiup" path="res://art/nature/baum märz 2025/sonnenblumeseamless.png" id="24_3fmyy"]
|
||||||
[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/Fight/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/fight/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"]
|
||||||
|
|||||||
@@ -105,6 +105,7 @@ _data = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[node name="SceneTransition" type="CanvasLayer" node_paths=PackedStringArray("animationPlayer")]
|
[node name="SceneTransition" type="CanvasLayer" node_paths=PackedStringArray("animationPlayer")]
|
||||||
|
layer = 100
|
||||||
script = ExtResource("1_e0bkc")
|
script = ExtResource("1_e0bkc")
|
||||||
animationPlayer = NodePath("SceneFadeAnimation")
|
animationPlayer = NodePath("SceneFadeAnimation")
|
||||||
|
|
||||||
|
|||||||
@@ -18,10 +18,13 @@ public partial class CameraController : Camera2D
|
|||||||
|
|
||||||
[Export] private Node2D _followNode;
|
[Export] private Node2D _followNode;
|
||||||
|
|
||||||
public FightInstance? fightToShow;
|
public FightHappening? fightToShow;
|
||||||
|
|
||||||
|
|
||||||
public override void _Process(double delta)
|
public override void _Process(double delta)
|
||||||
{
|
{
|
||||||
this.GlobalPosition = fightToShow?.camPositionNode.GlobalPosition ?? _followNode.GlobalPosition;
|
this.GlobalPosition = /*fightToShow?.camPositionNode.GlobalPosition ??*/ _followNode.GlobalPosition;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,13 +12,15 @@ 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
|
||||||
@@ -28,19 +32,17 @@ public partial class InteractionArea2D : Node2D
|
|||||||
|
|
||||||
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)
|
||||||
@@ -51,10 +53,10 @@ public partial class InteractionArea2D : Node2D
|
|||||||
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)
|
||||||
@@ -64,10 +66,14 @@ public partial class InteractionArea2D : Node2D
|
|||||||
|
|
||||||
_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)
|
||||||
@@ -81,8 +87,13 @@ public partial class InteractionArea2D : Node2D
|
|||||||
{
|
{
|
||||||
_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);
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
using Godot;
|
||||||
|
|
||||||
|
namespace Babushka.scripts.CSharp.Common.Fight;
|
||||||
|
|
||||||
|
public partial class ActionAnimationController : Node
|
||||||
|
{
|
||||||
|
#region Shortcuts
|
||||||
|
|
||||||
|
private FightWorld.FightHappeningData HappeningData => FightWorld.Instance.fightHappeningData ?? throw new NoFightHappeningException();
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
[Export] private AllFightersVisual _allFightersVisual = null!;
|
||||||
|
|
||||||
|
|
||||||
|
public void StateEnter()
|
||||||
|
{
|
||||||
|
_ = HappeningData.actionStaging!.AnimateAction(_allFightersVisual);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void StateExit()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://dtf4ejct4m682
|
||||||
@@ -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 @@
|
|||||||
|
uid://e8c8ym0fyprn
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task AnimateAction(AllFightersVisual allFightersVisual)
|
||||||
|
{
|
||||||
|
var currentFighter = HappeningData.fighterStack.Current;
|
||||||
|
var targetFighter = targetSelect.GetTarget();
|
||||||
|
|
||||||
|
var currentFighterVisual = allFightersVisual.GetVisualForFighter(currentFighter);
|
||||||
|
var targetFighterVisual = allFightersVisual.GetVisualForFighter(targetFighter);
|
||||||
|
|
||||||
|
await currentFighterVisual.AnimatePosToTarget(targetFighterVisual);
|
||||||
|
_ = targetFighterVisual.AnimateHit();
|
||||||
|
await currentFighterVisual.AnimatePosToBase();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://c8c4t80bqsja5
|
||||||
@@ -0,0 +1,137 @@
|
|||||||
|
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
|
||||||
|
{
|
||||||
|
[ExportCategory("References")] [Export]
|
||||||
|
private Node2D _allyFighters = null!;
|
||||||
|
|
||||||
|
[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)
|
||||||
|
{
|
||||||
|
if (to == FightHappening.FightState.FightersEnterAnim)
|
||||||
|
{
|
||||||
|
EnterFighter();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (to == FightHappening.FightState.InputActionDetail)
|
||||||
|
{
|
||||||
|
if (HappeningData.actionStaging!.CurrentDetail() is TargetSelectActionDetail targetDetail)
|
||||||
|
{
|
||||||
|
ShowTargetSelect(targetDetail);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (from == FightHappening.FightState.InputActionDetail)
|
||||||
|
{
|
||||||
|
HideTargetSelect();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (from == FightHappening.FightState.ActionAnim)
|
||||||
|
{
|
||||||
|
_fighterVisuals.Values.ForEach(fv=>fv.UpdateHealthBar());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
public FighterVisual GetVisualForFighter(FightWorld.Fighter fighter)
|
||||||
|
{
|
||||||
|
return _fighterVisuals.TryGetValue(fighter, out var visual)
|
||||||
|
? visual
|
||||||
|
: throw new InvalidOperationException("No visual for this fighter");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://dwsqst8fhhqlc
|
||||||
@@ -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
|
||||||
@@ -0,0 +1,367 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.ExceptionServices;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Babushka.scripts.CSharp.Common.Util;
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
namespace Babushka.scripts.CSharp.Common.Fight;
|
||||||
|
|
||||||
|
public partial class FightHappening : Node
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
To get a visual overview of the FightHappening state machine, refer to the graph on miro:
|
||||||
|
https://miro.com/app/board/uXjVK8YEprM=/?moveToWidget=3458764640805655262&cot=14
|
||||||
|
*/
|
||||||
|
|
||||||
|
#region Internal Types
|
||||||
|
|
||||||
|
public enum FightState
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
FightStartAnim,
|
||||||
|
FightersEnter,
|
||||||
|
FightersEnterAnim,
|
||||||
|
NextFighter,
|
||||||
|
StateCheck,
|
||||||
|
InputActionSelect,
|
||||||
|
ActionCheckDetails,
|
||||||
|
InputActionDetail,
|
||||||
|
ActionExecute,
|
||||||
|
ActionAnim,
|
||||||
|
EnemyActionSelect,
|
||||||
|
PlayerWin,
|
||||||
|
EnemyWin,
|
||||||
|
}
|
||||||
|
|
||||||
|
public class FightersEnterStaging
|
||||||
|
{
|
||||||
|
public required List<FightWorld.Fighter> enteringAllyFighters;
|
||||||
|
public required List<FightWorld.Fighter> enteringEnemyFighters;
|
||||||
|
|
||||||
|
public bool HasAnyToExecute()
|
||||||
|
{
|
||||||
|
return enteringAllyFighters.Any() || enteringEnemyFighters.Any();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Settings
|
||||||
|
|
||||||
|
private const float StartAnimationTime = 1;
|
||||||
|
private const float FightersEnterAnimationTime = 1;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Shortcuts
|
||||||
|
|
||||||
|
private static FightWorld.FightHappeningData HappeningData =>
|
||||||
|
FightWorld.Instance.fightHappeningData ?? throw new NoFightHappeningException();
|
||||||
|
|
||||||
|
private static FightWorld.Fighter CurrentFighter => HappeningData.fighterStack.Current;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Events
|
||||||
|
|
||||||
|
[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 Singleton
|
||||||
|
|
||||||
|
public static FightHappening Instance = null!;
|
||||||
|
|
||||||
|
private void SetupInstance()
|
||||||
|
{
|
||||||
|
Instance = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public override void _Ready()
|
||||||
|
{
|
||||||
|
SetupInstance();
|
||||||
|
StartFight();
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Public Methods
|
||||||
|
|
||||||
|
public void StartFight()
|
||||||
|
{
|
||||||
|
RequireState(FightState.None);
|
||||||
|
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;
|
||||||
|
TransitionToState(nextState);
|
||||||
|
|
||||||
|
EmitSignalSignalTransitionFromState(lastState);
|
||||||
|
EmitSignalSignalTransitionState(lastState, nextState);
|
||||||
|
EmitSignalSignalTransitionToState(nextState);
|
||||||
|
_inTransition = false;
|
||||||
|
|
||||||
|
if (_changeToAfterTransition.HasValue)
|
||||||
|
{
|
||||||
|
ChangeState(_changeToAfterTransition.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TransitionFromState()
|
||||||
|
{
|
||||||
|
// fixed behaviour
|
||||||
|
switch (HappeningData.fightState)
|
||||||
|
{
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TransitionToState(FightState nextState)
|
||||||
|
{
|
||||||
|
// fixed behaviour
|
||||||
|
switch (HappeningData.fightState)
|
||||||
|
{
|
||||||
|
case FightState.FightStartAnim:
|
||||||
|
AdvanceToStateInSeconds(FightState.FightersEnter, StartAnimationTime);
|
||||||
|
break;
|
||||||
|
case FightState.FightersEnter:
|
||||||
|
HappeningData.fightersEnterStaging = StageFightersEnter();
|
||||||
|
if (HappeningData.fightersEnterStaging.HasAnyToExecute())
|
||||||
|
{
|
||||||
|
ExecuteFightersEnter();
|
||||||
|
ChangeState(FightState.FightersEnterAnim);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ChangeState(FightState.NextFighter);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case FightState.FightersEnterAnim:
|
||||||
|
AdvanceToStateInSeconds(FightState.NextFighter, FightersEnterAnimationTime);
|
||||||
|
break;
|
||||||
|
case FightState.NextFighter:
|
||||||
|
ExecuteNextFighter();
|
||||||
|
ChangeState(FightState.StateCheck);
|
||||||
|
break;
|
||||||
|
case FightState.StateCheck:
|
||||||
|
// restest action staging and fighter enter staging
|
||||||
|
HappeningData.actionStaging = null;
|
||||||
|
HappeningData.fightersEnterStaging = null;
|
||||||
|
|
||||||
|
if (!FightWorld.Instance.allyFighters.IsAlive())
|
||||||
|
{
|
||||||
|
ChangeState(FightState.EnemyWin);
|
||||||
|
}
|
||||||
|
else if (HappeningData.enemyGroup.AreAllDead())
|
||||||
|
{
|
||||||
|
ChangeState(FightState.PlayerWin);
|
||||||
|
}
|
||||||
|
else if (CurrentFighter.actionPointsLeft <= 0)
|
||||||
|
{
|
||||||
|
ChangeState(FightState.FightersEnter);
|
||||||
|
}
|
||||||
|
else if (CurrentFighter.isEnemy)
|
||||||
|
{
|
||||||
|
ChangeState(FightState.EnemyActionSelect);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ChangeState(FightState.InputActionSelect);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case FightState.InputActionSelect:
|
||||||
|
// wait for player input
|
||||||
|
break;
|
||||||
|
case FightState.ActionCheckDetails:
|
||||||
|
RequireNotNull(HappeningData.actionStaging);
|
||||||
|
|
||||||
|
if (ActionAbort())
|
||||||
|
ChangeState(FightState.InputActionSelect);
|
||||||
|
else if (ActionNeededDetail())
|
||||||
|
ChangeState(FightState.InputActionDetail);
|
||||||
|
else
|
||||||
|
ChangeState(FightState.ActionExecute);
|
||||||
|
break;
|
||||||
|
case FightState.InputActionDetail:
|
||||||
|
// wait for player input
|
||||||
|
break;
|
||||||
|
case FightState.EnemyActionSelect:
|
||||||
|
HappeningData.actionStaging = CurrentFighter.AutoSelectAction();
|
||||||
|
ChangeState(FightState.ActionExecute);
|
||||||
|
break;
|
||||||
|
case FightState.ActionExecute:
|
||||||
|
ExecuteAction();
|
||||||
|
ChangeState(FightState.ActionAnim);
|
||||||
|
break;
|
||||||
|
case FightState.ActionAnim:
|
||||||
|
var actionTime = GetActionAnimationEnd();
|
||||||
|
if (actionTime.IsType<float>())
|
||||||
|
{
|
||||||
|
AdvanceToStateInSeconds(FightState.StateCheck, actionTime);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_ = AdvanceToStateWhenDone(FightState.StateCheck, actionTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Game Logic
|
||||||
|
|
||||||
|
private FightersEnterStaging StageFightersEnter()
|
||||||
|
{
|
||||||
|
// ally
|
||||||
|
var enteringAllyFighters = new List<FightWorld.Fighter>();
|
||||||
|
var allyFighters = FightWorld.Instance.allyFighters;
|
||||||
|
if (!allyFighters.vesnaFighter.entered)
|
||||||
|
{
|
||||||
|
enteringAllyFighters.Add(allyFighters.vesnaFighter);
|
||||||
|
}
|
||||||
|
|
||||||
|
// enemy
|
||||||
|
const int totalEnemySpace = 3;
|
||||||
|
var enemySpaceLeft = totalEnemySpace - HappeningData.enemyGroup.GetEnteredAmount();
|
||||||
|
|
||||||
|
return new FightersEnterStaging
|
||||||
|
{
|
||||||
|
enteringAllyFighters = enteringAllyFighters,
|
||||||
|
enteringEnemyFighters = HappeningData.enemyGroup.GetUptoUnenteredFighters(enemySpaceLeft).ToList()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ExecuteFightersEnter()
|
||||||
|
{
|
||||||
|
Debug.Assert(HappeningData.fightersEnterStaging != null);
|
||||||
|
foreach (var fighter in HappeningData.fightersEnterStaging.enteringAllyFighters)
|
||||||
|
{
|
||||||
|
fighter.entered = true;
|
||||||
|
HappeningData.fighterStack.AddAsLast(fighter);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var fighter in HappeningData.fightersEnterStaging.enteringEnemyFighters)
|
||||||
|
{
|
||||||
|
fighter.entered = true;
|
||||||
|
HappeningData.fighterStack.AddAsLast(fighter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ExecuteNextFighter()
|
||||||
|
{
|
||||||
|
HappeningData.fighterStack.Next();
|
||||||
|
CurrentFighter.actionPointsLeft = CurrentFighter.maxActionPoints;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ExecuteAction()
|
||||||
|
{
|
||||||
|
Debug.Assert(HappeningData.actionStaging != null);
|
||||||
|
HappeningData.actionStaging.ExecuteAction();
|
||||||
|
CurrentFighter.actionPointsLeft -= HappeningData.actionStaging.GetActionPointCost();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Variant<float, Func<bool>> GetActionAnimationEnd()
|
||||||
|
{
|
||||||
|
Debug.Assert(HappeningData.actionStaging != null);
|
||||||
|
return HappeningData.actionStaging.GetAnimationEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool ActionAbort()
|
||||||
|
{
|
||||||
|
Debug.Assert(HappeningData.actionStaging != null);
|
||||||
|
return HappeningData.actionStaging.MarkedForAbort();
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool ActionNeededDetail()
|
||||||
|
{
|
||||||
|
Debug.Assert(HappeningData.actionStaging != null);
|
||||||
|
return HappeningData.actionStaging.NextDetail();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion // Game Logic
|
||||||
|
|
||||||
|
#region Utility
|
||||||
|
|
||||||
|
private void RequireState(params FightState[] states)
|
||||||
|
{
|
||||||
|
if (states.Contains(HappeningData.fightState))
|
||||||
|
return;
|
||||||
|
|
||||||
|
throw new Exception(
|
||||||
|
$"Can not call this Method while in state {HappeningData.fightState}. Only available in {string.Join(" ,", states)}");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void 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)
|
||||||
|
{
|
||||||
|
FightWorld.Instance.GetTree().CreateTimer(seconds).Timeout += () => ChangeState(nextState);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task AdvanceToStateWhenDone(FightState nextState, Func<bool> isDone)
|
||||||
|
{
|
||||||
|
while (!isDone())
|
||||||
|
{
|
||||||
|
await FightWorld.Instance.ToSignal(FightWorld.Instance.GetTree(), SceneTree.SignalName.ProcessFrame);
|
||||||
|
}
|
||||||
|
|
||||||
|
ChangeState(nextState);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
using Godot;
|
||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using Babushka.scripts.CSharp.Common.Fight;
|
||||||
|
|
||||||
|
public partial class FightHappeningSceneSetup : Node2D
|
||||||
|
{
|
||||||
|
public override void _Ready()
|
||||||
|
{
|
||||||
|
var fightHappening = FightWorld.Instance.fightHappeningData;
|
||||||
|
Debug.Assert(fightHappening != null, "Fight happening scene loaded, without a fight happening");
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://cnhpnn8o0gybd
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
using Godot;
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using Babushka.scripts.CSharp.Common.Fight;
|
||||||
|
|
||||||
|
public partial class FightHappeningStateDebugger : Node
|
||||||
|
{
|
||||||
|
[Export] private Label _label;
|
||||||
|
|
||||||
|
[Export] private Label _current;
|
||||||
|
|
||||||
|
private FightWorld.FightHappeningData Data => FightWorld.Instance.fightHappeningData!;
|
||||||
|
|
||||||
|
public void StateChange(FightHappening.FightState from, FightHappening.FightState to)
|
||||||
|
{
|
||||||
|
_current.Text = $"{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,351 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using Babushka.scripts.CSharp.Common.Camera;
|
|
||||||
using Babushka.scripts.CSharp.Common.Util;
|
|
||||||
using Godot;
|
|
||||||
namespace Babushka.scripts.CSharp.Common.Fight;
|
|
||||||
|
|
||||||
public partial class FightInstance : Node2D //TODO: remake
|
|
||||||
{
|
|
||||||
[Export(PropertyHint.ArrayType)] private Node2D[] _friendlyFightSpots;
|
|
||||||
[Export(PropertyHint.ArrayType)] private Node2D[] _enemyFightSpots;
|
|
||||||
[Export] public Node2D camPositionNode;
|
|
||||||
[Export] private FightStateManager _fightStateManager;
|
|
||||||
[Export] private Label _fightEndText;
|
|
||||||
|
|
||||||
|
|
||||||
[Signal]
|
|
||||||
public delegate void FightStartedEventHandler();
|
|
||||||
|
|
||||||
[Signal]
|
|
||||||
public delegate void FightEndedEventHandler();
|
|
||||||
|
|
||||||
private List<Fighter> _friendlyFighters = new();
|
|
||||||
private List<Fighter> _enemyFighters = new();
|
|
||||||
|
|
||||||
private FightAttack? _stagedAttack = null;
|
|
||||||
|
|
||||||
public override void _Ready()
|
|
||||||
{
|
|
||||||
//_fightStateManager.CurrentFightState = FightStateManager.FightState.FightStartAnim;
|
|
||||||
_fightStateManager.ExitingTransition += from =>
|
|
||||||
{
|
|
||||||
switch (from)
|
|
||||||
{
|
|
||||||
case FightStateManager.FightState.None:
|
|
||||||
CaptureCamera();
|
|
||||||
Show();
|
|
||||||
EmitSignalFightStarted();
|
|
||||||
break;
|
|
||||||
case FightStateManager.FightState.Input:
|
|
||||||
HideAttackButtons();
|
|
||||||
break;
|
|
||||||
case FightStateManager.FightState.InputTargetSelect:
|
|
||||||
HideTargetButtons();
|
|
||||||
break;
|
|
||||||
case FightStateManager.FightState.FriendAttackAnim:
|
|
||||||
_stagedAttack = null;
|
|
||||||
break;
|
|
||||||
case FightStateManager.FightState.PlayerWinAnim:
|
|
||||||
case FightStateManager.FightState.EnemyWinAnim:
|
|
||||||
_fightEndText.Text = "";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
_fightStateManager.EnteringTransition += to =>
|
|
||||||
{
|
|
||||||
switch (to)
|
|
||||||
{
|
|
||||||
case FightStateManager.FightState.None:
|
|
||||||
EmitSignalFightEnded();
|
|
||||||
CleanUp();
|
|
||||||
Hide();
|
|
||||||
ReleaseCamera();
|
|
||||||
break;
|
|
||||||
case FightStateManager.FightState.Input:
|
|
||||||
if (CheckWinAndSetState())
|
|
||||||
break;
|
|
||||||
if (CheckFriendlyActionsLeftAndSetState())
|
|
||||||
break;
|
|
||||||
ShowAttackButtons();
|
|
||||||
break;
|
|
||||||
case FightStateManager.FightState.InputTargetSelect:
|
|
||||||
ShowTargetButtons();
|
|
||||||
break;
|
|
||||||
case FightStateManager.FightState.FriendAttackAnim:
|
|
||||||
ExecuteAttack();
|
|
||||||
GetTree().CreateTimer(1).Timeout += () => _fightStateManager.CurrentFightState = FightStateManager.FightState.Input;
|
|
||||||
break;
|
|
||||||
case FightStateManager.FightState.Enemy:
|
|
||||||
if (CheckWinAndSetState())
|
|
||||||
break;
|
|
||||||
if (CheckEnemyActionsLeftAndSetState())
|
|
||||||
break;
|
|
||||||
DecideEnemyAttack();
|
|
||||||
_fightStateManager.CurrentFightState = FightStateManager.FightState.EnemyAttackAnim;
|
|
||||||
break;
|
|
||||||
case FightStateManager.FightState.EnemyAttackAnim:
|
|
||||||
ExecuteAttack();
|
|
||||||
GetTree().CreateTimer(1).Timeout += () => _fightStateManager.CurrentFightState = FightStateManager.FightState.Enemy;
|
|
||||||
break;
|
|
||||||
case FightStateManager.FightState.PlayerWinAnim:
|
|
||||||
_fightEndText.Text = "You Win!";
|
|
||||||
GetTree().CreateTimer(1.5).Timeout += () => _fightStateManager.CurrentFightState = FightStateManager.FightState.None;
|
|
||||||
break;
|
|
||||||
case FightStateManager.FightState.EnemyWinAnim:
|
|
||||||
_fightEndText.Text = "You Died :(";
|
|
||||||
GetTree().CreateTimer(3).Timeout += () => _fightStateManager.CurrentFightState = FightStateManager.FightState.None;
|
|
||||||
break;
|
|
||||||
case FightStateManager.FightState.ChangeSideToEnemy:
|
|
||||||
ResetEnemyActions();
|
|
||||||
_fightStateManager.CurrentFightState = FightStateManager.FightState.Enemy;
|
|
||||||
break;
|
|
||||||
case FightStateManager.FightState.ChangeSideToFriendly:
|
|
||||||
ResetFriendlyActions();
|
|
||||||
_fightStateManager.CurrentFightState = FightStateManager.FightState.Input;
|
|
||||||
break;
|
|
||||||
case FightStateManager.FightState.Heal:
|
|
||||||
Heal();
|
|
||||||
GetTree().CreateTimer(1).Timeout += () => _fightStateManager.CurrentFightState = FightStateManager.FightState.Input;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
private void Heal()
|
|
||||||
{
|
|
||||||
// TODO: make heal staging system
|
|
||||||
_friendlyFighters.Where(f => !f.IsDead()).ForEach(f =>
|
|
||||||
{
|
|
||||||
f.Health += 50;
|
|
||||||
f.HealAnimation();
|
|
||||||
f.DecrementActions();
|
|
||||||
});
|
|
||||||
UpdateHealthVisual();
|
|
||||||
}
|
|
||||||
private void ResetEnemyActions()
|
|
||||||
{
|
|
||||||
_enemyFighters.ForEach(f => f.ResetActions());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ResetFriendlyActions()
|
|
||||||
{
|
|
||||||
_friendlyFighters.ForEach(f => f.ResetActions());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <returns>
|
|
||||||
* <c>true</c> if the state was changed
|
|
||||||
* </returns>
|
|
||||||
*/
|
|
||||||
private bool CheckFriendlyActionsLeftAndSetState()
|
|
||||||
{
|
|
||||||
var hasActionsLeft = _friendlyFighters.Where(f => !f.IsDead()).Any(f => f.HasActionsLeft());
|
|
||||||
if (hasActionsLeft)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
} // else
|
|
||||||
_fightStateManager.CurrentFightState = FightStateManager.FightState.ChangeSideToEnemy;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <returns>
|
|
||||||
* <c>true</c> if the state was changed
|
|
||||||
* </returns>
|
|
||||||
*/
|
|
||||||
private bool CheckEnemyActionsLeftAndSetState()
|
|
||||||
{
|
|
||||||
var hasActionsLeft = _enemyFighters.Where(f => !f.IsDead()).Any(f => f.HasActionsLeft());
|
|
||||||
if (hasActionsLeft)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
} // else
|
|
||||||
_fightStateManager.CurrentFightState = FightStateManager.FightState.ChangeSideToFriendly;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CleanUp()
|
|
||||||
{
|
|
||||||
_enemyFighters.ForEach(f => f.QueueFree());
|
|
||||||
_friendlyFighters.ForEach(f => f.QueueFree());
|
|
||||||
_enemyFighters = new();
|
|
||||||
_friendlyFighters = new();
|
|
||||||
}
|
|
||||||
private void DecideEnemyAttack()
|
|
||||||
{
|
|
||||||
var availableEnemyFighters =
|
|
||||||
_enemyFighters
|
|
||||||
.Where(f => !f.IsDead())
|
|
||||||
.Where(f=>f.HasActionsLeft())
|
|
||||||
.ToList();
|
|
||||||
var aliveFriendlyFighters =
|
|
||||||
_friendlyFighters
|
|
||||||
.Where(f => !f.IsDead())
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
if (availableEnemyFighters.Count <= 0)
|
|
||||||
throw new InvalidOperationException("No enemy fighters available for attack.");
|
|
||||||
|
|
||||||
if (aliveFriendlyFighters.Count <= 0)
|
|
||||||
throw new InvalidOperationException("No friendly fighters available to target.");
|
|
||||||
|
|
||||||
var fighter = availableEnemyFighters.Random();
|
|
||||||
var target = aliveFriendlyFighters.Random();
|
|
||||||
|
|
||||||
_stagedAttack = new FightAttack
|
|
||||||
{
|
|
||||||
attacker = fighter!,
|
|
||||||
needsSelectedTarget = true,
|
|
||||||
damage = fighter!.attackStrength,
|
|
||||||
target = target!
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ExecuteAttack()
|
|
||||||
{
|
|
||||||
if (_stagedAttack == null)
|
|
||||||
throw new InvalidOperationException("No staged attack to execute.");
|
|
||||||
|
|
||||||
if (!_stagedAttack.needsSelectedTarget)
|
|
||||||
throw new NotImplementedException("Non-targeted attacks are not implemented yet.");
|
|
||||||
|
|
||||||
if (_stagedAttack.needsSelectedTarget && _stagedAttack.target == null)
|
|
||||||
throw new InvalidOperationException("No target selected for the staged attack.");
|
|
||||||
|
|
||||||
_stagedAttack.target!.Health -= _stagedAttack.damage;
|
|
||||||
_stagedAttack.attacker.DecrementActions();
|
|
||||||
_stagedAttack.attacker.AttackAnimation(_stagedAttack);
|
|
||||||
|
|
||||||
UpdateHealthVisual();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateHealthVisual()
|
|
||||||
{
|
|
||||||
_friendlyFighters
|
|
||||||
.Concat(_enemyFighters)
|
|
||||||
.ForEach(f => f.UpdateHealthVisual());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ReleaseCamera()
|
|
||||||
{
|
|
||||||
CameraController.Instance.fightToShow = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CaptureCamera()
|
|
||||||
{
|
|
||||||
CameraController.Instance.fightToShow = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Start(FightParty fightParty, PackedScene?[] enemies)
|
|
||||||
{
|
|
||||||
if (_fightStateManager.IsRunning())
|
|
||||||
{
|
|
||||||
GD.PushWarning("Can not start a running fight");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fightParty.vesna)
|
|
||||||
{
|
|
||||||
InstantiateFighter(_friendlyFightSpots[1], FightManager.Instance.fightingVesnaScene);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i = 0; i < Math.Min(_enemyFightSpots.Length, enemies.Length); i++)
|
|
||||||
{
|
|
||||||
var enemy = enemies[i];
|
|
||||||
if (enemy == null)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
InstantiateFighter(_enemyFightSpots[i], enemy, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
_fightStateManager.ToStartAnim();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void InstantiateFighter(Node2D parent, PackedScene fighterScene, bool isEnemy = false)
|
|
||||||
{
|
|
||||||
var fighter = fighterScene.Instantiate<Fighter>();
|
|
||||||
fighter.fightInstance = this;
|
|
||||||
parent.AddChild(fighter);
|
|
||||||
|
|
||||||
if (isEnemy)
|
|
||||||
{
|
|
||||||
_enemyFighters.Add(fighter);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_friendlyFighters.Add(fighter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SelectAttack(Fighter fighter)
|
|
||||||
{
|
|
||||||
_stagedAttack = new FightAttack
|
|
||||||
{
|
|
||||||
attacker = fighter,
|
|
||||||
damage = fighter.attackStrength,
|
|
||||||
needsSelectedTarget = true
|
|
||||||
};
|
|
||||||
|
|
||||||
if (_stagedAttack.needsSelectedTarget)
|
|
||||||
{
|
|
||||||
_fightStateManager.CurrentFightState = FightStateManager.FightState.InputTargetSelect;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_fightStateManager.CurrentFightState = FightStateManager.FightState.FriendAttackAnim;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void HideAttackButtons()
|
|
||||||
{
|
|
||||||
_friendlyFighters.ForEach(f => f.HideAttackButton());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ShowAttackButtons()
|
|
||||||
{
|
|
||||||
_friendlyFighters.ForEach(f => f.ShowAttackButton());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void HideTargetButtons()
|
|
||||||
{
|
|
||||||
_enemyFighters.ForEach(f => f.HideTargetButtons());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ShowTargetButtons()
|
|
||||||
{
|
|
||||||
_enemyFighters.Where(f => !f.IsDead()).ForEach(f => f.ShowTargetButtons());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SelectTargetAndAttack(Fighter fighter)
|
|
||||||
{
|
|
||||||
if (_stagedAttack == null)
|
|
||||||
throw new InvalidOperationException("No staged attack to select target for.");
|
|
||||||
|
|
||||||
_stagedAttack.target = fighter;
|
|
||||||
|
|
||||||
_fightStateManager.CurrentFightState = FightStateManager.FightState.FriendAttackAnim;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SelectHeal(Fighter fighter)
|
|
||||||
{
|
|
||||||
_fightStateManager.CurrentFightState = FightStateManager.FightState.Heal;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool CheckWinAndSetState()
|
|
||||||
{
|
|
||||||
if (_enemyFighters.All(f => f.IsDead()))
|
|
||||||
{
|
|
||||||
_fightStateManager.CurrentFightState = FightStateManager.FightState.PlayerWinAnim;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (_friendlyFighters.All(f => f.IsDead()))
|
|
||||||
{
|
|
||||||
_fightStateManager.CurrentFightState = FightStateManager.FightState.EnemyWinAnim;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -0,0 +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(PropertyHint.ArrayType)] private Node2D[] _enemyGroupSpawns;
|
||||||
|
[Export] private PackedScene _roamingEnemyGroupPrefab;
|
||||||
|
[Export] private FightSceneSwitcher _fightSceneSwitcher;
|
||||||
|
|
||||||
|
|
||||||
|
public override void _Ready()
|
||||||
|
{
|
||||||
|
var room = FightWorld.Instance.currentRoom!;
|
||||||
|
|
||||||
|
var i = 0;
|
||||||
|
foreach (var availableParent in _enemyGroupSpawns.Shuffle())
|
||||||
|
{
|
||||||
|
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++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://dbu8afaiohpdh
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using Babushka.scripts.CSharp.Common.SceneManagement;
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
namespace Babushka.scripts.CSharp.Common.Fight;
|
||||||
|
|
||||||
|
public partial class FightSceneSwitcher : Node
|
||||||
|
{
|
||||||
|
[Export] private Node sceneRoot;
|
||||||
|
[Export] private string fightRoomScenePath;
|
||||||
|
[Export] private string fightHappeningScene;
|
||||||
|
|
||||||
|
private void LoadNext()
|
||||||
|
{
|
||||||
|
var nextRoom = FightWorld.Instance.currentRoom;
|
||||||
|
Debug.Assert(nextRoom != null, "nextRoom!=null");
|
||||||
|
var nextFightHappening = FightWorld.Instance.fightHappeningData;
|
||||||
|
SceneTransitionThreaded.Instance.ChangeSceneToFile(nextFightHappening != null
|
||||||
|
? fightHappeningScene
|
||||||
|
: fightRoomScenePath);
|
||||||
|
UnloadAfterDelay();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void UnloadAfterDelay()
|
||||||
|
{
|
||||||
|
await ToSignal(GetTree().CreateTimer(1.0f), "timeout"); // 1.0f seconds
|
||||||
|
//sceneRoot.QueueFree();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SwitchRoom(int pathIndex)
|
||||||
|
{
|
||||||
|
Debug.Assert(FightWorld.Instance.currentRoom != null, "FightWorld.Instance.currentRoom!=null");
|
||||||
|
|
||||||
|
if (!FightWorld.Instance.currentRoom.paths.TryGetValue(pathIndex, out var nextRoom))
|
||||||
|
throw new Exception("Trying to go down a non-existent path");
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://cql8mt5jsmcdl
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
using Godot;
|
|
||||||
namespace Babushka.scripts.CSharp.Common.Fight;
|
|
||||||
|
|
||||||
public partial class FightStateManager : Node
|
|
||||||
{
|
|
||||||
[Signal]
|
|
||||||
public delegate void ExitingTransitionEventHandler(FightState exitingState);
|
|
||||||
|
|
||||||
[Signal]
|
|
||||||
public delegate void EnteringTransitionEventHandler(FightState enteringState);
|
|
||||||
|
|
||||||
public enum FightState
|
|
||||||
{
|
|
||||||
None,
|
|
||||||
FightStartAnim,
|
|
||||||
Input,
|
|
||||||
InputTargetSelect,
|
|
||||||
FriendAttackAnim,
|
|
||||||
Enemy,
|
|
||||||
EnemyAttackAnim,
|
|
||||||
PlayerWinAnim,
|
|
||||||
EnemyWinAnim,
|
|
||||||
ChangeSideToEnemy,
|
|
||||||
ChangeSideToFriendly,
|
|
||||||
Heal,
|
|
||||||
}
|
|
||||||
|
|
||||||
private FightState _fightStateBacking = FightState.None;
|
|
||||||
|
|
||||||
public FightState CurrentFightState
|
|
||||||
{
|
|
||||||
set => Transition(_fightStateBacking, value);
|
|
||||||
get => _fightStateBacking;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Transition(FightState from, FightState to)
|
|
||||||
{
|
|
||||||
if(from == to)
|
|
||||||
return;
|
|
||||||
|
|
||||||
GD.Print($"Transitioning from {from} to {to}");
|
|
||||||
ExitTransition(from);
|
|
||||||
_fightStateBacking = to;
|
|
||||||
EnterTransition(to);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ExitTransition(FightState from)
|
|
||||||
{
|
|
||||||
EmitSignalExitingTransition(from);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void EnterTransition(FightState to)
|
|
||||||
{
|
|
||||||
EmitSignalEnteringTransition(to);
|
|
||||||
switch (to)
|
|
||||||
{
|
|
||||||
case FightState.FightStartAnim:
|
|
||||||
EnterFightStartAnim();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private void EnterFightStartAnim()
|
|
||||||
{
|
|
||||||
GetTree().CreateTimer(1).Timeout += () => CurrentFightState = FightState.Input;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ToStartAnim()
|
|
||||||
{
|
|
||||||
CurrentFightState = FightState.FightStartAnim;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsRunning()
|
|
||||||
{
|
|
||||||
return CurrentFightState != FightState.None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
uid://oe1uypehqvr7
|
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace Babushka.scripts.CSharp.Common.Fight;
|
||||||
|
|
||||||
|
public static class FightUtils
|
||||||
|
{
|
||||||
|
public static int GetEnteredAmount(this FightWorld.FighterGroup self)
|
||||||
|
{
|
||||||
|
return self.enemies.Count(e => e.IsAlive() && e.entered);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<FightWorld.Fighter> GetUptoUnenteredFighters(
|
||||||
|
this FightWorld.FighterGroup self,
|
||||||
|
int maxFighters)
|
||||||
|
{
|
||||||
|
if (maxFighters <= self.enemies.Count)
|
||||||
|
return self.enemies
|
||||||
|
.Where(e => !e.entered && e.IsAlive());
|
||||||
|
|
||||||
|
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 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());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://beuhpltb84pf
|
||||||
@@ -0,0 +1,190 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using Babushka.scripts.CSharp.Common.Util;
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
namespace Babushka.scripts.CSharp.Common.Fight;
|
||||||
|
|
||||||
|
public partial class FightWorld : Node
|
||||||
|
{
|
||||||
|
public class World
|
||||||
|
{
|
||||||
|
public required List<Room> rooms;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Room
|
||||||
|
{
|
||||||
|
public required Dictionary<int, Room> paths;
|
||||||
|
public required List<FighterGroup> enemyGroups;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class FighterGroup
|
||||||
|
{
|
||||||
|
public required List<Fighter> enemies;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class FightHappeningData
|
||||||
|
{
|
||||||
|
public FightHappening.FightState fightState = FightHappening.FightState.None;
|
||||||
|
public FighterStack fighterStack = new();
|
||||||
|
public required FighterGroup enemyGroup;
|
||||||
|
public FightHappening.FightersEnterStaging? fightersEnterStaging;
|
||||||
|
public FighterAction? actionStaging;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Fighter
|
||||||
|
{
|
||||||
|
public enum Type
|
||||||
|
{
|
||||||
|
Blob,
|
||||||
|
BigBlob,
|
||||||
|
Mavka,
|
||||||
|
YourMom,
|
||||||
|
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 actionPointsLeft;
|
||||||
|
|
||||||
|
public FighterAction AutoSelectAction()
|
||||||
|
{
|
||||||
|
return availableActions.Random() ?? new FighterAction.Skip();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#region AutoLoad ( Contains _EnterTree() )
|
||||||
|
|
||||||
|
public static FightWorld Instance { get; private set; } = null!;
|
||||||
|
|
||||||
|
public override void _EnterTree()
|
||||||
|
{
|
||||||
|
Instance = this;
|
||||||
|
MyEnterTree();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public World? world = null;
|
||||||
|
public Room? currentRoom = null;
|
||||||
|
public FightHappeningData? fightHappeningData = null;
|
||||||
|
public AllyFighters allyFighters = new();
|
||||||
|
|
||||||
|
public void MyEnterTree()
|
||||||
|
{
|
||||||
|
Generate();
|
||||||
|
currentRoom = world!.rooms[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Generate()
|
||||||
|
{
|
||||||
|
world = new Generator().GenerateWorld();
|
||||||
|
}
|
||||||
|
|
||||||
|
private class Generator
|
||||||
|
{
|
||||||
|
public World GenerateWorld()
|
||||||
|
{
|
||||||
|
var world = new World
|
||||||
|
{
|
||||||
|
rooms = GenerateRooms()
|
||||||
|
};
|
||||||
|
return world;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Room> GenerateRooms()
|
||||||
|
{
|
||||||
|
var rooms = new List<Room>();
|
||||||
|
|
||||||
|
var roomCount = 2;
|
||||||
|
|
||||||
|
for (var i = 0; i < roomCount; i++)
|
||||||
|
{
|
||||||
|
rooms.Add(GenerateDisconnectedRoom());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Connect rooms linearly
|
||||||
|
for (var i = 0; i < rooms.Count - 1; i++)
|
||||||
|
{
|
||||||
|
rooms[i].paths[0] = rooms[i + 1];
|
||||||
|
rooms[i + 1].paths[1] = rooms[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return rooms;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Room GenerateDisconnectedRoom()
|
||||||
|
{
|
||||||
|
var room = new Room
|
||||||
|
{
|
||||||
|
paths = new Dictionary<int, Room>(),
|
||||||
|
enemyGroups = GenerateEnemyGroups()
|
||||||
|
};
|
||||||
|
return room;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<FighterGroup> GenerateEnemyGroups()
|
||||||
|
{
|
||||||
|
var enemyGroups = new List<FighterGroup>();
|
||||||
|
|
||||||
|
var enemyGroupCount = GD.RandRange(1, 3);
|
||||||
|
|
||||||
|
for (var i = 0; i < enemyGroupCount; i++)
|
||||||
|
{
|
||||||
|
enemyGroups.Add(GenerateSingleEnemyGroup());
|
||||||
|
}
|
||||||
|
|
||||||
|
return enemyGroups;
|
||||||
|
}
|
||||||
|
|
||||||
|
private FighterGroup GenerateSingleEnemyGroup()
|
||||||
|
{
|
||||||
|
var enemyGroup = new FighterGroup
|
||||||
|
{
|
||||||
|
enemies = []
|
||||||
|
};
|
||||||
|
|
||||||
|
var enemyCount = GD.RandRange(1, 3);
|
||||||
|
|
||||||
|
for (var i = 0; i < enemyCount; i++)
|
||||||
|
{
|
||||||
|
enemyGroup.enemies.Add(GenerateSingleEnemy());
|
||||||
|
}
|
||||||
|
|
||||||
|
return enemyGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Fighter GenerateSingleEnemy()
|
||||||
|
{
|
||||||
|
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 = Fighter.Type.Blob;
|
||||||
|
|
||||||
|
var enemy = new Fighter
|
||||||
|
{
|
||||||
|
type = type,
|
||||||
|
health = null,
|
||||||
|
isEnemy = true,
|
||||||
|
maxHealth = 12,
|
||||||
|
availableActions =
|
||||||
|
[
|
||||||
|
new FighterAction.Skip()
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
return enemy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://dqe1i2qmpttwf
|
||||||
@@ -1,181 +0,0 @@
|
|||||||
using Godot;
|
|
||||||
namespace Babushka.scripts.CSharp.Common.Fight;
|
|
||||||
|
|
||||||
public partial class Fighter : Node2D
|
|
||||||
{
|
|
||||||
[Export] public string name;
|
|
||||||
[Export] public int maxHealth;
|
|
||||||
[Export] public int attackStrength;
|
|
||||||
[Export] public int maxActions = 1;
|
|
||||||
|
|
||||||
[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 int _health;
|
|
||||||
private int _actions;
|
|
||||||
|
|
||||||
|
|
||||||
public FightInstance fightInstance;
|
|
||||||
public int Health
|
|
||||||
{
|
|
||||||
get => _health;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_health = value;
|
|
||||||
if (_health <= 0)
|
|
||||||
{
|
|
||||||
_health = 0;
|
|
||||||
Die();
|
|
||||||
}
|
|
||||||
if (_health > maxHealth)
|
|
||||||
{
|
|
||||||
_health = maxHealth;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Die()
|
|
||||||
{
|
|
||||||
_visualSprite.Scale = new Vector2(1, 0.3f);
|
|
||||||
EmitSignalDying();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void _Ready()
|
|
||||||
{
|
|
||||||
Health = maxHealth;
|
|
||||||
UpdateHealthVisual();
|
|
||||||
ResetActions();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Attack()
|
|
||||||
{
|
|
||||||
fightInstance.SelectAttack(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void HideAttackButton()
|
|
||||||
{
|
|
||||||
_attackButtons.Hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ShowAttackButton()
|
|
||||||
{
|
|
||||||
_attackButtons.Show();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void HideTargetButtons()
|
|
||||||
{
|
|
||||||
_targetButtons.Hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
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()
|
|
||||||
{
|
|
||||||
fightInstance.SelectAttack(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ClickedHeal()
|
|
||||||
{
|
|
||||||
fightInstance.SelectHeal(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ClickedTarget()
|
|
||||||
{
|
|
||||||
fightInstance.SelectTargetAndAttack(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void StartHoverTarget()
|
|
||||||
{
|
|
||||||
_targetMarker.Visible = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void EndHoverTarget()
|
|
||||||
{
|
|
||||||
_targetMarker.Visible = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdateHealthVisual()
|
|
||||||
{
|
|
||||||
_healthText.Text = $"{Health}/{maxHealth}";
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AttackAnimation(FightAttack attack)
|
|
||||||
{
|
|
||||||
EmitSignalAttacking();
|
|
||||||
var tween = GetTree().CreateTween();
|
|
||||||
tween.TweenProperty(this, "global_position", attack.target.GlobalPosition, 0.15);
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
EmitSignalDamageTaken();
|
|
||||||
var tween = GetTree().CreateTween();
|
|
||||||
tween.TweenProperty(this, "scale", new Vector2(1.4f, 0.6f), 0.15);
|
|
||||||
tween.TweenProperty(this, "scale", new Vector2(1, 1), 0.4)
|
|
||||||
.SetTrans(Tween.TransitionType.Cubic).SetEase(Tween.EaseType.Out);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsDead()
|
|
||||||
{
|
|
||||||
return Health <= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ResetActions()
|
|
||||||
{
|
|
||||||
_actions = maxActions;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool HasActionsLeft()
|
|
||||||
{
|
|
||||||
return _actions > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DecrementActions()
|
|
||||||
{
|
|
||||||
_actions--;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void HealAnimation()
|
|
||||||
{
|
|
||||||
EmitSignalHealed();
|
|
||||||
var tween = GetTree().CreateTween();
|
|
||||||
tween.TweenProperty(this, "scale", new Vector2(0.6f, 1.4f), 0.15);
|
|
||||||
tween.TweenProperty(this, "scale", new Vector2(1, 1), 0.4)
|
|
||||||
.SetTrans(Tween.TransitionType.Cubic).SetEase(Tween.EaseType.Out);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,132 @@
|
|||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Babushka.scripts.CSharp.Common.Util;
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool _abort = false;
|
||||||
|
|
||||||
|
#region Shortcuts
|
||||||
|
|
||||||
|
protected static FightWorld.FightHappeningData HappeningData =>
|
||||||
|
FightWorld.Instance.fightHappeningData ?? throw new NoFightHappeningException();
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Executes the data modification for the action. This must happen instantly and not via a coroutines or callbacks.
|
||||||
|
/// To get a multiple hit effect for one action, use appropriate Visual Manipulation functions in AnimateAction.
|
||||||
|
/// </summary>
|
||||||
|
public virtual void ExecuteAction()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a way to determine, when an action animation is done
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>
|
||||||
|
/// A variant that can be <c>float</c> or <c>Func<bool></c>.<br/>
|
||||||
|
/// When the return type is <c>float</c>, the animation will take the return value amount of seconds.<br/>
|
||||||
|
/// When the return type is <c>Func<bool></c>, the animation will be done, when the function returns true.
|
||||||
|
/// </returns>
|
||||||
|
public abstract Variant<float, Func<bool>> GetAnimationEnd();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Animates the action.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="allFightersVisual"></param>
|
||||||
|
public virtual async Task AnimateAction(AllFightersVisual allFightersVisual)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void MarkAbort()
|
||||||
|
{
|
||||||
|
_abort = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool MarkedForAbort()
|
||||||
|
{
|
||||||
|
return _abort;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <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 override Variant<float, Func<bool>> GetAnimationEnd()
|
||||||
|
{
|
||||||
|
return 0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool NextDetail()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://c60jugfee0bpv
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using Godot.NativeInterop;
|
||||||
|
|
||||||
|
namespace Babushka.scripts.CSharp.Common.Fight;
|
||||||
|
|
||||||
|
public class FighterStack
|
||||||
|
{
|
||||||
|
private class Node
|
||||||
|
{
|
||||||
|
public Node next;
|
||||||
|
public FightWorld.Fighter fighter;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Node? currentNode;
|
||||||
|
|
||||||
|
public FightWorld.Fighter Current => currentNode.fighter;
|
||||||
|
|
||||||
|
public void Next()
|
||||||
|
{
|
||||||
|
currentNode = currentNode.next;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FightWorld.Fighter PeekNext()
|
||||||
|
{
|
||||||
|
return currentNode.next.fighter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddAsLast(FightWorld.Fighter value)
|
||||||
|
{
|
||||||
|
// if first node
|
||||||
|
if (currentNode == null)
|
||||||
|
{
|
||||||
|
currentNode = new Node { fighter = value };
|
||||||
|
currentNode.next = currentNode;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var newNode = new Node { fighter = value, next = currentNode };
|
||||||
|
var node = currentNode;
|
||||||
|
while (node.next != currentNode)
|
||||||
|
{
|
||||||
|
node = node.next;
|
||||||
|
}
|
||||||
|
|
||||||
|
node.next = newNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddAsNext(FightWorld.Fighter value)
|
||||||
|
{
|
||||||
|
// if first node
|
||||||
|
if (currentNode == null)
|
||||||
|
{
|
||||||
|
AddAsLast(value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var newNode = new Node { fighter = value, next = currentNode.next };
|
||||||
|
currentNode.next = newNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Remove(FightWorld.Fighter value)
|
||||||
|
{
|
||||||
|
if (currentNode == null) return false;
|
||||||
|
|
||||||
|
// if only one node
|
||||||
|
if (currentNode.next == currentNode)
|
||||||
|
{
|
||||||
|
if (currentNode.fighter == value)
|
||||||
|
{
|
||||||
|
currentNode = null;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var node = currentNode;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
// next is the fighter to remove
|
||||||
|
if (node.next.fighter == value)
|
||||||
|
{
|
||||||
|
// if removing current, keep current
|
||||||
|
// it will be implicitly deleted on the next Next() call
|
||||||
|
|
||||||
|
node.next = node.next.next;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
node = node.next;
|
||||||
|
} while (node != currentNode);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://bahm4ukspymm2
|
||||||
@@ -0,0 +1,117 @@
|
|||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Babushka.scripts.CSharp.Common.Fight.ActionDetails;
|
||||||
|
using Babushka.scripts.CSharp.Common.Fight.UI;
|
||||||
|
using Godot;
|
||||||
|
using Godot.Collections;
|
||||||
|
|
||||||
|
namespace Babushka.scripts.CSharp.Common.Fight;
|
||||||
|
|
||||||
|
|
||||||
|
public partial class FighterVisual : Node2D
|
||||||
|
{
|
||||||
|
#region Shortcuts
|
||||||
|
|
||||||
|
private FightWorld.FightHappeningData HappeningData =>
|
||||||
|
FightWorld.Instance.fightHappeningData ?? throw new NoFightHappeningException();
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
[ExportCategory("References")]
|
||||||
|
[Export] private Node2D _visualParent = null!;
|
||||||
|
[Export] private Node2D _targetSelectionParent = null!;
|
||||||
|
[Export] public FighterHealthBarVisual healthBarVisual = null!;
|
||||||
|
|
||||||
|
|
||||||
|
private FightWorld.Fighter _boundFighter;
|
||||||
|
|
||||||
|
public void Initialize(FightWorld.Fighter fighter)
|
||||||
|
{
|
||||||
|
_boundFighter = fighter;
|
||||||
|
UpdateMirrorState();
|
||||||
|
UpdateHealthBar();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <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()
|
||||||
|
{
|
||||||
|
_visualParent.Scale = new Vector2(_boundFighter.isEnemy ? -1 : 1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateHealthBar()
|
||||||
|
{
|
||||||
|
healthBarVisual.UpdateHealth(_boundFighter.GetHealth(), _boundFighter.maxHealth);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetTargetSelectionActive(bool value)
|
||||||
|
{
|
||||||
|
_targetSelectionParent.Visible = value;
|
||||||
|
_targetSelectionParent.ProcessMode = value ? ProcessModeEnum.Inherit : ProcessModeEnum.Disabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
// listen from inside
|
||||||
|
public void ClickedTarget()
|
||||||
|
{
|
||||||
|
if (HappeningData.actionStaging!.CurrentDetail() is not TargetSelectActionDetail targetDetail)
|
||||||
|
throw new InvalidOperationException("No target selection needed right now");
|
||||||
|
|
||||||
|
targetDetail.SetTarget(_boundFighter);
|
||||||
|
FightHappening.Instance.DetailFilled();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Animations
|
||||||
|
//public void AttackAnimation(FightAttack attack)
|
||||||
|
//{
|
||||||
|
// EmitSignalAttacking();
|
||||||
|
// var tween = GetTree().CreateTween();
|
||||||
|
// tween.TweenProperty(this, "global_position", attack.target.GlobalPosition, 0.15);
|
||||||
|
// 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);
|
||||||
|
//}
|
||||||
|
|
||||||
|
public async Task AnimatePosToTarget(FighterVisual targetVisual, double duration = 0.15)
|
||||||
|
{
|
||||||
|
var tween = GetTree().CreateTween();
|
||||||
|
tween.TweenProperty(_visualParent, "global_position", targetVisual.GlobalPosition, 0.15);
|
||||||
|
await ToSignal(tween, "finished");
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task AnimatePosToBase(double duration = 0.7)
|
||||||
|
{
|
||||||
|
var tween = GetTree().CreateTween();
|
||||||
|
tween.TweenProperty(_visualParent, "position", new Vector2(0, 0), 0.15);
|
||||||
|
await ToSignal(tween, "finished");
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task AnimateHit()
|
||||||
|
{
|
||||||
|
var tween = GetTree().CreateTween();
|
||||||
|
tween.TweenProperty(this, "scale", new Vector2(1.4f, 0.6f), 0.15);
|
||||||
|
tween.TweenProperty(this, "scale", new Vector2(1, 1), 0.4)
|
||||||
|
.SetTrans(Tween.TransitionType.Cubic).SetEase(Tween.EaseType.Out);
|
||||||
|
await ToSignal(tween, "finished");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//private void HitAnimation(FightAttack attack)
|
||||||
|
//{
|
||||||
|
// EmitSignalDamageTaken();
|
||||||
|
// var tween = GetTree().CreateTween();
|
||||||
|
// tween.TweenProperty(this, "scale", new Vector2(1.4f, 0.6f), 0.15);
|
||||||
|
// tween.TweenProperty(this, "scale", new Vector2(1, 1), 0.4)
|
||||||
|
// .SetTrans(Tween.TransitionType.Cubic).SetEase(Tween.EaseType.Out);
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//public void HealAnimation()
|
||||||
|
//{
|
||||||
|
// EmitSignalHealed();
|
||||||
|
// var tween = GetTree().CreateTween();
|
||||||
|
// tween.TweenProperty(this, "scale", new Vector2(0.6f, 1.4f), 0.15);
|
||||||
|
// tween.TweenProperty(this, "scale", new Vector2(1, 1), 0.4)
|
||||||
|
// .SetTrans(Tween.TransitionType.Cubic).SetEase(Tween.EaseType.Out);
|
||||||
|
//}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
using Godot;
|
||||||
|
using System;
|
||||||
|
using Babushka.scripts.CSharp.Common.Fight;
|
||||||
|
|
||||||
|
public partial class NextRoomTrigger : Area2D
|
||||||
|
{
|
||||||
|
[Export] private int pathIndex;
|
||||||
|
|
||||||
|
public override void _EnterTree()
|
||||||
|
{
|
||||||
|
BodyEntered += _OnBodyEnter;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void _OnBodyEnter(Node2D other)
|
||||||
|
{
|
||||||
|
var fss = GetNode<FightSceneSwitcher>("%FightSceneSwitcher");
|
||||||
|
fss.SwitchRoom(pathIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://bryibv73x5iwr
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Babushka.scripts.CSharp.Common.Fight;
|
||||||
|
|
||||||
|
public class NoFightHappeningException() : Exception("No fight happening right now")
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://b2n37glcxm8wv
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
using System.Diagnostics;
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
namespace Babushka.scripts.CSharp.Common.Fight;
|
||||||
|
|
||||||
|
public partial class PathSetup : Node
|
||||||
|
{
|
||||||
|
[Export] private int pathId;
|
||||||
|
|
||||||
|
[ExportCategory("Variants")] [Export] private CanvasItem closedVariant;
|
||||||
|
[Export] private CanvasItem nextRoomVariant;
|
||||||
|
|
||||||
|
public override void _Ready()
|
||||||
|
{
|
||||||
|
SetupPathVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetupPathVariant()
|
||||||
|
{
|
||||||
|
Debug.Assert(FightWorld.Instance.currentRoom != null);
|
||||||
|
if (FightWorld.Instance.currentRoom.paths.TryGetValue(pathId, out var nextRoom))
|
||||||
|
{
|
||||||
|
ShowOnlyVariant(nextRoomVariant);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ShowOnlyVariant(closedVariant);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ShowOnlyVariant(CanvasItem variantToShow)
|
||||||
|
{
|
||||||
|
HideVariant(closedVariant);
|
||||||
|
HideVariant(nextRoomVariant);
|
||||||
|
ShowVariant(variantToShow);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ShowVariant(CanvasItem variant)
|
||||||
|
{
|
||||||
|
variant.Visible = true;
|
||||||
|
variant.ProcessMode = ProcessModeEnum.Always;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HideVariant(CanvasItem variant)
|
||||||
|
{
|
||||||
|
variant.Visible = false;
|
||||||
|
variant.ProcessMode = ProcessModeEnum.Disabled;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://dpkx2gbg7b5xh
|
||||||
@@ -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,14 @@
|
|||||||
|
using Godot;
|
||||||
|
|
||||||
|
namespace Babushka.scripts.CSharp.Common.Fight.UI;
|
||||||
|
|
||||||
|
[GlobalClass]
|
||||||
|
public partial class FighterHealthBarVisual : Node2D
|
||||||
|
{
|
||||||
|
[Export] private Label _tmpHealthLabel = null!;
|
||||||
|
|
||||||
|
public void UpdateHealth(int currentHealth, int maxHealth)
|
||||||
|
{
|
||||||
|
_tmpHealthLabel.Text = $"{currentHealth} / {maxHealth}";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://b2dx06p6i7pu0
|
||||||
@@ -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
|
||||||
+2
-2
@@ -4,6 +4,6 @@ public class FightAttack
|
|||||||
{
|
{
|
||||||
public int damage;
|
public int damage;
|
||||||
public bool needsSelectedTarget;
|
public bool needsSelectedTarget;
|
||||||
public Fighter? target;
|
public FighterVisual? target;
|
||||||
public Fighter attacker;
|
public FighterVisual attacker;
|
||||||
}
|
}
|
||||||
+2
-2
@@ -19,10 +19,10 @@ public partial class FightManager : Node
|
|||||||
|
|
||||||
public FightParty fightParty = new();
|
public FightParty fightParty = new();
|
||||||
|
|
||||||
public void StartFight(PackedScene[] enemies, FightInstance instance)
|
public void StartFight(PackedScene[] enemies, FightHappening happening)
|
||||||
{
|
{
|
||||||
GD.Print("Starting Fight");
|
GD.Print("Starting Fight");
|
||||||
instance.Start(fightParty, enemies);
|
//happening.Start(fightParty, enemies);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+2
-2
@@ -4,7 +4,7 @@ namespace Babushka.scripts.CSharp.Common.Fight;
|
|||||||
public partial class FightStarter : Node
|
public partial class FightStarter : Node
|
||||||
{
|
{
|
||||||
[Export(PropertyHint.ArrayType)] private PackedScene[] enemies;
|
[Export(PropertyHint.ArrayType)] private PackedScene[] enemies;
|
||||||
[Export] private FightInstance _fightInstance;
|
//[Export] private FightHappening _fightHappening;
|
||||||
[Export] private bool _once = true;
|
[Export] private bool _once = true;
|
||||||
private bool hasBeenStarted = false;
|
private bool hasBeenStarted = false;
|
||||||
|
|
||||||
@@ -14,6 +14,6 @@ public partial class FightStarter : Node
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
hasBeenStarted = true;
|
hasBeenStarted = true;
|
||||||
FightManager.Instance.StartFight(enemies, _fightInstance);
|
//FightManager.Instance.StartFight(enemies, _fightHappening);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
namespace Babushka.scripts.CSharp.Common.Util;
|
||||||
|
|
||||||
|
public class Variant<T1, T2>
|
||||||
|
{
|
||||||
|
private Type _type;
|
||||||
|
private Object _value;
|
||||||
|
|
||||||
|
public Type GetVariantType()
|
||||||
|
{
|
||||||
|
return _type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T GetValue<T>()
|
||||||
|
{
|
||||||
|
if (_type != typeof(T))
|
||||||
|
throw new ArgumentOutOfRangeException(
|
||||||
|
$"The Variant does not store a {typeof(T)}. The current type is {_type}");
|
||||||
|
|
||||||
|
return (T)_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetValue<T>(T value)
|
||||||
|
{
|
||||||
|
if (typeof(T1) != typeof(T) && typeof(T2) != typeof(T))
|
||||||
|
throw new ArgumentOutOfRangeException(
|
||||||
|
$"The Variant does not support type {typeof(T)}. Supported types are {typeof(T1)} and {typeof(T2)}");
|
||||||
|
|
||||||
|
_type = typeof(T);
|
||||||
|
_value = value!;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static implicit operator T1(Variant<T1, T2> v)
|
||||||
|
{
|
||||||
|
return v.GetValue<T1>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static implicit operator T2(Variant<T1, T2> v)
|
||||||
|
{
|
||||||
|
return v.GetValue<T2>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static implicit operator Variant<T1, T2>(T1 t)
|
||||||
|
{
|
||||||
|
return new Variant<T1, T2> { _type = typeof(T1), _value = t! };
|
||||||
|
}
|
||||||
|
|
||||||
|
public static implicit operator Variant<T1, T2>(T2 t)
|
||||||
|
{
|
||||||
|
return new Variant<T1, T2> { _type = typeof(T2), _value = t! };
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsType<T>()
|
||||||
|
{
|
||||||
|
if (typeof(T1) != typeof(T) && typeof(T2) != typeof(T))
|
||||||
|
throw new ArgumentOutOfRangeException(
|
||||||
|
$"The Variant does not support type {typeof(T)}. Supported types are {typeof(T1)} and {typeof(T2)}");
|
||||||
|
|
||||||
|
return _type == typeof(T);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://bxs7sn7j3vd0n
|
||||||
@@ -26,7 +26,6 @@ uniform float heightOffset : hint_range(0.0, 1.0);
|
|||||||
// With the offset value, you can if you want different moves for each asset. Just put a random value (1, 2, 3) in the editor. Don't forget to mark the material as unique if you use this
|
// With the offset value, you can if you want different moves for each asset. Just put a random value (1, 2, 3) in the editor. Don't forget to mark the material as unique if you use this
|
||||||
uniform float offset = 0;
|
uniform float offset = 0;
|
||||||
|
|
||||||
|
|
||||||
float getWind(vec2 vertex, vec2 uv, float time){
|
float getWind(vec2 vertex, vec2 uv, float time){
|
||||||
float diff = pow(maxStrength - minStrength, 2.0);
|
float diff = pow(maxStrength - minStrength, 2.0);
|
||||||
float strength = clamp(minStrength + diff + sin(time / interval) * diff, minStrength, maxStrength) * strengthScale;
|
float strength = clamp(minStrength + diff + sin(time / interval) * diff, minStrength, maxStrength) * strengthScale;
|
||||||
@@ -37,7 +36,7 @@ float getWind(vec2 vertex, vec2 uv, float time){
|
|||||||
|
|
||||||
void vertex() {
|
void vertex() {
|
||||||
vec4 pos = MODEL_MATRIX * vec4(0.0, 0.0, 0.0, 1.0);
|
vec4 pos = MODEL_MATRIX * vec4(0.0, 0.0, 0.0, 1.0);
|
||||||
float time = TIME * speed + sin(float(INSTANCE_ID) * offset);
|
//float time = TIME * speed + sin(float(INSTANCE_ID) * offset); // not working when moving...
|
||||||
//float time = TIME * speed + pos.x * pos.y ; not working when moving...
|
float time = (TIME + (pos.x * offset)) * speed;
|
||||||
VERTEX.x += getWind(VERTEX.xy, UV, time);
|
VERTEX.x += getWind(VERTEX.xy, UV, time);
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user