Files
zeling_v2/Assets/Scripts/Core/Save/SaveData.cs
2026-05-08 11:04:00 +08:00

219 lines
9.1 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace BaseGames.Core.Save
{
// ─── 顶层 ─────────────────────────────────────────────────────────────────
[Serializable]
public class SaveData
{
[JsonExtensionData]
public Dictionary<string, JToken> ExtensionData = new();
public SaveMeta Meta = new();
public PlayerSaveData Player = new();
public EquipmentSaveData Equipment = new();
public WorldSaveData World = new();
public MapSaveData Map = new();
public QuestSaveData Quests = new();
public AchievementSaveData Achievements = new();
public ToolsSaveData Tools = new();
public ChallengeRoomsSaveData ChallengeRooms = new();
public EventChainsSaveData EventChains = new();
public ShopsSaveData Shops = new();
public StatsSaveData Stats = new();
public NGPlusSaveData NGPlus = null; // null = 非 NG+ 模式
public Dictionary<string, JObject> DLC = new();
}
// ─── Meta ─────────────────────────────────────────────────────────────────
[Serializable]
public class SaveMeta
{
public string Version = "2.1";
public int SlotIndex;
public string LastSaved; // ISO 8601
public float Playtime;
public string SavePointId;
public int NGPlusCount;
public int SaveCount;
public string Checksum; // HMAC-SHA256
}
// ─── Player ───────────────────────────────────────────────────────────────
[Serializable]
public class PlayerSaveData
{
public float PosX, PosY;
public string Scene;
public int CurrentHP, MaxHP;
public int CurrentGeo, LifetimeGeo;
// 能力解锁位掩码AbilityType [Flags] uint bitmask
public uint AbilityFlags = 0;
public string ActiveFormId;
public List<string> UnlockedFormIds = new();
public DeathShadeSaveData DeathShade;
// 护盾:-1 = 满护盾(默认),>= 0 = 当前耐久值
public int ShieldHP = -1;
public bool ShieldIsBroken = false;
}
[Serializable]
public class DeathShadeSaveData
{
public float PosX, PosY;
public string SceneId;
public int GeoAmount;
}
// ─── Equipment ────────────────────────────────────────────────────────────
[Serializable]
public class EquipmentSaveData
{
public List<string> EquippedCharmIds = new();
public int NotchesUsed;
public int MaxNotches;
public List<string> OwnedCharmIds = new();
public List<string> UpgradedCharmIds = new();
}
// ─── World ────────────────────────────────────────────────────────────────
[Serializable]
public class WorldSaveData
{
public List<string> VisitedScenes = new();
public List<string> ActivatedSavePoints = new();
public List<string> OpenedDoors = new();
public List<string> DefeatedBossIds = new();
public List<string> CollectedIds = new();
public Dictionary<string, bool> Switches = new();
public Dictionary<string, int> NpcRelations = new();
public HashSet<string> ChallengeFirstClears = new();
}
// ─── Map ──────────────────────────────────────────────────────────────────
[Serializable]
public class MapSaveData
{
public Dictionary<string, List<int>> DiscoveredRooms = new();
public Dictionary<string, bool> MapPurchased = new();
}
// ─── Quests ───────────────────────────────────────────────────────────────
[Serializable]
public class QuestSaveData
{
public Dictionary<string, QuestState> QuestStates = new();
public List<string> AvailableQuestIds = new();
}
[Serializable]
public class QuestState
{
public string Status; // "NotStarted"|"Active"|"Completed"|"Failed"
public int ObjectiveIndex;
public List<int> ProgressCounts = new();
public string GiverNpcId;
}
// ─── Achievements ─────────────────────────────────────────────────────────
[Serializable]
public class AchievementSaveData
{
public List<string> Unlocked = new();
public Dictionary<string, AchievementProgress> Progress = new();
}
[Serializable]
public class AchievementProgress
{
public int Count;
public float Percent;
}
// ─── Stats ────────────────────────────────────────────────────────────────
[Serializable]
public class StatsSaveData
{
public int EnemyKills, Deaths, ParrySuccess, ParryFail;
public int GeoEarned, GeoLost;
public float DistanceTraveled;
public int SaveCount;
public Dictionary<string, int> SkillUseCounts = new();
public Dictionary<string, int> DeathsByBoss = new();
}
// ─── Tools ────────────────────────────────────────────────────────────────
[Serializable]
public class ToolsSaveData
{
public string ToolSlot0;
public string ToolSlot1;
public List<string> OwnedToolIds = new();
public Dictionary<string, JObject> ToolStates = new();
}
// ─── ChallengeRooms ───────────────────────────────────────────────────────
[Serializable]
public class ChallengeRoomsSaveData
{
public Dictionary<string, ChallengeRoomRecord> Records = new();
}
[Serializable]
public class ChallengeRoomRecord
{
public int BestScore;
public float BestTime;
public string BestRank; // "S"/"A"/"B"/"C"
public int CompletionCount;
}
// ─── EventChains ──────────────────────────────────────────────────────────
[Serializable]
public class EventChainsSaveData
{
public Dictionary<string, string> ChainStates = new();
public Dictionary<string, bool> WorldFlags = new();
}
// ─── Shops ────────────────────────────────────────────────────────────────
[Serializable]
public class ShopsSaveData
{
public Dictionary<string, ShopRecord> ShopRecords = new();
}
[Serializable]
public class ShopRecord
{
public List<string> SoldUniqueItems = new();
public Dictionary<string, int> PurchaseCounts = new();
}
// ─── NGPlus ───────────────────────────────────────────────────────────────
[Serializable]
public class NGPlusSaveData
{
public int NGPlusCount;
public bool SteelSoulMode;
public Dictionary<string, bool> NGPlusFlags = new();
}
// ─── SlotSummary主菜单 UI 用)────────────────────────────────────────────
public class SlotSummary
{
public int SlotIndex;
public float Playtime;
public string LastSaved;
public string SceneName;
public string ActiveFormId;
}
}