using Theriapolis.Core.Entities; using Theriapolis.Core.Tactical; using Theriapolis.Core.Time; namespace Theriapolis.Core.Persistence; /// /// All save-worthy state outside the seed-derivable world. Phase 4 fills the /// player, clock, chunk deltas, and world-tile deltas; the other fields are /// reserved for Phase 5/6 so adding them later doesn't require a schema bump. /// public sealed class SaveBody { public PlayerActorState Player { get; set; } = new(); public WorldClockState Clock { get; set; } = new(); /// /// Phase 5: full character snapshot (clade, species, class, abilities, /// HP, inventory). Null on Phase-4 saves; the loader treats null as a /// migration-failed signal and refuses the save. /// public PlayerCharacterState? PlayerCharacter { get; set; } /// /// Phase 5 M5: per-chunk NPC roster delta (which spawn indices have died). /// Empty on a fresh save; populated as the player kills NPCs. /// public NpcRosterState NpcRoster { get; set; } = new(); /// /// Phase 5 M5: present only when the player saved mid-combat. On load, /// PlayScreen re-creates the encounter from this snapshot and pushes /// CombatHUDScreen directly without going through the title. /// public EncounterState? ActiveEncounter { get; set; } /// Per-chunk player-modification overlay. public Dictionary ModifiedChunks { get; set; } = new(); /// Sparse per-world-tile changes (e.g. burned settlement). public List ModifiedWorldTiles { get; set; } = new(); // ── Reserved for later phases ──────────────────────────────────────── // Empty containers so save schema doesn't need a migration when each // subsystem comes online. public Dictionary Flags { get; set; } = new(); /// v5 placeholder. Phase 6 M2 superseded by . public Dictionary Factions { get; set; } = new(); /// v5 placeholder. Phase 6 M4 superseded by . public List QuestState { get; set; } = new(); /// v5 placeholder. Phase 6 M2 superseded by . public Dictionary Reputation { get; set; } = new(); public List DiscoveredPoiIds { get; set; } = new(); /// /// Phase 6 M2 — full reputation snapshot (faction standings, per-NPC /// personal dispositions, recent ledger). Empty on a fresh game; the /// V5→V6 migration leaves this empty too (Phase-5 saves never /// accumulated rep state). /// public ReputationSnapshot ReputationState { get; set; } = new(); /// /// Phase 6 M4 — quest engine snapshot. Empty before any quest /// activates. Named QuestEngineState to avoid colliding with /// the v5 placeholder dictionary. /// public QuestSnapshot QuestEngineState { get; set; } = new(); } /// One world-tile cell that diverged from worldgen baseline. public readonly struct WorldTileDelta { public readonly ushort X; public readonly ushort Y; public readonly byte NewBiome; public readonly ushort NewFeatures; public WorldTileDelta(int x, int y, byte biome, ushort features) { X = (ushort)x; Y = (ushort)y; NewBiome = biome; NewFeatures = features; } }