diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index a1ccf6f2b..5f989557b 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -7959,9 +7959,10 @@ BattleScript_DoTurnDmgEnd: end2 BattleScript_PoisonHealActivates:: + copybyte gBattlerAbility, gBattlerAttacker + call BattleScript_AbilityPopUp printstring STRINGID_POISONHEALHPUP waitmessage B_WAIT_TIME_LONG - recordability BS_ATTACKER statusanimation BS_ATTACKER orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_DAMAGE healthbarupdate BS_ATTACKER diff --git a/test/battle/ability/defeatist.c b/test/battle/ability/defeatist.c new file mode 100644 index 000000000..a60144c46 --- /dev/null +++ b/test/battle/ability/defeatist.c @@ -0,0 +1,46 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(gBattleMoves[MOVE_TACKLE].split == SPLIT_PHYSICAL); + ASSUME(gBattleMoves[MOVE_ECHOED_VOICE].split == SPLIT_SPECIAL); +} + +SINGLE_BATTLE_TEST("Defeatist halves Attack when HP <= 50%", s16 damage) +{ + u32 hp; + PARAMETRIZE { hp = 400; } + PARAMETRIZE { hp = 200; } + GIVEN { + PLAYER(SPECIES_ARCHEN) { Ability(ABILITY_DEFEATIST); HP(hp), MaxHP(400);} + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_TACKLE); MOVE(opponent, MOVE_CELEBRATE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, player); + HP_BAR(opponent, captureDamage: &results[i].damage); + ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent); + } FINALLY { + EXPECT_MUL_EQ(results[0].damage, Q_4_12(0.5), results[1].damage); + } +} + +SINGLE_BATTLE_TEST("Defeatist halves Special Attack when HP <= 50%", s16 damage) +{ + u32 hp; + PARAMETRIZE { hp = 400; } + PARAMETRIZE { hp = 200; } + GIVEN { + PLAYER(SPECIES_ARCHEN) { Ability(ABILITY_DEFEATIST); HP(hp), MaxHP(400);} + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_ECHOED_VOICE); MOVE(opponent, MOVE_CELEBRATE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_ECHOED_VOICE, player); + HP_BAR(opponent, captureDamage: &results[i].damage); + ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent); + } FINALLY { + EXPECT_MUL_EQ(results[0].damage, Q_4_12(0.5), results[1].damage); + } +} \ No newline at end of file diff --git a/test/battle/ability/gale_wings.c b/test/battle/ability/gale_wings.c new file mode 100644 index 000000000..26c7349e0 --- /dev/null +++ b/test/battle/ability/gale_wings.c @@ -0,0 +1,47 @@ +#include "global.h" +#include "test/battle.h" + +SINGLE_BATTLE_TEST("Gale Wings only grants priority at full HP") +{ + u16 hp; + PARAMETRIZE { hp = 100; } + PARAMETRIZE { hp = 99; } + GIVEN { + ASSUME(B_GALE_WINGS >= GEN_7); + ASSUME(gBattleMoves[MOVE_AERIAL_ACE].type == TYPE_FLYING); + PLAYER(SPECIES_TALONFLAME) { Ability(ABILITY_GALE_WINGS); HP(hp); MaxHP(100); Speed(1);} + OPPONENT(SPECIES_WOBBUFFET) { Speed(100);}; + } WHEN { + TURN { MOVE(player, MOVE_AERIAL_ACE); } + } SCENE { + if (hp == 100) { + MESSAGE("Talonflame used Aerial Ace!"); + } + else { + MESSAGE("Foe Wobbuffet used Celebrate!"); + } + } +} + +SINGLE_BATTLE_TEST("Gale Wings only grants priority to Flying-type moves") +{ + u32 move; + PARAMETRIZE { move = MOVE_AERIAL_ACE; } + PARAMETRIZE { move = MOVE_FLARE_BLITZ; } + GIVEN { + ASSUME(B_GALE_WINGS >= GEN_7); + ASSUME(gBattleMoves[MOVE_AERIAL_ACE].type == TYPE_FLYING); + ASSUME(gBattleMoves[MOVE_FLARE_BLITZ].type == TYPE_FIRE); + PLAYER(SPECIES_TALONFLAME) { Ability(ABILITY_GALE_WINGS); HP(100); MaxHP(100); Speed(1);} + OPPONENT(SPECIES_WOBBUFFET) { Speed(100);}; + } WHEN { + TURN { MOVE(player, move); } + } SCENE { + if (move == MOVE_AERIAL_ACE) { + MESSAGE("Talonflame used Aerial Ace!"); + } + else { + MESSAGE("Foe Wobbuffet used Celebrate!"); + } + } +} diff --git a/test/battle/ability/poison_heal.c b/test/battle/ability/poison_heal.c new file mode 100644 index 000000000..e0da5a715 --- /dev/null +++ b/test/battle/ability/poison_heal.c @@ -0,0 +1,62 @@ +#include "global.h" +#include "test/battle.h" + +SINGLE_BATTLE_TEST("Poison Heal heals from Poison damage") +{ + GIVEN { + PLAYER(SPECIES_SHROOMISH) { Ability(ABILITY_POISON_HEAL); Status1(STATUS1_POISON); HP(1), MaxHP(400); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_CELEBRATE); } + } SCENE { + ABILITY_POPUP(player, ABILITY_POISON_HEAL); + MESSAGE("The poisoning healed Shroomish a little bit!"); + HP_BAR(player, damage: -50); + } +} + +SINGLE_BATTLE_TEST("Poison Heal heals from Toxic Poison damage") +{ + GIVEN { + PLAYER(SPECIES_SHROOMISH) { Ability(ABILITY_POISON_HEAL); Status1(STATUS1_TOXIC_POISON); HP(1), MaxHP(400); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_CELEBRATE); } + } SCENE { + ABILITY_POPUP(player, ABILITY_POISON_HEAL); + MESSAGE("The poisoning healed Shroomish a little bit!"); + HP_BAR(player, damage: -50); + } +} + +SINGLE_BATTLE_TEST("Poison Heal does not heal or cause damage when under Heal Block") +{ + GIVEN { + PLAYER(SPECIES_SHROOMISH) { Ability(ABILITY_POISON_HEAL); Status1(STATUS1_POISON); HP(1), MaxHP(400); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_HEAL_BLOCK); } + } SCENE { + NONE_OF { + ABILITY_POPUP(player, ABILITY_POISON_HEAL); + MESSAGE("The poisoning healed Shroomish a little bit!"); + HP_BAR(player, damage: -50); + } + } +} + +SINGLE_BATTLE_TEST("Poison Heal activates before Toxic Orb") +{ + GIVEN { + PLAYER(SPECIES_SHROOMISH) { Ability(ABILITY_POISON_HEAL); Item(ITEM_TOXIC_ORB); HP(1), MaxHP(400); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_CELEBRATE); } + } SCENE { + NONE_OF { + ABILITY_POPUP(player, ABILITY_POISON_HEAL); + MESSAGE("The poisoning healed Shroomish a little bit!"); + HP_BAR(player, damage: -50); + } + } +} \ No newline at end of file diff --git a/test/battle/ability/sap_sipper.c b/test/battle/ability/sap_sipper.c new file mode 100644 index 000000000..175ea4d96 --- /dev/null +++ b/test/battle/ability/sap_sipper.c @@ -0,0 +1,55 @@ +#include "global.h" +#include "test/battle.h" + +SINGLE_BATTLE_TEST("Sap Sipper negates damage from Grass-type moves") +{ + GIVEN { + PLAYER(SPECIES_MARILL) { Ability(ABILITY_SAP_SIPPER); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_VINE_WHIP); } + } SCENE { + NONE_OF { HP_BAR(player); } + } +} + +SINGLE_BATTLE_TEST("Sap Sipper negates effects from Grass-type moves") +{ + GIVEN { + PLAYER(SPECIES_MARILL) { Ability(ABILITY_SAP_SIPPER); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_SPORE); } + } SCENE { + NONE_OF { ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, player); } + NONE_OF { STATUS_ICON(player, sleep: TRUE); } + } +} + +SINGLE_BATTLE_TEST("Sap Sipper increases Attack by one stage when hit by a Grass-type move") +{ + GIVEN { + PLAYER(SPECIES_MARILL) { Ability(ABILITY_SAP_SIPPER); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_VINE_WHIP); } + } SCENE { + ABILITY_POPUP(player, ABILITY_SAP_SIPPER); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Marill's Attack rose!"); + } +} + +SINGLE_BATTLE_TEST("Sap Sipper does not increase Attack if already maxed") +{ + GIVEN { + PLAYER(SPECIES_MARILL) { Ability(ABILITY_SAP_SIPPER); } + OPPONENT(SPECIES_WOBBUFFET) { Speed(1); } + } WHEN { + TURN { MOVE(player, MOVE_BELLY_DRUM); MOVE(opponent, MOVE_VINE_WHIP); } + } SCENE { + ABILITY_POPUP(player, ABILITY_SAP_SIPPER); + NONE_OF { ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); } + NONE_OF { MESSAGE("Marill's Attack rose!"); } + } +} \ No newline at end of file