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

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

View file

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

View file

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

View file

@ -8,8 +8,9 @@ using GTweensGodot.Extensions;
public partial class GlobalState : Node
{
public static GlobalState Instance { get; private set; }
public static SessionSettings Session => GlobalState.Instance.SessionSettings;
public Node CurrentScene { get; set; }
public string CurrentSceneId { get; private set; }
private ColorRect _fader { get; set; }
@ -71,12 +72,18 @@ public partial class GlobalState : Node
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.
CurrentScene.Free();
// Load a new scene.
var nextScene = GD.Load<PackedScene>(path);
CurrentSceneId = nextScene.GetSceneUniqueId();
// Instance the new scene.
CurrentScene = nextScene.Instantiate();
@ -153,4 +160,25 @@ public partial class GlobalState : Node
_loadingPlaque?.Hide();
_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 static InventoryManager Instance { get; private set; }
public ItemsDatabase ItemsDatabase { get; set; }
public bool RedKeycard { get; set; }
private Dictionary<string, ItemContainer> _itemsDict = new();
@ -35,6 +38,8 @@ public partial class InventoryManager : Node2D
public override void _Ready()
{
Instance = this;
GD.Print("Loading items");
Load(GlobalState.Session.Items);
}
// 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);
}
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

View file

@ -1,6 +1,7 @@
using Godot;
using System;
using Cirno.Scripts.UI;
using Godot.Collections;
public partial class MainMenu : CanvasLayer
{
@ -51,6 +52,7 @@ public partial class MainMenu : CanvasLayer
{
if (GameScene != null)
{
GlobalState.Session.NewSession();
GlobalState.Instance.GotoScene(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 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 Shield {get;set;}
}
public float Health { get; set; }
public float Shield { get; set; }
public void NewSession()
{
Items = new();
}
}