State persistance between scenes

This commit is contained in:
Marco 2025-03-24 16:56:35 +01:00
commit 35254935e4
13 changed files with 142 additions and 27 deletions

View file

@ -0,0 +1,31 @@
[gd_resource type="Resource" script_class="ItemsDatabase" load_steps=25 format=3 uid="uid://cdi84udi6gldt"]
[ext_resource type="Resource" uid="uid://ct1fa2huvy34n" path="res://Resources/Items/Ammo1.tres" id="1_1s15f"]
[ext_resource type="Script" uid="uid://c23prvgfitlpd" path="res://Scripts/Resources/ItemsDatabase.cs" id="1_al8ea"]
[ext_resource type="Resource" uid="uid://cj5aa7btaw6q0" path="res://Resources/Items/Blue_Keycard.tres" id="2_nsx5p"]
[ext_resource type="Resource" uid="uid://cfq121rs3bsu8" path="res://Resources/Items/Cheat_Gun_Item.tres" id="3_oark3"]
[ext_resource type="Resource" uid="uid://cspcgkr0tane2" path="res://Resources/Items/Green_Keycard.tres" id="4_yj5fs"]
[ext_resource type="Resource" uid="uid://cvlwye1u5gv8u" path="res://Resources/Items/Green_Points_Pickup.tres" id="5_wigtd"]
[ext_resource type="Resource" uid="uid://ciybnocjfpshh" path="res://Resources/Items/Heart_Extend_Pickup.tres" id="6_ador3"]
[ext_resource type="Resource" uid="uid://dodwpect0ldjf" path="res://Resources/Items/Heart_Pickup.tres" id="7_xxd6q"]
[ext_resource type="Resource" uid="uid://dau0s8ob7qnpc" path="res://Resources/Items/IceShotgun.tres" id="8_33up1"]
[ext_resource type="Resource" uid="uid://cs3ihltcn2166" path="res://Resources/Items/IcicleGun.tres" id="9_a23i7"]
[ext_resource type="Resource" uid="uid://bgcgeg187vg1h" path="res://Resources/Items/IcicleRepeater.tres" id="10_0hw56"]
[ext_resource type="Resource" uid="uid://cltxhkrqp055v" path="res://Resources/Items/Money_Pickup.tres" id="11_nodmt"]
[ext_resource type="Resource" uid="uid://brsukcuyoq364" path="res://Resources/Items/NuclearGunPickup.tres" id="12_5stko"]
[ext_resource type="Resource" uid="uid://cfod8kephnio6" path="res://Resources/Items/Nuclear_Ammo_Pickup.tres" id="13_5x77y"]
[ext_resource type="Resource" uid="uid://dy53gia1tmkah" path="res://Resources/Items/Points_Pickup.tres" id="14_p1hpt"]
[ext_resource type="Resource" uid="uid://clr1gln7nxa1o" path="res://Resources/Items/Power_Pickup.tres" id="15_b6dqw"]
[ext_resource type="Resource" uid="uid://dibquna7fww7t" path="res://Resources/Items/Red_Keycard.tres" id="16_a5xwj"]
[ext_resource type="Resource" uid="uid://bdpbekqhuuq4l" path="res://Resources/Items/Shield_Extend_Pickup.tres" id="17_44qof"]
[ext_resource type="Resource" uid="uid://bhbufxodybsw4" path="res://Resources/Items/Shield_Pickup.tres" id="18_i5d5q"]
[ext_resource type="Resource" uid="uid://dhbltvgsa3g88" path="res://Resources/Items/Spider_Bomb_Pickup.tres" id="19_42kyh"]
[ext_resource type="Resource" uid="uid://b2vyr1tcm4rc1" path="res://Resources/Items/Yellow_Keycard.tres" id="20_q4lxx"]
[ext_resource type="Resource" uid="uid://diqm2ju0xakkt" path="res://Resources/Items/Yin_Yang_Ammo.tres" id="21_detwd"]
[ext_resource type="Resource" uid="uid://ccmuffmnevrt4" path="res://Resources/Items/Yin_Yang_Gun_Pickup.tres" id="22_w8yo3"]
[ext_resource type="Resource" uid="uid://b0qheywm2wej3" path="res://Resources/Items/Yin_Yang_Orb.tres" id="23_nq6hj"]
[resource]
script = ExtResource("1_al8ea")
LootItems = [ExtResource("1_1s15f"), ExtResource("2_nsx5p"), ExtResource("3_oark3"), ExtResource("4_yj5fs"), ExtResource("5_wigtd"), ExtResource("6_ador3"), ExtResource("7_xxd6q"), ExtResource("8_33up1"), ExtResource("9_a23i7"), ExtResource("10_0hw56"), ExtResource("11_nodmt"), ExtResource("12_5stko"), ExtResource("13_5x77y"), ExtResource("14_p1hpt"), ExtResource("15_b6dqw"), ExtResource("16_a5xwj"), ExtResource("17_44qof"), ExtResource("18_i5d5q"), ExtResource("19_42kyh"), ExtResource("20_q4lxx"), ExtResource("21_detwd"), ExtResource("22_w8yo3"), ExtResource("23_nq6hj")]
metadata/_custom_type_script = "uid://c23prvgfitlpd"

