diff --git a/PkmnLib.Dynamic/AI/AIHelpers.cs b/PkmnLib.Dynamic/AI/AIHelpers.cs
index 304c70a..2d76774 100644
--- a/PkmnLib.Dynamic/AI/AIHelpers.cs
+++ b/PkmnLib.Dynamic/AI/AIHelpers.cs
@@ -6,8 +6,14 @@ using PkmnLib.Static.Utils;
namespace PkmnLib.Dynamic.AI;
+///
+/// Helper functions for AI
+///
public static class AIHelpers
{
+ ///
+ /// Estimates the amount of damage that will be done by a move against a target.
+ ///
public static uint CalculateDamageEstimation(IMoveData move, IPokemon user, IPokemon target,
IDynamicLibrary library)
{
diff --git a/PkmnLib.Dynamic/AI/AILogging.cs b/PkmnLib.Dynamic/AI/AILogging.cs
index bd70b80..0bb236b 100644
--- a/PkmnLib.Dynamic/AI/AILogging.cs
+++ b/PkmnLib.Dynamic/AI/AILogging.cs
@@ -1,8 +1,18 @@
namespace PkmnLib.Dynamic.AI;
+///
+/// Logging implementation for AI
+///
public static class AILogging
{
+ ///
+ /// The actual function called by the logging.
+ ///
public static Action LogHandler { get; set; } = _ => { };
+ ///
+ /// Forwarding function.
+ ///
+ ///
public static void LogInformation(string message) => LogHandler(message);
}
\ No newline at end of file
diff --git a/PkmnLib.Dynamic/AI/Explicit/AIMoveState.cs b/PkmnLib.Dynamic/AI/Explicit/AIMoveState.cs
index a7c3914..8d19a0f 100644
--- a/PkmnLib.Dynamic/AI/Explicit/AIMoveState.cs
+++ b/PkmnLib.Dynamic/AI/Explicit/AIMoveState.cs
@@ -3,14 +3,25 @@ using PkmnLib.Static.Moves;
namespace PkmnLib.Dynamic.AI.Explicit;
+///
+/// Container wrapper for a move and its user.
+///
public class AIMoveState
{
+ ///
public AIMoveState(IPokemon user, IMoveData move)
{
User = user;
Move = move;
}
+ ///
+ /// The user that's being wrapper
+ ///
public IPokemon User { get; }
+
+ ///
+ /// The move that's being wrapper
+ ///
public IMoveData Move { get; }
}
\ No newline at end of file
diff --git a/PkmnLib.Dynamic/AI/Explicit/ExplicitAI.Switch.cs b/PkmnLib.Dynamic/AI/Explicit/ExplicitAI.Switch.cs
index bea4ee8..1a0c59d 100644
--- a/PkmnLib.Dynamic/AI/Explicit/ExplicitAI.Switch.cs
+++ b/PkmnLib.Dynamic/AI/Explicit/ExplicitAI.Switch.cs
@@ -45,8 +45,7 @@ public partial class ExplicitAI
return false;
}
var battleSide = pokemon.BattleData!.BattleSide;
- var bestReplacement =
- ChooseBestReplacementPokemon(pokemon.BattleData!.Position, terribleMoves, usablePokemon, battleSide);
+ var bestReplacement = ChooseBestReplacementPokemon(terribleMoves, usablePokemon, battleSide);
if (bestReplacement is null)
{
AILogging.LogInformation(
@@ -57,8 +56,8 @@ public partial class ExplicitAI
return true;
}
- private IPokemon? ChooseBestReplacementPokemon(byte position, bool terribleMoves,
- IReadOnlyList usablePokemon, IBattleSide battleSide)
+ private IPokemon? ChooseBestReplacementPokemon(bool terribleMoves, IReadOnlyList usablePokemon,
+ IBattleSide battleSide)
{
var options = usablePokemon.Where((_, index) =>
{
diff --git a/PkmnLib.Dynamic/AI/Explicit/ExplicitAIHandlers.cs b/PkmnLib.Dynamic/AI/Explicit/ExplicitAIHandlers.cs
index fe5ac56..0962465 100644
--- a/PkmnLib.Dynamic/AI/Explicit/ExplicitAIHandlers.cs
+++ b/PkmnLib.Dynamic/AI/Explicit/ExplicitAIHandlers.cs
@@ -3,17 +3,35 @@ using PkmnLib.Static.Utils;
namespace PkmnLib.Dynamic.AI.Explicit;
+///
+/// An option where a move is used against a target
+///
public record struct MoveOption(AIMoveState Move, IBattle Battle, IPokemon? Target, uint EstimatedDamage = 0);
+///
+/// A function that takes an explicit AI and a move option and returns a boolean value.
+///
public delegate bool AIBoolHandler(IExplicitAI ai, MoveOption option);
+///
+/// A function for returning whether a Pokemon should switch.
+///
public delegate bool AISwitchBoolHandler(IExplicitAI ai, IPokemon pokemon, IBattle battle,
IReadOnlyList reserves);
+///
+/// A function for returning the base power of a move.
+///
public delegate void AIMoveBasePowerHandler(IExplicitAI ai, MoveOption option, ref int score);
+///
+/// A function for returning a score
+///
public delegate void AIScoreMoveHandler(IExplicitAI ai, MoveOption option, ref int score);
+///
+/// Explicit AI Handlers are a library that allow plugins to explicitly indicate AI preferences.
+///
public interface IReadOnlyExplicitAIHandlers
{
///
@@ -86,28 +104,50 @@ public interface IReadOnlyExplicitAIHandlers
///
void ApplyGenerateMoveAgainstTargetScoreModifiers(IExplicitAI ai, MoveOption option, ref int score);
+ ///
+ /// Functions that indicate whether a Pokemon should switch
+ ///
IReadOnlyDictionary ShouldSwitchFunctions { get; }
+ ///
+ /// Indicates whether a Pokemon should switch into another Pokemon
+ ///
bool ShouldSwitch(IExplicitAI ai, IPokemon pokemon, IBattle battle, IReadOnlyList reserves);
+ ///
+ /// Functions that indicate whether a Pokemon should NOT switch
+ ///
IReadOnlyDictionary ShouldNotSwitchFunctions { get; }
+ ///
+ /// Indicates whether a Pokemon should NOT switch into another Pokemon
+ ///
bool ShouldNotSwitch(IExplicitAI ai, IPokemon pokemon, IBattle battle, IReadOnlyList reserves);
+ ///
+ /// Scores abilities
+ ///
IReadOnlyDictionary AbilityRanking { get; }
}
+///
public class ExplicitAIHandlers : IReadOnlyExplicitAIHandlers
{
///
IReadOnlyDictionary IReadOnlyExplicitAIHandlers.MoveFailureCheck => MoveFailureCheck;
+ ///
+ /// Checks whether a move will fail
+ ///
public FunctionHandlerDictionary MoveFailureCheck { get; } = new();
///
public bool MoveWillFail(IExplicitAI ai, StringKey functionCode, MoveOption option) =>
MoveFailureCheck.TryGetValue(functionCode, out var handler) && handler(ai, option);
+ ///
+ /// Checks whether a move will fail against a target
+ ///
public FunctionHandlerDictionary MoveFailureAgainstTargetCheck { get; } = new();
///
@@ -118,12 +158,18 @@ public class ExplicitAIHandlers : IReadOnlyExplicitAIHandlers
public bool MoveWillFailAgainstTarget(IExplicitAI ai, StringKey functionCode, MoveOption option) =>
MoveFailureAgainstTargetCheck.TryGetValue(functionCode, out var handler) && handler(ai, option);
+ ///
+ /// Functions to score a move
+ ///
public FunctionHandlerDictionary MoveEffectScore { get; } = [];
///
IReadOnlyDictionary IReadOnlyExplicitAIHandlers.MoveEffectScore =>
MoveEffectScore;
+ ///
+ /// Functions to score a move against a target
+ ///
public FunctionHandlerDictionary MoveEffectAgainstTargetScore = [];
///
@@ -137,6 +183,9 @@ public class ExplicitAIHandlers : IReadOnlyExplicitAIHandlers
IReadOnlyDictionary IReadOnlyExplicitAIHandlers.MoveEffectAgainstTargetScore =>
MoveEffectAgainstTargetScore;
+ ///
+ /// Functions that indicate a moves base power
+ ///
public FunctionHandlerDictionary MoveBasePower = [];
///
@@ -150,6 +199,9 @@ public class ExplicitAIHandlers : IReadOnlyExplicitAIHandlers
IReadOnlyDictionary IReadOnlyExplicitAIHandlers.MoveBasePower =>
MoveBasePower;
+ ///
+ /// Functions that indicate a moves score
+ ///
public FunctionHandlerDictionary GeneralMoveScore = [];
///
@@ -193,6 +245,7 @@ public class ExplicitAIHandlers : IReadOnlyExplicitAIHandlers
IReadOnlyDictionary IReadOnlyExplicitAIHandlers.ShouldSwitchFunctions =>
ShouldSwitchFunctions;
+ ///
public bool ShouldSwitch(IExplicitAI ai, IPokemon pokemon, IBattle battle, IReadOnlyList reserves)
{
var shouldSwitch = false;
@@ -203,6 +256,9 @@ public class ExplicitAIHandlers : IReadOnlyExplicitAIHandlers
return shouldSwitch;
}
+ ///
+ /// Functions that indicate whether we should not switch
+ ///
public FunctionHandlerDictionary ShouldNotSwitchFunctions = [];
///
@@ -210,6 +266,9 @@ public class ExplicitAIHandlers : IReadOnlyExplicitAIHandlers
IReadOnlyDictionary IReadOnlyExplicitAIHandlers.ShouldNotSwitchFunctions =>
ShouldNotSwitchFunctions;
+ ///
+ /// Functions to rank an ability
+ ///
public FunctionHandlerDictionary AbilityRanking = [];
///