Files
Workspace/Assets/Demos/ReplacedPerson/Core/Progression.cs
T
2026-08-17 18:18:13 +08:00

82 lines
3.4 KiB
C#

#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<string> CollectedCards { get; set; } = new();
public List<string> Ornaments { get; set; } = new();
public List<string> EquippedOrnaments { get; set; } = new();
public ReplacedDeck ActiveDeck { get; set; } = ReplacedBuiltInContent.CreateStarterDeck();
public List<ReplacedMatchCommand> 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<string>();
source.Ornaments ??= new List<string>();
source.EquippedOrnaments ??= new List<string>();
source.ActiveDeck ??= ReplacedBuiltInContent.CreateStarterDeck();
source.RecentReplay ??= new List<ReplacedMatchCommand>();
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<string>(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<string> collection, IEnumerable<string> 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);
}
}
}
}