chore: initial commit

This commit is contained in:
2026-05-08 11:04:00 +08:00
commit f55d2a57c3
6278 changed files with 866081 additions and 0 deletions

View File

@@ -0,0 +1,218 @@
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;
}
}