Fix doubles switch looping (#9167)
Some checks are pending
CI / build (push) Waiting to run
CI / docs_validate (push) Waiting to run
CI / allcontributors (push) Waiting to run

This commit is contained in:
Pawkkie 2026-02-09 13:47:35 -05:00 committed by GitHub
parent b7c400ea9c
commit e2c5ce3d8e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 27 additions and 5 deletions

View File

@ -471,7 +471,7 @@ static bool32 ShouldSwitchIfAllMovesBad(enum BattlerId battler)
ctx.holdEffectDef = gAiLogicData->holdEffects[ctx.battlerDef];
// Switch if no moves affect opponents
if (HasTwoOpponents(battler))
if (IsDoubleBattle())
{
enum BattlerId opposingPartner = BATTLE_PARTNER(opposingBattler);
for (u32 moveIndex = 0; moveIndex < MAX_MON_MOVES; moveIndex++)
@ -998,7 +998,7 @@ static bool32 CanUseSuperEffectiveMoveAgainstOpponents(enum BattlerId battler)
if (CanUseSuperEffectiveMoveAgainstOpponent(battler, opposingBattler))
return TRUE;
if (HasTwoOpponents(battler) && CanUseSuperEffectiveMoveAgainstOpponent(battler, BATTLE_PARTNER(BATTLE_OPPOSITE(battler))))
if (IsDoubleBattle() && CanUseSuperEffectiveMoveAgainstOpponent(battler, BATTLE_PARTNER(BATTLE_OPPOSITE(battler))))
return TRUE;
return FALSE;
@ -1159,7 +1159,7 @@ static bool32 ShouldSwitchIfBadChoiceLock(enum BattlerId battler)
u32 moveIndex = GetMoveIndex(battler, choicedMove);
if (HasTwoOpponents(battler))
if (IsDoubleBattle())
{
enum BattlerId opposingPartner = BATTLE_PARTNER(opposingBattler);
if (IsHoldEffectChoice(ctx.holdEffectAtk) && IsBattlerItemEnabled(battler))
@ -1359,7 +1359,7 @@ bool32 ShouldSwitchIfAllScoresBad(enum BattlerId battler)
for (u32 moveIndex = 0; moveIndex < MAX_MON_MOVES; moveIndex++)
{
if (HasTwoOpponents(battler))
if (IsDoubleBattle())
{
u32 score1 = gAiBattleData->finalScore[battler][opposingBattler][moveIndex];
u32 score2 = gAiBattleData->finalScore[battler][BATTLE_PARTNER(opposingBattler)][moveIndex];
@ -1398,7 +1398,7 @@ bool32 ShouldStayInToUseMove(enum BattlerId battler)
continue;
if (gAiBattleData->finalScore[battler][opposingBattler][moveIndex] > AI_GOOD_SCORE_THRESHOLD
|| (HasTwoOpponents(battler) && gAiBattleData->finalScore[battler][BATTLE_PARTNER(opposingBattler)][moveIndex] > AI_GOOD_SCORE_THRESHOLD))
|| (IsDoubleBattle() && gAiBattleData->finalScore[battler][BATTLE_PARTNER(opposingBattler)][moveIndex] > AI_GOOD_SCORE_THRESHOLD))
return TRUE;
}
}

View File

@ -2175,3 +2175,25 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_RANDOMIZE_SWITCHIN: AI will consider all mons tha
TURN { MOVE(player, MOVE_WATER_GUN); EXPECT_MOVE(opponent, MOVE_U_TURN); EXPECT_SEND_OUT(opponent, 2); }
}
}
AI_MULTI_BATTLE_TEST("AI will not switch out if the opposite battler is absent and its moves can still affect the other opponent")
{
GIVEN {
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
MULTI_PLAYER(SPECIES_WOBBUFFET) { HP(41); Speed(1); }
MULTI_PARTNER(SPECIES_DRAKLOAK) { HP(41); MaxHP(100); Speed(4); Item(ITEM_LIFE_ORB); Moves(MOVE_DRAGON_RAGE, MOVE_SHADOW_BALL); }
MULTI_PARTNER(SPECIES_DRAGAPULT) { Speed(4); Moves(MOVE_SHADOW_BALL); }
MULTI_OPPONENT_A(SPECIES_CYCLIZAR) { HP(41); MaxHP(100); Speed(3); Item(ITEM_LIFE_ORB); Moves(MOVE_BODY_SLAM, MOVE_DRAGON_RAGE); }
MULTI_OPPONENT_A(SPECIES_DRAMPA) { Speed(3); Moves(MOVE_BODY_SLAM); }
MULTI_OPPONENT_B(SPECIES_WYNAUT) { Speed(2); HP(41); }
} WHEN {
TURN {
EXPECT_MOVE(opponentLeft, MOVE_BODY_SLAM, target: playerLeft);
EXPECT_MOVE(playerRight, MOVE_SHADOW_BALL, target: opponentRight);
}
TURN {
EXPECT_MOVE(opponentLeft, MOVE_DRAGON_RAGE, target: playerRight);
EXPECT_MOVE(playerRight, MOVE_DRAGON_RAGE, target: opponentLeft);
}
}
}