ShouldSwitchIfGameStatePrompt Tests (#5462)
* Weird tests plz help <3 * better RNG tag names? * DATA.trial for data to reset between trials * Fix Wonder Guard test * Unused errors * Finish new tests * Split fix into its own PR * Spacing * Rename RNG_AI_SWITCH_TOXICD * Forgot to save file lol --------- Co-authored-by: Martin Griffin <martinrgriffin@gmail.com>
This commit is contained in:
parent
d7c5bfee68
commit
464c90a862
@ -163,6 +163,10 @@ enum RandomTag
|
||||
RNG_AI_ABILITY,
|
||||
RNG_AI_SWITCH_HASBADODDS,
|
||||
RNG_AI_SWITCH_WONDER_GUARD,
|
||||
RNG_AI_SWITCH_BADLY_POISONED,
|
||||
RNG_AI_SWITCH_CURSED,
|
||||
RNG_AI_SWITCH_NIGHTMARE,
|
||||
RNG_AI_SWITCH_SEEDED,
|
||||
RNG_SHELL_SIDE_ARM,
|
||||
};
|
||||
|
||||
|
||||
@ -180,7 +180,7 @@ static bool32 HasBadOdds(u32 battler, bool32 emitResult)
|
||||
&& gBattleMons[battler].hp >= gBattleMons[battler].maxHP / 4)))
|
||||
{
|
||||
// 50% chance to stay in regardless
|
||||
if (!RandomPercentage(RNG_AI_SWITCH_HASBADODDS, 50))
|
||||
if (RandomPercentage(RNG_AI_SWITCH_HASBADODDS, 50))
|
||||
return FALSE;
|
||||
|
||||
// Switch mon out
|
||||
@ -203,7 +203,7 @@ static bool32 HasBadOdds(u32 battler, bool32 emitResult)
|
||||
return FALSE;
|
||||
|
||||
// 50% chance to stay in regardless
|
||||
if (!RandomPercentage(RNG_AI_SWITCH_HASBADODDS, 50))
|
||||
if (RandomPercentage(RNG_AI_SWITCH_HASBADODDS, 50))
|
||||
return FALSE;
|
||||
|
||||
// Switch mon out
|
||||
@ -462,16 +462,12 @@ static bool32 ShouldSwitchIfGameStatePrompt(u32 battler, bool32 emitResult)
|
||||
u16 holdEffect = AI_DATA->holdEffects[battler];
|
||||
u8 opposingPosition = BATTLE_OPPOSITE(GetBattlerPosition(battler));
|
||||
u8 opposingBattler = GetBattlerAtPosition(opposingPosition);
|
||||
s32 moduloChance = 4; //25% Chance Default
|
||||
s32 chanceReducer = 1; //No Reduce default. Increase to reduce
|
||||
bool32 hasStatRaised = AnyStatIsRaised(battler);
|
||||
s32 firstId;
|
||||
s32 lastId;
|
||||
s32 i;
|
||||
struct Pokemon *party;
|
||||
|
||||
if (AnyStatIsRaised(battler))
|
||||
chanceReducer = 5; // Reduce switchout probability by factor of 5 if setup
|
||||
|
||||
//Perish Song
|
||||
if (gStatuses3[battler] & STATUS3_PERISH_SONG
|
||||
&& gDisableStructs[battler].perishSongTimer == 0
|
||||
@ -567,28 +563,24 @@ static bool32 ShouldSwitchIfGameStatePrompt(u32 battler, bool32 emitResult)
|
||||
&& !AiExpectsToFaintPlayer(battler))
|
||||
{
|
||||
//Toxic
|
||||
moduloChance = 2; //50%
|
||||
if (((gBattleMons[battler].status1 & STATUS1_TOXIC_COUNTER) >= STATUS1_TOXIC_TURN(2))
|
||||
&& gBattleMons[battler].hp >= (gBattleMons[battler].maxHP / 3)
|
||||
&& (Random() % (moduloChance*chanceReducer)) == 0)
|
||||
&& (hasStatRaised ? RandomPercentage(RNG_AI_SWITCH_BADLY_POISONED, 20) : RandomPercentage(RNG_AI_SWITCH_BADLY_POISONED, 50)))
|
||||
switchMon = TRUE;
|
||||
|
||||
//Cursed
|
||||
moduloChance = 2; //50%
|
||||
if (gBattleMons[battler].status2 & STATUS2_CURSED
|
||||
&& (Random() % (moduloChance*chanceReducer)) == 0)
|
||||
&& (hasStatRaised ? RandomPercentage(RNG_AI_SWITCH_CURSED, 20) : RandomPercentage(RNG_AI_SWITCH_CURSED, 50)))
|
||||
switchMon = TRUE;
|
||||
|
||||
//Nightmare
|
||||
moduloChance = 3; //33.3%
|
||||
if (gBattleMons[battler].status2 & STATUS2_NIGHTMARE
|
||||
&& (Random() % (moduloChance*chanceReducer)) == 0)
|
||||
&& (hasStatRaised ? RandomPercentage(RNG_AI_SWITCH_NIGHTMARE, 15) : RandomPercentage(RNG_AI_SWITCH_NIGHTMARE, 33)))
|
||||
switchMon = TRUE;
|
||||
|
||||
//Leech Seed
|
||||
moduloChance = 4; //25%
|
||||
if (gStatuses3[battler] & STATUS3_LEECHSEED
|
||||
&& (Random() % (moduloChance*chanceReducer)) == 0)
|
||||
&& (hasStatRaised ? RandomPercentage(RNG_AI_SWITCH_SEEDED, 10) : RandomPercentage(RNG_AI_SWITCH_SEEDED, 25)))
|
||||
switchMon = TRUE;
|
||||
}
|
||||
|
||||
@ -606,7 +598,7 @@ static bool32 ShouldSwitchIfGameStatePrompt(u32 battler, bool32 emitResult)
|
||||
if (FindMonThatAbsorbsOpponentsMove(battler, FALSE)) // Switch if absorber found. Note: FindMonThatAbsorbsOpponentsMove already provides id of the mon to switch into to gBattleStruct->AI_monToSwitchIntoId.
|
||||
switchMon = TRUE, monIdChosen = TRUE;
|
||||
if (!AI_OpponentCanFaintAiWithMod(battler, 0)
|
||||
&& AnyStatIsRaised(battler))
|
||||
&& hasStatRaised)
|
||||
switchMon = FALSE;
|
||||
if (AiExpectsToFaintPlayer(battler)
|
||||
&& AI_IsSlower(battler, opposingBattler, 0)
|
||||
|
||||
@ -486,3 +486,65 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if it can't d
|
||||
TURN { MOVE(player, MOVE_TACKLE) ; EXPECT_SWITCH(opponent, 1); }
|
||||
}
|
||||
}
|
||||
|
||||
AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if it has been Toxic'd for at least two turns 50% of the time with more than 1/3 HP remaining")
|
||||
{
|
||||
PASSES_RANDOMLY(50, 100, RNG_AI_SWITCH_BADLY_POISONED);
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_TOXIC].effect == EFFECT_TOXIC);
|
||||
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_SWITCHING);
|
||||
PLAYER(SPECIES_ZIGZAGOON) { Moves(MOVE_TACKLE, MOVE_CELEBRATE, MOVE_TOXIC); }
|
||||
OPPONENT(SPECIES_ZIGZAGOON) { Moves(MOVE_TACKLE); }
|
||||
OPPONENT(SPECIES_ZIGZAGOON) { Moves(MOVE_TACKLE); }
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_TOXIC); EXPECT_MOVE(opponent, MOVE_TACKLE); }
|
||||
TURN { MOVE(player, MOVE_TACKLE); EXPECT_MOVE(opponent, MOVE_TACKLE); }
|
||||
TURN { MOVE(player, MOVE_TACKLE); EXPECT_SWITCH(opponent, 1); }
|
||||
}
|
||||
}
|
||||
|
||||
AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if it has been Curse'd 50% of the time")
|
||||
{
|
||||
PASSES_RANDOMLY(50, 100, RNG_AI_SWITCH_CURSED);
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_CURSE].effect == EFFECT_CURSE);
|
||||
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_SWITCHING);
|
||||
PLAYER(SPECIES_DUSCLOPS) { Moves(MOVE_FIRE_PUNCH, MOVE_CURSE); }
|
||||
PLAYER(SPECIES_MILOTIC) { Moves(MOVE_WATER_GUN); }
|
||||
OPPONENT(SPECIES_DUSCLOPS) { Moves(MOVE_SHADOW_BALL); }
|
||||
OPPONENT(SPECIES_DUSCLOPS) { Moves(MOVE_SHADOW_BALL); }
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_CURSE) ; EXPECT_MOVE(opponent, MOVE_SHADOW_BALL); }
|
||||
TURN { MOVE(player, MOVE_FIRE_PUNCH); EXPECT_SWITCH(opponent, 1); }
|
||||
}
|
||||
}
|
||||
|
||||
AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if it has been Nightmare'd 33% of the time")
|
||||
{
|
||||
PASSES_RANDOMLY(33, 100, RNG_AI_SWITCH_NIGHTMARE);
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_NIGHTMARE].effect == EFFECT_NIGHTMARE);
|
||||
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_SWITCHING);
|
||||
PLAYER(SPECIES_GENGAR) { Moves(MOVE_NIGHTMARE); }
|
||||
OPPONENT(SPECIES_DUSCLOPS) { Moves(MOVE_SHADOW_BALL); Status1(STATUS1_SLEEP); }
|
||||
OPPONENT(SPECIES_DUSCLOPS) { Moves(MOVE_SHADOW_BALL); }
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_NIGHTMARE) ; EXPECT_MOVE(opponent, MOVE_SHADOW_BALL); }
|
||||
TURN { MOVE(player, MOVE_NIGHTMARE) ; EXPECT_SWITCH(opponent, 1); }
|
||||
}
|
||||
}
|
||||
|
||||
AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if it has been Leech Seed'd 25% of the time")
|
||||
{
|
||||
PASSES_RANDOMLY(25, 100, RNG_AI_SWITCH_SEEDED);
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_LEECH_SEED].effect == EFFECT_LEECH_SEED);
|
||||
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_SWITCHING);
|
||||
PLAYER(SPECIES_WHIMSICOTT) { Moves(MOVE_LEECH_SEED); }
|
||||
OPPONENT(SPECIES_ZIGZAGOON) { Moves(MOVE_TACKLE); }
|
||||
OPPONENT(SPECIES_ZIGZAGOON) { Moves(MOVE_TACKLE); }
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_LEECH_SEED) ; EXPECT_MOVE(opponent, MOVE_TACKLE); }
|
||||
TURN { MOVE(player, MOVE_LEECH_SEED); EXPECT_SWITCH(opponent, 1); }
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user