Implement basic AI check for whether a move would fail
This commit is contained in:
parent
a3a4993407
commit
364d4b9080
@ -6,3 +6,8 @@ namespace PkmnLib.Plugin.Gen7.AI;
|
||||
public class AIMoveScoreFunctionAttribute : Attribute
|
||||
{
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Method), MeansImplicitUse]
|
||||
public class AIMoveFailureFunctionAttribute : Attribute
|
||||
{
|
||||
}
|
@ -20,18 +20,37 @@ public static class ExplicitAIFunctions
|
||||
|
||||
if (attribute.Category == ScriptCategory.Move)
|
||||
{
|
||||
// Check if the move type has a static function in the following format:
|
||||
// public static void AIMoveEffectScore(MoveOption option, ref int score);
|
||||
var method = type.GetMethods(BindingFlags.Public | BindingFlags.Static).FirstOrDefault(m =>
|
||||
m.GetCustomAttribute<AIMoveScoreFunctionAttribute>() != null && m.ReturnType == typeof(void) &&
|
||||
m.GetParameters().Length == 2 && m.GetParameters()[0].ParameterType == typeof(MoveOption) &&
|
||||
m.GetParameters()[1].ParameterType == typeof(int).MakeByRefType());
|
||||
if (method != null)
|
||||
var failureMethod = type.GetMethods(BindingFlags.Public | BindingFlags.Static).FirstOrDefault(m =>
|
||||
m.GetCustomAttribute<AIMoveFailureFunctionAttribute>() != null);
|
||||
if (failureMethod != null)
|
||||
{
|
||||
if (failureMethod.ReturnType != typeof(bool) || failureMethod.GetParameters().Length != 1 ||
|
||||
failureMethod.GetParameters()[0].ParameterType != typeof(MoveOption))
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"Method {failureMethod.Name} in {type.Name} must return bool and take a single MoveOption parameter.");
|
||||
}
|
||||
var optionParam = Expression.Parameter(typeof(MoveOption), "option");
|
||||
var functionExpression = Expression.Lambda<AIBoolHandler>(
|
||||
Expression.Call(null, failureMethod, optionParam), optionParam).Compile();
|
||||
handlers.MoveFailureCheck.Add(attribute.Name, functionExpression);
|
||||
}
|
||||
|
||||
var scoreMethod = type.GetMethods(BindingFlags.Public | BindingFlags.Static).FirstOrDefault(m =>
|
||||
m.GetCustomAttribute<AIMoveScoreFunctionAttribute>() != null);
|
||||
if (scoreMethod != null)
|
||||
{
|
||||
if (scoreMethod.ReturnType != typeof(void) || scoreMethod.GetParameters().Length != 2 ||
|
||||
scoreMethod.GetParameters()[0].ParameterType != typeof(MoveOption) ||
|
||||
scoreMethod.GetParameters()[1].ParameterType != typeof(int).MakeByRefType())
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"Method {scoreMethod.Name} in {type.Name} must return void and take a MoveOption and an int by reference parameter.");
|
||||
}
|
||||
var optionParam = Expression.Parameter(typeof(MoveOption), "option");
|
||||
var scoreParam = Expression.Parameter(typeof(int).MakeByRefType(), "score");
|
||||
var functionExpression = Expression.Lambda<AIScoreMoveHandler>(
|
||||
Expression.Call(null, method, optionParam, scoreParam), optionParam, scoreParam).Compile();
|
||||
Expression.Call(null, scoreMethod, optionParam, scoreParam), optionParam, scoreParam).Compile();
|
||||
handlers.MoveEffectScore.Add(attribute.Name, functionExpression);
|
||||
}
|
||||
}
|
||||
|
@ -35,6 +35,9 @@ public abstract class ChangeUserStats : Script, IScriptOnInitialize, IScriptOnSe
|
||||
move.User.ChangeStatBoost(_stat, _amount, true, false);
|
||||
}
|
||||
|
||||
protected static bool WouldMoveFail(MoveOption option, Statistic stat) =>
|
||||
option.Move.User.StatBoost.GetStatistic(stat) == StatBoostStatisticSet.MaxStatBoost;
|
||||
|
||||
protected static void GetMoveEffectScore(MoveOption option, Statistic stat, ref int score)
|
||||
{
|
||||
if (option.Move.Move.SecondaryEffect == null ||
|
||||
@ -56,6 +59,9 @@ public class ChangeUserAttack : ChangeUserStats
|
||||
{
|
||||
}
|
||||
|
||||
[AIMoveFailureFunction]
|
||||
public static bool AIMoveWillFail(MoveOption option) => WouldMoveFail(option, Statistic.Attack);
|
||||
|
||||
[AIMoveScoreFunction]
|
||||
public static void AIMoveEffectScore(MoveOption option, ref int score) =>
|
||||
GetMoveEffectScore(option, Statistic.Attack, ref score);
|
||||
@ -68,6 +74,9 @@ public class ChangeUserDefense : ChangeUserStats
|
||||
{
|
||||
}
|
||||
|
||||
[AIMoveFailureFunction]
|
||||
public static bool AIMoveWillFail(MoveOption option) => WouldMoveFail(option, Statistic.Defense);
|
||||
|
||||
[AIMoveScoreFunction]
|
||||
public static void AIMoveEffectScore(MoveOption option, ref int score) =>
|
||||
GetMoveEffectScore(option, Statistic.Defense, ref score);
|
||||
@ -80,6 +89,9 @@ public class ChangeUserSpecialAttack : ChangeUserStats
|
||||
{
|
||||
}
|
||||
|
||||
[AIMoveFailureFunction]
|
||||
public static bool AIMoveWillFail(MoveOption option) => WouldMoveFail(option, Statistic.SpecialAttack);
|
||||
|
||||
[AIMoveScoreFunction]
|
||||
public static void AIMoveEffectScore(MoveOption option, ref int score) =>
|
||||
GetMoveEffectScore(option, Statistic.SpecialAttack, ref score);
|
||||
@ -92,6 +104,9 @@ public class ChangeUserSpecialDefense : ChangeUserStats
|
||||
{
|
||||
}
|
||||
|
||||
[AIMoveFailureFunction]
|
||||
public static bool AIMoveWillFail(MoveOption option) => WouldMoveFail(option, Statistic.SpecialDefense);
|
||||
|
||||
[AIMoveScoreFunction]
|
||||
public static void AIMoveEffectScore(MoveOption option, ref int score) =>
|
||||
GetMoveEffectScore(option, Statistic.SpecialDefense, ref score);
|
||||
@ -104,6 +119,9 @@ public class ChangeUserSpeed : ChangeUserStats
|
||||
{
|
||||
}
|
||||
|
||||
[AIMoveFailureFunction]
|
||||
public static bool AIMoveWillFail(MoveOption option) => WouldMoveFail(option, Statistic.Speed);
|
||||
|
||||
[AIMoveScoreFunction]
|
||||
public static void AIMoveEffectScore(MoveOption option, ref int score) =>
|
||||
GetMoveEffectScore(option, Statistic.Speed, ref score);
|
||||
@ -116,6 +134,9 @@ public class ChangeUserAccuracy : ChangeUserStats
|
||||
{
|
||||
}
|
||||
|
||||
[AIMoveFailureFunction]
|
||||
public static bool AIMoveWillFail(MoveOption option) => WouldMoveFail(option, Statistic.Accuracy);
|
||||
|
||||
[AIMoveScoreFunction]
|
||||
public static void AIMoveEffectScore(MoveOption option, ref int score) =>
|
||||
GetMoveEffectScore(option, Statistic.Accuracy, ref score);
|
||||
@ -128,6 +149,9 @@ public class ChangeUserEvasion : ChangeUserStats
|
||||
{
|
||||
}
|
||||
|
||||
[AIMoveFailureFunction]
|
||||
public static bool AIMoveWillFail(MoveOption option) => WouldMoveFail(option, Statistic.Evasion);
|
||||
|
||||
[AIMoveScoreFunction]
|
||||
public static void AIMoveEffectScore(MoveOption option, ref int score) =>
|
||||
GetMoveEffectScore(option, Statistic.Evasion, ref score);
|
||||
|
Loading…
x
Reference in New Issue
Block a user