View file

@ -65,7 +65,9 @@ theme = ExtResource("1_il8fq")
[node name="Label" type="Label" parent="ScrollContainer/HBoxContainer/HFlowContainer"] [node name="Label" type="Label" parent="ScrollContainer/HBoxContainer/HFlowContainer"]
layout_mode = 2 layout_mode = 2
text = "Note: The options currently do something" theme_override_constants/line_spacing = -4
text = "VSync and FullScreen detailed mode
selection coming soon"
[node name="Resolution" type="VBoxContainer" parent="ScrollContainer/HBoxContainer/HFlowContainer"] [node name="Resolution" type="VBoxContainer" parent="ScrollContainer/HBoxContainer/HFlowContainer"]
visible = false visible = false
@ -88,16 +90,6 @@ layout_mode = 2
size_flags_vertical = 0 size_flags_vertical = 0
text = "Full Screen" text = "Full Screen"
[node name="CheckBox3" type="CheckBox" parent="ScrollContainer/HBoxContainer/HFlowContainer"]
layout_mode = 2
size_flags_vertical = 0
disabled = true
text = "Disabled"
[node name="CheckBox4" type="CheckBox" parent="ScrollContainer/HBoxContainer/HFlowContainer"]
layout_mode = 2
text = "adsfdsaf"
[node name="VBoxContainer3" type="VBoxContainer" parent="ScrollContainer/HBoxContainer"] [node name="VBoxContainer3" type="VBoxContainer" parent="ScrollContainer/HBoxContainer"]
layout_mode = 2 layout_mode = 2

View file

