namespace AibisDream.SaveSystem { /// /// 可存点被拒绝的原因,供日志与 UI 提示使用。 /// public enum SavePointRejectReason { None, Restoring, GamePaused, NoActiveNode, StartNode, FunctionNode, NoAutoSave } /// /// 可存点判定器。 /// /// P3 只搭框架:规则不是最终版,后续随 Yarn 节点 tags 整理和章节策略扩展而更新。 /// 当前所有 FixState 均放行,不可存状态由 Yarn 节点流程控制。 /// /// public static class SavePointEvaluator { /// /// 当前是否可以自动存档。 /// public static bool CanAutoSave(out SavePointRejectReason reason) { if (SaveRestoreOrchestrator.IsRestoring) { reason = SavePointRejectReason.Restoring; return false; } if (GameManager.Instance != null && GameManager.Instance.state.isInPause) { reason = SavePointRejectReason.GamePaused; return false; } var (nodeName, tags) = DialogController.Instance != null ? DialogController.Instance.GetCurrentNodeContext() : (null, null); if (string.IsNullOrEmpty(nodeName)) { reason = SavePointRejectReason.NoActiveNode; return false; } if (nodeName == "Start") { reason = SavePointRejectReason.StartNode; return false; } if (tags != null && IsTagPresent(tags, "function")) { reason = SavePointRejectReason.FunctionNode; return false; } reason = SavePointRejectReason.None; return true; } /// /// 当前是否可以手动存档。 /// 手动档 = 复制最近自动档,因此需要当前可自动存档且自动档存在。 /// public static bool CanManualSave(out SavePointRejectReason reason) { if (!CanAutoSave(out reason)) { return false; } if (!SlotDirectory.Exists(SlotIndex.Auto)) { reason = SavePointRejectReason.NoAutoSave; return false; } reason = SavePointRejectReason.None; return true; } private static bool IsTagPresent(System.Collections.Generic.IReadOnlyList tags, string tag) { if (tags == null) return false; foreach (var t in tags) { if (t == tag) { return true; } } return false; } } }