diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 5fa5bf342d..1f066d77a8 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -288,6 +288,7 @@ BattleScript_EffectSaltCure:: call BattleScript_EffectHit_Ret tryfaintmon BS_TARGET jumpiffainted BS_TARGET, TRUE, BattleScript_EffectSaltCure_End + jumpifsubstituteblocks BattleScript_EffectSaltCure_End applysaltcure BS_TARGET printstring STRINGID_TARGETISBEINGSALTCURED waitmessage B_WAIT_TIME_LONG diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index bc3e2f7198..be474cea8a 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -5397,6 +5397,7 @@ static void Cmd_moveend(void) u16 *choicedMoveAtk = NULL; u32 endMode, endState; u32 originallyUsedMove; + u8 currBattler, liveBattlerCount; if (gChosenMove == MOVE_UNAVAILABLE) originallyUsedMove = MOVE_NONE; @@ -5661,7 +5662,10 @@ static void Cmd_moveend(void) switch (gBattleStruct->moveEffect2) { case MOVE_EFFECT_KNOCK_OFF: - effect = TryKnockOffBattleScript(gBattlerTarget); + if (!DoesSubstituteBlockMove(gBattlerAttacker, gBattlerTarget, gCurrentMove)) + { + effect = TryKnockOffBattleScript(gBattlerTarget); + } break; case MOVE_EFFECT_STOCKPILE_WORE_OFF: if (gDisableStructs[gBattlerAttacker].stockpileCounter != 0) @@ -5673,7 +5677,9 @@ static void Cmd_moveend(void) } break; case MOVE_EFFECT_SMACK_DOWN: - if (!IsBattlerGrounded(gBattlerTarget) && IsBattlerAlive(gBattlerTarget)) + if (!IsBattlerGrounded(gBattlerTarget) + && IsBattlerAlive(gBattlerTarget) + && !DoesSubstituteBlockMove(gBattlerAttacker, gBattlerTarget, gCurrentMove)) { gStatuses3[gBattlerTarget] |= STATUS3_SMACKED_DOWN; gStatuses3[gBattlerTarget] &= ~(STATUS3_MAGNET_RISE | STATUS3_TELEKINESIS | STATUS3_ON_AIR); @@ -5683,7 +5689,9 @@ static void Cmd_moveend(void) } break; case MOVE_EFFECT_REMOVE_STATUS: // Smelling salts, Wake-Up Slap, Sparkling Aria - if ((gBattleMons[gBattlerTarget].status1 & gMovesInfo[gCurrentMove].argument) && IsBattlerAlive(gBattlerTarget)) + if ((gBattleMons[gBattlerTarget].status1 & gMovesInfo[gCurrentMove].argument) + && IsBattlerAlive(gBattlerTarget) + && !DoesSubstituteBlockMove(gBattlerAttacker, gBattlerTarget, gCurrentMove)) { gBattleMons[gBattlerTarget].status1 &= ~(gMovesInfo[gCurrentMove].argument); @@ -5700,8 +5708,28 @@ static void Cmd_moveend(void) gBattlescriptCurrInstr = BattleScript_TargetWokeUp; break; case STATUS1_BURN: - gBattlescriptCurrInstr = BattleScript_TargetBurnHeal; - break; + // Checks to see if Sparkling Aria should cure a Shield Dust pokemon + if (gBattleMons[gBattlerTarget].ability == ABILITY_SHIELD_DUST || gBattleMons[gBattlerTarget].item == ITEM_COVERT_CLOAK) + { + liveBattlerCount = 0; + for (currBattler = 0; currBattler < gBattlersCount; currBattler++) + { + if (gBattleMons[currBattler].hp != 0) + { + liveBattlerCount++; + } + } + if (liveBattlerCount > 2) + { + gBattlescriptCurrInstr = BattleScript_TargetBurnHeal; + } + break; + } + else + { + gBattlescriptCurrInstr = BattleScript_TargetBurnHeal; + break; + } } } break; // MOVE_EFFECT_REMOVE_STATUS diff --git a/src/battle_util.c b/src/battle_util.c index 1bdc1d9050..64cba43782 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -8632,8 +8632,11 @@ static inline u32 CalcMoveBasePower(u32 move, u32 battlerAtk, u32 battlerDef, u3 break; case EFFECT_DOUBLE_POWER_ON_ARG_STATUS: // Comatose targets treated as if asleep - if ((gBattleMons[battlerDef].status1 | (STATUS1_SLEEP * (abilityDef == ABILITY_COMATOSE))) & gMovesInfo[move].argument) + if ((gBattleMons[battlerDef].status1 | (STATUS1_SLEEP * (abilityDef == ABILITY_COMATOSE))) & gMovesInfo[move].argument + && !((gMovesInfo[move].additionalEffects->moveEffect == MOVE_EFFECT_REMOVE_STATUS) && DoesSubstituteBlockMove(battlerAtk, battlerDef, move))) + { basePower *= 2; + } break; case EFFECT_VARY_POWER_BASED_ON_HP: basePower = gMovesInfo[move].argument * gBattleMons[battlerDef].hp / gBattleMons[battlerDef].maxHP; diff --git a/test/battle/ability/shield_dust.c b/test/battle/ability/shield_dust.c index 0c4ba99a83..11563151ad 100644 --- a/test/battle/ability/shield_dust.c +++ b/test/battle/ability/shield_dust.c @@ -121,19 +121,44 @@ SINGLE_BATTLE_TEST("Shield Dust does not block self-targeting effects, primary o } } -DOUBLE_BATTLE_TEST("Shield Dust does not block Sparkling Aria in doubles") +DOUBLE_BATTLE_TEST("Shield Dust does or does not block Sparkling Aria depending on number of targets hit") { - KNOWN_FAILING; + u32 moveToUse; + PARAMETRIZE { moveToUse = MOVE_FINAL_GAMBIT; } + PARAMETRIZE { moveToUse = MOVE_TACKLE; } GIVEN { - PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_WYNAUT); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_VIVILLON) { Ability(ABILITY_SHIELD_DUST); Status1(STATUS1_BURN); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { - TURN { MOVE(playerLeft, MOVE_SPARKLING_ARIA); } + TURN { MOVE(playerRight, moveToUse, target: opponentRight); MOVE(playerLeft, MOVE_SPARKLING_ARIA); } } SCENE { ANIMATION(ANIM_TYPE_MOVE, MOVE_SPARKLING_ARIA, playerLeft); - MESSAGE("Foe Vivillion's burn was healed."); - STATUS_ICON(opponentLeft, burn: TRUE); + if (moveToUse == MOVE_TACKLE) { + MESSAGE("Foe Vivillon's burn was healed."); + STATUS_ICON(opponentLeft, none: TRUE); + } else { + NONE_OF { + MESSAGE("Foe Vivillon's burn was healed."); + STATUS_ICON(opponentLeft, none: TRUE); + } + } + } +} + +SINGLE_BATTLE_TEST("Shield Dust blocks Sparkling Aria in singles") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_VIVILLON) { Ability(ABILITY_SHIELD_DUST); Status1(STATUS1_BURN); } + } WHEN { + TURN { MOVE(player, MOVE_SPARKLING_ARIA); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPARKLING_ARIA, player); + NONE_OF { + MESSAGE("Foe Vivillon's burn was healed."); + STATUS_ICON(opponent, none: TRUE); + } } } diff --git a/test/battle/item_effect/covert_cloak.c b/test/battle/item_effect/covert_cloak.c new file mode 100644 index 0000000000..76dec1c31c --- /dev/null +++ b/test/battle/item_effect/covert_cloak.c @@ -0,0 +1,162 @@ +#include "global.h" +#include "test/battle.h" + +SINGLE_BATTLE_TEST("Covert Cloak blocks secondary effects") +{ + u16 move; + PARAMETRIZE { move = MOVE_NUZZLE; } + PARAMETRIZE { move = MOVE_INFERNO; } + PARAMETRIZE { move = MOVE_MORTAL_SPIN; } + PARAMETRIZE { move = MOVE_FAKE_OUT; } + PARAMETRIZE { move = MOVE_ROCK_TOMB; } + PARAMETRIZE { move = MOVE_SPIRIT_SHACKLE; } + PARAMETRIZE { move = MOVE_PSYCHIC_NOISE; } + + GIVEN { + ASSUME(MoveHasAdditionalEffectWithChance(MOVE_NUZZLE, MOVE_EFFECT_PARALYSIS, 100) == TRUE); + ASSUME(MoveHasAdditionalEffectWithChance(MOVE_INFERNO, MOVE_EFFECT_BURN, 100) == TRUE); + ASSUME(MoveHasAdditionalEffectWithChance(MOVE_MORTAL_SPIN, MOVE_EFFECT_POISON, 100) == TRUE); + ASSUME(MoveHasAdditionalEffectWithChance(MOVE_FAKE_OUT, MOVE_EFFECT_FLINCH, 100) == TRUE); + ASSUME(MoveHasAdditionalEffectWithChance(MOVE_ROCK_TOMB, MOVE_EFFECT_SPD_MINUS_1, 100) == TRUE); + ASSUME(MoveHasAdditionalEffectWithChance(MOVE_SPIRIT_SHACKLE, MOVE_EFFECT_PREVENT_ESCAPE, 100) == TRUE); + ASSUME(MoveHasAdditionalEffectWithChance(MOVE_PSYCHIC_NOISE, MOVE_EFFECT_PSYCHIC_NOISE, 100) == TRUE); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_COVERT_CLOAK); } + } WHEN { + TURN { MOVE(player, move); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, move, player); + HP_BAR(opponent); + NONE_OF { + MESSAGE("Foe Wobbuffet is paralyzed! It may be unable to move!"); + MESSAGE("Foe Wobbuffet was burned!"); + MESSAGE("Foe Wobbuffet was poisoned!"); + MESSAGE("Foe Wobbuffet flinched!"); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); + MESSAGE("Foe Wobbuffet was prevented from healing!"); + } + } THEN { // Can't find good way to test trapping + EXPECT(!(opponent->status2 & STATUS2_ESCAPE_PREVENTION)); + } +} + +SINGLE_BATTLE_TEST("Covert Cloak does not block primary effects") +{ + u16 move; + PARAMETRIZE { move = MOVE_INFESTATION; } + PARAMETRIZE { move = MOVE_THOUSAND_ARROWS; } + PARAMETRIZE { move = MOVE_JAW_LOCK; } + PARAMETRIZE { move = MOVE_PAY_DAY; } + + GIVEN { + ASSUME(MoveHasAdditionalEffectWithChance(MOVE_INFESTATION, MOVE_EFFECT_WRAP, 0) == TRUE); + ASSUME(MoveHasAdditionalEffectWithChance(MOVE_THOUSAND_ARROWS, MOVE_EFFECT_SMACK_DOWN, 0) == TRUE); + ASSUME(MoveHasAdditionalEffectWithChance(MOVE_JAW_LOCK, MOVE_EFFECT_TRAP_BOTH, 0) == TRUE); + ASSUME(MoveHasAdditionalEffectWithChance(MOVE_PAY_DAY, MOVE_EFFECT_PAYDAY, 0) == TRUE); + ASSUME(MoveHasAdditionalEffectWithChance(MOVE_SMACK_DOWN, MOVE_EFFECT_SMACK_DOWN, 0) == TRUE); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_SKARMORY) { Item(ITEM_COVERT_CLOAK); } + } WHEN { + TURN { MOVE(player, move); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, move, player); + HP_BAR(opponent); + switch (move) { + case MOVE_INFESTATION: + MESSAGE("Foe Skarmory has been afflicted with an infestation by Wobbuffet!"); + break; + case MOVE_THOUSAND_ARROWS: + MESSAGE("Foe Skarmory fell straight down!"); + break; + case MOVE_JAW_LOCK: + MESSAGE("Neither Pokémon can run away!"); + break; + case MOVE_PAY_DAY: + MESSAGE("Coins scattered everywhere!"); + break; + } + } THEN { // Can't find good way to test trapping + if (move == MOVE_JAW_LOCK) { + EXPECT(opponent->status2 & STATUS2_ESCAPE_PREVENTION); + EXPECT(player->status2 & STATUS2_ESCAPE_PREVENTION); + } + } +} + +SINGLE_BATTLE_TEST("Covert Cloak does not block self-targeting effects, primary or secondary") +{ + u16 move; + PARAMETRIZE { move = MOVE_POWER_UP_PUNCH; } + PARAMETRIZE { move = MOVE_RAPID_SPIN; } + PARAMETRIZE { move = MOVE_LEAF_STORM; } + PARAMETRIZE { move = MOVE_METEOR_ASSAULT; } + + GIVEN { + ASSUME(MoveHasAdditionalEffectSelf(MOVE_POWER_UP_PUNCH, MOVE_EFFECT_ATK_PLUS_1) == TRUE); + ASSUME(MoveHasAdditionalEffectSelf(MOVE_RAPID_SPIN, MOVE_EFFECT_RAPID_SPIN) == TRUE); + ASSUME(MoveHasAdditionalEffectSelf(MOVE_LEAF_STORM, MOVE_EFFECT_SP_ATK_TWO_DOWN) == TRUE); + ASSUME(MoveHasAdditionalEffectSelf(MOVE_METEOR_ASSAULT, MOVE_EFFECT_RECHARGE) == TRUE); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_COVERT_CLOAK); } + } WHEN { + TURN { MOVE(player, move); } + if (move == MOVE_METEOR_ASSAULT) { + TURN { SKIP_TURN(player); } + } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, move, player); + HP_BAR(opponent); + switch (move) { + case MOVE_POWER_UP_PUNCH: + case MOVE_RAPID_SPIN: + case MOVE_LEAF_STORM: + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + break; + case MOVE_METEOR_ASSAULT: // second turn + MESSAGE("Wobbuffet must recharge!"); + break; + } + } +} + +DOUBLE_BATTLE_TEST("Covert Cloak does or does not block Sparkling Aria depending on number of targets hit") +{ + u32 moveToUse; + PARAMETRIZE { moveToUse = MOVE_FINAL_GAMBIT; } + PARAMETRIZE { moveToUse = MOVE_TACKLE; } + GIVEN { + PLAYER(SPECIES_WYNAUT); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_COVERT_CLOAK); Status1(STATUS1_BURN); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(playerRight, moveToUse, target: opponentRight); MOVE(playerLeft, MOVE_SPARKLING_ARIA); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPARKLING_ARIA, playerLeft); + if (moveToUse == MOVE_TACKLE) { + MESSAGE("Foe Wobbuffet's burn was healed."); + STATUS_ICON(opponentLeft, none: TRUE); + } else { + NONE_OF { + MESSAGE("Foe Wobbuffet's burn was healed."); + STATUS_ICON(opponentLeft, none: TRUE); + } + } + } +} + +SINGLE_BATTLE_TEST("Covert Cloak blocks Sparkling Aria in singles") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_COVERT_CLOAK); Status1(STATUS1_BURN); } + } WHEN { + TURN { MOVE(player, MOVE_SPARKLING_ARIA); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPARKLING_ARIA, player); + NONE_OF { + MESSAGE("Foe Wobbuffet's burn was healed."); + STATUS_ICON(opponent, none: TRUE); + } + } +} diff --git a/test/battle/move_effect/knock_off.c b/test/battle/move_effect/knock_off.c index 863cf165d3..883f313f3b 100644 --- a/test/battle/move_effect/knock_off.c +++ b/test/battle/move_effect/knock_off.c @@ -51,3 +51,15 @@ SINGLE_BATTLE_TEST("Knock Off activates after Rocky Helmet and Weakness Policy") } } } + +SINGLE_BATTLE_TEST("Knock Off doesn't knock off items from Pokemon behind substitutes") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_POKE_BALL); } + } WHEN { + TURN { MOVE(opponent, MOVE_SUBSTITUTE); MOVE(player, MOVE_KNOCK_OFF); } + } SCENE { + NOT MESSAGE("Wobbuffet knocked off Foe Wobbuffet's Poké Ball"); + } +} diff --git a/test/battle/move_effect/salt_cure.c b/test/battle/move_effect/salt_cure.c index 547797e38b..939e32f0a6 100644 --- a/test/battle/move_effect/salt_cure.c +++ b/test/battle/move_effect/salt_cure.c @@ -85,3 +85,17 @@ SINGLE_BATTLE_TEST("If Salt Cure faints the target no status will be applied") MESSAGE("Foe Wobbuffet fainted!"); } } + +SINGLE_BATTLE_TEST("Salt Cure does not get applied if hitting a Substitute") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_SUBSTITUTE); MOVE(player, MOVE_SALT_CURE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SALT_CURE, player); + MESSAGE("The SUBSTITUTE took damage for Foe Wobbuffet!"); + NOT MESSAGE("Foe Wobbuffet is being salt cured!"); + } +} diff --git a/test/battle/move_effect/smack_down.c b/test/battle/move_effect/smack_down.c new file mode 100644 index 0000000000..54bf6885af --- /dev/null +++ b/test/battle/move_effect/smack_down.c @@ -0,0 +1,19 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(gMovesInfo[MOVE_SMACK_DOWN].additionalEffects->moveEffect == MOVE_EFFECT_SMACK_DOWN); +} + +SINGLE_BATTLE_TEST("Smack Down does not ground mons behind substitutes") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_SKARMORY); + } WHEN { + TURN { MOVE(opponent, MOVE_SUBSTITUTE); MOVE(player, MOVE_SMACK_DOWN); } + } SCENE { + NOT MESSAGE("Foe Skarmory fell straight down!"); + } +} diff --git a/test/battle/move_effect/smelling_salts.c b/test/battle/move_effect/smelling_salts.c new file mode 100644 index 0000000000..09168f8a1e --- /dev/null +++ b/test/battle/move_effect/smelling_salts.c @@ -0,0 +1,63 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(gMovesInfo[MOVE_SMELLING_SALTS].additionalEffects->moveEffect == MOVE_EFFECT_REMOVE_STATUS); + ASSUME(gMovesInfo[MOVE_SMELLING_SALTS].argument == STATUS1_PARALYSIS); +} + +SINGLE_BATTLE_TEST("Smelling Salts does not cure paralyzed pokemons behind substitutes or get increased power") +{ + u32 ability; + PARAMETRIZE { ability = ABILITY_INNER_FOCUS; } + PARAMETRIZE { ability = ABILITY_INFILTRATOR; } + GIVEN { + PLAYER(SPECIES_CROBAT) { Ability(ability); } + OPPONENT(SPECIES_SEISMITOAD) { Status1(STATUS1_PARALYSIS); } + } WHEN { + TURN { MOVE(opponent, MOVE_SUBSTITUTE); MOVE(player, MOVE_CELEBRATE); } + TURN { MOVE(opponent, MOVE_CELEBRATE); MOVE(player, MOVE_SMELLING_SALTS); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SMELLING_SALTS, player); + if (ability == ABILITY_INNER_FOCUS) + { + MESSAGE("The SUBSTITUTE took damage for Foe Seismitoad!"); + NONE_OF + { + MESSAGE("Foe Seismitoad's SUBSTITUTE faded!"); // Smelling Salts does 86 damage, the sub has 122 HP, if hitting a sub it shouldn't get boosted damage. + MESSAGE("Foe Seismitoad was healed of paralysis!"); + STATUS_ICON(opponent, none: TRUE); + } + } + else + { + MESSAGE("Foe Seismitoad was healed of paralysis!"); + STATUS_ICON(opponent, none: TRUE); + } + } +} + +SINGLE_BATTLE_TEST("Smelling Salts get incread power vs. paralyzed targets") +{ + u32 status1; + PARAMETRIZE { status1 = STATUS1_PARALYSIS; } + PARAMETRIZE { status1 = STATUS1_NONE; } + GIVEN { + PLAYER(SPECIES_CROBAT); + OPPONENT(SPECIES_LOTAD) { Status1(status1); } + } WHEN { + TURN { MOVE(player, MOVE_SMELLING_SALTS); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SMELLING_SALTS, player); + if (status1 == STATUS1_PARALYSIS) + { + MESSAGE("Foe Lotad fainted!"); + } + else + { + NOT MESSAGE("Foe Lotad fainted!"); + MESSAGE("Foe Lotad used Celebrate!"); + } + } +} diff --git a/test/battle/move_effect/sparkling_aria.c b/test/battle/move_effect/sparkling_aria.c new file mode 100644 index 0000000000..1bf7de2df4 --- /dev/null +++ b/test/battle/move_effect/sparkling_aria.c @@ -0,0 +1,25 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(gMovesInfo[MOVE_SPARKLING_ARIA].additionalEffects->moveEffect == MOVE_EFFECT_REMOVE_STATUS); + ASSUME(gMovesInfo[MOVE_SPARKLING_ARIA].argument == STATUS1_BURN); + ASSUME(gMovesInfo[MOVE_SPARKLING_ARIA].soundMove == TRUE); +} + +DOUBLE_BATTLE_TEST("Sparkling Aria cures burns from all Pokemon on the field and behind substitutes") +{ + GIVEN { + PLAYER(SPECIES_PRIMARINA); + PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_BURN); } + OPPONENT(SPECIES_WOBBUFFET) { Status1(STATUS1_BURN); } + OPPONENT(SPECIES_WYNAUT) { Status1(STATUS1_BURN); } + } WHEN { + TURN { MOVE(opponentLeft, MOVE_SUBSTITUTE); MOVE(opponentRight, MOVE_CELEBRATE); MOVE(playerRight, MOVE_CELEBRATE); MOVE(playerLeft, MOVE_SPARKLING_ARIA); } + } SCENE { + MESSAGE("Foe Wobbuffet's burn was healed."); + MESSAGE("Wobbuffet's burn was healed."); + MESSAGE("Foe Wynaut's burn was healed."); + } +} diff --git a/test/battle/move_effect/thousand_arrows.c b/test/battle/move_effect/thousand_arrows.c new file mode 100644 index 0000000000..bff3706c34 --- /dev/null +++ b/test/battle/move_effect/thousand_arrows.c @@ -0,0 +1,55 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(gMovesInfo[MOVE_THOUSAND_ARROWS].additionalEffects->moveEffect == MOVE_EFFECT_SMACK_DOWN); + ASSUME(gMovesInfo[MOVE_THOUSAND_ARROWS].ignoreTypeIfFlyingAndUngrounded == TRUE); +} + +SINGLE_BATTLE_TEST("Thousand Arrows does not ground mons behind substitutes") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_SKARMORY); + } WHEN { + TURN { MOVE(opponent, MOVE_SUBSTITUTE); MOVE(player, MOVE_THOUSAND_ARROWS); } + } SCENE { + NOT MESSAGE("Foe Skarmory fell straight down!"); + } +} + +SINGLE_BATTLE_TEST("Thousand Arrows does neutral damage to non-grounded Flying types regardless of other typings") +{ + u32 pokemon; + PARAMETRIZE { pokemon = SPECIES_SKARMORY; } + PARAMETRIZE { pokemon = SPECIES_SCYTHER; } + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(pokemon); + } WHEN { + TURN { MOVE(player, MOVE_THOUSAND_ARROWS); } + TURN { MOVE(player, MOVE_THOUSAND_ARROWS); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_THOUSAND_ARROWS, player); + if (pokemon == SPECIES_SKARMORY) { + MESSAGE("Foe Skarmory fell straight down!"); + MESSAGE("Foe Skarmory used Celebrate!"); + } else { + MESSAGE("Foe Scyther fell straight down!"); + MESSAGE("Foe Scyther used Celebrate!"); + } + ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent); + MESSAGE("Congratulations, 1!"); + MESSAGE("Wobbuffet used ThousndArrws!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_THOUSAND_ARROWS, player); + if (pokemon == SPECIES_SKARMORY) + { + MESSAGE("It's super effective!"); + } + else + { + MESSAGE("It's not very effective…"); + } + } +} diff --git a/test/battle/move_effect/wake_up_slap.c b/test/battle/move_effect/wake_up_slap.c new file mode 100644 index 0000000000..98bcf95b20 --- /dev/null +++ b/test/battle/move_effect/wake_up_slap.c @@ -0,0 +1,57 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(gMovesInfo[MOVE_WAKE_UP_SLAP].additionalEffects->moveEffect == MOVE_EFFECT_REMOVE_STATUS); + ASSUME(gMovesInfo[MOVE_WAKE_UP_SLAP].argument == STATUS1_SLEEP); +} + +SINGLE_BATTLE_TEST("Wake-Up Slap does not cure paralyzed pokemons behind substitutes or get increased power") +{ + u32 ability; + PARAMETRIZE { ability = ABILITY_INNER_FOCUS; } + PARAMETRIZE { ability = ABILITY_INFILTRATOR; } + GIVEN { + PLAYER(SPECIES_CROBAT) { Ability(ability); } + OPPONENT(SPECIES_SEISMITOAD); + } WHEN { + TURN { MOVE(opponent, MOVE_SUBSTITUTE); MOVE(player, MOVE_SING); } + TURN { MOVE(opponent, MOVE_CELEBRATE); MOVE(player, MOVE_WAKE_UP_SLAP); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_WAKE_UP_SLAP, player); + if (ability == ABILITY_INNER_FOCUS) { + MESSAGE("The SUBSTITUTE took damage for Foe Seismitoad!"); + NONE_OF + { + MESSAGE("Foe Seismitoad's SUBSTITUTE faded!"); // Smelling Salts does 86 damage, the sub has 122 HP, if hitting a sub it shouldn't get boosted damage. + MESSAGE("Foe Seismitoad woke up!"); + STATUS_ICON(opponent, none: TRUE); + } + } else { + MESSAGE("Foe Seismitoad woke up!"); + STATUS_ICON(opponent, none: TRUE); + } + } +} + +SINGLE_BATTLE_TEST("Wake-Up Slap get incread power vs. sleeping targets") +{ + u32 status1; + PARAMETRIZE { status1 = STATUS1_SLEEP; } + PARAMETRIZE { status1 = STATUS1_NONE; } + GIVEN { + PLAYER(SPECIES_CROBAT); + OPPONENT(SPECIES_LOTAD) { Status1(status1); } + } WHEN { + TURN { MOVE(player, MOVE_WAKE_UP_SLAP); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_WAKE_UP_SLAP, player); + if (status1 == STATUS1_SLEEP) { + MESSAGE("Foe Lotad fainted!"); + } else { + NOT MESSAGE("Foe Lotad fainted!"); + MESSAGE("Foe Lotad used Celebrate!"); + } + } +}