diff --git a/test/battle/ability/fur_coat.c b/test/battle/ability/fur_coat.c index 56fb197114..84b8549e42 100644 --- a/test/battle/ability/fur_coat.c +++ b/test/battle/ability/fur_coat.c @@ -1,4 +1,45 @@ #include "global.h" #include "test/battle.h" -TO_DO_BATTLE_TEST("TODO: Write Fur Coat (Ability) test titles") +ASSUMPTIONS +{ + ASSUME(GetMoveCategory(MOVE_SCRATCH) == DAMAGE_CATEGORY_PHYSICAL); +} + +SINGLE_BATTLE_TEST("Fur Coat doubles Defense", s16 damage) +{ + u32 ability; + PARAMETRIZE { ability = ABILITY_FUR_COAT; } + PARAMETRIZE { ability = ABILITY_RATTLED; } + + GIVEN { + PLAYER(SPECIES_PERSIAN_ALOLA) { Ability(ability); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_SCRATCH); } + } SCENE { + HP_BAR(player, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_MUL_EQ(results[0].damage, Q_4_12(2.0), results[1].damage); + } +} + +SINGLE_BATTLE_TEST("Fur Coat has no effect on self-inflicted confusion damage", s16 damage) +{ + KNOWN_FAILING; + u32 ability; + PARAMETRIZE { ability = ABILITY_FUR_COAT; } + PARAMETRIZE { ability = ABILITY_RATTLED; } + + GIVEN { + PLAYER(SPECIES_PERSIAN_ALOLA) { Ability(ability); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_CONFUSE_RAY); MOVE(player, MOVE_POUND, WITH_RNG(RNG_CONFUSION, TRUE)); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_CONFUSE_RAY, opponent); + HP_BAR(player, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_EQ(results[0].damage, results[1].damage); + } +} diff --git a/test/battle/ability/iron_fist.c b/test/battle/ability/iron_fist.c index ae26f9cdd0..360b3606be 100644 --- a/test/battle/ability/iron_fist.c +++ b/test/battle/ability/iron_fist.c @@ -1,4 +1,26 @@ #include "global.h" #include "test/battle.h" -TO_DO_BATTLE_TEST("TODO: Write Iron Fist (Ability) test titles") +SINGLE_BATTLE_TEST("Iron Fist increases the power of punching moves by 20%", s16 damage) +{ + u32 move, ability; + PARAMETRIZE { move = MOVE_BULLET_PUNCH; ability = ABILITY_IRON_FIST; } + PARAMETRIZE { move = MOVE_BULLET_PUNCH; ability = ABILITY_BLAZE; } + PARAMETRIZE { move = MOVE_SCRATCH; ability = ABILITY_IRON_FIST; } + PARAMETRIZE { move = MOVE_SCRATCH; ability = ABILITY_BLAZE; } + + GIVEN { + ASSUME(IsPunchingMove(MOVE_BULLET_PUNCH)); + ASSUME(!IsPunchingMove(MOVE_SCRATCH)); + ASSUME(GetMovePower(MOVE_BULLET_PUNCH) == GetMovePower(MOVE_SCRATCH)); + PLAYER(SPECIES_CHIMCHAR) { Ability(ability); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, move); } + } SCENE { + HP_BAR(opponent, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_MUL_EQ(results[1].damage, Q_4_12(1.2), results[0].damage); // Iron Fist affects punching moves + EXPECT_EQ(results[2].damage, results[3].damage); // Iron Fist does not affect non-punching moves + } +} diff --git a/test/battle/ability/libero.c b/test/battle/ability/libero.c index 8ea93df3c0..b2ebf5cd5b 100644 --- a/test/battle/ability/libero.c +++ b/test/battle/ability/libero.c @@ -1,4 +1,4 @@ #include "global.h" #include "test/battle.h" -TO_DO_BATTLE_TEST("TODO: Write Libero (Ability) test titles") +// Tests for Libero are handled in test/battle/ability/protean.c diff --git a/test/battle/ability/protean.c b/test/battle/ability/protean.c index fe4ae25e60..c41fa58cca 100644 --- a/test/battle/ability/protean.c +++ b/test/battle/ability/protean.c @@ -1,12 +1,15 @@ #include "global.h" #include "test/battle.h" -SINGLE_BATTLE_TEST("Protean changes the type of the user to the move used every time (Gen6-8)") +SINGLE_BATTLE_TEST("Protean/Libero changes the type of the user to the move used every time (Gen6-8)") { + u32 ability, species; + PARAMETRIZE { ability = ABILITY_PROTEAN; species = SPECIES_KECLEON; } + PARAMETRIZE { ability = ABILITY_LIBERO; species = SPECIES_RABOOT; } GIVEN { WITH_CONFIG(GEN_PROTEAN_LIBERO, GEN_6); PLAYER(SPECIES_REGIROCK); - OPPONENT(SPECIES_KECLEON) { Ability(ABILITY_PROTEAN); } + OPPONENT(species) { Ability(ability); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { TURN { MOVE(opponent, MOVE_WATER_GUN); } @@ -15,24 +18,36 @@ SINGLE_BATTLE_TEST("Protean changes the type of the user to the move used every TURN { SWITCH(opponent, 0); } TURN { MOVE(opponent, MOVE_WATER_GUN); } } SCENE { - ABILITY_POPUP(opponent, ABILITY_PROTEAN); - MESSAGE("The opposing Kecleon transformed into the Water type!"); + ABILITY_POPUP(opponent, ability); + if (species == SPECIES_KECLEON) + MESSAGE("The opposing Kecleon transformed into the Water type!"); + else + MESSAGE("The opposing Raboot transformed into the Water type!"); ANIMATION(ANIM_TYPE_MOVE, MOVE_WATER_GUN, opponent); - ABILITY_POPUP(opponent, ABILITY_PROTEAN); - MESSAGE("The opposing Kecleon transformed into the Normal type!"); + ABILITY_POPUP(opponent, ability); + if (species == SPECIES_KECLEON) + MESSAGE("The opposing Kecleon transformed into the Normal type!"); + else + MESSAGE("The opposing Raboot transformed into the Normal type!"); ANIMATION(ANIM_TYPE_MOVE, MOVE_SCRATCH, opponent); - ABILITY_POPUP(opponent, ABILITY_PROTEAN); - MESSAGE("The opposing Kecleon transformed into the Water type!"); + ABILITY_POPUP(opponent, ability); + if (species == SPECIES_KECLEON) + MESSAGE("The opposing Kecleon transformed into the Water type!"); + else + MESSAGE("The opposing Raboot transformed into the Water type!"); ANIMATION(ANIM_TYPE_MOVE, MOVE_WATER_GUN, opponent); } } -SINGLE_BATTLE_TEST("Protean changes the type of the user only once per switch in (Gen9+)") +SINGLE_BATTLE_TEST("Protean/Libero changes the type of the user only once per switch in (Gen9+)") { + u32 ability, species; + PARAMETRIZE { ability = ABILITY_PROTEAN; species = SPECIES_KECLEON; } + PARAMETRIZE { ability = ABILITY_LIBERO; species = SPECIES_RABOOT; } GIVEN { WITH_CONFIG(GEN_PROTEAN_LIBERO, GEN_9); PLAYER(SPECIES_REGIROCK); - OPPONENT(SPECIES_KECLEON) { Ability(ABILITY_PROTEAN); } + OPPONENT(species) { Ability(ability); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { TURN { MOVE(opponent, MOVE_WATER_GUN); } @@ -41,31 +56,42 @@ SINGLE_BATTLE_TEST("Protean changes the type of the user only once per switch in TURN { SWITCH(opponent, 0); } TURN { MOVE(opponent, MOVE_WATER_GUN); } } SCENE { - ABILITY_POPUP(opponent, ABILITY_PROTEAN); - MESSAGE("The opposing Kecleon transformed into the Water type!"); + ABILITY_POPUP(opponent, ability); + if (species == SPECIES_KECLEON) + MESSAGE("The opposing Kecleon transformed into the Water type!"); + else + MESSAGE("The opposing Raboot transformed into the Water type!"); ANIMATION(ANIM_TYPE_MOVE, MOVE_WATER_GUN, opponent); NONE_OF { - ABILITY_POPUP(opponent, ABILITY_PROTEAN); + ABILITY_POPUP(opponent, ability); MESSAGE("The opposing Kecleon transformed into the Normal type!"); + MESSAGE("The opposing Raboot transformed into the Normal type!"); } ANIMATION(ANIM_TYPE_MOVE, MOVE_SCRATCH, opponent); - ABILITY_POPUP(opponent, ABILITY_PROTEAN); - MESSAGE("The opposing Kecleon transformed into the Water type!"); + ABILITY_POPUP(opponent, ability); + if (species == SPECIES_KECLEON) + MESSAGE("The opposing Kecleon transformed into the Water type!"); + else + MESSAGE("The opposing Raboot transformed into the Water type!"); ANIMATION(ANIM_TYPE_MOVE, MOVE_WATER_GUN, opponent); } } -SINGLE_BATTLE_TEST("Protean does not change the user's type when using Struggle") +SINGLE_BATTLE_TEST("Protean/Libero does not change the user's type when using Struggle") { + u32 ability, species; + PARAMETRIZE { ability = ABILITY_PROTEAN; species = SPECIES_GRENINJA; } + PARAMETRIZE { ability = ABILITY_LIBERO; species = SPECIES_RABOOT; } GIVEN { PLAYER(SPECIES_REGIROCK); - OPPONENT(SPECIES_GRENINJA) { Ability(ABILITY_PROTEAN); } + OPPONENT(species) { Ability(ability); } } WHEN { TURN { MOVE(opponent, MOVE_STRUGGLE); } } SCENE { NONE_OF { - ABILITY_POPUP(opponent, ABILITY_PROTEAN); + ABILITY_POPUP(opponent, ability); MESSAGE("The opposing Greninja transformed into the Normal type!"); + MESSAGE("The opposing Raboot transformed into the Normal type!"); } ANIMATION(ANIM_TYPE_MOVE, MOVE_STRUGGLE, opponent); } diff --git a/test/battle/ability/sharpness.c b/test/battle/ability/sharpness.c index 38ed79f86f..9b89614c36 100644 --- a/test/battle/ability/sharpness.c +++ b/test/battle/ability/sharpness.c @@ -1,7 +1,7 @@ #include "global.h" #include "test/battle.h" -SINGLE_BATTLE_TEST("Sharpness increases the power of slicing moves", s16 damage) +SINGLE_BATTLE_TEST("Sharpness increases the power of slicing moves by 50%", s16 damage) { u32 move; u16 ability; diff --git a/test/battle/gimmick/terastal.c b/test/battle/gimmick/terastal.c index 37a6d515b3..d238ea0d51 100644 --- a/test/battle/gimmick/terastal.c +++ b/test/battle/gimmick/terastal.c @@ -639,17 +639,21 @@ SINGLE_BATTLE_TEST("(TERA) Terastallizing into the Stellar type boosts all moves } } -SINGLE_BATTLE_TEST("(TERA) Protean cannot change the type of a Terastallized Pokemon") +SINGLE_BATTLE_TEST("(TERA) Protean/Libero cannot change the type of a Terastallized Pokemon") { + u32 ability, species; + PARAMETRIZE { ability = ABILITY_PROTEAN; species = SPECIES_GRENINJA; } + PARAMETRIZE { ability = ABILITY_LIBERO; species = SPECIES_RABOOT; } GIVEN { - PLAYER(SPECIES_GRENINJA) { Ability(ABILITY_PROTEAN); TeraType(TYPE_GRASS); } + PLAYER(species) { Ability(ability); TeraType(TYPE_GRASS); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { TURN { MOVE(player, MOVE_BUBBLE, gimmick: GIMMICK_TERA); MOVE(opponent, MOVE_EMBER); } } SCENE { - MESSAGE("Greninja used Bubble!"); - MESSAGE("The opposing Wobbuffet used Ember!"); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_TERA_ACTIVATE, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_BUBBLE, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_EMBER, opponent); MESSAGE("It's super effective!"); } } diff --git a/test/battle/move_effect/curse.c b/test/battle/move_effect/curse.c index bb1de42fba..355972e74e 100644 --- a/test/battle/move_effect/curse.c +++ b/test/battle/move_effect/curse.c @@ -37,16 +37,19 @@ SINGLE_BATTLE_TEST("Curse cuts the user's HP in half when used by Ghost-types") } } -SINGLE_BATTLE_TEST("Curse applies to the user if used with Protean") +SINGLE_BATTLE_TEST("Curse applies to the user if used with Protean/Libero") { + u32 ability, species; + PARAMETRIZE { ability = ABILITY_PROTEAN; species = SPECIES_KECLEON; } + PARAMETRIZE { ability = ABILITY_LIBERO; species = SPECIES_RABOOT; } GIVEN { - PLAYER(SPECIES_KECLEON) { Ability(ABILITY_PROTEAN); } + PLAYER(species) { Ability(ability); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { TURN { MOVE(player, MOVE_CURSE, target: player); } } SCENE { s32 playerMaxHP = GetMonData(&PLAYER_PARTY[0], MON_DATA_MAX_HP); - ABILITY_POPUP(player, ABILITY_PROTEAN); + ABILITY_POPUP(player, ability); ANIMATION(ANIM_TYPE_MOVE, MOVE_CURSE, player); HP_BAR(player, damage: playerMaxHP / 2); HP_BAR(player, damage: playerMaxHP / 4); diff --git a/test/battle/move_effect/powder.c b/test/battle/move_effect/powder.c index da8eba4caf..ea2f80e793 100644 --- a/test/battle/move_effect/powder.c +++ b/test/battle/move_effect/powder.c @@ -223,17 +223,20 @@ DOUBLE_BATTLE_TEST("Powder still blocks the target's Fire type moves even if it } } -SINGLE_BATTLE_TEST("Powder prevents Protean from changing its user to Fire type") +SINGLE_BATTLE_TEST("Powder prevents Protean/Libero from changing its user to Fire type") { + u32 ability, species; + PARAMETRIZE { ability = ABILITY_PROTEAN; species = SPECIES_GRENINJA; } + PARAMETRIZE { ability = ABILITY_LIBERO; species = SPECIES_RABOOT; } GIVEN { - PLAYER(SPECIES_GRENINJA) { Ability(ABILITY_PROTEAN); } + PLAYER(species) { Ability(ability); } OPPONENT(SPECIES_VIVILLON); } WHEN { TURN { MOVE(opponent, MOVE_POWDER); MOVE(player, MOVE_EMBER); } } SCENE { ANIMATION(ANIM_TYPE_MOVE, MOVE_POWDER, opponent); NONE_OF { - ABILITY_POPUP(player, ABILITY_PROTEAN); + ABILITY_POPUP(player, ability); ANIMATION(ANIM_TYPE_MOVE, MOVE_EMBER, player); HP_BAR(opponent); }