@ -1,8 +1,7 @@
[gd_scene load_steps=33 format=4 uid="uid://bx31ou6tw3kd1"] [gd_scene load_steps=32 format=4 uid="uid://bx31ou6tw3kd1"]
[ext_resource type="Script" uid="uid://doxmbokehw8ci" path="res://Scripts/GameManager.cs" id="1_6sq7s"] [ext_resource type="Script" uid="uid://doxmbokehw8ci" path="res://Scripts/GameManager.cs" id="1_6sq7s"]
[ext_resource type="PackedScene" uid="uid://c4pr2707hbeph" path="res://Scenes/Actors/fsm_player.tscn" id="2_cicvv"] [ext_resource type="PackedScene" uid="uid://c4pr2707hbeph" path="res://Scenes/Actors/fsm_player.tscn" id="2_cicvv"]
[ext_resource type="Script" uid="uid://epnwjptvks3t" path="res://Scripts/Resources/LootItem.cs" id="3_8anae"]
[ext_resource type="Script" uid="uid://mja0rk7n2kln" path="res://Scripts/Resources/MapStartDataResource.cs" id="4_tgwif"] [ext_resource type="Script" uid="uid://mja0rk7n2kln" path="res://Scripts/Resources/MapStartDataResource.cs" id="4_tgwif"]
[ext_resource type="TileSet" uid="uid://6k28roiljylj" path="res://Tilesets/factory_tileset.tres" id="5_vmlpc"] [ext_resource type="TileSet" uid="uid://6k28roiljylj" path="res://Tilesets/factory_tileset.tres" id="5_vmlpc"]
[ext_resource type="Script" uid="uid://krean0uywtms" path="res://Scripts/TilemapAvoidance.cs" id="6_sv42c"] [ext_resource type="Script" uid="uid://krean0uywtms" path="res://Scripts/TilemapAvoidance.cs" id="6_sv42c"]
@ -31,7 +30,7 @@
[sub_resource type="Resource" id="Resource_53p3c"] [sub_resource type="Resource" id="Resource_53p3c"]
script = ExtResource("4_tgwif") script = ExtResource("4_tgwif")
EggIndex = 0 EggIndex = 0
StartingEquipment = Array[ExtResource("3_8anae")]([null]) StartingEquipment = [null]
[sub_resource type="Resource" id="Resource_2ugqu"] [sub_resource type="Resource" id="Resource_2ugqu"]
script = ExtResource("11_esmuk") script = ExtResource("11_esmuk")
@ -180,6 +179,7 @@ position = Vector2(292, 408)
[node name="LevelTeleporter" parent="Tilemaps/Actors" instance=ExtResource("18_tbppe")] [node name="LevelTeleporter" parent="Tilemaps/Actors" instance=ExtResource("18_tbppe")]
position = Vector2(112, 304) position = Vector2(112, 304)
LevelPath = "res://Scenes/Maps/Level2.tscn" LevelPath = "res://Scenes/Maps/Level2.tscn"
SaveInventory = true
[node name="ControlPad" parent="Tilemaps" node_paths=PackedStringArray("Targets") instance=ExtResource("19_nxss7")] [node name="ControlPad" parent="Tilemaps" node_paths=PackedStringArray("Targets") instance=ExtResource("19_nxss7")]
position = Vector2(134, 371) position = Vector2(134, 371)

View file

@ -581,6 +581,7 @@ position = Vector2(-1688, -232)
[node name="LevelTeleporter" parent="Parallax2D/Factory Tilemaps/LevelProps" instance=ExtResource("44_q5xi2")] [node name="LevelTeleporter" parent="Parallax2D/Factory Tilemaps/LevelProps" instance=ExtResource("44_q5xi2")]
position = Vector2(-2000, -867) position = Vector2(-2000, -867)
LevelPath = "res://Scenes/Maps/RebelBase.tscn" LevelPath = "res://Scenes/Maps/RebelBase.tscn"
SaveInventory = true
IsEnabled = true IsEnabled = true
[node name="BigTank" parent="Parallax2D/Factory Tilemaps/LevelProps" instance=ExtResource("45_5qg27")] [node name="BigTank" parent="Parallax2D/Factory Tilemaps/LevelProps" instance=ExtResource("45_5qg27")]
@ -649,7 +650,7 @@ IsEnabled = true
Target = NodePath("../DebugTeleporter") Target = NodePath("../DebugTeleporter")
[node name="DebugTeleporter" parent="Parallax2D/Factory Tilemaps/LevelProps" instance=ExtResource("30_8fdby")] [node name="DebugTeleporter" parent="Parallax2D/Factory Tilemaps/LevelProps" instance=ExtResource("30_8fdby")]
position = Vector2(-1118, 206) position = Vector2(-2002, -817)
Invisible = true Invisible = true
metadata/_edit_group_ = true metadata/_edit_group_ = true

View file

