diff --git a/PkmnLib.Dynamic/Libraries/DynamicLibrary.cs b/PkmnLib.Dynamic/Libraries/DynamicLibrary.cs index b59c513..59eaf86 100644 --- a/PkmnLib.Dynamic/Libraries/DynamicLibrary.cs +++ b/PkmnLib.Dynamic/Libraries/DynamicLibrary.cs @@ -55,6 +55,11 @@ public interface IDynamicLibrary /// to make decisions. /// IReadOnlyExplicitAIHandlers ExplicitAIHandlers { get; } + + /// + /// Library for handling of whether a Pokemon can evolve. + /// + IEvolutionLibrary EvolutionLibrary { get; } } /// @@ -86,6 +91,7 @@ public class DynamicLibraryImpl : IDynamicLibrary ExplicitAIHandlers = explicitAIHandlers; ExperienceGainCalculator = experienceGainCalculator; CaptureLibrary = captureLibrary; + EvolutionLibrary = new EvolutionLibrary(miscLibrary, staticLibrary.Species); } /// @@ -111,4 +117,7 @@ public class DynamicLibraryImpl : IDynamicLibrary /// public IReadOnlyExplicitAIHandlers ExplicitAIHandlers { get; } + + /// + public IEvolutionLibrary EvolutionLibrary { get; } } \ No newline at end of file diff --git a/PkmnLib.Dynamic/Libraries/EvolutionLibrary.cs b/PkmnLib.Dynamic/Libraries/EvolutionLibrary.cs new file mode 100644 index 0000000..8e388c5 --- /dev/null +++ b/PkmnLib.Dynamic/Libraries/EvolutionLibrary.cs @@ -0,0 +1,81 @@ +using System.Diagnostics.CodeAnalysis; +using PkmnLib.Dynamic.Models; +using PkmnLib.Static; +using PkmnLib.Static.Libraries; +using PkmnLib.Static.Species; + +namespace PkmnLib.Dynamic.Libraries; + +/// +/// Handling of whether a Pokemon can evolve +/// +public interface IEvolutionLibrary +{ + /// + /// Check if a Pokemon can evolve if it levels up, Returns true if so. + /// + [PublicAPI] + bool CanEvolveFromLevelUp(IPokemon pokemon, LevelInt level, [NotNullWhen(true)] out ISpecies? evolveToSpecies, + [NotNullWhen(true)] out IForm? evolveToForm); +} + +/// +public class EvolutionLibrary : IEvolutionLibrary +{ + private readonly IMiscLibrary _miscLibrary; + private readonly IReadOnlySpeciesLibrary _speciesLibrary; + + /// + public EvolutionLibrary(IMiscLibrary miscLibrary, IReadOnlySpeciesLibrary speciesLibrary) + { + _miscLibrary = miscLibrary; + _speciesLibrary = speciesLibrary; + } + + /// + public bool CanEvolveFromLevelUp(IPokemon pokemon, LevelInt level, + [NotNullWhen(true)] out ISpecies? evolveToSpecies, [NotNullWhen(true)] out IForm? evolveToForm) + { + foreach (var data in pokemon.Species.EvolutionData) + { + switch (data) + { + case LevelEvolution lvlEvolution when lvlEvolution.Level >= level: + case LevelGenderEvolution genderEvolution + when genderEvolution.Gender == pokemon.Gender && genderEvolution.Level >= level: + case HoldItemEvolution holdItemEvolution when pokemon.HasHeldItem(holdItemEvolution.Item): + case DayHoldItemEvolution dayHoldItemEvolution + when _miscLibrary.GetTimeOfDay() is TimeOfDay.Day or TimeOfDay.Morning && + pokemon.HasHeldItem(dayHoldItemEvolution.Item): + case NightHoldItemEvolution nightHoldItemEvolution + when _miscLibrary.GetTimeOfDay() is TimeOfDay.Night or TimeOfDay.Evening && + pokemon.HasHeldItem(nightHoldItemEvolution.Item): + case HasMoveEvolution hasMoveEvolution when pokemon.HasMove(hasMoveEvolution.MoveName): + case HappinessEvolution happinessEvolution when pokemon.Happiness >= happinessEvolution.Happiness: + case HappinessDayEvolution happinessDayEvolution + when _miscLibrary.GetTimeOfDay() is TimeOfDay.Day or TimeOfDay.Morning && + pokemon.Happiness >= happinessDayEvolution.Happiness: + case HappinessNightEvolution happinessNightEvolution + when _miscLibrary.GetTimeOfDay() is TimeOfDay.Night or TimeOfDay.Evening && + pokemon.Happiness >= happinessNightEvolution.Happiness: + { + if (_speciesLibrary.TryGet(data.ToSpecies, out var species)) + { + evolveToSpecies = species; + evolveToForm = species.GetDefaultForm(); + return true; + } + throw new Exception($"Could not find evolution species {data.ToSpecies} for Pokemon {pokemon}"); + } + case CustomEvolution customEvolution: + { + throw new NotImplementedException( + $"Custom evolution for {pokemon.Species} to {customEvolution.ToSpecies} is not implemented"); + } + } + } + evolveToSpecies = null; + evolveToForm = null; + return false; + } +} \ No newline at end of file