using PkmnLib.Dynamic.Models; using PkmnLib.Static.Utils; namespace PkmnLib.Dynamic.AI.Explicit; public record struct MoveOption(AIMoveState Move, IBattle Battle, IPokemon? Target, uint EstimatedDamage = 0); public delegate bool AIBoolHandler(MoveOption option); public delegate void AIMoveBasePowerHandler(MoveOption option, ref int score); public delegate void AIScoreMoveHandler(MoveOption option, ref int score); public interface IReadOnlyExplicitAIHandlers { /// /// A list of checks to determine if a move will fail. /// IReadOnlyDictionary MoveFailureCheck { get; } /// /// Checks if a move will fail based on the provided function code and options. /// bool MoveWillFail(StringKey functionCode, MoveOption option); /// /// A list of checks to determine if a move will fail against a target. /// IReadOnlyDictionary MoveFailureAgainstTargetCheck { get; } /// /// Checks if a move will fail against a target based on the provided function code and options. /// bool MoveWillFailAgainstTarget(StringKey functionCode, MoveOption option); /// /// A list of handlers to apply scores for move effects. /// IReadOnlyDictionary MoveEffectScore { get; } /// /// Applies the score for a move effect based on the provided name and options. /// void ApplyMoveEffectScore(StringKey name, MoveOption option, ref int score); /// /// A list of handlers to apply scores for move effects against a target. /// IReadOnlyDictionary MoveEffectAgainstTargetScore { get; } /// /// Applies the score for a move effect against a target based on the provided name and options. /// void ApplyMoveEffectAgainstTargetScore(StringKey name, MoveOption option, ref int score); /// /// A list of handlers to determine the base power of a move. /// IReadOnlyDictionary MoveBasePower { get; } /// /// Applies the base power for a move based on the provided name and options. /// void GetBasePower(StringKey name, MoveOption option, ref int power); /// /// A list of handlers to apply scores for general move effectiveness. /// IReadOnlyDictionary GeneralMoveScore { get; } /// /// Applies the score for a general move based on the provided option. /// /// /// /// void ApplyGenerateMoveScoreModifiers(MoveOption option, ref int score); /// /// A list of handlers to apply scores for general move effectiveness against a target. /// IReadOnlyDictionary GeneralMoveAgainstTargetScore { get; } /// /// Applies the score for a general move against a target based on the provided option. /// void ApplyGenerateMoveAgainstTargetScoreModifiers(MoveOption option, ref int score); IReadOnlyDictionary ShouldSwitch { get; } IReadOnlyDictionary ShouldNotSwitch { get; } IReadOnlyDictionary AbilityRanking { get; } } public class ExplicitAIHandlers : IReadOnlyExplicitAIHandlers { /// IReadOnlyDictionary IReadOnlyExplicitAIHandlers.MoveFailureCheck => MoveFailureCheck; public FunctionHandlerDictionary MoveFailureCheck { get; } = new(); /// public bool MoveWillFail(StringKey functionCode, MoveOption option) => MoveFailureCheck.TryGetValue(functionCode, out var handler) && handler(option); public FunctionHandlerDictionary MoveFailureAgainstTargetCheck { get; } = new(); /// IReadOnlyDictionary IReadOnlyExplicitAIHandlers.MoveFailureAgainstTargetCheck => MoveFailureAgainstTargetCheck; /// public bool MoveWillFailAgainstTarget(StringKey functionCode, MoveOption option) => MoveFailureAgainstTargetCheck.TryGetValue(functionCode, out var handler) && handler(option); public FunctionHandlerDictionary MoveEffectScore { get; } = []; /// IReadOnlyDictionary IReadOnlyExplicitAIHandlers.MoveEffectScore => MoveEffectScore; public FunctionHandlerDictionary MoveEffectAgainstTargetScore = []; /// public void ApplyMoveEffectScore(StringKey name, MoveOption option, ref int score) { if (MoveEffectScore.TryGetValue(name, out var handler)) handler(option, ref score); } /// IReadOnlyDictionary IReadOnlyExplicitAIHandlers.MoveEffectAgainstTargetScore => MoveEffectAgainstTargetScore; public FunctionHandlerDictionary MoveBasePower = []; /// public void ApplyMoveEffectAgainstTargetScore(StringKey name, MoveOption option, ref int score) { if (MoveEffectAgainstTargetScore.TryGetValue(name, out var handler)) handler(option, ref score); } /// IReadOnlyDictionary IReadOnlyExplicitAIHandlers.MoveBasePower => MoveBasePower; public FunctionHandlerDictionary GeneralMoveScore = []; /// public void GetBasePower(StringKey name, MoveOption option, ref int power) { if (MoveBasePower.TryGetValue(name, out var handler)) handler(option, ref power); } /// IReadOnlyDictionary IReadOnlyExplicitAIHandlers.GeneralMoveScore => GeneralMoveScore; public FunctionHandlerDictionary GeneralMoveAgainstTargetScore = []; /// public void ApplyGenerateMoveScoreModifiers(MoveOption option, ref int score) { foreach (var (_, handler) in GeneralMoveScore) { handler(option, ref score); } } /// IReadOnlyDictionary IReadOnlyExplicitAIHandlers.GeneralMoveAgainstTargetScore => GeneralMoveAgainstTargetScore; public FunctionHandlerDictionary ShouldSwitch = []; /// public void ApplyGenerateMoveAgainstTargetScoreModifiers(MoveOption option, ref int score) { foreach (var (_, handler) in GeneralMoveAgainstTargetScore) { handler(option, ref score); } } /// IReadOnlyDictionary IReadOnlyExplicitAIHandlers.ShouldSwitch => ShouldSwitch; public FunctionHandlerDictionary ShouldNotSwitch = []; /// IReadOnlyDictionary IReadOnlyExplicitAIHandlers.ShouldNotSwitch => ShouldNotSwitch; public FunctionHandlerDictionary AbilityRanking = []; /// IReadOnlyDictionary IReadOnlyExplicitAIHandlers.AbilityRanking => AbilityRanking; }