From 6987ae560507b424206890cea10911a683ec7927 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Wed, 4 Oct 2023 13:23:35 +0200 Subject: [PATCH 1/5] tests for intimidate defiant --- test/battle/ability/defiant.c | 117 ++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 test/battle/ability/defiant.c diff --git a/test/battle/ability/defiant.c b/test/battle/ability/defiant.c new file mode 100644 index 000000000000..4b9cfa42b502 --- /dev/null +++ b/test/battle/ability/defiant.c @@ -0,0 +1,117 @@ +#include "global.h" +#include "test/battle.h" + +DOUBLE_BATTLE_TEST("Defiant sharply raises player's Attack after Intimidate") +{ + u32 abilityLeft, abilityRight; + + PARAMETRIZE { abilityLeft = ABILITY_VITAL_SPIRIT; abilityRight = ABILITY_VITAL_SPIRIT; } + PARAMETRIZE { abilityLeft = ABILITY_VITAL_SPIRIT; abilityRight = ABILITY_DEFIANT; } + PARAMETRIZE { abilityLeft = ABILITY_DEFIANT; abilityRight = ABILITY_VITAL_SPIRIT; } + PARAMETRIZE { abilityLeft = ABILITY_DEFIANT; abilityRight = ABILITY_DEFIANT; } + + GIVEN { + PLAYER(SPECIES_MANKEY) { Ability(abilityLeft); } + PLAYER(SPECIES_PRIMEAPE) { Ability(abilityRight); } + OPPONENT(SPECIES_GYARADOS) { Ability(ABILITY_INTIMIDATE); } + OPPONENT(SPECIES_ARBOK) { Ability(ABILITY_INTIMIDATE); } + } WHEN { + TURN { MOVE(playerLeft, MOVE_TACKLE, target:opponentLeft); MOVE(playerRight, MOVE_TACKLE, target:opponentRight); } + } SCENE { + //1st mon Intimidate + ABILITY_POPUP(opponentLeft, ABILITY_INTIMIDATE); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerLeft); + MESSAGE("Foe Gyarados's Intimidate cuts Mankey's attack!"); + if (abilityLeft == ABILITY_DEFIANT) { + ABILITY_POPUP(playerLeft, ABILITY_DEFIANT); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerLeft); + MESSAGE("Mankey's Attack sharply rose!"); + } + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerRight); + MESSAGE("Foe Gyarados's Intimidate cuts Primeape's attack!"); + if (abilityRight == ABILITY_DEFIANT) { + ABILITY_POPUP(playerRight, ABILITY_DEFIANT); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerRight); + MESSAGE("Primeape's Attack sharply rose!"); + } + + //2nd mon Intimidate + ABILITY_POPUP(opponentRight, ABILITY_INTIMIDATE); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerLeft); + MESSAGE("Foe Arbok's Intimidate cuts Mankey's attack!"); + if (abilityLeft == ABILITY_DEFIANT) { + ABILITY_POPUP(playerLeft, ABILITY_DEFIANT); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerLeft); + MESSAGE("Mankey's Attack sharply rose!"); + } + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerRight); + MESSAGE("Foe Arbok's Intimidate cuts Primeape's attack!"); + if (abilityRight == ABILITY_DEFIANT) { + ABILITY_POPUP(playerRight, ABILITY_DEFIANT); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerRight); + MESSAGE("Primeape's Attack sharply rose!"); + } + } FINALLY { + // -2 from Intimidates and +4 from Defiants gets +2 total + EXPECT_EQ(playerLeft->statStages[STAT_ATK], (abilityLeft == ABILITY_DEFIANT) ? DEFAULT_STAT_STAGE + 2 : DEFAULT_STAT_STAGE - 2); + EXPECT_EQ(playerRight->statStages[STAT_ATK], (abilityRight == ABILITY_DEFIANT) ? DEFAULT_STAT_STAGE + 2 : DEFAULT_STAT_STAGE - 2); + } +} + +// Same as above, but for opponent. +DOUBLE_BATTLE_TEST("Defiant sharply raises opponent's Attack after Intimidate") +{ + u32 abilityLeft, abilityRight; + + PARAMETRIZE { abilityLeft = ABILITY_VITAL_SPIRIT; abilityRight = ABILITY_VITAL_SPIRIT; } + PARAMETRIZE { abilityLeft = ABILITY_VITAL_SPIRIT; abilityRight = ABILITY_DEFIANT; } + PARAMETRIZE { abilityLeft = ABILITY_DEFIANT; abilityRight = ABILITY_VITAL_SPIRIT; } + PARAMETRIZE { abilityLeft = ABILITY_DEFIANT; abilityRight = ABILITY_DEFIANT; } + + GIVEN { + OPPONENT(SPECIES_MANKEY) { Ability(abilityLeft); } + OPPONENT(SPECIES_PRIMEAPE) { Ability(abilityRight); } + PLAYER(SPECIES_GYARADOS) { Ability(ABILITY_INTIMIDATE); } + PLAYER(SPECIES_ARBOK) { Ability(ABILITY_INTIMIDATE); } + } WHEN { + TURN { MOVE(opponentLeft, MOVE_TACKLE, target:playerLeft); MOVE(opponentRight, MOVE_TACKLE, target:playerRight); } + } SCENE { + //1st mon Intimidate + ABILITY_POPUP(playerLeft, ABILITY_INTIMIDATE); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentLeft); + MESSAGE("Gyarados's Intimidate cuts Foe Mankey's attack!"); + if (abilityLeft == ABILITY_DEFIANT) { + ABILITY_POPUP(opponentLeft, ABILITY_DEFIANT); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentLeft); + MESSAGE("Foe Mankey's Attack sharply rose!"); + } + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentRight); + MESSAGE("Gyarados's Intimidate cuts Foe Primeape's attack!"); + if (abilityRight == ABILITY_DEFIANT) { + ABILITY_POPUP(opponentRight, ABILITY_DEFIANT); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentRight); + MESSAGE("Foe Primeape's Attack sharply rose!"); + } + + //2nd mon Intimidate + ABILITY_POPUP(playerRight, ABILITY_INTIMIDATE); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentLeft); + MESSAGE("Arbok's Intimidate cuts Foe Mankey's attack!"); + if (abilityLeft == ABILITY_DEFIANT) { + ABILITY_POPUP(opponentLeft, ABILITY_DEFIANT); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentLeft); + MESSAGE("Foe Mankey's Attack sharply rose!"); + } + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentRight); + MESSAGE("Arbok's Intimidate cuts Foe Primeape's attack!"); + if (abilityRight == ABILITY_DEFIANT) { + ABILITY_POPUP(opponentRight, ABILITY_DEFIANT); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentRight); + MESSAGE("Foe Primeape's Attack sharply rose!"); + } + } FINALLY { + // -2 from Intimidates and +4 from Defiants gets +2 total + EXPECT_EQ(opponentLeft->statStages[STAT_ATK], (abilityLeft == ABILITY_DEFIANT) ? DEFAULT_STAT_STAGE + 2 : DEFAULT_STAT_STAGE - 2); + EXPECT_EQ(opponentRight->statStages[STAT_ATK], (abilityRight == ABILITY_DEFIANT) ? DEFAULT_STAT_STAGE + 2 : DEFAULT_STAT_STAGE - 2); + } +} From ea75b458fb90c4bd364c741f0b1b3d458eaecd9b Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Wed, 4 Oct 2023 13:23:45 +0200 Subject: [PATCH 2/5] sheer force fix + tests --- include/test/battle.h | 6 ++-- src/battle_script_commands.c | 2 +- test/battle/ability/sheer_force.c | 56 +++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 4 deletions(-) create mode 100644 test/battle/ability/sheer_force.c diff --git a/include/test/battle.h b/include/test/battle.h index e1b00efbdd20..c203762a44b0 100644 --- a/include/test/battle.h +++ b/include/test/battle.h @@ -600,9 +600,9 @@ struct BattleTestData struct BattleTestRunnerState { u8 battlersCount; - u8 parametersCount; // Valid only in BattleTest_Setup. - u8 parameters; - u8 runParameter; + u16 parametersCount; // Valid only in BattleTest_Setup. + u16 parameters; + u16 runParameter; u16 rngTag; u16 rngTrialOffset; u16 trials; diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index d9e8349241f8..1a1a0a86855d 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -2828,7 +2828,7 @@ void SetMoveEffect(bool32 primary, u32 certain) && !primary && gBattleScripting.moveEffect <= MOVE_EFFECT_CONFUSION) INCREMENT_RESET_RETURN - if (TestSheerForceFlag(gBattlerAttacker, gCurrentMove) && affectsUser != MOVE_EFFECT_AFFECTS_USER) + if (TestSheerForceFlag(gBattlerAttacker, gCurrentMove) && gBattleScripting.moveEffect != MOVE_EFFECT_CHARGING) INCREMENT_RESET_RETURN if (gBattleMons[gEffectBattler].hp == 0 && !activateAfterFaint) diff --git a/test/battle/ability/sheer_force.c b/test/battle/ability/sheer_force.c new file mode 100644 index 000000000000..6bff0bcd00cf --- /dev/null +++ b/test/battle/ability/sheer_force.c @@ -0,0 +1,56 @@ +#include "global.h" +#include "test/battle.h" + +SINGLE_BATTLE_TEST("Sheer Force boosts power, but removes secondary effects of moves", s16 damage) +{ + s32 j; + u32 ability, move; + + for (j = 1; j < MOVES_COUNT; j++) + { + if (gBattleMoves[j].sheerForceBoost && j != MOVE_ORDER_UP) + { + PARAMETRIZE { ability = ABILITY_ANGER_POINT; move = j; } + PARAMETRIZE { ability = ABILITY_SHEER_FORCE; move = j; } + } + } + + GIVEN { + PLAYER(SPECIES_TAUROS) { Ability(ability); Status1(move == MOVE_SNORE ? STATUS1_SLEEP : STATUS1_NONE); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, move); } + if (gBattleMoves[move].effect == EFFECT_TWO_TURNS_ATTACK || gBattleMoves[move].effect == EFFECT_SEMI_INVULNERABLE) { + TURN { SKIP_TURN(player); } + TURN { ; } + } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, move, player); + HP_BAR(opponent, captureDamage: &results[i].damage); + if (ability == ABILITY_SHEER_FORCE) { + NONE_OF { + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); + STATUS_ICON(opponent, STATUS1_FREEZE); + STATUS_ICON(opponent, STATUS1_POISON); + STATUS_ICON(opponent, STATUS1_BURN); + STATUS_ICON(opponent, STATUS1_TOXIC_POISON); + STATUS_ICON(opponent, STATUS1_PARALYSIS); + MESSAGE("Wobbuffet is confused!"); + MESSAGE("Wobbuffet flinched!"); + } + // Volt Tackle/Flare Blitz edge case: recoil happens, but target isn't statused + if (gBattleMoves[move].effect == EFFECT_RECOIL_33_STATUS) + { + HP_BAR(player); + MESSAGE("Tauros is hit with recoil!"); + } + } + } FINALLY { + s32 j; + for (j = 0; j < gBattleTestRunnerState->parametersCount; j+=2) + { + EXPECT_GT(results[j+1].damage, results[j].damage); + } + } +} From 9d0211972da767f2dfcc0facbc33d13d6cfac294 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Wed, 4 Oct 2023 14:04:34 +0200 Subject: [PATCH 3/5] white herb tests --- test/battle/hold_effect/white_herb.c | 70 ++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 test/battle/hold_effect/white_herb.c diff --git a/test/battle/hold_effect/white_herb.c b/test/battle/hold_effect/white_herb.c new file mode 100644 index 000000000000..f0ed096216f3 --- /dev/null +++ b/test/battle/hold_effect/white_herb.c @@ -0,0 +1,70 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + gItems[ITEM_WHITE_HERB].holdEffect == HOLD_EFFECT_RESTORE_STATS; +} + +SINGLE_BATTLE_TEST("White Herb restores stats when they're lowered") +{ + GIVEN { + ASSUME(gBattleMoves[MOVE_LEER].effect == EFFECT_DEFENSE_DOWN); + PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_WHITE_HERB); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_LEER); } + } SCENE { + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player); + MESSAGE("Wobbuffet's White Herb restored its status!"); + } THEN { + EXPECT(player->item == ITEM_NONE); + EXPECT(player->statStages[STAT_DEF] = DEFAULT_STAT_STAGE); + } +} + +SINGLE_BATTLE_TEST("White Herb restores stats after Attack was lowered by Intimidate in singles") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_WHITE_HERB); } + OPPONENT(SPECIES_ARBOK) { Ability(ABILITY_INTIMIDATE); } + } WHEN { + TURN { ; } + } SCENE { + ABILITY_POPUP(opponent, ABILITY_INTIMIDATE); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player); + MESSAGE("Wobbuffet's White Herb restored its status!"); + } THEN { + EXPECT(player->item == ITEM_NONE); + EXPECT(player->statStages[STAT_DEF] = DEFAULT_STAT_STAGE); + } +} + +DOUBLE_BATTLE_TEST("White Herb restores stats after Attack was lowered by Intimidate in doubles") +{ + GIVEN { + OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_WHITE_HERB); } + OPPONENT(SPECIES_WYNAUT) { Item(ITEM_WHITE_HERB); } + PLAYER(SPECIES_ARBOK) { Ability(ABILITY_INTIMIDATE); } + PLAYER(SPECIES_WOBBUFFET); + } WHEN { + TURN { ; } + } SCENE { + ABILITY_POPUP(playerLeft, ABILITY_INTIMIDATE); + + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentLeft); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentRight); + + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponentLeft); + MESSAGE("Foe Wobbuffet's White Herb restored its status!"); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponentRight); + MESSAGE("Foe Wynaut's White Herb restored its status!"); + } THEN { + EXPECT(opponentLeft->item == ITEM_NONE); + EXPECT(opponentLeft->statStages[STAT_DEF] = DEFAULT_STAT_STAGE); + EXPECT(opponentRight->item == ITEM_NONE); + EXPECT(opponentRight->statStages[STAT_DEF] = DEFAULT_STAT_STAGE); + } +} From 12ed0cfd17799ba7295f8d07cfcd6fa1e32b1dca Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Wed, 4 Oct 2023 15:36:15 +0200 Subject: [PATCH 4/5] tests for stealth rock, weak armor and last resort fix --- src/battle_script_commands.c | 2 + test/battle/ability/weak_armor.c | 72 +++++++++++++++ test/battle/move_effect/encore.c | 21 ++++- test/battle/move_effect/last_resort.c | 116 +++++++++++++++++++++++++ test/battle/move_effect/stealth_rock.c | 32 +++++++ 5 files changed, 242 insertions(+), 1 deletion(-) create mode 100644 test/battle/ability/weak_armor.c create mode 100644 test/battle/move_effect/last_resort.c create mode 100644 test/battle/move_effect/stealth_rock.c diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 1a1a0a86855d..426af74d9ce5 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -12882,6 +12882,8 @@ static void Cmd_trychoosesleeptalkmove(void) } else // at least one move can be chosen { + // Set Sleep Talk as used move, so it works with Last Resort. + gDisableStructs[gBattlerAttacker].usedMoves |= gBitTable[gCurrMovePos]; do { movePosition = MOD(Random(), MAX_MON_MOVES); diff --git a/test/battle/ability/weak_armor.c b/test/battle/ability/weak_armor.c new file mode 100644 index 000000000000..1ab6bf35d544 --- /dev/null +++ b/test/battle/ability/weak_armor.c @@ -0,0 +1,72 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(gBattleMoves[MOVE_TACKLE].power != 0); + ASSUME(gBattleMoves[MOVE_GUST].power != 0); + ASSUME(gBattleMoves[MOVE_GUST].split == SPLIT_SPECIAL); + ASSUME(gBattleMoves[MOVE_TACKLE].split == SPLIT_PHYSICAL); +} + +SINGLE_BATTLE_TEST("Weak Armor lowers Defense by 1 and boosts Speed by 2 when hit by a physical attack") +{ + u16 move; + + PARAMETRIZE { move = MOVE_TACKLE; } + PARAMETRIZE { move = MOVE_GUST; } + + GIVEN { + PLAYER(SPECIES_SLUGMA) { Ability(ABILITY_WEAK_ARMOR); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, move); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, move, opponent); + HP_BAR(player); + if (move == MOVE_TACKLE) { + ABILITY_POPUP(player, ABILITY_WEAK_ARMOR); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Slugma's Weak Armor lowered its Defense!"); + MESSAGE("Slugma's Weak Armor raised its Speed!"); + } + } + THEN { + if (move == MOVE_TACKLE) { + EXPECT_EQ(player->statStages[STAT_DEF], DEFAULT_STAT_STAGE - 1); + EXPECT_EQ(player->statStages[STAT_SPEED], DEFAULT_STAT_STAGE + 2); + } + } +} + +// Oddly specific, but it was a bug at one point. +SINGLE_BATTLE_TEST("Weak Armor does not trigger when brought in by Dragon Tail and taking Stealth Rock damage") +{ + GIVEN { + ASSUME(gBattleMoves[MOVE_STEALTH_ROCK].effect == EFFECT_STEALTH_ROCK); + ASSUME(gBattleMoves[MOVE_DRAGON_TAIL].effect == EFFECT_HIT_SWITCH_TARGET); + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_SLUGMA) { Ability(ABILITY_WEAK_ARMOR); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_STEALTH_ROCK); } + TURN { MOVE(opponent, MOVE_DRAGON_TAIL); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_STEALTH_ROCK, opponent); + ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_TAIL, opponent); + HP_BAR(player); + MESSAGE("Slugma was dragged out!"); + HP_BAR(player); + MESSAGE("Pointed stones dug into Slugma!"); + NONE_OF { + ABILITY_POPUP(player, ABILITY_WEAK_ARMOR); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Slugma's Weak Armor lowered its Defense!"); + MESSAGE("Slugma's Weak Armor raised its Speed!"); + } + } + THEN { + EXPECT_EQ(player->statStages[STAT_DEF], DEFAULT_STAT_STAGE); + EXPECT_EQ(player->statStages[STAT_SPEED], DEFAULT_STAT_STAGE); + } +} diff --git a/test/battle/move_effect/encore.c b/test/battle/move_effect/encore.c index eff6c33b2001..08d3f2544832 100644 --- a/test/battle/move_effect/encore.c +++ b/test/battle/move_effect/encore.c @@ -6,7 +6,7 @@ ASSUMPTIONS ASSUME(gBattleMoves[MOVE_ENCORE].effect == EFFECT_ENCORE); } -SINGLE_BATTLE_TEST("Encore forces consecutive move uses for 2 turns") +SINGLE_BATTLE_TEST("Encore forces consecutive move uses for 2 turns for player") { GIVEN { PLAYER(SPECIES_WOBBUFFET); @@ -25,6 +25,25 @@ SINGLE_BATTLE_TEST("Encore forces consecutive move uses for 2 turns") } } +SINGLE_BATTLE_TEST("Encore forces consecutive move uses for 2 turns for opponent") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_CELEBRATE); MOVE(player, MOVE_ENCORE); } + TURN { FORCED_MOVE(opponent); } + TURN { FORCED_MOVE(opponent); } + TURN { MOVE(opponent, MOVE_SPLASH); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent); + ANIMATION(ANIM_TYPE_MOVE, MOVE_ENCORE, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent); + ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPLASH, opponent); + } +} + SINGLE_BATTLE_TEST("Encore has no effect if no previous move") { GIVEN { diff --git a/test/battle/move_effect/last_resort.c b/test/battle/move_effect/last_resort.c new file mode 100644 index 000000000000..01a685ffc19d --- /dev/null +++ b/test/battle/move_effect/last_resort.c @@ -0,0 +1,116 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(gBattleMoves[MOVE_LAST_RESORT].effect == EFFECT_LAST_RESORT); +} + +SINGLE_BATTLE_TEST("Last Resort always fails if it's the only known move") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_LAST_RESORT); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_LAST_RESORT); } + TURN { MOVE(player, MOVE_LAST_RESORT); } + } SCENE { + MESSAGE("Wobbuffet used Last Resort!"); + MESSAGE("But it failed!"); + MESSAGE("Wobbuffet used Last Resort!"); + MESSAGE("But it failed!"); + NOT HP_BAR(opponent); + } +} + +SINGLE_BATTLE_TEST("Last Resort works only when all of the known moves have been used - 2 moves") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_LAST_RESORT, MOVE_TACKLE); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_LAST_RESORT); } + TURN { MOVE(player, MOVE_TACKLE); } + TURN { MOVE(player, MOVE_LAST_RESORT); } + } SCENE { + MESSAGE("Wobbuffet used Last Resort!"); + MESSAGE("But it failed!"); + MESSAGE("Wobbuffet used Tackle!"); + MESSAGE("Wobbuffet used Last Resort!"); + HP_BAR(opponent); + } +} + +SINGLE_BATTLE_TEST("Last Resort works only when all of the known moves have been used - 3 moves") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_LAST_RESORT, MOVE_TACKLE, MOVE_SCRATCH); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_LAST_RESORT); } + TURN { MOVE(player, MOVE_TACKLE); } + TURN { MOVE(player, MOVE_LAST_RESORT); } + TURN { MOVE(player, MOVE_SCRATCH); } + TURN { MOVE(player, MOVE_LAST_RESORT); } + } SCENE { + MESSAGE("Wobbuffet used Last Resort!"); + MESSAGE("But it failed!"); + MESSAGE("Wobbuffet used Tackle!"); + MESSAGE("Wobbuffet used Last Resort!"); + MESSAGE("But it failed!"); + MESSAGE("Wobbuffet used Scratch!"); + MESSAGE("Wobbuffet used Last Resort!"); + HP_BAR(opponent); + } +} + +SINGLE_BATTLE_TEST("Last Resort works only when all of the known moves have been used - 4 moves") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_LAST_RESORT, MOVE_TACKLE, MOVE_SCRATCH, MOVE_GUST); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_LAST_RESORT); } + TURN { MOVE(player, MOVE_TACKLE); } + TURN { MOVE(player, MOVE_LAST_RESORT); } + TURN { MOVE(player, MOVE_SCRATCH); } + TURN { MOVE(player, MOVE_LAST_RESORT); } + TURN { MOVE(player, MOVE_GUST); } + TURN { MOVE(player, MOVE_LAST_RESORT); } + } SCENE { + MESSAGE("Wobbuffet used Last Resort!"); + MESSAGE("But it failed!"); + MESSAGE("Wobbuffet used Tackle!"); + MESSAGE("Wobbuffet used Last Resort!"); + MESSAGE("But it failed!"); + MESSAGE("Wobbuffet used Scratch!"); + MESSAGE("Wobbuffet used Last Resort!"); + MESSAGE("But it failed!"); + MESSAGE("Wobbuffet used Gust!"); + MESSAGE("Wobbuffet used Last Resort!"); + HP_BAR(opponent); + } +} + +SINGLE_BATTLE_TEST("Last Resort works with Sleep Talk") +{ + GIVEN { + ASSUME(gBattleMoves[MOVE_SLEEP_TALK].effect == EFFECT_SLEEP_TALK); + PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_LAST_RESORT, MOVE_SLEEP_TALK); Status1(STATUS1_SLEEP_TURN(3)); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_SLEEP_TALK); } + TURN { MOVE(player, MOVE_SLEEP_TALK); } + } SCENE { + // Turn 1 + MESSAGE("Wobbuffet used Sleep Talk!"); + MESSAGE("Wobbuffet used Last Resort!"); + NOT MESSAGE("But it failed!"); + HP_BAR(opponent); + // Turn 2 + MESSAGE("Wobbuffet used Sleep Talk!"); + MESSAGE("Wobbuffet used Last Resort!"); + NOT MESSAGE("But it failed!"); + HP_BAR(opponent); + } +} diff --git a/test/battle/move_effect/stealth_rock.c b/test/battle/move_effect/stealth_rock.c new file mode 100644 index 000000000000..4662379f5ecb --- /dev/null +++ b/test/battle/move_effect/stealth_rock.c @@ -0,0 +1,32 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(gBattleMoves[MOVE_STEALTH_ROCK].effect == EFFECT_STEALTH_ROCK); +} + +SINGLE_BATTLE_TEST("Stealth Rock damage on switch in based on typing") +{ + u32 species, divisor; + + PARAMETRIZE { species = SPECIES_CHARIZARD; divisor = 2; } // Fire / Flying + PARAMETRIZE { species = SPECIES_PIDGEOT; divisor = 4; } // Flying + PARAMETRIZE { species = SPECIES_RATICATE; divisor = 8; } // Normal dmg + PARAMETRIZE { species = SPECIES_GOLEM; divisor = 16; } // Ground not very effective + PARAMETRIZE { species = SPECIES_STEELIX; divisor = 32; } // Ground/Steel not very effective + + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(species); + } WHEN { + TURN { MOVE(player, MOVE_STEALTH_ROCK); } + TURN { SWITCH(opponent, 1); } + } SCENE { + s32 maxHP = GetMonData(&OPPONENT_PARTY[1], MON_DATA_MAX_HP); + ANIMATION(ANIM_TYPE_MOVE, MOVE_STEALTH_ROCK, player); + // MESSAGE("2 sent out species!"); + HP_BAR(opponent, damage: maxHP / divisor); + } +} From b16c77b671aaea1f6cd44d7c94a806933a2e7976 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Mon, 30 Oct 2023 10:10:16 +0100 Subject: [PATCH 5/5] style changes to weak armor test --- test/battle/ability/weak_armor.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/test/battle/ability/weak_armor.c b/test/battle/ability/weak_armor.c index 1ab6bf35d544..abe4a797e583 100644 --- a/test/battle/ability/weak_armor.c +++ b/test/battle/ability/weak_armor.c @@ -30,8 +30,7 @@ SINGLE_BATTLE_TEST("Weak Armor lowers Defense by 1 and boosts Speed by 2 when hi MESSAGE("Slugma's Weak Armor lowered its Defense!"); MESSAGE("Slugma's Weak Armor raised its Speed!"); } - } - THEN { + } THEN { if (move == MOVE_TACKLE) { EXPECT_EQ(player->statStages[STAT_DEF], DEFAULT_STAT_STAGE - 1); EXPECT_EQ(player->statStages[STAT_SPEED], DEFAULT_STAT_STAGE + 2); @@ -64,8 +63,7 @@ SINGLE_BATTLE_TEST("Weak Armor does not trigger when brought in by Dragon Tail a MESSAGE("Slugma's Weak Armor lowered its Defense!"); MESSAGE("Slugma's Weak Armor raised its Speed!"); } - } - THEN { + } THEN { EXPECT_EQ(player->statStages[STAT_DEF], DEFAULT_STAT_STAGE); EXPECT_EQ(player->statStages[STAT_SPEED], DEFAULT_STAT_STAGE); }