Improve AI's Sucker Punch handling (#7389)

This commit is contained in:
Pawkkie 2025-07-22 14:13:10 -04:00 committed by GitHub
parent 8e8813e593
commit c544fee140
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 20 additions and 5 deletions

View File

@ -58,6 +58,8 @@
#define BOOST_INTO_HAZE_CHANCE 0 // Chance the AI will use a stat boosting move if the player has used Haze
#define SHOULD_RECOVER_CHANCE 50 // Chance the AI will give recovery moves score increase if less than ENABLE_RECOVERY_THRESHOLD and in no immediate danger
#define ENABLE_RECOVERY_THRESHOLD 60 // HP percentage beneath which SHOULD_RECOVER_CHANCE is active
#define SUCKER_PUNCH_CHANCE 50 // Chance for the AI to not use Sucker Punch if the player has a status move
#define SUCKER_PUNCH_PREDICTION_CHANCE 50 // Additional chance for the AI to not use Sucker Punch if actively predicting a status move if SUCKER_PUNCH_CHANCE fails
// AI damage calc considerations
#define RISKY_AI_CRIT_STAGE_THRESHOLD 2 // Stat stages at which Risky will assume it gets a crit

View File

@ -193,6 +193,7 @@ enum RandomTag
RNG_AI_CONSERVE_TERA,
RNG_AI_SWITCH_ALL_SCORES_BAD,
RNG_AI_PP_STALL_DISREGARD_MOVE,
RNG_AI_SUCKER_PUNCH,
RNG_SHELL_SIDE_ARM,
RNG_RANDOM_TARGET,
RNG_AI_PREDICT_ABILITY,

View File

@ -2745,11 +2745,10 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
ADJUST_SCORE(-10);
break;
case EFFECT_SUCKER_PUNCH:
if (predictedMove != MOVE_NONE)
{
if (IsBattleMoveStatus(predictedMove) || AI_IsSlower(battlerAtk, battlerDef, move)) // Opponent going first
ADJUST_SCORE(-10);
}
if ((HasMoveWithCategory(battlerDef, DAMAGE_CATEGORY_STATUS) && RandomPercentage(RNG_AI_SUCKER_PUNCH, SUCKER_PUNCH_CHANCE)) // Player has a status move
|| (IsBattleMoveStatus(predictedMove) && RandomPercentage(RNG_AI_SUCKER_PUNCH, SUCKER_PUNCH_PREDICTION_CHANCE) && (gAiThinkingStruct->aiFlags[battlerAtk] & AI_FLAG_PREDICT_MOVE)) // AI actively predicting incoming status move
|| AI_IsSlower(battlerAtk, battlerDef, move)) // Opponent going first
ADJUST_SCORE(-10);
break;
case EFFECT_TAILWIND:
if (gSideStatuses[GetBattlerSide(battlerAtk)] & SIDE_STATUS_TAILWIND

View File

@ -675,6 +675,19 @@ AI_SINGLE_BATTLE_TEST("AI won't use Sucker Punch if it expects a move of the sam
}
}
AI_SINGLE_BATTLE_TEST("AI won't use Sucker Punch if it expects a status move a percentage of the time")
{
PASSES_RANDOMLY(SUCKER_PUNCH_CHANCE, 100, RNG_AI_SUCKER_PUNCH);
GIVEN {
ASSUME(GetMoveEffect(MOVE_SUCKER_PUNCH) == EFFECT_SUCKER_PUNCH);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_OMNISCIENT);
PLAYER(SPECIES_ZIGZAGOON) { Moves(MOVE_GROWL, MOVE_SCRATCH); }
OPPONENT(SPECIES_ZIGZAGOON) { Moves(MOVE_SUCKER_PUNCH, MOVE_SCRATCH); }
} WHEN {
TURN { MOVE(player, MOVE_SCRATCH); EXPECT_MOVE(opponent, MOVE_SUCKER_PUNCH); }
}
}
AI_SINGLE_BATTLE_TEST("AI won't use thawing moves if target is frozen unless it is super effective or it has no other options")
{
u32 aiFlags = 0; u32 status = 0; u32 aiMove = 0;