2024-06-22 21:25:40 +01:00
# include "global.h"
# include "test/battle.h"
# include "constants/battle_z_move_effects.h"
// Basic Functionality
SINGLE_BATTLE_TEST ( " (Z-MOVE) Z-Moves do not retain priority " )
{
GIVEN {
ASSUME ( gMovesInfo [ MOVE_QUICK_ATTACK ] . type = = TYPE_NORMAL ) ;
PLAYER ( SPECIES_WOBBUFFET ) { Item ( ITEM_NORMALIUM_Z ) ; }
OPPONENT ( SPECIES_WOBBUFFET ) ;
} WHEN {
2024-08-15 03:48:20 +01:00
TURN { MOVE ( opponent , MOVE_TACKLE ) ;
2024-06-22 21:25:40 +01:00
MOVE ( player , MOVE_QUICK_ATTACK , gimmick : GIMMICK_Z_MOVE ) ; }
} SCENE {
ANIMATION ( ANIM_TYPE_MOVE , MOVE_TACKLE , opponent ) ;
ANIMATION ( ANIM_TYPE_GENERAL , B_ANIM_ZMOVE_ACTIVATE , player ) ;
ANIMATION ( ANIM_TYPE_MOVE , MOVE_BREAKNECK_BLITZ , player ) ;
}
}
SINGLE_BATTLE_TEST ( " (Z-MOVE) Z-Moves are not affected by -ate abilities " )
{
GIVEN {
ASSUME ( gMovesInfo [ MOVE_TACKLE ] . type = = TYPE_NORMAL ) ;
ASSUME ( gSpeciesInfo [ SPECIES_SWELLOW ] . types [ 1 ] = = TYPE_FLYING ) ;
PLAYER ( SPECIES_AURORUS ) { Ability ( ABILITY_REFRIGERATE ) ; Item ( ITEM_NORMALIUM_Z ) ; }
OPPONENT ( SPECIES_SWELLOW ) ;
} WHEN {
TURN { MOVE ( player , MOVE_TACKLE , gimmick : GIMMICK_Z_MOVE ) ; }
} SCENE {
ANIMATION ( ANIM_TYPE_GENERAL , B_ANIM_ZMOVE_ACTIVATE , player ) ;
ANIMATION ( ANIM_TYPE_MOVE , MOVE_BREAKNECK_BLITZ , player ) ;
NOT { MESSAGE ( " It's super effective! " ) ; }
}
}
SINGLE_BATTLE_TEST ( " (Z-MOVE) Z-Moves are affected by Ion Deluge " )
{
GIVEN {
ASSUME ( gMovesInfo [ MOVE_TACKLE ] . type = = TYPE_NORMAL ) ;
ASSUME ( gMovesInfo [ MOVE_ION_DELUGE ] . effect = = EFFECT_ION_DELUGE ) ;
PLAYER ( SPECIES_WOBBUFFET ) { Item ( ITEM_NORMALIUM_Z ) ; }
OPPONENT ( SPECIES_SWELLOW ) ;
} WHEN {
TURN { MOVE ( opponent , MOVE_ION_DELUGE ) ; MOVE ( player , MOVE_TACKLE , gimmick : GIMMICK_Z_MOVE ) ; }
} SCENE {
ANIMATION ( ANIM_TYPE_GENERAL , B_ANIM_ZMOVE_ACTIVATE , player ) ;
ANIMATION ( ANIM_TYPE_MOVE , MOVE_BREAKNECK_BLITZ , player ) ;
MESSAGE ( " It's super effective! " ) ;
}
}
SINGLE_BATTLE_TEST ( " (Z-MOVE) Z-Moves deal 1/4 damage through protect " , s16 damage )
{
bool32 protected ;
PARAMETRIZE { protected = TRUE ; }
PARAMETRIZE { protected = FALSE ; }
GIVEN {
ASSUME ( gMovesInfo [ MOVE_TACKLE ] . type = = TYPE_NORMAL ) ;
ASSUME ( gMovesInfo [ MOVE_PROTECT ] . effect = = EFFECT_PROTECT ) ;
PLAYER ( SPECIES_WOBBUFFET ) { Item ( ITEM_NORMALIUM_Z ) ; }
OPPONENT ( SPECIES_WOBBUFFET ) ;
} WHEN {
if ( protected )
TURN { MOVE ( player , MOVE_TACKLE , gimmick : GIMMICK_Z_MOVE ) ; MOVE ( opponent , MOVE_PROTECT ) ; }
else
TURN { MOVE ( player , MOVE_TACKLE , gimmick : GIMMICK_Z_MOVE ) ; }
} SCENE {
HP_BAR ( opponent , captureDamage : & results [ i ] . damage ) ;
} FINALLY {
EXPECT_MUL_EQ ( results [ 0 ] . damage , Q_4_12 ( 4 ) , results [ 1 ] . damage ) ;
}
}
// Status Z-Effects
SINGLE_BATTLE_TEST ( " (Z-MOVE) Z_EFFECT_RESET_STATS clears a battler's negative stat stages " )
{
GIVEN {
ASSUME ( gMovesInfo [ MOVE_LEECH_SEED ] . zMove . effect = = Z_EFFECT_RESET_STATS ) ;
PLAYER ( SPECIES_WOBBUFFET ) { Item ( ITEM_GRASSIUM_Z ) ; }
OPPONENT ( SPECIES_WOBBUFFET ) ;
} WHEN {
TURN { MOVE ( player , MOVE_SWORDS_DANCE ) ; MOVE ( opponent , MOVE_SCREECH ) ; }
TURN { MOVE ( player , MOVE_LEECH_SEED , gimmick : GIMMICK_Z_MOVE ) ; }
} SCENE {
ANIMATION ( ANIM_TYPE_MOVE , MOVE_SWORDS_DANCE , player ) ;
ANIMATION ( ANIM_TYPE_GENERAL , B_ANIM_ZMOVE_ACTIVATE , player ) ;
ANIMATION ( ANIM_TYPE_MOVE , MOVE_LEECH_SEED , player ) ;
} THEN {
EXPECT_EQ ( player - > statStages [ STAT_ATK ] , DEFAULT_STAT_STAGE + 2 ) ;
EXPECT_EQ ( player - > statStages [ STAT_DEF ] , DEFAULT_STAT_STAGE ) ;
}
}
SINGLE_BATTLE_TEST ( " (Z-MOVE) Z_EFFECT_ALL_STATS_UP raises all of a battler's stat stages by one " )
{
GIVEN {
ASSUME ( gMovesInfo [ MOVE_CELEBRATE ] . type = = TYPE_NORMAL ) ;
ASSUME ( gMovesInfo [ MOVE_CELEBRATE ] . zMove . effect = = Z_EFFECT_ALL_STATS_UP_1 ) ;
PLAYER ( SPECIES_WOBBUFFET ) { Item ( ITEM_NORMALIUM_Z ) ; }
OPPONENT ( SPECIES_WOBBUFFET ) ;
} WHEN {
TURN { MOVE ( player , MOVE_CELEBRATE , gimmick : GIMMICK_Z_MOVE ) ; }
} SCENE {
ANIMATION ( ANIM_TYPE_GENERAL , B_ANIM_ZMOVE_ACTIVATE , player ) ;
ANIMATION ( ANIM_TYPE_MOVE , MOVE_CELEBRATE , player ) ;
} THEN {
EXPECT_EQ ( player - > statStages [ STAT_ATK ] , DEFAULT_STAT_STAGE + 1 ) ;
EXPECT_EQ ( player - > statStages [ STAT_DEF ] , DEFAULT_STAT_STAGE + 1 ) ;
EXPECT_EQ ( player - > statStages [ STAT_SPATK ] , DEFAULT_STAT_STAGE + 1 ) ;
EXPECT_EQ ( player - > statStages [ STAT_SPDEF ] , DEFAULT_STAT_STAGE + 1 ) ;
EXPECT_EQ ( player - > statStages [ STAT_SPEED ] , DEFAULT_STAT_STAGE + 1 ) ;
}
}
SINGLE_BATTLE_TEST ( " (Z-MOVE) Z_EFFECT_BOOST_CRITS raises a battler's critical hit ratio " )
{
PASSES_RANDOMLY ( 1 , 2 , RNG_CRITICAL_HIT ) ;
GIVEN {
ASSUME ( gMovesInfo [ MOVE_FORESIGHT ] . type = = TYPE_NORMAL ) ;
ASSUME ( gMovesInfo [ MOVE_FORESIGHT ] . zMove . effect = = Z_EFFECT_BOOST_CRITS ) ;
PLAYER ( SPECIES_WOBBUFFET ) { Item ( ITEM_NORMALIUM_Z ) ; }
OPPONENT ( SPECIES_WOBBUFFET ) ;
} WHEN {
TURN { MOVE ( player , MOVE_FORESIGHT , gimmick : GIMMICK_Z_MOVE ) ; }
TURN { MOVE ( player , MOVE_TACKLE ) ; }
} SCENE {
ANIMATION ( ANIM_TYPE_GENERAL , B_ANIM_ZMOVE_ACTIVATE , player ) ;
ANIMATION ( ANIM_TYPE_MOVE , MOVE_FORESIGHT , player ) ;
ANIMATION ( ANIM_TYPE_MOVE , MOVE_TACKLE , player ) ;
MESSAGE ( " A critical hit! " ) ;
}
}
DOUBLE_BATTLE_TEST ( " (Z-MOVE) Z_EFFECT_FOLLOW_ME redirects attacks to the user " )
{
GIVEN {
ASSUME ( gMovesInfo [ MOVE_DESTINY_BOND ] . type = = TYPE_GHOST ) ;
ASSUME ( gMovesInfo [ MOVE_DESTINY_BOND ] . zMove . effect = = Z_EFFECT_FOLLOW_ME ) ;
PLAYER ( SPECIES_WOBBUFFET ) { Item ( ITEM_GHOSTIUM_Z ) ; }
PLAYER ( SPECIES_WYNAUT ) ;
OPPONENT ( SPECIES_WOBBUFFET ) ;
OPPONENT ( SPECIES_WYNAUT ) ;
} WHEN {
TURN { MOVE ( playerLeft , MOVE_DESTINY_BOND , gimmick : GIMMICK_Z_MOVE ) ;
MOVE ( opponentLeft , MOVE_TACKLE , target : playerRight ) ; }
} SCENE {
ANIMATION ( ANIM_TYPE_GENERAL , B_ANIM_ZMOVE_ACTIVATE , playerLeft ) ;
ANIMATION ( ANIM_TYPE_MOVE , MOVE_DESTINY_BOND , playerLeft ) ;
ANIMATION ( ANIM_TYPE_MOVE , MOVE_TACKLE , opponentLeft ) ;
NOT { HP_BAR ( playerRight ) ; }
HP_BAR ( playerLeft ) ;
}
}
SINGLE_BATTLE_TEST ( " (Z-MOVE) Z_EFFECT_RESTORE_REPLACEMENT_HP fully heals the replacement battler's HP " )
{
GIVEN {
ASSUME ( gMovesInfo [ MOVE_PARTING_SHOT ] . type = = TYPE_DARK ) ;
ASSUME ( gMovesInfo [ MOVE_PARTING_SHOT ] . zMove . effect = = Z_EFFECT_RESTORE_REPLACEMENT_HP ) ;
PLAYER ( SPECIES_WOBBUFFET ) { Item ( ITEM_DARKINIUM_Z ) ; }
PLAYER ( SPECIES_WYNAUT ) { HP ( 1 ) ; }
OPPONENT ( SPECIES_WOBBUFFET ) ;
} WHEN {
TURN { MOVE ( player , MOVE_PARTING_SHOT , gimmick : GIMMICK_Z_MOVE ) ; SEND_OUT ( player , 1 ) ; }
} SCENE {
ANIMATION ( ANIM_TYPE_GENERAL , B_ANIM_ZMOVE_ACTIVATE , player ) ;
ANIMATION ( ANIM_TYPE_MOVE , MOVE_PARTING_SHOT , player ) ;
HP_BAR ( player ) ;
} THEN {
EXPECT_EQ ( player - > species , SPECIES_WYNAUT ) ;
EXPECT_EQ ( player - > hp , player - > maxHP ) ;
}
}
// This tests the functionality of Z_EFFECT_RECOVER_HP and Z_EFFECT_ATK_UP_1 (and thus by extension all stat-up Z-effects)
SINGLE_BATTLE_TEST ( " (Z-MOVE) Z_EFFECT_CURSE activates Z_EFFECT_RECOVER_HP or Z_EFFECT_ATK_UP_1 depending on the type of the battler " )
{
u32 species ;
PARAMETRIZE { species = SPECIES_WOBBUFFET ; }
PARAMETRIZE { species = SPECIES_DUSCLOPS ; }
GIVEN {
ASSUME ( gMovesInfo [ MOVE_CURSE ] . type = = TYPE_GHOST ) ;
ASSUME ( gSpeciesInfo [ SPECIES_WOBBUFFET ] . types [ 0 ] ! = TYPE_GHOST ) ;
ASSUME ( gSpeciesInfo [ SPECIES_WOBBUFFET ] . types [ 1 ] ! = TYPE_GHOST ) ;
ASSUME ( gSpeciesInfo [ SPECIES_DUSCLOPS ] . types [ 0 ] = = TYPE_GHOST ) ;
ASSUME ( gMovesInfo [ MOVE_CURSE ] . zMove . effect = = Z_EFFECT_CURSE ) ;
PLAYER ( species ) { Item ( ITEM_GHOSTIUM_Z ) ; HP ( 1 ) ; }
OPPONENT ( SPECIES_WOBBUFFET ) ;
} WHEN {
TURN { MOVE ( player , MOVE_CURSE , gimmick : GIMMICK_Z_MOVE ) ; }
} SCENE {
ANIMATION ( ANIM_TYPE_GENERAL , B_ANIM_ZMOVE_ACTIVATE , player ) ;
if ( species = = SPECIES_DUSCLOPS ) {
HP_BAR ( player ) ;
NOT { ANIMATION ( ANIM_TYPE_GENERAL , B_ANIM_STATS_CHANGE , player ) ; }
ANIMATION ( ANIM_TYPE_MOVE , MOVE_CURSE , player ) ;
HP_BAR ( player ) ;
} else {
NOT { HP_BAR ( player ) ; }
ANIMATION ( ANIM_TYPE_GENERAL , B_ANIM_STATS_CHANGE , player ) ;
ANIMATION ( ANIM_TYPE_MOVE , MOVE_CURSE , player ) ;
NOT { HP_BAR ( player ) ; }
}
} THEN {
if ( species = = SPECIES_DUSCLOPS ) {
EXPECT_MUL_EQ ( player - > maxHP , UQ_4_12 ( 0.50 ) , player - > hp ) ; // heal to full HP then cut by half
EXPECT_EQ ( player - > statStages [ STAT_ATK ] , DEFAULT_STAT_STAGE ) ;
} else {
EXPECT_EQ ( player - > hp , 1 ) ;
EXPECT_EQ ( player - > statStages [ STAT_ATK ] , DEFAULT_STAT_STAGE + 2 ) ; // +1 from Curse, +1 from Z-Effect
}
}
}
// Specific Z-Move Interactions
SINGLE_BATTLE_TEST ( " (Z-MOVE) Z-Mirror Move raises the user's attack by two stages and copies the last used non-status move as a Z-Move " )
{
GIVEN {
ASSUME ( gMovesInfo [ MOVE_MIRROR_MOVE ] . type = = TYPE_FLYING ) ;
ASSUME ( gMovesInfo [ MOVE_MIRROR_MOVE ] . zMove . effect = = Z_EFFECT_ATK_UP_2 ) ;
PLAYER ( SPECIES_WOBBUFFET ) { Item ( ITEM_FLYINIUM_Z ) ; }
OPPONENT ( SPECIES_WOBBUFFET ) ;
} WHEN {
TURN { MOVE ( opponent , MOVE_TACKLE ) ; MOVE ( player , MOVE_MIRROR_MOVE , gimmick : GIMMICK_Z_MOVE ) ; }
TURN { MOVE ( player , MOVE_TACKLE ) ; }
} SCENE {
ANIMATION ( ANIM_TYPE_MOVE , MOVE_TACKLE , opponent ) ;
ANIMATION ( ANIM_TYPE_GENERAL , B_ANIM_ZMOVE_ACTIVATE , player ) ;
ANIMATION ( ANIM_TYPE_GENERAL , B_ANIM_STATS_CHANGE , player ) ;
ANIMATION ( ANIM_TYPE_MOVE , MOVE_BREAKNECK_BLITZ , player ) ;
// extra turn to make sure that everything resets properly
ANIMATION ( ANIM_TYPE_MOVE , MOVE_TACKLE , player ) ;
} THEN {
EXPECT_EQ ( player - > statStages [ STAT_ATK ] , DEFAULT_STAT_STAGE + 2 ) ;
}
}
SINGLE_BATTLE_TEST ( " (Z-MOVE) Z-Mirror Move raises the user's attack by two stages and copies the last used status move regularly " )
{
GIVEN {
ASSUME ( gMovesInfo [ MOVE_MIRROR_MOVE ] . type = = TYPE_FLYING ) ;
ASSUME ( gMovesInfo [ MOVE_MIRROR_MOVE ] . zMove . effect = = Z_EFFECT_ATK_UP_2 ) ;
PLAYER ( SPECIES_WOBBUFFET ) { Item ( ITEM_FLYINIUM_Z ) ; }
OPPONENT ( SPECIES_WOBBUFFET ) ;
} WHEN {
TURN { MOVE ( opponent , MOVE_SCREECH ) ; MOVE ( player , MOVE_MIRROR_MOVE , gimmick : GIMMICK_Z_MOVE ) ; }
} SCENE {
ANIMATION ( ANIM_TYPE_MOVE , MOVE_SCREECH , opponent ) ;
ANIMATION ( ANIM_TYPE_GENERAL , B_ANIM_ZMOVE_ACTIVATE , player ) ;
ANIMATION ( ANIM_TYPE_GENERAL , B_ANIM_STATS_CHANGE , player ) ;
ANIMATION ( ANIM_TYPE_MOVE , MOVE_SCREECH , player ) ;
} THEN {
EXPECT_EQ ( player - > statStages [ STAT_ATK ] , DEFAULT_STAT_STAGE + 2 ) ; // Z-Screech would cause an additional attack stat stage (reaching +3)
}
}
SINGLE_BATTLE_TEST ( " (Z-MOVE) Z-Copycat raises the user's accuracy by one stage and copies the last used non-status move as a Z-Move " )
{
GIVEN {
ASSUME ( gMovesInfo [ MOVE_COPYCAT ] . type = = TYPE_NORMAL ) ;
ASSUME ( gMovesInfo [ MOVE_COPYCAT ] . zMove . effect = = Z_EFFECT_ACC_UP_1 ) ;
PLAYER ( SPECIES_WOBBUFFET ) { Item ( ITEM_NORMALIUM_Z ) ; }
OPPONENT ( SPECIES_WOBBUFFET ) ;
} WHEN {
TURN { MOVE ( opponent , MOVE_TACKLE ) ; MOVE ( player , MOVE_COPYCAT , gimmick : GIMMICK_Z_MOVE ) ; }
} SCENE {
ANIMATION ( ANIM_TYPE_MOVE , MOVE_TACKLE , opponent ) ;
ANIMATION ( ANIM_TYPE_GENERAL , B_ANIM_ZMOVE_ACTIVATE , player ) ;
ANIMATION ( ANIM_TYPE_GENERAL , B_ANIM_STATS_CHANGE , player ) ;
ANIMATION ( ANIM_TYPE_MOVE , MOVE_BREAKNECK_BLITZ , player ) ;
} THEN {
EXPECT_EQ ( player - > statStages [ STAT_ACC ] , DEFAULT_STAT_STAGE + 1 ) ;
}
}
SINGLE_BATTLE_TEST ( " (Z-MOVE) Z-Me First raises the user's speed by two stages and copies the last used non-status move as a Z-Move with boosted damage " , s16 damage )
{
u32 meFirst ;
PARAMETRIZE { meFirst = TRUE ; }
PARAMETRIZE { meFirst = FALSE ; }
GIVEN {
ASSUME ( gMovesInfo [ MOVE_ME_FIRST ] . type = = TYPE_NORMAL ) ;
ASSUME ( gMovesInfo [ MOVE_ME_FIRST ] . zMove . effect = = Z_EFFECT_SPD_UP_2 ) ;
PLAYER ( SPECIES_WOBBUFFET ) { Item ( ITEM_NORMALIUM_Z ) ; }
OPPONENT ( SPECIES_WOBBUFFET ) ;
} WHEN {
if ( meFirst )
TURN { MOVE ( player , MOVE_ME_FIRST , gimmick : GIMMICK_Z_MOVE ) ; MOVE ( opponent , MOVE_TACKLE ) ; }
else
TURN { MOVE ( player , MOVE_TACKLE , gimmick : GIMMICK_Z_MOVE ) ; }
} SCENE {
ANIMATION ( ANIM_TYPE_GENERAL , B_ANIM_ZMOVE_ACTIVATE , player ) ;
if ( meFirst )
ANIMATION ( ANIM_TYPE_GENERAL , B_ANIM_STATS_CHANGE , player ) ;
ANIMATION ( ANIM_TYPE_MOVE , MOVE_BREAKNECK_BLITZ , player ) ;
HP_BAR ( opponent , captureDamage : & results [ i ] . damage ) ;
} THEN {
if ( meFirst )
EXPECT_EQ ( player - > statStages [ STAT_SPEED ] , DEFAULT_STAT_STAGE + 2 ) ;
} FINALLY {
EXPECT_MUL_EQ ( results [ 1 ] . damage , UQ_4_12 ( 1.50 ) , results [ 0 ] . damage ) ;
}
}
SINGLE_BATTLE_TEST ( " (Z-MOVE) Z-Nature Power transforms into different Z-Moves based on the current terrain " )
{
u32 terrainMove = MOVE_NONE ;
u32 zMove = MOVE_NONE ;
PARAMETRIZE { terrainMove = MOVE_ELECTRIC_TERRAIN ; zMove = gTypesInfo [ TYPE_ELECTRIC ] . zMove ; }
PARAMETRIZE { terrainMove = MOVE_PSYCHIC_TERRAIN ; zMove = gTypesInfo [ TYPE_PSYCHIC ] . zMove ; }
PARAMETRIZE { terrainMove = MOVE_GRASSY_TERRAIN ; zMove = gTypesInfo [ TYPE_GRASS ] . zMove ; }
PARAMETRIZE { terrainMove = MOVE_MISTY_TERRAIN ; zMove = gTypesInfo [ TYPE_FAIRY ] . zMove ; }
GIVEN {
ASSUME ( gMovesInfo [ MOVE_NATURE_POWER ] . type = = TYPE_NORMAL ) ;
PLAYER ( SPECIES_WOBBUFFET ) { Item ( ITEM_NORMALIUM_Z ) ; }
OPPONENT ( SPECIES_WOBBUFFET ) ;
} WHEN {
TURN { MOVE ( player , terrainMove ) ; }
TURN { MOVE ( player , MOVE_NATURE_POWER , gimmick : GIMMICK_Z_MOVE ) ; }
} SCENE {
ANIMATION ( ANIM_TYPE_MOVE , terrainMove , player ) ;
ANIMATION ( ANIM_TYPE_GENERAL , B_ANIM_ZMOVE_ACTIVATE , player ) ;
ANIMATION ( ANIM_TYPE_MOVE , zMove , player ) ;
}
}
SINGLE_BATTLE_TEST ( " (Z-MOVE) Z-Hidden Power always transforms into Breakneck Blitz " )
{
u8 iv ;
PARAMETRIZE { iv = 0 ; } // test different Hidden Power types
PARAMETRIZE { iv = 10 ; }
PARAMETRIZE { iv = 21 ; }
PARAMETRIZE { iv = 31 ; }
GIVEN {
ASSUME ( gMovesInfo [ MOVE_HIDDEN_POWER ] . type = = TYPE_NORMAL ) ;
PLAYER ( SPECIES_WOBBUFFET ) { Item ( ITEM_NORMALIUM_Z ) ; AttackIV ( iv ) ; }
OPPONENT ( SPECIES_WOBBUFFET ) ;
} WHEN {
TURN { MOVE ( player , MOVE_HIDDEN_POWER , gimmick : GIMMICK_Z_MOVE ) ; }
} SCENE {
ANIMATION ( ANIM_TYPE_GENERAL , B_ANIM_ZMOVE_ACTIVATE , player ) ;
ANIMATION ( ANIM_TYPE_MOVE , MOVE_BREAKNECK_BLITZ , player ) ;
}
}
SINGLE_BATTLE_TEST ( " (Z-MOVE) Z-Weather Ball transforms into different Z-Moves based on current weather " )
{
u32 weatherMove = MOVE_NONE ;
u32 zMove = MOVE_NONE ;
PARAMETRIZE { weatherMove = MOVE_RAIN_DANCE ; zMove = gTypesInfo [ TYPE_WATER ] . zMove ; }
PARAMETRIZE { weatherMove = MOVE_SUNNY_DAY ; zMove = gTypesInfo [ TYPE_FIRE ] . zMove ; }
PARAMETRIZE { weatherMove = MOVE_SANDSTORM ; zMove = gTypesInfo [ TYPE_ROCK ] . zMove ; }
PARAMETRIZE { weatherMove = MOVE_HAIL ; zMove = gTypesInfo [ TYPE_ICE ] . zMove ; }
GIVEN {
ASSUME ( gMovesInfo [ MOVE_WEATHER_BALL ] . type = = TYPE_NORMAL ) ;
PLAYER ( SPECIES_WOBBUFFET ) { Item ( ITEM_NORMALIUM_Z ) ; }
OPPONENT ( SPECIES_WOBBUFFET ) ;
} WHEN {
TURN { MOVE ( player , weatherMove ) ; }
TURN { MOVE ( player , MOVE_WEATHER_BALL , gimmick : GIMMICK_Z_MOVE ) ; }
} SCENE {
ANIMATION ( ANIM_TYPE_MOVE , weatherMove , player ) ;
ANIMATION ( ANIM_TYPE_GENERAL , B_ANIM_ZMOVE_ACTIVATE , player ) ;
ANIMATION ( ANIM_TYPE_MOVE , zMove , player ) ;
}
}
SINGLE_BATTLE_TEST ( " (Z-MOVE) Z-Sleep Talk transforms a used non-status move into a Z-Move " )
{
GIVEN {
ASSUME ( gMovesInfo [ MOVE_SLEEP_TALK ] . type = = TYPE_NORMAL ) ;
PLAYER ( SPECIES_WOBBUFFET ) { Item ( ITEM_NORMALIUM_Z ) ; Status1 ( STATUS1_SLEEP ) ; Moves ( MOVE_SLEEP_TALK , MOVE_ABSORB ) ; }
OPPONENT ( SPECIES_WOBBUFFET ) ;
} WHEN {
TURN { MOVE ( player , MOVE_SLEEP_TALK , gimmick : GIMMICK_Z_MOVE ) ; }
TURN { MOVE ( player , MOVE_SLEEP_TALK ) ; }
} SCENE {
ANIMATION ( ANIM_TYPE_GENERAL , B_ANIM_ZMOVE_ACTIVATE , player ) ;
ANIMATION ( ANIM_TYPE_MOVE , MOVE_BLOOM_DOOM , player ) ;
}
}
SINGLE_BATTLE_TEST ( " (Z-MOVE) Z-Sleep Talk turns Weather Ball into Breakneck Blitz even under rain " )
{
GIVEN {
ASSUME ( gMovesInfo [ MOVE_SLEEP_TALK ] . type = = TYPE_NORMAL ) ;
PLAYER ( SPECIES_WOBBUFFET ) { Item ( ITEM_NORMALIUM_Z ) ; Status1 ( STATUS1_SLEEP ) ; Moves ( MOVE_SLEEP_TALK , MOVE_WEATHER_BALL ) ; }
OPPONENT ( SPECIES_WOBBUFFET ) ;
} WHEN {
TURN { MOVE ( opponent , MOVE_RAIN_DANCE ) ; MOVE ( player , MOVE_SLEEP_TALK , gimmick : GIMMICK_Z_MOVE ) ; }
} SCENE {
ANIMATION ( ANIM_TYPE_MOVE , MOVE_RAIN_DANCE , opponent ) ;
ANIMATION ( ANIM_TYPE_GENERAL , B_ANIM_ZMOVE_ACTIVATE , player ) ;
ANIMATION ( ANIM_TYPE_MOVE , MOVE_BREAKNECK_BLITZ , player ) ;
}
}
2024-09-13 17:08:23 +01:00
SINGLE_BATTLE_TEST ( " (Z-MOVE) Powder blocks Fire type Z-Moves and deals 25% of maximum HP to the user " )
{
GIVEN {
ASSUME ( gMovesInfo [ MOVE_EMBER ] . type = = TYPE_FIRE ) ;
PLAYER ( SPECIES_WOBBUFFET ) { Item ( ITEM_FIRIUM_Z ) ; }
OPPONENT ( SPECIES_VIVILLON ) ;
} WHEN {
TURN { MOVE ( opponent , MOVE_POWDER ) ; MOVE ( player , MOVE_EMBER , gimmick : GIMMICK_Z_MOVE ) ; }
} SCENE {
ANIMATION ( ANIM_TYPE_MOVE , MOVE_POWDER , opponent ) ;
ANIMATION ( ANIM_TYPE_GENERAL , B_ANIM_ZMOVE_ACTIVATE , player ) ;
NOT ANIMATION ( ANIM_TYPE_MOVE , MOVE_INFERNO_OVERDRIVE , player ) ;
} THEN {
EXPECT_MUL_EQ ( player - > maxHP , UQ_4_12 ( 0.75 ) , player - > hp ) ;
}
}
DOUBLE_BATTLE_TEST ( " (Z-MOVE) Powder blocks Fire type Z-Moves (from Z-Mirror Move) " )
{
GIVEN {
ASSUME ( gMovesInfo [ MOVE_EMBER ] . type = = TYPE_FIRE ) ;
ASSUME ( gMovesInfo [ MOVE_MIRROR_MOVE ] . type = = TYPE_FLYING ) ;
PLAYER ( SPECIES_WOBBUFFET ) { Item ( ITEM_FLYINIUM_Z ) ; }
PLAYER ( SPECIES_WOBBUFFET ) ;
OPPONENT ( SPECIES_WOBBUFFET ) ;
OPPONENT ( SPECIES_VIVILLON ) ;
} WHEN {
TURN { MOVE ( opponentRight , MOVE_POWDER , target : playerLeft ) ; MOVE ( opponentLeft , MOVE_EMBER , target : playerLeft ) ; MOVE ( playerLeft , MOVE_MIRROR_MOVE , gimmick : GIMMICK_Z_MOVE ) ; }
} SCENE {
ANIMATION ( ANIM_TYPE_MOVE , MOVE_POWDER , opponentRight ) ;
ANIMATION ( ANIM_TYPE_MOVE , MOVE_EMBER , opponentLeft ) ;
ANIMATION ( ANIM_TYPE_GENERAL , B_ANIM_ZMOVE_ACTIVATE , playerLeft ) ;
NOT ANIMATION ( ANIM_TYPE_MOVE , MOVE_INFERNO_OVERDRIVE , playerLeft ) ;
}
}
SINGLE_BATTLE_TEST ( " (Z-MOVE) Powder blocks Fire type Z-Moves but not boosts granted " )
{
GIVEN {
ASSUME ( gMovesInfo [ MOVE_WILL_O_WISP ] . type = = TYPE_FIRE ) ;
ASSUME ( gMovesInfo [ MOVE_WILL_O_WISP ] . zMove . effect = = Z_EFFECT_ATK_UP_1 ) ;
PLAYER ( SPECIES_WOBBUFFET ) { Item ( ITEM_FIRIUM_Z ) ; }
OPPONENT ( SPECIES_VIVILLON ) ;
} WHEN {
TURN { MOVE ( opponent , MOVE_POWDER ) ; MOVE ( player , MOVE_WILL_O_WISP , gimmick : GIMMICK_Z_MOVE ) ; }
} SCENE {
ANIMATION ( ANIM_TYPE_MOVE , MOVE_POWDER , opponent ) ;
ANIMATION ( ANIM_TYPE_GENERAL , B_ANIM_ZMOVE_ACTIVATE , player ) ;
NOT ANIMATION ( ANIM_TYPE_MOVE , MOVE_WILL_O_WISP , player ) ;
} THEN {
EXPECT_EQ ( player - > statStages [ STAT_ATK ] , DEFAULT_STAT_STAGE + 1 ) ;
}
}
2024-06-22 21:25:40 +01:00
// Miscellaneous Interactions
DOUBLE_BATTLE_TEST ( " (Z-MOVE) Instruct fails if the target last used a Z-Move " )
{
GIVEN {
ASSUME ( gMovesInfo [ MOVE_TACKLE ] . type = = TYPE_NORMAL ) ;
PLAYER ( SPECIES_WOBBUFFET ) { Item ( ITEM_NORMALIUM_Z ) ; }
PLAYER ( SPECIES_WYNAUT ) ;
OPPONENT ( SPECIES_WOBBUFFET ) ;
OPPONENT ( SPECIES_WYNAUT ) ;
} WHEN {
TURN { MOVE ( playerLeft , MOVE_TACKLE , target : opponentLeft , gimmick : GIMMICK_Z_MOVE ) ;
MOVE ( playerRight , MOVE_INSTRUCT , target : playerLeft ) ; }
} SCENE {
ANIMATION ( ANIM_TYPE_GENERAL , B_ANIM_ZMOVE_ACTIVATE , playerLeft ) ;
ANIMATION ( ANIM_TYPE_MOVE , MOVE_BREAKNECK_BLITZ , playerLeft ) ;
MESSAGE ( " Wynaut used Instruct! " ) ;
MESSAGE ( " But it failed! " ) ;
}
}
DOUBLE_BATTLE_TEST ( " (Z-MOVE) Dancer does not use a Z-Move if the battler has used a Z-Move the same turn " )
{
GIVEN {
ASSUME ( gMovesInfo [ MOVE_TACKLE ] . type = = TYPE_NORMAL ) ;
PLAYER ( SPECIES_WOBBUFFET ) { Ability ( ABILITY_DANCER ) ; Item ( ITEM_NORMALIUM_Z ) ; }
PLAYER ( SPECIES_WYNAUT ) ;
OPPONENT ( SPECIES_WOBBUFFET ) ;
OPPONENT ( SPECIES_WYNAUT ) ;
} WHEN {
TURN { MOVE ( playerLeft , MOVE_TACKLE , target : opponentLeft , gimmick : GIMMICK_Z_MOVE ) ;
MOVE ( playerRight , MOVE_FIERY_DANCE , target : opponentRight ) ; }
} SCENE {
ANIMATION ( ANIM_TYPE_GENERAL , B_ANIM_ZMOVE_ACTIVATE , playerLeft ) ;
ANIMATION ( ANIM_TYPE_MOVE , MOVE_BREAKNECK_BLITZ , playerLeft ) ;
ANIMATION ( ANIM_TYPE_MOVE , MOVE_FIERY_DANCE , playerRight ) ;
ABILITY_POPUP ( playerLeft ) ;
ANIMATION ( ANIM_TYPE_MOVE , MOVE_FIERY_DANCE , playerLeft ) ;
}
}
// Signature Z-Moves
SINGLE_BATTLE_TEST ( " (Z-MOVE) Light That Burns the Sky uses the battler's highest attacking stat " , s16 damage )
{
bool32 useSwordsDance ;
PARAMETRIZE { useSwordsDance = FALSE ; }
PARAMETRIZE { useSwordsDance = TRUE ; }
GIVEN {
ASSUME ( gMovesInfo [ MOVE_SWORDS_DANCE ] . effect = = EFFECT_ATTACK_UP_2 ) ;
PLAYER ( SPECIES_NECROZMA_DUSK_MANE ) { Item ( ITEM_ULTRANECROZIUM_Z ) ; }
OPPONENT ( SPECIES_WOBBUFFET ) { HP ( 1000 ) ; MaxHP ( 1000 ) ; } ; // hits hard lol
} WHEN {
TURN { MOVE ( player , MOVE_TACKLE , gimmick : GIMMICK_ULTRA_BURST ) ; }
if ( useSwordsDance )
TURN { MOVE ( player , MOVE_SWORDS_DANCE ) ; }
TURN { MOVE ( player , MOVE_PHOTON_GEYSER , gimmick : GIMMICK_Z_MOVE ) ; }
} SCENE {
ANIMATION ( ANIM_TYPE_GENERAL , B_ANIM_ULTRA_BURST , player ) ; // implicitly testing double gimmicks :^)
ANIMATION ( ANIM_TYPE_GENERAL , B_ANIM_ZMOVE_ACTIVATE , player ) ;
ANIMATION ( ANIM_TYPE_MOVE , MOVE_LIGHT_THAT_BURNS_THE_SKY , player ) ;
HP_BAR ( opponent , captureDamage : & results [ i ] . damage ) ;
} FINALLY {
EXPECT_MUL_EQ ( results [ 0 ] . damage , UQ_4_12 ( 2.0 ) , results [ 1 ] . damage ) ;
}
}
SINGLE_BATTLE_TEST ( " (Z-MOVE) 10,000,000 Volt Thunderbolt has an increased critical hit ratio " )
{
PASSES_RANDOMLY ( 1 , 2 , RNG_CRITICAL_HIT ) ;
GIVEN {
ASSUME ( B_CRIT_CHANCE > = GEN_6 ) ;
ASSUME ( gMovesInfo [ MOVE_10_000_000_VOLT_THUNDERBOLT ] . criticalHitStage = = 2 ) ;
2024-10-27 19:15:11 +00:00
PLAYER ( SPECIES_PIKACHU_PARTNER ) { Item ( ITEM_PIKASHUNIUM_Z ) ; }
2024-06-22 21:25:40 +01:00
OPPONENT ( SPECIES_WOBBUFFET ) ;
} WHEN {
TURN { MOVE ( player , MOVE_THUNDERBOLT , gimmick : GIMMICK_Z_MOVE ) ; }
} SCENE {
ANIMATION ( ANIM_TYPE_GENERAL , B_ANIM_ZMOVE_ACTIVATE , player ) ;
ANIMATION ( ANIM_TYPE_MOVE , MOVE_10_000_000_VOLT_THUNDERBOLT , player ) ;
MESSAGE ( " A critical hit! " ) ;
}
}
SINGLE_BATTLE_TEST ( " (Z-MOVE) Stoked Sparksurfer paralyzes the target " )
{
GIVEN {
ASSUME ( gMovesInfo [ MOVE_STOKED_SPARKSURFER ] . additionalEffects [ 0 ] . moveEffect = = MOVE_EFFECT_PARALYSIS ) ;
PLAYER ( SPECIES_RAICHU_ALOLA ) { Item ( ITEM_ALORAICHIUM_Z ) ; }
OPPONENT ( SPECIES_WOBBUFFET ) ;
} WHEN {
TURN { MOVE ( player , MOVE_THUNDERBOLT , gimmick : GIMMICK_Z_MOVE ) ; }
} SCENE {
ANIMATION ( ANIM_TYPE_GENERAL , B_ANIM_ZMOVE_ACTIVATE , player ) ;
ANIMATION ( ANIM_TYPE_MOVE , MOVE_STOKED_SPARKSURFER , player ) ;
STATUS_ICON ( opponent , STATUS1_PARALYSIS ) ;
}
}
SINGLE_BATTLE_TEST ( " (Z-MOVE) Extreme Evoboost boosts all the user's stats by two stages " )
{
GIVEN {
ASSUME ( gMovesInfo [ MOVE_EXTREME_EVOBOOST ] . effect = = EFFECT_EXTREME_EVOBOOST ) ;
PLAYER ( SPECIES_EEVEE ) { Item ( ITEM_EEVIUM_Z ) ; }
OPPONENT ( SPECIES_WOBBUFFET ) ;
} WHEN {
TURN { MOVE ( player , MOVE_LAST_RESORT , gimmick : GIMMICK_Z_MOVE ) ; }
} SCENE {
ANIMATION ( ANIM_TYPE_GENERAL , B_ANIM_ZMOVE_ACTIVATE , player ) ;
ANIMATION ( ANIM_TYPE_MOVE , MOVE_EXTREME_EVOBOOST , player ) ;
} THEN {
EXPECT_EQ ( player - > statStages [ STAT_ATK ] , DEFAULT_STAT_STAGE + 2 ) ;
EXPECT_EQ ( player - > statStages [ STAT_DEF ] , DEFAULT_STAT_STAGE + 2 ) ;
EXPECT_EQ ( player - > statStages [ STAT_SPATK ] , DEFAULT_STAT_STAGE + 2 ) ;
EXPECT_EQ ( player - > statStages [ STAT_SPDEF ] , DEFAULT_STAT_STAGE + 2 ) ;
EXPECT_EQ ( player - > statStages [ STAT_SPEED ] , DEFAULT_STAT_STAGE + 2 ) ;
}
}
SINGLE_BATTLE_TEST ( " (Z-MOVE) Genesis Supernova sets up psychic terrain " )
{
GIVEN {
ASSUME ( gMovesInfo [ MOVE_GENESIS_SUPERNOVA ] . effect = = EFFECT_HIT_SET_REMOVE_TERRAIN ) ;
PLAYER ( SPECIES_MEW ) { Item ( ITEM_MEWNIUM_Z ) ; }
OPPONENT ( SPECIES_WOBBUFFET ) ;
} WHEN {
TURN { MOVE ( player , MOVE_PSYCHIC , gimmick : GIMMICK_Z_MOVE ) ; }
TURN { MOVE ( player , MOVE_QUICK_ATTACK ) ; }
} SCENE {
ANIMATION ( ANIM_TYPE_GENERAL , B_ANIM_ZMOVE_ACTIVATE , player ) ;
ANIMATION ( ANIM_TYPE_MOVE , MOVE_GENESIS_SUPERNOVA , player ) ;
NOT { ANIMATION ( ANIM_TYPE_MOVE , MOVE_QUICK_ATTACK , player ) ; }
MESSAGE ( " Mew cannot use Quick Attack! " ) ;
}
}
SINGLE_BATTLE_TEST ( " (Z-MOVE) Splintered Stormshards removes terrain " )
{
GIVEN {
ASSUME ( gMovesInfo [ MOVE_SPLINTERED_STORMSHARDS ] . effect = = EFFECT_HIT_SET_REMOVE_TERRAIN ) ;
PLAYER ( SPECIES_LYCANROC_DUSK ) { Item ( ITEM_LYCANIUM_Z ) ; }
OPPONENT ( SPECIES_TAPU_LELE ) { Ability ( ABILITY_PSYCHIC_SURGE ) ; HP ( 1000 ) ; MaxHP ( 1000 ) ; }
} WHEN {
TURN { MOVE ( player , MOVE_STONE_EDGE , gimmick : GIMMICK_Z_MOVE ) ; }
TURN { MOVE ( player , MOVE_QUICK_ATTACK ) ; }
} SCENE {
ANIMATION ( ANIM_TYPE_GENERAL , B_ANIM_ZMOVE_ACTIVATE , player ) ;
ANIMATION ( ANIM_TYPE_MOVE , MOVE_SPLINTERED_STORMSHARDS , player ) ;
2024-10-21 18:52:45 +01:00
MESSAGE ( " The weirdness disappeared from the battlefield! " ) ;
2024-06-22 21:25:40 +01:00
ANIMATION ( ANIM_TYPE_MOVE , MOVE_QUICK_ATTACK , player ) ;
HP_BAR ( opponent ) ;
}
}
SINGLE_BATTLE_TEST ( " (Z-MOVE) Clangorous Soulblaze boosts all the user's stats by one stage " )
{
GIVEN {
ASSUME ( gMovesInfo [ MOVE_CLANGOROUS_SOULBLAZE ] . additionalEffects [ 0 ] . moveEffect = = MOVE_EFFECT_ALL_STATS_UP ) ;
PLAYER ( SPECIES_KOMMO_O ) { Item ( ITEM_KOMMONIUM_Z ) ; }
OPPONENT ( SPECIES_WOBBUFFET ) ;
} WHEN {
TURN { MOVE ( player , MOVE_CLANGING_SCALES , gimmick : GIMMICK_Z_MOVE ) ; }
} SCENE {
ANIMATION ( ANIM_TYPE_GENERAL , B_ANIM_ZMOVE_ACTIVATE , player ) ;
ANIMATION ( ANIM_TYPE_MOVE , MOVE_CLANGOROUS_SOULBLAZE , player ) ;
} THEN {
EXPECT_EQ ( player - > statStages [ STAT_ATK ] , DEFAULT_STAT_STAGE + 1 ) ;
EXPECT_EQ ( player - > statStages [ STAT_DEF ] , DEFAULT_STAT_STAGE + 1 ) ;
EXPECT_EQ ( player - > statStages [ STAT_SPATK ] , DEFAULT_STAT_STAGE + 1 ) ;
EXPECT_EQ ( player - > statStages [ STAT_SPDEF ] , DEFAULT_STAT_STAGE + 1 ) ;
EXPECT_EQ ( player - > statStages [ STAT_SPEED ] , DEFAULT_STAT_STAGE + 1 ) ;
}
}
SINGLE_BATTLE_TEST ( " (Z-MOVE) Guardian of Alola deals 75 \ % of the target's current HP " )
{
GIVEN {
ASSUME ( gMovesInfo [ MOVE_GUARDIAN_OF_ALOLA ] . effect = = EFFECT_GUARDIAN_OF_ALOLA ) ;
PLAYER ( SPECIES_TAPU_FINI ) { Item ( ITEM_TAPUNIUM_Z ) ; }
OPPONENT ( SPECIES_WOBBUFFET ) ;
} WHEN {
TURN { MOVE ( player , MOVE_NATURES_MADNESS , gimmick : GIMMICK_Z_MOVE ) ; }
} SCENE {
ANIMATION ( ANIM_TYPE_GENERAL , B_ANIM_ZMOVE_ACTIVATE , player ) ;
ANIMATION ( ANIM_TYPE_MOVE , MOVE_GUARDIAN_OF_ALOLA , player ) ;
} THEN {
EXPECT_MUL_EQ ( opponent - > maxHP , UQ_4_12 ( 0.25 ) , opponent - > hp ) ;
}
}
SINGLE_BATTLE_TEST ( " (Z-MOVE) Searing Sunraze Smash ignores the target's abilities " )
{
GIVEN {
PLAYER ( SPECIES_SOLGALEO ) { Item ( ITEM_SOLGANIUM_Z ) ; }
OPPONENT ( SPECIES_LAPRAS ) { Ability ( ABILITY_BATTLE_ARMOR ) ; }
} WHEN {
TURN { MOVE ( player , MOVE_SUNSTEEL_STRIKE , gimmick : GIMMICK_Z_MOVE , criticalHit : TRUE ) ; }
} SCENE {
ANIMATION ( ANIM_TYPE_GENERAL , B_ANIM_ZMOVE_ACTIVATE , player ) ;
ANIMATION ( ANIM_TYPE_MOVE , MOVE_SEARING_SUNRAZE_SMASH , player ) ;
HP_BAR ( opponent ) ;
MESSAGE ( " A critical hit! " ) ;
2024-08-15 03:48:20 +01:00
}
2024-06-22 21:25:40 +01:00
}
2024-08-11 17:13:46 +01:00
SINGLE_BATTLE_TEST ( " (Z-MOVE) Z-Revelation Dance always transforms into Breakneck Blitz " )
{
u16 species ;
PARAMETRIZE { species = SPECIES_ORICORIO_BAILE ; }
PARAMETRIZE { species = SPECIES_ORICORIO_PAU ; }
PARAMETRIZE { species = SPECIES_ORICORIO_POM_POM ; }
PARAMETRIZE { species = SPECIES_ORICORIO_SENSU ; }
GIVEN {
ASSUME ( gMovesInfo [ MOVE_REVELATION_DANCE ] . type = = TYPE_NORMAL ) ;
PLAYER ( species ) { Item ( ITEM_NORMALIUM_Z ) ; }
OPPONENT ( SPECIES_WOBBUFFET ) ;
} WHEN {
TURN { MOVE ( player , MOVE_REVELATION_DANCE , gimmick : GIMMICK_Z_MOVE ) ; }
} SCENE {
ANIMATION ( ANIM_TYPE_GENERAL , B_ANIM_ZMOVE_ACTIVATE , player ) ;
ANIMATION ( ANIM_TYPE_MOVE , MOVE_BREAKNECK_BLITZ , player ) ;
}
}