diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 111150eb0..ee02db7b6 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -6338,6 +6338,7 @@ BattleScript_StickyWebOnSwitchInPrintStatMsg: BattleScript_StickyWebOnSwitchInEnd: restoretarget restoreattacker + setbyte sSTICKY_WEB_STAT_DROP, 0 return BattleScript_PerishSongTakesLife:: diff --git a/include/load_save.h b/include/load_save.h index cd51f90c8..a1582a2ab 100644 --- a/include/load_save.h +++ b/include/load_save.h @@ -9,6 +9,7 @@ extern struct SaveBlock2 gSaveBlock2; extern struct SaveBlock3 gSaveblock3; extern struct PokemonStorage gPokemonStorage; +void ClearSav3(void); void ClearSav2(void); void ClearSav1(void); void CheckForFlashMemory(void); diff --git a/test/battle/ability/comatose.c b/test/battle/ability/comatose.c index bd991c258..cc65e9afa 100644 --- a/test/battle/ability/comatose.c +++ b/test/battle/ability/comatose.c @@ -34,7 +34,10 @@ SINGLE_BATTLE_TEST("Comatose may be suppressed if pokemon transformed into a pok PARAMETRIZE { move = MOVE_THUNDER_WAVE; } GIVEN { - PLAYER(SPECIES_KOMALA) { Ability(ABILITY_COMATOSE); Speed(30); } + // FIXME: Explicit moves currently required here because Ditto + // expects to find Celebrate in slot 1 during the second turn + // (after transforming). + PLAYER(SPECIES_KOMALA) { Ability(ABILITY_COMATOSE); Speed(30); Moves(MOVE_CELEBRATE, MOVE_GASTRO_ACID, move); } OPPONENT(SPECIES_DITTO) { Speed(20); } } WHEN { TURN { MOVE(player, MOVE_GASTRO_ACID); MOVE(opponent, MOVE_TRANSFORM); } diff --git a/test/battle/ability/defiant.c b/test/battle/ability/defiant.c index 84b65bdc5..79136a559 100644 --- a/test/battle/ability/defiant.c +++ b/test/battle/ability/defiant.c @@ -139,6 +139,65 @@ SINGLE_BATTLE_TEST("Defiant activates after Sticky Web lowers Speed") } } +SINGLE_BATTLE_TEST("Defiant doesn't activate after Sticky Web lowers Speed if Court Changed") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_MANKEY) { Ability(ABILITY_DEFIANT); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_STICKY_WEB); MOVE(opponent, MOVE_COURT_CHANGE); } + TURN { SWITCH(player, 1); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_STICKY_WEB, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_COURT_CHANGE, opponent); + // Switch-in - Sticky Web activates + SEND_IN_MESSAGE("Mankey"); + MESSAGE("Mankey was caught in a Sticky Web!"); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Mankey's Speed fell!"); + // Defiant doesn't activate + NONE_OF { + ABILITY_POPUP(player, ABILITY_DEFIANT); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Mankey's Attack sharply rose!"); + } + } +} + +SINGLE_BATTLE_TEST("Defiant correctly activates after Sticky Web lowers Speed if Court Changed") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_MANKEY) { Ability(ABILITY_DEFIANT); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_STICKY_WEB); MOVE(opponent, MOVE_COURT_CHANGE); } + TURN { SWITCH(player, 1); } + TURN { MOVE(opponent, MOVE_GROWL);} + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_STICKY_WEB, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_COURT_CHANGE, opponent); + // Switch-in - Sticky Web activates + SEND_IN_MESSAGE("Mankey"); + MESSAGE("Mankey was caught in a Sticky Web!"); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Mankey's Speed fell!"); + // Defiant doesn't activate + NONE_OF { + ABILITY_POPUP(player, ABILITY_DEFIANT); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Mankey's Attack sharply rose!"); + } + // Defiant triggers correctly after Sticky Web + ANIMATION(ANIM_TYPE_MOVE, MOVE_GROWL, opponent); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Mankey's Attack fell!"); + ABILITY_POPUP(player, ABILITY_DEFIANT); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Mankey's Attack sharply rose!"); + } +} DOUBLE_BATTLE_TEST("Defiant is activated by Cotton Down for non-ally pokemon") { diff --git a/test/battle/ability/disguise.c b/test/battle/ability/disguise.c index 7d3e36bf7..c4f79d8fe 100644 --- a/test/battle/ability/disguise.c +++ b/test/battle/ability/disguise.c @@ -121,3 +121,16 @@ SINGLE_BATTLE_TEST("Disguised Mimikyu takes damage from Rough Skin without break EXPECT_EQ(player->species, SPECIES_MIMIKYU_DISGUISED); } } + +SINGLE_BATTLE_TEST("Disguised Mimikyu is ignored by Mold Breaker") +{ + GIVEN { + PLAYER(SPECIES_MIMIKYU_DISGUISED) { Ability(ABILITY_DISGUISE); } + OPPONENT(SPECIES_PINSIR) { Ability(ABILITY_MOLD_BREAKER); } + } WHEN { + TURN { MOVE(opponent, MOVE_AERIAL_ACE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_AERIAL_ACE, opponent); + NOT ABILITY_POPUP(player, ABILITY_DISGUISE); + } +} diff --git a/test/battle/ability/shield_dust.c b/test/battle/ability/shield_dust.c index 25ab1a5c7..d1785bd69 100644 --- a/test/battle/ability/shield_dust.c +++ b/test/battle/ability/shield_dust.c @@ -164,3 +164,15 @@ SINGLE_BATTLE_TEST("Shield Dust blocks Sparkling Aria in singles") } } } + +SINGLE_BATTLE_TEST("Shield Dust does not prevent ability stat changes") +{ + GIVEN { + PLAYER(SPECIES_VIVILLON) { Ability(ABILITY_SHIELD_DUST); } + OPPONENT(SPECIES_ELDEGOSS) { Ability(ABILITY_COTTON_DOWN); } + } WHEN { + TURN { MOVE(player, MOVE_TACKLE); } + } SCENE { + MESSAGE("Vivillon's Speed fell!"); + } +} diff --git a/test/battle/ability/stalwart.c b/test/battle/ability/stalwart.c new file mode 100644 index 000000000..289f25dd1 --- /dev/null +++ b/test/battle/ability/stalwart.c @@ -0,0 +1,55 @@ +#include "global.h" +#include "test/battle.h" + +DOUBLE_BATTLE_TEST("Stalwart ignores redirection from Follow-Me") +{ + GIVEN { + PLAYER(SPECIES_ARCHALUDON) { Ability(ABILITY_STALWART); } + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponentLeft, MOVE_FOLLOW_ME); MOVE(playerLeft, MOVE_DRACO_METEOR, target: opponentRight); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_FOLLOW_ME, opponentLeft); + ANIMATION(ANIM_TYPE_MOVE, MOVE_DRACO_METEOR, playerLeft); + HP_BAR(opponentRight); + NOT HP_BAR(opponentLeft); + } +} + +DOUBLE_BATTLE_TEST("Stalwart stops Lightning Rod and Storm Drain from redirecting moves") +{ + u32 ability, species; + PARAMETRIZE { ability = ABILITY_STORM_DRAIN; species = SPECIES_LUMINEON; } + PARAMETRIZE { ability = ABILITY_LIGHTNING_ROD; species = SPECIES_RAICHU; } + GIVEN { + ASSUME(gMovesInfo[MOVE_SPARK].type == TYPE_ELECTRIC); + ASSUME(gMovesInfo[MOVE_WATER_GUN].type == TYPE_WATER); + PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_STALWART); } + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(species) { Ability(ability); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { + if (ability == ABILITY_LIGHTNING_ROD) + MOVE(playerLeft, MOVE_SPARK, target: opponentRight); + else + MOVE(playerLeft, MOVE_WATER_GUN, target: opponentRight); + } + } SCENE { + if (B_REDIRECT_ABILITY_IMMUNITY >= GEN_5) { + HP_BAR(opponentRight); + NONE_OF { + ABILITY_POPUP(opponentLeft, ability); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentLeft); + MESSAGE("Foe Raichu's Sp. Atk rose!"); + } + } else { + HP_BAR(opponentRight); + NONE_OF { + HP_BAR(opponentLeft); + } + } + } +} diff --git a/test/battle/ai/ai_check_viability.c b/test/battle/ai/ai_check_viability.c index 2e75f3190..fa921e867 100644 --- a/test/battle/ai/ai_check_viability.c +++ b/test/battle/ai/ai_check_viability.c @@ -203,7 +203,7 @@ AI_DOUBLE_BATTLE_TEST("AI chooses moves that cure self or partner") GIVEN { ASSUME(gMovesInfo[MOVE_HEAL_BELL].effect == EFFECT_HEAL_BELL); - ASSUME(B_HEAL_BELL_SOUNDPROOF >= GEN_9); + ASSUME(B_HEAL_BELL_SOUNDPROOF >= GEN_8); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); diff --git a/test/battle/ai/ai_switching.c b/test/battle/ai/ai_switching.c index fcc8e322c..b3927509f 100644 --- a/test/battle/ai/ai_switching.c +++ b/test/battle/ai/ai_switching.c @@ -121,7 +121,7 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_MON_CHOICES: Avoid infinite loop if damage { GIVEN { ASSUME(gItemsInfo[ITEM_LEFTOVERS].holdEffect == HOLD_EFFECT_LEFTOVERS); - 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); + AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY | AI_FLAG_SMART_MON_CHOICES); PLAYER(SPECIES_MEOWTH_GALARIAN) { Level(100); Moves(MOVE_GROWL, MOVE_FAKE_OUT, MOVE_HONE_CLAWS); } // Scenario courtesy of Duke, who triggered the bug in the first place OPPONENT(SPECIES_MEOWTH_GALARIAN) { Level(5); Moves(MOVE_GROWL, MOVE_FAKE_OUT, MOVE_HONE_CLAWS); } @@ -357,3 +357,21 @@ AI_SINGLE_BATTLE_TEST("AI won't use trapping behaviour if player only has 1 mon TURN{ MOVE(player, MOVE_PROTECT); EXPECT_MOVE(opponent, MOVE_SELF_DESTRUCT); EXPECT_SEND_OUT(opponent, 2); } } } + +AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if mon would be OKHO'd and they have a good switchin 50% of the time") +{ + PASSES_RANDOMLY(50, 100, RNG_AI_HASBADODDS); + GIVEN { + ASSUME(gSpeciesInfo[SPECIES_RHYDON].types[0] == TYPE_GROUND); + ASSUME(gSpeciesInfo[SPECIES_PELIPPER].types[0] == TYPE_WATER); + ASSUME(gSpeciesInfo[SPECIES_PELIPPER].types[1] == TYPE_FLYING); + ASSUME(gMovesInfo[MOVE_THUNDERBOLT].type == TYPE_ELECTRIC); + ASSUME(gMovesInfo[MOVE_EARTHQUAKE].type == TYPE_GROUND); + AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_SWITCHING | AI_FLAG_SMART_MON_CHOICES); + PLAYER(SPECIES_ELECTRODE) { Moves(MOVE_THUNDERBOLT, MOVE_THUNDER_WAVE, MOVE_THUNDER_SHOCK); } + OPPONENT(SPECIES_PELIPPER) { Moves(MOVE_EARTHQUAKE); }; + OPPONENT(SPECIES_RHYDON) { Moves(MOVE_EARTHQUAKE); Ability(ABILITY_ROCK_HEAD); } + } WHEN { + TURN { MOVE(player, MOVE_THUNDERBOLT) ; EXPECT_SWITCH(opponent, 1); } + } +} diff --git a/test/battle/damage_formula.c b/test/battle/damage_formula.c index d89fb7e7f..473f631b1 100644 --- a/test/battle/damage_formula.c +++ b/test/battle/damage_formula.c @@ -116,3 +116,37 @@ SINGLE_BATTLE_TEST("Damage calculation matches Gen5+ (Marshadow vs Mawile)") EXPECT_EQ(expectedDamage, dmg); } } + +DOUBLE_BATTLE_TEST("A spread move will do correct damage to the second mon if the first target faints from first hit of the spread move") +{ + s16 damage[6]; + GIVEN { + PLAYER(SPECIES_REGIROCK); + PLAYER(SPECIES_REGIROCK); + OPPONENT(SPECIES_WOBBUFFET) { HP(200); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(playerLeft, MOVE_ROCK_SLIDE); } + TURN { MOVE(playerLeft, MOVE_ROCK_SLIDE); MOVE(playerRight, MOVE_ROCK_SLIDE); } + TURN { MOVE(playerLeft, MOVE_ROCK_SLIDE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_ROCK_SLIDE, playerLeft); + HP_BAR(opponentLeft, captureDamage: &damage[0]); + HP_BAR(opponentRight, captureDamage: &damage[1]); + + ANIMATION(ANIM_TYPE_MOVE, MOVE_ROCK_SLIDE, playerLeft); + HP_BAR(opponentLeft, captureDamage: &damage[2]); + HP_BAR(opponentRight, captureDamage: &damage[3]); + + ANIMATION(ANIM_TYPE_MOVE, MOVE_ROCK_SLIDE, playerRight); + HP_BAR(opponentRight, captureDamage: &damage[4]); + + ANIMATION(ANIM_TYPE_MOVE, MOVE_ROCK_SLIDE, playerLeft); + HP_BAR(opponentRight, captureDamage: &damage[5]); + } THEN { + EXPECT_EQ(damage[0], damage[1]); + EXPECT_EQ(damage[1], damage[3]); + EXPECT_MUL_EQ(damage[5], UQ_4_12(0.75), damage[3]); + EXPECT_EQ(damage[4], damage[5]); + } +} diff --git a/test/battle/gimmick/dynamax.c b/test/battle/gimmick/dynamax.c index 56fd2e25e..dca175c63 100644 --- a/test/battle/gimmick/dynamax.c +++ b/test/battle/gimmick/dynamax.c @@ -362,21 +362,6 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon lose their substitutes") } } -DOUBLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon can have their base moves copied by Copycat") -{ - GIVEN { - PLAYER(SPECIES_WOBBUFFET); - PLAYER(SPECIES_WYNAUT); - OPPONENT(SPECIES_WOBBUFFET); - OPPONENT(SPECIES_WYNAUT); - } WHEN { - TURN { MOVE(playerLeft, MOVE_TRICK_ROOM, gimmick: GIMMICK_DYNAMAX, target: opponentLeft); MOVE(playerRight, MOVE_COPYCAT, target: opponentLeft); } - } SCENE { - MESSAGE("Wobbuffet used Max Guard!"); - MESSAGE("Wynaut used Trick Room!"); - } -} - SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon take double damage from Dynamax Cannon", s16 damage) { u32 dynamax; diff --git a/test/battle/item_effect/covert_cloak.c b/test/battle/hold_effect/covert_cloak.c similarity index 93% rename from test/battle/item_effect/covert_cloak.c rename to test/battle/hold_effect/covert_cloak.c index 4e00ece8f..e15bca3b9 100644 --- a/test/battle/item_effect/covert_cloak.c +++ b/test/battle/hold_effect/covert_cloak.c @@ -1,6 +1,11 @@ #include "global.h" #include "test/battle.h" +ASSUMPTIONS +{ + ASSUME(gItemsInfo[ITEM_COVERT_CLOAK].holdEffect == HOLD_EFFECT_COVERT_CLOAK); +} + SINGLE_BATTLE_TEST("Covert Cloak blocks secondary effects") { u16 move; @@ -162,3 +167,15 @@ SINGLE_BATTLE_TEST("Covert Cloak blocks Sparkling Aria in singles") } } } + +SINGLE_BATTLE_TEST("Covert Cloak does not prevent ability stat changes") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_COVERT_CLOAK); } + OPPONENT(SPECIES_ELDEGOSS) { Ability(ABILITY_COTTON_DOWN); } + } WHEN { + TURN { MOVE(player, MOVE_TACKLE); } + } SCENE { + MESSAGE("Wobbuffet's Speed fell!"); + } +} diff --git a/test/battle/move.c b/test/battle/move.c index 936a82108..228a09a7c 100644 --- a/test/battle/move.c +++ b/test/battle/move.c @@ -66,10 +66,9 @@ SINGLE_BATTLE_TEST("Turn order is determined by Speed if priority ties") } } -SINGLE_BATTLE_TEST("Turn order is determined randomly if priority and Speed tie") +SINGLE_BATTLE_TEST("Turn order is determined randomly if priority and Speed tie [singles]") { - KNOWN_FAILING; // The algorithm is significantly biased. - PASSES_RANDOMLY(1, 2); + PASSES_RANDOMLY(1, 2, RNG_SPEED_TIE); GIVEN { PLAYER(SPECIES_WOBBUFFET) { Speed(1); } OPPONENT(SPECIES_WOBBUFFET) { Speed(1); } @@ -81,6 +80,60 @@ SINGLE_BATTLE_TEST("Turn order is determined randomly if priority and Speed tie" } } +DOUBLE_BATTLE_TEST("Turn order is determined randomly if priority and Speed tie [doubles]") +{ + struct BattlePokemon *order[4] = { NULL, NULL, NULL, NULL }; + u32 a, b, c, d; + + // TODO: Test all of these in a single PASSES_RANDOMLY pass rather + // than 24 PARAMETRIZEd passes. + PARAMETRIZE { a = 0; b = 1; c = 2; d = 3; } + PARAMETRIZE { a = 0; b = 1; c = 3; d = 2; } + PARAMETRIZE { a = 0; b = 2; c = 1; d = 3; } + PARAMETRIZE { a = 0; b = 2; c = 3; d = 1; } + PARAMETRIZE { a = 0; b = 3; c = 1; d = 2; } + PARAMETRIZE { a = 0; b = 3; c = 2; d = 1; } + PARAMETRIZE { a = 1; b = 0; c = 2; d = 3; } + PARAMETRIZE { a = 1; b = 0; c = 3; d = 2; } + PARAMETRIZE { a = 1; b = 2; c = 0; d = 3; } + PARAMETRIZE { a = 1; b = 2; c = 3; d = 0; } + PARAMETRIZE { a = 1; b = 3; c = 0; d = 2; } + PARAMETRIZE { a = 1; b = 3; c = 2; d = 0; } + PARAMETRIZE { a = 2; b = 0; c = 1; d = 3; } + PARAMETRIZE { a = 2; b = 0; c = 3; d = 1; } + PARAMETRIZE { a = 2; b = 1; c = 0; d = 3; } + PARAMETRIZE { a = 2; b = 1; c = 3; d = 0; } + PARAMETRIZE { a = 2; b = 3; c = 0; d = 1; } + PARAMETRIZE { a = 2; b = 3; c = 1; d = 0; } + PARAMETRIZE { a = 3; b = 0; c = 1; d = 2; } + PARAMETRIZE { a = 3; b = 0; c = 2; d = 1; } + PARAMETRIZE { a = 3; b = 1; c = 0; d = 2; } + PARAMETRIZE { a = 3; b = 1; c = 2; d = 0; } + PARAMETRIZE { a = 3; b = 2; c = 0; d = 1; } + PARAMETRIZE { a = 3; b = 2; c = 1; d = 0; } + + order[a] = playerLeft; + order[b] = playerRight; + order[c] = opponentLeft; + order[d] = opponentRight; + + PASSES_RANDOMLY(1, 24, RNG_SPEED_TIE); + + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Speed(1); } + PLAYER(SPECIES_WYNAUT) { Speed(1); } + OPPONENT(SPECIES_WOBBUFFET) { Speed(1); } + OPPONENT(SPECIES_WYNAUT) { Speed(1); } + } WHEN { + TURN { MOVE(playerLeft, MOVE_SPLASH); MOVE(playerRight, MOVE_SPLASH); MOVE(opponentLeft, MOVE_SPLASH); MOVE(opponentRight, MOVE_SPLASH); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPLASH, order[0]); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPLASH, order[1]); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPLASH, order[2]); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPLASH, order[3]); + } +} + SINGLE_BATTLE_TEST("Critical hits occur at a 1/24 rate") { ASSUME(B_CRIT_CHANCE >= GEN_7); diff --git a/test/battle/move_effect/calm_mind.c b/test/battle/move_effect/calm_mind.c new file mode 100644 index 000000000..66c16361f --- /dev/null +++ b/test/battle/move_effect/calm_mind.c @@ -0,0 +1,4 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Calm Mind increases the user's Sp. Attack and Sp. Defense by 1 stage each"); diff --git a/test/battle/move_effect/camouflage.c b/test/battle/move_effect/camouflage.c new file mode 100644 index 000000000..a8728e311 --- /dev/null +++ b/test/battle/move_effect/camouflage.c @@ -0,0 +1,8 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Camouflage changes the type of the user based on battle environment"); +TO_DO_BATTLE_TEST("Camouflage changes the type of the user to Grass if Grassy Terrain is active"); +TO_DO_BATTLE_TEST("Camouflage changes the type of the user to Electric if Electric Terrain is active"); +TO_DO_BATTLE_TEST("Camouflage changes the type of the user to Psychic if Psychic Terrain is active"); +TO_DO_BATTLE_TEST("Camouflage changes the type of the user to Fairy if Misty Terrain is active"); diff --git a/test/battle/move_effect/captivate.c b/test/battle/move_effect/captivate.c new file mode 100644 index 000000000..0da58983c --- /dev/null +++ b/test/battle/move_effect/captivate.c @@ -0,0 +1,7 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Captivate decreases the target's Sp. Attack if they're opposite gender from the user"); +TO_DO_BATTLE_TEST("Captivate fails if the target and user share gender"); +TO_DO_BATTLE_TEST("Captivate fails if the target is genderless"); +TO_DO_BATTLE_TEST("Captivate fails if the user is genderless"); diff --git a/test/battle/move_effect/change_type_on_item.c b/test/battle/move_effect/change_type_on_item.c index 0bd181cf6..6365215a4 100644 --- a/test/battle/move_effect/change_type_on_item.c +++ b/test/battle/move_effect/change_type_on_item.c @@ -7,8 +7,7 @@ ASSUMPTIONS ASSUME(gMovesInfo[MOVE_TECHNO_BLAST].argument == HOLD_EFFECT_DRIVE); } - -SINGLE_BATTLE_TEST("Techno Blast changes the move type depending on the mask the user holds") +SINGLE_BATTLE_TEST("Techno Blast changes type depending on the drive the user holds") { u16 species; u16 item; @@ -29,3 +28,6 @@ SINGLE_BATTLE_TEST("Techno Blast changes the move type depending on the mask the MESSAGE("It's super effective!"); } } + +TO_DO_BATTLE_TEST("Judgement changes type depending on the plate the user holds"); +TO_DO_BATTLE_TEST("Multi Attack changes type depending on the memory the user holds"); diff --git a/test/battle/move_effect/charge.c b/test/battle/move_effect/charge.c new file mode 100644 index 000000000..e0a782b15 --- /dev/null +++ b/test/battle/move_effect/charge.c @@ -0,0 +1,9 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Charge doubles the damage of the next Electric move of the user"); +TO_DO_BATTLE_TEST("Charge's effect is removed regardless if the next move is Electric or not (Gen 3-8)"); +TO_DO_BATTLE_TEST("Charge's effect is kept until the user uses an Electric move (Gen 9+)"); +TO_DO_BATTLE_TEST("Charge's effect is removed if the user fails using an Electric move (Gen 9+)"); +TO_DO_BATTLE_TEST("Charge's effect does not stack with Electromorphosis"); +TO_DO_BATTLE_TEST("Charge's effect does not stack with Wind Power"); diff --git a/test/battle/move_effect/chilly_reception.c b/test/battle/move_effect/chilly_reception.c index f2c50b844..a52c83eb5 100644 --- a/test/battle/move_effect/chilly_reception.c +++ b/test/battle/move_effect/chilly_reception.c @@ -88,3 +88,4 @@ SINGLE_BATTLE_TEST("Chilly Reception changes the weather, even if the user canno } } +TO_DO_BATTLE_TEST("Chilly Reception doesn't announce its move if it's called by a different move"); diff --git a/test/battle/move_effect/clangorous_soul.c b/test/battle/move_effect/clangorous_soul.c new file mode 100644 index 000000000..17e57d7dd --- /dev/null +++ b/test/battle/move_effect/clangorous_soul.c @@ -0,0 +1,11 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Clangorous Soul raises the user's Attack by 1 stage"); +TO_DO_BATTLE_TEST("Clangorous Soul raises the user's Defense by 1 stage"); +TO_DO_BATTLE_TEST("Clangorous Soul raises the user's Sp. Attack by 1 stage"); +TO_DO_BATTLE_TEST("Clangorous Soul raises the user's Sp. Defense by 1 stage"); +TO_DO_BATTLE_TEST("Clangorous Soul raises the user's Speed by 1 stage"); +TO_DO_BATTLE_TEST("Clangorous Soul cuts the user's HP by 1/3"); +TO_DO_BATTLE_TEST("Clangorous Soul fails if Attack, Defense, Sp. Attack, Sp. Defense and Speed are all maxed out"); +TO_DO_BATTLE_TEST("Clangorous Soul fails if the user's HP is less or equal than 1/3"); diff --git a/test/battle/move_effect/coaching.c b/test/battle/move_effect/coaching.c new file mode 100644 index 000000000..2f50aceab --- /dev/null +++ b/test/battle/move_effect/coaching.c @@ -0,0 +1,8 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Coaching raises Attack and Defense of ally by 1 stage each"); +TO_DO_BATTLE_TEST("Coaching doesn't raise stats of the user"); +TO_DO_BATTLE_TEST("Coaching bypasses protection of allies"); +TO_DO_BATTLE_TEST("Coaching fails in single battles"); +TO_DO_BATTLE_TEST("Coaching fails if there's no ally"); diff --git a/test/battle/move_effect/coil.c b/test/battle/move_effect/coil.c new file mode 100644 index 000000000..ce9e8629a --- /dev/null +++ b/test/battle/move_effect/coil.c @@ -0,0 +1,6 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Coil raises the user's Attack by 1 stage"); +TO_DO_BATTLE_TEST("Coil raises the user's Defense by 1 stage"); +TO_DO_BATTLE_TEST("Coil raises the user's Accuracy by 1 stage"); diff --git a/test/battle/move_effect/conversion.c b/test/battle/move_effect/conversion.c new file mode 100644 index 000000000..ac863cf2b --- /dev/null +++ b/test/battle/move_effect/conversion.c @@ -0,0 +1,10 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Conversion changes the user's types to the target's current types (Gen 1)"); +TO_DO_BATTLE_TEST("Conversion changes the user's types randomly to one of the user's move (Gen 2-5)"); +TO_DO_BATTLE_TEST("Conversion ignores moves that share types with the user (Gen 2-5)"); +TO_DO_BATTLE_TEST("Conversion fails if all the user's moves share types with the user (Gen 2-5)"); +TO_DO_BATTLE_TEST("Conversion changes the user's types to the one in the user's first slot (Gen 6+)"); +TO_DO_BATTLE_TEST("Conversion can read the user's first move slot even if that move cannot be selected (Gen 6+)"); //Eg. Disable +TO_DO_BATTLE_TEST("Conversion can change the user's types to Conversion's type"); diff --git a/test/battle/move_effect/conversion_2.c b/test/battle/move_effect/conversion_2.c new file mode 100644 index 000000000..2e81212ef --- /dev/null +++ b/test/battle/move_effect/conversion_2.c @@ -0,0 +1,14 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Conversion 2 randomly changes the type of the user to a type that resists the last move that hit the user (Gen 3-4)"); +TO_DO_BATTLE_TEST("Conversion 2 randomly changes the type of the user to a type that resists the last move used by the target (Gen 5+)"); +TO_DO_BATTLE_TEST("Conversion 2's type change considers the type of moves called by other moves"); +TO_DO_BATTLE_TEST("Conversion 2's type change considers dynamic type moves"); // Eg. Weather Ball +TO_DO_BATTLE_TEST("Conversion 2's type change considers move types changed by Normalize and Electrify"); +TO_DO_BATTLE_TEST("Conversion 2's type change considers move types changed by Normalize"); +TO_DO_BATTLE_TEST("Conversion 2's type change considers Struggle to be Normal type (Gen 3-4)"); +TO_DO_BATTLE_TEST("Conversion 2 fails if the move used is of typeless damage (Gen 5+)"); +TO_DO_BATTLE_TEST("Conversion 2's type change considers status moves (Gen 5+)"); +TO_DO_BATTLE_TEST("Conversion 2's type change considers Inverse Battles"); +TO_DO_BATTLE_TEST("Conversion 2 fails if the move used is Stellar Type"); diff --git a/test/battle/move_effect/copycat.c b/test/battle/move_effect/copycat.c new file mode 100644 index 000000000..cdc164cd0 --- /dev/null +++ b/test/battle/move_effect/copycat.c @@ -0,0 +1,37 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Copycat causes the user to use the last move used in battle"); +TO_DO_BATTLE_TEST("Copycat can call the user's last move used if it was the last move used in battle"); +TO_DO_BATTLE_TEST("Copycat fails if no move has been made"); +TO_DO_BATTLE_TEST("Copycat chooses a target at random if the copied move wasn't the user's"); +TO_DO_BATTLE_TEST("Copycat can copy moves regardless if they failed or not"); //Has "X used move!" +TO_DO_BATTLE_TEST("Copycat fails if the last move used is a Z-Move"); + +// Gen 4 +TO_DO_BATTLE_TEST("Copycat can only copy charging moves after it has been executed (Gen 4)"); +TO_DO_BATTLE_TEST("Copycat can only copy recharging moves after it has been executed (Gen 4)"); +TO_DO_BATTLE_TEST("Copycat cannot copy Bide's final turn (Gen 4)"); +TO_DO_BATTLE_TEST("Copycat copies other calling moves instead of the move they called (Gen 4)"); +TO_DO_BATTLE_TEST("Copycat copies moves called by other calling moves instead of the calling move if they are executed in a second turn (Gen 5+)"); //Eg. Dig + +// Gen 5+ +TO_DO_BATTLE_TEST("Copycat can copy charging moves in both the charging and the executing turn (Gen 5+)"); +TO_DO_BATTLE_TEST("Copycat ignores the recharging turn of recharging moves (Gen 5+)"); +TO_DO_BATTLE_TEST("Copycat can copy Bide on all turns"); +TO_DO_BATTLE_TEST("Copycat copies moves called by other calling moves instead of the calling move (Gen 5+)"); + +DOUBLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon can have their base moves copied by Copycat") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_WYNAUT); + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WYNAUT); + } WHEN { + TURN { MOVE(playerLeft, MOVE_TRICK_ROOM, gimmick: GIMMICK_DYNAMAX, target: opponentLeft); MOVE(playerRight, MOVE_COPYCAT, target: opponentLeft); } + } SCENE { + MESSAGE("Wobbuffet used Max Guard!"); + MESSAGE("Wynaut used Trick Room!"); + } +} diff --git a/test/battle/move_effect/corrosive_gas.c b/test/battle/move_effect/corrosive_gas.c index 714702703..f6a9c738e 100644 --- a/test/battle/move_effect/corrosive_gas.c +++ b/test/battle/move_effect/corrosive_gas.c @@ -117,3 +117,6 @@ DOUBLE_BATTLE_TEST("Corrosive Gas destroys foes and ally's items if they have on EXPECT_EQ(opponentRight->item, ITEM_NONE); } } + +TO_DO_BATTLE_TEST("Corrosive Gas doesn't destroy the item of a Pokemon behind a Substitute"); +TO_DO_BATTLE_TEST("Corrosive Gas doesn't destroy items if they change the Pokémon's form"); // Giratina, Genesect, Silvally, Zacian, Zamazenta. Bulbapedia hasn't confirmed Arceus or Ogerpon, but it's a safe assumption that they will also fail. diff --git a/test/battle/move_effect/cosmic_power.c b/test/battle/move_effect/cosmic_power.c new file mode 100644 index 000000000..8680e9f28 --- /dev/null +++ b/test/battle/move_effect/cosmic_power.c @@ -0,0 +1,4 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Cosmic Power increases the user's Defense and Sp. Defense by 1 stage each"); diff --git a/test/battle/move_effect/counter.c b/test/battle/move_effect/counter.c new file mode 100644 index 000000000..f4d3a7811 --- /dev/null +++ b/test/battle/move_effect/counter.c @@ -0,0 +1,22 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Counter will do twice as much damage received from the opponent"); +TO_DO_BATTLE_TEST("Counter cannot affect ally Pokémon"); +TO_DO_BATTLE_TEST("Counter hits the last opponent that hit the user"); //Doubles + +// Gen 1 +TO_DO_BATTLE_TEST("Counter can only counter Normal and Fighting-type moves (Gen 1)"); +TO_DO_BATTLE_TEST("Counter can hit ghost-type Pokémon (Gen 1)"); +TO_DO_BATTLE_TEST("Counter can return damage dealt to a substitute (Gen 1)"); + +// Gen 2-3 +TO_DO_BATTLE_TEST("Counter can counter Hidden Power regardless of type (Gen 2-3)"); + +// Gen 2+ +TO_DO_BATTLE_TEST("Counter can only counter physical moves (Gen 2+)"); +TO_DO_BATTLE_TEST("Counter cannot hit ghost-type Pokémon (Gen 2+)"); +TO_DO_BATTLE_TEST("Counter cannot return damage dealt to a substitute (Gen 2+)"); + +// Triple Battles required to test +//TO_DO_BATTLE_TEST("Counter can hit non-adjacent opponents if they were the last Pokémon to hit the user"); diff --git a/test/battle/move_effect/court_change.c b/test/battle/move_effect/court_change.c index a5e3e0561..b9be19db7 100644 --- a/test/battle/move_effect/court_change.c +++ b/test/battle/move_effect/court_change.c @@ -78,7 +78,7 @@ DOUBLE_BATTLE_TEST("Court Change swaps entry hazards used by the player") } } -DOUBLE_BATTLE_TEST("Court Change used by the player swaps Mist, Safeguard, Lucky Chant, Reflect, Light Screen, Tailwind") +DOUBLE_BATTLE_TEST("Court Change used by the player swaps Mist, Safeguard, Aurora Veil, Reflect, Light Screen, Tailwind") { GIVEN { PLAYER(SPECIES_WYNAUT); @@ -88,8 +88,8 @@ DOUBLE_BATTLE_TEST("Court Change used by the player swaps Mist, Safeguard, Lucky OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { - TURN { MOVE(opponentLeft, MOVE_MIST); MOVE(opponentRight, MOVE_SAFEGUARD); } - TURN { MOVE(opponentLeft, MOVE_LUCKY_CHANT); MOVE(opponentRight, MOVE_REFLECT); } + TURN { MOVE(playerLeft, MOVE_SNOWSCAPE); MOVE(opponentLeft, MOVE_MIST); MOVE(opponentRight, MOVE_SAFEGUARD); } + TURN { MOVE(opponentLeft, MOVE_AURORA_VEIL); MOVE(opponentRight, MOVE_REFLECT); } TURN { MOVE(opponentLeft, MOVE_LIGHT_SCREEN); MOVE(opponentRight, MOVE_TAILWIND); } TURN { MOVE(playerLeft, MOVE_COURT_CHANGE); } TURN { } @@ -97,9 +97,10 @@ DOUBLE_BATTLE_TEST("Court Change used by the player swaps Mist, Safeguard, Lucky TURN { } TURN { } } SCENE { + MESSAGE("Wynaut used Snowscape!"); MESSAGE("Foe Wobbuffet used Mist!"); MESSAGE("Foe Wobbuffet used Safeguard!"); - MESSAGE("Foe Wobbuffet used Lucky Chant!"); + MESSAGE("Foe Wobbuffet used Aurora Veil!"); MESSAGE("Foe Wobbuffet used Reflect!"); MESSAGE("Foe Wobbuffet used Light Screen!"); MESSAGE("Foe Wobbuffet used Tailwind!"); @@ -109,13 +110,13 @@ DOUBLE_BATTLE_TEST("Court Change used by the player swaps Mist, Safeguard, Lucky MESSAGE("Ally's Mist wore off!"); MESSAGE("Ally's party is no longer protected by Safeguard!"); MESSAGE("Ally's Reflect wore off!"); - MESSAGE("Your team's Lucky Chant wore off!"); + MESSAGE("Ally's Aurora Veil wore off!"); MESSAGE("Your team's tailwind petered out!"); MESSAGE("Ally's Light Screen wore off!"); } } -DOUBLE_BATTLE_TEST("Court Change used by the opponent swaps Mist, Safeguard, Lucky Chant, Reflect, Light Screen, Tailwind") +DOUBLE_BATTLE_TEST("Court Change used by the opponent swaps Mist, Safeguard, Aurora Veil, Reflect, Light Screen, Tailwind") { GIVEN { PLAYER(SPECIES_WOBBUFFET); @@ -125,8 +126,8 @@ DOUBLE_BATTLE_TEST("Court Change used by the opponent swaps Mist, Safeguard, Luc OPPONENT(SPECIES_WYNAUT); OPPONENT(SPECIES_WYNAUT); } WHEN { - TURN { MOVE(playerLeft, MOVE_MIST); MOVE(playerRight, MOVE_SAFEGUARD); } - TURN { MOVE(playerLeft, MOVE_LUCKY_CHANT); MOVE(playerRight, MOVE_REFLECT); } + TURN { MOVE(opponentLeft, MOVE_SNOWSCAPE); MOVE(playerLeft, MOVE_MIST); MOVE(playerRight, MOVE_SAFEGUARD); } + TURN { MOVE(playerLeft, MOVE_AURORA_VEIL); MOVE(playerRight, MOVE_REFLECT); } TURN { MOVE(playerLeft, MOVE_LIGHT_SCREEN); MOVE(playerRight, MOVE_TAILWIND); } TURN { MOVE(opponentLeft, MOVE_COURT_CHANGE); } TURN { } @@ -136,7 +137,7 @@ DOUBLE_BATTLE_TEST("Court Change used by the opponent swaps Mist, Safeguard, Luc } SCENE { MESSAGE("Wobbuffet used Mist!"); MESSAGE("Wobbuffet used Safeguard!"); - MESSAGE("Wobbuffet used Lucky Chant!"); + MESSAGE("Wobbuffet used Aurora Veil!"); MESSAGE("Wobbuffet used Reflect!"); MESSAGE("Wobbuffet used Light Screen!"); MESSAGE("Wobbuffet used Tailwind!"); @@ -146,8 +147,10 @@ DOUBLE_BATTLE_TEST("Court Change used by the opponent swaps Mist, Safeguard, Luc MESSAGE("Foe's Mist wore off!"); MESSAGE("Foe's party is no longer protected by Safeguard!"); MESSAGE("Foe's Reflect wore off!"); - MESSAGE("The opposing team's Lucky Chant wore off!"); + MESSAGE("Foe's Aurora Veil wore off!"); MESSAGE("The opposing team's tailwind petered out!"); MESSAGE("Foe's Light Screen wore off!"); } } + +TO_DO_BATTLE_TEST("Court Change used by the player swaps G-Max Steelsurge, G-Max Vine Lash, G-Max Wildfire, G-Max Cannonade"); diff --git a/test/battle/move_effect/fury_cutter.c b/test/battle/move_effect/fury_cutter.c index cf3871964..b193882d3 100644 --- a/test/battle/move_effect/fury_cutter.c +++ b/test/battle/move_effect/fury_cutter.c @@ -36,3 +36,27 @@ SINGLE_BATTLE_TEST("Fury Cutter power doubles with each use, up to 160 power") EXPECT_EQ(damage[maxTurns - 2], damage[maxTurns - 1]); } } + +SINGLE_BATTLE_TEST("Fury Cutter counter is the same for both hits of Parental Bond") +{ + s16 damage[4]; + + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_PARENTAL_BOND); } + OPPONENT(SPECIES_REGIROCK); + } WHEN { + TURN { MOVE(player, MOVE_FURY_CUTTER); } + TURN { MOVE(player, MOVE_FURY_CUTTER); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_FURY_CUTTER, player); + HP_BAR(opponent, captureDamage: &damage[0]); + HP_BAR(opponent, captureDamage: &damage[1]); + ANIMATION(ANIM_TYPE_MOVE, MOVE_FURY_CUTTER, player); + HP_BAR(opponent, captureDamage: &damage[2]); + HP_BAR(opponent, captureDamage: &damage[3]); + } THEN { + EXPECT_MUL_EQ(damage[0], B_PARENTAL_BOND_DMG >= GEN_7 ? UQ_4_12(0.25) : UQ_4_12(0.5), damage[1]); + EXPECT_MUL_EQ(damage[2], B_PARENTAL_BOND_DMG >= GEN_7 ? UQ_4_12(0.25) : UQ_4_12(0.5), damage[3]); + EXPECT_NE(damage[0], damage[2]); + } +} diff --git a/test/battle/move_effect/heal_bell.c b/test/battle/move_effect/heal_bell.c index 7c01d0cfd..8bd6c1f45 100644 --- a/test/battle/move_effect/heal_bell.c +++ b/test/battle/move_effect/heal_bell.c @@ -88,7 +88,7 @@ SINGLE_BATTLE_TEST("Heal Bell cures inactive soundproof Pokemon") SINGLE_BATTLE_TEST("Heal Bell cures a soundproof user") { - ASSUME(B_HEAL_BELL_SOUNDPROOF == GEN_5 || B_HEAL_BELL_SOUNDPROOF >= GEN_9); + ASSUME(B_HEAL_BELL_SOUNDPROOF == GEN_5 || B_HEAL_BELL_SOUNDPROOF >= GEN_8); GIVEN { PLAYER(SPECIES_EXPLOUD) { Ability(ABILITY_SOUNDPROOF); Status1(STATUS1_POISON); } diff --git a/test/battle/move_effect/reflect_type.c b/test/battle/move_effect/reflect_type.c index b75ffc0b0..32ed9520c 100644 --- a/test/battle/move_effect/reflect_type.c +++ b/test/battle/move_effect/reflect_type.c @@ -123,9 +123,9 @@ SINGLE_BATTLE_TEST("Reflect Type copies a target's dual types") ANIMATION(ANIM_TYPE_MOVE, MOVE_REFLECT_TYPE, player); MESSAGE("Arcanine's type changed to match the Foe Poliwrath's!"); } THEN { - EXPECT_EQ(player->type1, TYPE_WATER); - EXPECT_EQ(player->type2, TYPE_FIGHTING); - EXPECT_EQ(player->type3, TYPE_MYSTERY); + EXPECT_EQ(player->types[0], TYPE_WATER); + EXPECT_EQ(player->types[1], TYPE_FIGHTING); + EXPECT_EQ(player->types[2], TYPE_MYSTERY); } } @@ -145,13 +145,13 @@ SINGLE_BATTLE_TEST("Reflect Type copies a target's pure type") ANIMATION(ANIM_TYPE_MOVE, MOVE_REFLECT_TYPE, player); MESSAGE("Arcanine's type changed to match the Foe Sudowoodo's!"); } THEN { - EXPECT_EQ(player->type1, TYPE_ROCK); - EXPECT_EQ(player->type2, TYPE_ROCK); - EXPECT_EQ(player->type3, TYPE_MYSTERY); + EXPECT_EQ(player->types[0], TYPE_ROCK); + EXPECT_EQ(player->types[1], TYPE_ROCK); + EXPECT_EQ(player->types[2], TYPE_MYSTERY); } } -SINGLE_BATTLE_TEST("Reflect Type defaults to Normal type for the user's type1 and type2 if the target only has a 3rd type") +SINGLE_BATTLE_TEST("Reflect Type defaults to Normal type for the user's types[0] and types[1] if the target only has a 3rd type") { ASSUME(gSpeciesInfo[SPECIES_WOBBUFFET].types[0] == TYPE_PSYCHIC); ASSUME(gSpeciesInfo[SPECIES_WOBBUFFET].types[1] == TYPE_PSYCHIC); @@ -179,8 +179,8 @@ SINGLE_BATTLE_TEST("Reflect Type defaults to Normal type for the user's type1 an ANIMATION(ANIM_TYPE_MOVE, MOVE_REFLECT_TYPE, player); MESSAGE("Wobbuffet's type changed to match the Foe Arcanine's!"); } THEN { - EXPECT_EQ(player->type1, TYPE_NORMAL); - EXPECT_EQ(player->type2, TYPE_NORMAL); - EXPECT_EQ(player->type3, TYPE_GRASS); + EXPECT_EQ(player->types[0], TYPE_NORMAL); + EXPECT_EQ(player->types[1], TYPE_NORMAL); + EXPECT_EQ(player->types[2], TYPE_GRASS); } } diff --git a/test/battle/move_effect/sleep_talk.c b/test/battle/move_effect/sleep_talk.c new file mode 100644 index 000000000..0a42eb90e --- /dev/null +++ b/test/battle/move_effect/sleep_talk.c @@ -0,0 +1,93 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(gMovesInfo[MOVE_SLEEP_TALK].effect == EFFECT_SLEEP_TALK); + ASSUME(gMovesInfo[MOVE_RAZOR_WIND].sleepTalkBanned == TRUE); + ASSUME(gMovesInfo[MOVE_FLY].sleepTalkBanned == TRUE); + ASSUME(gMovesInfo[MOVE_DIG].sleepTalkBanned == TRUE); +} + +SINGLE_BATTLE_TEST("Sleep Talk fails if not asleep") +{ + u32 status; + PARAMETRIZE { status = STATUS1_SLEEP; } + PARAMETRIZE { status = STATUS1_NONE; } + + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Status1(status); Moves(MOVE_SLEEP_TALK, MOVE_TACKLE, MOVE_POUND, MOVE_SCRATCH); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_SLEEP_TALK); } + } SCENE { + if (status == STATUS1_SLEEP) { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SLEEP_TALK, player); + NOT MESSAGE("But it failed!"); + } + else { + NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_SLEEP_TALK, player); + MESSAGE("But it failed!"); + } + } +} + + +SINGLE_BATTLE_TEST("Sleep Talk works if user has Comatose") +{ + + GIVEN { + PLAYER(SPECIES_KOMALA) { Moves(MOVE_SLEEP_TALK, MOVE_TACKLE, MOVE_POUND, MOVE_SCRATCH); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_SLEEP_TALK); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SLEEP_TALK, player); + NOT MESSAGE("But it failed!"); + } +} + +SINGLE_BATTLE_TEST("Sleep Talk fails if no moves work") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_SLEEP); Moves(MOVE_SLEEP_TALK, MOVE_RAZOR_WIND, MOVE_FLY, MOVE_DIG); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_SLEEP_TALK); } + } SCENE { + NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_SLEEP_TALK, player); + MESSAGE("But it failed!"); + } +} + +SINGLE_BATTLE_TEST("Sleep Talk can still use moves with no PP") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_SLEEP); MovesWithPP({MOVE_SLEEP_TALK, 10}, {MOVE_TACKLE, 0}, {MOVE_FLY, 10}, {MOVE_DIG, 10}); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_SLEEP_TALK); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SLEEP_TALK, player); + NOT MESSAGE("But it failed!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE); + } +} + +SINGLE_BATTLE_TEST("Sleep Talk can use moves while choiced into Sleep Talk") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_CHOICE_BAND); Status1(STATUS1_SLEEP); Moves(MOVE_SLEEP_TALK, MOVE_TACKLE, MOVE_FLY, MOVE_DIG); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_SLEEP_TALK); } + TURN { MOVE(player, MOVE_SLEEP_TALK); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SLEEP_TALK, player); + NOT MESSAGE("But it failed!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SLEEP_TALK, player); + NOT MESSAGE("But it failed!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE); + } +} diff --git a/test/battle/terrain/electric.c b/test/battle/terrain/electric.c index 2227afdcd..c39bfbbb7 100644 --- a/test/battle/terrain/electric.c +++ b/test/battle/terrain/electric.c @@ -34,7 +34,7 @@ SINGLE_BATTLE_TEST("Electric Terrain activates Electric Seed and Mimicry") ABILITY_POPUP(opponent); MESSAGE("Foe Stunfisk's type changed to Electric!"); } THEN { - EXPECT_EQ(gBattleMons[B_POSITION_OPPONENT_LEFT].type1, TYPE_ELECTRIC); + EXPECT_EQ(gBattleMons[B_POSITION_OPPONENT_LEFT].types[0], TYPE_ELECTRIC); } } diff --git a/test/battle/terrain/grassy.c b/test/battle/terrain/grassy.c index 862c9052f..5840f0310 100644 --- a/test/battle/terrain/grassy.c +++ b/test/battle/terrain/grassy.c @@ -30,7 +30,7 @@ SINGLE_BATTLE_TEST("Grassy Terrain activates Grassy Seed and Mimicry") ABILITY_POPUP(opponent); MESSAGE("Foe Stunfisk's type changed to Grass!"); } THEN { - EXPECT_EQ(gBattleMons[B_POSITION_OPPONENT_LEFT].type1, TYPE_GRASS); + EXPECT_EQ(gBattleMons[B_POSITION_OPPONENT_LEFT].types[0], TYPE_GRASS); } } diff --git a/test/battle/terrain/misty.c b/test/battle/terrain/misty.c index cd89b2d9a..fbf04fcba 100644 --- a/test/battle/terrain/misty.c +++ b/test/battle/terrain/misty.c @@ -34,7 +34,7 @@ SINGLE_BATTLE_TEST("Misty Terrain activates Misty Seed and Mimicry") ABILITY_POPUP(opponent); MESSAGE("Foe Stunfisk's type changed to Fairy!"); } THEN { - EXPECT_EQ(gBattleMons[B_POSITION_OPPONENT_LEFT].type1, TYPE_FAIRY); + EXPECT_EQ(gBattleMons[B_POSITION_OPPONENT_LEFT].types[0], TYPE_FAIRY); } } diff --git a/test/battle/terrain/psychic.c b/test/battle/terrain/psychic.c index 0c13122fa..44a89598d 100644 --- a/test/battle/terrain/psychic.c +++ b/test/battle/terrain/psychic.c @@ -33,7 +33,7 @@ SINGLE_BATTLE_TEST("Psychic Terrain activates Psychic Seed and Mimicry") ABILITY_POPUP(opponent); MESSAGE("Foe Stunfisk's type changed to Psychic!"); } THEN { - EXPECT_EQ(gBattleMons[B_POSITION_OPPONENT_LEFT].type1, TYPE_PSYCHIC); + EXPECT_EQ(gBattleMons[B_POSITION_OPPONENT_LEFT].types[0], TYPE_PSYCHIC); } } diff --git a/test/battle/trainer_control.h b/test/battle/trainer_control.h index 994e7d25d..faea5b399 100644 --- a/test/battle/trainer_control.h +++ b/test/battle/trainer_control.h @@ -2,7 +2,7 @@ // DO NOT MODIFY THIS FILE! It is auto-generated from test/battle/trainer_control.party // // If you want to modify this file set COMPETITIVE_PARTY_SYNTAX to FALSE -// in include/config.h and remove this notice. +// in include/config/general.h and remove this notice. // Use sed -i '/^#line/d' 'test/battle/trainer_control.h' to remove #line markers. // diff --git a/test/species.c b/test/species.c index d09f1e3eb..2d702b6c4 100644 --- a/test/species.c +++ b/test/species.c @@ -116,12 +116,7 @@ TEST("No species has two evolutions that use the evolution tracker") for (i = 0; evolutions[i].method != EVOLUTIONS_END; i++) { if (evolutions[i].method == EVO_USE_MOVE_TWENTY_TIMES - #ifdef EVO_DEFEAT_WITH_ITEM - || evolutions[i].method == EVO_DEFEAT_WITH_ITEM - #endif //EVO_DEFEAT_WITH_ITEM - #ifdef EVO_OVERWORLD_STEPS - || evolutions[i].method == EVO_OVERWORLD_STEPS - #endif //EVO_OVERWORLD_STEPS + || evolutions[i].method == EVO_DEFEAT_THREE_WITH_ITEM ) evolutionTrackerEvolutions++; diff --git a/test/test_runner.c b/test/test_runner.c index 4f36549d1..3e8ef696d 100644 --- a/test/test_runner.c +++ b/test/test_runner.c @@ -120,6 +120,7 @@ top: MoveSaveBlocks_ResetHeap(); ClearSav1(); ClearSav2(); + ClearSav3(); gIntrTable[7] = Intr_Timer2;