@ -6,10 +6,11 @@ using Godot;
namespace Cirno.Scripts.Activables; namespace Cirno.Scripts.Activables;
public partial class LevelTeleporter : Teleporter public partial class LevelTeleporter : Teleporter
{ {
[Export] [Export] public string LevelPath { get; private set; }
public string LevelPath {get; private set;}
[Export] public bool SaveInventory { get; private set; }
protected override async Task Teleport(IStateMachine<PlayerState, CharacterBody2D> player) protected override async Task Teleport(IStateMachine<PlayerState, CharacterBody2D> player)
{ {
@ -20,13 +21,19 @@ public partial class LevelTeleporter : Teleporter
await TweenPlayer(player.MainObject); await TweenPlayer(player.MainObject);
_particles.Emitting = true; _particles.Emitting = true;
//await player.Teleport(); //await player.Teleport();
player.SetState(PlayerState.UnTeleporting); player.SetState(PlayerState.UnTeleporting);
await Task.Delay((int)(0.6f * 1000)); await Task.Delay((int)(0.6f * 1000));
await Task.Delay((int)(TeleportAnimationLength * 1000)); await Task.Delay((int)(TeleportAnimationLength * 1000));
if (SaveInventory)
{
// Save inventory
GlobalState.Instance.SessionSettings.Items = InventoryManager.Instance.Save();
}
GlobalState.Instance.GotoScene(LevelPath); GlobalState.Instance.GotoScene(LevelPath);
} }
} }

View file

