From 6500f4653f1e1ec349d530c3f04965ab20f63a4e Mon Sep 17 00:00:00 2001 From: Pawkkie <61265402+Pawkkie@users.noreply.github.com> Date: Fri, 7 Mar 2025 05:44:59 -0500 Subject: [PATCH] Switch AI will factor in player's choice lock when determining hits to KO (#6343) --- src/battle_ai_switch_items.c | 7 +++++++ test/battle/ai/ai_switching.c | 17 +++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/battle_ai_switch_items.c b/src/battle_ai_switch_items.c index ef8f45fb17..0c3b31ed59 100644 --- a/src/battle_ai_switch_items.c +++ b/src/battle_ai_switch_items.c @@ -249,6 +249,11 @@ static bool32 ShouldSwitchIfHasBadOdds(u32 battler) if (playerMove != MOVE_NONE && !IsBattleMoveStatus(playerMove) && GetMoveEffect(playerMove) != EFFECT_FOCUS_PUNCH) { damageTaken = AI_CalcDamage(playerMove, opposingBattler, battler, &effectiveness, FALSE, weather, DMG_ROLL_HIGHEST).expected; + if (playerMove == gBattleStruct->choicedMove[opposingBattler]) // If player is choiced, only care about the choice locked move + { + return maxDamageTaken = damageTaken; + break; + } if (damageTaken > maxDamageTaken) maxDamageTaken = damageTaken; } @@ -1818,6 +1823,8 @@ static s32 GetMaxDamagePlayerCouldDealToSwitchin(u32 battler, u32 opposingBattle if (playerMove != MOVE_NONE && !IsBattleMoveStatus(playerMove) && GetMoveEffect(playerMove) != EFFECT_FOCUS_PUNCH) { damageTaken = AI_CalcPartyMonDamage(playerMove, opposingBattler, battler, battleMon, FALSE, DMG_ROLL_HIGHEST); + if (playerMove == gBattleStruct->choicedMove[opposingBattler]) // If player is choiced, only care about the choice locked move + return damageTaken; if (damageTaken > maxDamageTaken) maxDamageTaken = damageTaken; } diff --git a/test/battle/ai/ai_switching.c b/test/battle/ai/ai_switching.c index 367afbc0f1..e41eba0a4c 100644 --- a/test/battle/ai/ai_switching.c +++ b/test/battle/ai/ai_switching.c @@ -1085,3 +1085,20 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI won't switch in absorbing mon TURN { MOVE(player, MOVE_CLOSE_COMBAT); EXPECT_MOVE(opponent, MOVE_DRACO_METEOR); } } } + +AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_MON_CHOICES: AI will consider choice-locked player when determining which mon to send out") +{ + u32 item; + PARAMETRIZE { item = ITEM_NONE; } + PARAMETRIZE { item = ITEM_CHOICE_BAND; } + GIVEN { + ASSUME(gItemsInfo[ITEM_CHOICE_BAND].holdEffect == HOLD_EFFECT_CHOICE_BAND); + AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY | AI_FLAG_SMART_SWITCHING | AI_FLAG_SMART_MON_CHOICES | AI_FLAG_OMNISCIENT); + PLAYER(SPECIES_JOLTEON) { Speed(5); Moves(MOVE_EARTHQUAKE, MOVE_THUNDERBOLT); Item(item); } + OPPONENT(SPECIES_WOBBUFFET) { Speed(4); HP(1); Moves(MOVE_TACKLE); } + OPPONENT(SPECIES_MACHAMP) { Speed(4); Moves(MOVE_REVENGE); } + OPPONENT(SPECIES_GYARADOS) { Speed(4); Moves(MOVE_EARTHQUAKE); } + } WHEN { + TURN { MOVE(player, MOVE_EARTHQUAKE); EXPECT_MOVE(opponent, MOVE_TACKLE); item == ITEM_NONE ? EXPECT_SEND_OUT(opponent, 1) : EXPECT_SEND_OUT(opponent, 2); } + } +}