262 lines
11 KiB
C#
262 lines
11 KiB
C#
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 TutorialSaveData Tutorial = new();
|
||
public SettingsSaveData Settings = new();
|
||
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
|
||
/// <summary>此存档是否以钢铁之魂(一命)模式开始;加载后 DifficultyManager 会锁定到 SteelSoul。</summary>
|
||
public bool IsSteelSoul;
|
||
}
|
||
|
||
// ─── 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 List<string> DestroyedObjectIds = new();
|
||
public Dictionary<string, bool> Switches = new();
|
||
public Dictionary<string, int> NpcRelations = new();
|
||
public HashSet<string> ChallengeFirstClears = new();
|
||
}
|
||
|
||
// ─── Map ──────────────────────────────────────────────────────────────────
|
||
[Serializable]
|
||
public class MapSaveData
|
||
{
|
||
public List<string> ExploredRooms = new(); // 踏入过的房间 ID
|
||
public List<string> MappedRooms = new(); // 完整地图信息(购买/存档点揭示)
|
||
public List<MapPin> Pins = new(); // 玩家自定义地图标记
|
||
}
|
||
|
||
/// <summary>玩家在地图上放置的自定义标记(架构 15_MapShopModule §1.5)。</summary>
|
||
[Serializable]
|
||
public class MapPin
|
||
{
|
||
public string RoomId;
|
||
public float NormalizedPosX;
|
||
public float NormalizedPosY;
|
||
public int PinTypeInt; // PinType 枚举整数值,避免 SaveData 依赖 Map 程序集
|
||
public string Note; // 玩家备注(最多 64 字符)
|
||
}
|
||
|
||
public enum PinType
|
||
{
|
||
Marker = 0,
|
||
Chest = 1,
|
||
Enemy = 2,
|
||
Path = 3,
|
||
Note = 4,
|
||
}
|
||
|
||
// ─── 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 float SpeedrunTime;
|
||
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;
|
||
}
|
||
|
||
// ─── Tutorial ─────────────────────────────────────────────────────────────
|
||
[Serializable]
|
||
public class TutorialSaveData
|
||
{
|
||
/// <summary>已完成(不再弹出)的提示 ID 列表。</summary>
|
||
public List<string> CompletedHintIds = new();
|
||
}
|
||
|
||
// ─── Settings ─────────────────────────────────────────────────────────────
|
||
[Serializable]
|
||
public class SettingsSaveData
|
||
{
|
||
/// <summary>玩家选择的语言。空字符串 = 使用系统默认。</summary>
|
||
public string Language = string.Empty;
|
||
}
|
||
}
|