@ -48,7 +48,12 @@ public partial class Boss : Enemy, IActivable, IScriptHost
} }
_homePosition = this.GlobalPosition; _homePosition = this.GlobalPosition;
CallDeferred(MethodName.InitDeferred);
}
private void InitDeferred()
{
_cameraMarker = new Marker2D(); _cameraMarker = new Marker2D();
GameManager.Instance.CallDeferred("add_child", _cameraMarker); GameManager.Instance.CallDeferred("add_child", _cameraMarker);
_cameraMarker.GlobalPosition = _homePosition + CameraOffset; _cameraMarker.GlobalPosition = _homePosition + CameraOffset;
@ -87,6 +92,7 @@ public partial class Boss : Enemy, IActivable, IScriptHost
} }
} }
public override void _Process(double delta) public override void _Process(double delta)
{ {

View file

@ -113,7 +113,7 @@ public partial class GameManager : Node2D
public void ApplySessionState(SessionSettings settings) public void ApplySessionState(SessionSettings settings)
{ {
//_inventoryManager.Load(settings.Items);
} }
public override void _Process(double delta) public override void _Process(double delta)

View file

@ -8,8 +8,9 @@ using GTweensGodot.Extensions;
public partial class GlobalState : Node public partial class GlobalState : Node
{ {
public static GlobalState Instance { get; private set; } public static GlobalState Instance { get; private set; }
public static SessionSettings Session => GlobalState.Instance.SessionSettings;
public Node CurrentScene { get; set; } public Node CurrentScene { get; set; }
public string CurrentSceneId { get; private set; }
private ColorRect _fader { get; set; } private ColorRect _fader { get; set; }
@ -71,12 +72,18 @@ public partial class GlobalState : Node
private void DeferredGotoScene(string path, MapStartDataResource startData = null) private void DeferredGotoScene(string path, MapStartDataResource startData = null)
{ {
// if (InventoryManager.Instance is not null)
// {
// SessionSettings.Items = InventoryManager.Instance.Save();
// }
// It is now safe to remove the current scene. // It is now safe to remove the current scene.
CurrentScene.Free(); CurrentScene.Free();
// Load a new scene. // Load a new scene.
var nextScene = GD.Load<PackedScene>(path); var nextScene = GD.Load<PackedScene>(path);
CurrentSceneId = nextScene.GetSceneUniqueId();
// Instance the new scene. // Instance the new scene.
CurrentScene = nextScene.Instantiate(); CurrentScene = nextScene.Instantiate();
@ -153,4 +160,25 @@ public partial class GlobalState : Node
_loadingPlaque?.Hide(); _loadingPlaque?.Hide();
_fader.TweenModulateAlpha(0, 1f).PlayUnpausable(); _fader.TweenModulateAlpha(0, 1f).PlayUnpausable();
} }
public void SaveGame()
{
var items = InventoryManager.Instance.Save();
var serializedSavedata = new Godot.Collections.Dictionary<string, Variant>()
{
{ "Items", items },
{ "Level", CurrentSceneId }
};
var saveFile = FileAccess.Open("user://savegame.save", FileAccess.ModeFlags.Write);
var jsonString = Json.Stringify(serializedSavedata);
saveFile.StoreLine(jsonString);
}
public void LoadGame()
{
}
} }

View file

@ -8,6 +8,9 @@ using Cirno.Scripts.Resources;
public partial class InventoryManager : Node2D public partial class InventoryManager : Node2D
{ {
public static InventoryManager Instance { get; private set; } public static InventoryManager Instance { get; private set; }
public ItemsDatabase ItemsDatabase { get; set; }
public bool RedKeycard { get; set; } public bool RedKeycard { get; set; }
private Dictionary<string, ItemContainer> _itemsDict = new(); private Dictionary<string, ItemContainer> _itemsDict = new();
@ -35,6 +38,8 @@ public partial class InventoryManager : Node2D
public override void _Ready() public override void _Ready()
{ {
Instance = this; Instance = this;
GD.Print("Loading items");
Load(GlobalState.Session.Items);
} }
// Called every frame. 'delta' is the elapsed time since the previous frame. // Called every frame. 'delta' is the elapsed time since the previous frame.
@ -154,6 +159,32 @@ public partial class InventoryManager : Node2D
{ {
EmitSignal(SignalName.LoadedAmmoChanged, weaponDataItemKey, loadedAmmo); EmitSignal(SignalName.LoadedAmmoChanged, weaponDataItemKey, loadedAmmo);
} }
public Godot.Collections.Dictionary<string, int> Save()
{
Godot.Collections.Dictionary<string, int> dict = new();
foreach (var item in _itemsDict)
{
dict.Add(item.Key, item.Value.Count);
}
return dict;
}
public void Load(Godot.Collections.Dictionary<string, int> items)
{
ItemsDatabase = ResourceLoader.Load<ItemsDatabase>("uid://cdi84udi6gldt");
_itemsDict.Clear();
_itemsDict = items.ToDictionary(x => x.Key, x => new ItemContainer()
{
Item = ItemsDatabase.LootItems.FirstOrDefault(y => y.ItemKey == x.Key),
Count = x.Value
});
GD.Print($"Items after loading: {_itemsDict.Count}");
}
} }
public class ItemContainer public class ItemContainer

View file

@ -1,6 +1,7 @@
using Godot; using Godot;
using System; using System;
using Cirno.Scripts.UI; using Cirno.Scripts.UI;
using Godot.Collections;
public partial class MainMenu : CanvasLayer public partial class MainMenu : CanvasLayer
{ {
@ -51,6 +52,7 @@ public partial class MainMenu : CanvasLayer
{ {
if (GameScene != null) if (GameScene != null)
{ {
GlobalState.Session.NewSession();
GlobalState.Instance.GotoScene(GameScene); GlobalState.Instance.GotoScene(GameScene);
//GetTree().ChangeSceneToFile(GameScene); //GetTree().ChangeSceneToFile(GameScene);
} }

View file

@ -0,0 +1,11 @@
using Godot;
using Godot.Collections;
namespace Cirno.Scripts.Resources;
[GlobalClass]
public partial class ItemsDatabase : Resource
{
[Export]
public Array<LootItem> LootItems { get; set; } = new();
}

View file

@ -0,0 +1 @@
uid://c23prvgfitlpd

View file

@ -8,8 +8,13 @@ public class SessionSettings
public bool SkipDialogues { get; set; } = false; public bool SkipDialogues { get; set; } = false;
public bool GodMode { get; set; } = false; public bool GodMode { get; set; } = false;
public Dictionary<string,int> Items {get;set;} = new(); public Godot.Collections.Dictionary<string, int> Items { get; set; } = new();
public float Health {get;set;} public float Health { get; set; }
public float Shield {get;set;} public float Shield { get; set; }
}
public void NewSession()
{
Items = new();
}
}