diff --git a/src/battle_ai_switch_items.c b/src/battle_ai_switch_items.c index 2f7f74a726..74d62e6673 100644 --- a/src/battle_ai_switch_items.c +++ b/src/battle_ai_switch_items.c @@ -22,7 +22,7 @@ #include "constants/moves.h" // this file's functions -static bool32 HasSuperEffectiveMoveAgainstOpponents(u32 battler, bool32 noRng); +static bool32 CanUseSuperEffectiveMoveAgainstOpponents(u32 battler); static bool32 FindMonWithFlagsAndSuperEffective(u32 battler, u16 flags, u32 moduloPercent); static bool32 ShouldUseItem(u32 battler); static bool32 AiExpectsToFaintPlayer(u32 battler); @@ -463,7 +463,7 @@ static bool32 FindMonThatAbsorbsOpponentsMove(u32 battler) return FALSE; if (gBattleStruct->prevTurnSpecies[battler] != gBattleMons[battler].species && !(gAiThinkingStruct->aiFlags[battler] & AI_FLAG_PREDICT_MOVE)) // AI mon has changed, player's behaviour no longer reliable; override this if using AI_FLAG_PREDICT_MOVE return FALSE; - if (HasSuperEffectiveMoveAgainstOpponents(battler, TRUE) && (RandomPercentage(RNG_AI_SWITCH_ABSORBING_STAY_IN, STAY_IN_ABSORBING_PERCENTAGE) || gAiLogicData->aiPredictionInProgress)) + if (CanUseSuperEffectiveMoveAgainstOpponents(battler) && (RandomPercentage(RNG_AI_SWITCH_ABSORBING_STAY_IN, STAY_IN_ABSORBING_PERCENTAGE) || gAiLogicData->aiPredictionInProgress)) return FALSE; if (AreStatsRaised(battler)) return FALSE; @@ -785,7 +785,7 @@ static bool32 ShouldSwitchIfAbilityBenefit(u32 battler) return SetSwitchinAndSwitch(battler, PARTY_SIZE); } -static bool32 HasSuperEffectiveMoveAgainstOpponents(u32 battler, bool32 noRng) +static bool32 CanUseSuperEffectiveMoveAgainstOpponents(u32 battler) { s32 i; u16 move; @@ -798,15 +798,12 @@ static bool32 HasSuperEffectiveMoveAgainstOpponents(u32 battler, bool32 noRng) for (i = 0; i < MAX_MON_MOVES; i++) { move = gBattleMons[battler].moves[i]; - if (move == MOVE_NONE) + if (move == MOVE_NONE || AI_DoesChoiceItemBlockMove(battler, move)) continue; if (AI_GetMoveEffectiveness(move, battler, opposingBattler) >= UQ_4_12(2.0)) { - if (noRng) - return TRUE; - if (Random() % 10 != 0) - return TRUE; + return TRUE; } } } @@ -820,15 +817,12 @@ static bool32 HasSuperEffectiveMoveAgainstOpponents(u32 battler, bool32 noRng) for (i = 0; i < MAX_MON_MOVES; i++) { move = gBattleMons[battler].moves[i]; - if (move == MOVE_NONE) + if (move == MOVE_NONE || AI_DoesChoiceItemBlockMove(battler, move)) continue; if (AI_GetMoveEffectiveness(move, battler, opposingBattler) >= UQ_4_12(2.0)) { - if (noRng) - return TRUE; - if (Random() % 10 != 0) - return TRUE; + return TRUE; } } } @@ -1174,7 +1168,7 @@ bool32 ShouldSwitch(u32 battler) // We don't use FindMonWithFlagsAndSuperEffective with AI_FLAG_SMART_SWITCHING, so we can bail early. if (gAiThinkingStruct->aiFlags[GetThinkingBattler(battler)] & AI_FLAG_SMART_SWITCHING) return FALSE; - if (HasSuperEffectiveMoveAgainstOpponents(battler, FALSE)) + if (CanUseSuperEffectiveMoveAgainstOpponents(battler)) return FALSE; if (AreStatsRaised(battler)) return FALSE; diff --git a/test/battle/ai/ai_choice.c b/test/battle/ai/ai_choice.c index ae67b9c06a..fc3706ca29 100644 --- a/test/battle/ai/ai_choice.c +++ b/test/battle/ai/ai_choice.c @@ -230,3 +230,23 @@ AI_SINGLE_BATTLE_TEST("Choiced Pokémon will only see choiced moves when conside TURN { MOVE(player, MOVE_CLOSE_COMBAT); EXPECT_SWITCH(opponent, 1); } } } + +AI_SINGLE_BATTLE_TEST("Choiced Pokémon will only see choiced moves when considering switching with FindMonThatAbsorbsMove") +{ + PASSES_RANDOMLY(SHOULD_SWITCH_ABSORBS_MOVE_PERCENTAGE, 100, RNG_AI_SWITCH_ABSORBING); + GIVEN { + ASSUME(gSpeciesInfo[SPECIES_SANDSHREW].types[0] == TYPE_GROUND); + ASSUME(GetMoveType(MOVE_SCRATCH) == TYPE_NORMAL); + ASSUME(GetMoveType(MOVE_THUNDERBOLT) == TYPE_ELECTRIC); + ASSUME(GetMoveType(MOVE_WATER_GUN) == TYPE_WATER); + AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_OMNISCIENT | AI_FLAG_SMART_SWITCHING | AI_FLAG_SMART_MON_CHOICES); + PLAYER(SPECIES_WOOPER) { Ability(ABILITY_WATER_ABSORB); Moves(MOVE_CELEBRATE); } + PLAYER(SPECIES_DWEBBLE) { Moves(MOVE_WATER_GUN); } + OPPONENT(SPECIES_MUDKIP) { Item(ITEM_CHOICE_SCARF); Moves(MOVE_SCRATCH, MOVE_WATER_GUN); } + OPPONENT(SPECIES_WOOPER) { Ability(ABILITY_WATER_ABSORB); Moves(MOVE_SCRATCH); } + } WHEN { + TURN { SWITCH(player, 1); EXPECT_MOVE(opponent, MOVE_SCRATCH); } + TURN { MOVE(player, MOVE_WATER_GUN); EXPECT_MOVE(opponent, MOVE_SCRATCH); } + TURN { MOVE(player, MOVE_WATER_GUN); EXPECT_SWITCH(opponent, 1); } + } +}