diff --git a/src/battle_ai_switch_items.c b/src/battle_ai_switch_items.c index 66bea62206..6feff721c4 100644 --- a/src/battle_ai_switch_items.c +++ b/src/battle_ai_switch_items.c @@ -1535,7 +1535,7 @@ static u32 GetSwitchinHitsToKO(s32 damageTaken, u32 battler) s32 currentHP = startingHP; // No damage being dealt - if (damageTaken + statusDamage + recurringDamage < recurringHealing) + if ((damageTaken + statusDamage + recurringDamage < recurringHealing) || damageTaken + statusDamage + recurringDamage == 0) return startingHP; // Mon fainted to hazards diff --git a/test/battle/ai.c b/test/battle/ai.c index c8a64faceb..0597925356 100644 --- a/test/battle/ai.c +++ b/test/battle/ai.c @@ -545,6 +545,22 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_MON_CHOICES: Number of hits to KO calculati } } +AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_MON_CHOICES: Number of hits to KO calculation checks whether incoming damage is zero to avoid an infinite loop") +{ + GIVEN { + 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); + PLAYER(SPECIES_BULBASAUR) { Level(5); Moves(MOVE_SWORDS_DANCE, MOVE_WHIRLWIND, MOVE_SAND_ATTACK, MOVE_TAIL_WHIP); } + // Scenario courtesy of Duke, who triggered the bug in the first place + OPPONENT(SPECIES_GEODUDE) { Level(100); Moves(MOVE_TACKLE); } + OPPONENT(SPECIES_GEODUDE) { Level(100); Moves(MOVE_TACKLE); } + OPPONENT(SPECIES_NOSEPASS) { Level(100); Moves(MOVE_TACKLE); } + } WHEN { + TURN { MOVE(player, MOVE_SWORDS_DANCE); EXPECT_MOVES(opponent, MOVE_TACKLE); } + } SCENE { + MESSAGE("Bulbasaur fainted!"); + } +} + AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_MON_CHOICES: AI will not switch in a Pokemon which is slower and gets 1HKOed after fainting") { bool32 alakazamFirst;