Improve "all moves bad" switching (#6453)
This commit is contained in:
parent
9a23f19575
commit
4c18e88282
@ -44,6 +44,9 @@
|
||||
#define SHOULD_SWITCH_REGENERATOR_PERCENTAGE 50
|
||||
#define SHOULD_SWITCH_REGENERATOR_STATS_RAISED_PERCENTAGE 20
|
||||
|
||||
// AI switchin considerations
|
||||
#define ALL_MOVES_BAD_STATUS_MOVES_BAD FALSE // If the AI has no moves that affect the target, ShouldSwitchIfAllMovesBad can prompt a switch. Enabling this config will ignore status moves that can affect the target when making this decision.
|
||||
|
||||
// AI held item-based move scoring
|
||||
#define LOW_ACCURACY_THRESHOLD 75 // Moves with accuracy equal OR below this value are considered low accuracy
|
||||
|
||||
|
||||
@ -331,6 +331,38 @@ static bool32 ShouldSwitchIfTruant(u32 battler)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static u32 FindMonWithMoveOfEffectiveness(u32 battler, u32 opposingBattler, uq4_12_t effectiveness)
|
||||
{
|
||||
u32 move, i, j;
|
||||
s32 firstId;
|
||||
s32 lastId; // + 1
|
||||
struct Pokemon *party = NULL;
|
||||
|
||||
// Get party information.
|
||||
GetAIPartyIndexes(battler, &firstId, &lastId);
|
||||
party = GetBattlerParty(battler);
|
||||
|
||||
// Find a Pokémon in the party that has a super effective move.
|
||||
for (i = firstId; i < lastId; i++)
|
||||
{
|
||||
if (!IsValidForBattle(&party[i]))
|
||||
continue;
|
||||
if (i == gBattlerPartyIndexes[battler])
|
||||
continue;
|
||||
if (IsAceMon(battler, i))
|
||||
continue;
|
||||
|
||||
for (j = 0; j < MAX_MON_MOVES; j++)
|
||||
{
|
||||
move = GetMonData(&party[i], MON_DATA_MOVE1 + j);
|
||||
if (move != MOVE_NONE && AI_GetMoveEffectiveness(move, battler, opposingBattler) >= effectiveness && gMovesInfo[move].power != 0)
|
||||
return SetSwitchinAndSwitch(battler, i);
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE; // There is not a single Pokémon in the party that has a move with this effectiveness threshold
|
||||
}
|
||||
|
||||
static bool32 ShouldSwitchIfAllMovesBad(u32 battler)
|
||||
{
|
||||
u32 moveIndex;
|
||||
@ -355,24 +387,27 @@ static bool32 ShouldSwitchIfAllMovesBad(u32 battler)
|
||||
for (moveIndex = 0; moveIndex < MAX_MON_MOVES; moveIndex++)
|
||||
{
|
||||
aiMove = gBattleMons[battler].moves[moveIndex];
|
||||
if (AI_GetMoveEffectiveness(aiMove, battler, opposingBattler) > UQ_4_12(0.0) && aiMove != MOVE_NONE)
|
||||
if (AI_GetMoveEffectiveness(aiMove, battler, opposingBattler) > UQ_4_12(0.0) && aiMove != MOVE_NONE
|
||||
&& (!ALL_MOVES_BAD_STATUS_MOVES_BAD || gMovesInfo[aiMove].power != 0)) // If using ALL_MOVES_BAD_STATUS_MOVES_BAD, then need power to be non-zero
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (RandomPercentage(RNG_AI_SWITCH_ALL_MOVES_BAD, GetSwitchChance(SHOULD_SWITCH_ALL_MOVES_BAD)))
|
||||
return SetSwitchinAndSwitch(battler, PARTY_SIZE);
|
||||
{
|
||||
if (AI_DATA->mostSuitableMonId[battler] == PARTY_SIZE) // No good candidate mons, find any one that can deal damage
|
||||
return FindMonWithMoveOfEffectiveness(battler, opposingBattler, UQ_4_12(1.0));
|
||||
else // Good candidate mon, send that in
|
||||
return SetSwitchinAndSwitch(battler, PARTY_SIZE);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static bool32 FindMonThatHitsWonderGuard(u32 battler)
|
||||
{
|
||||
u32 opposingBattler = GetOppositeBattler(battler);
|
||||
s32 i, j;
|
||||
s32 firstId;
|
||||
s32 lastId; // + 1
|
||||
struct Pokemon *party = NULL;
|
||||
u16 move;
|
||||
u32 i, move;
|
||||
|
||||
if (IsDoubleBattle())
|
||||
return FALSE;
|
||||
@ -391,33 +426,10 @@ static bool32 FindMonThatHitsWonderGuard(u32 battler)
|
||||
}
|
||||
}
|
||||
|
||||
// Get party information.
|
||||
GetAIPartyIndexes(battler, &firstId, &lastId);
|
||||
party = GetBattlerParty(battler);
|
||||
if (RandomPercentage(RNG_AI_SWITCH_WONDER_GUARD, GetSwitchChance(SHOULD_SWITCH_WONDER_GUARD)))
|
||||
return FindMonWithMoveOfEffectiveness(battler, opposingBattler, UQ_4_12(2.0));
|
||||
|
||||
// Find a Pokémon in the party that has a super effective move.
|
||||
for (i = firstId; i < lastId; i++)
|
||||
{
|
||||
if (!IsValidForBattle(&party[i]))
|
||||
continue;
|
||||
if (i == gBattlerPartyIndexes[battler])
|
||||
continue;
|
||||
if (IsAceMon(battler, i))
|
||||
continue;
|
||||
|
||||
for (j = 0; j < MAX_MON_MOVES; j++)
|
||||
{
|
||||
move = GetMonData(&party[i], MON_DATA_MOVE1 + j);
|
||||
if (move != MOVE_NONE)
|
||||
{
|
||||
// Found a mon
|
||||
if (AI_GetMoveEffectiveness(move, battler, opposingBattler) >= UQ_4_12(2.0) && RandomPercentage(RNG_AI_SWITCH_WONDER_GUARD, GetSwitchChance(SHOULD_SWITCH_WONDER_GUARD)))
|
||||
return SetSwitchinAndSwitch(battler, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE; // There is not a single Pokémon in the party that has a super effective move against a mon with Wonder Guard.
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static bool32 FindMonThatAbsorbsOpponentsMove(u32 battler)
|
||||
|
||||
@ -82,6 +82,22 @@ AI_SINGLE_BATTLE_TEST("AI will switch out if it has no move that affects the pla
|
||||
}
|
||||
}
|
||||
|
||||
AI_SINGLE_BATTLE_TEST("When AI switches out due to having no move that affects the player, AI will send in a mon that can hit the player, even if not ideal")
|
||||
{
|
||||
GIVEN {
|
||||
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_MON_CHOICES);
|
||||
PLAYER(SPECIES_GENGAR) { Moves(MOVE_SHADOW_BALL, MOVE_CELEBRATE); }
|
||||
OPPONENT(SPECIES_ABRA) { Moves(MOVE_TACKLE); }
|
||||
OPPONENT(SPECIES_ABRA) { Moves(MOVE_TACKLE); }
|
||||
OPPONENT(SPECIES_ABRA) { Level(5); Moves(MOVE_CONFUSION); }
|
||||
OPPONENT(SPECIES_ABRA) { Moves(MOVE_TACKLE); }
|
||||
OPPONENT(SPECIES_ABRA) { Moves(MOVE_TACKLE); }
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_SHADOW_BALL); EXPECT_SWITCH(opponent, 2); EXPECT_SEND_OUT(opponent, 4); }
|
||||
TURN { MOVE(player, MOVE_SHADOW_BALL); EXPECT_MOVE(opponent, MOVE_TACKLE); }
|
||||
}
|
||||
}
|
||||
|
||||
AI_DOUBLE_BATTLE_TEST("AI will not try to switch for the same pokemon for 2 spots in a double battle (Wonder Guard)")
|
||||
{
|
||||
PASSES_RANDOMLY(SHOULD_SWITCH_WONDER_GUARD_PERCENTAGE, 100, RNG_AI_SWITCH_WONDER_GUARD);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user