Fix AI_FLAG_DOUBLE_ACE_POKEMON sending duplicate Pokémon in doubles (#8279)

This commit is contained in:
moostoet 2025-11-18 19:33:49 +01:00 committed by GitHub
parent 9b16204705
commit 5e40456f45
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 84 additions and 5 deletions

View File

@ -2414,6 +2414,9 @@ u32 GetMostSuitableMonToSwitchInto(u32 battler, enum SwitchType switchType)
if (bestMonId != PARTY_SIZE)
return bestMonId;
if (aceMonId != PARTY_SIZE && aliveCount == 0)
return aceMonId;
bestMonId = GetBestMonTypeMatchup(party, firstId, lastId, invalidMons, battler, opposingBattler);
if (bestMonId != PARTY_SIZE)
return bestMonId;

View File

@ -512,13 +512,57 @@ static inline bool32 IsAcePokemon(u32 chosenMonId, u32 pokemonInBattle, u32 batt
&& CountAIAliveNonEggMonsExcept(PARTY_SIZE) != pokemonInBattle;
}
static inline bool32 IsDoubleAceSlot(u32 battler, u32 partyId)
{
u32 partyCountEnd;
if (!(gAiThinkingStruct->aiFlags[battler] & AI_FLAG_DOUBLE_ACE_POKEMON))
return FALSE;
partyCountEnd = CalculateEnemyPartyCountInSide(battler);
if (partyCountEnd == 0)
return FALSE;
if (partyId == partyCountEnd - 1)
return TRUE;
if (partyCountEnd > 1 && partyId == partyCountEnd - 2)
return TRUE;
return FALSE;
}
static inline bool32 IsDoubleAcePokemon(u32 chosenMonId, u32 pokemonInBattle, u32 battler)
{
return gAiThinkingStruct->aiFlags[battler] & AI_FLAG_DOUBLE_ACE_POKEMON
&& (chosenMonId == CalculateEnemyPartyCountInSide(battler) - 1)
&& (chosenMonId == CalculateEnemyPartyCountInSide(battler) - 2)
&& CountAIAliveNonEggMonsExcept(PARTY_SIZE) != pokemonInBattle
&& CountAIAliveNonEggMonsExcept(PARTY_SIZE-1) != pokemonInBattle;
s32 battler1, battler2, firstId, lastId;
s32 i;
if (!IsDoubleAceSlot(battler, chosenMonId))
return FALSE;
if (!IsDoubleBattle())
{
battler2 = battler1 = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
}
else
{
battler1 = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
battler2 = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT);
}
GetAIPartyIndexes(battler, &firstId, &lastId);
for (i = firstId; i < lastId; i++)
{
if (!IsValidForBattle(&gEnemyParty[i])
|| i == gBattlerPartyIndexes[battler1]
|| i == gBattlerPartyIndexes[battler2]
|| i == chosenMonId)
continue;
if (!IsAcePokemon(i, pokemonInBattle, battler) && !IsDoubleAceSlot(battler, i))
return TRUE;
}
return FALSE;
}
static void OpponentHandleChoosePokemon(u32 battler)

View File

@ -94,3 +94,35 @@ AI_DOUBLE_BATTLE_TEST("AI_FLAG_DOUBLE_ACE_POKEMON: Ace mons won't be switched in
TURN { EXPECT_SWITCH(opponentLeft, 2); }
}
}
AI_DOUBLE_BATTLE_TEST("AI_FLAG_DOUBLE_ACE_POKEMON: sends out Ace mons when no other options remain mid-battle")
{
GIVEN {
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_SMART_SWITCHING | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_MON_CHOICES | AI_FLAG_DOUBLE_ACE_POKEMON);
PLAYER(SPECIES_WOBBUFFET) { Level(50); Speed(200); Moves(MOVE_THUNDERBOLT, MOVE_CELEBRATE); SpAttack(200); }
PLAYER(SPECIES_WOBBUFFET) { Level(50); Speed(150); Moves(MOVE_THUNDERBOLT, MOVE_CELEBRATE); SpAttack(200); }
OPPONENT(SPECIES_ZIGZAGOON) { Level(5); HP(1); Speed(1); Moves(MOVE_SPLASH); }
OPPONENT(SPECIES_POOCHYENA) { Level(5); HP(1); Speed(1); Moves(MOVE_SPLASH); }
// Aces
OPPONENT(SPECIES_MIGHTYENA) { Level(50); Speed(10); Moves(MOVE_CRUNCH); }
OPPONENT(SPECIES_GENGAR) { Level(50); Speed(10); Moves(MOVE_SPLASH); }
} WHEN {
TURN {
MOVE(playerLeft, MOVE_THUNDERBOLT, target: opponentLeft);
MOVE(playerRight, MOVE_CELEBRATE);
EXPECT_MOVE(opponentLeft, MOVE_SPLASH);
EXPECT_MOVE(opponentRight, MOVE_SPLASH);
EXPECT_SEND_OUT(opponentLeft, 3);
}
TURN {
MOVE(playerLeft, MOVE_CELEBRATE);
MOVE(playerRight, MOVE_THUNDERBOLT, target: opponentRight);
EXPECT_MOVE(opponentLeft, MOVE_SPLASH);
EXPECT_MOVE(opponentRight, MOVE_SPLASH);
EXPECT_SEND_OUT(opponentRight, 2);
}
}
}