using System; using System.Collections.Generic; using System.Collections.Immutable; using System.IO; using System.Linq; using System.Text.Json; using PkmnLib.Dataloader.Models; using PkmnLib.Static.Libraries; using PkmnLib.Static.Moves; using PkmnLib.Static.Utils; namespace PkmnLib.Dataloader; public static class MoveDataLoader { public static MoveLibrary LoadMoves(Stream stream, TypeLibrary typeLibrary) { var library = new MoveLibrary(); var objects = JsonSerializer.Deserialize(stream, new JsonSerializerOptions() { PropertyNameCaseInsensitive = true, }); if (objects == null) throw new InvalidDataException("Move data is empty."); var moves = objects.Data.Select(x => DeserializeMove(x, typeLibrary)); foreach (var m in moves) library.Add(m); return library; } private static MoveDataImpl DeserializeMove(SerializedMove serialized, TypeLibrary typeLibrary) { var type = serialized.Type; var power = serialized.Power; var pp = serialized.PP; var accuracy = serialized.Accuracy; var priority = serialized.Priority; var target = serialized.Target; var category = serialized.Category; var flags = serialized.Flags; var effect = serialized.Effect; if (target.Equals("self", StringComparison.InvariantCultureIgnoreCase)) target = "selfUse"; if (!typeLibrary.TryGetTypeIdentifier(type, out var typeIdentifier)) throw new InvalidDataException($"Type {type} is not a valid type."); if (!Enum.TryParse(category, true, out var categoryEnum)) throw new InvalidDataException($"Category {category} is not a valid category."); if (!Enum.TryParse(target, true, out var targetEnum)) throw new InvalidDataException($"Target {target} is not a valid target."); var secondaryEffect = ParseEffect(effect); var move = new MoveDataImpl(serialized.Name, typeIdentifier, categoryEnum, power, accuracy, pp, targetEnum, priority, secondaryEffect, flags.Select(x => (StringKey)x).ToImmutableHashSet()); return move; } private static ISecondaryEffect? ParseEffect(SerializedMoveEffect? effect) { if (effect == null) return null; var name = effect.Name; var chance = effect.Chance; var parameters = effect.Parameters?.ToDictionary(x => (StringKey)x.Key, x => x.Value.ToParameter()) ?? new Dictionary(); return new SecondaryEffectImpl(chance, name, parameters); } }