Files
przygody-pana-cegly/Autoloads/SaveSystem.cs
2026-01-31 16:31:36 +01:00

123 lines
3.4 KiB
C#

using System.Text.Json;
using Godot;
using Mr.BrickAdventures.scripts.State;
namespace Mr.BrickAdventures.Autoloads;
/// <summary>
/// Save system that serializes POCOs directly to JSON.
/// </summary>
public partial class SaveSystem : Node
{
[Export] public string SavePath { get; set; } = "user://savegame.json";
[Export] public int Version { get; set; } = 2; // Bumped version for new format
private static readonly JsonSerializerOptions JsonOptions = new()
{
WriteIndented = true,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
};
public override void _Ready()
{
// No longer needs GameManager reference - works with GameStateStore directly
}
public void SaveGame()
{
var store = GameStateStore.Instance;
if (store == null)
{
GD.PrintErr("SaveSystem: GameStateStore not available.");
return;
}
var saveData = new SaveData
{
Version = Version,
Player = store.Player,
CurrentLevel = store.Session.CurrentLevel
};
try
{
var json = JsonSerializer.Serialize(saveData, JsonOptions);
using var file = FileAccess.Open(SavePath, FileAccess.ModeFlags.Write);
file.StoreString(json);
GD.Print("Game saved to: ", SavePath);
EventBus.EmitGameSaved();
}
catch (System.Exception e)
{
GD.PrintErr($"SaveSystem: Failed to save game: {e.Message}");
}
}
public bool LoadGame()
{
if (!FileAccess.FileExists(SavePath))
{
GD.Print("SaveSystem: No save file found.");
return false;
}
try
{
using var file = FileAccess.Open(SavePath, FileAccess.ModeFlags.Read);
var json = file.GetAsText();
var saveData = JsonSerializer.Deserialize<SaveData>(json, JsonOptions);
if (saveData == null)
{
GD.PrintErr("SaveSystem: Failed to deserialize save data.");
return false;
}
if (saveData.Version != Version)
{
GD.PrintErr($"SaveSystem: Version mismatch. Expected {Version}, found {saveData.Version}");
return false;
}
var store = GameStateStore.Instance;
if (store == null)
{
GD.PrintErr("SaveSystem: GameStateStore not available.");
return false;
}
// Apply loaded state
store.Player = saveData.Player ?? new PlayerState();
store.Session.CurrentLevel = saveData.CurrentLevel;
GD.Print("Game loaded from: ", SavePath);
return true;
}
catch (System.Exception e)
{
GD.PrintErr($"SaveSystem: Failed to load game: {e.Message}");
return false;
}
}
public bool CheckSaveExists() => FileAccess.FileExists(SavePath);
public void DeleteSave()
{
if (FileAccess.FileExists(SavePath))
{
DirAccess.RemoveAbsolute(ProjectSettings.GlobalizePath(SavePath));
GD.Print("Save file deleted.");
}
}
}
/// <summary>
/// Container for save data.
/// </summary>
public class SaveData
{
public int Version { get; set; }
public PlayerState Player { get; set; }
public int CurrentLevel { get; set; }
}