Deukhoofd fdfca99e71
All checks were successful
continuous-integration/drone/push Build is passing
Document all undocumented methods and properties
2025-05-16 13:59:36 +02:00

76 lines
3.2 KiB
C#

using System.Collections.Immutable;
using System.Text.Json;
using JetBrains.Annotations;
using PkmnLib.Dynamic.Libraries.DataLoaders.Models;
using PkmnLib.Static;
using PkmnLib.Static.Libraries;
using PkmnLib.Static.Moves;
using PkmnLib.Static.Utils;
namespace PkmnLib.Dynamic.Libraries.DataLoaders;
/// <summary>
/// Loads move data from a JSON file.
/// </summary>
public static class MoveDataLoader
{
/// <summary>
/// Loads move data from a stream.
/// </summary>
public static MoveLibrary LoadMoves(Stream stream, TypeLibrary typeLibrary,
Action<SerializedMoveDataWrapper>? onAfterLoad = null)
{
var library = new MoveLibrary();
var objects = JsonSerializer.Deserialize<SerializedMoveDataWrapper>(stream, JsonOptions.DefaultOptions);
if (objects == null)
throw new InvalidDataException("Move data is empty.");
onAfterLoad?.Invoke(objects);
var moves = objects.Data.Select(x => DeserializeMove(x, typeLibrary));
foreach (var m in moves)
library.Add(m);
return library;
}
/// <summary>
/// Factory delegate for creating moves.
/// </summary>
public delegate MoveDataImpl MoveFactoryDelegate(SerializedMove serialized, StringKey name, TypeIdentifier type,
MoveCategory category, byte basePower, byte accuracy, byte pp, MoveTarget target, sbyte priority,
ISecondaryEffect? secondaryEffect, IEnumerable<StringKey> flags);
/// <summary>
/// The move constructor. This is used to create moves from the JSON data.
/// </summary>
[PublicAPI] public static MoveFactoryDelegate MoveConstructor =
(_, name, moveType, category, basePower, accuracy, baseUsages, target, priority, secondaryEffect, flags) =>
new MoveDataImpl(name, moveType, category, basePower, accuracy, baseUsages, target, priority,
secondaryEffect, flags);
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<MoveCategory>(category, true, out var categoryEnum))
throw new InvalidDataException($"Category {category} is not a valid category.");
if (!Enum.TryParse<MoveTarget>(target, true, out var targetEnum))
throw new InvalidDataException($"Target {target} is not a valid target.");
var secondaryEffect = effect.ParseEffect();
var move = MoveConstructor(serialized, serialized.Name, typeIdentifier, categoryEnum, power, accuracy, pp,
targetEnum, priority, secondaryEffect, flags.Select(x => (StringKey)x).ToImmutableHashSet());
return move;
}
}