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