From 8c4396ddafc329ac37beb6e895e7dc81c28da835 Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 29 Mar 2023 13:01:20 +0200 Subject: [PATCH] Gen9 move tests batch2 --- include/random.h | 1 + src/battle_script_commands.c | 6 ++-- test/move_effect_axe_kick.c | 54 ++++++++++++++++++++++++++++ test/move_effect_infernal_parade.c | 48 +++++++++++++++++++++++++ test/move_effect_take_heart.c | 47 +++++++++++++++++++++++++ test/move_effect_triple_arrows.c | 56 ++++++++++++++++++++++++++++++ 6 files changed, 209 insertions(+), 3 deletions(-) create mode 100644 test/move_effect_axe_kick.c create mode 100644 test/move_effect_infernal_parade.c create mode 100644 test/move_effect_take_heart.c create mode 100644 test/move_effect_triple_arrows.c diff --git a/include/random.h b/include/random.h index 60c718348..14b6a253e 100644 --- a/include/random.h +++ b/include/random.h @@ -60,6 +60,7 @@ enum RandomTag RNG_SPEED_TIE, RNG_STATIC, RNG_STENCH, + RNG_TRIPLE_ARROWS, }; #define RandomWeighted(tag, ...) \ diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 38e949131..775f8c456 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -3801,13 +3801,13 @@ void SetMoveEffect(bool32 primary, u32 certain) break; case MOVE_EFFECT_TRIPLE_ARROWS: { - u8 randomChance = Random() % 100; - if (randomChance < 50) // Chance to reduce a foe's Defense by 1 stat stage. + u8 randomChance = RandomUniform(RNG_TRIPLE_ARROWS, 1, 10); + if (randomChance <= 5) // Chance to reduce a foe's Defense by 1 stat stage. { BattleScriptPush(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = BattleScript_DefDown; } - if (randomChance >= 50 && randomChance <= 80) // Chance to cause a foe to flinch. + if (randomChance > 5 && randomChance <= 8) // Chance to cause a foe to flinch. { if (battlerAbility == ABILITY_INNER_FOCUS && (primary == TRUE || certain == MOVE_EFFECT_CERTAIN)) { diff --git a/test/move_effect_axe_kick.c b/test/move_effect_axe_kick.c new file mode 100644 index 000000000..cf04e601e --- /dev/null +++ b/test/move_effect_axe_kick.c @@ -0,0 +1,54 @@ +#include "global.h" +#include "test_battle.h" + +ASSUMPTIONS +{ + ASSUME(gBattleMoves[MOVE_AXE_KICK].effect == EFFECT_AXE_KICK); +} + +SINGLE_BATTLE_TEST("Axe Kick confuses the target") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_AXE_KICK); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_AXE_KICK, player); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_CONFUSION, opponent); + MESSAGE("Foe Wobbuffet became confused!"); + } +} + +SINGLE_BATTLE_TEST("Axe Kick deals damage half the hp to user if def battler protected") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_PROTECT); MOVE(player, MOVE_AXE_KICK); } + } SCENE { + s32 maxHP = GetMonData(&PLAYER_PARTY[0], MON_DATA_MAX_HP); + ANIMATION(ANIM_TYPE_MOVE, MOVE_PROTECT, opponent); + MESSAGE("Foe Wobbuffet protected itself!"); + MESSAGE("Foe Wobbuffet protected itself!"); + MESSAGE("Wobbuffet kept going and crashed!"); + HP_BAR(player, hp: maxHP / 2); + } +} + +SINGLE_BATTLE_TEST("Axe Kick deals damage half the hp to user if it fails") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_AXE_KICK, hit: FALSE); } + } SCENE { + s32 maxHP = GetMonData(&PLAYER_PARTY[0], MON_DATA_MAX_HP); + MESSAGE("Wobbuffet used Axe Kick!"); + MESSAGE("Wobbuffet's attack missed!"); + MESSAGE("Wobbuffet kept going and crashed!"); + HP_BAR(player, hp: maxHP / 2); + } +} diff --git a/test/move_effect_infernal_parade.c b/test/move_effect_infernal_parade.c new file mode 100644 index 000000000..5b951eca1 --- /dev/null +++ b/test/move_effect_infernal_parade.c @@ -0,0 +1,48 @@ +#include "global.h" +#include "test_battle.h" + +ASSUMPTIONS +{ + ASSUME(gBattleMoves[MOVE_INFERNAL_PARADE].effect == EFFECT_INFERNAL_PARADE); +} + +SINGLE_BATTLE_TEST("Infernal Parade inflicts poison") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_INFERNAL_PARADE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_INFERNAL_PARADE, player); + HP_BAR(opponent); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_BRN, opponent); + STATUS_ICON(opponent, burn: TRUE); + } +} + +SINGLE_BATTLE_TEST("Infernal Parade's power doubles if the target has a status condition", s16 damage) +{ + u32 status1; + PARAMETRIZE { status1 = STATUS1_NONE; } + PARAMETRIZE { status1 = STATUS1_SLEEP; } + PARAMETRIZE { status1 = STATUS1_POISON; } + PARAMETRIZE { status1 = STATUS1_BURN; } + PARAMETRIZE { status1 = STATUS1_FREEZE; } + PARAMETRIZE { status1 = STATUS1_PARALYSIS; } + PARAMETRIZE { status1 = STATUS1_TOXIC_POISON; } + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET) { Status1(status1); }; + } WHEN { + TURN { MOVE(player, MOVE_INFERNAL_PARADE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_INFERNAL_PARADE, player); + HP_BAR(opponent, captureDamage: &results[i].damage); + } THEN { + if (i > 0) + EXPECT_MUL_EQ(results[0].damage, Q_4_12(2.0), results[i].damage); + if (i > 1) + EXPECT_EQ(results[i-1].damage, results[i].damage); + } +} diff --git a/test/move_effect_take_heart.c b/test/move_effect_take_heart.c new file mode 100644 index 000000000..82745957f --- /dev/null +++ b/test/move_effect_take_heart.c @@ -0,0 +1,47 @@ +#include "global.h" +#include "test_battle.h" + +ASSUMPTIONS +{ + ASSUME(gBattleMoves[MOVE_TAKE_HEART].effect == EFFECT_TAKE_HEART); +} + +SINGLE_BATTLE_TEST("Take Heart increases Sp. Atk and Sp. Def by one stage") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_TAKE_HEART); } + } SCENE { + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + } +} + +SINGLE_BATTLE_TEST("Take Heart cures the user of all status conditions") +{ + u32 status1; + PARAMETRIZE { status1 = STATUS1_SLEEP; } + PARAMETRIZE { status1 = STATUS1_POISON; } + PARAMETRIZE { status1 = STATUS1_FREEZE; } + PARAMETRIZE { status1 = STATUS1_BURN; } + PARAMETRIZE { status1 = STATUS1_PARALYSIS; } + PARAMETRIZE { status1 = STATUS1_TOXIC_POISON; } + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Status1(status1); }; + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_TAKE_HEART); } + } SCENE { + if (status1 == STATUS1_SLEEP) { + MESSAGE("Wobbuffet is fast asleep."); + } else if (status1 == STATUS1_FREEZE) { + PASSES_RANDOMLY(20, 100, RNG_FROZEN); + STATUS_ICON(player, none: TRUE); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + } else { + MESSAGE("Wobbuffet's status returned to normal!"); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + } + } +} diff --git a/test/move_effect_triple_arrows.c b/test/move_effect_triple_arrows.c new file mode 100644 index 000000000..4dd717d80 --- /dev/null +++ b/test/move_effect_triple_arrows.c @@ -0,0 +1,56 @@ +#include "global.h" +#include "test_battle.h" + +ASSUMPTIONS +{ + ASSUME(gBattleMoves[MOVE_TRIPLE_ARROWS].effect == EFFECT_TRIPLE_ARROWS); +} + +SINGLE_BATTLE_TEST("Triple Arrows lower's defense by one stage") +{ + PASSES_RANDOMLY(50, 100, RNG_TRIPLE_ARROWS); + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_TRIPLE_ARROWS); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_TRIPLE_ARROWS, player); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); + MESSAGE("Foe Wobbuffet's defense fell!"); + } +} + +SINGLE_BATTLE_TEST("Triple Arrows flinch 30% of the time") +{ + PASSES_RANDOMLY(30, 100, RNG_TRIPLE_ARROWS); + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_TRIPLE_ARROWS); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_TRIPLE_ARROWS, player); + NONE_OF { + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); + MESSAGE("Foe Wobbuffet's defense fell!"); + } + MESSAGE("Foe Wobbuffet flinched!"); + } +} + +SINGLE_BATTLE_TEST("Triple Arrows lands a critical hit") +{ + ASSUME(B_CRIT_CHANCE >= GEN_7); + ASSUME(gBattleMoves[MOVE_TRIPLE_ARROWS].flags & FLAG_HIGH_CRIT); + PASSES_RANDOMLY(1, 8, RNG_CRITICAL_HIT); + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_TRIPLE_ARROWS); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_TRIPLE_ARROWS, player); + MESSAGE("A critical hit!"); + } +} \ No newline at end of file