using Godot; using System.Collections.Generic; using System.Text.Json; public static class SaveGameManager { private const string SaveDirectory = "user://savegame"; private const string GameDataPath = SaveDirectory + "/gamedata.json"; private const string RobotsPath = SaveDirectory + "/robots.json"; private const string ResearchPath = SaveDirectory + "/research.json"; private const string LayerPrefix = SaveDirectory + "/layer_"; private const string JsonExtension = ".json"; private static readonly JsonSerializerOptions JsonOptions = new JsonSerializerOptions { WriteIndented = true }; public static bool SaveExists() { return FileAccess.FileExists(GameDataPath); } public static void SaveGame() { SaveGameData saveGame = CreateSaveData(); CreateSaveDirectory(); ClearOldLayerFiles(); SaveJson(GameDataPath, SaveGameDataFactory.CreateCoreSaveData(saveGame)); SaveJson(RobotsPath, saveGame.Robots); SaveJson(ResearchPath, saveGame.Research); foreach (LayerSaveData layer in saveGame.Layers) { SaveJson(GetLayerPath(layer.Level), layer); } } public static SaveGameData LoadSaveData() { if (!SaveExists()) return null; SaveGameData saveGame = LoadJson(GameDataPath); if (saveGame == null) return null; saveGame.Robots = LoadJson>(RobotsPath) ?? new List(); saveGame.Research = LoadJson>(ResearchPath) ?? new List(); saveGame.Layers = LoadLayerSaveData(); return saveGame; } public static SaveGameData CreateSaveData() { return SaveGameDataFactory.CreateSaveData(); } public static void ApplyWorldData(SaveGameData saveGame) { SaveGameDataApplier.ApplyWorldData(saveGame); } private static List LoadLayerSaveData() { List result = new List(); for (int i = 0; i < GameData.ruinSize; i++) { string path = GetLayerPath(i); if (!FileAccess.FileExists(path)) continue; LayerSaveData layer = LoadJson(path); if (layer != null) { result.Add(layer); } } return result; } private static string GetLayerPath(int level) { return LayerPrefix + level + JsonExtension; } private static void CreateSaveDirectory() { DirAccess.MakeDirRecursiveAbsolute(SaveDirectory); } private static void ClearOldLayerFiles() { DirAccess directory = DirAccess.Open(SaveDirectory); if (directory == null) return; directory.ListDirBegin(); while (true) { string fileName = directory.GetNext(); if (fileName == "") break; if (directory.CurrentIsDir()) continue; if (!fileName.StartsWith("layer_") || !fileName.EndsWith(JsonExtension)) continue; directory.Remove(fileName); } directory.ListDirEnd(); } private static void SaveJson(string path, T data) { string json = JsonSerializer.Serialize(data, JsonOptions); FileAccess file = FileAccess.Open(path, FileAccess.ModeFlags.Write); if (file == null) return; file.StoreString(json); file.Flush(); } private static T LoadJson(string path) { if (!FileAccess.FileExists(path)) return default; FileAccess file = FileAccess.Open(path, FileAccess.ModeFlags.Read); if (file == null) return default; string json = file.GetAsText(); return JsonSerializer.Deserialize(json); } }