#nullable enable using System; using System.Collections.Generic; using System.Linq; namespace ReplacedPerson.Core { [Serializable] public sealed class ReplacedPersonSaveData { public const int CurrentVersion = 3; public int Version { get; set; } = CurrentVersion; public int ChapterProgress { get; set; } public List CollectedCards { get; set; } = new(); public List Ornaments { get; set; } = new(); public List EquippedOrnaments { get; set; } = new(); public ReplacedDeck ActiveDeck { get; set; } = ReplacedBuiltInContent.CreateStarterDeck(); public List RecentReplay { get; set; } = new(); } public static class ReplacedPersonSaveMigration { public static ReplacedPersonSaveData Migrate(ReplacedPersonSaveData source) { if (source == null) throw new ArgumentNullException(nameof(source)); if (source.Version > ReplacedPersonSaveData.CurrentVersion) throw new InvalidOperationException("Save data comes from a newer version."); source.CollectedCards ??= new List(); source.Ornaments ??= new List(); source.EquippedOrnaments ??= new List(); source.ActiveDeck ??= ReplacedBuiltInContent.CreateStarterDeck(); source.RecentReplay ??= new List(); if (source.Version < 2) { if (source.ChapterProgress > 0 && !source.Ornaments.Contains("ornament.gold-eye")) source.Ornaments.Add("ornament.gold-eye"); source.Version = 2; } if (source.Version < 3) { var starter = ReplacedBuiltInContent.CreateStarterDeck(); if (IsLegacyStarter(source.ActiveDeck)) source.ActiveDeck = starter; EnsureOwnedCopies(source.CollectedCards, starter.NormalCards); source.Version = 3; } return source; } public static ReplacedPersonSaveData CreateNew() { var deck = ReplacedBuiltInContent.CreateStarterDeck(); return new ReplacedPersonSaveData { ActiveDeck = deck, CollectedCards = new List(deck.NormalCards) }; } private static bool IsLegacyStarter(ReplacedDeck deck) { var legacy = new[] { "attack.kill", "attack.kill", "attack.elbow", "attack.elbow", "attack.break", "attack.break", "dodge.flash", "dodge.flash", "dodge.phase", "dodge.phase", "counter.blood", "counter.blood" }; return deck.NormalCards.OrderBy(value => value, StringComparer.Ordinal) .SequenceEqual(legacy.OrderBy(value => value, StringComparer.Ordinal)) && deck.EndCards.SequenceEqual(new[] { "end.inherit", "end.ledger", "end.severance", "end.black" }); } private static void EnsureOwnedCopies(List collection, IEnumerable starterCards) { foreach (var group in starterCards.GroupBy(value => value, StringComparer.Ordinal)) { var missing = group.Count() - collection.Count(value => value == group.Key); for (var i = 0; i < missing; i++) collection.Add(group.Key); } } } }