Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7ab513f01c | |||
| c7142111ed | |||
| a6fa4315dc | |||
| 7841252809 | |||
| 1b77718b9b | |||
| 0bf3cc19c7 | |||
| 89321e917a | |||
| 2cbf7e15a4 | |||
| 628da80ed3 | |||
| 0dfbd73978 | |||
| 8a93b00e72 | |||
| ba7d550c3f | |||
| b65a3bbd6d | |||
| bcbc074c86 | |||
| 745f54b375 | |||
| 59d313d97d |
@@ -8,4 +8,7 @@
|
|||||||
<Folder Include="prefabs\UI\Inventory\" />
|
<Folder Include="prefabs\UI\Inventory\" />
|
||||||
<Folder Include="scripts\CSharp\Low Code\Randomizer\" />
|
<Folder Include="scripts\CSharp\Low Code\Randomizer\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
|
||||||
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
<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/=236f7aa5_002D7b06_002D43ca_002Dbf2a_002D9b31bfcff09a/@EntryIndexedValue"><Policy><Descriptor Staticness="Any" AccessRightKinds="Private" Description="Constant fields (private)"><ElementKinds><Kind Name="CONSTANT_FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="AA_BB" /></Policy></s:String>
|
||||||
<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/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/CodeStyle/Naming/CSharpNaming/UserRules/=669e5282_002Dfb4b_002D4e90_002D91e7_002D07d269d04b60/@EntryIndexedValue"><Policy><Descriptor Staticness="Any" AccessRightKinds="Protected, ProtectedInternal, Internal, Public, PrivateProtected" Description="Constant fields (not private)"><ElementKinds><Kind Name="CONSTANT_FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="AA_BB" /></Policy></s:String>
|
||||||
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=0B2502BD29F5EC4798EEFD2950AA7E06/Description/@EntryValue">Godot Signal</s:String>
|
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=0B2502BD29F5EC4798EEFD2950AA7E06/Description/@EntryValue">Godot Signal</s:String>
|
||||||
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=0B2502BD29F5EC4798EEFD2950AA7E06/Text/@EntryValue">[Signal]
|
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=0B2502BD29F5EC4798EEFD2950AA7E06/Text/@EntryValue">[Signal]
|
||||||
public delegate void $SignalName$EventHandler($END$);</s:String>
|
public delegate void $SignalName$EventHandler($END$);</s:String>
|
||||||
|
|||||||
@@ -4,19 +4,22 @@ importer="scene"
|
|||||||
importer_version=1
|
importer_version=1
|
||||||
type="PackedScene"
|
type="PackedScene"
|
||||||
uid="uid://b3kyrsoobmkhp"
|
uid="uid://b3kyrsoobmkhp"
|
||||||
valid=false
|
path="res://.godot/imported/best_house_blender.blend-ac89c74aef2f275bdf4b4baadee17c0c.scn"
|
||||||
|
|
||||||
[deps]
|
[deps]
|
||||||
|
|
||||||
source_file="res://art/mockups/3d/best_house_blender.blend"
|
source_file="res://art/mockups/3d/best_house_blender.blend"
|
||||||
|
dest_files=["res://.godot/imported/best_house_blender.blend-ac89c74aef2f275bdf4b4baadee17c0c.scn"]
|
||||||
|
|
||||||
[params]
|
[params]
|
||||||
|
|
||||||
nodes/root_type=""
|
nodes/root_type=""
|
||||||
nodes/root_name=""
|
nodes/root_name=""
|
||||||
|
nodes/root_script=null
|
||||||
nodes/apply_root_scale=true
|
nodes/apply_root_scale=true
|
||||||
nodes/root_scale=1.0
|
nodes/root_scale=1.0
|
||||||
nodes/import_as_skeleton_bones=false
|
nodes/import_as_skeleton_bones=false
|
||||||
|
nodes/use_name_suffixes=true
|
||||||
nodes/use_node_type_suffixes=true
|
nodes/use_node_type_suffixes=true
|
||||||
meshes/ensure_tangents=true
|
meshes/ensure_tangents=true
|
||||||
meshes/generate_lods=true
|
meshes/generate_lods=true
|
||||||
@@ -31,6 +34,9 @@ animation/trimming=false
|
|||||||
animation/remove_immutable_tracks=true
|
animation/remove_immutable_tracks=true
|
||||||
animation/import_rest_as_RESET=false
|
animation/import_rest_as_RESET=false
|
||||||
import_script/path=""
|
import_script/path=""
|
||||||
|
materials/extract=0
|
||||||
|
materials/extract_format=0
|
||||||
|
materials/extract_path=""
|
||||||
_subresources={}
|
_subresources={}
|
||||||
blender/nodes/visible=0
|
blender/nodes/visible=0
|
||||||
blender/nodes/active_collection_only=false
|
blender/nodes/active_collection_only=false
|
||||||
@@ -50,3 +56,4 @@ blender/materials/export_materials=1
|
|||||||
blender/animation/limit_playback=true
|
blender/animation/limit_playback=true
|
||||||
blender/animation/always_sample=true
|
blender/animation/always_sample=true
|
||||||
blender/animation/group_tracks=true
|
blender/animation/group_tracks=true
|
||||||
|
gltf/naming_version=0
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
[gd_scene load_steps=489 format=3 uid="uid://c25udixd5m6l0"]
|
[gd_scene load_steps=495 format=3 uid="uid://c25udixd5m6l0"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://b05uyj001ehwi" path="res://scripts/CSharp/Common/Farming/VesnaBehaviour2D.cs" id="1_yd5ep"]
|
[ext_resource type="Script" uid="uid://b05uyj001ehwi" path="res://scripts/CSharp/Common/Farming/VesnaBehaviour2D.cs" id="1_yd5ep"]
|
||||||
[ext_resource type="Script" uid="uid://cjbclkxesh3hc" path="res://scripts/CSharp/Common/CharacterControls/PlayerMovement.cs" id="2_1vqmv"]
|
[ext_resource type="Script" uid="uid://cjbclkxesh3hc" path="res://scripts/CSharp/Common/CharacterControls/PlayerMovement.cs" id="2_1vqmv"]
|
||||||
@@ -286,6 +286,7 @@
|
|||||||
[ext_resource type="Script" uid="uid://dj1qjambsa4pg" path="res://scripts/CSharp/Common/Farming/WateringCanSaveHelper.cs" id="472_kduih"]
|
[ext_resource type="Script" uid="uid://dj1qjambsa4pg" path="res://scripts/CSharp/Common/Farming/WateringCanSaveHelper.cs" id="472_kduih"]
|
||||||
[ext_resource type="Texture2D" uid="uid://blh0t2ofqj2uq" path="res://art/animation/Vesna2D/Vesna Anims Tools/F01-Idle-Gießkanne/0016.png" id="472_wdxsr"]
|
[ext_resource type="Texture2D" uid="uid://blh0t2ofqj2uq" path="res://art/animation/Vesna2D/Vesna Anims Tools/F01-Idle-Gießkanne/0016.png" id="472_wdxsr"]
|
||||||
[ext_resource type="AudioStream" uid="uid://dymoalptxmge" path="res://audio/sfx/Footsteps/Single/Gravel/Reverb/SFX_Footstep_Gravel_04_R.wav" id="473_8hbu5"]
|
[ext_resource type="AudioStream" uid="uid://dymoalptxmge" path="res://audio/sfx/Footsteps/Single/Gravel/Reverb/SFX_Footstep_Gravel_04_R.wav" id="473_8hbu5"]
|
||||||
|
[ext_resource type="Script" uid="uid://ccdhx1lt4n271" path="res://scripts/CSharp/Common/Camera/CameraTarget.cs" id="473_fn3kd"]
|
||||||
[ext_resource type="AudioStream" uid="uid://4555a4w30tda" path="res://audio/sfx/Footsteps/Single/Gravel/Reverb/SFX_Footstep_Gravel_05_R.wav" id="474_t1d6r"]
|
[ext_resource type="AudioStream" uid="uid://4555a4w30tda" path="res://audio/sfx/Footsteps/Single/Gravel/Reverb/SFX_Footstep_Gravel_05_R.wav" id="474_t1d6r"]
|
||||||
[ext_resource type="Texture2D" uid="uid://3t1m2xi4ks75" path="res://art/animation/Vesna2D/Vesna Anims Tools/F01-Idle-Gießkanne/0018.png" id="474_tu801"]
|
[ext_resource type="Texture2D" uid="uid://3t1m2xi4ks75" path="res://art/animation/Vesna2D/Vesna Anims Tools/F01-Idle-Gießkanne/0018.png" id="474_tu801"]
|
||||||
[ext_resource type="AudioStream" uid="uid://dpqvnogggvgea" path="res://audio/sfx/Footsteps/Single/Gravel/Reverb/SFX_Footstep_Gravel_06_R.wav" id="475_83c4i"]
|
[ext_resource type="AudioStream" uid="uid://dpqvnogggvgea" path="res://audio/sfx/Footsteps/Single/Gravel/Reverb/SFX_Footstep_Gravel_06_R.wav" id="475_83c4i"]
|
||||||
@@ -299,8 +300,12 @@
|
|||||||
[ext_resource type="Texture2D" uid="uid://bopxv06co1osl" path="res://art/animation/Vesna2D/Vesna Anims Sequences/F02-Walk/0006.png" id="482_wfdif"]
|
[ext_resource type="Texture2D" uid="uid://bopxv06co1osl" path="res://art/animation/Vesna2D/Vesna Anims Sequences/F02-Walk/0006.png" id="482_wfdif"]
|
||||||
[ext_resource type="Script" uid="uid://iquhbkr7pqeg" path="res://scripts/CSharp/Common/Savegame/SaveCheats.cs" id="483_kduih"]
|
[ext_resource type="Script" uid="uid://iquhbkr7pqeg" path="res://scripts/CSharp/Common/Savegame/SaveCheats.cs" id="483_kduih"]
|
||||||
[ext_resource type="Texture2D" uid="uid://coyggdfwgkeru" path="res://art/animation/Vesna2D/Vesna Anims Sequences/F02-Walk/0008.png" id="484_32thn"]
|
[ext_resource type="Texture2D" uid="uid://coyggdfwgkeru" path="res://art/animation/Vesna2D/Vesna Anims Sequences/F02-Walk/0008.png" id="484_32thn"]
|
||||||
|
[ext_resource type="AudioStream" uid="uid://fsiypqhql67w" path="res://audio/sfx/Farming/SFX_GettingWater_01.wav" id="484_jb7tm"]
|
||||||
[ext_resource type="Script" uid="uid://ca4s0algeij1h" path="res://scripts/CSharp/Common/Savegame/SaveIDProviderTool.cs" id="484_upuan"]
|
[ext_resource type="Script" uid="uid://ca4s0algeij1h" path="res://scripts/CSharp/Common/Savegame/SaveIDProviderTool.cs" id="484_upuan"]
|
||||||
|
[ext_resource type="AudioStream" uid="uid://foyw26hq1qp5" path="res://audio/sfx/Farming/SFX_GettingWater_02.wav" id="485_fn3kd"]
|
||||||
[ext_resource type="Texture2D" uid="uid://du6x1h42smp6m" path="res://art/animation/Vesna2D/Vesna Anims Sequences/F02-Walk/0010.png" id="486_kobao"]
|
[ext_resource type="Texture2D" uid="uid://du6x1h42smp6m" path="res://art/animation/Vesna2D/Vesna Anims Sequences/F02-Walk/0010.png" id="486_kobao"]
|
||||||
|
[ext_resource type="AudioStream" uid="uid://c43a6x43jkikl" path="res://audio/sfx/Farming/SFX_GettingWater_Well_01_Reverb.wav" id="486_ux0r8"]
|
||||||
|
[ext_resource type="Script" uid="uid://cfnrd5k1k0gxw" path="res://scripts/CSharp/Common/AudioPlayer2D.cs" id="487_7qtxa"]
|
||||||
[ext_resource type="Texture2D" uid="uid://bras5gn8ov27l" path="res://art/animation/Vesna2D/Vesna Anims Sequences/F02-Walk/0012.png" id="488_ygjj5"]
|
[ext_resource type="Texture2D" uid="uid://bras5gn8ov27l" path="res://art/animation/Vesna2D/Vesna Anims Sequences/F02-Walk/0012.png" id="488_ygjj5"]
|
||||||
[ext_resource type="Texture2D" uid="uid://rjmsht4g8dvp" path="res://art/animation/Vesna2D/Vesna Anims Sequences/F02-Walk/0014.png" id="490_6603x"]
|
[ext_resource type="Texture2D" uid="uid://rjmsht4g8dvp" path="res://art/animation/Vesna2D/Vesna Anims Sequences/F02-Walk/0014.png" id="490_6603x"]
|
||||||
[ext_resource type="Texture2D" uid="uid://diqnv8ut7lffx" path="res://art/animation/Vesna2D/Vesna Anims Sequences/F02-Walk/0016.png" id="492_0tmn6"]
|
[ext_resource type="Texture2D" uid="uid://diqnv8ut7lffx" path="res://art/animation/Vesna2D/Vesna Anims Sequences/F02-Walk/0016.png" id="492_0tmn6"]
|
||||||
@@ -484,7 +489,7 @@
|
|||||||
[ext_resource type="Texture2D" uid="uid://b0v61all3tsny" path="res://art/animation/Vesna2D/Vesna Anims Tools/S02-Walk-Gießkanne/0018.png" id="812_sf8kv"]
|
[ext_resource type="Texture2D" uid="uid://b0v61all3tsny" path="res://art/animation/Vesna2D/Vesna Anims Tools/S02-Walk-Gießkanne/0018.png" id="812_sf8kv"]
|
||||||
[ext_resource type="Texture2D" uid="uid://cao7vqax8cblo" path="res://art/animation/Vesna2D/Vesna Anims Tools/S02-Walk-Gießkanne/0020.png" id="814_3uq4g"]
|
[ext_resource type="Texture2D" uid="uid://cao7vqax8cblo" path="res://art/animation/Vesna2D/Vesna Anims Tools/S02-Walk-Gießkanne/0020.png" id="814_3uq4g"]
|
||||||
[ext_resource type="Script" uid="uid://bcskt5ckh3rqa" path="res://scripts/CSharp/Common/Farming/FarmingControls2D.cs" id="817_6nrw3"]
|
[ext_resource type="Script" uid="uid://bcskt5ckh3rqa" path="res://scripts/CSharp/Common/Farming/FarmingControls2D.cs" id="817_6nrw3"]
|
||||||
[ext_resource type="Script" uid="uid://cvkw4qd2hxksi" path="res://scripts/GdScript/dialogic_toggle.gd" id="819_4na52"]
|
[ext_resource type="Script" path="res://scripts/GdScript/dialogic_toggle.gd" id="819_4na52"]
|
||||||
|
|
||||||
[sub_resource type="CircleShape2D" id="CircleShape2D_ssqtd"]
|
[sub_resource type="CircleShape2D" id="CircleShape2D_ssqtd"]
|
||||||
radius = 110.018
|
radius = 110.018
|
||||||
@@ -2087,11 +2092,17 @@ stream_4/stream = ExtResource("474_t1d6r")
|
|||||||
stream_5/stream = ExtResource("475_83c4i")
|
stream_5/stream = ExtResource("475_83c4i")
|
||||||
stream_6/stream = ExtResource("476_deeju")
|
stream_6/stream = ExtResource("476_deeju")
|
||||||
|
|
||||||
[node name="Vesna" type="Node2D" node_paths=PackedStringArray("_farmingControls", "_player2d", "_vesnaAnimations")]
|
[sub_resource type="AudioStreamRandomizer" id="AudioStreamRandomizer_4da77"]
|
||||||
|
streams_count = 3
|
||||||
|
stream_0/stream = ExtResource("484_jb7tm")
|
||||||
|
stream_1/stream = ExtResource("485_fn3kd")
|
||||||
|
stream_2/stream = ExtResource("486_ux0r8")
|
||||||
|
|
||||||
|
[node name="Vesna" type="Node2D" node_paths=PackedStringArray("_farmingControls", "player2d", "_vesnaAnimations")]
|
||||||
y_sort_enabled = true
|
y_sort_enabled = true
|
||||||
script = ExtResource("1_yd5ep")
|
script = ExtResource("1_yd5ep")
|
||||||
_farmingControls = NodePath("FarmingControls")
|
_farmingControls = NodePath("FarmingControls")
|
||||||
_player2d = NodePath("CharacterBody2D")
|
player2d = NodePath("CharacterBody2D")
|
||||||
_vesnaAnimations = NodePath("CharacterBody2D/visuals")
|
_vesnaAnimations = NodePath("CharacterBody2D/visuals")
|
||||||
_hoe = ExtResource("2_dnm27")
|
_hoe = ExtResource("2_dnm27")
|
||||||
_wateringCan = ExtResource("3_e04c3")
|
_wateringCan = ExtResource("3_e04c3")
|
||||||
@@ -2175,6 +2186,10 @@ _wateringCanFillStateNode = NodePath("../WateringCanFillState")
|
|||||||
[node name="DetectionCross" parent="CharacterBody2D" instance=ExtResource("466_e04c3")]
|
[node name="DetectionCross" parent="CharacterBody2D" instance=ExtResource("466_e04c3")]
|
||||||
position = Vector2(0, -260)
|
position = Vector2(0, -260)
|
||||||
|
|
||||||
|
[node name="CameraTarget" type="Node2D" parent="CharacterBody2D"]
|
||||||
|
script = ExtResource("473_fn3kd")
|
||||||
|
Priority = 10.0
|
||||||
|
|
||||||
[node name="FarmingControls" type="Node2D" parent="." node_paths=PackedStringArray("_movingPlayer")]
|
[node name="FarmingControls" type="Node2D" parent="." node_paths=PackedStringArray("_movingPlayer")]
|
||||||
script = ExtResource("817_6nrw3")
|
script = ExtResource("817_6nrw3")
|
||||||
_sceneKeyProvider = ExtResource("471_83c4i")
|
_sceneKeyProvider = ExtResource("471_83c4i")
|
||||||
@@ -2197,6 +2212,12 @@ script = ExtResource("471_2f15g")
|
|||||||
[node name="Timer" type="Timer" parent="SFX/FootstepsAudio"]
|
[node name="Timer" type="Timer" parent="SFX/FootstepsAudio"]
|
||||||
wait_time = 0.5
|
wait_time = 0.5
|
||||||
|
|
||||||
|
[node name="FillWater SFX2" type="AudioStreamPlayer2D" parent="SFX"]
|
||||||
|
stream = SubResource("AudioStreamRandomizer_4da77")
|
||||||
|
max_distance = 20000000.0
|
||||||
|
playback_type = 2
|
||||||
|
script = ExtResource("487_7qtxa")
|
||||||
|
|
||||||
[node name="SaveSystem" type="Node" parent="."]
|
[node name="SaveSystem" type="Node" parent="."]
|
||||||
|
|
||||||
[node name="SaveGameCheat" type="Node" parent="SaveSystem"]
|
[node name="SaveGameCheat" type="Node" parent="SaveSystem"]
|
||||||
@@ -2206,6 +2227,7 @@ script = ExtResource("483_kduih")
|
|||||||
script = ExtResource("484_upuan")
|
script = ExtResource("484_upuan")
|
||||||
|
|
||||||
[connection signal="FilledWateringCan" from="." to="CharacterBody2D/WateringCan/WateringCanUI" method="Refill"]
|
[connection signal="FilledWateringCan" from="." to="CharacterBody2D/WateringCan/WateringCanUI" method="Refill"]
|
||||||
|
[connection signal="FilledWateringCan" from="." to="SFX/FillWater SFX2" method="PlayOneShot"]
|
||||||
[connection signal="InventorySelectionChanged" from="." to="CharacterBody2D/WateringCan/WateringCanUI" method="IsWateringCanActive"]
|
[connection signal="InventorySelectionChanged" from="." to="CharacterBody2D/WateringCan/WateringCanUI" method="IsWateringCanActive"]
|
||||||
[connection signal="PickedUpTool" from="." to="CharacterBody2D/visuals" method="ActivateTool"]
|
[connection signal="PickedUpTool" from="." to="CharacterBody2D/visuals" method="ActivateTool"]
|
||||||
[connection signal="PickedUpTool" from="." to="CharacterBody2D/WateringCan/WateringCanUI" method="IsWateringCanActive"]
|
[connection signal="PickedUpTool" from="." to="CharacterBody2D/WateringCan/WateringCanUI" method="IsWateringCanActive"]
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
[gd_scene load_steps=4 format=3 uid="uid://cv7trh2b3dyiv"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" uid="uid://dcn4giw1auva4" path="res://scripts/CSharp/GameEntity/EntityPlacer/VesnaEntityPlacer.cs" id="1_nq5fu"]
|
||||||
|
[ext_resource type="Script" uid="uid://n7oihifvqp23" path="res://scripts/CSharp/Common/Animation/VesnaAnimations.cs" id="2_cpdud"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://cloe0etis2lcu" path="res://art/animation/Vesna2D/Vesna Anims Tools/S02-Walk-Gießkanne/0001.png" id="451_d8nvl"]
|
||||||
|
|
||||||
|
[node name="VesnaPlacer" type="Node2D"]
|
||||||
|
script = ExtResource("1_nq5fu")
|
||||||
|
|
||||||
|
[node name="visuals" type="Node2D" parent="." node_paths=PackedStringArray("_sprite")]
|
||||||
|
position = Vector2(0, -374)
|
||||||
|
script = ExtResource("2_cpdud")
|
||||||
|
_sprite = NodePath("")
|
||||||
|
|
||||||
|
[node name="0001" type="Sprite2D" parent="visuals"]
|
||||||
|
position = Vector2(1, 0)
|
||||||
|
texture = ExtResource("451_d8nvl")
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
[gd_scene load_steps=5 format=3 uid="uid://hdfejdnmp8sl"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" uid="uid://umop2b1m1qm8" path="res://scripts/CSharp/GameEntity/Management/EntityManager.cs" id="1_2bwns"]
|
||||||
|
[ext_resource type="Script" uid="uid://bogqp274y1pgr" path="res://scripts/CSharp/GameEntity/Management/EntityNodeCreator.cs" id="2_8m173"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://sbf12hin4kes" path="res://prefabs/Interactables/trash_object.tscn" id="3_v3vdc"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://c25udixd5m6l0" path="res://prefabs/characters/Vesna.tscn" id="4_8m173"]
|
||||||
|
|
||||||
|
[node name="EntityManager" type="Node" node_paths=PackedStringArray("_nodeCreator")]
|
||||||
|
script = ExtResource("1_2bwns")
|
||||||
|
_nodeCreator = NodePath("EntityCreator")
|
||||||
|
|
||||||
|
[node name="EntityCreator" type="Node" parent="."]
|
||||||
|
script = ExtResource("2_8m173")
|
||||||
|
_entityPrefabs = Dictionary[String, PackedScene]({
|
||||||
|
"TrashEntity": ExtResource("3_v3vdc"),
|
||||||
|
"VesnaEntity": ExtResource("4_8m173")
|
||||||
|
})
|
||||||
+16
-1
@@ -11,7 +11,7 @@ config_version=5
|
|||||||
[application]
|
[application]
|
||||||
|
|
||||||
config/name="Babushka"
|
config/name="Babushka"
|
||||||
run/main_scene="uid://bopv10dqm1knc"
|
run/main_scene="uid://66pmq4efjip8"
|
||||||
config/features=PackedStringArray("4.5", "C#", "Forward Plus")
|
config/features=PackedStringArray("4.5", "C#", "Forward Plus")
|
||||||
run/max_fps=120
|
run/max_fps=120
|
||||||
boot_splash/fullsize=false
|
boot_splash/fullsize=false
|
||||||
@@ -35,6 +35,7 @@ FightWorldAutoload="*res://prefabs/fight/fight_world_autoload.tscn"
|
|||||||
SaveGameManager="*res://scripts/CSharp/Common/Savegame/SaveGameManager.cs"
|
SaveGameManager="*res://scripts/CSharp/Common/Savegame/SaveGameManager.cs"
|
||||||
SettingsSaveController="*res://scripts/CSharp/Common/Savegame/SettingsSaveController.cs"
|
SettingsSaveController="*res://scripts/CSharp/Common/Savegame/SettingsSaveController.cs"
|
||||||
DayAndNight="*res://prefabs/day_and_night/day_and_night.tscn"
|
DayAndNight="*res://prefabs/day_and_night/day_and_night.tscn"
|
||||||
|
EntityManager="*res://prefabs/entity_system/entity_manager.tscn"
|
||||||
|
|
||||||
[dialogic]
|
[dialogic]
|
||||||
|
|
||||||
@@ -224,6 +225,10 @@ folder_colors={
|
|||||||
"res://shader/": "pink"
|
"res://shader/": "pink"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[filesystem]
|
||||||
|
|
||||||
|
import/blender/enabled=false
|
||||||
|
|
||||||
[global_group]
|
[global_group]
|
||||||
|
|
||||||
Saveable=""
|
Saveable=""
|
||||||
@@ -310,6 +315,16 @@ NextDayCheat={
|
|||||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":32,"key_label":0,"unicode":32,"location":0,"echo":false,"script":null)
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":32,"key_label":0,"unicode":32,"location":0,"echo":false,"script":null)
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
DebugEntities={
|
||||||
|
"deadzone": 0.2,
|
||||||
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":66,"key_label":0,"unicode":98,"location":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
SaveGame={
|
||||||
|
"deadzone": 0.2,
|
||||||
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194336,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
[internationalization]
|
[internationalization]
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,8 @@
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Babushka.scripts.CSharp.Common.Inventory;
|
using Babushka.scripts.CSharp.Common.Inventory;
|
||||||
using Babushka.scripts.CSharp.Common.Services;
|
using Babushka.scripts.CSharp.Common.Services;
|
||||||
|
using Babushka.scripts.CSharp.GameEntity.Entities;
|
||||||
|
using Babushka.scripts.CSharp.GameEntity.Management;
|
||||||
using Godot;
|
using Godot;
|
||||||
|
|
||||||
namespace Babushka.scripts.CSharp.Common.Animation;
|
namespace Babushka.scripts.CSharp.Common.Animation;
|
||||||
@@ -27,12 +29,12 @@ public partial class VesnaAnimations : Node
|
|||||||
|
|
||||||
private void SetupSubscriptions()
|
private void SetupSubscriptions()
|
||||||
{
|
{
|
||||||
InventoryManager.Instance.playerInventory.InventoryContentsChanged += HandleNewItemInInventory;
|
EntityManager.Instance.GetUniqueEntity<VesnaEntity>().inventory.InventoryContentsChanged += HandleNewItemInInventory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void _ExitTree()
|
public override void _ExitTree()
|
||||||
{
|
{
|
||||||
InventoryManager.Instance.playerInventory.InventoryContentsChanged -= HandleNewItemInInventory;
|
EntityManager.Instance.GetUniqueEntity<VesnaEntity>().inventory.InventoryContentsChanged -= HandleNewItemInInventory;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleNewItemInInventory()
|
private void HandleNewItemInInventory()
|
||||||
|
|||||||
@@ -5,26 +5,8 @@ namespace Babushka.scripts.CSharp.Common.Camera;
|
|||||||
|
|
||||||
public partial class CameraController : Camera2D
|
public partial class CameraController : Camera2D
|
||||||
{
|
{
|
||||||
#region Singleton ( Contains _EnterTree() ) // TODO: use autoload or other solution
|
|
||||||
|
|
||||||
public static CameraController Instance { get; private set; } = null!;
|
|
||||||
|
|
||||||
public override void _EnterTree()
|
|
||||||
{
|
|
||||||
Instance = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
[Export] private Node2D _followNode;
|
|
||||||
|
|
||||||
public FightHappening? fightToShow;
|
|
||||||
|
|
||||||
|
|
||||||
public override void _Process(double delta)
|
public override void _Process(double delta)
|
||||||
{
|
{
|
||||||
this.GlobalPosition = /*fightToShow?.camPositionNode.GlobalPosition ??*/ _followNode.GlobalPosition;
|
GlobalPosition = CameraTarget.GetActiveTarget().GlobalPosition;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
namespace Babushka.scripts.CSharp.Common.Camera;
|
||||||
|
|
||||||
|
public partial class CameraTarget : Node2D
|
||||||
|
{
|
||||||
|
private static readonly List<CameraTarget> AllTargets = new();
|
||||||
|
|
||||||
|
public static CameraTarget GetActiveTarget() // Called every frame. Maybe needs performance optimization in the future
|
||||||
|
{
|
||||||
|
return AllTargets
|
||||||
|
.OrderByDescending(t => t.Priority)
|
||||||
|
.First();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Export] public float Priority { get; set; }
|
||||||
|
|
||||||
|
public override void _EnterTree()
|
||||||
|
{
|
||||||
|
AllTargets.Add(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void _ExitTree()
|
||||||
|
{
|
||||||
|
AllTargets.Remove(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://ccdhx1lt4n271
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using Babushka.scripts.CSharp.Common.Services;
|
using Babushka.scripts.CSharp.Common.Services;
|
||||||
|
using Babushka.scripts.CSharp.GameEntity.Entities;
|
||||||
using Godot;
|
using Godot;
|
||||||
|
|
||||||
namespace Babushka.scripts.CSharp.Common.CharacterControls;
|
namespace Babushka.scripts.CSharp.Common.CharacterControls;
|
||||||
@@ -8,6 +9,14 @@ public partial class PlayerMovement : CharacterBody2D
|
|||||||
[Export] private float _speed = 1000f;
|
[Export] private float _speed = 1000f;
|
||||||
[Export] private Timer _stepTimer;
|
[Export] private Timer _stepTimer;
|
||||||
|
|
||||||
|
private PositionalEntity _entity;
|
||||||
|
|
||||||
|
public void Initialize(PositionalEntity entity)
|
||||||
|
{
|
||||||
|
_entity = entity;
|
||||||
|
GlobalPosition = entity.position;
|
||||||
|
}
|
||||||
|
|
||||||
public override void _Process(double delta)
|
public override void _Process(double delta)
|
||||||
{
|
{
|
||||||
bool anyActionPressed = false;
|
bool anyActionPressed = false;
|
||||||
@@ -76,6 +85,7 @@ public partial class PlayerMovement : CharacterBody2D
|
|||||||
|
|
||||||
Velocity = currentVelocity;
|
Velocity = currentVelocity;
|
||||||
MoveAndSlide();
|
MoveAndSlide();
|
||||||
|
_entity.position = GlobalPosition;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -8,11 +8,11 @@ public partial class FarmingControls2D : Node2D
|
|||||||
{
|
{
|
||||||
[Export] private VariableResource _sceneKeyProvider;
|
[Export] private VariableResource _sceneKeyProvider;
|
||||||
[Export] private Node2D _movingPlayer;
|
[Export] private Node2D _movingPlayer;
|
||||||
[Export] private Camera2D _camera;
|
//[Export] private Camera2D _camera; // can be replaced with GetViewport().GetCamera2D()
|
||||||
|
|
||||||
[Export] private float _wateringCanParticlesVerticalOffset = 50f;
|
[Export] private float _wateringCanParticlesVerticalOffset = 50f;
|
||||||
[Export] private Vector2I _fieldOffsetVector = new Vector2I(735, 651);
|
[Export] private Vector2I _fieldOffsetVector = new Vector2I(735, 651);
|
||||||
[Export] private Node2D _fieldParent;
|
//[Export] private Node2D _fieldParent; // never used
|
||||||
|
|
||||||
private int _toolId = -1;
|
private int _toolId = -1;
|
||||||
private bool _wateringCanFilled = false;
|
private bool _wateringCanFilled = false;
|
||||||
@@ -51,7 +51,8 @@ public partial class FarmingControls2D : Node2D
|
|||||||
|
|
||||||
private Vector2I GetAdjustedMousePosition()
|
private Vector2I GetAdjustedMousePosition()
|
||||||
{
|
{
|
||||||
Vector2 mousePosition = _camera.GetGlobalMousePosition();
|
var camera = GetViewport().GetCamera2D();
|
||||||
|
Vector2 mousePosition = camera.GetGlobalMousePosition();
|
||||||
Vector2I mousePositionInteger = (Vector2I) mousePosition;
|
Vector2I mousePositionInteger = (Vector2I) mousePosition;
|
||||||
Vector2I adjustedPosition = AdjustValue(mousePositionInteger, _fieldOffsetVector);
|
Vector2I adjustedPosition = AdjustValue(mousePositionInteger, _fieldOffsetVector);
|
||||||
return adjustedPosition;
|
return adjustedPosition;
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ using Babushka.scripts.CSharp.Common.CharacterControls;
|
|||||||
using Babushka.scripts.CSharp.Common.DayAndNight;
|
using Babushka.scripts.CSharp.Common.DayAndNight;
|
||||||
using Babushka.scripts.CSharp.Common.Inventory;
|
using Babushka.scripts.CSharp.Common.Inventory;
|
||||||
using Babushka.scripts.CSharp.Common.Savegame;
|
using Babushka.scripts.CSharp.Common.Savegame;
|
||||||
|
using Babushka.scripts.CSharp.GameEntity.Entities;
|
||||||
|
using Babushka.scripts.CSharp.GameEntity.Management;
|
||||||
using Babushka.scripts.CSharp.Low_Code.Events;
|
using Babushka.scripts.CSharp.Low_Code.Events;
|
||||||
using Babushka.scripts.CSharp.Low_Code.Variables;
|
using Babushka.scripts.CSharp.Low_Code.Variables;
|
||||||
using Godot;
|
using Godot;
|
||||||
@@ -178,8 +180,8 @@ public partial class FieldBehaviour2D : Sprite2D, ISaveable
|
|||||||
private bool TryPlant()
|
private bool TryPlant()
|
||||||
{
|
{
|
||||||
bool success = false;
|
bool success = false;
|
||||||
int currentSlotIndex = InventoryManager.Instance.CurrentSelectedSlotIndex;
|
int currentSlotIndex = EntityManager.Instance.GetUniqueEntity<VesnaEntity>().CurrentSelectedSlotIndex;
|
||||||
ItemInstance? item = InventoryManager.Instance.playerInventory.Slots[currentSlotIndex].itemInstance;
|
ItemInstance? item = EntityManager.Instance.GetUniqueEntity<VesnaEntity>().inventory.Slots[currentSlotIndex].itemInstance;
|
||||||
|
|
||||||
if (item == null || PlantingPlaceholder.GetChildCount() > 0 || item.amount == 0)
|
if (item == null || PlantingPlaceholder.GetChildCount() > 0 || item.amount == 0)
|
||||||
return success;
|
return success;
|
||||||
@@ -189,7 +191,7 @@ public partial class FieldBehaviour2D : Sprite2D, ISaveable
|
|||||||
if (!string.IsNullOrEmpty(plantPrefabPath))
|
if (!string.IsNullOrEmpty(plantPrefabPath))
|
||||||
{
|
{
|
||||||
PlantPrefab(plantPrefabPath);
|
PlantPrefab(plantPrefabPath);
|
||||||
InventoryManager.Instance.playerInventory.RemoveItem(currentSlotIndex);
|
EntityManager.Instance.GetUniqueEntity<VesnaEntity>().inventory.RemoveItem(currentSlotIndex);
|
||||||
success = true;
|
success = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,15 +2,17 @@ using Babushka.scripts.CSharp.Common.Animation;
|
|||||||
using Babushka.scripts.CSharp.Common.CharacterControls;
|
using Babushka.scripts.CSharp.Common.CharacterControls;
|
||||||
using Babushka.scripts.CSharp.Common.Inventory;
|
using Babushka.scripts.CSharp.Common.Inventory;
|
||||||
using Babushka.scripts.CSharp.Common.Services;
|
using Babushka.scripts.CSharp.Common.Services;
|
||||||
|
using Babushka.scripts.CSharp.GameEntity.Entities;
|
||||||
|
using Babushka.scripts.CSharp.GameEntity.Management;
|
||||||
using Godot;
|
using Godot;
|
||||||
|
|
||||||
namespace Babushka.scripts.CSharp.Common.Farming;
|
namespace Babushka.scripts.CSharp.Common.Farming;
|
||||||
|
|
||||||
public partial class VesnaBehaviour2D : Node
|
public partial class VesnaBehaviour2D : Node2D // EntityNode
|
||||||
{
|
{
|
||||||
[ExportGroup("Farming")]
|
[ExportGroup("Farming")]
|
||||||
[Export] private FarmingControls2D _farmingControls;
|
[Export] private FarmingControls2D _farmingControls;
|
||||||
[Export] private PlayerMovement _player2d;
|
[Export] public PlayerMovement player2d;
|
||||||
[Export] private VesnaAnimations _vesnaAnimations;
|
[Export] private VesnaAnimations _vesnaAnimations;
|
||||||
[Export] private ItemResource _hoe;
|
[Export] private ItemResource _hoe;
|
||||||
[Export] private ItemResource _wateringCan;
|
[Export] private ItemResource _wateringCan;
|
||||||
@@ -20,34 +22,32 @@ public partial class VesnaBehaviour2D : Node
|
|||||||
|
|
||||||
[Signal] public delegate void InventorySelectionChangedEventHandler(int toolId);
|
[Signal] public delegate void InventorySelectionChangedEventHandler(int toolId);
|
||||||
|
|
||||||
private InventoryManager _inventoryManager;
|
//private InventoryManager _inventoryManager;
|
||||||
private InventoryInstance _inventoryInstance;
|
private VesnaEntity _vesnaEntity;
|
||||||
|
private InventoryInstance _playerInventory;
|
||||||
|
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
_inventoryManager = InventoryManager.Instance;
|
_vesnaEntity = EntityManager.Instance.GetUniqueEntity<VesnaEntity>();
|
||||||
_inventoryInstance = _inventoryManager.playerInventory;
|
_playerInventory = _vesnaEntity.inventory;
|
||||||
_inventoryManager.SlotIndexChanged += HandleInventorySelectedSlotIndexChanged;
|
_vesnaEntity.SlotIndexChanged += HandleInventorySelectedSlotIndexChanged;
|
||||||
|
_playerInventory.InventoryContentsChanged += UpdateToolInHand;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void _ExitTree()
|
public override void _ExitTree()
|
||||||
{
|
{
|
||||||
_inventoryManager.SlotIndexChanged -= HandleInventorySelectedSlotIndexChanged;
|
_vesnaEntity.SlotIndexChanged -= HandleInventorySelectedSlotIndexChanged;
|
||||||
|
_playerInventory.InventoryContentsChanged -= UpdateToolInHand;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
private void HandleInventorySelectedSlotIndexChanged(int _ = 0)
|
||||||
/// Called when picking up an item.
|
|
||||||
/// Makes sure that item animations are also updated when they are occupying a currently empty spot.
|
|
||||||
/// </summary>
|
|
||||||
public void HandlePickUp()
|
|
||||||
{
|
{
|
||||||
//Calls the same event handler as the inventory to ensure the currently selected item is updated in the animation.
|
UpdateToolInHand();
|
||||||
HandleInventorySelectedSlotIndexChanged(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleInventorySelectedSlotIndexChanged(int newIndex = 0)
|
private void UpdateToolInHand()
|
||||||
{
|
{
|
||||||
InventorySlot currentSlot = InventoryManager.Instance.GetCurrentSelectedSlot();
|
InventorySlot currentSlot = _playerInventory.Slots[_vesnaEntity.CurrentSelectedSlotIndex];
|
||||||
ItemInstance? currentItem = currentSlot.itemInstance;
|
ItemInstance? currentItem = currentSlot.itemInstance;
|
||||||
|
|
||||||
int toolId = -1;
|
int toolId = -1;
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ using System.Diagnostics;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Babushka.scripts.CSharp.Common.Inventory;
|
using Babushka.scripts.CSharp.Common.Inventory;
|
||||||
using Babushka.scripts.CSharp.Common.Util;
|
using Babushka.scripts.CSharp.Common.Util;
|
||||||
|
using Babushka.scripts.CSharp.GameEntity.Entities;
|
||||||
|
using Babushka.scripts.CSharp.GameEntity.Management;
|
||||||
|
|
||||||
namespace Babushka.scripts.CSharp.Common.Fight.Actions;
|
namespace Babushka.scripts.CSharp.Common.Fight.Actions;
|
||||||
|
|
||||||
@@ -17,7 +19,7 @@ public class EatBeetrootAction : FighterAction
|
|||||||
{
|
{
|
||||||
Debug.Assert(FightWorld.Instance.itemBeetrootToEatForHealth != null,
|
Debug.Assert(FightWorld.Instance.itemBeetrootToEatForHealth != null,
|
||||||
"Item to eat for health has not been set in the FightWorld autoload");
|
"Item to eat for health has not been set in the FightWorld autoload");
|
||||||
return !InventoryManager.Instance.playerInventory!.HasItems(new ItemInstance
|
return !EntityManager.Instance.GetUniqueEntity<VesnaEntity>().inventory.HasItems(new ItemInstance
|
||||||
{ blueprint = FightWorld.Instance.itemBeetrootToEatForHealth });
|
{ blueprint = FightWorld.Instance.itemBeetrootToEatForHealth });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,7 +37,7 @@ public class EatBeetrootAction : FighterAction
|
|||||||
{
|
{
|
||||||
var fighter = HappeningData.fighterTurn.Current;
|
var fighter = HappeningData.fighterTurn.Current;
|
||||||
|
|
||||||
var result = InventoryManager.Instance.playerInventory!.TryRemoveAllItems(
|
var result = EntityManager.Instance.GetUniqueEntity<VesnaEntity>().inventory.TryRemoveAllItems(
|
||||||
new ItemInstance { blueprint = FightWorld.Instance.itemBeetrootToEatForHealth! });
|
new ItemInstance { blueprint = FightWorld.Instance.itemBeetrootToEatForHealth! });
|
||||||
|
|
||||||
if (result != InventoryActionResult.Success)
|
if (result != InventoryActionResult.Success)
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
using Babushka.scripts.CSharp.Common.Inventory;
|
using Babushka.scripts.CSharp.Common.Inventory;
|
||||||
|
using Babushka.scripts.CSharp.GameEntity.Entities;
|
||||||
|
using Babushka.scripts.CSharp.GameEntity.Management;
|
||||||
using Godot;
|
using Godot;
|
||||||
|
|
||||||
namespace Babushka.scripts.CSharp.Common.Fight.UI;
|
namespace Babushka.scripts.CSharp.Common.Fight.UI;
|
||||||
@@ -9,7 +11,7 @@ public partial class HealButtonVisual : Button
|
|||||||
|
|
||||||
public void UpdateText()
|
public void UpdateText()
|
||||||
{
|
{
|
||||||
var healItemsLeft = InventoryManager.Instance.playerInventory!.TotalItemsOfBlueprint(_healItemBlueprint);
|
var healItemsLeft = EntityManager.Instance.GetUniqueEntity<VesnaEntity>().inventory.TotalItemsOfBlueprint(_healItemBlueprint);
|
||||||
Text = $"x{healItemsLeft} - Heal";
|
Text = $"x{healItemsLeft} - Heal";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4,24 +4,21 @@ using Godot;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Babushka.scripts.CSharp.Common.Savegame;
|
using Babushka.scripts.CSharp.Common.Savegame;
|
||||||
|
using Babushka.scripts.CSharp.GameEntity.LoadSave;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
namespace Babushka.scripts.CSharp.Common.Inventory;
|
namespace Babushka.scripts.CSharp.Common.Inventory;
|
||||||
|
|
||||||
public partial class InventoryInstance : Node, ISaveable
|
public partial class InventoryInstance : IJsonSerializable
|
||||||
{
|
{
|
||||||
private List<InventorySlot> _slots = new();
|
private readonly List<InventorySlot> _slots;
|
||||||
public IReadOnlyList<InventorySlot> Slots => _slots;
|
public IReadOnlyList<InventorySlot> Slots => _slots;
|
||||||
|
|
||||||
[Signal]
|
public event Action? SlotAmountChanged;
|
||||||
public delegate void SlotAmountChangedEventHandler();
|
public event Action? InventoryContentsChanged;
|
||||||
|
|
||||||
[Signal]
|
|
||||||
public delegate void InventoryContentsChangedEventHandler();
|
|
||||||
|
|
||||||
public static string ID = "inventoryInstance";
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The total amount of Inventoryslots in the inventory (empty and occupied).
|
/// The total amount of InventorySlots in the inventory (empty and occupied).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Export]
|
[Export]
|
||||||
public int SlotAmount
|
public int SlotAmount
|
||||||
@@ -41,29 +38,20 @@ public partial class InventoryInstance : Node, ISaveable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EmitSignal(SignalName.SlotAmountChanged);
|
SlotAmountChanged?.Invoke();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void _EnterTree()
|
public InventoryInstance(int slotCount)
|
||||||
{
|
{
|
||||||
LoadFromSaveData();
|
_slots = new();
|
||||||
InventoryContentsChanged += UpdateSaveData;
|
SlotAmount = slotCount;
|
||||||
SlotAmountChanged += UpdateSaveData;
|
|
||||||
SavegameService.OnSaveGameReset += SaveGameReset;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void _ExitTree()
|
|
||||||
{
|
|
||||||
InventoryContentsChanged -= UpdateSaveData;
|
|
||||||
SlotAmountChanged -= UpdateSaveData;
|
|
||||||
SavegameService.OnSaveGameReset -= SaveGameReset;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public InventoryActionResult AddItem(ItemInstance newItem)
|
public InventoryActionResult AddItem(ItemInstance newItem)
|
||||||
{
|
{
|
||||||
var result = AddItemAndStackRecursive(newItem, 0);
|
var result = AddItemAndStackRecursive(newItem, 0);
|
||||||
EmitSignal(SignalName.InventoryContentsChanged);
|
InventoryContentsChanged?.Invoke();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,7 +125,7 @@ public partial class InventoryInstance : Node, ISaveable
|
|||||||
if (itemInstance.amount == 0)
|
if (itemInstance.amount == 0)
|
||||||
_slots[inventorySlot].itemInstance = null;
|
_slots[inventorySlot].itemInstance = null;
|
||||||
|
|
||||||
EmitSignal(SignalName.InventoryContentsChanged);
|
InventoryContentsChanged?.Invoke();
|
||||||
return InventoryActionResult.Success;
|
return InventoryActionResult.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,7 +140,7 @@ public partial class InventoryInstance : Node, ISaveable
|
|||||||
if (hasItemsCount < items.amount)
|
if (hasItemsCount < items.amount)
|
||||||
return InventoryActionResult.SourceDoesNotExist;
|
return InventoryActionResult.SourceDoesNotExist;
|
||||||
|
|
||||||
var amountToRemove = items.amount;
|
var amountToRemove = items.amount;
|
||||||
foreach (var s in _slots)
|
foreach (var s in _slots)
|
||||||
{
|
{
|
||||||
if (s.IsEmpty() || s.itemInstance!.blueprint != items.blueprint)
|
if (s.IsEmpty() || s.itemInstance!.blueprint != items.blueprint)
|
||||||
@@ -173,8 +161,8 @@ public partial class InventoryInstance : Node, ISaveable
|
|||||||
if (amountToRemove == 0)
|
if (amountToRemove == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
EmitSignal(SignalName.InventoryContentsChanged);
|
InventoryContentsChanged?.Invoke();
|
||||||
return InventoryActionResult.Success;
|
return InventoryActionResult.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,7 +175,7 @@ public partial class InventoryInstance : Node, ISaveable
|
|||||||
return InventoryActionResult.DestinationFull;
|
return InventoryActionResult.DestinationFull;
|
||||||
|
|
||||||
_slots[destinationSlot].itemInstance = itemInstance;
|
_slots[destinationSlot].itemInstance = itemInstance;
|
||||||
EmitSignal(SignalName.InventoryContentsChanged);
|
InventoryContentsChanged?.Invoke();
|
||||||
return InventoryActionResult.Success;
|
return InventoryActionResult.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,61 +196,26 @@ public partial class InventoryInstance : Node, ISaveable
|
|||||||
return items.All(HasItems);
|
return items.All(HasItems);
|
||||||
}
|
}
|
||||||
|
|
||||||
#region SAVE AND LOAD
|
public void LoadFromJson(JObject json)
|
||||||
|
|
||||||
public void UpdateSaveData()
|
|
||||||
{
|
{
|
||||||
var payloadData = new Godot.Collections.Dictionary<string, Variant>();
|
var itemsArray = (JArray?)json["items"];
|
||||||
|
if (itemsArray == null) return;
|
||||||
|
|
||||||
for (int i = 0; i < _slots.Count; i++)
|
foreach (var (itemToken, slot) in itemsArray.Zip(_slots))
|
||||||
{
|
{
|
||||||
if (!_slots[i].IsEmpty())
|
var itemObj = (JObject?)itemToken;
|
||||||
{
|
if (itemObj == null) continue;
|
||||||
string key = i.ToString();
|
slot.LoadFromJson(itemObj);
|
||||||
string[] value = new string[2];
|
|
||||||
value[0] = _slots[i].itemInstance.blueprint.ResourcePath;
|
|
||||||
value[1] = _slots[i].itemInstance.amount.ToString();
|
|
||||||
payloadData.Add(key, value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SavegameService.AppendDataToSave(ID, payloadData);
|
InventoryContentsChanged?.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LoadFromSaveData()
|
public JObject SaveToJson()
|
||||||
{
|
{
|
||||||
var id = ID;
|
return new JObject
|
||||||
|
|
||||||
Godot.Collections.Dictionary<string, Variant> save = SavegameService.GetSaveData(id);
|
|
||||||
|
|
||||||
if (save.Count > 0)
|
|
||||||
{
|
{
|
||||||
for (int i = 0; i < _slots.Count; i++)
|
["items"] = new JArray(_slots.Select(s => s.SaveToJson()))
|
||||||
{
|
};
|
||||||
if (save.TryGetValue(i.ToString(), out Variant inventoryItemData))
|
|
||||||
{
|
|
||||||
string[] savePayload = inventoryItemData.AsStringArray();
|
|
||||||
ItemResource resource = ResourceLoader.Load<ItemResource>(savePayload[0]);
|
|
||||||
int _amount = int.Parse(savePayload[1]);
|
|
||||||
|
|
||||||
ItemInstance instance = new ItemInstance { blueprint = resource, amount = _amount };
|
|
||||||
AddItem(instance);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Called when a new save is created.
|
|
||||||
/// Needs to do a runtime check because the InventoryInstance is already in existence at the beginning of the first scene.
|
|
||||||
/// </summary>
|
|
||||||
private void SaveGameReset()
|
|
||||||
{
|
|
||||||
foreach (var slot in _slots)
|
|
||||||
{
|
|
||||||
slot.itemInstance = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
using Babushka.scripts.CSharp.GameEntity.Entities;
|
||||||
|
using Babushka.scripts.CSharp.GameEntity.Management;
|
||||||
using Godot;
|
using Godot;
|
||||||
|
|
||||||
namespace Babushka.scripts.CSharp.Common.Inventory;
|
namespace Babushka.scripts.CSharp.Common.Inventory;
|
||||||
@@ -8,16 +10,25 @@ public partial class InventoryListener : Node
|
|||||||
|
|
||||||
[Signal] public delegate void ItemInstanceActivatedEventHandler(bool activated);
|
[Signal] public delegate void ItemInstanceActivatedEventHandler(bool activated);
|
||||||
|
|
||||||
|
private VesnaEntity _vesnaEntity;
|
||||||
|
private InventoryInstance _playerInventory;
|
||||||
|
|
||||||
|
public override void _EnterTree()
|
||||||
|
{
|
||||||
|
_vesnaEntity = EntityManager.Instance.GetUniqueEntity<VesnaEntity>();
|
||||||
|
_playerInventory = _vesnaEntity.inventory;
|
||||||
|
}
|
||||||
|
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
InventoryManager.Instance.playerInventory.InventoryContentsChanged += HandleNewItemInInventory;
|
_playerInventory.InventoryContentsChanged += HandleNewItemInInventory;
|
||||||
InventoryManager.Instance.SlotIndexChanged += HandleNewItemInInventory;
|
_vesnaEntity.SlotIndexChanged += HandleNewItemInInventory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void _ExitTree()
|
public override void _ExitTree()
|
||||||
{
|
{
|
||||||
InventoryManager.Instance.playerInventory.InventoryContentsChanged -= HandleNewItemInInventory;
|
_playerInventory.InventoryContentsChanged -= HandleNewItemInInventory;
|
||||||
InventoryManager.Instance.SlotIndexChanged -= HandleNewItemInInventory;
|
_vesnaEntity.SlotIndexChanged -= HandleNewItemInInventory;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleNewItemInInventory(int newIndex)
|
private void HandleNewItemInInventory(int newIndex)
|
||||||
@@ -27,8 +38,8 @@ public partial class InventoryListener : Node
|
|||||||
|
|
||||||
private void HandleNewItemInInventory()
|
private void HandleNewItemInInventory()
|
||||||
{
|
{
|
||||||
int currentSlotIndex = InventoryManager.Instance.CurrentSelectedSlotIndex;
|
int currentSlotIndex = _vesnaEntity.CurrentSelectedSlotIndex;
|
||||||
ItemInstance? instance = InventoryManager.Instance.playerInventory.Slots[currentSlotIndex].itemInstance;
|
ItemInstance? instance = _playerInventory.Slots[currentSlotIndex].itemInstance;
|
||||||
if (instance != null)
|
if (instance != null)
|
||||||
{
|
{
|
||||||
ItemResource? item = instance.blueprint;
|
ItemResource? item = instance.blueprint;
|
||||||
|
|||||||
@@ -5,25 +5,8 @@ namespace Babushka.scripts.CSharp.Common.Inventory;
|
|||||||
|
|
||||||
public partial class InventoryManager : Node
|
public partial class InventoryManager : Node
|
||||||
{
|
{
|
||||||
[Signal]
|
|
||||||
public delegate void SlotIndexChangedEventHandler(int newIndex);
|
|
||||||
|
|
||||||
|
|
||||||
public static InventoryManager Instance { get; private set; } = null!;
|
public static InventoryManager Instance { get; private set; } = null!;
|
||||||
public int CurrentSelectedSlotIndex
|
|
||||||
{
|
|
||||||
get => _currentSelectedSlotIndex;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (value >= 0 && value <= 8)
|
|
||||||
{
|
|
||||||
_currentSelectedSlotIndex = value;
|
|
||||||
EmitSignalSlotIndexChanged(_currentSelectedSlotIndex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public InventoryInstance? playerInventory;
|
|
||||||
|
|
||||||
private int _currentSelectedSlotIndex = 0;
|
private int _currentSelectedSlotIndex = 0;
|
||||||
|
|
||||||
@@ -34,9 +17,6 @@ public partial class InventoryManager : Node
|
|||||||
|
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
playerInventory = new InventoryInstance();
|
|
||||||
playerInventory.SlotAmount = 37;
|
|
||||||
AddChild(playerInventory);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public InventoryActionResult CreateItem(
|
public InventoryActionResult CreateItem(
|
||||||
@@ -82,19 +62,4 @@ public partial class InventoryManager : Node
|
|||||||
{
|
{
|
||||||
return inventory.RemoveItem(inventorySlot);
|
return inventory.RemoveItem(inventorySlot);
|
||||||
}
|
}
|
||||||
|
|
||||||
public InventoryActionResult CollectItem(ItemInstance itemInstance)
|
|
||||||
{
|
|
||||||
return playerInventory.AddItem(itemInstance);
|
|
||||||
}
|
|
||||||
|
|
||||||
public InventorySlot GetCurrentSelectedSlot()
|
|
||||||
{
|
|
||||||
if (CurrentSelectedSlotIndex < 0 || CurrentSelectedSlotIndex > 8)
|
|
||||||
throw new ArgumentOutOfRangeException(
|
|
||||||
nameof(CurrentSelectedSlotIndex),
|
|
||||||
"currentInventoryBarIndex must be between 0 and 8 (inclusively)");
|
|
||||||
|
|
||||||
return playerInventory.Slots[CurrentSelectedSlotIndex];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
#nullable enable
|
#nullable enable
|
||||||
|
using Babushka.scripts.CSharp.GameEntity.LoadSave;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
namespace Babushka.scripts.CSharp.Common.Inventory;
|
namespace Babushka.scripts.CSharp.Common.Inventory;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a virtual object wrapper for an item instance.
|
/// Represents a virtual object wrapper for an item instance.
|
||||||
/// Can return the containing item or null.
|
/// Can return the containing item or null.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class InventorySlot
|
public class InventorySlot: IJsonSerializable
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The inventory item instance that may or may not be bound to this slot.
|
/// The inventory item instance that may or may not be bound to this slot.
|
||||||
@@ -20,5 +23,27 @@ public class InventorySlot
|
|||||||
{
|
{
|
||||||
return itemInstance == null;
|
return itemInstance == null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void LoadFromJson(JObject json)
|
||||||
|
{
|
||||||
|
var itemJson = json.Value<JObject>("item");
|
||||||
|
if (itemJson != null)
|
||||||
|
{
|
||||||
|
itemInstance = new ItemInstance();
|
||||||
|
itemInstance.LoadFromJson(itemJson);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
itemInstance = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public JObject SaveToJson()
|
||||||
|
{
|
||||||
|
return new JObject()
|
||||||
|
{
|
||||||
|
["item"] = itemInstance?.SaveToJson()
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
using Godot;
|
using Babushka.scripts.CSharp.GameEntity.Entities;
|
||||||
|
using Babushka.scripts.CSharp.GameEntity.Management;
|
||||||
|
using Godot;
|
||||||
namespace Babushka.scripts.CSharp.Common.Inventory;
|
namespace Babushka.scripts.CSharp.Common.Inventory;
|
||||||
|
|
||||||
public partial class InventoryTestScript : Node
|
public partial class InventoryTestScript : Node
|
||||||
@@ -10,7 +12,7 @@ public partial class InventoryTestScript : Node
|
|||||||
{
|
{
|
||||||
foreach (var itemResource in _testItemsToCreate)
|
foreach (var itemResource in _testItemsToCreate)
|
||||||
{
|
{
|
||||||
InventoryManager.Instance.CreateItem(itemResource, InventoryManager.Instance.playerInventory);
|
InventoryManager.Instance.CreateItem(itemResource, EntityManager.Instance.GetUniqueEntity<VesnaEntity>().inventory);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
using Babushka.scripts.CSharp.GameEntity.Entities;
|
||||||
|
using Babushka.scripts.CSharp.GameEntity.Management;
|
||||||
using Godot;
|
using Godot;
|
||||||
|
|
||||||
namespace Babushka.scripts.CSharp.Common.Inventory;
|
namespace Babushka.scripts.CSharp.Common.Inventory;
|
||||||
@@ -10,6 +12,7 @@ public partial class InventoryUi : Control
|
|||||||
[Export] private Control _slotSelect;
|
[Export] private Control _slotSelect;
|
||||||
|
|
||||||
private InventoryInstance _playerInventory;
|
private InventoryInstance _playerInventory;
|
||||||
|
private VesnaEntity _vesnaEntity;
|
||||||
private int? _slotOnMouse;
|
private int? _slotOnMouse;
|
||||||
private bool _inventoryExtended = false;
|
private bool _inventoryExtended = false;
|
||||||
private Tween? _inventoryExtensionTween;
|
private Tween? _inventoryExtensionTween;
|
||||||
@@ -18,17 +21,18 @@ public partial class InventoryUi : Control
|
|||||||
|
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
_playerInventory = InventoryManager.Instance.playerInventory;
|
_vesnaEntity = EntityManager.Instance.GetUniqueEntity<VesnaEntity>();
|
||||||
|
_playerInventory = _vesnaEntity.inventory;
|
||||||
//PopulateSlots();
|
//PopulateSlots();
|
||||||
SubscribeSlots();
|
SubscribeSlots();
|
||||||
SetSlotContent();
|
SetSlotContent();
|
||||||
SetSlotSelectPosition();
|
SetSlotSelectPosition();
|
||||||
InventoryManager.Instance.playerInventory.InventoryContentsChanged += SetSlotContent;
|
_playerInventory.InventoryContentsChanged += SetSlotContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void _ExitTree()
|
public override void _ExitTree()
|
||||||
{
|
{
|
||||||
InventoryManager.Instance.playerInventory.InventoryContentsChanged -= SetSlotContent;
|
_playerInventory.InventoryContentsChanged -= SetSlotContent;
|
||||||
UnsubscribeSlots();
|
UnsubscribeSlots();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,7 +79,7 @@ public partial class InventoryUi : Control
|
|||||||
|
|
||||||
private void SetSlotSelectPosition()
|
private void SetSlotSelectPosition()
|
||||||
{
|
{
|
||||||
_slotSelect.GlobalPosition = _headerSlots[InventoryManager.Instance.CurrentSelectedSlotIndex].GlobalPosition;
|
_slotSelect.GlobalPosition = _headerSlots[_vesnaEntity.CurrentSelectedSlotIndex].GlobalPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PopulateSlots()
|
private void PopulateSlots()
|
||||||
@@ -147,17 +151,17 @@ public partial class InventoryUi : Control
|
|||||||
|
|
||||||
if (Input.IsActionJustPressed("ui_inventory_disadvance"))
|
if (Input.IsActionJustPressed("ui_inventory_disadvance"))
|
||||||
{
|
{
|
||||||
InventoryManager.Instance.CurrentSelectedSlotIndex++;
|
_vesnaEntity.CurrentSelectedSlotIndex++;
|
||||||
if (InventoryManager.Instance.CurrentSelectedSlotIndex > 8)
|
if (_vesnaEntity.CurrentSelectedSlotIndex > 8)
|
||||||
InventoryManager.Instance.CurrentSelectedSlotIndex = 0;
|
_vesnaEntity.CurrentSelectedSlotIndex = 0;
|
||||||
SetSlotSelectPosition();
|
SetSlotSelectPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Input.IsActionJustPressed("ui_inventory_advance"))
|
if (Input.IsActionJustPressed("ui_inventory_advance"))
|
||||||
{
|
{
|
||||||
InventoryManager.Instance.CurrentSelectedSlotIndex--;
|
_vesnaEntity.CurrentSelectedSlotIndex--;
|
||||||
if (InventoryManager.Instance.CurrentSelectedSlotIndex < 0)
|
if (_vesnaEntity.CurrentSelectedSlotIndex < 0)
|
||||||
InventoryManager.Instance.CurrentSelectedSlotIndex = 8;
|
_vesnaEntity.CurrentSelectedSlotIndex = 8;
|
||||||
SetSlotSelectPosition();
|
SetSlotSelectPosition();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
|
using Babushka.scripts.CSharp.GameEntity.LoadSave;
|
||||||
using Godot;
|
using Godot;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
namespace Babushka.scripts.CSharp.Common.Inventory;
|
namespace Babushka.scripts.CSharp.Common.Inventory;
|
||||||
|
|
||||||
// Do not instantiate this resource
|
// Do not instantiate this resource
|
||||||
// But it has to be a resource because Godot
|
// But it has to be a resource because Godot
|
||||||
[GlobalClass]
|
[GlobalClass]
|
||||||
public partial class ItemInstance: Resource
|
public partial class ItemInstance : Resource, IJsonSerializable
|
||||||
{
|
{
|
||||||
[Export] public required ItemResource blueprint;
|
[Export] public ItemResource blueprint;
|
||||||
[Export] public int amount = 1;
|
[Export] public int amount = 1;
|
||||||
|
|
||||||
public ItemInstance Clone()
|
public ItemInstance Clone()
|
||||||
@@ -17,4 +20,18 @@ public partial class ItemInstance: Resource
|
|||||||
amount = amount
|
amount = amount
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public void LoadFromJson(JObject json)
|
||||||
|
{
|
||||||
|
var blueprintPath = json.GetStringValue("blueprint");
|
||||||
|
blueprint = GD.Load<ItemResource>(blueprintPath);
|
||||||
|
amount = json.GetIntValue("amount");
|
||||||
|
}
|
||||||
|
|
||||||
|
public JObject SaveToJson()
|
||||||
|
{
|
||||||
|
return new(
|
||||||
|
new JProperty("blueprint", blueprint.ResourcePath),
|
||||||
|
new JProperty("amount", amount));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
using Babushka.scripts.CSharp.Common.Savegame;
|
using Babushka.scripts.CSharp.Common.Savegame;
|
||||||
|
using Babushka.scripts.CSharp.GameEntity.Entities;
|
||||||
|
using Babushka.scripts.CSharp.GameEntity.Management;
|
||||||
using Godot;
|
using Godot;
|
||||||
using Godot.Collections;
|
using Godot.Collections;
|
||||||
|
|
||||||
@@ -44,7 +46,7 @@ public partial class ItemOnGround2D : Node, ISaveable
|
|||||||
if (!IsActive)
|
if (!IsActive)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var result = InventoryManager.Instance.CollectItem(itemInstance.Clone());
|
var result = EntityManager.Instance.GetUniqueEntity<VesnaEntity>().inventory.AddItem(itemInstance.Clone());
|
||||||
EmitSignal(SignalName.SuccessfulPickUp);
|
EmitSignal(SignalName.SuccessfulPickUp);
|
||||||
if (result == InventoryActionResult.Success)
|
if (result == InventoryActionResult.Success)
|
||||||
{
|
{
|
||||||
@@ -111,51 +113,54 @@ public partial class ItemOnGround2D : Node, ISaveable
|
|||||||
|
|
||||||
public void LoadFromSaveData()
|
public void LoadFromSaveData()
|
||||||
{
|
{
|
||||||
if (!_saveToDisk)
|
// WON'T FIX - WILL BE REDONE ANYWAY
|
||||||
return;
|
|
||||||
|
|
||||||
if (_infiniteSupply)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// standard check: how many times has this item been collected?
|
|
||||||
string id = GetMeta("SaveID").AsString();
|
|
||||||
|
|
||||||
Dictionary<string, Variant> save = SavegameService.GetSaveData(id);
|
|
||||||
if (save.Count > 0)
|
|
||||||
{
|
|
||||||
if(save.TryGetValue("pickupCounter", out Variant countVar))
|
|
||||||
{
|
|
||||||
int count = countVar.AsInt32();
|
|
||||||
for (int i = 0; i < count; i++)
|
|
||||||
{
|
|
||||||
Pickup();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
//if (!_saveToDisk)
|
||||||
|
// return;
|
||||||
|
//
|
||||||
|
//if (_infiniteSupply)
|
||||||
|
// return;
|
||||||
|
//
|
||||||
|
//// standard check: how many times has this item been collected?
|
||||||
|
//string id = GetMeta("SaveID").AsString();
|
||||||
|
//
|
||||||
|
//Dictionary<string, Variant> save = SavegameService.GetSaveData(id);
|
||||||
|
//if (save.Count > 0)
|
||||||
|
//{
|
||||||
|
// if(save.TryGetValue("pickupCounter", out Variant countVar))
|
||||||
|
// {
|
||||||
|
// int count = countVar.AsInt32();
|
||||||
|
// for (int i = 0; i < count; i++)
|
||||||
|
// {
|
||||||
|
// Pickup();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
//
|
||||||
//separate check for unique items: If already in inventory, delete this instance.
|
//separate check for unique items: If already in inventory, delete this instance.
|
||||||
ItemResource itemResource = itemInstance.blueprint;
|
//ItemResource itemResource = itemInstance.blueprint;
|
||||||
Dictionary<string, Variant> savegameData = SavegameService.GetSaveData(InventoryInstance.ID);
|
//Dictionary<string, Variant> savegameData = SavegameService.GetSaveData(InventoryInstance.ID);
|
||||||
if (savegameData.Count > 0)
|
//if (savegameData.Count > 0)
|
||||||
{
|
//{
|
||||||
foreach (var kvp in savegameData)
|
// foreach (var kvp in savegameData)
|
||||||
{
|
// {
|
||||||
// if it's a unique item, then it can only exist once in the world (either as a pickup OR in the inventory)
|
// // if it's a unique item, then it can only exist once in the world (either as a pickup OR in the inventory)
|
||||||
if (itemInstance.blueprint.isUnique)
|
// if (itemInstance.blueprint.isUnique)
|
||||||
{
|
// {
|
||||||
//comparing resource path to identify the item
|
// //comparing resource path to identify the item
|
||||||
string[] valuePair = kvp.Value.AsStringArray();
|
// string[] valuePair = kvp.Value.AsStringArray();
|
||||||
if (valuePair[0] == itemResource.ResourcePath)
|
// if (valuePair[0] == itemResource.ResourcePath)
|
||||||
{
|
// {
|
||||||
int amountInInventory = int.Parse(valuePair[1]);
|
// int amountInInventory = int.Parse(valuePair[1]);
|
||||||
// comparing amount to see if it's all in the inventory now.
|
// // comparing amount to see if it's all in the inventory now.
|
||||||
if (amountInInventory > 0)
|
// if (amountInInventory > 0)
|
||||||
{
|
// {
|
||||||
Pickup();
|
// Pickup();
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
using Godot;
|
using Babushka.scripts.CSharp.GameEntity.LoadSave;
|
||||||
|
using Godot;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
namespace Babushka.scripts.CSharp.Common.Inventory;
|
namespace Babushka.scripts.CSharp.Common.Inventory;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
using Babushka.scripts.CSharp.Common.CharacterControls;
|
using Babushka.scripts.CSharp.Common.CharacterControls;
|
||||||
using Babushka.scripts.CSharp.Common.Inventory;
|
using Babushka.scripts.CSharp.Common.Inventory;
|
||||||
|
using Babushka.scripts.CSharp.GameEntity.Entities;
|
||||||
|
using Babushka.scripts.CSharp.GameEntity.Management;
|
||||||
using Godot;
|
using Godot;
|
||||||
using Godot.Collections;
|
using Godot.Collections;
|
||||||
|
|
||||||
@@ -10,21 +12,21 @@ public partial class InventoryDependentInteractable : Node2D
|
|||||||
[Export] private InteractionArea2D _interactionArea;
|
[Export] private InteractionArea2D _interactionArea;
|
||||||
[Export] private Array<ItemResource> _itemsToReactTo;
|
[Export] private Array<ItemResource> _itemsToReactTo;
|
||||||
[Export] private bool _activateOnItem = true;
|
[Export] private bool _activateOnItem = true;
|
||||||
|
|
||||||
private InventoryManager _inventoryManager;
|
private VesnaEntity _vesnaEntity;
|
||||||
private InventoryInstance _inventoryInstance;
|
private InventoryInstance _playerInventory;
|
||||||
|
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
_inventoryManager = InventoryManager.Instance;
|
_vesnaEntity = EntityManager.Instance.GetUniqueEntity<VesnaEntity>();
|
||||||
_inventoryInstance = _inventoryManager.playerInventory;
|
_playerInventory = _vesnaEntity.inventory;
|
||||||
_inventoryManager.SlotIndexChanged += HandleInventorySelectedSlotIndexChanged;
|
_vesnaEntity.SlotIndexChanged += HandleInventorySelectedSlotIndexChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleInventorySelectedSlotIndexChanged(int newIndex)
|
private void HandleInventorySelectedSlotIndexChanged(int newIndex)
|
||||||
{
|
{
|
||||||
int currentSlotIndex = InventoryManager.Instance.CurrentSelectedSlotIndex;
|
int currentSlotIndex = _vesnaEntity.CurrentSelectedSlotIndex;
|
||||||
ItemInstance? item = InventoryManager.Instance.playerInventory.Slots[currentSlotIndex].itemInstance;
|
ItemInstance? item = _playerInventory.Slots[currentSlotIndex].itemInstance;
|
||||||
|
|
||||||
if (item != null)
|
if (item != null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Babushka.scripts.CSharp.Common.Inventory;
|
using Babushka.scripts.CSharp.Common.Inventory;
|
||||||
using Babushka.scripts.CSharp.Common.Quest;
|
using Babushka.scripts.CSharp.Common.Quest;
|
||||||
|
using Babushka.scripts.CSharp.GameEntity.Entities;
|
||||||
|
using Babushka.scripts.CSharp.GameEntity.Management;
|
||||||
|
|
||||||
public partial class DetectInventoryContains : QuestFulfillmentBase
|
public partial class DetectInventoryContains : QuestFulfillmentBase
|
||||||
{
|
{
|
||||||
@@ -12,7 +14,7 @@ public partial class DetectInventoryContains : QuestFulfillmentBase
|
|||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
QuestManager.Instance!.QuestsChanged += CheckInventory;
|
QuestManager.Instance!.QuestsChanged += CheckInventory;
|
||||||
InventoryManager.Instance.playerInventory.InventoryContentsChanged += CheckInventory;
|
EntityManager.Instance.GetUniqueEntity<VesnaEntity>().inventory.InventoryContentsChanged += CheckInventory;
|
||||||
|
|
||||||
CheckInventory();
|
CheckInventory();
|
||||||
}
|
}
|
||||||
@@ -20,12 +22,12 @@ public partial class DetectInventoryContains : QuestFulfillmentBase
|
|||||||
public override void _ExitTree()
|
public override void _ExitTree()
|
||||||
{
|
{
|
||||||
QuestManager.Instance!.QuestsChanged -= CheckInventory;
|
QuestManager.Instance!.QuestsChanged -= CheckInventory;
|
||||||
InventoryManager.Instance.playerInventory.InventoryContentsChanged -= CheckInventory;
|
EntityManager.Instance.GetUniqueEntity<VesnaEntity>().inventory.InventoryContentsChanged -= CheckInventory;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CheckInventory()
|
private void CheckInventory()
|
||||||
{
|
{
|
||||||
if (IsQuestActive() && InventoryManager.Instance.playerInventory.HasItems(_itemsToContain))
|
if (IsQuestActive() && EntityManager.Instance.GetUniqueEntity<VesnaEntity>().inventory.HasItems(_itemsToContain))
|
||||||
{
|
{
|
||||||
Fulfill();
|
Fulfill();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
using System;
|
||||||
|
using Babushka.scripts.CSharp.GameEntity.LoadSave;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
|
namespace Babushka.scripts.CSharp.GameEntity.Entities;
|
||||||
|
|
||||||
|
public class Entity
|
||||||
|
{
|
||||||
|
public long id;
|
||||||
|
public virtual string EntityType => "";
|
||||||
|
|
||||||
|
public Entity()
|
||||||
|
{
|
||||||
|
id = new Random().NextInt64();
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void SaveEntity(JObject json)
|
||||||
|
{
|
||||||
|
json["id"] = id;
|
||||||
|
json["type"] = EntityType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void LoadEntity(JObject json)
|
||||||
|
{
|
||||||
|
id = json.GetLongValue("id");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://hnmpt23ovfgl
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Transactions;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
|
namespace Babushka.scripts.CSharp.GameEntity.Entities;
|
||||||
|
|
||||||
|
public class LoadedScenesEntity : Entity
|
||||||
|
{
|
||||||
|
private HashSet<string> _loadedScenes = new();
|
||||||
|
public override string EntityType => OWN_TYPE_NAME;
|
||||||
|
public const string OWN_TYPE_NAME = "LoadedScenesEntity";
|
||||||
|
|
||||||
|
public void AddScene(string sceneName) => _loadedScenes.Add(sceneName);
|
||||||
|
|
||||||
|
public bool WasSceneLoaded(string sceneName) => _loadedScenes.Contains(sceneName);
|
||||||
|
|
||||||
|
public override void SaveEntity(JObject json)
|
||||||
|
{
|
||||||
|
base.SaveEntity(json);
|
||||||
|
json["scenes"] = new JArray(_loadedScenes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void LoadEntity(JObject json)
|
||||||
|
{
|
||||||
|
base.LoadEntity(json);
|
||||||
|
JArray array = (JArray?) json["scenes"] ?? throw new Exception("No scenes found in LoadedScenesEntity.");
|
||||||
|
|
||||||
|
_loadedScenes = array.ToObject<HashSet<string>>()!;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://rabb1y637cm5
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
using Babushka.scripts.CSharp.GameEntity.LoadSave;
|
||||||
|
using Godot;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
|
namespace Babushka.scripts.CSharp.GameEntity.Entities;
|
||||||
|
|
||||||
|
public abstract class PositionalEntity : Entity
|
||||||
|
{
|
||||||
|
public Vector2 position;
|
||||||
|
public string sceneName = "none";
|
||||||
|
|
||||||
|
public override void SaveEntity(JObject json)
|
||||||
|
{
|
||||||
|
base.SaveEntity(json);
|
||||||
|
json["posx"] = position.X;
|
||||||
|
json["posy"] = position.Y;
|
||||||
|
json["scene"] = sceneName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void LoadEntity(JObject json)
|
||||||
|
{
|
||||||
|
base.LoadEntity(json);
|
||||||
|
position = new Vector2(
|
||||||
|
json.GetFloatValue("posx"),
|
||||||
|
json.GetFloatValue("posy"));
|
||||||
|
sceneName = json.GetStringValue("scene");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deals with Instantiation of the node
|
||||||
|
public abstract void InstantiateEntityNode(Node2D parent);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://bs38dulqv7sop
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
using Babushka.scripts.CSharp.GameEntity.Management;
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
namespace Babushka.scripts.CSharp.GameEntity.Entities;
|
||||||
|
|
||||||
|
public class TrashEntity : PositionalEntity
|
||||||
|
{
|
||||||
|
public override string EntityType => OWN_TYPE_NAME;
|
||||||
|
public const string OWN_TYPE_NAME = "TrashEntity";
|
||||||
|
private EntityNodeCreator _creator;
|
||||||
|
|
||||||
|
public TrashEntity()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void InstantiateEntityNode(Node2D parent)
|
||||||
|
{
|
||||||
|
if(_creator == null) _creator = EntityManager.Instance.NodeCreator;
|
||||||
|
var entityNode = _creator.InstantiateNode(EntityType);
|
||||||
|
parent.AddChild(entityNode);
|
||||||
|
entityNode.GlobalPosition = position;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://c31k34epunk5t
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
using System;
|
||||||
|
using Babushka.scripts.CSharp.Common.Farming;
|
||||||
|
using Babushka.scripts.CSharp.Common.Inventory;
|
||||||
|
using Babushka.scripts.CSharp.GameEntity.Management;
|
||||||
|
using Godot;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
|
namespace Babushka.scripts.CSharp.GameEntity.Entities;
|
||||||
|
|
||||||
|
public class VesnaEntity : PositionalEntity
|
||||||
|
{
|
||||||
|
public override string EntityType => OWN_TYPE_NAME;
|
||||||
|
public const string OWN_TYPE_NAME = "VesnaEntity";
|
||||||
|
public readonly InventoryInstance inventory = new (37);
|
||||||
|
|
||||||
|
public event Action<int>? SlotIndexChanged;
|
||||||
|
|
||||||
|
private int _currentSelectedSlotIndex;
|
||||||
|
public int CurrentSelectedSlotIndex
|
||||||
|
{
|
||||||
|
get => _currentSelectedSlotIndex;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value >= 0 && value <= 8)
|
||||||
|
{
|
||||||
|
_currentSelectedSlotIndex = value;
|
||||||
|
SlotIndexChanged?.Invoke(_currentSelectedSlotIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public override void InstantiateEntityNode(Node2D parent)
|
||||||
|
{
|
||||||
|
var node = (VesnaBehaviour2D) EntityManager.Instance.NodeCreator.InstantiateNode(OWN_TYPE_NAME);
|
||||||
|
node.player2d.Initialize(this);
|
||||||
|
parent.AddChild(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SaveEntity(JObject json)
|
||||||
|
{
|
||||||
|
base.SaveEntity(json);
|
||||||
|
json["slot"] = CurrentSelectedSlotIndex;
|
||||||
|
json["inventory"] = inventory.SaveToJson();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void LoadEntity(JObject json)
|
||||||
|
{
|
||||||
|
base.LoadEntity(json);
|
||||||
|
CurrentSelectedSlotIndex = json.Value<int>("slot");
|
||||||
|
inventory.LoadFromJson(json.Value<JObject>("inventory")!);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://c7e45co1valv3
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
using Babushka.scripts.CSharp.GameEntity.Entities;
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
namespace Babushka.scripts.CSharp.GameEntity.EntityNodes;
|
||||||
|
|
||||||
|
public partial class TrashEntityNode : Node2D
|
||||||
|
{
|
||||||
|
private TrashEntity _trashEntity;
|
||||||
|
|
||||||
|
public void Initialize(TrashEntity trashEntity)
|
||||||
|
{
|
||||||
|
_trashEntity = trashEntity;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://d3n8kwva4pxx5
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
using Babushka.scripts.CSharp.GameEntity.Entities;
|
||||||
|
using Babushka.scripts.CSharp.GameEntity.Management;
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
namespace Babushka.scripts.CSharp.GameEntity.EntityPlacer;
|
||||||
|
|
||||||
|
public partial class TrashEntityPlacer : Node2D
|
||||||
|
{
|
||||||
|
private string _trashEntityType = TrashEntity.OWN_TYPE_NAME;
|
||||||
|
|
||||||
|
public override void _Ready()
|
||||||
|
{
|
||||||
|
string sceneName = EntityManager.Instance.CurrentEntitySceneContainer!.sceneName;
|
||||||
|
var loadedScenesEntity = EntityManager.Instance.GetUniqueEntity<LoadedScenesEntity>();
|
||||||
|
|
||||||
|
if (!loadedScenesEntity.WasSceneLoaded(sceneName))
|
||||||
|
{
|
||||||
|
TrashEntity entity = new TrashEntity();
|
||||||
|
entity.sceneName = sceneName;
|
||||||
|
entity.position = GlobalPosition;
|
||||||
|
EntityManager.Instance.AddEntity(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
QueueFree();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://bilg7e33usxuv
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
using Babushka.scripts.CSharp.GameEntity.Entities;
|
||||||
|
using Babushka.scripts.CSharp.GameEntity.Management;
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
namespace Babushka.scripts.CSharp.GameEntity.EntityPlacer;
|
||||||
|
|
||||||
|
public partial class VesnaEntityPlacer : Node2D
|
||||||
|
{
|
||||||
|
public override void _Ready()
|
||||||
|
{
|
||||||
|
var sceneName = EntityManager.Instance.CurrentEntitySceneContainer!.sceneName;
|
||||||
|
var entity = EntityManager.Instance.GetUniqueEntity<VesnaEntity>();
|
||||||
|
|
||||||
|
if (entity.sceneName != sceneName)
|
||||||
|
{
|
||||||
|
entity.position = GlobalPosition;
|
||||||
|
entity.sceneName = sceneName;
|
||||||
|
}
|
||||||
|
|
||||||
|
QueueFree();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://dcn4giw1auva4
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
|
namespace Babushka.scripts.CSharp.GameEntity.LoadSave;
|
||||||
|
|
||||||
|
public static class EntityLoadSaveUtil
|
||||||
|
{
|
||||||
|
private static void AssertTokenType(this JObject json, string key, JTokenType type)
|
||||||
|
{
|
||||||
|
var token = json[key];
|
||||||
|
if (token == null) throw new MalformedJsonException(json, key, "does not exist");
|
||||||
|
//if (!token.HasValues) throw new MalformedJsonException(json, key, "has no value");
|
||||||
|
if (token.Type != type) throw new MalformedJsonException(json, key, $"is not of type {type}");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long GetLongValue(this JObject json, string key)
|
||||||
|
{
|
||||||
|
AssertTokenType(json, key, JTokenType.Integer);
|
||||||
|
return json.Value<long>(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int GetIntValue(this JObject json, string key)
|
||||||
|
{
|
||||||
|
AssertTokenType(json, key, JTokenType.Integer);
|
||||||
|
return json.Value<int>(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float GetFloatValue(this JObject json, string key)
|
||||||
|
{
|
||||||
|
AssertTokenType(json, key, JTokenType.Float);
|
||||||
|
return json.Value<float>(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JObject GetObject(this JObject json, string key)
|
||||||
|
{
|
||||||
|
AssertTokenType(json, key, JTokenType.Object);
|
||||||
|
return json.Value<JObject>(key)!;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string GetStringValue(this JObject json, string key)
|
||||||
|
{
|
||||||
|
AssertTokenType(json, key, JTokenType.String);
|
||||||
|
return json.Value<string>(key)!;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://ccu6p418viliu
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
|
namespace Babushka.scripts.CSharp.GameEntity.LoadSave;
|
||||||
|
|
||||||
|
public interface IJsonSerializable
|
||||||
|
{
|
||||||
|
public void LoadFromJson(JObject json);
|
||||||
|
public JObject SaveToJson();
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://cuma3347l55mb
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
|
namespace Babushka.scripts.CSharp.GameEntity.LoadSave;
|
||||||
|
|
||||||
|
public class MalformedJsonException(JObject actualJson, string key, string problem) : Exception
|
||||||
|
{
|
||||||
|
public override string Message => $"JsonObject was malformed: {key} {problem}";
|
||||||
|
public override IDictionary Data => new Dictionary<string, JObject> { { "json", actualJson } };
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://d1o066hh84ow
|
||||||
@@ -0,0 +1,158 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Babushka.scripts.CSharp.GameEntity.Entities;
|
||||||
|
using Godot;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using Entity = Babushka.scripts.CSharp.GameEntity.Entities.Entity;
|
||||||
|
using PositionalEntity = Babushka.scripts.CSharp.GameEntity.Entities.PositionalEntity;
|
||||||
|
|
||||||
|
namespace Babushka.scripts.CSharp.GameEntity.Management;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Manages the lifecycle and interactions of all entities within the game, including their creation, retrieval,
|
||||||
|
/// and organization. The EntityManager serves as a centralized hub for managing both standard and positional entities.
|
||||||
|
/// </summary>
|
||||||
|
public partial class EntityManager : Node
|
||||||
|
{
|
||||||
|
public static EntityManager Instance;
|
||||||
|
|
||||||
|
[Export] private EntityNodeCreator _nodeCreator = null!;
|
||||||
|
[Export] private string saveDirectory = "user://save_data/";
|
||||||
|
|
||||||
|
private EntitySceneContainer? _currentEntitySceneContainer;
|
||||||
|
private readonly List<Entity> _allEntities = new();
|
||||||
|
|
||||||
|
public IEnumerable<Entity> AllEntities => _allEntities;
|
||||||
|
public IEnumerable<PositionalEntity> AllPositionalEntities => _allEntities.OfType<PositionalEntity>();
|
||||||
|
public EntitySceneContainer? CurrentEntitySceneContainer => _currentEntitySceneContainer;
|
||||||
|
public EntityNodeCreator NodeCreator => _nodeCreator;
|
||||||
|
|
||||||
|
public override void _EnterTree()
|
||||||
|
{
|
||||||
|
Instance = this;
|
||||||
|
Load();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void _Input(InputEvent @event)
|
||||||
|
{
|
||||||
|
// for debugging purposes
|
||||||
|
if (@event.IsActionPressed("DebugEntities"))
|
||||||
|
{
|
||||||
|
GD.Print("Entities:");
|
||||||
|
foreach (var entity in AllEntities)
|
||||||
|
{
|
||||||
|
GD.Print(entity.EntityType + " " + entity.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(@event.IsActionPressed("SaveGame")) Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Save()
|
||||||
|
{
|
||||||
|
JArray array = new JArray();
|
||||||
|
foreach (var entity in AllEntities)
|
||||||
|
{
|
||||||
|
JObject saveData = new JObject();
|
||||||
|
entity.SaveEntity(saveData);
|
||||||
|
array.Add(saveData);
|
||||||
|
}
|
||||||
|
|
||||||
|
using var SaveFile = FileAccess.Open(saveDirectory + "save.json", FileAccess.ModeFlags.Write);
|
||||||
|
SaveFile.StoreString(array.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Load()
|
||||||
|
{
|
||||||
|
using var saveFile = FileAccess.Open(saveDirectory + "save.json", FileAccess.ModeFlags.Read);
|
||||||
|
if (saveFile == null) return;
|
||||||
|
|
||||||
|
JArray array = JArray.Parse(saveFile.GetAsText());
|
||||||
|
|
||||||
|
foreach (var token in array)
|
||||||
|
{
|
||||||
|
var jobj = (JObject)token;
|
||||||
|
|
||||||
|
if (jobj == null) continue;
|
||||||
|
|
||||||
|
if (jobj.TryGetValue("type", out var entityType))
|
||||||
|
{
|
||||||
|
string entityTypeString = (string) entityType!;
|
||||||
|
Entity entity = InitializeEntity(entityTypeString);
|
||||||
|
entity.LoadEntity(jobj);
|
||||||
|
AddEntity(entity);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Entity InitializeEntity(string type)
|
||||||
|
{
|
||||||
|
Entity entity = type switch
|
||||||
|
{
|
||||||
|
TrashEntity.OWN_TYPE_NAME => new TrashEntity(),
|
||||||
|
LoadedScenesEntity.OWN_TYPE_NAME => new LoadedScenesEntity(),
|
||||||
|
VesnaEntity.OWN_TYPE_NAME => new VesnaEntity(),
|
||||||
|
_ => throw new Exception($"Trying to load unknown entity type: {type}")
|
||||||
|
};
|
||||||
|
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region ENTITY MANAGEMENT
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds an entity to the list of managed entities. If the entity is a positional entity
|
||||||
|
/// and its scene matches the current scene container, it is also instantiated in the scene.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="entity">The entity to be added to the manager.</param>
|
||||||
|
public void AddEntity(Entity entity)
|
||||||
|
{
|
||||||
|
if (!_allEntities.Contains(entity))
|
||||||
|
_allEntities.Add(entity);
|
||||||
|
if(entity is PositionalEntity positionalEntity && positionalEntity.sceneName == _currentEntitySceneContainer?.sceneName)
|
||||||
|
InstantiatePositionalEntityNode(positionalEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InstantiatePositionalEntityNode(PositionalEntity entity)
|
||||||
|
{
|
||||||
|
if(_currentEntitySceneContainer == null) return;
|
||||||
|
entity.InstantiateEntityNode(_currentEntitySceneContainer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves the first entity of the specified type from the list of managed entities.
|
||||||
|
/// If no such entity exists, creates a new instance of the specified type, adds it to the manager, and returns it.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">The type of entity to retrieve or create. Must inherit from the Entity class and have a parameterless constructor.</typeparam>
|
||||||
|
/// <returns>The first entity of the specified type or a newly created entity of that type if none were found.</returns>
|
||||||
|
public T GetUniqueEntity<T>() where T : Entity, new()
|
||||||
|
{
|
||||||
|
var result = AllEntities.OfType<T>().FirstOrDefault();
|
||||||
|
if (result == null)
|
||||||
|
{
|
||||||
|
var newEntity = new T();
|
||||||
|
AddEntity(newEntity);
|
||||||
|
result = newEntity;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region SCENE CONTAINER ACCESS
|
||||||
|
|
||||||
|
public void SetSceneContainer(EntitySceneContainer sceneContainer)
|
||||||
|
{
|
||||||
|
_currentEntitySceneContainer = sceneContainer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UnsetSceneContainer()
|
||||||
|
{
|
||||||
|
_currentEntitySceneContainer = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://umop2b1m1qm8
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
using PositionalEntity = Babushka.scripts.CSharp.GameEntity.Entities.PositionalEntity;
|
||||||
|
|
||||||
|
namespace Babushka.scripts.CSharp.GameEntity.Management;
|
||||||
|
|
||||||
|
public static class EntityManagerUtil
|
||||||
|
{
|
||||||
|
public static void AddIfNeeded(this EntitySceneContainer? self, PositionalEntity entity)
|
||||||
|
{
|
||||||
|
if(self == null) return;
|
||||||
|
if(self.sceneName != entity.sceneName) return;
|
||||||
|
|
||||||
|
self.AddEntity(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://dc3283h7sx4cl
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
using System;
|
||||||
|
using Godot;
|
||||||
|
using Godot.Collections;
|
||||||
|
|
||||||
|
namespace Babushka.scripts.CSharp.GameEntity.Management;
|
||||||
|
|
||||||
|
public partial class EntityNodeCreator : Node
|
||||||
|
{
|
||||||
|
[Export] private Dictionary<string, PackedScene> _entityPrefabs;
|
||||||
|
|
||||||
|
public Node2D InstantiateNode(string type)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(type))
|
||||||
|
{
|
||||||
|
throw new NullReferenceException("The type provided for Node instantiation cannot be null or empty.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_entityPrefabs.ContainsKey(type))
|
||||||
|
{
|
||||||
|
throw new Exception($"The type provided for Node instantiation ({type}) is not specified in the EntityNodeCreator dictionary.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return _entityPrefabs[type].Instantiate<Node2D>();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://bogqp274y1pgr
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using Babushka.scripts.CSharp.GameEntity.Entities;
|
||||||
|
using Godot;
|
||||||
|
using PositionalEntity = Babushka.scripts.CSharp.GameEntity.Entities.PositionalEntity;
|
||||||
|
|
||||||
|
namespace Babushka.scripts.CSharp.GameEntity.Management;
|
||||||
|
|
||||||
|
public partial class EntitySceneContainer : Node2D
|
||||||
|
{
|
||||||
|
[Export] public string sceneName = "none";
|
||||||
|
|
||||||
|
public override void _EnterTree()
|
||||||
|
{
|
||||||
|
EntityManager.Instance.SetSceneContainer(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void _ExitTree()
|
||||||
|
{
|
||||||
|
EntityManager.Instance.Save();
|
||||||
|
EntityManager.Instance.UnsetSceneContainer();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void _Ready()
|
||||||
|
{
|
||||||
|
AddAllEntities();
|
||||||
|
CallDeferred(nameof(RegisterWithScenesEntity));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RegisterWithScenesEntity()
|
||||||
|
{
|
||||||
|
var loadedScenesEntity = EntityManager.Instance.GetUniqueEntity<LoadedScenesEntity>();
|
||||||
|
loadedScenesEntity.AddScene(sceneName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddAllEntities()
|
||||||
|
{
|
||||||
|
foreach (var positionalEntity in EntityManager.Instance.AllPositionalEntities.Where(x => x.sceneName == sceneName))
|
||||||
|
{
|
||||||
|
AddEntity(positionalEntity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddEntity(PositionalEntity entity)
|
||||||
|
{
|
||||||
|
entity.InstantiateEntityNode(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://ca1pg6k3gn47y
|
||||||
@@ -12,6 +12,9 @@ uniform float brightness_add : hint_range(-1.0, 1.0) = 0.0;
|
|||||||
// Contrast multiplier in RGB space. 1.0 means no change.
|
// Contrast multiplier in RGB space. 1.0 means no change.
|
||||||
uniform float contrast_mult : hint_range(0.0, 2.0) = 1.0;
|
uniform float contrast_mult : hint_range(0.0, 2.0) = 1.0;
|
||||||
|
|
||||||
|
//Cached Color value to reapply modulate
|
||||||
|
varying vec4 modulate;
|
||||||
|
|
||||||
// Converts an RGB color to HSV.
|
// Converts an RGB color to HSV.
|
||||||
vec3 rgb2hsv(vec3 c) {
|
vec3 rgb2hsv(vec3 c) {
|
||||||
float cMax = max(max(c.r, c.g), c.b);
|
float cMax = max(max(c.r, c.g), c.b);
|
||||||
@@ -65,6 +68,10 @@ vec3 hsv2rgb(vec3 c) {
|
|||||||
return rgb + vec3(m);
|
return rgb + vec3(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void vertex(){
|
||||||
|
modulate = COLOR;
|
||||||
|
}
|
||||||
|
|
||||||
void fragment() {
|
void fragment() {
|
||||||
// Get the original texture color.
|
// Get the original texture color.
|
||||||
vec4 tex_color = texture(TEXTURE, UV);
|
vec4 tex_color = texture(TEXTURE, UV);
|
||||||
@@ -89,4 +96,6 @@ void fragment() {
|
|||||||
|
|
||||||
// Output the final color while preserving the original alpha.
|
// Output the final color while preserving the original alpha.
|
||||||
COLOR = vec4(col, tex_color.a);
|
COLOR = vec4(col, tex_color.a);
|
||||||
|
//reapply vertex color value to keep modulate changes
|
||||||
|
COLOR = COLOR * modulate;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,14 @@ shader_type canvas_item;
|
|||||||
|
|
||||||
uniform vec2 tiling_scale = vec2(5.0, 5.0);
|
uniform vec2 tiling_scale = vec2(5.0, 5.0);
|
||||||
uniform sampler2D noise : repeat_enable;
|
uniform sampler2D noise : repeat_enable;
|
||||||
|
varying vec4 modulate;
|
||||||
|
|
||||||
|
void vertex() {
|
||||||
|
modulate = COLOR;
|
||||||
|
}
|
||||||
|
|
||||||
void fragment() {
|
void fragment() {
|
||||||
vec2 uv = vec2(UV.x * tiling_scale.x, UV.y * tiling_scale.y); // Change 10.0 to control tiling scale
|
vec2 uv = vec2(UV.x * tiling_scale.x, UV.y * tiling_scale.y); // Change 10.0 to control tiling scale
|
||||||
COLOR = texture(TEXTURE, fract(uv));
|
COLOR = texture(TEXTURE, fract(uv));
|
||||||
|
COLOR = COLOR * modulate;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,9 @@ uniform float heightOffset : hint_range(0.0, 1.0);
|
|||||||
// With the offset value, you can if you want different moves for each asset. Just put a random value (1, 2, 3) in the editor. Don't forget to mark the material as unique if you use this
|
// With the offset value, you can if you want different moves for each asset. Just put a random value (1, 2, 3) in the editor. Don't forget to mark the material as unique if you use this
|
||||||
uniform float offset = 0;
|
uniform float offset = 0;
|
||||||
|
|
||||||
|
// caching color settings to reapply modulate value
|
||||||
|
varying vec4 modulate;
|
||||||
|
|
||||||
float getWind(vec2 vertex, vec2 uv, float time){
|
float getWind(vec2 vertex, vec2 uv, float time){
|
||||||
float diff = pow(maxStrength - minStrength, 2.0);
|
float diff = pow(maxStrength - minStrength, 2.0);
|
||||||
float strength = clamp(minStrength + diff + sin(time / interval) * diff, minStrength, maxStrength) * strengthScale;
|
float strength = clamp(minStrength + diff + sin(time / interval) * diff, minStrength, maxStrength) * strengthScale;
|
||||||
@@ -47,8 +50,13 @@ float noise(vec2 x) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void vertex() {
|
void vertex() {
|
||||||
|
modulate = COLOR;
|
||||||
vec4 pos = MODEL_MATRIX * vec4(0.0, 0.0, 0.0, 1.0);
|
vec4 pos = MODEL_MATRIX * vec4(0.0, 0.0, 0.0, 1.0);
|
||||||
//float time = TIME * speed + sin(VERTEX.x * noise(VERTEX.xy) * offset);
|
//float time = TIME * speed + sin(VERTEX.x * noise(VERTEX.xy) * offset);
|
||||||
float time = TIME * speed + sin(pos.x * offset) * cos( pos.x * offset) ;
|
float time = TIME * speed + sin(pos.x * offset) * cos( pos.x * offset) ;
|
||||||
VERTEX.x += getWind(VERTEX.xy, UV, time);
|
VERTEX.x += getWind(VERTEX.xy, UV, time);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void fragment() {
|
||||||
|
COLOR = modulate * COLOR;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user