From 83e2f4bdf8b4c02f5868f40eb7a3c877359a2053 Mon Sep 17 00:00:00 2001 From: Alex <93446519+AlexOn1ine@users.noreply.github.com> Date: Fri, 22 Dec 2023 16:22:53 +0100 Subject: [PATCH] Adds ability Minds Eye + Tests (#3782) * Implemented Mind's Eye with tests + Keen Eye tests * AI test * fix AI minds eye test * Adds ability Minds Eye + Tests * fix tests --------- Co-authored-by: Eduardo Quezada Co-authored-by: Bassoonian --- src/battle_ai_main.c | 6 +- src/battle_ai_switch_items.c | 1 + src/battle_ai_util.c | 1 + src/battle_script_commands.c | 9 +- src/battle_util.c | 9 +- test/battle/ability/keen_eye.c | 199 ++++++++++++++++++++++++++++++++ test/battle/ability/minds_eye.c | 71 ++++++++++++ 7 files changed, 288 insertions(+), 8 deletions(-) create mode 100644 test/battle/ability/keen_eye.c create mode 100644 test/battle/ability/minds_eye.c diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c index f6b51910c5..dbdfeb84da 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -877,6 +877,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) break; // fallthrough case ABILITY_KEEN_EYE: + case ABILITY_MINDS_EYE: if (moveEffect == EFFECT_ACCURACY_DOWN || moveEffect == EFFECT_ACCURACY_DOWN_2) RETURN_SCORE_MINUS(10); break; @@ -1299,7 +1300,8 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) case EFFECT_ACCURACY_DOWN_2: if (!ShouldLowerStat(battlerDef, aiData->abilities[battlerDef], STAT_ACC)) ADJUST_SCORE(-10); - else if (aiData->abilities[battlerDef] == ABILITY_KEEN_EYE || (B_ILLUMINATE_EFFECT >= GEN_9 && aiData->abilities[battlerDef] == ABILITY_ILLUMINATE)) + else if (aiData->abilities[battlerDef] == ABILITY_KEEN_EYE || aiData->abilities[battlerDef] == ABILITY_MINDS_EYE + || (B_ILLUMINATE_EFFECT >= GEN_9 && aiData->abilities[battlerDef] == ABILITY_ILLUMINATE)) ADJUST_SCORE(-8); break; case EFFECT_EVASION_DOWN: @@ -3933,7 +3935,7 @@ static s32 AI_CheckViability(u32 battlerAtk, u32 battlerDef, u32 move, s32 score //TODO - track entire opponent party data to determine hazard effectiveness break; case EFFECT_FORESIGHT: - if (aiData->abilities[battlerAtk] == ABILITY_SCRAPPY) + if (aiData->abilities[battlerAtk] == ABILITY_SCRAPPY || aiData->abilities[battlerAtk] == ABILITY_MINDS_EYE) break; else if (gBattleMons[battlerDef].statStages[STAT_EVASION] > DEFAULT_STAT_STAGE || (IS_BATTLER_OF_TYPE(battlerDef, TYPE_GHOST) diff --git a/src/battle_ai_switch_items.c b/src/battle_ai_switch_items.c index 6a6ced311a..7436f7af6d 100644 --- a/src/battle_ai_switch_items.c +++ b/src/battle_ai_switch_items.c @@ -509,6 +509,7 @@ static bool32 ShouldSwitchIfGameStatePrompt(u32 battler, bool32 emitResult) if (gBattleMons[battler].statStages[STAT_EVASION] > (DEFAULT_STAT_STAGE + 3) && AI_DATA->abilities[opposingBattler] != ABILITY_UNAWARE && AI_DATA->abilities[opposingBattler] != ABILITY_KEEN_EYE + && AI_DATA->abilities[opposingBattler] != ABILITY_MINDS_EYE && (B_ILLUMINATE_EFFECT >= GEN_9 && AI_DATA->abilities[opposingBattler] != ABILITY_ILLUMINATE) && !(gBattleMons[battler].status2 & STATUS2_FORESIGHT) && !(gStatuses3[battler] & STATUS3_MIRACLE_EYED)) diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index 1a41f72992..1ad4343442 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -1855,6 +1855,7 @@ bool32 ShouldLowerAccuracy(u32 battlerAtk, u32 battlerDef, u32 defAbility) && defAbility != ABILITY_WHITE_SMOKE && defAbility != ABILITY_FULL_METAL_BODY && defAbility != ABILITY_KEEN_EYE + && defAbility != ABILITY_MINDS_EYE && (B_ILLUMINATE_EFFECT >= GEN_9 && defAbility != ABILITY_ILLUMINATE) && AI_DATA->holdEffects[battlerDef] != HOLD_EFFECT_CLEAR_AMULET) return TRUE; diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index a14f387b04..225bef077c 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -1547,7 +1547,7 @@ static bool32 AccuracyCalcHelper(u16 move) return TRUE; } // If the attacker has the ability No Guard and they aren't targeting a Pokemon involved in a Sky Drop with the move Sky Drop, move hits. - else if (GetBattlerAbility(gBattlerAttacker) == ABILITY_NO_GUARD && (move != MOVE_SKY_DROP || gBattleStruct->skyDropTargets[gBattlerTarget] == 0xFF)) + else if (GetBattlerAbility(gBattlerTarget) == ABILITY_NO_GUARD && (move != MOVE_SKY_DROP || gBattleStruct->skyDropTargets[gBattlerTarget] == 0xFF)) { if (!JumpIfMoveFailed(7, move)) RecordAbilityBattle(gBattlerAttacker, ABILITY_NO_GUARD); @@ -1636,7 +1636,8 @@ u32 GetTotalAccuracy(u32 battlerAtk, u32 battlerDef, u32 move, u32 atkAbility, u gPotentialItemEffectBattler = battlerDef; accStage = gBattleMons[battlerAtk].statStages[STAT_ACC]; evasionStage = gBattleMons[battlerDef].statStages[STAT_EVASION]; - if (atkAbility == ABILITY_UNAWARE || atkAbility == ABILITY_KEEN_EYE || (B_ILLUMINATE_EFFECT >= GEN_9 && atkAbility == ABILITY_ILLUMINATE)) + if (atkAbility == ABILITY_UNAWARE || atkAbility == ABILITY_KEEN_EYE || atkAbility == ABILITY_MINDS_EYE + || (B_ILLUMINATE_EFFECT >= GEN_9 && atkAbility == ABILITY_ILLUMINATE)) evasionStage = DEFAULT_STAT_STAGE; if (gBattleMoves[move].ignoresTargetDefenseEvasionStages) evasionStage = DEFAULT_STAT_STAGE; @@ -5080,7 +5081,7 @@ static void Cmd_playstatchangeanimation(void) && ability != ABILITY_CLEAR_BODY && ability != ABILITY_FULL_METAL_BODY && ability != ABILITY_WHITE_SMOKE - && !(ability == ABILITY_KEEN_EYE && currStat == STAT_ACC) + && !((ability == ABILITY_KEEN_EYE || ability == ABILITY_MINDS_EYE) && currStat == STAT_ACC) && !(B_ILLUMINATE_EFFECT >= GEN_9 && ability == ABILITY_ILLUMINATE && currStat == STAT_ACC) && !(ability == ABILITY_HYPER_CUTTER && currStat == STAT_ATK) && !(ability == ABILITY_BIG_PECKS && currStat == STAT_DEF)) @@ -11355,7 +11356,7 @@ static u32 ChangeStatBuffs(s8 statValue, u32 statId, u32 flags, const u8 *BS_ptr return STAT_CHANGE_DIDNT_WORK; } else if (!certain - && ((battlerAbility == ABILITY_KEEN_EYE && statId == STAT_ACC) + && (((battlerAbility == ABILITY_KEEN_EYE || battlerAbility == ABILITY_MINDS_EYE) && statId == STAT_ACC) || (B_ILLUMINATE_EFFECT >= GEN_9 && battlerAbility == ABILITY_ILLUMINATE && statId == STAT_ACC) || (battlerAbility == ABILITY_HYPER_CUTTER && statId == STAT_ATK) || (battlerAbility == ABILITY_BIG_PECKS && statId == STAT_DEF))) diff --git a/src/battle_util.c b/src/battle_util.c index b30eff7c18..be71068e2f 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -976,6 +976,8 @@ static const u8 sAbilitiesAffectedByMoldBreaker[] = [ABILITY_GOOD_AS_GOLD] = 1, [ABILITY_PURIFYING_SALT] = 1, [ABILITY_WELL_BAKED_BODY] = 1, + [ABILITY_MINDS_EYE] = 1, + [ABILITY_ILLUMINATE] = 1, }; static const u8 sAbilitiesNotTraced[ABILITIES_COUNT] = @@ -9984,6 +9986,7 @@ s32 CalculateMoveDamageVars(u32 move, u32 battlerAtk, u32 battlerDef, u32 moveTy static inline void MulByTypeEffectiveness(uq4_12_t *modifier, u32 move, u32 moveType, u32 battlerDef, u32 defType, u32 battlerAtk, bool32 recordAbilities) { uq4_12_t mod = GetTypeModifier(moveType, defType); + u32 abilityAtk = GetBattlerAbility(battlerAtk); if (mod == UQ_4_12(0.0) && GetBattlerHoldEffect(battlerDef, TRUE) == HOLD_EFFECT_RING_TARGET) { @@ -9995,11 +9998,13 @@ static inline void MulByTypeEffectiveness(uq4_12_t *modifier, u32 move, u32 move { mod = UQ_4_12(1.0); } - else if ((moveType == TYPE_FIGHTING || moveType == TYPE_NORMAL) && defType == TYPE_GHOST && GetBattlerAbility(battlerAtk) == ABILITY_SCRAPPY && mod == UQ_4_12(0.0)) + else if ((moveType == TYPE_FIGHTING || moveType == TYPE_NORMAL) && defType == TYPE_GHOST + && (abilityAtk == ABILITY_SCRAPPY || abilityAtk == ABILITY_MINDS_EYE) + && mod == UQ_4_12(0.0)) { mod = UQ_4_12(1.0); if (recordAbilities) - RecordAbilityBattle(battlerAtk, ABILITY_SCRAPPY); + RecordAbilityBattle(battlerAtk, abilityAtk); } if (moveType == TYPE_PSYCHIC && defType == TYPE_DARK && gStatuses3[battlerDef] & STATUS3_MIRACLE_EYED && mod == UQ_4_12(0.0)) diff --git a/test/battle/ability/keen_eye.c b/test/battle/ability/keen_eye.c new file mode 100644 index 0000000000..c0a6f34c84 --- /dev/null +++ b/test/battle/ability/keen_eye.c @@ -0,0 +1,199 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(gBattleMoves[MOVE_TACKLE].accuracy == 100); + ASSUME(gBattleMoves[MOVE_SAND_ATTACK].effect == EFFECT_ACCURACY_DOWN); + ASSUME(B_ILLUMINATE_EFFECT >= GEN_9); +} + +SINGLE_BATTLE_TEST("Keen Eye, Gen9+ Illuminate & Minds Eye prevent accuracy stage reduction from moves") +{ + u16 ability; + u32 species; + + PARAMETRIZE { species = SPECIES_HITMONCHAN; ability = ABILITY_KEEN_EYE; } + PARAMETRIZE { species = SPECIES_STARYU; ability = ABILITY_ILLUMINATE; } + PARAMETRIZE { species = SPECIES_URSALUNA_BLOODMOON; ability = ABILITY_MINDS_EYE; } + + PASSES_RANDOMLY(100, 100, RNG_ACCURACY); + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(species) { Ability(ability); } + } WHEN { + TURN { MOVE(player, MOVE_SAND_ATTACK); MOVE(opponent, MOVE_TACKLE); } + } SCENE { + ABILITY_POPUP(opponent, ability); + NOT ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + if (species == SPECIES_HITMONCHAN) + MESSAGE("Foe Hitmonchan's Keen Eye prevents accuracy loss!"); + else if (species == SPECIES_STARYU) + MESSAGE("Foe Staryu's Illuminate prevents accuracy loss!"); + else + MESSAGE("Foe Ursaluna's Mind's Eye prevents accuracy loss!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent); + } +} + +SINGLE_BATTLE_TEST("Keen Eye, Gen9+ Illuminate & Minds Eye ignore target's evasion stat") +{ + u16 ability; + u32 species; + + PARAMETRIZE { species = SPECIES_HITMONCHAN; ability = ABILITY_KEEN_EYE; } + PARAMETRIZE { species = SPECIES_STARYU; ability = ABILITY_ILLUMINATE; } + PARAMETRIZE { species = SPECIES_URSALUNA_BLOODMOON; ability = ABILITY_MINDS_EYE; } + + PASSES_RANDOMLY(100, 100, RNG_ACCURACY); + GIVEN { + ASSUME(gBattleMoves[MOVE_DOUBLE_TEAM].effect == EFFECT_EVASION_UP); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(species) { Ability(ability); } + } WHEN { + TURN { MOVE(player, MOVE_DOUBLE_TEAM); MOVE(opponent, MOVE_TACKLE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_DOUBLE_TEAM, player); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent); + } +} + +SINGLE_BATTLE_TEST("Keen Eye, Gen9+ Illuminate & Minds Eye are ignored by Mold Breaker abilities") +{ + u16 abilityPlayer = ABILITY_NONE, abilityOpponent = ABILITY_NONE; + u16 speciesPlayer = SPECIES_NONE, speciesOpponent = SPECIES_NONE; + + u32 j; + static const u16 moldBreakerAbilities[][2] = { + {SPECIES_PINSIR, ABILITY_MOLD_BREAKER}, + {SPECIES_RESHIRAM, ABILITY_TURBOBLAZE}, + {SPECIES_ZEKROM, ABILITY_TERAVOLT}, + }; + + for (j = 0; j < ARRAY_COUNT(moldBreakerAbilities); j++) { + speciesPlayer = moldBreakerAbilities[j][0]; abilityPlayer = moldBreakerAbilities[j][1]; + PARAMETRIZE { speciesOpponent = SPECIES_HITMONCHAN; abilityOpponent = ABILITY_KEEN_EYE; } + PARAMETRIZE { speciesOpponent = SPECIES_STARYU; abilityOpponent = ABILITY_ILLUMINATE; } + PARAMETRIZE { speciesOpponent = SPECIES_URSALUNA_BLOODMOON; abilityOpponent = ABILITY_MINDS_EYE; } + } + + PASSES_RANDOMLY(gBattleMoves[MOVE_TACKLE].accuracy * 3 / 4, 100, RNG_ACCURACY); + GIVEN { + PLAYER(speciesPlayer) { Ability(abilityPlayer); } + OPPONENT(speciesOpponent) { Ability(abilityOpponent); } + } WHEN { + TURN { MOVE(player, MOVE_SAND_ATTACK); MOVE(opponent, MOVE_TACKLE); } + } SCENE { + ABILITY_POPUP(player, abilityPlayer); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SAND_ATTACK, player); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent); + } +} + +SINGLE_BATTLE_TEST("Keen Eye, Gen9+ Illuminate & Minds Eye don't prevent Topsy-Turvy") +{ + u16 ability; + u32 species; + + PARAMETRIZE { species = SPECIES_HITMONCHAN; ability = ABILITY_KEEN_EYE; } + PARAMETRIZE { species = SPECIES_STARYU; ability = ABILITY_ILLUMINATE; } + PARAMETRIZE { species = SPECIES_URSALUNA_BLOODMOON; ability = ABILITY_MINDS_EYE; } + + GIVEN { + ASSUME(gBattleMoves[MOVE_HONE_CLAWS].effect == EFFECT_ATTACK_ACCURACY_UP); + ASSUME(gBattleMoves[MOVE_TOPSY_TURVY].effect == EFFECT_TOPSY_TURVY); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(species) { Ability(ability); } + } WHEN { + TURN { MOVE(opponent, MOVE_HONE_CLAWS); MOVE(player, MOVE_TOPSY_TURVY); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_HONE_CLAWS, opponent); + if (species == SPECIES_HITMONCHAN) { + MESSAGE("Foe Hitmonchan's Attack rose!"); + MESSAGE("Foe Hitmonchan's accuracy rose!"); + } else if (species == SPECIES_STARYU) { + MESSAGE("Foe Staryu's Attack rose!"); + MESSAGE("Foe Staryu's accuracy rose!"); + } else { + MESSAGE("Foe Ursaluna's Attack rose!"); + MESSAGE("Foe Ursaluna's accuracy rose!"); + } + ANIMATION(ANIM_TYPE_MOVE, MOVE_TOPSY_TURVY, player); + if (species == SPECIES_HITMONCHAN) + MESSAGE("Foe Hitmonchan's stat changes were all reversed!"); + else if (species == SPECIES_STARYU) + MESSAGE("Foe Staryu's stat changes were all reversed!"); + else + MESSAGE("Foe Ursaluna's stat changes were all reversed!"); + } THEN { + EXPECT_EQ(opponent->statStages[STAT_ACC], DEFAULT_STAT_STAGE - 1); + } +} + +SINGLE_BATTLE_TEST("Keen Eye, Gen9+ Illuminate & Minds Eye don't prevent receiving negative Attack stage changes from Baton Pass") +{ + u16 ability; + u32 species; + PARAMETRIZE { species = SPECIES_HITMONCHAN; ability = ABILITY_KEEN_EYE; } + PARAMETRIZE { species = SPECIES_STARYU; ability = ABILITY_ILLUMINATE; } + PARAMETRIZE { species = SPECIES_URSALUNA_BLOODMOON; ability = ABILITY_MINDS_EYE; } + + GIVEN { + ASSUME(gBattleMoves[MOVE_BATON_PASS].effect == EFFECT_BATON_PASS); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(species) { Ability(ability); } + } WHEN { + TURN { MOVE(player, MOVE_SAND_ATTACK); + MOVE(opponent, MOVE_BATON_PASS); + SEND_OUT(opponent, 1); + } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SAND_ATTACK, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_BATON_PASS, opponent); + if (species == SPECIES_HITMONCHAN) + MESSAGE("2 sent out Hitmonchan!"); + else if (species == SPECIES_STARYU) + MESSAGE("2 sent out Staryu!"); + else + MESSAGE("2 sent out Ursaluna!"); + } THEN { + EXPECT_EQ(opponent->statStages[STAT_ACC], DEFAULT_STAT_STAGE - 1); + } +} + +SINGLE_BATTLE_TEST("Keen Eye & Gen9+ Illuminate don't prevent Spectral Thief from resetting positive accuracy stage changes") +{ + u16 ability; + u32 species; + + PARAMETRIZE { species = SPECIES_HITMONCHAN; ability = ABILITY_KEEN_EYE; } + PARAMETRIZE { species = SPECIES_STARYU; ability = ABILITY_ILLUMINATE; } + + GIVEN { + ASSUME(gBattleMoves[MOVE_HONE_CLAWS].effect == EFFECT_ATTACK_ACCURACY_UP); + ASSUME(gBattleMoves[MOVE_SPECTRAL_THIEF].effect == EFFECT_SPECTRAL_THIEF); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(species) { Ability(ability); } + } WHEN { + TURN { MOVE(opponent, MOVE_HONE_CLAWS); MOVE(player, MOVE_SPECTRAL_THIEF); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_HONE_CLAWS, opponent); + if (species == SPECIES_HITMONCHAN) + { + MESSAGE("Foe Hitmonchan's Attack rose!"); + MESSAGE("Foe Hitmonchan's accuracy rose!"); + } + else + { + MESSAGE("Foe Staryu's Attack rose!"); + MESSAGE("Foe Staryu's accuracy rose!"); + } + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPECTRAL_THIEF, player); + MESSAGE("Wobbuffet stole the target's boosted stats!"); + } THEN { + EXPECT_EQ(opponent->statStages[STAT_ACC], DEFAULT_STAT_STAGE); + } +} diff --git a/test/battle/ability/minds_eye.c b/test/battle/ability/minds_eye.c new file mode 100644 index 0000000000..52434c6670 --- /dev/null +++ b/test/battle/ability/minds_eye.c @@ -0,0 +1,71 @@ +#include "global.h" +#include "test/battle.h" + +SINGLE_BATTLE_TEST("Mind's Eye allows to hit Ghost-type Pokémon with Normal- and Fighting-type moves") +{ + u32 move; + PARAMETRIZE { move = MOVE_TACKLE; } + PARAMETRIZE { move = MOVE_KARATE_CHOP; } + + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_MINDS_EYE); }; + OPPONENT(SPECIES_GASTLY); + } WHEN { + TURN { MOVE(player, move); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, move, player); + HP_BAR(opponent); + } +} + +// No current official way to test this, effect based on Smogon's NatDex format. +SINGLE_BATTLE_TEST("Mind's Eye doesn't bypass a Ghost-type's Wonder Guard") +{ + u32 move; + PARAMETRIZE { move = MOVE_TACKLE; } + PARAMETRIZE { move = MOVE_KARATE_CHOP; } + + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_SCRAPPY); }; + OPPONENT(SPECIES_SHEDINJA) { Ability(ABILITY_WONDER_GUARD); }; + } WHEN { + TURN { MOVE(player, move); } + } SCENE { + NONE_OF { + ANIMATION(ANIM_TYPE_MOVE, move, player); + HP_BAR(opponent); + } + ABILITY_POPUP(opponent, ABILITY_WONDER_GUARD); + MESSAGE("Foe Shedinja avoided damage with Wonder Guard!"); + } +} + +//// AI TESTS //// + +AI_SINGLE_BATTLE_TEST("AI doesn't use accuracy-lowering moves if it knows that the foe has Mind's Eye") +{ + u32 abilityAI = ABILITY_NONE, moveAI = MOVE_NONE, j = 0; + + for (j = MOVE_NONE + 1; j < MOVES_COUNT; j++) + { + if (gBattleMoves[j].effect == EFFECT_ACCURACY_DOWN || gBattleMoves[j].effect == EFFECT_ACCURACY_DOWN_2) { + PARAMETRIZE{ moveAI = j; abilityAI = ABILITY_SWIFT_SWIM; } + PARAMETRIZE{ moveAI = j; abilityAI = ABILITY_MOLD_BREAKER; } + } + } + + GIVEN { + AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); + PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_MINDS_EYE); } + OPPONENT(SPECIES_BASCULEGION) { Moves(MOVE_CELEBRATE, moveAI); Ability(abilityAI); } + } WHEN { + TURN { MOVE(player, MOVE_TACKLE); } + TURN { MOVE(player, MOVE_TACKLE); + if (abilityAI == ABILITY_MOLD_BREAKER) { SCORE_GT(opponent, moveAI, MOVE_CELEBRATE); } + else { SCORE_EQ(opponent, moveAI, MOVE_CELEBRATE); } + } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, player); + if (abilityAI == ABILITY_MOLD_BREAKER) { ANIMATION(ANIM_TYPE_MOVE, moveAI, opponent); } + } +}