From 9735c5d68e63a5aa9d10aff0a505784c804dff29 Mon Sep 17 00:00:00 2001 From: Bassoonian Date: Thu, 5 Oct 2023 23:12:30 +0200 Subject: [PATCH 1/3] Defeatist, Gale Wings, Poison Heal, Sap Sipper tests --- data/battle_scripts_1.s | 3 +- test/battle/ability/defeatist.c | 46 +++++++++++++++++++++++ test/battle/ability/gale_wings.c | 47 +++++++++++++++++++++++ test/battle/ability/poison_heal.c | 62 +++++++++++++++++++++++++++++++ test/battle/ability/sap_sipper.c | 55 +++++++++++++++++++++++++++ 5 files changed, 212 insertions(+), 1 deletion(-) create mode 100644 test/battle/ability/defeatist.c create mode 100644 test/battle/ability/gale_wings.c create mode 100644 test/battle/ability/poison_heal.c create mode 100644 test/battle/ability/sap_sipper.c 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 From cee84f0f74482d781beac15c245cb338fba738b9 Mon Sep 17 00:00:00 2001 From: Bassoonian Date: Fri, 6 Oct 2023 15:13:26 +0200 Subject: [PATCH 2/3] Fix issues and add more ability tests --- include/config/battle.h | 1 + src/battle_util.c | 4 +++ test/battle/ability/defeatist.c | 2 +- test/battle/ability/dragons_maw.c | 33 +++++++++++++++++++++ test/battle/ability/earth_eater.c | 46 +++++++++++++++++++++++++++++ test/battle/ability/gale_wings.c | 6 ++++ test/battle/ability/poison_heal.c | 25 ++++++++++++---- test/battle/ability/rocky_payload.c | 33 +++++++++++++++++++++ test/battle/ability/steelworker.c | 33 +++++++++++++++++++++ test/battle/ability/transistor.c | 38 ++++++++++++++++++++++++ 10 files changed, 215 insertions(+), 6 deletions(-) create mode 100644 test/battle/ability/dragons_maw.c create mode 100644 test/battle/ability/earth_eater.c create mode 100644 test/battle/ability/rocky_payload.c create mode 100644 test/battle/ability/steelworker.c create mode 100644 test/battle/ability/transistor.c diff --git a/include/config/battle.h b/include/config/battle.h index aee79daee..6f09b8ebf 100644 --- a/include/config/battle.h +++ b/include/config/battle.h @@ -126,6 +126,7 @@ #define B_ABSORBING_ABILITY_STRING GEN_LATEST // In Gen5+, the abilities that absorb moves of a certain type use a generic string for stat increases and decreases. #define B_LEAF_GUARD_PREVENTS_REST GEN_LATEST // In Gen5+, Leaf Guard prevents the use of Rest in harsh sunlight. #define B_SNOW_WARNING GEN_LATEST // In Gen9+, Snow Warning will summon snow instead of hail. +#define B_TRANSISTOR GEN_LATEST // In Gen9+, Transistor will only boost Electric-type moves by 1.3x as opposed to 1.5x. // Item settings #define B_HP_BERRIES GEN_LATEST // In Gen4+, berries which restore hp activate immediately after HP drops to half. In Gen3, the effect occurs at the end of the turn. diff --git a/src/battle_util.c b/src/battle_util.c index 25e5d87f2..d6dba1564 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -8964,7 +8964,11 @@ static inline u32 CalcMoveBasePowerAfterModifiers(u32 move, u32 battlerAtk, u32 break; case ABILITY_TRANSISTOR: if (moveType == TYPE_ELECTRIC) + #if B_TRANSISTOR >= GEN_9 + modifier = uq4_12_multiply(modifier, UQ_4_12(5325 / 4096)); + #else modifier = uq4_12_multiply(modifier, UQ_4_12(1.5)); + #endif break; case ABILITY_DRAGONS_MAW: if (moveType == TYPE_DRAGON) diff --git a/test/battle/ability/defeatist.c b/test/battle/ability/defeatist.c index a60144c46..820c7da35 100644 --- a/test/battle/ability/defeatist.c +++ b/test/battle/ability/defeatist.c @@ -43,4 +43,4 @@ SINGLE_BATTLE_TEST("Defeatist halves Special Attack when HP <= 50%", s16 damage) } 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/dragons_maw.c b/test/battle/ability/dragons_maw.c new file mode 100644 index 000000000..07bbef9ce --- /dev/null +++ b/test/battle/ability/dragons_maw.c @@ -0,0 +1,33 @@ +#include "global.h" +#include "test/battle.h" + +SINGLE_BATTLE_TEST("Dragon's Maw increases Dragon-type move damage", s16 damage) +{ + u32 move; + u16 ability; + + PARAMETRIZE { move = MOVE_TACKLE; ability = ABILITY_KLUTZ; } + PARAMETRIZE { move = MOVE_TACKLE; ability = ABILITY_DRAGONS_MAW; } + PARAMETRIZE { move = MOVE_DRAGON_CLAW; ability = ABILITY_KLUTZ; } + PARAMETRIZE { move = MOVE_DRAGON_CLAW; ability = ABILITY_DRAGONS_MAW; } + PARAMETRIZE { move = MOVE_DRAGON_BREATH; ability = ABILITY_KLUTZ; } + PARAMETRIZE { move = MOVE_DRAGON_BREATH; ability = ABILITY_DRAGONS_MAW; } + + GIVEN { + ASSUME(gBattleMoves[MOVE_TACKLE].type == TYPE_NORMAL); + ASSUME(gBattleMoves[MOVE_DRAGON_CLAW].type == TYPE_DRAGON); + ASSUME(gBattleMoves[MOVE_DRAGON_BREATH].type == TYPE_DRAGON); + ASSUME(gBattleMoves[MOVE_DRAGON_CLAW].split == SPLIT_PHYSICAL); + ASSUME(gBattleMoves[MOVE_DRAGON_BREATH].split == SPLIT_SPECIAL); + PLAYER(SPECIES_REGIDRAGO) { Ability(ability); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, move); } + } SCENE { + HP_BAR(opponent, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_EQ(results[0].damage, results[1].damage); // Tackle should be unaffected + EXPECT_MUL_EQ(results[2].damage, Q_4_12(1.5), results[3].damage); // Dragon Claw should be affected + EXPECT_MUL_EQ(results[4].damage, Q_4_12(1.5), results[5].damage); // Dragon Breath should be affected + } +} diff --git a/test/battle/ability/earth_eater.c b/test/battle/ability/earth_eater.c new file mode 100644 index 000000000..a0ba2b54d --- /dev/null +++ b/test/battle/ability/earth_eater.c @@ -0,0 +1,46 @@ +#include "global.h" +#include "test/battle.h" + +SINGLE_BATTLE_TEST("Earth Eater heals 25% when hit by ground type moves") +{ + GIVEN { + ASSUME(gBattleMoves[MOVE_MUD_SLAP].type == TYPE_GROUND); + PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_EARTH_EATER); HP(1); MaxHP(100); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_MUD_SLAP); } + } SCENE { + ABILITY_POPUP(player, ABILITY_EARTH_EATER); + HP_BAR(player, damage: -25); + MESSAGE("Wobbuffet restored HP using its Earth Eater!"); + } +} + +SINGLE_BATTLE_TEST("Earth Eater does not activate if protected") +{ + GIVEN { + ASSUME(gBattleMoves[MOVE_MUD_SLAP].type == TYPE_GROUND); + PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_EARTH_EATER); HP(1); MaxHP(100); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_PROTECT); MOVE(opponent, MOVE_MUD_SLAP); } + } SCENE { + NONE_OF { ABILITY_POPUP(player, ABILITY_EARTH_EATER); HP_BAR(player); MESSAGE("Wobbuffet restored HP using its Earth Eater!"); } + } +} + +SINGLE_BATTLE_TEST("Earth Eater activates on status moves") +{ + GIVEN { + ASSUME(gBattleMoves[MOVE_SAND_ATTACK].type == TYPE_GROUND); + ASSUME(gBattleMoves[MOVE_SAND_ATTACK].split == SPLIT_STATUS); + PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_EARTH_EATER); HP(1); MaxHP(100); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_SAND_ATTACK); } + } SCENE { + ABILITY_POPUP(player, ABILITY_EARTH_EATER); + HP_BAR(player, damage: -25); + MESSAGE("Wobbuffet restored HP using its Earth Eater!"); + } +} diff --git a/test/battle/ability/gale_wings.c b/test/battle/ability/gale_wings.c index 26c7349e0..d44bfb4d4 100644 --- a/test/battle/ability/gale_wings.c +++ b/test/battle/ability/gale_wings.c @@ -16,9 +16,11 @@ SINGLE_BATTLE_TEST("Gale Wings only grants priority at full HP") } SCENE { if (hp == 100) { MESSAGE("Talonflame used Aerial Ace!"); + MESSAGE("Foe Wobbuffet used Celebrate!"); } else { MESSAGE("Foe Wobbuffet used Celebrate!"); + MESSAGE("Talonflame used Aerial Ace!"); } } } @@ -39,9 +41,13 @@ SINGLE_BATTLE_TEST("Gale Wings only grants priority to Flying-type moves") } SCENE { if (move == MOVE_AERIAL_ACE) { MESSAGE("Talonflame used Aerial Ace!"); + MESSAGE("Foe Wobbuffet used Celebrate!"); } else { MESSAGE("Foe Wobbuffet used Celebrate!"); + MESSAGE("Talonflame used Flare Blitz!"); } } } + +TO_DO_BATTLE_TEST("Gale Wings doesn't increase priority of Flying-type Hidden Power, Natural Gift, Judgment or Tera Blast"); diff --git a/test/battle/ability/poison_heal.c b/test/battle/ability/poison_heal.c index e0da5a715..f79f8065c 100644 --- a/test/battle/ability/poison_heal.c +++ b/test/battle/ability/poison_heal.c @@ -1,10 +1,14 @@ #include "global.h" #include "test/battle.h" -SINGLE_BATTLE_TEST("Poison Heal heals from Poison damage") +SINGLE_BATTLE_TEST("Poison Heal heals from (Toxic) Poison damage") { + u8 status; + PARAMETRIZE { status=STATUS1_POISON; } + PARAMETRIZE { status=STATUS1_TOXIC_POISON; } + GIVEN { - PLAYER(SPECIES_SHROOMISH) { Ability(ABILITY_POISON_HEAL); Status1(STATUS1_POISON); HP(1), MaxHP(400); } + PLAYER(SPECIES_SHROOMISH) { Ability(ABILITY_POISON_HEAL); Status1(status); HP(1), MaxHP(400); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { TURN { MOVE(player, MOVE_CELEBRATE); } @@ -15,17 +19,27 @@ SINGLE_BATTLE_TEST("Poison Heal heals from Poison damage") } } -SINGLE_BATTLE_TEST("Poison Heal heals from Toxic Poison damage") +SINGLE_BATTLE_TEST("Poison Heal heals from Toxic Poison damage are constant") { + s16 turnOneHit; + s16 turnTwoHit; + 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); } + 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); + HP_BAR(player, captureDamage: &turnOneHit); + + ABILITY_POPUP(player, ABILITY_POISON_HEAL); + MESSAGE("The poisoning healed Shroomish a little bit!"); + HP_BAR(player, captureDamage: &turnTwoHit); + } THEN { + EXPECT_EQ(turnOneHit, turnTwoHit); } } @@ -57,6 +71,7 @@ SINGLE_BATTLE_TEST("Poison Heal activates before Toxic Orb") ABILITY_POPUP(player, ABILITY_POISON_HEAL); MESSAGE("The poisoning healed Shroomish a little bit!"); HP_BAR(player, damage: -50); + HP_BAR(player, damage: 50); } } -} \ No newline at end of file +} diff --git a/test/battle/ability/rocky_payload.c b/test/battle/ability/rocky_payload.c new file mode 100644 index 000000000..13efc9acf --- /dev/null +++ b/test/battle/ability/rocky_payload.c @@ -0,0 +1,33 @@ +#include "global.h" +#include "test/battle.h" + +SINGLE_BATTLE_TEST("Rocky Payload increases Rock-type move damage", s16 damage) +{ + u32 move; + u16 ability; + + PARAMETRIZE { move = MOVE_TACKLE; ability = ABILITY_BIG_PECKS; } + PARAMETRIZE { move = MOVE_TACKLE; ability = ABILITY_ROCKY_PAYLOAD; } + PARAMETRIZE { move = MOVE_ROCK_THROW; ability = ABILITY_BIG_PECKS; } + PARAMETRIZE { move = MOVE_ROCK_THROW; ability = ABILITY_ROCKY_PAYLOAD; } + PARAMETRIZE { move = MOVE_POWER_GEM; ability = ABILITY_BIG_PECKS; } + PARAMETRIZE { move = MOVE_POWER_GEM; ability = ABILITY_ROCKY_PAYLOAD; } + + GIVEN { + ASSUME(gBattleMoves[MOVE_TACKLE].type == TYPE_NORMAL); + ASSUME(gBattleMoves[MOVE_ROCK_THROW].type == TYPE_ROCK); + ASSUME(gBattleMoves[MOVE_POWER_GEM].type == TYPE_ROCK); + ASSUME(gBattleMoves[MOVE_ROCK_THROW].split == SPLIT_PHYSICAL); + ASSUME(gBattleMoves[MOVE_POWER_GEM].split == SPLIT_SPECIAL); + PLAYER(SPECIES_WOBBUFFET) { Ability(ability); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, move); } + } SCENE { + HP_BAR(opponent, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_EQ(results[0].damage, results[1].damage); // Tackle should be unaffected + EXPECT_MUL_EQ(results[2].damage, Q_4_12(1.5), results[3].damage); // Rock Throw should be affected + EXPECT_MUL_EQ(results[4].damage, Q_4_12(1.5), results[5].damage); // Power Gem should be affected + } +} diff --git a/test/battle/ability/steelworker.c b/test/battle/ability/steelworker.c new file mode 100644 index 000000000..73637a588 --- /dev/null +++ b/test/battle/ability/steelworker.c @@ -0,0 +1,33 @@ +#include "global.h" +#include "test/battle.h" + +SINGLE_BATTLE_TEST("Steelworker increases Steel-type move damage", s16 damage) +{ + u32 move; + u16 ability; + + PARAMETRIZE { move = MOVE_TACKLE; ability = ABILITY_KLUTZ; } + PARAMETRIZE { move = MOVE_TACKLE; ability = ABILITY_STEELWORKER; } + PARAMETRIZE { move = MOVE_ANCHOR_SHOT; ability = ABILITY_KLUTZ; } + PARAMETRIZE { move = MOVE_ANCHOR_SHOT; ability = ABILITY_STEELWORKER; } + PARAMETRIZE { move = MOVE_FLASH_CANNON; ability = ABILITY_KLUTZ; } + PARAMETRIZE { move = MOVE_FLASH_CANNON; ability = ABILITY_STEELWORKER; } + + GIVEN { + ASSUME(gBattleMoves[MOVE_TACKLE].type == TYPE_NORMAL); + ASSUME(gBattleMoves[MOVE_ANCHOR_SHOT].type == TYPE_STEEL); + ASSUME(gBattleMoves[MOVE_FLASH_CANNON].type == TYPE_STEEL); + ASSUME(gBattleMoves[MOVE_ANCHOR_SHOT].split == SPLIT_PHYSICAL); + ASSUME(gBattleMoves[MOVE_FLASH_CANNON].split == SPLIT_SPECIAL); + PLAYER(SPECIES_DHELMISE) { Ability(ability); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, move); } + } SCENE { + HP_BAR(opponent, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_EQ(results[0].damage, results[1].damage); // Tackle should be unaffected + EXPECT_MUL_EQ(results[2].damage, Q_4_12(1.5), results[3].damage); // Anchor Shot should be affected + EXPECT_MUL_EQ(results[4].damage, Q_4_12(1.5), results[5].damage); // Flash Cannon should be affected + } +} diff --git a/test/battle/ability/transistor.c b/test/battle/ability/transistor.c new file mode 100644 index 000000000..344f554f0 --- /dev/null +++ b/test/battle/ability/transistor.c @@ -0,0 +1,38 @@ +#include "global.h" +#include "test/battle.h" + +SINGLE_BATTLE_TEST("Transistor increases Electric-type move damage", s16 damage) +{ + u32 move; + u16 ability; + + PARAMETRIZE { move = MOVE_TACKLE; ability = ABILITY_KLUTZ; } + PARAMETRIZE { move = MOVE_TACKLE; ability = ABILITY_TRANSISTOR; } + PARAMETRIZE { move = MOVE_WILD_CHARGE; ability = ABILITY_KLUTZ; } + PARAMETRIZE { move = MOVE_WILD_CHARGE; ability = ABILITY_TRANSISTOR; } + PARAMETRIZE { move = MOVE_THUNDER_SHOCK; ability = ABILITY_KLUTZ; } + PARAMETRIZE { move = MOVE_THUNDER_SHOCK; ability = ABILITY_TRANSISTOR; } + + GIVEN { + ASSUME(gBattleMoves[MOVE_TACKLE].type == TYPE_NORMAL); + ASSUME(gBattleMoves[MOVE_WILD_CHARGE].type == TYPE_ELECTRIC); + ASSUME(gBattleMoves[MOVE_THUNDER_SHOCK].type == TYPE_ELECTRIC); + ASSUME(gBattleMoves[MOVE_WILD_CHARGE].split == SPLIT_PHYSICAL); + ASSUME(gBattleMoves[MOVE_THUNDER_SHOCK].split == SPLIT_SPECIAL); + PLAYER(SPECIES_REGIELEKI) { Ability(ability); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, move); } + } SCENE { + HP_BAR(opponent, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_EQ(results[0].damage, results[1].damage); // Tackle should be unaffected + #if B_TRANSISTOR >= GEN_9 + EXPECT_MUL_EQ(results[2].damage, Q_4_12(5325 / 4096), results[3].damage); // Wild Charge should be affected + EXPECT_MUL_EQ(results[4].damage, Q_4_12(5325 / 4096), results[5].damage); // Thunder Shock should be affected + #else + EXPECT_MUL_EQ(results[2].damage, Q_4_12(1.5), results[3].damage); // Wild Charge should be affected + EXPECT_MUL_EQ(results[4].damage, Q_4_12(1.5), results[5].damage); // Thunder Shock should be affected + #endif + } +} From 8c9ea8b7869d2a540d83bb199296cb4d80baa05e Mon Sep 17 00:00:00 2001 From: Bassoonian Date: Wed, 11 Oct 2023 16:11:46 +0200 Subject: [PATCH 3/3] Incorporate requested changes --- test/battle/ability/dragons_maw.c | 2 +- test/battle/ability/poison_heal.c | 8 ++++---- test/battle/ability/rocky_payload.c | 2 +- test/battle/ability/sap_sipper.c | 2 +- test/battle/ability/steelworker.c | 2 +- test/battle/ability/transistor.c | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/test/battle/ability/dragons_maw.c b/test/battle/ability/dragons_maw.c index 07bbef9ce..af633d81d 100644 --- a/test/battle/ability/dragons_maw.c +++ b/test/battle/ability/dragons_maw.c @@ -14,7 +14,7 @@ SINGLE_BATTLE_TEST("Dragon's Maw increases Dragon-type move damage", s16 damage) PARAMETRIZE { move = MOVE_DRAGON_BREATH; ability = ABILITY_DRAGONS_MAW; } GIVEN { - ASSUME(gBattleMoves[MOVE_TACKLE].type == TYPE_NORMAL); + ASSUME(gBattleMoves[MOVE_TACKLE].type != TYPE_DRAGON); ASSUME(gBattleMoves[MOVE_DRAGON_CLAW].type == TYPE_DRAGON); ASSUME(gBattleMoves[MOVE_DRAGON_BREATH].type == TYPE_DRAGON); ASSUME(gBattleMoves[MOVE_DRAGON_CLAW].split == SPLIT_PHYSICAL); diff --git a/test/battle/ability/poison_heal.c b/test/battle/ability/poison_heal.c index f79f8065c..2ee7620c6 100644 --- a/test/battle/ability/poison_heal.c +++ b/test/battle/ability/poison_heal.c @@ -4,8 +4,8 @@ SINGLE_BATTLE_TEST("Poison Heal heals from (Toxic) Poison damage") { u8 status; - PARAMETRIZE { status=STATUS1_POISON; } - PARAMETRIZE { status=STATUS1_TOXIC_POISON; } + PARAMETRIZE { status = STATUS1_POISON; } + PARAMETRIZE { status = STATUS1_TOXIC_POISON; } GIVEN { PLAYER(SPECIES_SHROOMISH) { Ability(ABILITY_POISON_HEAL); Status1(status); HP(1), MaxHP(400); } @@ -28,8 +28,8 @@ SINGLE_BATTLE_TEST("Poison Heal heals from Toxic Poison damage are constant") PLAYER(SPECIES_SHROOMISH) { Ability(ABILITY_POISON_HEAL); Status1(STATUS1_TOXIC_POISON); HP(1), MaxHP(400); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { - TURN { MOVE(player, MOVE_CELEBRATE); } - TURN { MOVE(player, MOVE_CELEBRATE); } + TURN { } + TURN { } } SCENE { ABILITY_POPUP(player, ABILITY_POISON_HEAL); MESSAGE("The poisoning healed Shroomish a little bit!"); diff --git a/test/battle/ability/rocky_payload.c b/test/battle/ability/rocky_payload.c index 13efc9acf..498b09c9d 100644 --- a/test/battle/ability/rocky_payload.c +++ b/test/battle/ability/rocky_payload.c @@ -14,7 +14,7 @@ SINGLE_BATTLE_TEST("Rocky Payload increases Rock-type move damage", s16 damage) PARAMETRIZE { move = MOVE_POWER_GEM; ability = ABILITY_ROCKY_PAYLOAD; } GIVEN { - ASSUME(gBattleMoves[MOVE_TACKLE].type == TYPE_NORMAL); + ASSUME(gBattleMoves[MOVE_TACKLE].type != TYPE_ROCK); ASSUME(gBattleMoves[MOVE_ROCK_THROW].type == TYPE_ROCK); ASSUME(gBattleMoves[MOVE_POWER_GEM].type == TYPE_ROCK); ASSUME(gBattleMoves[MOVE_ROCK_THROW].split == SPLIT_PHYSICAL); diff --git a/test/battle/ability/sap_sipper.c b/test/battle/ability/sap_sipper.c index 175ea4d96..89ec42249 100644 --- a/test/battle/ability/sap_sipper.c +++ b/test/battle/ability/sap_sipper.c @@ -52,4 +52,4 @@ SINGLE_BATTLE_TEST("Sap Sipper does not increase Attack if already maxed") NONE_OF { ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); } NONE_OF { MESSAGE("Marill's Attack rose!"); } } -} \ No newline at end of file +} diff --git a/test/battle/ability/steelworker.c b/test/battle/ability/steelworker.c index 73637a588..bf7d0ca9c 100644 --- a/test/battle/ability/steelworker.c +++ b/test/battle/ability/steelworker.c @@ -14,7 +14,7 @@ SINGLE_BATTLE_TEST("Steelworker increases Steel-type move damage", s16 damage) PARAMETRIZE { move = MOVE_FLASH_CANNON; ability = ABILITY_STEELWORKER; } GIVEN { - ASSUME(gBattleMoves[MOVE_TACKLE].type == TYPE_NORMAL); + ASSUME(gBattleMoves[MOVE_TACKLE].type != TYPE_STEEL); ASSUME(gBattleMoves[MOVE_ANCHOR_SHOT].type == TYPE_STEEL); ASSUME(gBattleMoves[MOVE_FLASH_CANNON].type == TYPE_STEEL); ASSUME(gBattleMoves[MOVE_ANCHOR_SHOT].split == SPLIT_PHYSICAL); diff --git a/test/battle/ability/transistor.c b/test/battle/ability/transistor.c index 344f554f0..3da12c832 100644 --- a/test/battle/ability/transistor.c +++ b/test/battle/ability/transistor.c @@ -14,7 +14,7 @@ SINGLE_BATTLE_TEST("Transistor increases Electric-type move damage", s16 damage) PARAMETRIZE { move = MOVE_THUNDER_SHOCK; ability = ABILITY_TRANSISTOR; } GIVEN { - ASSUME(gBattleMoves[MOVE_TACKLE].type == TYPE_NORMAL); + ASSUME(gBattleMoves[MOVE_TACKLE].type != TYPE_ELECTRIC); ASSUME(gBattleMoves[MOVE_WILD_CHARGE].type == TYPE_ELECTRIC); ASSUME(gBattleMoves[MOVE_THUNDER_SHOCK].type == TYPE_ELECTRIC); ASSUME(gBattleMoves[MOVE_WILD_CHARGE].split == SPLIT_PHYSICAL);