From 8d2d62273bd0d3565c4edb211ae4cf6a6b35b258 Mon Sep 17 00:00:00 2001 From: PhallenTree <168426989+PhallenTree@users.noreply.github.com> Date: Thu, 10 Oct 2024 17:36:01 +0100 Subject: [PATCH] Updated ability popups for Skill Swap, Mummy/Lingering Aroma, Worry Seed, Simple Beam, fix Doodle/Role Play bugs (#5493) * Updated ability popups of Skill Swap, Mummy/Lingering Aroma, Worry Seed, Simple Beam, Fix Doodle and Role Play issues * More Doodle fixes * Add tests * Fix Doodle not activating if partner is fainted and its ability cannot be suppressed * Fix tests compile * Commander cantBeOverwritten * Add battle script for Overwrite then Regular ability --- data/battle_scripts_1.s | 94 +++++++++++++--------- src/battle_message.c | 4 +- src/battle_script_commands.c | 12 ++- src/battle_util.c | 3 +- src/data/abilities.h | 1 + test/battle/ability/mummy.c | 12 +-- test/battle/move_effect/doodle.c | 40 +++++++++- test/battle/move_effect/role_play.c | 74 ++++++++++++++--- test/battle/move_effect/simple_beam.c | 74 +++++++++++++++++ test/battle/move_effect/skill_swap.c | 111 ++++++++++++++++++++++++++ test/battle/move_effect/worry_seed.c | 74 +++++++++++++++++ 11 files changed, 432 insertions(+), 67 deletions(-) create mode 100644 test/battle/move_effect/simple_beam.c create mode 100644 test/battle/move_effect/skill_swap.c create mode 100644 test/battle/move_effect/worry_seed.c diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 94f5736317..fa56c3ff7a 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -214,27 +214,25 @@ BattleScript_EffectDoodle:: attackcanceler attackstring ppreduce + trycopyability BS_ATTACKER, BattleScript_ButItFailed attackanimation waitanimation setbyte gBattleCommunication, 0 + goto BattleScript_EffectDoodle_AfterCopy BattleScript_EffectDoodle_CopyAbility: - trycopyability BS_ATTACKER, BattleScript_ButItFailed + trycopyability BS_ATTACKER, BattleScript_MoveEnd +BattleScript_EffectDoodle_AfterCopy: .if B_ABILITY_POP_UP == TRUE - setbyte sFIXED_ABILITY_POPUP, TRUE - showabilitypopup BS_ATTACKER - pause 60 - sethword sABILITY_OVERWRITE, 0 - updateabilitypopup BS_ATTACKER - pause 20 - destroyabilitypopup - pause 40 + copybyte gBattlerAbility, gBattlerAttacker + call BattleScript_AbilityPopUpOverwriteThenNormal .endif + recordability BS_ATTACKER printstring STRINGID_PKMNCOPIEDFOE waitmessage B_WAIT_TIME_LONG switchinabilities BS_ATTACKER jumpifbyte CMP_NOT_EQUAL, gBattleCommunication, 0x0, BattleScript_MoveEnd addbyte gBattleCommunication, 1 - jumpifnoally BS_TARGET, BattleScript_MoveEnd + jumpifnoally BS_ATTACKER, BattleScript_MoveEnd setallytonextattacker BattleScript_EffectDoodle_CopyAbility goto BattleScript_MoveEnd @@ -2346,6 +2344,11 @@ BattleScript_EffectSimpleBeam:: setabilitysimple BS_TARGET, BattleScript_ButItFailed attackanimation waitanimation +.if B_ABILITY_POP_UP == TRUE + copybyte gBattlerAbility, gBattlerTarget + call BattleScript_AbilityPopUpOverwriteThenNormal +.endif + recordability BS_TARGET printstring STRINGID_PKMNACQUIREDSIMPLE waitmessage B_WAIT_TIME_LONG trytoclearprimalweather @@ -2444,11 +2447,17 @@ BattleScript_EffectWorrySeed:: tryworryseed BattleScript_ButItFailed attackanimation waitanimation +.if B_ABILITY_POP_UP == TRUE + copybyte gBattlerAbility, gBattlerTarget + call BattleScript_AbilityPopUpOverwriteThenNormal +.endif + recordability BS_TARGET printstring STRINGID_PKMNACQUIREDABILITY waitmessage B_WAIT_TIME_LONG trytoclearprimalweather tryrevertweatherform flushtextbox + tryendneutralizinggas BS_TARGET goto BattleScript_MoveEnd BattleScript_EffectPowerSplit:: @@ -5034,15 +5043,10 @@ BattleScript_EffectRolePlay:: attackanimation waitanimation .if B_ABILITY_POP_UP == TRUE - setbyte sFIXED_ABILITY_POPUP, TRUE - showabilitypopup BS_ATTACKER - pause 60 - sethword sABILITY_OVERWRITE, 0 - updateabilitypopup BS_ATTACKER - pause 20 - destroyabilitypopup - pause 40 + copybyte gBattlerAbility, gBattlerAttacker + call BattleScript_AbilityPopUpOverwriteThenNormal .endif + recordability BS_ATTACKER printstring STRINGID_PKMNCOPIEDFOE waitmessage B_WAIT_TIME_LONG switchinabilities BS_ATTACKER @@ -5185,12 +5189,17 @@ BattleScript_EffectSkillSwap:: tryswapabilities BattleScript_ButItFailed attackanimation waitanimation + jumpiftargetally BattleScript_EffectSkillSwap_AfterAbilityPopUp .if B_ABILITY_POP_UP == TRUE - call BattleScript_AbilityPopUpTarget - pause 20 copybyte gBattlerAbility, gBattlerAttacker - call BattleScript_AbilityPopUp + call BattleScript_AbilityPopUpOverwriteThenNormal + copybyte gBattlerAbility, gBattlerTarget + copyhword sABILITY_OVERWRITE, gLastUsedAbility + call BattleScript_AbilityPopUpOverwriteThenNormal .endif +BattleScript_EffectSkillSwap_AfterAbilityPopUp: + recordability BS_ATTACKER + recordability BS_TARGET printstring STRINGID_PKMNSWAPPEDABILITIES waitmessage B_WAIT_TIME_LONG .if B_SKILL_SWAP >= GEN_4 @@ -7605,6 +7614,18 @@ BattleScript_AbilityPopUpScripting: sethword sABILITY_OVERWRITE, 0 return +BattleScript_AbilityPopUpOverwriteThenNormal: + setbyte sFIXED_ABILITY_POPUP, TRUE + showabilitypopup BS_ABILITY_BATTLER + pause 60 + sethword sABILITY_OVERWRITE, 0 + updateabilitypopup BS_ABILITY_BATTLER + pause 20 + recordability BS_ABILITY_BATTLER + destroyabilitypopup + pause 40 + return + BattleScript_SpeedBoostActivates:: statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_CHANGE_ALLOW_PTR, BattleScript_SpeedBoostActivatesEnd call BattleScript_AbilityPopUp @@ -8366,33 +8387,30 @@ BattleScript_CursedBodyActivates:: return BattleScript_MummyActivates:: - call BattleScript_AbilityPopUp +.if B_ABILITY_POP_UP == TRUE + call BattleScript_AbilityPopUpTarget + setbyte sFIXED_ABILITY_POPUP, TRUE + copybyte gBattlerAbility, gBattlerAttacker + copyhword sABILITY_OVERWRITE, gLastUsedAbility + call BattleScript_AbilityPopUpOverwriteThenNormal +.endif + recordability BS_TARGET + recordability BS_ATTACKER printstring STRINGID_ATTACKERACQUIREDABILITY waitmessage B_WAIT_TIME_LONG return BattleScript_WanderingSpiritActivates:: .if B_ABILITY_POP_UP == TRUE - setbyte sFIXED_ABILITY_POPUP, TRUE + copybyte gBattlerAbility, gBattlerTarget sethword sABILITY_OVERWRITE, ABILITY_WANDERING_SPIRIT - showabilitypopup BS_TARGET - pause 60 - sethword sABILITY_OVERWRITE, 0 - updateabilitypopup BS_TARGET - pause 20 - destroyabilitypopup - pause 40 + call BattleScript_AbilityPopUpOverwriteThenNormal copybyte gBattlerAbility, gBattlerAttacker - setbyte sFIXED_ABILITY_POPUP, TRUE copyhword sABILITY_OVERWRITE, gLastUsedAbility - showabilitypopup BS_ATTACKER - pause 60 - sethword sABILITY_OVERWRITE, 0 - updateabilitypopup BS_ATTACKER - pause 20 - destroyabilitypopup - pause 40 + call BattleScript_AbilityPopUpOverwriteThenNormal .endif + recordability BS_TARGET + recordability BS_ATTACKER printstring STRINGID_SWAPPEDABILITIES waitmessage B_WAIT_TIME_LONG switchinabilities BS_ATTACKER diff --git a/src/battle_message.c b/src/battle_message.c index ecb2932124..52c6dec6ae 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -640,7 +640,7 @@ static const u8 sText_HealingWishCameTrue[] = _("The healing wish came true\nfor static const u8 sText_HealingWishHealed[] = _("{B_ATK_NAME_WITH_PREFIX} regained health!"); static const u8 sText_LunarDanceCameTrue[] = _("{B_ATK_NAME_WITH_PREFIX} became cloaked\nin mystical moonlight!"); static const u8 sText_CursedBodyDisabled[] = _("{B_ATK_NAME_WITH_PREFIX}'s {B_BUFF1} was disabled\nby {B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY}!"); -static const u8 sText_AttackerAquiredAbility[] = _("{B_ATK_NAME_WITH_PREFIX} acquired\n{B_LAST_ABILITY}!"); +static const u8 sText_AttackerAcquiredAbility[] = _("{B_ATK_NAME_WITH_PREFIX} acquired\n{B_ATK_ABILITY}!"); static const u8 sText_TargetStatWontGoHigher[] = _("{B_DEF_NAME_WITH_PREFIX}'s {B_BUFF1}\nwon't go higher!"); static const u8 sText_PkmnMoveBouncedViaAbility[] = _("{B_ATK_NAME_WITH_PREFIX}'s {B_CURRENT_MOVE} was\nbounced back by {B_DEF_NAME_WITH_PREFIX}'s\l{B_DEF_ABILITY}!"); static const u8 sText_ImposterTransform[] = _("{B_ATK_NAME_WITH_PREFIX} transformed into\n{B_DEF_NAME_WITH_PREFIX} using {B_LAST_ABILITY}!"); @@ -1477,7 +1477,7 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = [STRINGID_HEALINGWISHHEALED - BATTLESTRINGS_TABLE_START] = sText_HealingWishHealed, [STRINGID_LUNARDANCECAMETRUE - BATTLESTRINGS_TABLE_START] = sText_LunarDanceCameTrue, [STRINGID_CUSEDBODYDISABLED - BATTLESTRINGS_TABLE_START] = sText_CursedBodyDisabled, - [STRINGID_ATTACKERACQUIREDABILITY - BATTLESTRINGS_TABLE_START] = sText_AttackerAquiredAbility, + [STRINGID_ATTACKERACQUIREDABILITY - BATTLESTRINGS_TABLE_START] = sText_AttackerAcquiredAbility, [STRINGID_TARGETABILITYSTATLOWER - BATTLESTRINGS_TABLE_START] = sText_TargetAbilityLoweredStat, [STRINGID_TARGETSTATWONTGOHIGHER - BATTLESTRINGS_TABLE_START] = sText_TargetStatWontGoHigher, [STRINGID_PKMNMOVEBOUNCEDABILITY - BATTLESTRINGS_TABLE_START] = sText_PkmnMoveBouncedViaAbility, diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index ba372d1c54..618164dd18 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -9782,6 +9782,7 @@ static void Cmd_various(void) if (gBattleMons[gBattlerTarget].ability == ABILITY_NEUTRALIZING_GAS) gSpecialStatuses[gBattlerTarget].neutralizingGasRemoved = TRUE; + gBattleScripting.abilityPopupOverwrite = gBattleMons[gBattlerTarget].ability; gBattleMons[gBattlerTarget].ability = gBattleStruct->overwrittenAbilities[gBattlerTarget] = ABILITY_SIMPLE; gBattlescriptCurrInstr = cmd->nextInstr; } @@ -14369,7 +14370,7 @@ static void Cmd_trycopyability(void) if (gBattleMons[battler].ability == defAbility || defAbility == ABILITY_NONE || gAbilitiesInfo[gBattleMons[battler].ability].cantBeSuppressed - || gAbilitiesInfo[gBattleMons[BATTLE_PARTNER(battler)].ability].cantBeSuppressed + || (IsBattlerAlive(BATTLE_PARTNER(battler)) && gAbilitiesInfo[gBattleMons[BATTLE_PARTNER(battler)].ability].cantBeSuppressed && gMovesInfo[gCurrentMove].effect == EFFECT_DOODLE) || gAbilitiesInfo[defAbility].cantBeCopied) { gBattlescriptCurrInstr = cmd->failInstr; @@ -14565,9 +14566,11 @@ static void Cmd_tryswapabilities(void) } else { - u16 abilityAtk = gBattleMons[gBattlerAttacker].ability; - gBattleMons[gBattlerAttacker].ability = gBattleStruct->overwrittenAbilities[gBattlerAttacker] = gBattleMons[gBattlerTarget].ability; - gBattleMons[gBattlerTarget].ability = gBattleStruct->overwrittenAbilities[gBattlerTarget] = abilityAtk; + if (GetBattlerSide(gBattlerAttacker) != GetBattlerSide(gBattlerTarget)) + gBattleScripting.abilityPopupOverwrite = gBattleMons[gBattlerAttacker].ability; + gLastUsedAbility = gBattleMons[gBattlerTarget].ability; + gBattleMons[gBattlerTarget].ability = gBattleStruct->overwrittenAbilities[gBattlerTarget] = gBattleMons[gBattlerAttacker].ability; + gBattleMons[gBattlerAttacker].ability = gBattleStruct->overwrittenAbilities[gBattlerAttacker] = gLastUsedAbility; gBattlescriptCurrInstr = cmd->nextInstr; } @@ -15859,6 +15862,7 @@ static void Cmd_tryworryseed(void) } else { + gBattleScripting.abilityPopupOverwrite = gBattleMons[gBattlerTarget].ability; gBattleMons[gBattlerTarget].ability = gBattleStruct->overwrittenAbilities[gBattlerTarget] = ABILITY_INSOMNIA; gBattlescriptCurrInstr = cmd->nextInstr; } diff --git a/src/battle_util.c b/src/battle_util.c index b572acc7c1..e5d8c5f041 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -5546,7 +5546,8 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 break; } - gLastUsedAbility = gBattleMons[gBattlerAttacker].ability = gBattleStruct->overwrittenAbilities[gBattlerAttacker] = gBattleMons[gBattlerTarget].ability; + gLastUsedAbility = gBattleMons[gBattlerAttacker].ability; + gBattleMons[gBattlerAttacker].ability = gBattleStruct->overwrittenAbilities[gBattlerAttacker] = gBattleMons[gBattlerTarget].ability; BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_MummyActivates; effect++; diff --git a/src/data/abilities.h b/src/data/abilities.h index a85f114fec..ba768a0a51 100644 --- a/src/data/abilities.h +++ b/src/data/abilities.h @@ -2273,6 +2273,7 @@ const struct Ability gAbilitiesInfo[ABILITIES_COUNT] = .cantBeSwapped = TRUE, .cantBeTraced = TRUE, .cantBeSuppressed = TRUE, + .cantBeOverwritten = TRUE, }, [ABILITY_ELECTROMORPHOSIS] = diff --git a/test/battle/ability/mummy.c b/test/battle/ability/mummy.c index ed80a178e6..74461ec2ee 100644 --- a/test/battle/ability/mummy.c +++ b/test/battle/ability/mummy.c @@ -70,19 +70,19 @@ SINGLE_BATTLE_TEST("Mummy doesn't replace abilities that can't be suppressed") PARAMETRIZE { species = SPECIES_ARCEUS; ability = ABILITY_MULTITYPE; } PARAMETRIZE { species = SPECIES_AEGISLASH; ability = ABILITY_STANCE_CHANGE; } - PARAMETRIZE { species = SPECIES_WISHIWASHI; ability = ABILITY_SCHOOLING; } - PARAMETRIZE { species = SPECIES_KOMALA; ability = ABILITY_COMATOSE; } PARAMETRIZE { species = SPECIES_MINIOR; ability = ABILITY_SHIELDS_DOWN; } + PARAMETRIZE { species = SPECIES_WISHIWASHI; ability = ABILITY_SCHOOLING; } PARAMETRIZE { species = SPECIES_MIMIKYU; ability = ABILITY_DISGUISE; } - PARAMETRIZE { species = SPECIES_SILVALLY; ability = ABILITY_RKS_SYSTEM; } PARAMETRIZE { species = SPECIES_GRENINJA_BATTLE_BOND; ability = ABILITY_BATTLE_BOND; } PARAMETRIZE { species = SPECIES_ZYGARDE; ability = ABILITY_POWER_CONSTRUCT; } - PARAMETRIZE { species = SPECIES_EISCUE; ability = ABILITY_ICE_FACE; } + PARAMETRIZE { species = SPECIES_KOMALA; ability = ABILITY_COMATOSE; } + PARAMETRIZE { species = SPECIES_SILVALLY; ability = ABILITY_RKS_SYSTEM; } PARAMETRIZE { species = SPECIES_CRAMORANT; ability = ABILITY_GULP_MISSILE; } + PARAMETRIZE { species = SPECIES_EISCUE; ability = ABILITY_ICE_FACE; } + PARAMETRIZE { species = SPECIES_CALYREX_ICE; ability = ABILITY_AS_ONE_ICE_RIDER; } + PARAMETRIZE { species = SPECIES_CALYREX_SHADOW; ability = ABILITY_AS_ONE_SHADOW_RIDER; } PARAMETRIZE { species = SPECIES_PALAFIN_ZERO; ability = ABILITY_ZERO_TO_HERO; } PARAMETRIZE { species = SPECIES_TATSUGIRI; ability = ABILITY_COMMANDER; } - PARAMETRIZE { species = SPECIES_CALYREX_SHADOW_RIDER; ability = ABILITY_AS_ONE_SHADOW_RIDER; } - PARAMETRIZE { species = SPECIES_CALYREX_ICE_RIDER; ability = ABILITY_AS_ONE_ICE_RIDER; } GIVEN { PLAYER(SPECIES_YAMASK); diff --git a/test/battle/move_effect/doodle.c b/test/battle/move_effect/doodle.c index bf7e208646..ba7729a895 100644 --- a/test/battle/move_effect/doodle.c +++ b/test/battle/move_effect/doodle.c @@ -35,8 +35,8 @@ DOUBLE_BATTLE_TEST("Doodle can't copy a banned ability") } WHEN { TURN { MOVE(playerLeft, MOVE_DOODLE, target: opponentLeft); } } SCENE { - ANIMATION(ANIM_TYPE_MOVE, MOVE_DOODLE, playerLeft); NONE_OF { + ANIMATION(ANIM_TYPE_MOVE, MOVE_DOODLE, playerLeft); MESSAGE("Wynaut copied Foe Great Tusk's Protosynthesis!"); MESSAGE("Wynaut copied Foe Great Tusk's Protosynthesis!"); } @@ -56,7 +56,7 @@ DOUBLE_BATTLE_TEST("Doodle fails if user has a banned Ability") } WHEN { TURN { MOVE(playerLeft, MOVE_DOODLE, target: opponentLeft); } } SCENE { - ANIMATION(ANIM_TYPE_MOVE, MOVE_DOODLE, playerLeft); + NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_DOODLE, playerLeft); MESSAGE("But it failed!"); } THEN { EXPECT(playerLeft->ability == ABILITY_GULP_MISSILE); @@ -74,10 +74,44 @@ DOUBLE_BATTLE_TEST("Doodle fails if partner has a banned Ability") } WHEN { TURN { MOVE(playerLeft, MOVE_DOODLE, target: opponentLeft); } } SCENE { - ANIMATION(ANIM_TYPE_MOVE, MOVE_DOODLE, playerLeft); + NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_DOODLE, playerLeft); MESSAGE("But it failed!"); } THEN { EXPECT(playerLeft->ability == ABILITY_SHADOW_TAG); EXPECT(playerRight->ability == ABILITY_GULP_MISSILE); } } + +DOUBLE_BATTLE_TEST("Doodle fails if ally's ability can't be suppressed") +{ + u32 species, ability; + + PARAMETRIZE { species = SPECIES_ARCEUS; ability = ABILITY_MULTITYPE; } + PARAMETRIZE { species = SPECIES_DARMANITAN; ability = ABILITY_ZEN_MODE; } + PARAMETRIZE { species = SPECIES_AEGISLASH; ability = ABILITY_STANCE_CHANGE; } + PARAMETRIZE { species = SPECIES_MINIOR; ability = ABILITY_SHIELDS_DOWN; } + PARAMETRIZE { species = SPECIES_WISHIWASHI; ability = ABILITY_SCHOOLING; } + PARAMETRIZE { species = SPECIES_MIMIKYU; ability = ABILITY_DISGUISE; } + PARAMETRIZE { species = SPECIES_GRENINJA_BATTLE_BOND; ability = ABILITY_BATTLE_BOND; } + PARAMETRIZE { species = SPECIES_ZYGARDE; ability = ABILITY_POWER_CONSTRUCT; } + PARAMETRIZE { species = SPECIES_KOMALA; ability = ABILITY_COMATOSE; } + PARAMETRIZE { species = SPECIES_SILVALLY; ability = ABILITY_RKS_SYSTEM; } + PARAMETRIZE { species = SPECIES_CRAMORANT; ability = ABILITY_GULP_MISSILE; } + PARAMETRIZE { species = SPECIES_EISCUE; ability = ABILITY_ICE_FACE; } + PARAMETRIZE { species = SPECIES_CALYREX_ICE; ability = ABILITY_AS_ONE_ICE_RIDER; } + PARAMETRIZE { species = SPECIES_CALYREX_SHADOW; ability = ABILITY_AS_ONE_SHADOW_RIDER; } + PARAMETRIZE { species = SPECIES_PALAFIN_ZERO; ability = ABILITY_ZERO_TO_HERO; } + PARAMETRIZE { species = SPECIES_TATSUGIRI; ability = ABILITY_COMMANDER; } + + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_TELEPATHY); } + PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_TELEPATHY); } + OPPONENT(SPECIES_WOBBUFFET) { Ability(ABILITY_TELEPATHY); } + OPPONENT(species) { Ability(ability); } + } WHEN { + TURN { MOVE(opponentLeft, MOVE_DOODLE, target: playerLeft); } + } SCENE { + NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_DOODLE, opponentLeft); + MESSAGE("But it failed!"); + } +} diff --git a/test/battle/move_effect/role_play.c b/test/battle/move_effect/role_play.c index 46452ec3ff..ab0d801ee9 100644 --- a/test/battle/move_effect/role_play.c +++ b/test/battle/move_effect/role_play.c @@ -1,25 +1,65 @@ #include "global.h" #include "test/battle.h" -// Technically also covers Skill Swap and Doodle since both moves use the same command as Role Play ASSUMPTIONS { ASSUME(gMovesInfo[MOVE_ROLE_PLAY].effect == EFFECT_ROLE_PLAY); } -SINGLE_BATTLE_TEST("Role Play fails if target has a banned ability") +SINGLE_BATTLE_TEST("Role Play copies target's ability") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_TELEPATHY); } + OPPONENT(SPECIES_CHARMANDER) { Ability(ABILITY_BLAZE); } + }WHEN { + TURN { MOVE(player, MOVE_ROLE_PLAY); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_ROLE_PLAY, player); + ABILITY_POPUP(player, ABILITY_TELEPATHY); + } THEN { + EXPECT_EQ(player->ability, ABILITY_BLAZE); + EXPECT_EQ(opponent->ability, ABILITY_BLAZE); + } +} + +DOUBLE_BATTLE_TEST("Role Play copies target's current ability even if it changed during that turn") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_TELEPATHY); } + PLAYER(SPECIES_CHARMANDER) { Ability(ABILITY_BLAZE); } + OPPONENT(SPECIES_BULBASAUR) { Ability(ABILITY_OVERGROW); } + OPPONENT(SPECIES_SQUIRTLE) { Ability(ABILITY_TORRENT); } + } WHEN { + TURN { MOVE(playerLeft, MOVE_ROLE_PLAY, target: opponentLeft); MOVE(opponentRight, MOVE_ROLE_PLAY, target: playerLeft); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_ROLE_PLAY, playerLeft); + ABILITY_POPUP(playerLeft, ABILITY_TELEPATHY); + if (MOVE_ROLE_PLAY == MOVE_DOODLE) + ABILITY_POPUP(playerRight, ABILITY_BLAZE); + ANIMATION(ANIM_TYPE_MOVE, MOVE_ROLE_PLAY, opponentRight); + ABILITY_POPUP(opponentRight, ABILITY_TORRENT); + NOT ABILITY_POPUP(opponentLeft, ABILITY_OVERGROW); // Already has ability (Doodle) + } THEN { + EXPECT_EQ(playerLeft->ability, ABILITY_OVERGROW); + if (MOVE_ROLE_PLAY == MOVE_DOODLE) + EXPECT_EQ(playerRight->ability, ABILITY_OVERGROW); + EXPECT_EQ(opponentLeft->ability, ABILITY_OVERGROW); + EXPECT_EQ(opponentRight->ability, ABILITY_OVERGROW); + } +} + +SINGLE_BATTLE_TEST("Role Play and Doodle fail if target's ability can't be copied'") { u32 species, ability; PARAMETRIZE { species = SPECIES_SHEDINJA; ability = ABILITY_WONDER_GUARD; } PARAMETRIZE { species = SPECIES_CASTFORM; ability = ABILITY_FORECAST; } - PARAMETRIZE { species = SPECIES_CHERRIM; ability = ABILITY_FLOWER_GIFT; } PARAMETRIZE { species = SPECIES_ARCEUS; ability = ABILITY_MULTITYPE; } + PARAMETRIZE { species = SPECIES_CHERRIM; ability = ABILITY_FLOWER_GIFT; } PARAMETRIZE { species = SPECIES_ZORUA; ability = ABILITY_ILLUSION; } PARAMETRIZE { species = SPECIES_DARMANITAN; ability = ABILITY_ZEN_MODE; } - PARAMETRIZE { species = SPECIES_DITTO; ability = ABILITY_IMPOSTER; } PARAMETRIZE { species = SPECIES_AEGISLASH; ability = ABILITY_STANCE_CHANGE; } - PARAMETRIZE { species = SPECIES_MUK_ALOLAN; ability = ABILITY_POWER_OF_ALCHEMY; } + PARAMETRIZE { species = SPECIES_MUK_ALOLA; ability = ABILITY_POWER_OF_ALCHEMY; } PARAMETRIZE { species = SPECIES_PASSIMIAN; ability = ABILITY_RECEIVER; } PARAMETRIZE { species = SPECIES_WISHIWASHI; ability = ABILITY_SCHOOLING; } PARAMETRIZE { species = SPECIES_KOMALA; ability = ABILITY_COMATOSE; } @@ -38,29 +78,34 @@ SINGLE_BATTLE_TEST("Role Play fails if target has a banned ability") PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_TELEPATHY); } OPPONENT(species) { Ability(ability); } } WHEN { - TURN { MOVE(player,MOVE_ROLE_PLAY); } + TURN { MOVE(player, MOVE_ROLE_PLAY); } + TURN { MOVE(player, MOVE_DOODLE); } } SCENE { NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_ROLE_PLAY, player); MESSAGE("But it failed!"); + NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_DOODLE, player); + MESSAGE("But it failed!"); } } -SINGLE_BATTLE_TEST("Role Play fails if user has a banned ability") +SINGLE_BATTLE_TEST("Role Play fails if user's ability can't be suppressed") { u32 species, ability; PARAMETRIZE { species = SPECIES_ARCEUS; ability = ABILITY_MULTITYPE; } PARAMETRIZE { species = SPECIES_DARMANITAN; ability = ABILITY_ZEN_MODE; } PARAMETRIZE { species = SPECIES_AEGISLASH; ability = ABILITY_STANCE_CHANGE; } - PARAMETRIZE { species = SPECIES_WISHIWASHI; ability = ABILITY_SCHOOLING; } - PARAMETRIZE { species = SPECIES_KOMALA; ability = ABILITY_COMATOSE; } PARAMETRIZE { species = SPECIES_MINIOR; ability = ABILITY_SHIELDS_DOWN; } + PARAMETRIZE { species = SPECIES_WISHIWASHI; ability = ABILITY_SCHOOLING; } PARAMETRIZE { species = SPECIES_MIMIKYU; ability = ABILITY_DISGUISE; } - PARAMETRIZE { species = SPECIES_SILVALLY; ability = ABILITY_RKS_SYSTEM; } - PARAMETRIZE { species = SPECIES_ZYGARDE; ability = ABILITY_POWER_CONSTRUCT; } PARAMETRIZE { species = SPECIES_GRENINJA_BATTLE_BOND; ability = ABILITY_BATTLE_BOND; } - PARAMETRIZE { species = SPECIES_EISCUE; ability = ABILITY_ICE_FACE; } + PARAMETRIZE { species = SPECIES_ZYGARDE; ability = ABILITY_POWER_CONSTRUCT; } + PARAMETRIZE { species = SPECIES_KOMALA; ability = ABILITY_COMATOSE; } + PARAMETRIZE { species = SPECIES_SILVALLY; ability = ABILITY_RKS_SYSTEM; } PARAMETRIZE { species = SPECIES_CRAMORANT; ability = ABILITY_GULP_MISSILE; } + PARAMETRIZE { species = SPECIES_EISCUE; ability = ABILITY_ICE_FACE; } + PARAMETRIZE { species = SPECIES_CALYREX_ICE; ability = ABILITY_AS_ONE_ICE_RIDER; } + PARAMETRIZE { species = SPECIES_CALYREX_SHADOW; ability = ABILITY_AS_ONE_SHADOW_RIDER; } PARAMETRIZE { species = SPECIES_PALAFIN_ZERO; ability = ABILITY_ZERO_TO_HERO; } PARAMETRIZE { species = SPECIES_TATSUGIRI; ability = ABILITY_COMMANDER; } @@ -68,9 +113,12 @@ SINGLE_BATTLE_TEST("Role Play fails if user has a banned ability") PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_TELEPATHY); } OPPONENT(species) { Ability(ability); } } WHEN { - TURN { MOVE(opponent,MOVE_ROLE_PLAY); } + TURN { MOVE(opponent, MOVE_ROLE_PLAY); } + TURN { MOVE(opponent, MOVE_DOODLE); } } SCENE { NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_ROLE_PLAY, opponent); MESSAGE("But it failed!"); + NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_DOODLE, opponent); + MESSAGE("But it failed!"); } } diff --git a/test/battle/move_effect/simple_beam.c b/test/battle/move_effect/simple_beam.c new file mode 100644 index 0000000000..e91bf0b8ce --- /dev/null +++ b/test/battle/move_effect/simple_beam.c @@ -0,0 +1,74 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(gMovesInfo[MOVE_SIMPLE_BEAM].effect == EFFECT_SIMPLE_BEAM); +} + +SINGLE_BATTLE_TEST("Simple Beam replaces target's ability with Simple") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_TELEPATHY); } + OPPONENT(SPECIES_CHARMANDER) { Ability(ABILITY_BLAZE); } + }WHEN { + TURN { MOVE(player, MOVE_SIMPLE_BEAM); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SIMPLE_BEAM, player); + ABILITY_POPUP(opponent, ABILITY_BLAZE); + } THEN { + EXPECT_EQ(opponent->ability, ABILITY_SIMPLE); + } +} + +DOUBLE_BATTLE_TEST("Simple Beam fails if the target already has Simple") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_TELEPATHY); } + PLAYER(SPECIES_CHARMANDER) { Ability(ABILITY_BLAZE); } + OPPONENT(SPECIES_BULBASAUR) { Ability(ABILITY_OVERGROW); } + OPPONENT(SPECIES_SQUIRTLE) { Ability(ABILITY_TORRENT); } + } WHEN { + TURN { MOVE(playerLeft, MOVE_SIMPLE_BEAM, target: opponentLeft); MOVE(playerRight, MOVE_SIMPLE_BEAM, target: opponentLeft); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SIMPLE_BEAM, playerLeft); + ABILITY_POPUP(opponentLeft, ABILITY_OVERGROW); + NONE_OF { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SIMPLE_BEAM, playerRight); + ABILITY_POPUP(opponentLeft, ABILITY_SIMPLE); + } + } THEN { + EXPECT_EQ(opponentLeft->ability, ABILITY_SIMPLE); + } +} + +SINGLE_BATTLE_TEST("Simple Beam fails if target has an ability that can't be overwritten") +{ + u32 species, ability; + + PARAMETRIZE { species = SPECIES_ARCEUS; ability = ABILITY_MULTITYPE; } + PARAMETRIZE { species = SPECIES_AEGISLASH; ability = ABILITY_STANCE_CHANGE; } + PARAMETRIZE { species = SPECIES_MINIOR; ability = ABILITY_SHIELDS_DOWN; } + PARAMETRIZE { species = SPECIES_WISHIWASHI; ability = ABILITY_SCHOOLING; } + PARAMETRIZE { species = SPECIES_MIMIKYU; ability = ABILITY_DISGUISE; } + PARAMETRIZE { species = SPECIES_GRENINJA_BATTLE_BOND; ability = ABILITY_BATTLE_BOND; } + PARAMETRIZE { species = SPECIES_ZYGARDE; ability = ABILITY_POWER_CONSTRUCT; } + PARAMETRIZE { species = SPECIES_KOMALA; ability = ABILITY_COMATOSE; } + PARAMETRIZE { species = SPECIES_SILVALLY; ability = ABILITY_RKS_SYSTEM; } + PARAMETRIZE { species = SPECIES_CRAMORANT; ability = ABILITY_GULP_MISSILE; } + PARAMETRIZE { species = SPECIES_EISCUE; ability = ABILITY_ICE_FACE; } + PARAMETRIZE { species = SPECIES_CALYREX_ICE; ability = ABILITY_AS_ONE_ICE_RIDER; } + PARAMETRIZE { species = SPECIES_CALYREX_SHADOW; ability = ABILITY_AS_ONE_SHADOW_RIDER; } + PARAMETRIZE { species = SPECIES_PALAFIN_ZERO; ability = ABILITY_ZERO_TO_HERO; } + PARAMETRIZE { species = SPECIES_TATSUGIRI; ability = ABILITY_COMMANDER; } + + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_TELEPATHY); } + OPPONENT(species) { Ability(ability); } + } WHEN { + TURN { MOVE(player, MOVE_SIMPLE_BEAM); } + } SCENE { + NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_SIMPLE_BEAM, player); + MESSAGE("But it failed!"); + } +} diff --git a/test/battle/move_effect/skill_swap.c b/test/battle/move_effect/skill_swap.c new file mode 100644 index 0000000000..5f2196fe7e --- /dev/null +++ b/test/battle/move_effect/skill_swap.c @@ -0,0 +1,111 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(gMovesInfo[MOVE_SKILL_SWAP].effect == EFFECT_SKILL_SWAP); +} + +SINGLE_BATTLE_TEST("Skill Swap swaps user and target's abilities") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_TELEPATHY); } + OPPONENT(SPECIES_CHARMANDER) { Ability(ABILITY_BLAZE); } + }WHEN { + TURN { MOVE(player, MOVE_SKILL_SWAP); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SKILL_SWAP, player); + ABILITY_POPUP(player, ABILITY_TELEPATHY); + ABILITY_POPUP(opponent, ABILITY_BLAZE); + } THEN { + EXPECT_EQ(player->ability, ABILITY_BLAZE); + EXPECT_EQ(opponent->ability, ABILITY_TELEPATHY); + } +} + +DOUBLE_BATTLE_TEST("Skill Swap only swaps user's ability with target's ability") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_TELEPATHY); } + PLAYER(SPECIES_CHARMANDER) { Ability(ABILITY_BLAZE); } + OPPONENT(SPECIES_BULBASAUR) { Ability(ABILITY_OVERGROW); } + OPPONENT(SPECIES_SQUIRTLE) { Ability(ABILITY_TORRENT); } + } WHEN { + TURN { MOVE(playerLeft, MOVE_SKILL_SWAP, target: opponentLeft); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SKILL_SWAP, playerLeft); + ABILITY_POPUP(playerLeft, ABILITY_TELEPATHY); + ABILITY_POPUP(opponentLeft, ABILITY_OVERGROW); + } THEN { + EXPECT_EQ(playerLeft->ability, ABILITY_OVERGROW); + EXPECT_EQ(playerRight->ability, ABILITY_BLAZE); + EXPECT_EQ(opponentLeft->ability, ABILITY_TELEPATHY); + EXPECT_EQ(opponentRight->ability, ABILITY_TORRENT); + } +} + +DOUBLE_BATTLE_TEST("Skill Swap doesn't display ability popups when swapping with an ally") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_TELEPATHY); } + PLAYER(SPECIES_CHARMANDER) { Ability(ABILITY_BLAZE); } + OPPONENT(SPECIES_BULBASAUR) { Ability(ABILITY_OVERGROW); } + OPPONENT(SPECIES_SQUIRTLE) { Ability(ABILITY_TORRENT); } + } WHEN { + TURN { MOVE(playerLeft, MOVE_SKILL_SWAP, target: playerRight); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SKILL_SWAP, playerLeft); + NONE_OF { + ABILITY_POPUP(playerLeft, ABILITY_TELEPATHY); + ABILITY_POPUP(playerRight, ABILITY_BLAZE); + } + } THEN { + EXPECT_EQ(playerLeft->ability, ABILITY_BLAZE); + EXPECT_EQ(playerRight->ability, ABILITY_TELEPATHY); + } +} + +SINGLE_BATTLE_TEST("Skill Swap fails if user or target has an ability that can't be swapped") +{ + u32 species, ability; + + PARAMETRIZE { species = SPECIES_SHEDINJA; ability = ABILITY_WONDER_GUARD; } + PARAMETRIZE { species = SPECIES_ARCEUS; ability = ABILITY_MULTITYPE; } + PARAMETRIZE { species = SPECIES_ZORUA; ability = ABILITY_ILLUSION; } + PARAMETRIZE { species = SPECIES_DARMANITAN; ability = ABILITY_ZEN_MODE; } + PARAMETRIZE { species = SPECIES_AEGISLASH; ability = ABILITY_STANCE_CHANGE; } + PARAMETRIZE { species = SPECIES_MINIOR; ability = ABILITY_SHIELDS_DOWN; } + PARAMETRIZE { species = SPECIES_WISHIWASHI; ability = ABILITY_SCHOOLING; } + PARAMETRIZE { species = SPECIES_MIMIKYU; ability = ABILITY_DISGUISE; } + PARAMETRIZE { species = SPECIES_GRENINJA_BATTLE_BOND; ability = ABILITY_BATTLE_BOND; } + PARAMETRIZE { species = SPECIES_ZYGARDE; ability = ABILITY_POWER_CONSTRUCT; } + PARAMETRIZE { species = SPECIES_KOMALA; ability = ABILITY_COMATOSE; } + PARAMETRIZE { species = SPECIES_SILVALLY; ability = ABILITY_RKS_SYSTEM; } + PARAMETRIZE { species = SPECIES_EISCUE; ability = ABILITY_ICE_FACE; } + PARAMETRIZE { species = SPECIES_KOFFING; ability = ABILITY_NEUTRALIZING_GAS; } + PARAMETRIZE { species = SPECIES_MORPEKO; ability = ABILITY_HUNGER_SWITCH; } + PARAMETRIZE { species = SPECIES_CALYREX_ICE; ability = ABILITY_AS_ONE_ICE_RIDER; } + PARAMETRIZE { species = SPECIES_CALYREX_SHADOW; ability = ABILITY_AS_ONE_SHADOW_RIDER; } + PARAMETRIZE { species = SPECIES_PALAFIN_ZERO; ability = ABILITY_ZERO_TO_HERO; } + PARAMETRIZE { species = SPECIES_TATSUGIRI; ability = ABILITY_COMMANDER; } + PARAMETRIZE { species = SPECIES_GREAT_TUSK; ability = ABILITY_PROTOSYNTHESIS; } + PARAMETRIZE { species = SPECIES_IRON_TREADS; ability = ABILITY_QUARK_DRIVE; } + PARAMETRIZE { species = SPECIES_OGERPON_TEAL_MASK_TERA; ability = ABILITY_EMBODY_ASPECT_TEAL_MASK; } + PARAMETRIZE { species = SPECIES_OGERPON_HEARTHFLAME_MASK_TERA; ability = ABILITY_EMBODY_ASPECT_HEARTHFLAME_MASK; } + PARAMETRIZE { species = SPECIES_OGERPON_WELLSPRING_MASK_TERA; ability = ABILITY_EMBODY_ASPECT_WELLSPRING_MASK; } + PARAMETRIZE { species = SPECIES_OGERPON_CORNERSTONE_MASK_TERA; ability = ABILITY_EMBODY_ASPECT_CORNERSTONE_MASK; } + PARAMETRIZE { species = SPECIES_TERAPAGOS_TERASTAL; ability = ABILITY_TERA_SHELL; } + PARAMETRIZE { species = SPECIES_TERAPAGOS_STELLAR; ability = ABILITY_TERAFORM_ZERO; } + + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_TELEPATHY); } + OPPONENT(species) { Ability(ability); } + } WHEN { + TURN { MOVE(player, MOVE_SKILL_SWAP); MOVE(opponent, MOVE_SKILL_SWAP); } + } SCENE { + NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_SKILL_SWAP, player); + MESSAGE("But it failed!"); + NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_SKILL_SWAP, opponent); + MESSAGE("But it failed!"); + } +} diff --git a/test/battle/move_effect/worry_seed.c b/test/battle/move_effect/worry_seed.c new file mode 100644 index 0000000000..3e74c883e7 --- /dev/null +++ b/test/battle/move_effect/worry_seed.c @@ -0,0 +1,74 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(gMovesInfo[MOVE_WORRY_SEED].effect == EFFECT_WORRY_SEED); +} + +SINGLE_BATTLE_TEST("Worry Seed replaces target's ability with Insomnia") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_TELEPATHY); } + OPPONENT(SPECIES_CHARMANDER) { Ability(ABILITY_BLAZE); } + }WHEN { + TURN { MOVE(player, MOVE_WORRY_SEED); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_WORRY_SEED, player); + ABILITY_POPUP(opponent, ABILITY_BLAZE); + } THEN { + EXPECT_EQ(opponent->ability, ABILITY_INSOMNIA); + } +} + +DOUBLE_BATTLE_TEST("Worry Seed fails if the target already has Insomnia") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_TELEPATHY); } + PLAYER(SPECIES_CHARMANDER) { Ability(ABILITY_BLAZE); } + OPPONENT(SPECIES_BULBASAUR) { Ability(ABILITY_OVERGROW); } + OPPONENT(SPECIES_SQUIRTLE) { Ability(ABILITY_TORRENT); } + } WHEN { + TURN { MOVE(playerLeft, MOVE_WORRY_SEED, target: opponentLeft); MOVE(playerRight, MOVE_WORRY_SEED, target: opponentLeft); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_WORRY_SEED, playerLeft); + ABILITY_POPUP(opponentLeft, ABILITY_OVERGROW); + NONE_OF { + ANIMATION(ANIM_TYPE_MOVE, MOVE_WORRY_SEED, playerRight); + ABILITY_POPUP(opponentLeft, ABILITY_INSOMNIA); + } + } THEN { + EXPECT_EQ(opponentLeft->ability, ABILITY_INSOMNIA); + } +} + +SINGLE_BATTLE_TEST("Worry Seed fails if target has an ability that can't be overwritten") +{ + u32 species, ability; + + PARAMETRIZE { species = SPECIES_ARCEUS; ability = ABILITY_MULTITYPE; } + PARAMETRIZE { species = SPECIES_AEGISLASH; ability = ABILITY_STANCE_CHANGE; } + PARAMETRIZE { species = SPECIES_MINIOR; ability = ABILITY_SHIELDS_DOWN; } + PARAMETRIZE { species = SPECIES_WISHIWASHI; ability = ABILITY_SCHOOLING; } + PARAMETRIZE { species = SPECIES_MIMIKYU; ability = ABILITY_DISGUISE; } + PARAMETRIZE { species = SPECIES_GRENINJA_BATTLE_BOND; ability = ABILITY_BATTLE_BOND; } + PARAMETRIZE { species = SPECIES_ZYGARDE; ability = ABILITY_POWER_CONSTRUCT; } + PARAMETRIZE { species = SPECIES_KOMALA; ability = ABILITY_COMATOSE; } + PARAMETRIZE { species = SPECIES_SILVALLY; ability = ABILITY_RKS_SYSTEM; } + PARAMETRIZE { species = SPECIES_CRAMORANT; ability = ABILITY_GULP_MISSILE; } + PARAMETRIZE { species = SPECIES_EISCUE; ability = ABILITY_ICE_FACE; } + PARAMETRIZE { species = SPECIES_CALYREX_ICE; ability = ABILITY_AS_ONE_ICE_RIDER; } + PARAMETRIZE { species = SPECIES_CALYREX_SHADOW; ability = ABILITY_AS_ONE_SHADOW_RIDER; } + PARAMETRIZE { species = SPECIES_PALAFIN_ZERO; ability = ABILITY_ZERO_TO_HERO; } + PARAMETRIZE { species = SPECIES_TATSUGIRI; ability = ABILITY_COMMANDER; } + + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_TELEPATHY); } + OPPONENT(species) { Ability(ability); } + } WHEN { + TURN { MOVE(player, MOVE_WORRY_SEED); } + } SCENE { + NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_WORRY_SEED, player); + MESSAGE("But it failed!"); + } +}