Move data and data loading to plugin libraries.
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
227
PkmnLib.Dynamic/Libraries/DataLoaders/SpeciesDataLoader.cs
Normal file
227
PkmnLib.Dynamic/Libraries/DataLoaders/SpeciesDataLoader.cs
Normal file
@@ -0,0 +1,227 @@
|
||||
using System.Collections.Immutable;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Nodes;
|
||||
using PkmnLib.Dynamic.Libraries.DataLoaders.Models;
|
||||
using PkmnLib.Static;
|
||||
using PkmnLib.Static.Libraries;
|
||||
using PkmnLib.Static.Species;
|
||||
using PkmnLib.Static.Utils;
|
||||
|
||||
namespace PkmnLib.Dynamic.Libraries.DataLoaders;
|
||||
|
||||
public static class SpeciesDataLoader
|
||||
{
|
||||
private static Dictionary<string, SerializedSpecies> LoadSpeciesData(Stream stream)
|
||||
{
|
||||
var obj = JsonSerializer.Deserialize<JsonObject>(stream, JsonOptions.DefaultOptions);
|
||||
if (obj == null)
|
||||
throw new InvalidDataException("Species data is empty.");
|
||||
return obj.Where(x => x.Key != "$schema").ToDictionary(x => x.Key,
|
||||
x => x.Value.Deserialize<SerializedSpecies>(JsonOptions.DefaultOptions))!;
|
||||
}
|
||||
|
||||
public static SpeciesLibrary LoadSpecies(Stream stream, IReadOnlyTypeLibrary typeLibrary,
|
||||
Action<Dictionary<string, SerializedSpecies>>? action = null)
|
||||
{
|
||||
var library = new SpeciesLibrary();
|
||||
var objects = LoadSpeciesData(stream);
|
||||
if (objects == null)
|
||||
throw new InvalidDataException("Species data is empty.");
|
||||
action?.Invoke(objects);
|
||||
var species = objects.Select(x => DeserializeSpecies(x.Value, typeLibrary));
|
||||
foreach (var s in species)
|
||||
library.Add(s);
|
||||
return library;
|
||||
}
|
||||
|
||||
public static
|
||||
Func<SerializedSpecies, ushort, StringKey, float, StringKey, byte, byte, IReadOnlyDictionary<StringKey, IForm>,
|
||||
IEnumerable<StringKey>, IReadOnlyList<IEvolution>, IEnumerable<StringKey>, SpeciesImpl> SpeciesConstructor =
|
||||
(_, id, name, genderRate, growthRate, captureRate, baseHappiness, forms, flags, evolutionData, eggGroups) =>
|
||||
{
|
||||
return new SpeciesImpl(id, name, genderRate, growthRate, captureRate, baseHappiness, forms, flags,
|
||||
evolutionData, eggGroups);
|
||||
};
|
||||
|
||||
private static SpeciesImpl DeserializeSpecies(SerializedSpecies serialized, IReadOnlyTypeLibrary typeLibrary)
|
||||
{
|
||||
var id = serialized.Id;
|
||||
var genderRate = serialized.GenderRatio;
|
||||
if (genderRate < -1.0 || genderRate > 100.0)
|
||||
{
|
||||
throw new InvalidDataException(
|
||||
$"Gender rate for species {id} is invalid: {genderRate}. Must be between -1.0 and 100.0.");
|
||||
}
|
||||
|
||||
if (serialized.EggCycles < 0)
|
||||
{
|
||||
throw new InvalidDataException(
|
||||
$"Egg cycles for species {id} is invalid: {serialized.EggCycles}. Must be greater than or equal to 0.");
|
||||
}
|
||||
|
||||
var forms = serialized.Formes.ToDictionary(x => (StringKey)x.Key,
|
||||
x => DeserializeForm(x.Key, x.Value, typeLibrary));
|
||||
var evolutions = serialized.Evolutions.Select(DeserializeEvolution).ToList();
|
||||
|
||||
var species = SpeciesConstructor(serialized, serialized.Id, serialized.Species, genderRate,
|
||||
serialized.GrowthRate, serialized.CatchRate, serialized.BaseHappiness, forms,
|
||||
serialized.Flags.Select(x => new StringKey(x)), evolutions, serialized.EggGroups.Select(x => (StringKey)x));
|
||||
return species;
|
||||
}
|
||||
|
||||
private static IForm DeserializeForm(string name, SerializedForm form, IReadOnlyTypeLibrary typeLibrary)
|
||||
{
|
||||
if (form == null)
|
||||
throw new ArgumentException("Form data is null.", nameof(form));
|
||||
if (form.Height < 0.0)
|
||||
{
|
||||
throw new InvalidDataException(
|
||||
$"Height for form {name} is invalid: {form.Height}. Must be greater than or equal to 0.0.");
|
||||
}
|
||||
if (form.Weight < 0.0)
|
||||
{
|
||||
throw new InvalidDataException(
|
||||
$"Weight for form {name} is invalid: {form.Weight}. Must be greater than or equal to 0.0.");
|
||||
}
|
||||
var types = form.Types.Select(x =>
|
||||
typeLibrary.TryGetTypeIdentifier(new StringKey(x), out var t)
|
||||
? t
|
||||
: throw new InvalidDataException($"Type {x} for form {name} is invalid.")).ToList();
|
||||
|
||||
return new FormImpl(name, form.Height, form.Weight, form.BaseExp, types, DeserializeStats(form.BaseStats),
|
||||
form.Abilities.Select(x => new StringKey(x)).ToList(),
|
||||
form.HiddenAbilities.Select(x => new StringKey(x)).ToList(), DeserializeMoves(form.Moves),
|
||||
form.Flags.Select(x => new StringKey(x)).ToImmutableHashSet());
|
||||
}
|
||||
|
||||
private static ILearnableMoves DeserializeMoves(SerializedMoves moves)
|
||||
{
|
||||
var learnableMoves = new LearnableMovesImpl();
|
||||
if (moves.LevelMoves != null)
|
||||
{
|
||||
foreach (var levelMove in moves.LevelMoves)
|
||||
{
|
||||
learnableMoves.AddLevelMove((byte)levelMove.Level, new StringKey(levelMove.Name));
|
||||
}
|
||||
}
|
||||
|
||||
if (moves.EggMoves != null)
|
||||
{
|
||||
foreach (var eggMove in moves.EggMoves)
|
||||
{
|
||||
learnableMoves.AddEggMove(new StringKey(eggMove));
|
||||
}
|
||||
}
|
||||
|
||||
return learnableMoves;
|
||||
}
|
||||
|
||||
private static ImmutableStatisticSet<ushort> DeserializeStats(SerializedStats stats) =>
|
||||
new(stats.Hp, stats.Attack, stats.Defense, stats.SpecialAttack, stats.SpecialDefense, stats.Speed);
|
||||
|
||||
private static IEvolution DeserializeEvolution(SerializedEvolution evolution)
|
||||
{
|
||||
return evolution.Method.ToLowerInvariant() switch
|
||||
{
|
||||
"level" => new LevelEvolution
|
||||
{
|
||||
Level = evolution.Data.GetValue<byte>(),
|
||||
ToSpecies = evolution.Species,
|
||||
},
|
||||
"levelfemale" => new LevelGenderEvolution
|
||||
{
|
||||
Level = evolution.Data.GetValue<byte>(),
|
||||
Gender = Gender.Female,
|
||||
ToSpecies = evolution.Species,
|
||||
},
|
||||
"levelmale" => new LevelGenderEvolution
|
||||
{
|
||||
Level = evolution.Data.GetValue<byte>(),
|
||||
Gender = Gender.Male,
|
||||
ToSpecies = evolution.Species,
|
||||
},
|
||||
"happiness" => new HappinessEvolution
|
||||
{
|
||||
Happiness = evolution.Data.GetValue<byte>(),
|
||||
ToSpecies = evolution.Species,
|
||||
},
|
||||
"happinessday" => new HappinessDayEvolution
|
||||
{
|
||||
Happiness = evolution.Data.GetValue<byte>(),
|
||||
ToSpecies = evolution.Species,
|
||||
},
|
||||
"happinessnight" => new HappinessNightEvolution
|
||||
{
|
||||
Happiness = evolution.Data.GetValue<byte>(),
|
||||
ToSpecies = evolution.Species,
|
||||
},
|
||||
"item" => new ItemUseEvolution
|
||||
{
|
||||
Item = evolution.Data.GetValue<string>() ?? throw new InvalidDataException("Item is null."),
|
||||
ToSpecies = evolution.Species,
|
||||
},
|
||||
"itemmale" => new ItemGenderEvolution
|
||||
{
|
||||
Item = evolution.Data.GetValue<string>() ?? throw new InvalidDataException("Item is null."),
|
||||
ToSpecies = evolution.Species,
|
||||
},
|
||||
"itemfemale" => new ItemGenderEvolution
|
||||
{
|
||||
Item = evolution.Data.GetValue<string>() ?? throw new InvalidDataException("Item is null."),
|
||||
ToSpecies = evolution.Species,
|
||||
},
|
||||
"holditem" => new HoldItemEvolution
|
||||
{
|
||||
Item = evolution.Data.GetValue<string>() ?? throw new InvalidDataException("Item is null."),
|
||||
ToSpecies = evolution.Species,
|
||||
},
|
||||
"dayholditem" => new DayHoldItemEvolution
|
||||
{
|
||||
Item = evolution.Data.GetValue<string>() ?? throw new InvalidDataException("Item is null."),
|
||||
ToSpecies = evolution.Species,
|
||||
},
|
||||
"nightholditem" => new NightHoldItemEvolution
|
||||
{
|
||||
Item = evolution.Data.GetValue<string>() ?? throw new InvalidDataException("Item is null."),
|
||||
ToSpecies = evolution.Species,
|
||||
},
|
||||
"hasmove" => new HasMoveEvolution
|
||||
{
|
||||
MoveName = evolution.Data.GetValue<string>() ?? throw new InvalidDataException("Move is null."),
|
||||
ToSpecies = evolution.Species,
|
||||
},
|
||||
"trade" => new TradeEvolution
|
||||
{
|
||||
ToSpecies = evolution.Species,
|
||||
},
|
||||
"tradespecies" => new TradeSpeciesEvolution
|
||||
{
|
||||
WithSpecies = evolution.Data.GetValue<string>() ?? throw new InvalidDataException("Species is null."),
|
||||
ToSpecies = evolution.Species,
|
||||
},
|
||||
"tradeitem" => new TradeItemEvolution
|
||||
{
|
||||
Item = evolution.Data.GetValue<string>() ?? throw new InvalidDataException("Item is null."),
|
||||
ToSpecies = evolution.Species,
|
||||
},
|
||||
"location" => new CustomEvolution
|
||||
{
|
||||
Name = "location",
|
||||
Parameters = new Dictionary<StringKey, object?>
|
||||
{
|
||||
["location"] = evolution.Data.ToString() ?? throw new InvalidDataException("Location is null."),
|
||||
},
|
||||
ToSpecies = evolution.Species,
|
||||
},
|
||||
"custom" => new CustomEvolution
|
||||
{
|
||||
Name = evolution.Data.AsObject()["type"]?.GetValue<string>() ??
|
||||
throw new InvalidDataException("Type is null."),
|
||||
Parameters = evolution.Data.AsObject().Where(x => x.Key != "type")
|
||||
.ToDictionary(x => new StringKey(x.Key), x => x.Value!.ToParameter()),
|
||||
ToSpecies = evolution.Species,
|
||||
},
|
||||
_ => throw new InvalidDataException($"Evolution type {evolution.Method} is invalid."),
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user