diff --git a/data/battle_anim_scripts.s b/data/battle_anim_scripts.s index 1d05258dcf..de752be59b 100644 --- a/data/battle_anim_scripts.s +++ b/data/battle_anim_scripts.s @@ -3361,6 +3361,7 @@ gBattleAnimMove_AquaJet:: visible ANIM_ATTACKER clearmonbg ANIM_DEF_PARTNER blendoff + setarg 7, 0x1000 end gBattleAnimMove_AttackOrder:: diff --git a/include/random.h b/include/random.h index de0f406fe5..0eb5c0f155 100644 --- a/include/random.h +++ b/include/random.h @@ -215,6 +215,8 @@ enum RandomTag RNG_AI_REFRESH_TRICK_ROOM_ON_LAST_TURN, RNG_AI_APPLY_TAILWIND_ON_LAST_TURN_OF_TRICK_ROOM, RNG_WRAP, + RNG_PRESENT, + RNG_MAGNITUDE, }; #define RandomWeighted(tag, ...) \ diff --git a/include/test/battle.h b/include/test/battle.h index 28547f2614..21aa5c20ac 100644 --- a/include/test/battle.h +++ b/include/test/battle.h @@ -697,6 +697,7 @@ struct BattleTestData struct Pokemon *currentMon; u8 gender; u8 nature; + bool8 isShiny; u16 forcedAbilities[NUM_BATTLE_SIDES][PARTY_SIZE]; u8 chosenGimmick[NUM_BATTLE_SIDES][PARTY_SIZE]; @@ -881,7 +882,8 @@ struct moveWithPP { #define DynamaxLevel(dynamaxLevel) DynamaxLevel_(__LINE__, dynamaxLevel) #define GigantamaxFactor(gigantamaxFactor) GigantamaxFactor_(__LINE__, gigantamaxFactor) #define TeraType(teraType) TeraType_(__LINE__, teraType) -#define Shadow(isShadow) Shadow_(__LINE__, shadow) +#define Shadow(isShadow) Shadow_(__LINE__, isShadow) +#define Shiny(isShiny) Shiny_(__LINE__, isShiny) void SetFlagForTest(u32 sourceLine, u16 flagId); void TestSetConfig(u32 sourceLine, enum GenConfigTag configTag, u32 value); @@ -919,6 +921,7 @@ void DynamaxLevel_(u32 sourceLine, u32 dynamaxLevel); void GigantamaxFactor_(u32 sourceLine, bool32 gigantamaxFactor); void TeraType_(u32 sourceLine, u32 teraType); void Shadow_(u32 sourceLine, bool32 isShadow); +void Shiny_(u32 sourceLine, bool32 isShiny); // Created for easy use of EXPECT_MOVES, so the user can provide 1, 2, 3 or 4 moves for AI which can pass the test. struct FourMoves diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 796d966050..af80d4468c 100755 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -11833,7 +11833,7 @@ static void Cmd_presentdamagecalculation(void) { CMD_ARGS(); - u32 rand = Random() & 0xFF; + u32 rand = RandomUniform(RNG_PRESENT, 0, 0xFF); /* Don't reroll present effect/power for the second hit of Parental Bond. * Not sure if this is the correct behaviour, but bulbapedia states @@ -11904,7 +11904,7 @@ static void Cmd_magnitudedamagecalculation(void) { CMD_ARGS(); - u32 magnitude = Random() % 100; + u32 magnitude = RandomUniform(RNG_MAGNITUDE, 0, 99); if (magnitude < 5) { diff --git a/test/battle/ability/sheer_force.c b/test/battle/ability/sheer_force.c index c6e84694ba..50f814f0e2 100644 --- a/test/battle/ability/sheer_force.c +++ b/test/battle/ability/sheer_force.c @@ -66,7 +66,9 @@ SINGLE_BATTLE_TEST("Sheer Force doesn't boost Present", s16 damage) PLAYER(SPECIES_TAUROS) { Ability(ability); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { - TURN { MOVE(player, MOVE_PRESENT); } + //Test will fail if present heals because the hp change would be 0 + //so we want a damaging version of present + TURN { MOVE(player, MOVE_PRESENT, WITH_RNG(RNG_PRESENT, 1)); } } SCENE { HP_BAR(opponent, captureDamage: &results[i].damage); } FINALLY { diff --git a/test/battle/move_animations/all_anims.c b/test/battle/move_animations/all_anims.c index c929921d3f..11b286084e 100644 --- a/test/battle/move_animations/all_anims.c +++ b/test/battle/move_animations/all_anims.c @@ -9,7 +9,7 @@ #define ANIM_TEST_END_MOVE MOVES_COUNT-1 // Last move to test -static void ParametrizeMovesAndSpecies(u32 j, u32 *pMove, u32 *pSpecies) +static void ParametrizeMovesAndSpecies(u32 j, u32 *pMove, u32 *pSpecies, u32 variation) { if (gMovesInfo[j].effect == EFFECT_DARK_VOID) // User needs to be Darkrai { @@ -41,11 +41,36 @@ static void ParametrizeMovesAndSpecies(u32 j, u32 *pMove, u32 *pSpecies) *pMove = j; *pSpecies = SPECIES_JOLTEON; } + else if (gMovesInfo[j].effect == EFFECT_CURSE && variation == 1) // User needs to be Ghost-type + { + *pMove = j; + *pSpecies = SPECIES_GASTLY; + } else if (gMovesInfo[j].effect == EFFECT_MAGNETIC_FLUX || gMovesInfo[j].effect == EFFECT_GEAR_UP) // User needs to have Plus { *pMove = j; *pSpecies = SPECIES_KLINKLANG; } + else if (gMovesInfo[j].effect == EFFECT_IVY_CUDGEL && variation > 0) + { + *pMove = j; + if (variation == 1) + *pSpecies = SPECIES_OGERPON_WELLSPRING; + else if (variation == 2) + *pSpecies = SPECIES_OGERPON_HEARTHFLAME; + else + *pSpecies = SPECIES_OGERPON_CORNERSTONE; + } + else if (gMovesInfo[j].effect == EFFECT_DRAGON_DARTS && variation > 0) + { + *pMove = j; + *pSpecies = SPECIES_DRAGAPULT; + } + else if (gMovesInfo[j].effect == EFFECT_TERA_STARSTORM && variation == 1) + { + *pMove = j; + *pSpecies = SPECIES_TERAPAGOS_STELLAR; + } else if (gMovesInfo[j].effect == EFFECT_PLACEHOLDER) // Ignore placeholder *pMoves { *pMove = MOVE_POUND; @@ -58,6 +83,75 @@ static void ParametrizeMovesAndSpecies(u32 j, u32 *pMove, u32 *pSpecies) } } +static u32 ParametrizeFriendship(u32 move, u32 variation) +{ + if (gMovesInfo[move].effect == EFFECT_FRUSTRATION + || gMovesInfo[move].effect == EFFECT_RETURN + ) + { + if (variation == 0) + return 1; + else if (variation == 1) + return 61; + else if (variation == 2) + return 101; + else if (variation == 3) + return 201; + } + return 0; +} + +static u32 GetParametrizedHP(u32 move, u32 variation) +{ + if (gMovesInfo[move].effect == EFFECT_POWER_BASED_ON_USER_HP && variation > 0) + { + if (variation == 1) + return 6000; + else if (variation == 2) + return 4000; + else if (variation == 3) + return 2000; + } + return 9997; +} + +static u32 GetParametrizedItem(u32 move, u32 variation) +{ + if ((move == MOVE_TECHNO_BLAST) && variation > 0) + { + if (variation == 1) + return ITEM_DOUSE_DRIVE; + else if (variation == 2) + return ITEM_SHOCK_DRIVE; + else if (variation == 3) + return ITEM_BURN_DRIVE; + else if (variation == 4) + return ITEM_CHILL_DRIVE; + } + return ITEM_ORAN_BERRY; +} + +static u32 GetParametrizedLevel(u32 move, u32 variation) +{ + if (gMovesInfo[move].effect == EFFECT_LEVEL_DAMAGE && variation > 0) + { + if (variation == 1) + return 50; + else if (variation == 2) + return 20; + } + return 100; +} + +static bool32 GetParametrizedShinyness(u32 move, u32 variation) +{ + if ((gMovesInfo[move].effect == EFFECT_DRAGON_DARTS && variation == 2) + || (move == MOVE_SYRUP_BOMB && variation == 1) + ) + return TRUE; + return FALSE; +} + static bool32 TargetHasToMove(u32 move) // Opponent needs to hit the player first { if (gMovesInfo[move].effect == EFFECT_COUNTER @@ -104,7 +198,37 @@ static bool32 UserHasToGoFirst(u32 move) // Player needs to go first return FALSE; } -static void WhenSingles(u32 move, struct BattlePokemon *attacker, struct BattlePokemon *defender) +static u32 GetVariationsNumber(u32 move, bool8 isDouble) +{ + u32 variationsNumber; + + if (gMovesInfo[move].effect == EFFECT_WEATHER_BALL + || gMovesInfo[move].effect == EFFECT_TERRAIN_PULSE + || move == MOVE_TECHNO_BLAST) + variationsNumber = 5; + else if (gMovesInfo[move].effect == EFFECT_FRUSTRATION + || gMovesInfo[move].effect == EFFECT_RETURN + || gMovesInfo[move].effect == EFFECT_IVY_CUDGEL + || move == MOVE_WATER_SPOUT) //we don't use the effect because other moves with the water spout effect don't have animation variations + variationsNumber = 4; + else if (gMovesInfo[move].effect == EFFECT_SPIT_UP + || gMovesInfo[move].effect == EFFECT_SWALLOW + || gMovesInfo[move].effect == EFFECT_DRAGON_DARTS + || move == MOVE_SEISMIC_TOSS) + variationsNumber = 3; + else if (gMovesInfo[move].effect == EFFECT_CURSE + || gMovesInfo[move].effect == EFFECT_PRESENT + || gMovesInfo[move].effect == EFFECT_SHELL_SIDE_ARM + || gMovesInfo[move].effect == EFFECT_FICKLE_BEAM + || gMovesInfo[move].effect == EFFECT_MAGNITUDE + || (isDouble && gMovesInfo[move].effect == EFFECT_TERA_STARSTORM) + || move == MOVE_SYRUP_BOMB) + variationsNumber = 2; + else + variationsNumber = 1; + return variationsNumber; +} +static void WhenSingles(u32 move, struct BattlePokemon *attacker, struct BattlePokemon *defender, u32 variation) { // Setup turn if (gMovesInfo[move].effect == EFFECT_SNORE @@ -115,7 +239,10 @@ static void WhenSingles(u32 move, struct BattlePokemon *attacker, struct BattleP else if (gMovesInfo[move].effect == EFFECT_SPIT_UP || gMovesInfo[move].effect == EFFECT_SWALLOW) { // attacker needs to have used Stockpile - TURN { MOVE(attacker, MOVE_STOCKPILE); } + for (u32 i = 0; i <= variation; i++) + { + TURN { MOVE(attacker, MOVE_STOCKPILE); } + } } else if ((gMovesInfo[move].effect == EFFECT_DOUBLE_POWER_ON_ARG_STATUS && gMovesInfo[move].argument.status == STATUS1_PARALYSIS)) { // defender needs to be paralyzed @@ -157,6 +284,32 @@ static void WhenSingles(u32 move, struct BattlePokemon *attacker, struct BattleP { // Needs a terrain TURN { MOVE(attacker, MOVE_ELECTRIC_TERRAIN); } } + else if (gMovesInfo[move].effect == EFFECT_WEATHER_BALL && variation > 0) + { + if (variation == 1) + TURN { MOVE(attacker, MOVE_SUNNY_DAY); } + else if (variation == 2) + TURN { MOVE(attacker, MOVE_RAIN_DANCE); } + else if (variation == 3) + TURN { MOVE(attacker, MOVE_SANDSTORM); } + else + TURN { MOVE(attacker, MOVE_HAIL); } + } + else if (gMovesInfo[move].effect == EFFECT_TERRAIN_PULSE && variation > 0) + { + if (variation == 1) + TURN { MOVE(attacker, MOVE_ELECTRIC_TERRAIN); } + else if (variation == 2) + TURN { MOVE(attacker, MOVE_GRASSY_TERRAIN); } + else if (variation == 3) + TURN { MOVE(attacker, MOVE_PSYCHIC_TERRAIN); } + else if (variation == 4) + TURN { MOVE(attacker, MOVE_MISTY_TERRAIN); } + } + else if (gBattleMoveEffects[gMovesInfo[move].effect].twoTurnEffect) + { + TURN { MOVE(attacker, move); } + } // Effective turn TURN { if (TargetHasToMove(move)) @@ -198,12 +351,62 @@ static void WhenSingles(u32 move, struct BattlePokemon *attacker, struct BattleP { MOVE(attacker, move, target: attacker); } + else if (gBattleMoveEffects[gMovesInfo[move].effect].twoTurnEffect) + { + MOVE(defender, MOVE_HELPING_HAND); + SKIP_TURN(attacker); + } + else if (gMovesInfo[move].effect == EFFECT_PRESENT) + { + if (variation == 0) + MOVE(attacker, move, WITH_RNG(RNG_PRESENT, 1)); + else if (variation == 1) + MOVE(attacker, move, WITH_RNG(RNG_PRESENT, 254)); + } + else if (gMovesInfo[move].effect == EFFECT_MAGNITUDE) + { + if (variation == 0) + MOVE(attacker, move, WITH_RNG(RNG_MAGNITUDE, 50)); + else if (variation == 1) + MOVE(attacker, move, WITH_RNG(RNG_MAGNITUDE, 99)); + } + else if (gMovesInfo[move].effect == EFFECT_FICKLE_BEAM) + { + if (variation == 0) + MOVE(attacker, move, WITH_RNG(RNG_FICKLE_BEAM, FALSE)); + else if (variation == 1) + MOVE(attacker, move, WITH_RNG(RNG_FICKLE_BEAM, TRUE)); + } + else if (gMovesInfo[move].effect == EFFECT_SHELL_SIDE_ARM) + { + if (variation == 0) + MOVE(attacker, move, WITH_RNG(RNG_SHELL_SIDE_ARM, FALSE)); + else if (variation == 1) + MOVE(attacker, move, WITH_RNG(RNG_SHELL_SIDE_ARM, TRUE)); + } else { // All other moves MOVE(defender, MOVE_HELPING_HAND); // Helping Hand, so there's no anim on the defender's side. MOVE(attacker, move); } } + if (gMovesInfo[move].effect == EFFECT_WISH) + { + TURN {}; + } + else if (gMovesInfo[move].effect == EFFECT_FUTURE_SIGHT) + { + TURN {}; + TURN {}; + } + else if (gMovesInfo[move].effect == EFFECT_ROLLOUT) + { + TURN {MOVE(attacker, move);}; + TURN {MOVE(attacker, move);}; + TURN {MOVE(attacker, move);}; + TURN {MOVE(attacker, move);}; + TURN {MOVE(attacker, MOVE_HELPING_HAND);}; + } } static void SceneSingles(u32 move, struct BattlePokemon *mon) @@ -233,7 +436,7 @@ static void SceneSingles(u32 move, struct BattlePokemon *mon) } } -static void DoublesWhen(u32 move, struct BattlePokemon *attacker, struct BattlePokemon *target, struct BattlePokemon *ignore1, struct BattlePokemon *ignore2) +static void DoublesWhen(u32 move, struct BattlePokemon *attacker, struct BattlePokemon *target, struct BattlePokemon *ignore1, struct BattlePokemon *ignore2, u32 variation) { // Setup turn if (gMovesInfo[move].effect == EFFECT_SNORE @@ -244,7 +447,10 @@ static void DoublesWhen(u32 move, struct BattlePokemon *attacker, struct BattleP else if (gMovesInfo[move].effect == EFFECT_SPIT_UP || gMovesInfo[move].effect == EFFECT_SWALLOW) { // Player needs to have used Stockpile - TURN { MOVE(attacker, MOVE_STOCKPILE); } + for (u32 i = 0; i <= variation; i++) + { + TURN { MOVE(attacker, MOVE_STOCKPILE); } + } } else if ((gMovesInfo[move].effect == EFFECT_DOUBLE_POWER_ON_ARG_STATUS && gMovesInfo[move].argument.status == STATUS1_PARALYSIS)) { // Opponent needs to be paralyzed @@ -286,6 +492,32 @@ static void DoublesWhen(u32 move, struct BattlePokemon *attacker, struct BattleP { // Needs a terrain TURN { MOVE(attacker, MOVE_ELECTRIC_TERRAIN); } } + else if (gMovesInfo[move].effect == EFFECT_WEATHER_BALL && variation > 0) + { + if (variation == 1) + TURN { MOVE(attacker, MOVE_SUNNY_DAY); } + else if (variation == 2) + TURN { MOVE(attacker, MOVE_RAIN_DANCE); } + else if (variation == 3) + TURN { MOVE(attacker, MOVE_SANDSTORM); } + else + TURN { MOVE(attacker, MOVE_HAIL); } + } + else if (gMovesInfo[move].effect == EFFECT_TERRAIN_PULSE && variation > 0) + { + if (variation == 1) + TURN { MOVE(attacker, MOVE_ELECTRIC_TERRAIN); } + else if (variation == 2) + TURN { MOVE(attacker, MOVE_GRASSY_TERRAIN); } + else if (variation == 3) + TURN { MOVE(attacker, MOVE_PSYCHIC_TERRAIN); } + else if (variation == 4) + TURN { MOVE(attacker, MOVE_MISTY_TERRAIN); } + } + else if (gBattleMoveEffects[gMovesInfo[move].effect].twoTurnEffect) + { + TURN { MOVE(attacker, move, target: target); } + } // Effective turn TURN { if (TargetHasToMove(move)) @@ -330,6 +562,39 @@ static void DoublesWhen(u32 move, struct BattlePokemon *attacker, struct BattleP MOVE(attacker, move, target: target); MOVE(target, MOVE_QUICK_ATTACK, target: attacker); } + else if (gBattleMoveEffects[gMovesInfo[move].effect].twoTurnEffect) + { + MOVE(target, MOVE_LAST_RESORT, target: attacker); + SKIP_TURN(attacker); + } + else if (gMovesInfo[move].effect == EFFECT_PRESENT) + { + if (variation == 0) + MOVE(attacker, move, target: target, WITH_RNG(RNG_PRESENT, 1)); + else if (variation == 1) + MOVE(attacker, move, target: target, WITH_RNG(RNG_PRESENT, 254)); + } + else if (gMovesInfo[move].effect == EFFECT_MAGNITUDE) + { + if (variation == 0) + MOVE(attacker, move, WITH_RNG(RNG_MAGNITUDE, 50)); + else if (variation == 1) + MOVE(attacker, move, WITH_RNG(RNG_MAGNITUDE, 99)); + } + else if (gMovesInfo[move].effect == EFFECT_FICKLE_BEAM) + { + if (variation == 0) + MOVE(attacker, move, target: target, WITH_RNG(RNG_FICKLE_BEAM, FALSE)); + else if (variation == 1) + MOVE(attacker, move, target: target, WITH_RNG(RNG_FICKLE_BEAM, TRUE)); + } + else if (gMovesInfo[move].effect == EFFECT_SHELL_SIDE_ARM) + { + if (variation == 0) + MOVE(attacker, move, target: target, WITH_RNG(RNG_SHELL_SIDE_ARM, FALSE)); + else if (variation == 1) + MOVE(attacker, move, target: target, WITH_RNG(RNG_SHELL_SIDE_ARM, TRUE)); + } else { // All other moves MOVE(target, MOVE_LAST_RESORT, target: attacker); // Last Resort, so there's no anim on the opponent's side. @@ -342,6 +607,23 @@ static void DoublesWhen(u32 move, struct BattlePokemon *attacker, struct BattleP MOVE(ignore2, MOVE_CELEBRATE); } } + if (gMovesInfo[move].effect == EFFECT_WISH) + { + TURN {}; + } + else if (gMovesInfo[move].effect == EFFECT_FUTURE_SIGHT) + { + TURN {}; + TURN {}; + } + else if (gMovesInfo[move].effect == EFFECT_ROLLOUT) + { + TURN {MOVE(attacker, move, target: target);}; + TURN {MOVE(attacker, move, target: target);}; + TURN {MOVE(attacker, move, target: target);}; + TURN {MOVE(attacker, move, target: target);}; + TURN {MOVE(attacker, MOVE_LAST_RESORT, target: attacker);}; + } } static void DoublesScene(u32 move, struct BattlePokemon *attacker) @@ -372,18 +654,27 @@ static void DoublesScene(u32 move, struct BattlePokemon *attacker) SINGLE_BATTLE_TEST("Move Animations don't leak when used - Singles (player to opponent)") { u32 j = ANIM_TEST_START_MOVE, move = 0, species = 0; + u32 k = 0, variation = 0, variationsNumber; + u32 friendship = 0, tempFriendship; u32 tempMove, tempSpecies; FORCE_MOVE_ANIM(TRUE); for (; j <= ANIM_TEST_END_MOVE; j++) { - ParametrizeMovesAndSpecies(j, &tempMove, &tempSpecies); - PARAMETRIZE { move = tempMove; species = tempSpecies; } + variationsNumber = GetVariationsNumber(j, FALSE); + for (k = 0; k < variationsNumber; k++) { + ParametrizeMovesAndSpecies(j, &tempMove, &tempSpecies, k); + tempFriendship = ParametrizeFriendship(j, k); + PARAMETRIZE { move = tempMove; species = tempSpecies; variation = k; friendship = tempFriendship;} + } } GIVEN { PLAYER(species) { - HP(9997); MaxHP(9999); Item(ITEM_ORAN_BERRY); + Level(GetParametrizedLevel(move, variation)); + HP(GetParametrizedHP(move, variation)); MaxHP(9999); Item(GetParametrizedItem(move, variation)); if (species == SPECIES_WOBBUFFET) Gender(MON_FEMALE); if (gMovesInfo[move].effect == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND); if (species == SPECIES_KLINKLANG) Ability(ABILITY_PLUS); + if (friendship) Friendship(friendship); + if (GetParametrizedShinyness(move, variation)) Shiny(TRUE); } PLAYER(SPECIES_WOBBUFFET) { Gender(MON_MALE); MaxHP(9999); Moves(MOVE_POUND); @@ -396,7 +687,7 @@ SINGLE_BATTLE_TEST("Move Animations don't leak when used - Singles (player to op } OPPONENT(SPECIES_WOBBUFFET) { Gender(MON_FEMALE); HP(9998); MaxHP(9999); SpDefense(9999); Defense(9999); } } WHEN { - WhenSingles(move, player, opponent); + WhenSingles(move, player, opponent, variation); } SCENE { SceneSingles(move, player); } THEN { @@ -410,18 +701,27 @@ SINGLE_BATTLE_TEST("Move Animations don't leak when used - Singles (player to op SINGLE_BATTLE_TEST("Move Animations don't leak when used - Singles (opponent to player)") { u32 j = ANIM_TEST_START_MOVE, move = 0, species = 0; + u32 k = 0, variation = 0, variationsNumber; + u32 friendship = 0, tempFriendship; u32 tempMove, tempSpecies; FORCE_MOVE_ANIM(TRUE); for (; j <= ANIM_TEST_END_MOVE; j++) { - ParametrizeMovesAndSpecies(j, &tempMove, &tempSpecies); - PARAMETRIZE { move = tempMove; species = tempSpecies; } + variationsNumber = GetVariationsNumber(j, FALSE); + for (k = 0; k < variationsNumber; k++) { + ParametrizeMovesAndSpecies(j, &tempMove, &tempSpecies, k); + tempFriendship = ParametrizeFriendship(j, k); + PARAMETRIZE { move = tempMove; species = tempSpecies; variation = k; friendship = tempFriendship;} + } } GIVEN { OPPONENT(species) { - HP(9997); MaxHP(9999); Item(ITEM_ORAN_BERRY); + Level(GetParametrizedLevel(move, variation)); + HP(GetParametrizedHP(move, variation)); MaxHP(9999); Item(GetParametrizedItem(move, variation)); if (species == SPECIES_WOBBUFFET) Gender(MON_FEMALE); if (gMovesInfo[move].effect == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND); if (species == SPECIES_KLINKLANG) Ability(ABILITY_PLUS); + if (friendship) Friendship(friendship); + if (GetParametrizedShinyness(move, variation)) Shiny(TRUE); } OPPONENT(SPECIES_WOBBUFFET) { Gender(MON_MALE); MaxHP(9999); Moves(MOVE_POUND); @@ -434,7 +734,7 @@ SINGLE_BATTLE_TEST("Move Animations don't leak when used - Singles (opponent to } PLAYER(SPECIES_WOBBUFFET) { Gender(MON_FEMALE); HP(9998); MaxHP(9999); SpDefense(9999); Defense(9999); } } WHEN { - WhenSingles(move, opponent, player); + WhenSingles(move, opponent, player, variation); } SCENE { SceneSingles(move, opponent); } THEN { @@ -448,6 +748,8 @@ SINGLE_BATTLE_TEST("Move Animations don't leak when used - Singles (opponent to DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (playerLeft to opponentLeft)") { u32 j = ANIM_TEST_START_MOVE, move = 0, species = 0; + u32 k = 0, variation = 0, variationsNumber; + u32 friendship = 0, tempFriendship; u32 tempMove, tempSpecies; FORCE_MOVE_ANIM(TRUE); struct BattlePokemon *attacker = playerLeft; @@ -455,25 +757,35 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (playerLeft t struct BattlePokemon *ignore1 = playerRight; struct BattlePokemon *ignore2 = opponentRight; for (; j <= ANIM_TEST_END_MOVE; j++) { - ParametrizeMovesAndSpecies(j, &tempMove, &tempSpecies); - PARAMETRIZE { move = tempMove; species = tempSpecies; } + variationsNumber = GetVariationsNumber(j, TRUE); + for (k = 0; k < variationsNumber; k++) { + ParametrizeMovesAndSpecies(j, &tempMove, &tempSpecies, k); + tempFriendship = ParametrizeFriendship(j, k); + PARAMETRIZE { move = tempMove; species = tempSpecies; variation = k; friendship = tempFriendship;} + } } GIVEN { PLAYER(species) { - HP(9997); MaxHP(9999); Item(ITEM_ORAN_BERRY); + Level(GetParametrizedLevel(move, variation)); + HP(GetParametrizedHP(move, variation)); MaxHP(9999); Item(GetParametrizedItem(move, variation)); if (attacker == playerLeft) { if (species == SPECIES_WOBBUFFET) Gender(MON_FEMALE); if (gMovesInfo[move].effect == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND); if (species == SPECIES_KLINKLANG) Ability(ABILITY_PLUS); + if (friendship) Friendship(friendship); + if (GetParametrizedShinyness(move, variation)) Shiny(TRUE); } } PLAYER(species) { - HP(9997); MaxHP(9999); Item(ITEM_ORAN_BERRY); + Level(GetParametrizedLevel(move, variation)); + HP(GetParametrizedHP(move, variation)); MaxHP(9999); Item(GetParametrizedItem(move, variation)); if (attacker == playerRight) { if (species == SPECIES_WOBBUFFET) Gender(MON_FEMALE); if (gMovesInfo[move].effect == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND); if (species == SPECIES_KLINKLANG) Ability(ABILITY_PLUS); + if (friendship) Friendship(friendship); + if (GetParametrizedShinyness(move, variation)) Shiny(TRUE); } } PLAYER(SPECIES_WOBBUFFET) { @@ -492,7 +804,7 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (playerLeft t } OPPONENT(SPECIES_WOBBUFFET) { Gender(MON_FEMALE); HP(9998); MaxHP(9999); SpDefense(9999); Defense(9999); } } WHEN { - DoublesWhen(move, attacker, target, ignore1, ignore2); + DoublesWhen(move, attacker, target, ignore1, ignore2, variation); } SCENE { DoublesScene(move, attacker); } THEN { @@ -506,6 +818,8 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (playerLeft t DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (opponentLeft to playerLeft)") { u32 j = ANIM_TEST_START_MOVE, move = 0, species = 0; + u32 k = 0, variation = 0, variationsNumber; + u32 friendship = 0, tempFriendship; u32 tempMove, tempSpecies; FORCE_MOVE_ANIM(TRUE); struct BattlePokemon *attacker = opponentLeft; @@ -513,24 +827,34 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (opponentLeft struct BattlePokemon *ignore1 = opponentRight; struct BattlePokemon *ignore2 = playerRight; for (; j <= ANIM_TEST_END_MOVE; j++) { - ParametrizeMovesAndSpecies(j, &tempMove, &tempSpecies); - PARAMETRIZE { move = tempMove; species = tempSpecies; } + variationsNumber = GetVariationsNumber(j, TRUE); + for (k = 0; k < variationsNumber; k++) { + ParametrizeMovesAndSpecies(j, &tempMove, &tempSpecies, k); + tempFriendship = ParametrizeFriendship(j, k); + PARAMETRIZE { move = tempMove; species = tempSpecies; variation = k; friendship = tempFriendship;} + } } GIVEN { OPPONENT(species) { - HP(9997); MaxHP(9999); Item(ITEM_ORAN_BERRY); + Level(GetParametrizedLevel(move, variation)); + HP(GetParametrizedHP(move, variation)); MaxHP(9999); Item(GetParametrizedItem(move, variation)); if (attacker == opponentLeft) { if (species == SPECIES_WOBBUFFET) Gender(MON_FEMALE); if (gMovesInfo[move].effect == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND); if (species == SPECIES_KLINKLANG) Ability(ABILITY_PLUS); + if (friendship) Friendship(friendship); + if (GetParametrizedShinyness(move, variation)) Shiny(TRUE); } } OPPONENT(species) { - HP(9997); MaxHP(9999); Item(ITEM_ORAN_BERRY); + Level(GetParametrizedLevel(move, variation)); + HP(GetParametrizedHP(move, variation)); MaxHP(9999); Item(GetParametrizedItem(move, variation)); if (attacker == opponentRight) { if (species == SPECIES_WOBBUFFET) Gender(MON_FEMALE); if (gMovesInfo[move].effect == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND); if (species == SPECIES_KLINKLANG) Ability(ABILITY_PLUS); + if (friendship) Friendship(friendship); + if (GetParametrizedShinyness(move, variation)) Shiny(TRUE); } } OPPONENT(SPECIES_WOBBUFFET) { @@ -551,7 +875,7 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (opponentLeft } PLAYER(SPECIES_WOBBUFFET) { Gender(MON_FEMALE); HP(9998); MaxHP(9999); SpDefense(9999); Defense(9999); } } WHEN { - DoublesWhen(move, attacker, target, ignore1, ignore2); + DoublesWhen(move, attacker, target, ignore1, ignore2, variation); } SCENE { DoublesScene(move, attacker); } THEN { @@ -565,6 +889,8 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (opponentLeft DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (playerLeft to opponentRight)") { u32 j = ANIM_TEST_START_MOVE, move = 0, species = 0; + u32 k = 0, variation = 0, variationsNumber; + u32 friendship = 0, tempFriendship; u32 tempMove, tempSpecies; FORCE_MOVE_ANIM(TRUE); struct BattlePokemon *attacker = playerLeft; @@ -572,24 +898,34 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (playerLeft t struct BattlePokemon *ignore1 = playerRight; struct BattlePokemon *ignore2 = opponentLeft; for (; j <= ANIM_TEST_END_MOVE; j++) { - ParametrizeMovesAndSpecies(j, &tempMove, &tempSpecies); - PARAMETRIZE { move = tempMove; species = tempSpecies; } + variationsNumber = GetVariationsNumber(j, TRUE); + for (k = 0; k < variationsNumber; k++) { + ParametrizeMovesAndSpecies(j, &tempMove, &tempSpecies, k); + tempFriendship = ParametrizeFriendship(j, k); + PARAMETRIZE { move = tempMove; species = tempSpecies; variation = k; friendship = tempFriendship;} + } } GIVEN { PLAYER(species) { - HP(9997); MaxHP(9999); Item(ITEM_ORAN_BERRY); + Level(GetParametrizedLevel(move, variation)); + HP(GetParametrizedHP(move, variation)); MaxHP(9999); Item(GetParametrizedItem(move, variation)); if (attacker == playerLeft) { if (species == SPECIES_WOBBUFFET) Gender(MON_FEMALE); if (gMovesInfo[move].effect == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND); if (species == SPECIES_KLINKLANG) Ability(ABILITY_PLUS); + if (friendship) Friendship(friendship); + if (GetParametrizedShinyness(move, variation)) Shiny(TRUE); } } PLAYER(species) { - HP(9997); MaxHP(9999); Item(ITEM_ORAN_BERRY); + Level(GetParametrizedLevel(move, variation)); + HP(GetParametrizedHP(move, variation)); MaxHP(9999); Item(GetParametrizedItem(move, variation)); if (attacker == playerRight) { if (species == SPECIES_WOBBUFFET) Gender(MON_FEMALE); if (gMovesInfo[move].effect == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND); if (species == SPECIES_KLINKLANG) Ability(ABILITY_PLUS); + if (friendship) Friendship(friendship); + if (GetParametrizedShinyness(move, variation)) Shiny(TRUE); } } PLAYER(SPECIES_WOBBUFFET) { @@ -610,7 +946,7 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (playerLeft t } OPPONENT(SPECIES_WOBBUFFET) { Gender(MON_FEMALE); HP(9998); MaxHP(9999); SpDefense(9999); Defense(9999); } } WHEN { - DoublesWhen(move, attacker, target, ignore1, ignore2); + DoublesWhen(move, attacker, target, ignore1, ignore2, variation); } SCENE { DoublesScene(move, attacker); } THEN { @@ -624,6 +960,8 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (playerLeft t DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (opponentRight to playerLeft)") { u32 j = ANIM_TEST_START_MOVE, move = 0, species = 0; + u32 k = 0, variation = 0, variationsNumber; + u32 friendship = 0, tempFriendship; u32 tempMove, tempSpecies; FORCE_MOVE_ANIM(TRUE); struct BattlePokemon *attacker = opponentRight; @@ -631,24 +969,34 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (opponentRigh struct BattlePokemon *ignore1 = opponentLeft; struct BattlePokemon *ignore2 = playerRight; for (; j <= ANIM_TEST_END_MOVE; j++) { - ParametrizeMovesAndSpecies(j, &tempMove, &tempSpecies); - PARAMETRIZE { move = tempMove; species = tempSpecies; } + variationsNumber = GetVariationsNumber(j, TRUE); + for (k = 0; k < variationsNumber; k++) { + ParametrizeMovesAndSpecies(j, &tempMove, &tempSpecies, k); + tempFriendship = ParametrizeFriendship(j, k); + PARAMETRIZE { move = tempMove; species = tempSpecies; variation = k; friendship = tempFriendship;} + } } GIVEN { OPPONENT(species) { - HP(9997); MaxHP(9999); Item(ITEM_ORAN_BERRY); + Level(GetParametrizedLevel(move, variation)); + HP(GetParametrizedHP(move, variation)); MaxHP(9999); Item(GetParametrizedItem(move, variation)); if (attacker == opponentLeft) { if (species == SPECIES_WOBBUFFET) Gender(MON_FEMALE); if (gMovesInfo[move].effect == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND); if (species == SPECIES_KLINKLANG) Ability(ABILITY_PLUS); + if (friendship) Friendship(friendship); + if (GetParametrizedShinyness(move, variation)) Shiny(TRUE); } } OPPONENT(species) { - HP(9997); MaxHP(9999); Item(ITEM_ORAN_BERRY); + Level(GetParametrizedLevel(move, variation)); + HP(GetParametrizedHP(move, variation)); MaxHP(9999); Item(GetParametrizedItem(move, variation)); if (attacker == opponentRight) { if (species == SPECIES_WOBBUFFET) Gender(MON_FEMALE); if (gMovesInfo[move].effect == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND); if (species == SPECIES_KLINKLANG) Ability(ABILITY_PLUS); + if (friendship) Friendship(friendship); + if (GetParametrizedShinyness(move, variation)) Shiny(TRUE); } } OPPONENT(SPECIES_WOBBUFFET) { @@ -669,7 +1017,7 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (opponentRigh } PLAYER(SPECIES_WOBBUFFET) { Gender(MON_FEMALE); HP(9998); MaxHP(9999); SpDefense(9999); Defense(9999); } } WHEN { - DoublesWhen(move, attacker, target, ignore1, ignore2); + DoublesWhen(move, attacker, target, ignore1, ignore2, variation); } SCENE { DoublesScene(move, attacker); } THEN { @@ -683,6 +1031,8 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (opponentRigh DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (playerRight to opponentLeft)") { u32 j = ANIM_TEST_START_MOVE, move = 0, species = 0; + u32 k = 0, variation = 0, variationsNumber; + u32 friendship = 0, tempFriendship; u32 tempMove, tempSpecies; FORCE_MOVE_ANIM(TRUE); struct BattlePokemon *attacker = playerRight; @@ -690,24 +1040,34 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (playerRight struct BattlePokemon *ignore1 = playerLeft; struct BattlePokemon *ignore2 = opponentRight; for (; j <= ANIM_TEST_END_MOVE; j++) { - ParametrizeMovesAndSpecies(j, &tempMove, &tempSpecies); - PARAMETRIZE { move = tempMove; species = tempSpecies; } + variationsNumber = GetVariationsNumber(j, TRUE); + for (k = 0; k < variationsNumber; k++) { + ParametrizeMovesAndSpecies(j, &tempMove, &tempSpecies, k); + tempFriendship = ParametrizeFriendship(j, k); + PARAMETRIZE { move = tempMove; species = tempSpecies; variation = k; friendship = tempFriendship;} + } } GIVEN { PLAYER(species) { - HP(9997); MaxHP(9999); Item(ITEM_ORAN_BERRY); + Level(GetParametrizedLevel(move, variation)); + HP(GetParametrizedHP(move, variation)); MaxHP(9999); Item(GetParametrizedItem(move, variation)); if (attacker == playerLeft) { if (species == SPECIES_WOBBUFFET) Gender(MON_FEMALE); if (gMovesInfo[move].effect == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND); if (species == SPECIES_KLINKLANG) Ability(ABILITY_PLUS); + if (friendship) Friendship(friendship); + if (GetParametrizedShinyness(move, variation)) Shiny(TRUE); } } PLAYER(species) { - HP(9997); MaxHP(9999); Item(ITEM_ORAN_BERRY); + Level(GetParametrizedLevel(move, variation)); + HP(GetParametrizedHP(move, variation)); MaxHP(9999); Item(GetParametrizedItem(move, variation)); if (attacker == playerRight) { if (species == SPECIES_WOBBUFFET) Gender(MON_FEMALE); if (gMovesInfo[move].effect == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND); if (species == SPECIES_KLINKLANG) Ability(ABILITY_PLUS); + if (friendship) Friendship(friendship); + if (GetParametrizedShinyness(move, variation)) Shiny(TRUE); } } PLAYER(SPECIES_WOBBUFFET) { @@ -728,7 +1088,7 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (playerRight } OPPONENT(SPECIES_WOBBUFFET) { Gender(MON_FEMALE); HP(9998); MaxHP(9999); SpDefense(9999); Defense(9999); } } WHEN { - DoublesWhen(move, attacker, target, ignore1, ignore2); + DoublesWhen(move, attacker, target, ignore1, ignore2, variation); } SCENE { DoublesScene(move, attacker); } THEN { @@ -742,6 +1102,8 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (playerRight DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (opponentLeft to playerRight)") { u32 j = ANIM_TEST_START_MOVE, move = 0, species = 0; + u32 k = 0, variation = 0, variationsNumber; + u32 friendship = 0, tempFriendship; u32 tempMove, tempSpecies; FORCE_MOVE_ANIM(TRUE); struct BattlePokemon *attacker = opponentLeft; @@ -749,24 +1111,34 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (opponentLeft struct BattlePokemon *ignore1 = playerLeft; struct BattlePokemon *ignore2 = opponentRight; for (; j <= ANIM_TEST_END_MOVE; j++) { - ParametrizeMovesAndSpecies(j, &tempMove, &tempSpecies); - PARAMETRIZE { move = tempMove; species = tempSpecies; } + variationsNumber = GetVariationsNumber(j, TRUE); + for (k = 0; k < variationsNumber; k++) { + ParametrizeMovesAndSpecies(j, &tempMove, &tempSpecies, k); + tempFriendship = ParametrizeFriendship(j, k); + PARAMETRIZE { move = tempMove; species = tempSpecies; variation = k; friendship = tempFriendship;} + } } GIVEN { OPPONENT(species) { - HP(9997); MaxHP(9999); Item(ITEM_ORAN_BERRY); + Level(GetParametrizedLevel(move, variation)); + HP(GetParametrizedHP(move, variation)); MaxHP(9999); Item(GetParametrizedItem(move, variation)); if (attacker == opponentLeft) { if (species == SPECIES_WOBBUFFET) Gender(MON_FEMALE); if (gMovesInfo[move].effect == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND); if (species == SPECIES_KLINKLANG) Ability(ABILITY_PLUS); + if (friendship) Friendship(friendship); + if (GetParametrizedShinyness(move, variation)) Shiny(TRUE); } } OPPONENT(species) { - HP(9997); MaxHP(9999); Item(ITEM_ORAN_BERRY); + Level(GetParametrizedLevel(move, variation)); + HP(GetParametrizedHP(move, variation)); MaxHP(9999); Item(GetParametrizedItem(move, variation)); if (attacker == opponentRight) { if (species == SPECIES_WOBBUFFET) Gender(MON_FEMALE); if (gMovesInfo[move].effect == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND); if (species == SPECIES_KLINKLANG) Ability(ABILITY_PLUS); + if (friendship) Friendship(friendship); + if (GetParametrizedShinyness(move, variation)) Shiny(TRUE); } } OPPONENT(SPECIES_WOBBUFFET) { @@ -787,7 +1159,7 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (opponentLeft } PLAYER(SPECIES_WOBBUFFET) { Gender(MON_FEMALE); HP(9998); MaxHP(9999); SpDefense(9999); Defense(9999); } } WHEN { - DoublesWhen(move, attacker, target, ignore1, ignore2); + DoublesWhen(move, attacker, target, ignore1, ignore2, variation); } SCENE { DoublesScene(move, attacker); } THEN { @@ -801,6 +1173,8 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (opponentLeft DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (playerRight to opponentRight)") { u32 j = ANIM_TEST_START_MOVE, move = 0, species = 0; + u32 k = 0, variation = 0, variationsNumber; + u32 friendship = 0, tempFriendship; u32 tempMove, tempSpecies; FORCE_MOVE_ANIM(TRUE); struct BattlePokemon *attacker = playerRight; @@ -808,24 +1182,34 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (playerRight struct BattlePokemon *ignore1 = playerLeft; struct BattlePokemon *ignore2 = opponentLeft; for (; j <= ANIM_TEST_END_MOVE; j++) { - ParametrizeMovesAndSpecies(j, &tempMove, &tempSpecies); - PARAMETRIZE { move = tempMove; species = tempSpecies; } + variationsNumber = GetVariationsNumber(j, TRUE); + for (k = 0; k < variationsNumber; k++) { + ParametrizeMovesAndSpecies(j, &tempMove, &tempSpecies, k); + tempFriendship = ParametrizeFriendship(j, k); + PARAMETRIZE { move = tempMove; species = tempSpecies; variation = k; friendship = tempFriendship;} + } } GIVEN { PLAYER(species) { - HP(9997); MaxHP(9999); Item(ITEM_ORAN_BERRY); + Level(GetParametrizedLevel(move, variation)); + HP(GetParametrizedHP(move, variation)); MaxHP(9999); Item(GetParametrizedItem(move, variation)); if (attacker == playerLeft) { if (species == SPECIES_WOBBUFFET) Gender(MON_FEMALE); if (gMovesInfo[move].effect == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND); if (species == SPECIES_KLINKLANG) Ability(ABILITY_PLUS); + if (friendship) Friendship(friendship); + if (GetParametrizedShinyness(move, variation)) Shiny(TRUE); } } PLAYER(species) { - HP(9997); MaxHP(9999); Item(ITEM_ORAN_BERRY); + Level(GetParametrizedLevel(move, variation)); + HP(GetParametrizedHP(move, variation)); MaxHP(9999); Item(GetParametrizedItem(move, variation)); if (attacker == playerRight) { if (species == SPECIES_WOBBUFFET) Gender(MON_FEMALE); if (gMovesInfo[move].effect == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND); if (species == SPECIES_KLINKLANG) Ability(ABILITY_PLUS); + if (friendship) Friendship(friendship); + if (GetParametrizedShinyness(move, variation)) Shiny(TRUE); } } PLAYER(SPECIES_WOBBUFFET) { @@ -846,7 +1230,7 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (playerRight } OPPONENT(SPECIES_WOBBUFFET) { Gender(MON_FEMALE); HP(9998); MaxHP(9999); SpDefense(9999); Defense(9999); } } WHEN { - DoublesWhen(move, attacker, target, ignore1, ignore2); + DoublesWhen(move, attacker, target, ignore1, ignore2, variation); } SCENE { DoublesScene(move, attacker); } THEN { @@ -860,6 +1244,8 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (playerRight DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (opponentRight to playerRight)") { u32 j = ANIM_TEST_START_MOVE, move = 0, species = 0; + u32 k = 0, variation = 0, variationsNumber; + u32 friendship = 0, tempFriendship; u32 tempMove, tempSpecies; FORCE_MOVE_ANIM(TRUE); struct BattlePokemon *attacker = opponentRight; @@ -867,24 +1253,34 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (opponentRigh struct BattlePokemon *ignore1 = playerLeft; struct BattlePokemon *ignore2 = opponentLeft; for (; j <= ANIM_TEST_END_MOVE; j++) { - ParametrizeMovesAndSpecies(j, &tempMove, &tempSpecies); - PARAMETRIZE { move = tempMove; species = tempSpecies; } + variationsNumber = GetVariationsNumber(j, TRUE); + for (k = 0; k < variationsNumber; k++) { + ParametrizeMovesAndSpecies(j, &tempMove, &tempSpecies, k); + tempFriendship = ParametrizeFriendship(j, k); + PARAMETRIZE { move = tempMove; species = tempSpecies; variation = k; friendship = tempFriendship;} + } } GIVEN { OPPONENT(species) { - HP(9997); MaxHP(9999); Item(ITEM_ORAN_BERRY); + Level(GetParametrizedLevel(move, variation)); + HP(GetParametrizedHP(move, variation)); MaxHP(9999); Item(GetParametrizedItem(move, variation)); if (attacker == opponentLeft) { if (species == SPECIES_WOBBUFFET) Gender(MON_FEMALE); if (gMovesInfo[move].effect == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND); if (species == SPECIES_KLINKLANG) Ability(ABILITY_PLUS); + if (friendship) Friendship(friendship); + if (GetParametrizedShinyness(move, variation)) Shiny(TRUE); } } OPPONENT(species) { - HP(9997); MaxHP(9999); Item(ITEM_ORAN_BERRY); + Level(GetParametrizedLevel(move, variation)); + HP(GetParametrizedHP(move, variation)); MaxHP(9999); Item(GetParametrizedItem(move, variation)); if (attacker == opponentRight) { if (species == SPECIES_WOBBUFFET) Gender(MON_FEMALE); if (gMovesInfo[move].effect == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND); if (species == SPECIES_KLINKLANG) Ability(ABILITY_PLUS); + if (friendship) Friendship(friendship); + if (GetParametrizedShinyness(move, variation)) Shiny(TRUE); } } OPPONENT(SPECIES_WOBBUFFET) { @@ -905,7 +1301,7 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (opponentRigh } PLAYER(SPECIES_WOBBUFFET) { Gender(MON_FEMALE); HP(9998); MaxHP(9999); SpDefense(9999); Defense(9999); } } WHEN { - DoublesWhen(move, attacker, target, ignore1, ignore2); + DoublesWhen(move, attacker, target, ignore1, ignore2, variation); } SCENE { DoublesScene(move, attacker); } THEN { @@ -927,7 +1323,7 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (playerLeft t struct BattlePokemon *ignore1 = opponentRight; struct BattlePokemon *ignore2 = opponentLeft; for (; j <= ANIM_TEST_END_MOVE; j++) { - ParametrizeMovesAndSpecies(j, &tempMove, &tempSpecies); + ParametrizeMovesAndSpecies(j, &tempMove, &tempSpecies, 0); PARAMETRIZE { move = tempMove; species = tempSpecies; } } GIVEN { @@ -986,7 +1382,7 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (playerRight struct BattlePokemon *ignore1 = opponentRight; struct BattlePokemon *ignore2 = opponentLeft; for (; j <= ANIM_TEST_END_MOVE; j++) { - ParametrizeMovesAndSpecies(j, &tempMove, &tempSpecies); + ParametrizeMovesAndSpecies(j, &tempMove, &tempSpecies, 0); PARAMETRIZE { move = tempMove; species = tempSpecies; } } GIVEN { @@ -1045,7 +1441,7 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (opponentleft struct BattlePokemon *ignore1 = playerLeft; struct BattlePokemon *ignore2 = playerRight; for (; j <= ANIM_TEST_END_MOVE; j++) { - ParametrizeMovesAndSpecies(j, &tempMove, &tempSpecies); + ParametrizeMovesAndSpecies(j, &tempMove, &tempSpecies, 0); PARAMETRIZE { move = tempMove; species = tempSpecies; } } GIVEN { @@ -1104,7 +1500,7 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (opponentRigh struct BattlePokemon *ignore1 = playerLeft; struct BattlePokemon *ignore2 = playerRight; for (; j <= ANIM_TEST_END_MOVE; j++) { - ParametrizeMovesAndSpecies(j, &tempMove, &tempSpecies); + ParametrizeMovesAndSpecies(j, &tempMove, &tempSpecies, 0); PARAMETRIZE { move = tempMove; species = tempSpecies; } } GIVEN { @@ -1157,18 +1553,27 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (opponentRigh SINGLE_BATTLE_TEST("Move Animations occur before their stat change animations - Singles (player to opponent)") { u32 j = ANIM_TEST_START_MOVE, move = 0, species = 0; + u32 k = 0, variation = 0, variationsNumber; + u32 friendship = 0, tempFriendship; u32 tempMove, tempSpecies; FORCE_MOVE_ANIM(TRUE); for (; j <= ANIM_TEST_END_MOVE; j++) { - ParametrizeMovesAndSpecies(j, &tempMove, &tempSpecies); - PARAMETRIZE { move = tempMove; species = tempSpecies; } + variationsNumber = GetVariationsNumber(j, FALSE); + for (k = 0; k < variationsNumber; k++) { + ParametrizeMovesAndSpecies(j, &tempMove, &tempSpecies, k); + tempFriendship = ParametrizeFriendship(j, k); + PARAMETRIZE { move = tempMove; species = tempSpecies; variation = k; friendship = tempFriendship;} + } } GIVEN { PLAYER(species) { - HP(9997); MaxHP(9999); Item(ITEM_ORAN_BERRY); + Level(GetParametrizedLevel(move, variation)); + HP(GetParametrizedHP(move, variation)); MaxHP(9999); Item(GetParametrizedItem(move, variation)); if (species == SPECIES_WOBBUFFET) Gender(MON_FEMALE); if (gMovesInfo[move].effect == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND); if (species == SPECIES_KLINKLANG) Ability(ABILITY_PLUS); + if (friendship) Friendship(friendship); + if (GetParametrizedShinyness(move, variation)) Shiny(TRUE); } PLAYER(SPECIES_WOBBUFFET) { Gender(MON_MALE); MaxHP(9999); Moves(MOVE_POUND); @@ -1181,7 +1586,7 @@ SINGLE_BATTLE_TEST("Move Animations occur before their stat change animations - } OPPONENT(SPECIES_WOBBUFFET) { Gender(MON_FEMALE); HP(9998); MaxHP(9999); SpDefense(9999); Defense(9999); } } WHEN { - WhenSingles(move, player, opponent); + WhenSingles(move, player, opponent, variation); } SCENE { if (!(gMovesInfo[move].effect == EFFECT_RECYCLE || gMovesInfo[move].effect == EFFECT_BELCH diff --git a/test/test_runner_battle.c b/test/test_runner_battle.c index f2bb69fa91..95daa6ee9d 100644 --- a/test/test_runner_battle.c +++ b/test/test_runner_battle.c @@ -1574,6 +1574,7 @@ void OpenPokemon(u32 sourceLine, u32 side, u32 species) DATA.currentMon = &party[DATA.currentPartyIndex]; DATA.gender = 0xFF; // Male DATA.nature = NATURE_HARDY; + DATA.isShiny = FALSE; (*partySize)++; CreateMon(DATA.currentMon, species, 100, 0, TRUE, 0, OT_ID_PRESET, 0); @@ -1628,9 +1629,9 @@ void ClosePokemon(u32 sourceLine) INVALID_IF(GetMonData(DATA.currentMon, MON_DATA_HP) == 0, "Battlers cannot be fainted"); } } - data = FALSE; - SetMonData(DATA.currentMon, MON_DATA_IS_SHINY, &data); UpdateMonPersonality(&DATA.currentMon->box, GenerateNature(DATA.nature, DATA.gender % NUM_NATURES) | DATA.gender); + data = DATA.isShiny; + SetMonData(DATA.currentMon, MON_DATA_IS_SHINY, &data); DATA.currentMon = NULL; } @@ -1895,6 +1896,12 @@ void Shadow_(u32 sourceLine, bool32 isShadow) SetMonData(DATA.currentMon, MON_DATA_IS_SHADOW, &isShadow); } +void Shiny_(u32 sourceLine, bool32 isShiny) +{ + INVALID_IF(!DATA.currentMon, "Shiny outside of PLAYER/OPPONENT"); + DATA.isShiny = isShiny; +} + static const char *const sBattlerIdentifiersSingles[] = { "player",