202 lines
6.9 KiB
C#
202 lines
6.9 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
|
||
namespace AibisDream.SaveSystem
|
||
{
|
||
/// <summary>
|
||
/// 当前快照 schema 的版本号。结构变更时递增。
|
||
/// </summary>
|
||
public static class SaveSnapshotSchema
|
||
{
|
||
public const int CurrentVersion = 1;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 存档快照根对象:描述「进入可存节点那一刻」的完整游戏状态。
|
||
/// <para>
|
||
/// 与槽位/文件路径解耦;序列化后写入 JSON。对应需求§3 四分类:
|
||
/// anchor(恢复锚点)、sections(宏观 scene/macro + 表现类)、yarnVariables、deepRepair(深度维修,P5)。
|
||
/// </para>
|
||
/// <para>
|
||
/// 宏观阶段(场景 / 章节 SO / YarnProject)不单独冗余存储,统一以 sections["scene"] / sections["macro"]
|
||
/// 为唯一来源;槽位 UI 等需要摘要时通过 <see cref="SaveSnapshotSummary"/> 现算派生,避免重复字段漂移。
|
||
/// </para>
|
||
/// </summary>
|
||
[Serializable]
|
||
public class SaveSnapshot
|
||
{
|
||
/// <summary>快照结构版本,对应 <see cref="SaveSnapshotSchema.CurrentVersion"/>。</summary>
|
||
public int schemaVersion = SaveSnapshotSchema.CurrentVersion;
|
||
|
||
/// <summary>保存时的 <c>Application.version</c>。</summary>
|
||
public string gameVersion;
|
||
|
||
/// <summary>保存时间(本地),格式 <c>yyyy-MM-dd HH:mm:ss</c>。</summary>
|
||
public string savedAt;
|
||
|
||
/// <summary>当前场景(恢复的第一步)。</summary>
|
||
public SceneSnapshotDto scene = new();
|
||
|
||
/// <summary>恢复锚点:章节、YarnProject 与节点,读档最后阶段重新进入。</summary>
|
||
public AnchorSnapshot anchor = new();
|
||
|
||
/// <summary>全部 Yarn 运行时变量(来自 <see cref="YarnVariableStorage"/>)。</summary>
|
||
public YarnVariablesSnapshot yarnVariables = new();
|
||
|
||
/// <summary>
|
||
/// 各子系统表现类快照,key 为 <see cref="SnapshotProviderIds"/> 中的稳定 id。
|
||
/// </summary>
|
||
public Dictionary<string, object> sections = new();
|
||
|
||
/// <summary>
|
||
/// 深度维修段。P1 捕获时不写入(null);P5 按模块策略填充。
|
||
/// </summary>
|
||
public DeepRepairSnapshot deepRepair;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 恢复锚点:包含宏观章节信息,读档最后阶段加载对话工程并重新 <c>StartDialogue</c>。
|
||
/// </summary>
|
||
[Serializable]
|
||
public class AnchorSnapshot
|
||
{
|
||
/// <summary>当前章节 TalkSceneSO 名称,用于 <see cref="GameManager.SetSceneSoByName"/>。</summary>
|
||
public string sceneSoName;
|
||
public string yarnProjectId;
|
||
public string nodeName;
|
||
}
|
||
|
||
/// <summary>Yarn 变量三分组,与 Yarn Spinner 支持的类型一致。</summary>
|
||
[Serializable]
|
||
public class YarnVariablesSnapshot
|
||
{
|
||
public Dictionary<string, float> floats = new();
|
||
public Dictionary<string, string> strings = new();
|
||
public Dictionary<string, bool> bools = new();
|
||
}
|
||
|
||
#region Provider DTOs
|
||
|
||
/// <summary>sections["scene"]:当前加载的场景。</summary>
|
||
[Serializable]
|
||
public class SceneSnapshotDto
|
||
{
|
||
public string sceneName;
|
||
}
|
||
|
||
/// <summary>sections["env"]:环境时间/天气。</summary>
|
||
[Serializable]
|
||
public class EnvironmentSnapshotDto
|
||
{
|
||
/// <summary><see cref="TimesOfDay"/> 枚举名。</summary>
|
||
public string curTime;
|
||
|
||
/// <summary><see cref="Weather"/> 枚举名。</summary>
|
||
public string curWeather;
|
||
|
||
public bool isInitialized;
|
||
}
|
||
|
||
/// <summary>sections["actor"]:场景中所有角色的逐项状态。</summary>
|
||
[Serializable]
|
||
public class ActorSnapshotDto
|
||
{
|
||
public List<ActorEntrySnapshotDto> actors = new();
|
||
}
|
||
|
||
/// <summary>单个角色的快照条目。</summary>
|
||
[Serializable]
|
||
public class ActorEntrySnapshotDto
|
||
{
|
||
public string actorName;
|
||
public string slotName;
|
||
public string actorType;
|
||
public string stateName;
|
||
public float alpha;
|
||
public float faceParam;
|
||
}
|
||
|
||
/// <summary>sections["audio"]:FMOD 音乐/SFX 终态与 AMB 状态(不记播放进度)。</summary>
|
||
[Serializable]
|
||
public class AudioSnapshotDto
|
||
{
|
||
/// <summary>key → FMOD event path。</summary>
|
||
public Dictionary<string, string> musicPaths = new();
|
||
|
||
public Dictionary<string, string> sfxPaths = new();
|
||
|
||
/// <summary><see cref="AmbState"/> 枚举名。</summary>
|
||
public string ambState;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Timeline 终/初态标记(决策 D1.1:不按时间轴逐帧还原)。
|
||
/// 序列化进 JSON 时使用字符串形式存入 <see cref="TimelineEntrySnapshotDto.phase"/>。
|
||
/// </summary>
|
||
public enum TimelinePlaybackPhase
|
||
{
|
||
AtStart,
|
||
AtEnd,
|
||
Stopped
|
||
}
|
||
|
||
/// <summary>sections["timeline"]:各 PlayableDirector 的终/初态。</summary>
|
||
[Serializable]
|
||
public class TimelineSnapshotDto
|
||
{
|
||
public List<TimelineEntrySnapshotDto> entries = new();
|
||
}
|
||
|
||
[Serializable]
|
||
public class TimelineEntrySnapshotDto
|
||
{
|
||
public string directorName;
|
||
public bool isActive;
|
||
|
||
/// <summary><see cref="TimelinePlaybackPhase"/> 的字符串名。</summary>
|
||
public string phase;
|
||
|
||
/// <summary>若由 Addressables 加载 Timeline,记录 key;否则为空。</summary>
|
||
public string loadedAddressableKey;
|
||
}
|
||
|
||
/// <summary>sections["screen"]:屏幕饱和度与演出淡入淡出遮罩。</summary>
|
||
[Serializable]
|
||
public class ScreenSnapshotDto
|
||
{
|
||
/// <summary>Post-process Volume weight(0=正常,1=完全褪色)。</summary>
|
||
public float saturationWeight;
|
||
|
||
/// <summary>
|
||
/// <see cref="PlayToolPanel"/> 演出遮罩终态:<c>true</c> = 黑屏盖住(<c>FadeIn</c> 完成);
|
||
/// <c>false</c> = 画面可见(<c>FadeOut</c> 完成或遮罩未启用)。不记录转场中间 alpha。
|
||
/// </summary>
|
||
public bool isFadeScreenCovered;
|
||
}
|
||
|
||
/// <summary>sections["fix"]:Fix 场景宏观状态(FixStateMachine)。</summary>
|
||
[Serializable]
|
||
public class FixSnapshotDto
|
||
{
|
||
/// <summary><see cref="FixState"/> 枚举名。</summary>
|
||
public string state;
|
||
|
||
/// <summary>状态参数(如 BodyModule 的 ModuleState 字符串)。</summary>
|
||
public string args;
|
||
|
||
/// <summary>BodyModule 当前分组(Body/Head)。</summary>
|
||
public string moduleState;
|
||
|
||
/// <summary>EyeSystem 当前颜色阶段。</summary>
|
||
public string eyeColorState;
|
||
|
||
/// <summary>FixPanelSystem 是否已启动。</summary>
|
||
public bool isSystemOn;
|
||
|
||
/// <summary>RepairSystemManager 当前激活的系统类型名。</summary>
|
||
public string currentRepairSystemType;
|
||
}
|
||
|
||
#endregion
|
||
}
|