103 lines
5.4 KiB
C#

using PkmnLib.Dynamic.Libraries.DataLoaders;
using PkmnLib.Dynamic.ScriptHandling;
using PkmnLib.Dynamic.ScriptHandling.Registry;
using PkmnLib.Static.Libraries;
namespace PkmnLib.Dynamic.Libraries;
/// <summary>
/// Helper class for building data from plugins.
/// </summary>
public static class LibraryLoader
{
/// <summary>
/// Result of loading plugins.
/// </summary>
public record LoadResult(ScriptRegistry Registry, ScriptResolver Resolver, IStaticLibrary StaticLibrary);
/// <summary>
/// Loads plugins and creates a static library from them.
/// </summary>
public static LoadResult LoadPlugins(IEnumerable<Plugin> plugins)
{
var registry = new ScriptRegistry();
var orderedPlugins = plugins.OrderBy(x => x.LoadOrder).ToList();
var staticLibrary = CreateStaticLibrary(orderedPlugins);
foreach (var plugin in orderedPlugins)
{
plugin.Register(registry);
}
if (registry.DamageCalculator is null)
throw new InvalidOperationException("Damage calculator not found in plugins.");
if (registry.BattleStatCalculator is null)
throw new InvalidOperationException("Stat calculator not found in plugins.");
if (registry.MiscLibrary is null)
throw new InvalidOperationException("Misc library not found in plugins.");
if (registry.CaptureLibrary is null)
throw new InvalidOperationException("Capture library not found in plugins.");
var scriptResolver = new ScriptResolver(registry.ScriptTypes, registry.ItemScriptTypes);
return new LoadResult(registry, scriptResolver, staticLibrary);
}
private static StaticLibraryImpl CreateStaticLibrary(IReadOnlyList<Plugin> plugins)
{
var resourceProviders = plugins.OfType<IResourceProvider>().ToList();
var settings = resourceProviders.Select(x => x.Settings).LastOrDefault(x => x != null);
if (settings == null)
throw new InvalidOperationException("Settings not found.");
var typesResult = resourceProviders.Select(x => x.GetResource(ResourceFileType.Types))
.LastOrDefault(x => x != null);
if (typesResult == null)
throw new InvalidOperationException("Types resource not found.");
var naturesResult = resourceProviders.Select(x => x.GetResource(ResourceFileType.Natures))
.LastOrDefault(x => x != null);
if (naturesResult == null)
throw new InvalidOperationException("Natures resource not found.");
var movesResult = resourceProviders.Select(x => x.GetResource(ResourceFileType.Moves))
.LastOrDefault(x => x != null);
if (movesResult == null)
throw new InvalidOperationException("Moves resource not found.");
var itemsResult = resourceProviders.Select(x => x.GetResource(ResourceFileType.Items))
.LastOrDefault(x => x != null);
if (itemsResult == null)
throw new InvalidOperationException("Items resource not found.");
var abilitiesResult = resourceProviders.Select(x => x.GetResource(ResourceFileType.Abilities))
.LastOrDefault(x => x != null);
if (abilitiesResult == null)
throw new InvalidOperationException("Abilities resource not found.");
var growthRatesResult = resourceProviders.Select(x => x.GetResource(ResourceFileType.GrowthRates))
.LastOrDefault(x => x != null);
if (growthRatesResult == null)
throw new InvalidOperationException("Growth rates resource not found.");
var speciesResult = resourceProviders.Select(x => x.GetResource(ResourceFileType.Species))
.LastOrDefault(x => x != null);
if (speciesResult == null)
throw new InvalidOperationException("Species resource not found.");
// ReSharper disable once SuspiciousTypeConversion.Global
var mutators = plugins.OfType<IPluginDataMutator>().ToList();
using var typesStream = typesResult.Open();
var typesLibrary = TypeDataLoader.LoadTypeLibrary(typesStream);
using var naturesStream = naturesResult.Open();
var naturesLibrary = NatureDataLoader.LoadNatureLibrary(naturesStream);
using var movesStream = movesResult.Open();
var movesLibrary = MoveDataLoader.LoadMoves(movesStream, typesLibrary,
wrapper => mutators.ForEach(x => x.MutateMoveData(wrapper)));
using var itemsStream = itemsResult.Open();
var itemsLibrary = ItemDataLoader.LoadItems(itemsStream,
items => mutators.ForEach(x => x.MutateItemData(items)));
using var abilitiesStream = abilitiesResult.Open();
var abilitiesLibrary = AbilityDataLoader.LoadAbilities(abilitiesStream,
abilities => mutators.ForEach(x => x.MutateAbilityData(abilities)));
using var growthRatesStream = growthRatesResult.Open();
var growthRatesLibrary = GrowthRateDataLoader.LoadGrowthRates(growthRatesStream,
growthRates => mutators.ForEach(x => x.MutateGrowthRateData(growthRates)));
using var speciesStream = speciesResult.Open();
var speciesLibrary = SpeciesDataLoader.LoadSpecies(speciesStream, typesLibrary,
map => mutators.ForEach(x => x.MutateSpeciesData(map)));
return new StaticLibraryImpl(settings, speciesLibrary, movesLibrary, abilitiesLibrary, typesLibrary,
naturesLibrary, growthRatesLibrary, itemsLibrary);
}
}