using PkmnLib.Dynamic.Libraries.DataLoaders; using PkmnLib.Dynamic.ScriptHandling; using PkmnLib.Dynamic.ScriptHandling.Registry; using PkmnLib.Static.Libraries; namespace PkmnLib.Dynamic.Libraries; /// /// Helper class for building data from plugins. /// public static class LibraryLoader { /// /// Result of loading plugins. /// public record LoadResult(ScriptRegistry Registry, ScriptResolver Resolver, IStaticLibrary StaticLibrary); /// /// Loads plugins and creates a static library from them. /// public static LoadResult LoadPlugins(IEnumerable 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 plugins) { var resourceProviders = plugins.OfType().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().ToList(); var typesLibrary = TypeDataLoader.LoadTypeLibrary(typesResult); var naturesLibrary = NatureDataLoader.LoadNatureLibrary(naturesResult); var movesLibrary = MoveDataLoader.LoadMoves(movesResult, typesLibrary, wrapper => mutators.ForEach(x => x.MutateMoveData(wrapper))); var itemsLibrary = ItemDataLoader.LoadItems(itemsResult, items => mutators.ForEach(x => x.MutateItemData(items))); var abilitiesLibrary = AbilityDataLoader.LoadAbilities(abilitiesResult, abilities => mutators.ForEach(x => x.MutateAbilityData(abilities))); var growthRatesLibrary = GrowthRateDataLoader.LoadGrowthRates(growthRatesResult, growthRates => mutators.ForEach(x => x.MutateGrowthRateData(growthRates))); var speciesLibrary = SpeciesDataLoader.LoadSpecies(speciesResult, typesLibrary, map => mutators.ForEach(x => x.MutateSpeciesData(map))); return new StaticLibraryImpl(settings, speciesLibrary, movesLibrary, abilitiesLibrary, typesLibrary, naturesLibrary, growthRatesLibrary, itemsLibrary); } }