From ab2774f8c7976bdc915319508e65e392fdcbc447 Mon Sep 17 00:00:00 2001 From: Alex <93446519+AlexOn1ine@users.noreply.github.com> Date: Sat, 3 Feb 2024 16:00:41 +0100 Subject: [PATCH] Adds Dragon Cheer (#4122) * Adds Dragon Cheer * fix assumptions --------- Co-authored-by: ghoulslash <41651341+ghoulslash@users.noreply.github.com> --- data/battle_anim_scripts.s | 2 +- data/battle_scripts_1.s | 4 +- data/battle_scripts_2.s | 2 +- include/constants/battle.h | 9 +-- include/constants/battle_move_effects.h | 1 + src/battle_ai_main.c | 10 ++- src/battle_ai_switch_items.c | 2 +- src/battle_main.c | 2 +- src/battle_message.c | 2 +- src/battle_script_commands.c | 19 ++++-- src/battle_util.c | 6 +- src/battle_z_move.c | 2 +- src/data/battle_move_effects.h | 7 ++ src/data/moves_info.h | 3 +- src/item_use.c | 2 +- test/battle/crit_chance.c | 91 ++++++++++++++++++++++++- 16 files changed, 138 insertions(+), 26 deletions(-) diff --git a/data/battle_anim_scripts.s b/data/battle_anim_scripts.s index 6a9fce1b89..0f79ab4e1a 100644 --- a/data/battle_anim_scripts.s +++ b/data/battle_anim_scripts.s @@ -17159,7 +17159,7 @@ Move_RAGING_BULL:: restorebg waitbgfadein end - + @ Credits to Z-nogyroP. Simple anim that combines Force Palm + Fake Out Move_UPPER_HAND:: loadspritegfx ANIM_TAG_SHADOW_BALL diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 685378df8f..c814b85510 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -3579,7 +3579,7 @@ BattleScript_EffectFocusEnergy:: attackcanceler attackstring ppreduce - jumpifstatus2 BS_ATTACKER, STATUS2_FOCUS_ENERGY, BattleScript_ButItFailed + jumpifstatus2 BS_ATTACKER, STATUS2_FOCUS_ENERGY_ANY, BattleScript_ButItFailed setfocusenergy attackanimation waitanimation @@ -9941,10 +9941,8 @@ BattleScript_RaiseCritAlliesLoop: setstatchanger STAT_ATK, 0, FALSE @ for animation setgraphicalstatchangevalues playanimation BS_TARGET, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1 - swapattackerwithtarget printstring STRINGID_PKMNGETTINGPUMPED waitmessage B_WAIT_TIME_LONG - swapattackerwithtarget BattleScript_RaiseCritAlliesIncrement: setbyte sSTAT_ANIM_PLAYED, FALSE jumpifbytenotequal gBattlerTarget, gBattlerAttacker, BattleScript_RaiseCritAlliesEnd diff --git a/data/battle_scripts_2.s b/data/battle_scripts_2.s index 78e077fbd5..d760e00acd 100644 --- a/data/battle_scripts_2.s +++ b/data/battle_scripts_2.s @@ -114,7 +114,7 @@ BattleScript_ItemSetMist:: BattleScript_ItemSetFocusEnergy:: call BattleScript_UseItemMessage - jumpifstatus2 BS_ATTACKER, STATUS2_FOCUS_ENERGY, BattleScript_ButItFailed + jumpifstatus2 BS_ATTACKER, STATUS2_FOCUS_ENERGY_ANY, BattleScript_ButItFailed setfocusenergy playmoveanimation BS_ATTACKER, MOVE_FOCUS_ENERGY waitanimation diff --git a/include/constants/battle.h b/include/constants/battle.h index ddaa79cbc9..a353fbb357 100644 --- a/include/constants/battle.h +++ b/include/constants/battle.h @@ -129,7 +129,7 @@ #define STATUS2_FLINCHED (1 << 3) #define STATUS2_UPROAR (1 << 4 | 1 << 5 | 1 << 6) #define STATUS2_UPROAR_TURN(num) ((num) << 4) -#define STATUS2_UNUSED (1 << 7) +#define STATUS2_TORMENT (1 << 7) #define STATUS2_BIDE (1 << 8 | 1 << 9) #define STATUS2_BIDE_TURN(num) (((num) << 8) & STATUS2_BIDE) #define STATUS2_LOCK_CONFUSE (1 << 10 | 1 << 11) // e.g. Thrash @@ -139,7 +139,7 @@ #define STATUS2_POWDER (1 << 14) #define STATUS2_INFATUATION (1 << 16 | 1 << 17 | 1 << 18 | 1 << 19) // 4 bits, one for every battler #define STATUS2_INFATUATED_WITH(battler) (gBitTable[battler] << 16) -#define STATUS2_FOCUS_ENERGY (1 << 20) +#define STATUS2_DEFENSE_CURL (1 << 20) #define STATUS2_TRANSFORMED (1 << 21) #define STATUS2_RECHARGE (1 << 22) #define STATUS2_RAGE (1 << 23) @@ -149,8 +149,9 @@ #define STATUS2_NIGHTMARE (1 << 27) #define STATUS2_CURSED (1 << 28) #define STATUS2_FORESIGHT (1 << 29) -#define STATUS2_DEFENSE_CURL (1 << 30) -#define STATUS2_TORMENT (1 << 31) +#define STATUS2_DRAGON_CHEER (1 << 30) +#define STATUS2_FOCUS_ENERGY (1 << 31) +#define STATUS2_FOCUS_ENERGY_ANY (STATUS2_DRAGON_CHEER | STATUS2_FOCUS_ENERGY) #define STATUS3_LEECHSEED_BATTLER (1 << 0 | 1 << 1) // The battler to receive HP from Leech Seed #define STATUS3_LEECHSEED (1 << 2) diff --git a/include/constants/battle_move_effects.h b/include/constants/battle_move_effects.h index 4b03a2eef1..004d675701 100644 --- a/include/constants/battle_move_effects.h +++ b/include/constants/battle_move_effects.h @@ -352,6 +352,7 @@ enum { EFFECT_RAIN_ALWAYS_HIT, // Unlike EFFECT_THUNDER, it doesn't get its accuracy reduced under sun. EFFECT_SHED_TAIL, EFFECT_UPPER_HAND, + EFFECT_DRAGON_CHEER, NUM_BATTLE_MOVE_EFFECTS, }; diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c index a6d320b129..4945a7d873 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -1477,7 +1477,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) ADJUST_SCORE(-10); break; case EFFECT_FOCUS_ENERGY: - if (gBattleMons[battlerAtk].status2 & STATUS2_FOCUS_ENERGY) + if (gBattleMons[battlerAtk].status2 & STATUS2_FOCUS_ENERGY_ANY) ADJUST_SCORE(-10); break; case EFFECT_CONFUSE: @@ -1762,6 +1762,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) break; case EFFECT_FOLLOW_ME: case EFFECT_HELPING_HAND: + case EFFECT_DRAGON_CHEER: if (!isDoubleBattle || !IsBattlerAlive(BATTLE_PARTNER(battlerAtk)) || PartnerHasSameMoveEffectWithoutTarget(BATTLE_PARTNER(battlerAtk), move, aiData->partnerMove) @@ -2781,6 +2782,13 @@ static s32 AI_DoubleBattle(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) RETURN_SCORE_PLUS(DECENT_EFFECT); // partner has earthquake or magnitude -> good idea to use magnet rise } break; + case EFFECT_DRAGON_CHEER: + if (gBattleMons[battlerAtkPartner].status2 & STATUS2_FOCUS_ENERGY_ANY || !HasDamagingMove(battlerAtkPartner)) + ADJUST_SCORE(-5); + else if (atkPartnerHoldEffect == HOLD_EFFECT_SCOPE_LENS + || IS_BATTLER_OF_TYPE(battlerAtkPartner, TYPE_DRAGON) + || gMovesInfo[aiData->partnerMove].criticalHitStage > 0) + ADJUST_SCORE(GOOD_EFFECT); } // our effect relative to partner // consider global move effects diff --git a/src/battle_ai_switch_items.c b/src/battle_ai_switch_items.c index 657ebb9c73..231ab442a5 100644 --- a/src/battle_ai_switch_items.c +++ b/src/battle_ai_switch_items.c @@ -2088,7 +2088,7 @@ static bool32 ShouldUseItem(u32 battler) break; case EFFECT_ITEM_SET_FOCUS_ENERGY: if (!gDisableStructs[battler].isFirstTurn - || gBattleMons[battler].status2 & STATUS2_FOCUS_ENERGY + || gBattleMons[battler].status2 & STATUS2_FOCUS_ENERGY_ANY || AI_OpponentCanFaintAiWithMod(battler, 0)) break; shouldUse = TRUE; diff --git a/src/battle_main.c b/src/battle_main.c index bb10546d9c..e4c5c7a784 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -3106,7 +3106,7 @@ void SwitchInClearSetData(u32 battler) } if (gMovesInfo[gCurrentMove].effect == EFFECT_BATON_PASS) { - gBattleMons[battler].status2 &= (STATUS2_CONFUSION | STATUS2_FOCUS_ENERGY | STATUS2_SUBSTITUTE | STATUS2_ESCAPE_PREVENTION | STATUS2_CURSED); + gBattleMons[battler].status2 &= (STATUS2_CONFUSION | STATUS2_FOCUS_ENERGY_ANY | STATUS2_SUBSTITUTE | STATUS2_ESCAPE_PREVENTION | STATUS2_CURSED); gStatuses3[battler] &= (STATUS3_LEECHSEED_BATTLER | STATUS3_LEECHSEED | STATUS3_ALWAYS_HITS | STATUS3_PERISH_SONG | STATUS3_ROOTED | STATUS3_GASTRO_ACID | STATUS3_EMBARGO | STATUS3_TELEKINESIS | STATUS3_MAGNET_RISE | STATUS3_HEAL_BLOCK | STATUS3_AQUA_RING | STATUS3_POWER_TRICK); diff --git a/src/battle_message.c b/src/battle_message.c index 28318b3850..258b103af7 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -166,7 +166,7 @@ static const u8 sText_PkmnFreedFrom[] = _("{B_ATK_NAME_WITH_PREFIX} was freed\nf static const u8 sText_PkmnCrashed[] = _("{B_ATK_NAME_WITH_PREFIX} kept going\nand crashed!"); const u8 gText_PkmnShroudedInMist[] = _("{B_ATK_PREFIX2} became\nshrouded in MIST!"); static const u8 sText_PkmnProtectedByMist[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} is protected\nby MIST!"); -const u8 gText_PkmnGettingPumped[] = _("{B_ATK_NAME_WITH_PREFIX} is getting\npumped!"); +const u8 gText_PkmnGettingPumped[] = _("{B_DEF_NAME_WITH_PREFIX} is getting\npumped!"); static const u8 sText_PkmnHitWithRecoil[] = _("{B_ATK_NAME_WITH_PREFIX} is hit\nwith recoil!"); static const u8 sText_PkmnProtectedItself2[] = _("{B_ATK_NAME_WITH_PREFIX} protected\nitself!"); static const u8 sText_PkmnBuffetedBySandstorm[] = _("{B_ATK_NAME_WITH_PREFIX} is buffeted\nby the sandstorm!"); diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index ec9afc056c..5ea9d6563a 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -1906,6 +1906,7 @@ s32 CalcCritChanceStageArgs(u32 battlerAtk, u32 battlerDef, u32 move, bool32 rec else { critChance = 2 * ((gBattleMons[battlerAtk].status2 & STATUS2_FOCUS_ENERGY) != 0) + + 1 * ((gBattleMons[battlerAtk].status2 & STATUS2_DRAGON_CHEER) != 0) + gMovesInfo[gCurrentMove].criticalHitStage + (holdEffectAtk == HOLD_EFFECT_SCOPE_LENS) + 2 * (holdEffectAtk == HOLD_EFFECT_LUCKY_PUNCH && gBattleMons[battlerAtk].species == SPECIES_CHANSEY) @@ -12331,14 +12332,20 @@ static void Cmd_setfocusenergy(void) { CMD_ARGS(); - if (gBattleMons[gBattlerAttacker].status2 & STATUS2_FOCUS_ENERGY) + if ((gMovesInfo[gCurrentMove].effect == EFFECT_DRAGON_CHEER && (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE) || (gAbsentBattlerFlags & gBitTable[gBattlerTarget]))) + || gBattleMons[gBattlerTarget].status2 & STATUS2_FOCUS_ENERGY_ANY) { gMoveResultFlags |= MOVE_RESULT_FAILED; gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_FOCUS_ENERGY_FAILED; } + else if (gMovesInfo[gCurrentMove].effect == EFFECT_DRAGON_CHEER && !IS_BATTLER_OF_TYPE(gBattlerTarget, TYPE_DRAGON)) + { + gBattleMons[gBattlerTarget].status2 |= STATUS2_DRAGON_CHEER; + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_GETTING_PUMPED; + } else { - gBattleMons[gBattlerAttacker].status2 |= STATUS2_FOCUS_ENERGY; + gBattleMons[gBattlerTarget].status2 |= STATUS2_FOCUS_ENERGY; gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_GETTING_PUMPED; } gBattlescriptCurrInstr = cmd->nextInstr; @@ -16539,10 +16546,10 @@ void BS_TryUpperHand(void) { NATIVE_ARGS(const u8 *failInstr); - if (GetBattlerTurnOrderNum(gBattlerAttacker) > GetBattlerTurnOrderNum(gBattlerTarget) - || gChosenMoveByBattler[gBattlerTarget] == MOVE_NONE - || IS_MOVE_STATUS(gChosenMoveByBattler[gBattlerTarget]) - || GetChosenMovePriority(gBattlerTarget) < 1 || GetChosenMovePriority(gBattlerTarget) > 3) // Fails if priority is less than 1 or greater than 3, if target already moved, or if using a status + if (GetBattlerTurnOrderNum(gBattlerAttacker) > GetBattlerTurnOrderNum(gBattlerTarget) + || gChosenMoveByBattler[gBattlerTarget] == MOVE_NONE + || IS_MOVE_STATUS(gChosenMoveByBattler[gBattlerTarget]) + || GetChosenMovePriority(gBattlerTarget) < 1 || GetChosenMovePriority(gBattlerTarget) > 3) // Fails if priority is less than 1 or greater than 3, if target already moved, or if using a status gBattlescriptCurrInstr = cmd->failInstr; else gBattlescriptCurrInstr = cmd->nextInstr; diff --git a/src/battle_util.c b/src/battle_util.c index 4385dc3ecb..d2d5c50925 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -6859,7 +6859,7 @@ static u8 ItemEffectMoveEnd(u32 battler, u16 holdEffect) break; case HOLD_EFFECT_CRITICAL_UP: // lansat berry if (B_BERRIES_INSTANT >= GEN_4 - && !(gBattleMons[battler].status2 & STATUS2_FOCUS_ENERGY) + && !(gBattleMons[battler].status2 & STATUS2_FOCUS_ENERGY_ANY) && HasEnoughHpToEatBerry(battler, GetBattlerItemHoldEffectParam(battler, gLastUsedItem), gLastUsedItem)) { gBattleMons[battler].status2 |= STATUS2_FOCUS_ENERGY; @@ -6984,7 +6984,7 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn) break; case HOLD_EFFECT_CRITICAL_UP: if (B_BERRIES_INSTANT >= GEN_4 - && !(gBattleMons[battler].status2 & STATUS2_FOCUS_ENERGY) + && !(gBattleMons[battler].status2 & STATUS2_FOCUS_ENERGY_ANY) && HasEnoughHpToEatBerry(battler, GetBattlerItemHoldEffectParam(battler, gLastUsedItem), gLastUsedItem)) { gBattleMons[battler].status2 |= STATUS2_FOCUS_ENERGY; @@ -7295,7 +7295,7 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn) effect = StatRaiseBerry(battler, gLastUsedItem, STAT_SPDEF, TRUE); break; case HOLD_EFFECT_CRITICAL_UP: - if (!moveTurn && !(gBattleMons[battler].status2 & STATUS2_FOCUS_ENERGY) + if (!moveTurn && !(gBattleMons[battler].status2 & STATUS2_FOCUS_ENERGY_ANY) && HasEnoughHpToEatBerry(battler, GetBattlerItemHoldEffectParam(battler, gLastUsedItem), gLastUsedItem)) { gBattleMons[battler].status2 |= STATUS2_FOCUS_ENERGY; diff --git a/src/battle_z_move.c b/src/battle_z_move.c index 8cb379d892..b2377bffd4 100644 --- a/src/battle_z_move.c +++ b/src/battle_z_move.c @@ -606,7 +606,7 @@ void SetZEffect(void) } break; case Z_EFFECT_BOOST_CRITS: - if (!(gBattleMons[gBattlerAttacker].status2 & STATUS2_FOCUS_ENERGY)) + if (!(gBattleMons[gBattlerAttacker].status2 & STATUS2_FOCUS_ENERGY_ANY)) { gBattleMons[gBattlerAttacker].status2 |= STATUS2_FOCUS_ENERGY; gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_Z_BOOST_CRITS; diff --git a/src/data/battle_move_effects.h b/src/data/battle_move_effects.h index 97d91b2630..09234f6fdf 100644 --- a/src/data/battle_move_effects.h +++ b/src/data/battle_move_effects.h @@ -2229,4 +2229,11 @@ const struct BattleMoveEffect gBattleMoveEffects[NUM_BATTLE_MOVE_EFFECTS] = .battleScript = BattleScript_EffectUpperHand, .battleTvScore = 0, // TODO: Assign points }, + + [EFFECT_DRAGON_CHEER] = + { + .battleScript = BattleScript_EffectFocusEnergy, + .battleTvScore = 1, + .encourageEncore = TRUE, + }, }; diff --git a/src/data/moves_info.h b/src/data/moves_info.h index e46482e304..b68aecb319 100644 --- a/src/data/moves_info.h +++ b/src/data/moves_info.h @@ -2884,6 +2884,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .priority = 0, .category = DAMAGE_CATEGORY_STATUS, .zMove = { .effect = Z_EFFECT_ACC_UP_1 }, + .argument = STATUS2_FOCUS_ENERGY, .ignoresProtect = TRUE, .mirrorMoveBanned = TRUE, .snatchAffected = TRUE, @@ -19859,7 +19860,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .description = COMPOUND_STRING( "Increases allies' critical hit\n" "ratio, especially if Dragons."), - .effect = EFFECT_PLACEHOLDER, //EFFECT_DRAGON_CHEER + .effect = EFFECT_DRAGON_CHEER, .power = 0, .type = TYPE_DRAGON, .accuracy = 0, diff --git a/src/item_use.c b/src/item_use.c index f9badda639..e711f8cd22 100644 --- a/src/item_use.c +++ b/src/item_use.c @@ -1192,7 +1192,7 @@ bool32 CannotUseItemsInBattle(u16 itemId, struct Pokemon *mon) cannotUse = TRUE; break; case EFFECT_ITEM_SET_FOCUS_ENERGY: - if (gBattleMons[gBattlerInMenuId].status2 & STATUS2_FOCUS_ENERGY) + if (gBattleMons[gBattlerInMenuId].status2 & STATUS2_FOCUS_ENERGY_ANY) cannotUse = TRUE; break; case EFFECT_ITEM_SET_MIST: diff --git a/test/battle/crit_chance.c b/test/battle/crit_chance.c index 66ba62495f..4964767e8e 100644 --- a/test/battle/crit_chance.c +++ b/test/battle/crit_chance.c @@ -212,7 +212,6 @@ SINGLE_BATTLE_TEST("Signature items Leek and Lucky Punch increase the critical h u32 species; u32 item; - ASSUME(B_CRIT_CHANCE >= GEN_7); PASSES_RANDOMLY(1, 2, RNG_CRITICAL_HIT); PARAMETRIZE { species = SPECIES_FARFETCHD; item = ITEM_LEEK; } @@ -250,3 +249,93 @@ SINGLE_BATTLE_TEST("Dire Hit increases a battler's critical hit chance by 2 stag MESSAGE("A critical hit!"); } } + +SINGLE_BATTLE_TEST("Focus Energy increases critical hit ratio by two") +{ + PASSES_RANDOMLY(8, 8, RNG_CRITICAL_HIT); + GIVEN { + ASSUME(gMovesInfo[MOVE_SLASH].criticalHitStage == 1); + ASSUME(gMovesInfo[MOVE_FOCUS_ENERGY].effect == EFFECT_FOCUS_ENERGY); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_FOCUS_ENERGY); } + TURN { MOVE(player, MOVE_SLASH); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_FOCUS_ENERGY, player); + MESSAGE("Wobbuffet is getting pumped!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SLASH, player); + MESSAGE("A critical hit!"); + } +} + +SINGLE_BATTLE_TEST("Dragon Cheer fails in a single battle") +{ + GIVEN { + ASSUME(gMovesInfo[MOVE_DRAGON_CHEER].effect == EFFECT_DRAGON_CHEER); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_DRAGON_CHEER); } + } SCENE { + MESSAGE("But it failed!"); + } +} + +DOUBLE_BATTLE_TEST("Dragon Cheer increases critical hit ratio by one on non Dragon types") +{ + PASSES_RANDOMLY(1, 8, RNG_CRITICAL_HIT); + GIVEN { + ASSUME(gMovesInfo[MOVE_TACKLE].criticalHitStage == 0); + ASSUME(gMovesInfo[MOVE_DRAGON_CHEER].effect == EFFECT_DRAGON_CHEER); + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_WYNAUT); + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(playerLeft, MOVE_DRAGON_CHEER, target: playerRight); MOVE(playerRight, MOVE_TACKLE, target: opponentLeft); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_CHEER, playerLeft); + MESSAGE("Wynaut is getting pumped!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, playerRight); + MESSAGE("A critical hit!"); + } +} + +DOUBLE_BATTLE_TEST("Dragon Cheer increases critical hit ratio by two on Dragon types") +{ + PASSES_RANDOMLY(1, 2, RNG_CRITICAL_HIT); + GIVEN { + ASSUME(gMovesInfo[MOVE_TACKLE].criticalHitStage == 0); + ASSUME(gMovesInfo[MOVE_DRAGON_CHEER].effect == EFFECT_DRAGON_CHEER); + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_DRATINI); + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(playerLeft, MOVE_DRAGON_CHEER, target: playerRight); MOVE(playerRight, MOVE_TACKLE, target: opponentLeft); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_CHEER, playerLeft); + MESSAGE("Dratini is getting pumped!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, playerRight); + MESSAGE("A critical hit!"); + } +} + +DOUBLE_BATTLE_TEST("Dragon Cheer fails if critical hit stage was already increased by Focus Energy") +{ + GIVEN { + ASSUME(gMovesInfo[MOVE_SLASH].criticalHitStage == 1); + ASSUME(gMovesInfo[MOVE_FOCUS_ENERGY].effect == EFFECT_FOCUS_ENERGY); + ASSUME(gMovesInfo[MOVE_DRAGON_CHEER].effect == EFFECT_DRAGON_CHEER); + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(playerLeft, MOVE_FOCUS_ENERGY); MOVE(playerRight, MOVE_DRAGON_CHEER, target: playerLeft); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_FOCUS_ENERGY, playerLeft); + MESSAGE("But it failed!"); + } +}