Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1edbe7aeb7 | |||
| 45d4b26b6a | |||
| 719b1fa800 | |||
| bd6432f568 | |||
| 224863f891 | |||
| 7d35c991f3 | |||
| ff8e4a85d2 | |||
| 96df233496 | |||
| 3f23f4471b | |||
| f2bf44bf9e | |||
| f0db6372e5 | |||
| 52f1560c48 | |||
| 8055381478 | |||
| daabcdc5ee | |||
| 2929c5dd25 | |||
| 9bebe1a44d | |||
| 06a270e916 | |||
| b621df5435 | |||
| 03dbc08293 |
@@ -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">
|
||||
<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/Text/@EntryValue">[Signal]
|
||||
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">
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AArea3D_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F8a54226fa2e1c9371a8091f24cfd744aef11fe6869527dc23b9b837623a29b9_003FArea3D_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AArray_00601_002Ecs_002Fl_003AC_0021_003FUsers_003FJonathan_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fe37dc1faf08a4d5ea030ad59bdf77522523400_003Fa3_003Fe272a3a7_003FArray_00601_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AAudioStreamPlayer2D_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003F848324b1c23114c3f5e8bbb5a42c4ade394c59a7a7a133a66b76581ca571_003FAudioStreamPlayer2D_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ABabushka_002Escripts_002ECSharp_002ECommon_002EFarming_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_002Fz_003A2_002D1/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ABabushka_002Escripts_002ECSharp_002ECommon_002EQuest_002EQuestListItemUi_005FScriptMethods_002Egenerated_002Ecs_002Fl_003AC_0021_003FUsers_003FJonathan_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003F48fad7e7f3c9e292b3fdbddf9d363f0d1752aa_003FBabushka_002Escripts_002ECSharp_002ECommon_002EQuest_002EQuestListItemUi_005FScriptMethods_002Egenerated_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ABabushka_002Escripts_002ECSharp_002ECommon_002EQuest_002EQuestManager_005FScriptSignals_002Egenerated_002Ecs_002Fl_003AC_0021_003FUsers_003FJonathan_003FAppData_003FLocal_003FTemp_003FSourceGeneratedDocuments_003F9509A9D00FD8A232B5E86A84_003FGodot_002ESourceGenerators_003FGodot_002ESourceGenerators_002EScriptSignalsGenerator_003FBabushka_002Escripts_002ECSharp_002ECommon_002EQuest_002EQuestManager_005FScriptSignals_002Egenerated_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ACanvasItem_002Ecs_002Fl_003AC_0021_003FUsers_003FJonathan_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003Fef7b819b226fab796d1dfe66d415dd7510bcac87675020ddb8f03a828e763_003FCanvasItem_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ACastHelpers_002Ecs_002Fl_003AC_0021_003FUsers_003FJonathan_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003F3c92637ae2e83da0a63791071c41eae291d594156062866d8621b7ed7245c_003FCastHelpers_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ACastHelpers_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fd111abf504bf42b5968a609b168fd093b2e200_003Fbb_003F1c116fcd_003FCastHelpers_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ACharacterBody2D_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003Fbba0bbd7a98ee58286e9484fbe86e01afff6232283f6efd3556eb7116453_003FCharacterBody2D_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ACount_002Ecs_002Fl_003AC_0021_003FUsers_003FJonathan_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003Ffe5a7cee5a1771b89077bd73292de84439b4f816799e2ad6c2615c6ff5bd748e_003FCount_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ADictionary_00602_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003Fhome_003Fjonathan_003F_002Econfig_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fe37dc1faf08a4d5ea030ad59bdf77522523400_003Fd4_003Fbd338aeb_003FDictionary_00602_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AEnumerable_002Ecs_002Fl_003AC_0021_003FUsers_003FJonathan_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F76fabf6f8acf4a0099cae0bcf8b218467f10_003F7e_003F28cee476_003FEnumerable_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AGD_005Fconstants_002Ecs_002Fl_003AC_0021_003FUsers_003FJonathan_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003F4ef0bac6437b6a9567d44f62ae567d854fa7b8513ef7139ef349b49768bc9df_003FGD_005Fconstants_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ANode_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003Ff1d69ec2da76ccf9bc8a75c8e0fdca9a7ba1adf8c8c9d5047e2fa5991c02eca_003FNode_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ANullable_002Ecs_002Fl_003AC_0021_003FUsers_003FJonathan_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003F5acc345db3c207bc9d886a36ff14867ef8d65557432172c2a42f19aeac04d1b_003FNullable_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AResourceLoader_002Ecs_002Fl_003AC_0021_003FUsers_003FJonathan_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003F9f4e8eb124d11f8219cb513a19bed22b2120ed29f9d6785ba56e3367b48d581_003FResourceLoader_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_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>
|
||||
@@ -9,7 +9,7 @@ var quest_resource: String
|
||||
func _execute() -> void:
|
||||
var resource = ResourceLoader.load(quest_resource)
|
||||
QuestManager.ChangeQuestStatus(resource,QuestEventUtils.QuestStatus.AVAILABLE)
|
||||
QuestManager.SetFollowQuest(resource)
|
||||
QuestManager.SetActiveQuest(resource)
|
||||
finish() # called to continue with the next event
|
||||
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ var quest_resource: String
|
||||
func _execute() -> void:
|
||||
var resource = ResourceLoader.load(quest_resource)
|
||||
QuestManager.ChangeQuestStatus(resource,QuestEventUtils.QuestStatus.DONE)
|
||||
QuestManager.SetFollowQuest(null)
|
||||
QuestManager.SetActiveQuest(null)
|
||||
finish() # called to continue with the next event
|
||||
|
||||
|
||||
|
||||
@@ -23,9 +23,9 @@ func _execute() -> void:
|
||||
|
||||
var result: bool
|
||||
if compare_status == QuestEventUtils.QuestStatusOrActive.ACTIVE:
|
||||
result = QuestManager.GetFollowQuest() == resource
|
||||
result = QuestManager.GetActiveQuest() == resource
|
||||
elif compare_status == QuestEventUtils.QuestStatusOrActive.NOT_ACTIVE:
|
||||
result = QuestManager.GetFollowQuest() != resource
|
||||
result = QuestManager.GetActiveQuest() != resource
|
||||
else:
|
||||
result = QuestManager.GetQuestStatus(resource).status == compare_status
|
||||
|
||||
|
||||
@@ -1,510 +0,0 @@
|
||||
{
|
||||
"swagger": "2.0",
|
||||
"info": {
|
||||
"title": "LanguageTool API",
|
||||
"description": "Check texts for style and grammar issues with <a href='https://languagetool.org'>LanguageTool</a>. Please consider the following default limitations:<ul><li>your daily request limit depending on <a href='https://languagetool.org/editor/settings/access-tokens'>your plan</a> <li>maximum number of requests per minute: 20 (free) / 80 (Premium) <li>maximum number of characters per minute: 75,000 (free) / 300,000 (Premium) <li>maximum number of characters per request: 20,000 (free) / 60,000 (Premium) <li>for the free version, also consider the <a href='https://dev.languagetool.org/public-http-api'>limitations documented here</a> <li><b>Note:</b> any parameters or outputs not part of this documentation are internal and must not be relied on</ul> Need more generous limits? Just <a href='https://languagetool.org/proofreading-api'>contact us</a>.",
|
||||
"version": "1.1.2"
|
||||
},
|
||||
"host": "api.languagetoolplus.com",
|
||||
"schemes": [
|
||||
"https"
|
||||
],
|
||||
"basePath": "/v2",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"paths": {
|
||||
"/check": {
|
||||
"post": {
|
||||
"summary": "Check a text",
|
||||
"description": "The main feature - check a text with LanguageTool for possible style and grammar issues.",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "text",
|
||||
"in": "formData",
|
||||
"type": "string",
|
||||
"description": "The text to be checked. This or 'data' is required.",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"name": "data",
|
||||
"in": "formData",
|
||||
"type": "string",
|
||||
"description": "The text to be checked, given as a JSON document that specifies what's text and what's markup. This or 'text' is required. Markup will be ignored when looking for errors. Example text: <pre>A <b>test</b></pre>JSON for the example text: <pre>{\"annotation\":[\n {\"text\": \"A \"},\n {\"markup\": \"<b>\"},\n {\"text\": \"test\"},\n {\"markup\": \"</b>\"}\n]}</pre> <p>If you have markup that should be interpreted as whitespace, like <tt><p></tt> in HTML, you can have it interpreted like this: <pre>{\"markup\": \"<p>\", \"interpretAs\": \"\\n\\n\"}</pre><p>The 'data' feature is not limited to HTML or XML, it can be used for any kind of markup. Entities will need to be expanded in this input.",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"name": "language",
|
||||
"in": "formData",
|
||||
"type": "string",
|
||||
"description": "A language code like `en-US`, `de-DE`, `fr`, or `auto` to guess the language automatically (see `preferredVariants` below). For languages with variants (English, German, Portuguese) spell checking will only be activated when you specify the variant, e.g. `en-GB` instead of just `en`.",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "username",
|
||||
"in": "formData",
|
||||
"type": "string",
|
||||
"description": "Set to get Premium API access: Your username/email as used to log in at languagetool.org."
|
||||
},
|
||||
{
|
||||
"name": "apiKey",
|
||||
"in": "formData",
|
||||
"type": "string",
|
||||
"format": "password",
|
||||
"description": "Set to get Premium API access: <a target='_blank' href='https://languagetool.org/editor/settings/access-tokens'>your API key</a>"
|
||||
},
|
||||
{
|
||||
"name": "dicts",
|
||||
"in": "formData",
|
||||
"type": "string",
|
||||
"description": "Comma-separated list of dictionaries to include words from; uses special default dictionary if this is unset"
|
||||
},
|
||||
{
|
||||
"name": "motherTongue",
|
||||
"in": "formData",
|
||||
"type": "string",
|
||||
"description": "A language code of the user's native language, enabling false friends checks for some language pairs."
|
||||
},
|
||||
{
|
||||
"name": "preferredVariants",
|
||||
"in": "formData",
|
||||
"type": "string",
|
||||
"description": "Comma-separated list of preferred language variants. The language detector used with `language=auto` can detect e.g. English, but it cannot decide whether British English or American English is used. Thus this parameter can be used to specify the preferred variants like `en-GB` and `de-AT`. Only available with `language=auto`. You should set variants for at least German and English, as otherwise the spell checking will not work for those, as no spelling dictionary can be selected for just `en` or `de`."
|
||||
},
|
||||
{
|
||||
"name": "enabledRules",
|
||||
"in": "formData",
|
||||
"type": "string",
|
||||
"description": "IDs of rules to be enabled, comma-separated. Note that 'level' still applies, so the rule won't run unless 'level' is set to a level that activates the rule."
|
||||
},
|
||||
{
|
||||
"name": "disabledRules",
|
||||
"in": "formData",
|
||||
"type": "string",
|
||||
"description": "IDs of rules to be disabled, comma-separated"
|
||||
},
|
||||
{
|
||||
"name": "enabledCategories",
|
||||
"in": "formData",
|
||||
"type": "string",
|
||||
"description": "IDs of categories to be enabled, comma-separated"
|
||||
},
|
||||
{
|
||||
"name": "disabledCategories",
|
||||
"in": "formData",
|
||||
"type": "string",
|
||||
"description": "IDs of categories to be disabled, comma-separated"
|
||||
},
|
||||
{
|
||||
"name": "enabledOnly",
|
||||
"in": "formData",
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "If true, only the rules and categories whose IDs are specified with `enabledRules` or `enabledCategories` are enabled."
|
||||
},
|
||||
{
|
||||
"name": "level",
|
||||
"in": "formData",
|
||||
"type": "string",
|
||||
"enum": ["default", "picky"],
|
||||
"description": "If set to `picky`, additional rules will be activated, i.e. rules that you might only find useful when checking formal text."
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "the result of checking the text",
|
||||
"schema": {
|
||||
"properties": {
|
||||
"software": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name",
|
||||
"version",
|
||||
"buildDate",
|
||||
"apiVersion"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Usually 'LanguageTool'."
|
||||
},
|
||||
"version": {
|
||||
"type": "string",
|
||||
"description": "A version string like '3.3' or '3.4-SNAPSHOT'."
|
||||
},
|
||||
"buildDate": {
|
||||
"type": "string",
|
||||
"description": "Date when the software was built, e.g. '2016-05-25'."
|
||||
},
|
||||
"apiVersion": {
|
||||
"type": "integer",
|
||||
"description": "Version of this API response. We don't expect to make incompatible changes, so this can also be increased for newly added fields."
|
||||
},
|
||||
"status": {
|
||||
"type": "string",
|
||||
"description": "An optional warning, e.g. when the API format is not stable."
|
||||
},
|
||||
"premium": {
|
||||
"type": "boolean",
|
||||
"description": "true if you're using a Premium account with all the premium text checks (since LanguageTool 4.2)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"language": {
|
||||
"type": "object",
|
||||
"description": "The language used for checking the text.",
|
||||
"required": [
|
||||
"name",
|
||||
"code",
|
||||
"detectedLanguage"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Language name like 'French' or 'English (US)'."
|
||||
},
|
||||
"code": {
|
||||
"type": "string",
|
||||
"description": "ISO 639-1 code like 'en', 'en-US', or 'ca-ES-valencia'"
|
||||
},
|
||||
"detectedLanguage": {
|
||||
"type": "object",
|
||||
"description": "The automatically detected text language (might be different from the language actually used for checking).",
|
||||
"required": [
|
||||
"name",
|
||||
"code"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Language name like 'French' or 'English (US)'."
|
||||
},
|
||||
"code": {
|
||||
"type": "string",
|
||||
"description": "ISO 639-1 code like 'en', 'en-US', or 'ca-ES-valencia'."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"matches": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"message",
|
||||
"offset",
|
||||
"length",
|
||||
"replacements",
|
||||
"context",
|
||||
"sentence"
|
||||
],
|
||||
"properties": {
|
||||
"message": {
|
||||
"type": "string",
|
||||
"description": "Message about the error displayed to the user."
|
||||
},
|
||||
"shortMessage": {
|
||||
"type": "string",
|
||||
"description": "An optional shorter version of 'message'."
|
||||
},
|
||||
"offset": {
|
||||
"type": "integer",
|
||||
"description": "The 0-based character offset of the error in the text."
|
||||
},
|
||||
"length": {
|
||||
"type": "integer",
|
||||
"description": "The length of the error in characters."
|
||||
},
|
||||
"replacements": {
|
||||
"type": "array",
|
||||
"description": "Replacements that might correct the error. The array can be empty, in this case there is no suggested replacement.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"value": {
|
||||
"type": "string",
|
||||
"description": "the replacement string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"context": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"text",
|
||||
"offset",
|
||||
"length"
|
||||
],
|
||||
"properties": {
|
||||
"text": {
|
||||
"type": "string",
|
||||
"description": "Context of the error, i.e. the error and some text to the left and to the left."
|
||||
},
|
||||
"offset": {
|
||||
"type": "integer",
|
||||
"description": "The 0-based character offset of the error in the context text."
|
||||
},
|
||||
"length": {
|
||||
"type": "integer",
|
||||
"description": "The length of the error in characters in the context."
|
||||
}
|
||||
}
|
||||
},
|
||||
"sentence": {
|
||||
"type": "string",
|
||||
"description": "The sentence the error occurred in (since LanguageTool 4.0 or later)"
|
||||
},
|
||||
"rule": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"id",
|
||||
"description",
|
||||
"category"
|
||||
],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"description": "An rule's identifier that's unique for this language."
|
||||
},
|
||||
"subId": {
|
||||
"type": "string",
|
||||
"description": "An optional sub identifier of the rule, used when several rules are grouped."
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"urls": {
|
||||
"type": "array",
|
||||
"description": "An optional array of URLs with a more detailed description of the error.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"value": {
|
||||
"type": "string",
|
||||
"description": "the URL"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"issueType": {
|
||||
"type": "string",
|
||||
"description": "The <a href=\"http://www.w3.org/International/multilingualweb/lt/drafts/its20/its20.html#lqissue-typevalues\">Localization Quality Issue Type</a>. This is not defined for all languages, in which case it will always be 'Uncategorized'."
|
||||
},
|
||||
"category": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"description": "A category's identifier that's unique for this language."
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "A short description of the category."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/languages": {
|
||||
"get": {
|
||||
"summary": "Get a list of supported languages.",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "An array of language objects.",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name",
|
||||
"code",
|
||||
"longCode"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "a language name like 'French' or 'English (Australia)'"
|
||||
},
|
||||
"code": {
|
||||
"type": "string",
|
||||
"description": "a language code like 'en'"
|
||||
},
|
||||
"longCode": {
|
||||
"type": "string",
|
||||
"description": "a language code like 'en-US' or 'ca-ES-valencia'"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/words": {
|
||||
"get": {
|
||||
"summary": "List words in dictionaries",
|
||||
"description": "List words in the user's personal dictionaries.",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "offset",
|
||||
"in": "query",
|
||||
"type": "integer",
|
||||
"description": "Offset of where to start in the list of words. Defaults to 0."
|
||||
},
|
||||
{
|
||||
"name": "limit",
|
||||
"in": "query",
|
||||
"type": "integer",
|
||||
"description": "Maximum number of words to return. Defaults to 10."
|
||||
},
|
||||
{
|
||||
"name": "username",
|
||||
"in": "query",
|
||||
"type": "string",
|
||||
"description": "Your username as used to log in at languagetool.org.",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "apiKey",
|
||||
"in": "query",
|
||||
"type": "string",
|
||||
"format": "password",
|
||||
"description": "<a target='_blank' href='https://languagetool.org/editor/settings/access-tokens'>Your API key</a>",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "dicts",
|
||||
"in": "query",
|
||||
"type": "string",
|
||||
"description": "Comma-separated list of dictionaries to include words from; uses special default dictionary if this is unset"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "the user's words from the given user dictionaries",
|
||||
"schema": {
|
||||
"properties": {
|
||||
"words": {
|
||||
"type": "array",
|
||||
"description": "array of words",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/words/add": {
|
||||
"post": {
|
||||
"summary": "Add word to a dictionary",
|
||||
"description": "Add a word to one of the user's personal dictionaries. Please note that this feature is considered to be used for personal dictionaries which must not contain more than 500 words. If this is an issue for you, please contact us.",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "word",
|
||||
"in": "formData",
|
||||
"type": "string",
|
||||
"description": "The word to be added. Must not be a phrase, i.e. cannot contain white space. The word is added to a global dictionary that applies to all languages.",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "username",
|
||||
"in": "formData",
|
||||
"type": "string",
|
||||
"description": "Your username as used to log in at languagetool.org.",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "apiKey",
|
||||
"in": "formData",
|
||||
"type": "string",
|
||||
"format": "password",
|
||||
"description": "<a target='_blank' href='https://languagetool.org/editor/settings/access-tokens'>Your API key</a>",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "dict",
|
||||
"in": "formData",
|
||||
"type": "string",
|
||||
"description": "Name of the dictionary to add the word to; non-existent dictionaries are created after calling this; if unset, adds to special default dictionary"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "the result of adding the word",
|
||||
"schema": {
|
||||
"properties": {
|
||||
"added": {
|
||||
"type": "boolean",
|
||||
"description": "true if the word has been added. false means the word hasn't been added because it had been added before."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/words/delete": {
|
||||
"post": {
|
||||
"summary": "Remove word from a dictionary",
|
||||
"description": "Remove a word from one of the user's personal dictionaries.",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "word",
|
||||
"in": "formData",
|
||||
"type": "string",
|
||||
"description": "The word to be removed.",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "username",
|
||||
"in": "formData",
|
||||
"type": "string",
|
||||
"description": "Your username as used to log in at languagetool.org.",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "apiKey",
|
||||
"in": "formData",
|
||||
"type": "string",
|
||||
"format": "password",
|
||||
"description": "<a target='_blank' href='https://languagetool.org/editor/settings/access-tokens'>Your API key</a>",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "dict",
|
||||
"in": "formData",
|
||||
"type": "string",
|
||||
"description": "Name of the dictionary to remove the word from; if the dictionary is empty upon calling this, it is deleted; if unset, removes from special default dictionary"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "the result of removing the word",
|
||||
"schema": {
|
||||
"properties": {
|
||||
"deleted": {
|
||||
"type": "boolean",
|
||||
"description": "true if the word has been removed. false means the word hasn't been removed because it was not in the dictionary."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
@tool
|
||||
extends EditorPlugin
|
||||
|
||||
var plugin: LanguagetToolPlugin
|
||||
|
||||
func _enter_tree() -> void:
|
||||
plugin = LanguagetToolPlugin.new()
|
||||
add_child(plugin)
|
||||
|
||||
EditorInterface.get_inspector().edited_object_changed.connect(_inspector_edited_object_changed)
|
||||
|
||||
func _inspector_edited_object_changed():
|
||||
plugin.check_new_inspector();
|
||||
|
||||
|
||||
|
||||
func _exit_tree() -> void:
|
||||
pass
|
||||
@@ -1 +0,0 @@
|
||||
uid://fm32qkudo8sp
|
||||
@@ -1,7 +0,0 @@
|
||||
[plugin]
|
||||
|
||||
name="LanguageTool"
|
||||
description="Check texts for style and grammar issues with LanguageTool. "
|
||||
author="Jonathan @ Cozy Raven Interactive"
|
||||
version=""
|
||||
script="languagetool.gd"
|
||||
@@ -1,110 +0,0 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://dxalawvo2ji7p"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://dkyiuvuc2w2xc" path="res://addons/languagetool/scripts/language_tool_correction_overlay_references.gd" id="1_rh5c2"]
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_hdqxg"]
|
||||
bg_color = Color(0.145098, 0.145098, 0.145098, 1)
|
||||
border_width_left = 2
|
||||
border_width_top = 2
|
||||
border_width_right = 2
|
||||
border_width_bottom = 2
|
||||
border_color = Color(0.0784314, 0.0784314, 0.0784314, 1)
|
||||
corner_radius_top_left = 5
|
||||
corner_radius_top_right = 5
|
||||
corner_radius_bottom_right = 5
|
||||
corner_radius_bottom_left = 5
|
||||
|
||||
[node name="CorrectionOverlay" type="VBoxContainer"]
|
||||
offset_right = 408.0
|
||||
offset_bottom = 181.0
|
||||
size_flags_horizontal = 0
|
||||
size_flags_vertical = 0
|
||||
script = ExtResource("1_rh5c2")
|
||||
|
||||
[node name="MarginContainer" type="MarginContainer" parent="."]
|
||||
layout_mode = 2
|
||||
theme_override_constants/margin_left = 15
|
||||
theme_override_constants/margin_top = 15
|
||||
theme_override_constants/margin_right = 15
|
||||
theme_override_constants/margin_bottom = 15
|
||||
|
||||
[node name="PanelContainer" type="PanelContainer" parent="MarginContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_styles/panel = SubResource("StyleBoxFlat_hdqxg")
|
||||
|
||||
[node name="MarginContainer" type="MarginContainer" parent="MarginContainer/PanelContainer"]
|
||||
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="VBoxContainer" type="VBoxContainer" parent="MarginContainer/PanelContainer/MarginContainer"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/PanelContainer/MarginContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="CategoryLabel" type="Label" parent="MarginContainer/PanelContainer/MarginContainer/VBoxContainer/HBoxContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
theme_override_font_sizes/font_size = 11
|
||||
text = "Rechtschreibung"
|
||||
autowrap_mode = 3
|
||||
|
||||
[node name="CloseButton" type="Button" parent="MarginContainer/PanelContainer/MarginContainer/VBoxContainer/HBoxContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 11
|
||||
text = "X"
|
||||
|
||||
[node name="Spacer" type="Control" parent="MarginContainer/PanelContainer/MarginContainer/VBoxContainer"]
|
||||
custom_minimum_size = Vector2(0, 4)
|
||||
layout_mode = 2
|
||||
|
||||
[node name="DescriptionLabel" type="Label" parent="MarginContainer/PanelContainer/MarginContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/paragraph_spacing = 0
|
||||
text = "Ensure spelling is correct"
|
||||
autowrap_mode = 3
|
||||
|
||||
[node name="Spacer2" type="Control" parent="MarginContainer/PanelContainer/MarginContainer/VBoxContainer"]
|
||||
custom_minimum_size = Vector2(0, 2)
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Replacements" type="HFlowContainer" parent="MarginContainer/PanelContainer/MarginContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Button" type="Button" parent="MarginContainer/PanelContainer/MarginContainer/VBoxContainer/Replacements"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 0
|
||||
text = "Test 1"
|
||||
|
||||
[node name="Button2" type="Button" parent="MarginContainer/PanelContainer/MarginContainer/VBoxContainer/Replacements"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 0
|
||||
text = "Test 1"
|
||||
|
||||
[node name="Button3" type="Button" parent="MarginContainer/PanelContainer/MarginContainer/VBoxContainer/Replacements"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 0
|
||||
text = "Test 1"
|
||||
|
||||
[node name="Button4" type="Button" parent="MarginContainer/PanelContainer/MarginContainer/VBoxContainer/Replacements"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 0
|
||||
text = "Hello world!!!"
|
||||
|
||||
[node name="Button5" type="Button" parent="MarginContainer/PanelContainer/MarginContainer/VBoxContainer/Replacements"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 0
|
||||
text = "Test 1"
|
||||
|
||||
[node name="Button6" type="Button" parent="MarginContainer/PanelContainer/MarginContainer/VBoxContainer/Replacements"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 0
|
||||
text = "Test 1"
|
||||
|
||||
[node name="Button7" type="Button" parent="MarginContainer/PanelContainer/MarginContainer/VBoxContainer/Replacements"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 0
|
||||
text = "Test 1"
|
||||
@@ -1,41 +0,0 @@
|
||||
@tool
|
||||
extends Node
|
||||
|
||||
class_name LanguageToolCorrectionOverlay
|
||||
|
||||
const CORRECTION_OVERLAY = preload("res://addons/languagetool/scenes/correction_overlay.tscn")
|
||||
var instantiatedOverlay: LanguageToolCorrectionOverlayReferences
|
||||
|
||||
func _enter_tree() -> void:
|
||||
instantiatedOverlay = CORRECTION_OVERLAY.instantiate()
|
||||
add_child(instantiatedOverlay)
|
||||
hideOverlay()
|
||||
|
||||
func _ready():
|
||||
instantiatedOverlay.close_button.pressed.connect(hideOverlay)
|
||||
|
||||
func _exit_tree() -> void:
|
||||
pass
|
||||
|
||||
func hideOverlay():
|
||||
instantiatedOverlay.hide()
|
||||
|
||||
func showOverlay(position:Vector2, width: float, _match:LanguageToolApiWrapper.LanguageToolCheckResponse.Match, replacement_clicked : Callable):
|
||||
#print(instantiatedOverlay.test)
|
||||
instantiatedOverlay.show()
|
||||
instantiatedOverlay.global_position = position
|
||||
instantiatedOverlay.size = Vector2(0,0)
|
||||
instantiatedOverlay.custom_minimum_size = Vector2(width, 0)
|
||||
instantiatedOverlay.category_label.text = _match.rule.category.name
|
||||
instantiatedOverlay.description_label.text = _match.message
|
||||
|
||||
for c in instantiatedOverlay.replacements.get_children():
|
||||
c.free()
|
||||
|
||||
for r in _match.replacements:
|
||||
var replacementButton = Button.new()
|
||||
replacementButton.text = r
|
||||
replacementButton.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
replacementButton.pressed.connect(func():replacement_clicked.call(r))
|
||||
instantiatedOverlay.replacements.add_child(replacementButton)
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
uid://ct2t8rr000prq
|
||||
@@ -1,9 +0,0 @@
|
||||
@tool
|
||||
extends VBoxContainer
|
||||
|
||||
class_name LanguageToolCorrectionOverlayReferences
|
||||
|
||||
@onready var category_label: Label = $MarginContainer/PanelContainer/MarginContainer/VBoxContainer/HBoxContainer/CategoryLabel
|
||||
@onready var description_label: Label = $MarginContainer/PanelContainer/MarginContainer/VBoxContainer/DescriptionLabel
|
||||
@onready var replacements: HFlowContainer = $MarginContainer/PanelContainer/MarginContainer/VBoxContainer/Replacements
|
||||
@onready var close_button: Button = $MarginContainer/PanelContainer/MarginContainer/VBoxContainer/HBoxContainer/CloseButton
|
||||
@@ -1 +0,0 @@
|
||||
uid://dkyiuvuc2w2xc
|
||||
@@ -1,32 +0,0 @@
|
||||
extends SyntaxHighlighter
|
||||
|
||||
class_name LanguageToolErrorSyntaxHighlighter
|
||||
|
||||
var check:LanguageToolApiWrapper.LanguageToolCheckResponse
|
||||
|
||||
func _init(check:LanguageToolApiWrapper.LanguageToolCheckResponse):
|
||||
self.check = check
|
||||
|
||||
func _get_line_syntax_highlighting(line: int) -> Dictionary:
|
||||
var normalColor = EditorInterface.get_base_control().get_theme_color("font_color", "Editor")
|
||||
var errorColor = EditorInterface.get_base_control().get_theme_color("error_color", "Editor")
|
||||
var warningColor = EditorInterface.get_base_control().get_theme_color("warning_color", "Editor")
|
||||
var successColor = EditorInterface.get_base_control().get_theme_color("success_color", "Editor")
|
||||
|
||||
var retval = {}
|
||||
|
||||
for m:LanguageToolApiWrapper.LanguageToolCheckResponse.Match in check.matches:
|
||||
var row_column = LanguageToolUtils.offset_to_row_column(m.offset,get_text_edit().text)
|
||||
if row_column[0] != line:
|
||||
continue
|
||||
match m.rule.category.id:
|
||||
"GRAMMAR":
|
||||
retval[row_column[1]] = {"color":warningColor}
|
||||
"TYPOS":
|
||||
retval[row_column[1]] = {"color":errorColor}
|
||||
_:
|
||||
retval[row_column[1]] = {"color":successColor}
|
||||
|
||||
retval[row_column[1]+m.length] = {"color":normalColor}
|
||||
|
||||
return retval
|
||||
@@ -1 +0,0 @@
|
||||
uid://csxcr0bsetagc
|
||||
@@ -1,112 +0,0 @@
|
||||
extends Node
|
||||
|
||||
class_name LanguagetToolPlugin
|
||||
|
||||
var api: LanguageToolApiWrapper
|
||||
var overlay: LanguageToolCorrectionOverlay
|
||||
|
||||
var checkDict: Dictionary[String,LanguageToolApiWrapper.LanguageToolCheckResponse] = {}
|
||||
|
||||
func _enter_tree() -> void:
|
||||
api = LanguageToolApiWrapper.new()
|
||||
add_child(api)
|
||||
overlay = LanguageToolCorrectionOverlay.new()
|
||||
add_child(overlay)
|
||||
|
||||
func _exit_tree() -> void:
|
||||
pass
|
||||
|
||||
func check_new_inspector():
|
||||
overlay.hideOverlay()
|
||||
|
||||
var textEdits: Array[TextEdit] = _find_multiline_text_edits()
|
||||
for te: TextEdit in textEdits:
|
||||
te.text_changed.connect(func():_on_text_changed(te))
|
||||
te.focus_exited.connect(func():_on_focus_lost(te))
|
||||
te.caret_changed.connect(func():_on_caret_changed(te))
|
||||
|
||||
_check_text(te)
|
||||
_mark_errors_in_text(te)
|
||||
|
||||
|
||||
func _on_text_changed(textEdit: TextEdit):
|
||||
_mark_errors_in_text(textEdit)
|
||||
overlay.hideOverlay()
|
||||
|
||||
func _on_focus_lost(textEdit: TextEdit):
|
||||
_check_text(textEdit)
|
||||
_mark_errors_in_text(textEdit)
|
||||
|
||||
func _on_caret_changed(textEdit: TextEdit):
|
||||
if(!checkDict.has(textEdit.text)):
|
||||
return
|
||||
var check: LanguageToolApiWrapper.LanguageToolCheckResponse = checkDict[textEdit.text]
|
||||
|
||||
# find match at caret
|
||||
var caret_offset:int = LanguageToolUtils.row_column_to_offset(textEdit.get_caret_line(), textEdit.get_caret_column(),textEdit.text)
|
||||
var _match:LanguageToolApiWrapper.LanguageToolCheckResponse.Match = null
|
||||
for m in check.matches:
|
||||
if m.offset <= caret_offset and m.offset + m.length >= caret_offset:
|
||||
_match = m
|
||||
break
|
||||
|
||||
if _match != null:
|
||||
var edit_global_rect = textEdit.get_global_rect()
|
||||
overlay.showOverlay(
|
||||
edit_global_rect.position + Vector2(0,edit_global_rect.size.y),
|
||||
edit_global_rect.size.x,
|
||||
_match,
|
||||
func(newText):_apply_text_change(textEdit,newText,_match))
|
||||
else:
|
||||
overlay.hideOverlay()
|
||||
pass
|
||||
|
||||
func _check_text(textEdit: TextEdit):
|
||||
if textEdit.text == "":
|
||||
return
|
||||
|
||||
if checkDict.has(textEdit.text):
|
||||
return
|
||||
|
||||
var response = api.check(textEdit.text)
|
||||
checkDict[textEdit.text] = response
|
||||
|
||||
|
||||
func _mark_errors_in_text(textEdit: TextEdit):
|
||||
if(!checkDict.has(textEdit.text)):
|
||||
textEdit.syntax_highlighter=null
|
||||
return
|
||||
var check: LanguageToolApiWrapper.LanguageToolCheckResponse = checkDict[textEdit.text]
|
||||
textEdit.syntax_highlighter = LanguageToolErrorSyntaxHighlighter.new(check)
|
||||
|
||||
func _apply_text_change(textEdit:TextEdit, newText: String, _match:LanguageToolApiWrapper.LanguageToolCheckResponse.Match):
|
||||
var oldText = textEdit.text
|
||||
var removedOldWord = oldText.erase(_match.offset,_match.length)
|
||||
var newWordInserted = removedOldWord.insert(_match.offset,newText)
|
||||
textEdit.text = newWordInserted
|
||||
textEdit.text_changed.emit()
|
||||
overlay.hideOverlay()
|
||||
_check_text(textEdit)
|
||||
_mark_errors_in_text(textEdit)
|
||||
|
||||
func _find_multiline_text_edits()->Array[TextEdit]:
|
||||
var multilinteTexts:Array[Node] = _find_recursive(
|
||||
EditorInterface.get_inspector().get_child(0).get_child(2),
|
||||
"EditorPropertyMultilineText");
|
||||
|
||||
var textEditors:Array[TextEdit]
|
||||
textEditors.assign( multilinteTexts.map(func(c):return c.get_child(0).get_child(0) as TextEdit))
|
||||
|
||||
return textEditors
|
||||
|
||||
func _find_recursive(node: Node, type: Variant) -> Array[Node]:
|
||||
if type is String:
|
||||
if node.get_class() == type:
|
||||
return [node]
|
||||
elif is_instance_of(node, type):
|
||||
return [node]
|
||||
|
||||
var retval: Array[Node] = []
|
||||
for child in node.get_children():
|
||||
retval.append_array(_find_recursive(child, type))
|
||||
return retval
|
||||
@@ -1 +0,0 @@
|
||||
uid://bi8yv26eglkso
|
||||
@@ -1,32 +0,0 @@
|
||||
@tool
|
||||
extends Object
|
||||
|
||||
class_name LanguageToolUtils
|
||||
|
||||
static func offset_to_row_column(offset:int, text:String)->Vector2i:
|
||||
var row:int = 0
|
||||
var column:int = 0
|
||||
|
||||
if offset > text.length():
|
||||
return Vector2i(-1,-1)
|
||||
|
||||
for i in offset:
|
||||
if text[i] == "\n":
|
||||
row+=1
|
||||
column = 0
|
||||
else:
|
||||
column+=1
|
||||
return Vector2i(row, column)
|
||||
|
||||
static func row_column_to_offset(row:int, column:int, text:String) -> int:
|
||||
var current_row:int = 0
|
||||
var current_column:int = 0
|
||||
for i in text.length():
|
||||
if current_row == row and current_column == column:
|
||||
return i
|
||||
if text[i] == "\n":
|
||||
current_row += 1
|
||||
current_column = 0
|
||||
else:
|
||||
current_column += 1
|
||||
return -1
|
||||
@@ -1 +0,0 @@
|
||||
uid://q01v4f8pfgfe
|
||||
@@ -1,211 +0,0 @@
|
||||
@tool
|
||||
class_name LanguageToolApiWrapper
|
||||
extends Node
|
||||
|
||||
const BASE_URL := "https://api.languagetoolplus.com/v2"
|
||||
|
||||
func _make_request(endpoint: String, method: HTTPClient.Method = HTTPClient.METHOD_GET, data: Dictionary = {}, headers: Dictionary = {}):
|
||||
var url = BASE_URL + endpoint
|
||||
var scheme_split = url.split("://")
|
||||
var scheme = scheme_split[0]
|
||||
var rest = scheme_split[1]
|
||||
var host_and_path = rest.split("/", false, 1)
|
||||
var host = host_and_path[0]
|
||||
var path = "/" + host_and_path[1] if host_and_path.size() > 1 else "/"
|
||||
var port = 443 if scheme == "https" else 80
|
||||
|
||||
var client = HTTPClient.new()
|
||||
var tlsOptions: TLSOptions = (TLSOptions.client() if scheme == "https" else null)
|
||||
var err = client.connect_to_host(host, port, tlsOptions)
|
||||
if err != OK:
|
||||
push_error("Failed to connect to host: " + str(err))
|
||||
return null
|
||||
|
||||
while client.get_status() in [HTTPClient.STATUS_CONNECTING, HTTPClient.STATUS_RESOLVING]:
|
||||
client.poll()
|
||||
OS.delay_msec(10)
|
||||
|
||||
var header_array = []
|
||||
for k in headers.keys():
|
||||
header_array.append(str(k) + ": " + str(headers[k]))
|
||||
|
||||
var body = ""
|
||||
if method == HTTPClient.METHOD_POST:
|
||||
body = ""
|
||||
if data.size() > 0:
|
||||
body = client.query_string_from_dict(data)
|
||||
header_array.append("Content-Type: application/x-www-form-urlencoded")
|
||||
header_array.append("Content-Length: " + str(body.length()))
|
||||
client.request(HTTPClient.METHOD_POST, path, header_array, body)
|
||||
else:
|
||||
if data.size() > 0:
|
||||
path += "?" + client.query_string_from_dict(data)
|
||||
client.request(HTTPClient.METHOD_GET, path, header_array)
|
||||
|
||||
while client.get_status() == HTTPClient.STATUS_REQUESTING:
|
||||
client.poll()
|
||||
OS.delay_msec(10)
|
||||
|
||||
var response = ""
|
||||
while client.get_status() == HTTPClient.STATUS_BODY or client.has_response():
|
||||
client.poll()
|
||||
var chunk = client.read_response_body_chunk()
|
||||
if chunk.size() == 0:
|
||||
break
|
||||
response += chunk.get_string_from_utf8()
|
||||
OS.delay_msec(10)
|
||||
|
||||
var resp_code = client.get_response_code()
|
||||
if resp_code != 200:
|
||||
push_error("HTTP error: " + str(resp_code) + "\\n" + response)
|
||||
return null
|
||||
|
||||
var json = JSON.new()
|
||||
var json_err = json.parse(response)
|
||||
if json_err != OK:
|
||||
push_error("JSON parse error: " + str(json_err) + "\\n" + response)
|
||||
return null
|
||||
return json.get_data()
|
||||
|
||||
func check(text: String, language: String = "auto", opts: Dictionary = {}) -> LanguageToolCheckResponse:
|
||||
var data = {
|
||||
"text": text,
|
||||
"language": language
|
||||
}
|
||||
for k in opts.keys():
|
||||
data[k] = opts[k]
|
||||
print("Checking text: "+text)
|
||||
return LanguageToolCheckResponse.new(_make_request("/check", HTTPClient.METHOD_POST, data))
|
||||
|
||||
func get_languages():
|
||||
return _make_request("/languages", HTTPClient.METHOD_GET)
|
||||
|
||||
func list_words(username: String, apiKey: String, offset: int = 0, limit: int = 10, dicts: String = ""):
|
||||
var data = {
|
||||
"username": username,
|
||||
"apiKey": apiKey,
|
||||
"offset": offset,
|
||||
"limit": limit
|
||||
}
|
||||
if dicts != "":
|
||||
data["dicts"] = dicts
|
||||
return _make_request("/words", HTTPClient.METHOD_GET, data)
|
||||
|
||||
func add_word(word: String, username: String, apiKey: String, dict: String = ""):
|
||||
var data = {
|
||||
"word": word,
|
||||
"username": username,
|
||||
"apiKey": apiKey
|
||||
}
|
||||
if dict != "":
|
||||
data["dict"] = dict
|
||||
return _make_request("/words/add", HTTPClient.METHOD_POST, data)
|
||||
|
||||
func delete_word(word: String, username: String, apiKey: String, dict: String = ""):
|
||||
var data = {
|
||||
"word": word,
|
||||
"username": username,
|
||||
"apiKey": apiKey
|
||||
}
|
||||
if dict != "":
|
||||
data["dict"] = dict
|
||||
return _make_request("/words/delete", HTTPClient.METHOD_POST, data)
|
||||
|
||||
static func percent_encode(text: String) -> String:
|
||||
return text.uri_encode()
|
||||
|
||||
class LanguageToolCheckResponse:
|
||||
|
||||
# Software info
|
||||
var software_name: String
|
||||
var software_version: String
|
||||
var software_build_date: String
|
||||
var software_api_version: int
|
||||
var software_status: String = ""
|
||||
var software_premium: bool = false
|
||||
|
||||
# Language info
|
||||
var language_name: String
|
||||
var language_code: String
|
||||
var detected_language_name: String
|
||||
var detected_language_code: String
|
||||
|
||||
# Match structure
|
||||
class Match:
|
||||
var message: String
|
||||
var short_message: String = ""
|
||||
var offset: int
|
||||
var length: int
|
||||
var replacements: Array[String] = []
|
||||
var context_text: String
|
||||
var context_offset: int
|
||||
var context_length: int
|
||||
var sentence: String
|
||||
class Rule:
|
||||
var id: String
|
||||
var sub_id: String = ""
|
||||
var description: String
|
||||
var urls: Array[String] = []
|
||||
var issue_type: String = ""
|
||||
class Category:
|
||||
var id: String
|
||||
var name: String
|
||||
var category: Category
|
||||
var rule: Rule
|
||||
|
||||
var matches: Array[Match] = []
|
||||
|
||||
func _init(response: Variant) -> void:
|
||||
# Parse software
|
||||
var sw = response.software if response.has("software") else {}
|
||||
software_name = sw.name if sw.has("name") else ""
|
||||
software_version = sw.version if sw.has("version") else ""
|
||||
software_build_date = sw.buildDate if sw.has("buildDate") else ""
|
||||
software_api_version = sw.apiVersion if sw.has("apiVersion") else 0
|
||||
software_status = sw.status if sw.has("status") else ""
|
||||
software_premium = sw.premium if sw.has("premium") else false
|
||||
|
||||
# Parse language
|
||||
var lang = response.language if response.has("language") else {}
|
||||
language_name = lang.name if lang.has("name") else ""
|
||||
language_code = lang.code if lang.has("code") else ""
|
||||
var det_lang = lang.detectedLanguage if lang.has("detectedLanguage") else {}
|
||||
detected_language_name = det_lang.name if det_lang.has("name") else ""
|
||||
detected_language_code = det_lang.code if det_lang.has("code") else ""
|
||||
|
||||
# Parse matches
|
||||
matches = []
|
||||
var matches_arr = response.matches if response.has("matches") else []
|
||||
for m in matches_arr:
|
||||
var _match = Match.new()
|
||||
_match.message = m.message if m.has("message") else ""
|
||||
_match.short_message = m.shortMessage if m.has("shortMessage") else ""
|
||||
_match.offset = m.offset if m.has("offset") else 0
|
||||
_match.length = m.length if m.has("length") else 0
|
||||
#_match.replacements = []
|
||||
var replacements_arr = m.replacements if m.has("replacements") else []
|
||||
for r in replacements_arr:
|
||||
_match.replacements.append(r.value if r.has("value") else "")
|
||||
var ctx = m.context if m.has("context") else {}
|
||||
_match.context_text = ctx.text if ctx.has("text") else ""
|
||||
_match.context_offset = ctx.offset if ctx.has("offset") else 0
|
||||
_match.context_length = ctx.length if ctx.has("length") else 0
|
||||
_match.sentence = m.sentence if m.has("sentence") else ""
|
||||
var rule_dict = m.rule if m.has("rule") else {}
|
||||
var rule = Match.Rule.new()
|
||||
rule.id = rule_dict.id if rule_dict.has("id") else ""
|
||||
rule.sub_id = rule_dict.subId if rule_dict.has("subId") else ""
|
||||
rule.description = rule_dict.description if rule_dict.has("description") else ""
|
||||
#rule.urls = []
|
||||
var urls_arr = rule_dict.urls if rule_dict.has("urls") else []
|
||||
for u in urls_arr:
|
||||
rule.urls.append(u.value if u.has("value") else "")
|
||||
rule.issue_type = rule_dict.issueType if rule_dict.has("issueType") else ""
|
||||
var cat = rule_dict.category if rule_dict.has("category") else {}
|
||||
var category = Match.Rule.Category.new()
|
||||
category.id = cat.id if cat.has("id") else ""
|
||||
category.name = cat.name if cat.has("name") else ""
|
||||
rule.category = category
|
||||
_match.rule = rule
|
||||
matches.append(_match)
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
uid://bkyd022t8ugkw
|
||||
@@ -1,8 +0,0 @@
|
||||
@tool
|
||||
extends EditorScript
|
||||
|
||||
func _run():
|
||||
var api = LanguageToolApiWrapper.new()
|
||||
EditorInterface.get_base_control().add_child(api)
|
||||
var result = api.check("Hello this is a santence how are you")
|
||||
print(result.matches[0])
|
||||
@@ -1 +0,0 @@
|
||||
uid://77jt5suj0wdj
|
||||
@@ -1,47 +0,0 @@
|
||||
@tool
|
||||
extends EditorScript
|
||||
|
||||
var testButton: Button
|
||||
|
||||
func _run():
|
||||
#var selected: Node = EditorInterface.get_inspector().get_child(0).get_child(2)
|
||||
#_print_info(selected)
|
||||
#print((EditorInterface.get_inspector().get_child(0).get_child(2).get_child(-1) as Button).text)
|
||||
#print((selected as LineEdit).text)
|
||||
#(selected as LineEdit).insert_text_at_caret("hello")
|
||||
#(selected as LineEdit).text_changed.emit((selected as LineEdit).text)
|
||||
#print(selected.get_class())
|
||||
#print(is_instance_of(selected, EditorPropertyText))
|
||||
#print(_find_recursive(selected,"EditorPropertyMultilineText")[0].get_child(0).get_child(0).get_class())
|
||||
#print(_find_recursive(selected,"EditorPropertyText")[0].get_child(0).get_child(0).get_class())
|
||||
testButton = Button.new()
|
||||
testButton.text = "Remove this button"
|
||||
#testButton.global_position = Vector2(1904.0, 305.0)
|
||||
testButton.pressed.connect(
|
||||
func():
|
||||
testButton.get_parent().remove_child(testButton)
|
||||
testButton.queue_free()
|
||||
)
|
||||
EditorInterface.get_base_control().add_child(testButton)
|
||||
|
||||
pass
|
||||
|
||||
|
||||
func _print_info(node: Control):
|
||||
print("Name: "+node.name)
|
||||
print("Children:")
|
||||
for child in node.get_children():
|
||||
print(" - "+child.name)
|
||||
|
||||
func _find_recursive(node: Node, type: Variant) -> Array[Node]:
|
||||
if type is String:
|
||||
if node.get_class() == type:
|
||||
return [node]
|
||||
elif is_instance_of(node, type):
|
||||
return [node]
|
||||
|
||||
var retval: Array[Node] = []
|
||||
for child in node.get_children():
|
||||
retval.append_array(_find_recursive(child, type))
|
||||
return retval
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
uid://t6f7snttaggn
|
||||
@@ -0,0 +1,8 @@
|
||||
[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"]
|
||||
script = ExtResource("1_5dt1r")
|
||||
_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"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://c76mhhqyk4lgh" path="res://scripts/CSharp/Common/Fight/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://c76mhhqyk4lgh" path="res://scripts/CSharp/Common/FightOld/FightInstance.cs" id="1_ygesl"]
|
||||
[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")]
|
||||
script = ExtResource("1_ygesl")
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://cnjsepvaqdbyq"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://j5ge24rk25wm" path="res://scripts/CSharp/Common/Fight/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="Script" uid="uid://j5ge24rk25wm" path="res://scripts/CSharp/Common/FightOld/FightManager.cs" id="1_8p7ev"]
|
||||
[ext_resource type="PackedScene" uid="uid://cpanatqdjjpa3" path="res://prefabs/fightOld/fighters/vesna_fighter.tscn" id="2_ak1vo"]
|
||||
|
||||
[node name="FightManagerAutoload" type="Node"]
|
||||
script = ExtResource("1_8p7ev")
|
||||
+2
-4
@@ -1,7 +1,7 @@
|
||||
[gd_scene load_steps=10 format=3 uid="uid://bp64p6y72j71w"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://ccrnmx6bd842k" path="res://art/characters/farm fäulnis blobs.png" id="1_vem8k"]
|
||||
[ext_resource type="Script" uid="uid://by88f32fou7lh" path="res://scripts/CSharp/Common/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="AudioStream" uid="uid://x7cc5woop5ec" path="res://audio/sfx/Battle/Enemies/SFX_Slime_Hit_V2_03.wav" id="5_v4f83"]
|
||||
[ext_resource type="Texture2D" uid="uid://bn56p0ytuo060" path="res://art/ui/UI/AttackButton.png" id="5_vbkts"]
|
||||
@@ -19,6 +19,7 @@ script = ExtResource("2_4w1ab")
|
||||
name = "Blob"
|
||||
maxHealth = 20
|
||||
attackStrength = 10
|
||||
maxActions = null
|
||||
_attackButtons = NodePath("FightButtons")
|
||||
_targetButtons = NodePath("TargetButtons")
|
||||
_targetMarker = NodePath("TargetButtons/TargetMarker")
|
||||
@@ -95,9 +96,6 @@ stream = ExtResource("6_vbkts")
|
||||
[node name="AttackAudio" type="AudioStreamPlayer" parent="."]
|
||||
stream = ExtResource("6_oykh8")
|
||||
|
||||
[connection signal="Attacking" from="." to="AttackAudio" method="play" binds= [0.0]]
|
||||
[connection signal="DamageTaken" from="." to="HitAudio" method="play" binds= [0.0]]
|
||||
[connection signal="Dying" from="." to="DieAudio" method="play" binds= [0.0]]
|
||||
[connection signal="input_event" from="TargetButtons/Area2D" to="." method="TargetMouseEvent"]
|
||||
[connection signal="mouse_entered" from="TargetButtons/Area2D" to="." method="StartHoverTarget"]
|
||||
[connection signal="mouse_exited" from="TargetButtons/Area2D" to="." method="EndHoverTarget"]
|
||||
+2
-10
@@ -1,6 +1,6 @@
|
||||
[gd_scene load_steps=10 format=3 uid="uid://cr66tpdr5rma5"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://by88f32fou7lh" path="res://scripts/CSharp/Common/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://qlfwuakhe57t" path="res://art/ui/UI/attack_select_wheel.png" id="3_nkuei"]
|
||||
[ext_resource type="Texture2D" uid="uid://bn56p0ytuo060" path="res://art/ui/UI/AttackButton.png" id="4_u3hw3"]
|
||||
@@ -14,16 +14,8 @@ radius = 388.063
|
||||
[sub_resource type="CircleShape2D" id="CircleShape2D_s74nc"]
|
||||
radius = 173.44
|
||||
|
||||
[node name="EnemyMavkhaFighter" type="Node2D" node_paths=PackedStringArray("_attackButtons", "_targetButtons", "_targetMarker", "_healthText", "_visualSprite")]
|
||||
[node name="EnemyMavkhaFighter" type="Node2D"]
|
||||
script = ExtResource("1_t6th8")
|
||||
name = "Mavkha"
|
||||
maxHealth = 40
|
||||
attackStrength = 10
|
||||
_attackButtons = NodePath("FightButtons")
|
||||
_targetButtons = NodePath("TargetButtons")
|
||||
_targetMarker = NodePath("TargetButtons/TargetMarker")
|
||||
_healthText = NodePath("HealthShow")
|
||||
_visualSprite = NodePath("Visual")
|
||||
|
||||
[node name="Visual" type="Node2D" parent="."]
|
||||
|
||||
@@ -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")
|
||||
@@ -0,0 +1,38 @@
|
||||
[gd_scene load_steps=7 format=3 uid="uid://bydwj3pbvqrhb"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://ct7l4er2kljnc" path="res://scripts/CSharp/Common/Minigame/MinigameController.cs" id="1_17v35"]
|
||||
[ext_resource type="PackedScene" uid="uid://dhfda4o386byp" path="res://prefabs/minigame/region_visual.tscn" id="2_rrvb1"]
|
||||
[ext_resource type="Script" uid="uid://djkyrp24ljff0" path="res://scripts/CSharp/Common/Minigame/SpinnyArmVisual.cs" id="3_86pvs"]
|
||||
[ext_resource type="Texture2D" uid="uid://bgn2ci6nu85t5" path="res://addons/dialogic/Example Assets/next-indicator/next-indicator-dialogic-1.png" id="3_pe4tw"]
|
||||
[ext_resource type="Script" uid="uid://dq7gahfp0lk7v" path="res://scripts/CSharp/Common/Util/ClickDetect.cs" id="5_86pvs"]
|
||||
|
||||
[sub_resource type="CircleShape2D" id="CircleShape2D_pe4tw"]
|
||||
radius = 554.923
|
||||
|
||||
[node name="Minigame" type="Node2D" node_paths=PackedStringArray("_regionsParent")]
|
||||
script = ExtResource("1_17v35")
|
||||
_regionVisualPrefab = ExtResource("2_rrvb1")
|
||||
_regionsParent = NodePath("RegionsParent")
|
||||
_baseRegionColor = Color(0.176888, 0.482224, 0.338857, 1)
|
||||
|
||||
[node name="RegionsParent" type="Node2D" parent="."]
|
||||
|
||||
[node name="SpinnyArm" type="Node2D" parent="."]
|
||||
script = ExtResource("3_86pvs")
|
||||
|
||||
[node name="ArmVisual" type="Node2D" parent="SpinnyArm"]
|
||||
|
||||
[node name="Sprite" type="Sprite2D" parent="SpinnyArm/ArmVisual"]
|
||||
position = Vector2(0, -40)
|
||||
rotation = -3.14159
|
||||
scale = Vector2(1, 2.08)
|
||||
texture = ExtResource("3_pe4tw")
|
||||
|
||||
[node name="Area2D" type="Area2D" parent="."]
|
||||
script = ExtResource("5_86pvs")
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"]
|
||||
shape = SubResource("CircleShape2D_pe4tw")
|
||||
|
||||
[connection signal="ArmMoved" from="." to="SpinnyArm" method="SetAngle"]
|
||||
[connection signal="Click" from="Area2D" to="." method="Hit"]
|
||||
@@ -0,0 +1,52 @@
|
||||
[gd_scene load_steps=5 format=3 uid="uid://dhfda4o386byp"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://cdpsa4qrlai31" path="res://scripts/CSharp/Common/Minigame/RegionVisual.cs" id="1_4ymj8"]
|
||||
[ext_resource type="Shader" uid="uid://d0dayn7dc885j" path="res://shader/minigame_pie_section.gdshader" id="1_8p2xn"]
|
||||
|
||||
[sub_resource type="ShaderMaterial" id="ShaderMaterial_86pvs"]
|
||||
resource_local_to_scene = true
|
||||
shader = ExtResource("1_8p2xn")
|
||||
shader_parameter/textureSize = 400.0
|
||||
shader_parameter/fillColor = Color(0.285466, 0.685481, 0.880632, 1)
|
||||
shader_parameter/borderColor = Color(1, 1, 1, 1)
|
||||
shader_parameter/borderWidth = 0.025
|
||||
shader_parameter/angles = Vector2(0.01, 0.18)
|
||||
shader_parameter/smoothWidth = 0.0052
|
||||
|
||||
[sub_resource type="PlaceholderTexture2D" id="PlaceholderTexture2D_0navw"]
|
||||
size = Vector2(400, 400)
|
||||
|
||||
[node name="RegionVisual" type="Node2D" node_paths=PackedStringArray("_sliceSprite", "_textLabel", "_labelPivot")]
|
||||
script = ExtResource("1_4ymj8")
|
||||
_sliceSprite = NodePath("Sprite2D")
|
||||
_textLabel = NodePath("LabelPivot/Label")
|
||||
_labelPivot = NodePath("LabelPivot")
|
||||
_fillColors = Dictionary[int, Color]({
|
||||
0: Color(0.427493, 0.427493, 0.427493, 1),
|
||||
1: Color(0.675735, 0.105671, 0.0799616, 1),
|
||||
2: Color(0.645128, 0.346481, 0.215967, 1),
|
||||
3: Color(0.754619, 0.665655, 0.384568, 1),
|
||||
4: Color(0.365769, 0.400285, 0.598083, 1),
|
||||
5: Color(0.222174, 0.457454, 0.45483, 1),
|
||||
6: Color(0.316126, 0.448834, 0.312852, 1),
|
||||
7: Color(0.244391, 0.640687, 0.283315, 1)
|
||||
})
|
||||
|
||||
[node name="Sprite2D" type="Sprite2D" parent="."]
|
||||
material = SubResource("ShaderMaterial_86pvs")
|
||||
texture = SubResource("PlaceholderTexture2D_0navw")
|
||||
|
||||
[node name="LabelPivot" type="Node2D" parent="."]
|
||||
|
||||
[node name="Label" type="Label" parent="LabelPivot"]
|
||||
custom_minimum_size = Vector2(100, 40)
|
||||
offset_left = -50.0
|
||||
offset_top = -240.0
|
||||
offset_right = 50.0
|
||||
offset_bottom = -200.0
|
||||
pivot_offset = Vector2(50, 20)
|
||||
size_flags_horizontal = 0
|
||||
theme_override_font_sizes/font_size = 21
|
||||
text = "test"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
+2
-2
@@ -28,10 +28,10 @@ buses/default_bus_layout="uid://b6dwkmkyb0axk"
|
||||
SceneTransition="*res://scenes/SceneTransition.tscn"
|
||||
Dialogic="*res://addons/dialogic/Core/DialogicGameHandler.gd"
|
||||
InventoryManager="*res://scripts/CSharp/Common/Inventory/InventoryManager.cs"
|
||||
FightManagerAutoload="*res://prefabs/fight/fight_manager_autoload.tscn"
|
||||
InputService="*res://scripts/CSharp/Common/Services/InputService.cs"
|
||||
QuestManager="*res://prefabs/quests/quest_manager_autoload.tscn"
|
||||
Signal_Debugger="*res://addons/SignalVisualizer/Debugger/SignalDebugger.gd"
|
||||
FightWorldAutoload="*res://prefabs/fight/fight_world_autoload.tscn"
|
||||
|
||||
[dialogic]
|
||||
|
||||
@@ -185,7 +185,7 @@ movie_writer/movie_file="/home/kaddi/Documents/Repos/Godot/Babushka/_clips/clip.
|
||||
|
||||
[editor_plugins]
|
||||
|
||||
enabled=PackedStringArray("res://addons/SignalVisualizer/plugin.cfg", "res://addons/anthonyec.camera_preview/plugin.cfg", "res://addons/babushkahelpers/plugin.cfg", "res://addons/dialogic/plugin.cfg", "res://addons/languagetool/plugin.cfg")
|
||||
enabled=PackedStringArray("res://addons/SignalVisualizer/plugin.cfg", "res://addons/anthonyec.camera_preview/plugin.cfg", "res://addons/babushkahelpers/plugin.cfg", "res://addons/dialogic/plugin.cfg")
|
||||
|
||||
[file_customization]
|
||||
|
||||
|
||||
@@ -6,5 +6,5 @@
|
||||
script = ExtResource("1_wactd")
|
||||
id = "2_collect_ducks"
|
||||
title = "Collect the Ducks"
|
||||
description = "Collect all 6 ducks running around the farm by approaching them and pressing [E]"
|
||||
description = "Collect all 6 ducks running around the farm by aporaching them and pressing [E]"
|
||||
metadata/_custom_type_script = "uid://vji5lp4qc8pp"
|
||||
|
||||
@@ -5,5 +5,6 @@
|
||||
[node name="BabushkaSceneBootstrap" type="Node2D"]
|
||||
|
||||
[node name="BabushkaSceneStartMenu" parent="." instance=ExtResource("1_15ton")]
|
||||
_sceneNamesToLoad = PackedStringArray("res://scenes/Babushka_scene_fight_world_room.tscn")
|
||||
|
||||
[node name="SceneParent" type="Node" parent="."]
|
||||
|
||||
@@ -2381,17 +2381,17 @@ script = ExtResource("40_w3jkj")
|
||||
script = ExtResource("66_2065p")
|
||||
questResource = ExtResource("67_tm0yg")
|
||||
toStatus = 1
|
||||
makeCurrent = true
|
||||
makeActive = true
|
||||
|
||||
[node name="ToolsCollectedTrigger" type="Node" parent="SpeicialQuestTrigger"]
|
||||
script = ExtResource("68_hux6i")
|
||||
_itemsToContain = Array[Resource]([SubResource("Resource_y820s"), SubResource("Resource_50loj")])
|
||||
_onActiveQuest = ExtResource("68_lbnqo")
|
||||
_onAvailableQuest = ExtResource("68_lbnqo")
|
||||
_toNextQuest = ExtResource("69_l4wxt")
|
||||
|
||||
[node name="FieldWorkTrigger" type="Node" parent="SpeicialQuestTrigger"]
|
||||
script = ExtResource("74_fv1t2")
|
||||
_onActiveQuest = ExtResource("75_l7ekk")
|
||||
_onAvailableQuest = ExtResource("75_l7ekk")
|
||||
_toNextQuest = ExtResource("76_xcwle")
|
||||
|
||||
[node name="StartDialog" type="Node" parent="SpeicialQuestTrigger/FieldWorkTrigger"]
|
||||
@@ -2416,7 +2416,7 @@ timeline = "quest2_tomatoes_end"
|
||||
[connection signal="Dialogue" from="YSorted/ducks/DialogicToggle" to="YSorted/ducks/dialogic starter" method="open"]
|
||||
[connection signal="finished" from="Audio/Background Music Ramp up" to="Audio/Background Music loop" method="PlayFromOffset"]
|
||||
[connection signal="ready" from="SpeicialQuestTrigger/QuestInstantStart" to="SpeicialQuestTrigger/QuestInstantStart/QuestTrigger" method="Trigger"]
|
||||
[connection signal="OnFulfilled" from="SpeicialQuestTrigger/FieldWorkTrigger" to="SpeicialQuestTrigger/FieldWorkTrigger/StartDialog" method="start"]
|
||||
[connection signal="OnFulfilled" from="SpeicialQuestTrigger/FieldWorkTrigger" to="SpeicialQuestTrigger/FieldWorkTrigger/StartDialog" method="open"]
|
||||
|
||||
[editable path="YSorted/Vesna"]
|
||||
[editable path="YSorted/Brünnen/InteractionArea"]
|
||||
|
||||
@@ -0,0 +1,220 @@
|
||||
[gd_scene load_steps=14 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="PackedScene" uid="uid://bydwj3pbvqrhb" path="res://prefabs/minigame/minigame.tscn" id="8_2b3cf"]
|
||||
[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://bwm0nhvt1083k" path="res://scripts/CSharp/Common/Fight/FightMinigameHandler.cs" id="8_falfe"]
|
||||
[ext_resource type="Script" uid="uid://d2ugtb3dalrg3" path="res://scripts/CSharp/Common/Fight/FightHappeningStateDebugger.cs" id="8_tv7cl"]
|
||||
[ext_resource type="Script" uid="uid://2f7rqk50gtdg" path="res://scripts/CSharp/Common/Fight/SwitchSceneOnFightEnd.cs" id="10_qqd8u"]
|
||||
|
||||
[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(300, 550, 800)
|
||||
|
||||
[node name="AllyFighters" type="Node2D" parent="FightVisuals"]
|
||||
|
||||
[node name="EnemyFighters" type="Node2D" parent="FightVisuals"]
|
||||
|
||||
[node name="EnvironmentVisuals" type="Node2D" parent="."]
|
||||
|
||||
[node name="MinigameHandler" type="Node2D" parent="." node_paths=PackedStringArray("_minigameController")]
|
||||
script = ExtResource("8_falfe")
|
||||
_minigameController = NodePath("Minigame")
|
||||
|
||||
[node name="Minigame" parent="MinigameHandler" instance=ExtResource("8_2b3cf")]
|
||||
process_mode = 4
|
||||
visible = false
|
||||
|
||||
[node name="SwitchSceneOnFightEnd" type="Node" parent="." node_paths=PackedStringArray("_fightSceneSwitcher")]
|
||||
script = ExtResource("10_qqd8u")
|
||||
_fightSceneSwitcher = NodePath("FightSceneSwitcher")
|
||||
|
||||
[node name="FightSceneSwitcher" parent="SwitchSceneOnFightEnd" node_paths=PackedStringArray("_sceneRoot") instance=ExtResource("2_phrlx")]
|
||||
_sceneRoot = NodePath("../..")
|
||||
|
||||
[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="ActionAnimationController/StateReactionActionAnimation" method="FightHappeningStateTransitioned"]
|
||||
[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="SignalTransitionToState" from="FightHappening" to="MinigameHandler" method="OnStateEnter"]
|
||||
[connection signal="SignalTransitionToState" from="FightHappening" to="SwitchSceneOnFightEnd" method="OnFightStateEnter"]
|
||||
[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://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="Script" uid="uid://di0xxwfw43m0i" path="res://scripts/CSharp/Common/Fight/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://bp64p6y72j71w" path="res://prefabs/fight/fighters/enemy_blob_fighter.tscn" id="27_hfhye"]
|
||||
[ext_resource type="Script" uid="uid://di0xxwfw43m0i" path="res://scripts/CSharp/Common/FightOld/FightStarter.cs" id="26_gg38r"]
|
||||
[ext_resource type="PackedScene" uid="uid://hk8ahyp6dgl6" path="res://prefabs/fightOld/fight_base_scene.tscn" id="27_55b52"]
|
||||
[ext_resource type="PackedScene" uid="uid://bp64p6y72j71w" path="res://prefabs/fightOld/fighters/enemy_blob_fighter.tscn" id="27_hfhye"]
|
||||
[ext_resource type="PackedScene" uid="uid://c25udixd5m6l0" path="res://prefabs/characters/Player2D.tscn" id="29_3jjxs"]
|
||||
[ext_resource type="PackedScene" uid="uid://ddpl8cbck7e6s" path="res://prefabs/characters/Chugar.tscn" id="29_26tkn"]
|
||||
[ext_resource type="PackedScene" uid="uid://cr66tpdr5rma5" path="res://prefabs/fight/fighters/enemy_mavkha_fighter.tscn" id="29_hfhye"]
|
||||
[ext_resource type="PackedScene" uid="uid://cr66tpdr5rma5" path="res://prefabs/fightOld/fighters/enemy_mavkha_fighter.tscn" id="29_hfhye"]
|
||||
[ext_resource type="Resource" uid="uid://dlcmqfjvgphqu" path="res://resources/items/rake.tres" id="30_l10vl"]
|
||||
[ext_resource type="Resource" uid="uid://cndd64batns31" path="res://resources/items/wateringcan.tres" id="31_c2gvt"]
|
||||
[ext_resource type="Texture2D" uid="uid://dyueumlr5ltvr" path="res://art/nature/baum märz 2025/megaeichel megaast.png" id="37_gg38r"]
|
||||
@@ -2186,7 +2186,7 @@ script = ExtResource("56_bjj0f")
|
||||
script = ExtResource("55_ub0r7")
|
||||
questResource = ExtResource("56_q833x")
|
||||
toStatus = 1
|
||||
makeCurrent = true
|
||||
makeActive = true
|
||||
|
||||
[connection signal="body_entered" from="Fight1/FightStarter/TriggerArea" to="Fight1/FightStarter" method="Start"]
|
||||
[connection signal="FightEnded" from="Fight1/FightBaseScene" to="YSorted/Vesna" method="show"]
|
||||
|
||||
@@ -563,7 +563,7 @@ script = ExtResource("17_k0k8c")
|
||||
script = ExtResource("21_blyw3")
|
||||
questResource = ExtResource("22_yd2gv")
|
||||
toStatus = 1
|
||||
makeCurrent = true
|
||||
makeActive = true
|
||||
|
||||
[node name="Camera2D" type="Camera2D" parent="." node_paths=PackedStringArray("_followNode")]
|
||||
position = Vector2(-1534, -26)
|
||||
|
||||
@@ -105,6 +105,7 @@ _data = {
|
||||
}
|
||||
|
||||
[node name="SceneTransition" type="CanvasLayer" node_paths=PackedStringArray("animationPlayer")]
|
||||
layer = 100
|
||||
script = ExtResource("1_e0bkc")
|
||||
animationPlayer = NodePath("SceneFadeAnimation")
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://c1dsbe7ryaije"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://iv0dbf32bfw1" path="res://scripts/CSharp/Common/TestScripts/MinigameTestStarter.cs" id="1_fwf73"]
|
||||
[ext_resource type="PackedScene" uid="uid://bydwj3pbvqrhb" path="res://prefabs/minigame/minigame.tscn" id="1_wh3re"]
|
||||
|
||||
[node name="BabushkaSceneMinigameTest" type="Node2D" node_paths=PackedStringArray("_minigameController")]
|
||||
script = ExtResource("1_fwf73")
|
||||
_minigameController = NodePath("Minigame")
|
||||
|
||||
[node name="Minigame" parent="." instance=ExtResource("1_wh3re")]
|
||||
|
||||
[node name="Camera2D" type="Camera2D" parent="."]
|
||||
@@ -18,7 +18,7 @@ text = "Start Quest 1"
|
||||
script = ExtResource("1_wnfrg")
|
||||
questResource = ExtResource("2_nud5h")
|
||||
toStatus = 1
|
||||
makeCurrent = true
|
||||
makeActive = true
|
||||
|
||||
[node name="Button2" type="Button" parent="."]
|
||||
offset_left = 460.0
|
||||
@@ -43,7 +43,7 @@ text = "Start Quest 2"
|
||||
script = ExtResource("1_wnfrg")
|
||||
questResource = ExtResource("3_tb5fn")
|
||||
toStatus = 1
|
||||
makeCurrent = true
|
||||
makeActive = true
|
||||
|
||||
[node name="Button4" type="Button" parent="."]
|
||||
offset_left = 460.0
|
||||
|
||||
@@ -41,7 +41,7 @@ text = "Active"
|
||||
script = ExtResource("3_sx4ix")
|
||||
questResource = ExtResource("4_qyyck")
|
||||
toStatus = 1
|
||||
makeCurrent = true
|
||||
makeActive = true
|
||||
|
||||
[node name="Done" type="Button" parent="CanvasLayer2/VBoxContainer/HBoxContainer"]
|
||||
layout_mode = 2
|
||||
|
||||
@@ -18,10 +18,13 @@ public partial class CameraController : Camera2D
|
||||
|
||||
[Export] private Node2D _followNode;
|
||||
|
||||
public FightInstance? fightToShow;
|
||||
public FightHappening? fightToShow;
|
||||
|
||||
|
||||
public override void _Process(double delta)
|
||||
{
|
||||
this.GlobalPosition = fightToShow?.camPositionNode.GlobalPosition ?? _followNode.GlobalPosition;
|
||||
this.GlobalPosition = /*fightToShow?.camPositionNode.GlobalPosition ??*/ _followNode.GlobalPosition;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Babushka.scripts.CSharp.Common.Util;
|
||||
using Godot;
|
||||
|
||||
namespace Babushka.scripts.CSharp.Common.CharacterControls;
|
||||
@@ -10,80 +12,89 @@ public partial class InteractionArea2D : Node2D
|
||||
[Export] private bool _active = true;
|
||||
[Export] private bool _useOutline = true;
|
||||
[Export] private ShaderMaterial _outlineMaterial;
|
||||
[Export] private bool _useSprite = true;
|
||||
[Export] private CanvasItem _spriteToOutline;
|
||||
//[Export] private bool _useSprite = true;
|
||||
[Export(PropertyHint.ArrayType)] private CanvasItem[] _spriteToOutline = [];
|
||||
[Export] private bool _showLabel = true;
|
||||
[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 InteractedEventHandler();
|
||||
|
||||
public bool IsActive
|
||||
{
|
||||
get => _active;
|
||||
set => _active = value;
|
||||
set => _active = value;
|
||||
}
|
||||
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
|
||||
if (_useSprite && _useOutline)
|
||||
if (_useOutline)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void OnPlayerEntered(Node2D player)
|
||||
{
|
||||
if (!_active)
|
||||
return;
|
||||
|
||||
if(_showLabel)
|
||||
|
||||
if (_showLabel)
|
||||
_label.Show();
|
||||
|
||||
if (!_useSprite || !_useOutline)
|
||||
|
||||
if (!_useOutline)
|
||||
return;
|
||||
|
||||
_spriteToOutline.Material = _outlineMaterial;
|
||||
|
||||
_spriteToOutline.ForEach(s => s.Material = _outlineMaterial);
|
||||
}
|
||||
|
||||
public void OnPlayerExited(Node2D player)
|
||||
{
|
||||
if (!_active)
|
||||
return;
|
||||
|
||||
|
||||
_label.Hide();
|
||||
|
||||
if (!_useSprite || !_useOutline)
|
||||
if (!_useOutline)
|
||||
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)
|
||||
{
|
||||
if (!_active)
|
||||
return;
|
||||
|
||||
|
||||
if (@event.IsAction("interact") && @event.IsPressed())
|
||||
{
|
||||
if (_area.HasOverlappingBodies())
|
||||
{
|
||||
_label.Hide();
|
||||
|
||||
if (_useSprite && _useOutline)
|
||||
_spriteToOutline.Material = _backupMaterial;
|
||||
|
||||
|
||||
if (_useOutline)
|
||||
{
|
||||
for (var i = 0; i < _spriteToOutline.Length; i++)
|
||||
{
|
||||
_spriteToOutline[i].Material = _backupMaterial[i];
|
||||
}
|
||||
}
|
||||
|
||||
EmitSignal(SignalName.InteractedTool, _id);
|
||||
EmitSignal(SignalName.Interacted);
|
||||
}
|
||||
@@ -93,7 +104,7 @@ public partial class InteractionArea2D : Node2D
|
||||
public void SetSpriteActiveState(bool success, int id) // TODO: remove
|
||||
{
|
||||
GD.PrintErr("SetSpriteActiveState is being called.");
|
||||
if(!_active)
|
||||
if (!_active)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -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,26 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Babushka.scripts.CSharp.Common.Fight.ActionDetails;
|
||||
|
||||
public class MinigameActionDetail : FighterAction.FighterActionDetail
|
||||
{
|
||||
// settings
|
||||
|
||||
|
||||
// result
|
||||
public List<int>? damageHits = null;
|
||||
|
||||
public MinigameActionDetail()
|
||||
{
|
||||
}
|
||||
|
||||
public override bool DetailComplete()
|
||||
{
|
||||
return damageHits != null;
|
||||
}
|
||||
|
||||
public void ResetResult()
|
||||
{
|
||||
damageHits = null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://dtn4la0ycl5wx
|
||||
@@ -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,65 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
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 MinigameActionDetail minigameDetail = new();
|
||||
|
||||
public override Variant<float, Func<bool>> GetAnimationEnd()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
public override bool NextDetail()
|
||||
{
|
||||
return !targetSelect.DetailComplete() || !minigameDetail.DetailComplete();
|
||||
}
|
||||
|
||||
public override FighterActionDetail CurrentDetail()
|
||||
{
|
||||
return targetSelect.DetailComplete() ? minigameDetail : targetSelect;
|
||||
}
|
||||
|
||||
public override AllyActionButton BindToActionButton()
|
||||
{
|
||||
return AllyActionButton.Attack;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
targetSelect.ResetResult();
|
||||
minigameDetail.ResetResult();
|
||||
}
|
||||
|
||||
public override void ExecuteAction()
|
||||
{
|
||||
var totalDamage = minigameDetail.damageHits!.Sum(dh => dh);
|
||||
targetSelect.GetTarget().AddHealth(-totalDamage);
|
||||
}
|
||||
|
||||
public override async Task AnimateAction(AllFightersVisual allFightersVisual)
|
||||
{
|
||||
var currentFighter = HappeningData.fighterTurn.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,36 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Babushka.scripts.CSharp.Common.Util;
|
||||
|
||||
namespace Babushka.scripts.CSharp.Common.Fight.Actions;
|
||||
|
||||
public class BlobAttackAction : FighterAction
|
||||
{
|
||||
public override Variant<float, Func<bool>> GetAnimationEnd()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
public override bool NextDetail()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void ExecuteAction()
|
||||
{
|
||||
FightWorld.Instance.allyFighters.vesnaFighter.AddHealth(-3);
|
||||
}
|
||||
|
||||
public override async Task AnimateAction(AllFightersVisual allFightersVisual)
|
||||
{
|
||||
var currentFighter = HappeningData.fighterTurn.Current;
|
||||
var targetFighter = FightWorld.Instance.allyFighters.vesnaFighter;
|
||||
|
||||
var currentFighterVisual = allFightersVisual.GetVisualForFighter(currentFighter);
|
||||
var targetFighterVisual = allFightersVisual.GetVisualForFighter(targetFighter);
|
||||
|
||||
await currentFighterVisual.AnimatePosToTarget(targetFighterVisual);
|
||||
_ = targetFighterVisual.AnimateHit();
|
||||
await currentFighterVisual.AnimatePosToBase();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://dlik4vktiu7dg
|
||||
@@ -0,0 +1,144 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Babushka.scripts.CSharp.Common.Fight.ActionDetails;
|
||||
using Babushka.scripts.CSharp.Common.Util;
|
||||
using Godot;
|
||||
|
||||
namespace Babushka.scripts.CSharp.Common.Fight;
|
||||
|
||||
public partial class AllFightersVisual : Node
|
||||
{
|
||||
[ExportCategory("References")] [Export]
|
||||
private Node2D _allyFighters = null!;
|
||||
|
||||
[Export] private Node2D _enemyFighters = null!;
|
||||
|
||||
// TODO: move type to prefab mapping to Resource
|
||||
[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)
|
||||
{
|
||||
// TODO: use Event bus
|
||||
if (targetDetail.selectEnemy)
|
||||
_fighterVisuals
|
||||
.Where(kv => kv.Key.IsInFormation(HappeningData.enemyFighterFormation))
|
||||
.ForEach(kv => kv.Value.SetTargetSelectionActive(true));
|
||||
|
||||
if (targetDetail.selectAlly)
|
||||
_fighterVisuals
|
||||
.Where(kv => kv.Key.IsInFormation(HappeningData.allyFighterFormation))
|
||||
.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,30 @@
|
||||
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,
|
||||
availableActions =
|
||||
[
|
||||
new AllyAttackAction()
|
||||
]
|
||||
};
|
||||
public FightWorld.Fighter chuhaFighter = new()
|
||||
{
|
||||
type = FightWorld.Fighter.Type.Chuha,
|
||||
maxHealth = 15,
|
||||
availableActions =
|
||||
[
|
||||
new FighterAction.Skip()
|
||||
]
|
||||
};
|
||||
|
||||
public bool IsAlive()
|
||||
{
|
||||
return vesnaFighter.IsAlive();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://dst8xcyiw18uc
|
||||
@@ -0,0 +1,386 @@
|
||||
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.fighterTurn.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.IsInFormation(HappeningData.enemyFighterFormation))
|
||||
{
|
||||
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;
|
||||
case FightState.EnemyWin:
|
||||
// TODO: remove and find proper solution
|
||||
ReviveVesna();
|
||||
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.IsInFormation(HappeningData.allyFighterFormation))
|
||||
{
|
||||
enteringAllyFighters.Add(allyFighters.vesnaFighter);
|
||||
}
|
||||
|
||||
// enemy
|
||||
const int totalEnemySpace = 3;
|
||||
var enemySpaceLeft = HappeningData.enemyFighterFormation.GetEmptySlotCount();
|
||||
|
||||
return new FightersEnterStaging
|
||||
{
|
||||
enteringAllyFighters = enteringAllyFighters,
|
||||
enteringEnemyFighters = HappeningData.enemyGroup.fighters
|
||||
.WhereIsAlive()
|
||||
.WhereIsNotInFormation(HappeningData.enemyFighterFormation)
|
||||
.Take(enemySpaceLeft)
|
||||
.ToList()
|
||||
};
|
||||
}
|
||||
|
||||
private void ExecuteFightersEnter()
|
||||
{
|
||||
Debug.Assert(HappeningData.fightersEnterStaging != null);
|
||||
foreach (var fighter in HappeningData.fightersEnterStaging.enteringAllyFighters)
|
||||
{
|
||||
var emptySlotIndex = HappeningData.allyFighterFormation.GetFirstEmptySlot();
|
||||
if (emptySlotIndex < 0) throw new Exception("No empty slot for ally fighter to enter");
|
||||
HappeningData.allyFighterFormation.SetFighterAtPosition(emptySlotIndex, fighter);
|
||||
HappeningData.fighterTurn.AddAsLast(fighter);
|
||||
}
|
||||
|
||||
foreach (var fighter in HappeningData.fightersEnterStaging.enteringEnemyFighters)
|
||||
{
|
||||
var emptySlotIndex = HappeningData.enemyFighterFormation.GetFirstEmptySlot();
|
||||
if (emptySlotIndex < 0) throw new Exception("No empty slot for enemy fighter to enter");
|
||||
HappeningData.enemyFighterFormation.SetFighterAtPosition(emptySlotIndex, fighter);
|
||||
HappeningData.fighterTurn.AddAsLast(fighter);
|
||||
}
|
||||
}
|
||||
|
||||
private void ExecuteNextFighter()
|
||||
{
|
||||
HappeningData.fighterTurn.Next();
|
||||
CurrentFighter.actionPointsLeft = FightWorld.Fighter.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();
|
||||
}
|
||||
|
||||
// TODO: remove
|
||||
private void ReviveVesna()
|
||||
{
|
||||
var vesnaFighter = FightWorld.Instance.allyFighters.vesnaFighter;
|
||||
vesnaFighter.health = vesnaFighter.maxHealth;
|
||||
GD.Print("Vesna has been revived. This is for the current prototype only");
|
||||
}
|
||||
|
||||
#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,43 @@
|
||||
using Godot;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Babushka.scripts.CSharp.Common.Fight;
|
||||
using Babushka.scripts.CSharp.Common.Fight.ActionDetails;
|
||||
using Babushka.scripts.CSharp.Common.Minigame;
|
||||
|
||||
public partial class FightMinigameHandler : Node
|
||||
{
|
||||
#region Shortcuts
|
||||
|
||||
private FightWorld.FightHappeningData HappeningData => FightWorld.Instance.fightHappeningData ?? throw new NoFightHappeningException();
|
||||
|
||||
#endregion
|
||||
|
||||
[Export] private MinigameController _minigameController;
|
||||
|
||||
|
||||
public void OnStateEnter(FightHappening.FightState to)
|
||||
{
|
||||
if(to!=FightHappening.FightState.InputActionDetail) return;
|
||||
|
||||
var currentDetail = HappeningData.actionStaging!.CurrentDetail();
|
||||
if(currentDetail is not MinigameActionDetail minigameDetail) return;
|
||||
|
||||
_minigameController.Run(new MinigameController.Builder<int>()
|
||||
.AddRegion(4).RegionWithText("4").RegionWithTheme(MinigameController.RegionTheme.Normal)
|
||||
.AddRegion(0).RegionWithProportion(1.5f).RegionWithText("0").RegionWithTheme(MinigameController.RegionTheme.Bad)
|
||||
.AddRegion(8).RegionWithProportion(0.5f).RegionWithText("8").RegionWithTheme(MinigameController.RegionTheme.VeryGood)
|
||||
.AddRegion(0).RegionWithProportion(1.5f).RegionWithText("0").RegionWithTheme(MinigameController.RegionTheme.Bad)
|
||||
.AddRegion(3).RegionWithText("3").RegionWithTheme(MinigameController.RegionTheme.NormalAlt1)
|
||||
.AddRegion(5).RegionWithText("5").RegionWithTheme(MinigameController.RegionTheme.NormalAlt2)
|
||||
.WithHitCount(3)
|
||||
).ContinueWith(task =>
|
||||
{
|
||||
minigameDetail.damageHits = task.Result;
|
||||
//FightHappening.Instance.DetailFilled();
|
||||
// Apparently ContinueWith spawn a new Thread, but methods on a node only want to be called from the main thread
|
||||
FightHappening.Instance.CallDeferred("DetailFilled");
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://bwm0nhvt1083k
|
||||
@@ -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,63 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Threading.Tasks;
|
||||
using Babushka.scripts.CSharp.Common.SceneManagement;
|
||||
using Godot;
|
||||
|
||||
namespace Babushka.scripts.CSharp.Common.Fight;
|
||||
|
||||
public partial class FightSceneSwitcher : Node
|
||||
{
|
||||
[Export] private Node _sceneRoot = null!;
|
||||
[Export] private string _fightRoomScenePath = null!;
|
||||
[Export] private string _fightHappeningScene = null!;
|
||||
|
||||
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 Task 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();
|
||||
}
|
||||
|
||||
public void ExitFight()
|
||||
{
|
||||
if (FightWorld.Instance.fightHappeningData == null)
|
||||
throw new Exception("Trying to exit a fight while not in a fight");
|
||||
|
||||
FightWorld.Instance.fightHappeningData = null;
|
||||
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,48 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Babushka.scripts.CSharp.Common.Fight;
|
||||
|
||||
public static class FightUtils
|
||||
{
|
||||
public static IEnumerable<FightWorld.Fighter> WhereIsAlive(this IEnumerable<FightWorld.Fighter> self)
|
||||
{
|
||||
return self.Where(e => e.IsAlive());
|
||||
}
|
||||
|
||||
public static IEnumerable<FightWorld.Fighter> WhereIsNotInFormation(this IEnumerable<FightWorld.Fighter> self, FighterFormation formation)
|
||||
{
|
||||
return self.Where(e => !e.IsInFormation(formation));
|
||||
}
|
||||
|
||||
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 Math.Max(self.health ?? self.maxHealth, 0);
|
||||
}
|
||||
|
||||
public static void AddHealth(this FightWorld.Fighter self, int addHealth)
|
||||
{
|
||||
self.health = self.GetHealth() + addHealth;
|
||||
}
|
||||
|
||||
public static bool IsInFormation(this FightWorld.Fighter self, FighterFormation formation)
|
||||
{
|
||||
return formation.ContainsFighter(self);
|
||||
}
|
||||
|
||||
public static bool AreAllDead(this FightWorld.FighterGroup self)
|
||||
{
|
||||
return self.fighters.All(e => e.IsDead());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://beuhpltb84pf
|
||||
@@ -0,0 +1,191 @@
|
||||
using System.Collections.Generic;
|
||||
using Babushka.scripts.CSharp.Common.Fight.Actions;
|
||||
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> fighters;
|
||||
}
|
||||
|
||||
public class FightHappeningData
|
||||
{
|
||||
public required FighterGroup enemyGroup;
|
||||
public FightHappening.FightState fightState = FightHappening.FightState.None;
|
||||
public readonly FighterTurn fighterTurn = new();
|
||||
public readonly FighterFormation allyFighterFormation = new();
|
||||
public readonly FighterFormation enemyFighterFormation = new();
|
||||
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 List<FighterAction> availableActions;
|
||||
public const int MaxActionPoints = 1;
|
||||
public int? health = null; // null => initialize to full health on spawn
|
||||
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
|
||||
{
|
||||
fighters = []
|
||||
};
|
||||
|
||||
var enemyCount = GD.RandRange(1, 3);
|
||||
|
||||
for (var i = 0; i < enemyCount; i++)
|
||||
{
|
||||
enemyGroup.fighters.Add(GenerateSingleEnemy());
|
||||
}
|
||||
|
||||
return enemyGroup;
|
||||
}
|
||||
|
||||
private Fighter GenerateSingleEnemy()
|
||||
{
|
||||
var typeRoll = GD.RandRange(0, 99);
|
||||
|
||||
// Disabled generating different types due to lack of fighter visual type implementation
|
||||
//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,
|
||||
maxHealth = 12,
|
||||
availableActions =
|
||||
[
|
||||
new BlobAttackAction()
|
||||
]
|
||||
};
|
||||
|
||||
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,56 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
|
||||
namespace Babushka.scripts.CSharp.Common.Fight;
|
||||
|
||||
public class FighterFormation
|
||||
{
|
||||
private readonly List<FightWorld.Fighter?> _fighters;
|
||||
|
||||
public FighterFormation(int slots = 3)
|
||||
{
|
||||
_fighters = [];
|
||||
for (var i = 0; i < slots; i++)
|
||||
{
|
||||
_fighters.Add(null);
|
||||
}
|
||||
}
|
||||
|
||||
public FightWorld.Fighter? GetFighterAtPosition(int position)
|
||||
{
|
||||
Debug.Assert(position >= 0, "position>=0");
|
||||
Debug.Assert(position < _fighters.Count, "position does not exist");
|
||||
|
||||
return _fighters[position];
|
||||
}
|
||||
|
||||
public void SetFighterAtPosition(int position, FightWorld.Fighter value)
|
||||
{
|
||||
Debug.Assert(position >= 0, "position>=0");
|
||||
Debug.Assert(position < _fighters.Count, "position does not exist");
|
||||
|
||||
_fighters[position] = value;
|
||||
}
|
||||
|
||||
public bool ContainsFighter(FightWorld.Fighter fighter)
|
||||
{
|
||||
return _fighters.Contains(fighter);
|
||||
}
|
||||
|
||||
public int GetFirstEmptySlot()
|
||||
{
|
||||
for (var i = 0; i < _fighters.Count; i++)
|
||||
{
|
||||
if (_fighters[i] == null)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public int GetEmptySlotCount()
|
||||
{
|
||||
return _fighters.Count(fighter => fighter == null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://oipfvb87uyq3
|
||||
@@ -0,0 +1,97 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Babushka.scripts.CSharp.Common.Fight;
|
||||
|
||||
public class FighterTurn
|
||||
{
|
||||
private class Node
|
||||
{
|
||||
public required Node next;
|
||||
public required FightWorld.Fighter fighter;
|
||||
}
|
||||
|
||||
private Node? _currentNode;
|
||||
|
||||
public FightWorld.Fighter Current => _currentNode?.fighter ?? throw new InvalidOperationException("No current fighter");
|
||||
|
||||
public void Next()
|
||||
{
|
||||
Debug.Assert(_currentNode != null, "currentNode!=null");
|
||||
_currentNode = _currentNode.next;
|
||||
}
|
||||
|
||||
public FightWorld.Fighter PeekNext()
|
||||
{
|
||||
Debug.Assert(_currentNode != null, "currentNode!=null");
|
||||
return _currentNode.next.fighter;
|
||||
}
|
||||
|
||||
public void AddAsLast(FightWorld.Fighter value)
|
||||
{
|
||||
// if first node
|
||||
if (_currentNode == null)
|
||||
{
|
||||
_currentNode = new Node { fighter = value, next = null! };
|
||||
_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 by loss of reference 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,98 @@
|
||||
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.IsInFormation(HappeningData.enemyFighterFormation) ? -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 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");
|
||||
}
|
||||
|
||||
// Keep for reference for new Heal animation
|
||||
//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")
|
||||
{
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user