using System.Diagnostics.CodeAnalysis; using PkmnLib.Static.Species; using PkmnLib.Static.Utils; namespace PkmnLib.Static.Libraries; /// <summary> /// The library for all species in the game. /// </summary> public interface IReadOnlySpeciesLibrary : IEnumerable<ISpecies> { /// <summary> /// Tries to get a species from the library. Returns false if the species is not found. /// </summary> bool TryGet(StringKey key, [MaybeNullWhen(false)] out ISpecies value); /// <summary> /// Tried to get a species from the library by its national dex number. Returns false if the species is not found. /// </summary> bool TryGetById(int id, [MaybeNullWhen(false)] out ISpecies value); /// <summary> /// Gets a random species from the library. /// </summary> ISpecies GetRandom(IRandom random); /// <summary> /// The amount of species in the library. /// </summary> int Count { get; } /// <summary> /// Whether the library is empty. /// </summary> bool IsEmpty { get; } /// <summary> /// Finds the Pokémon that evolves into the given species. If the species does not evolve, returns null. /// If multiple species evolve into the given species, returns the first one found. /// </summary> ISpecies? FindPreEvolution(ISpecies species); } /// <inheritdoc cref="IReadOnlySpeciesLibrary"/> public class SpeciesLibrary : DataLibrary<ISpecies>, IReadOnlySpeciesLibrary { private Dictionary<ISpecies, ISpecies> _preEvolutionCache = new(); /// <inheritdoc /> public bool TryGetById(int id, [MaybeNullWhen(false)] out ISpecies value) { return this.FirstOrDefault(s => s.Id == id) is { } species ? (value = species) != null : (value = default) != null; } /// <inheritdoc /> public ISpecies? FindPreEvolution(ISpecies species) { if (_preEvolutionCache.TryGetValue(species, out var preEvolution)) return preEvolution; foreach (var s in this) { if (s.EvolutionData.All(e => e.ToSpecies != species.Name)) continue; _preEvolutionCache[species] = s; return s; } return null; } }