From db42d2b5a48175f123aa70e470b2b4efafc68d00 Mon Sep 17 00:00:00 2001 From: Alex <93446519+AlexOn1ine@users.noreply.github.com> Date: Fri, 5 Apr 2024 19:38:50 +0200 Subject: [PATCH] Adds Booster Energy (#4337) * Adds Booster Energy * fix string * fixes strings in tests * Apply suggestions from code review --------- Co-authored-by: Bassoonian --- data/battle_scripts_1.s | 10 + include/battle.h | 1 + include/battle_scripts.h | 1 + include/constants/battle_string_ids.h | 3 +- src/battle_main.c | 2 + src/battle_message.c | 4 +- src/battle_util.c | 35 ++- .../pokemon/species_info/gen_9_families.h | 2 - test/battle/ability/booster_energy.c | 211 ++++++++++++++++++ 9 files changed, 261 insertions(+), 8 deletions(-) create mode 100644 test/battle/ability/booster_energy.c diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index a23423b42e..539d109037 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -9926,6 +9926,16 @@ BattleScript_BerserkGeneRet_End: removeitem BS_SCRIPTING end3 +BattleScript_BoosterEnergyEnd2:: + playanimation BS_SCRIPTING, B_ANIM_HELD_ITEM_EFFECT, sB_ANIM_ARG1 + call BattleScript_AbilityPopUp + printstring STRINGID_BOOSTERENERGYACTIVATES + waitmessage B_WAIT_TIME_MED + printstring STRINGID_STATWASHEIGHTENED + waitmessage B_WAIT_TIME_MED + removeitem BS_SCRIPTING + end2 + BattleScript_EffectSnow:: attackcanceler attackstring diff --git a/include/battle.h b/include/battle.h index 5a69fc8d50..fbe3f8b48b 100644 --- a/include/battle.h +++ b/include/battle.h @@ -778,6 +778,7 @@ struct BattleStruct u8 supremeOverlordCounter[MAX_BATTLERS_COUNT]; u8 quickClawRandom[MAX_BATTLERS_COUNT]; u8 quickDrawRandom[MAX_BATTLERS_COUNT]; + u8 boosterEnergyActivates; }; // The palaceFlags member of struct BattleStruct contains 1 flag per move to indicate which moves the AI should consider, diff --git a/include/battle_scripts.h b/include/battle_scripts.h index 319437c12f..13998ac46c 100644 --- a/include/battle_scripts.h +++ b/include/battle_scripts.h @@ -495,6 +495,7 @@ extern const u8 BattleScript_TheSwampDisappeared[]; extern const u8 BattleScript_ItemRestoreHP_Party[]; extern const u8 BattleScript_EffectPsychicNoise[]; extern const u8 BattleScript_AromaVeilProtectsRet[]; +extern const u8 BattleScript_BoosterEnergyEnd2[]; // zmoves extern const u8 BattleScript_ZMoveActivateDamaging[]; diff --git a/include/constants/battle_string_ids.h b/include/constants/battle_string_ids.h index 7a64f6d6fd..edab0e659d 100644 --- a/include/constants/battle_string_ids.h +++ b/include/constants/battle_string_ids.h @@ -707,8 +707,9 @@ #define STRINGID_BIZARREARENACREATED 705 #define STRINGID_BIZARREAREACREATED 706 #define STRINGID_TIDYINGUPCOMPLETE 707 +#define STRINGID_BOOSTERENERGYACTIVATES 708 -#define BATTLESTRINGS_COUNT 708 +#define BATTLESTRINGS_COUNT 709 // This is the string id that gBattleStringsTable starts with. // String ids before this (e.g. STRINGID_INTROMSG) are not in the table, diff --git a/src/battle_main.c b/src/battle_main.c index 5e5f8187bb..631b886ef5 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -3467,6 +3467,7 @@ void SwitchInClearSetData(u32 battler) gBattleStruct->lastTakenMoveFrom[battler][3] = 0; gBattleStruct->lastMoveFailed &= ~(gBitTable[battler]); gBattleStruct->palaceFlags &= ~(gBitTable[battler]); + gBattleStruct->boosterEnergyActivates &= ~(gBitTable[battler]); for (i = 0; i < ARRAY_COUNT(gSideTimers); i++) { @@ -3598,6 +3599,7 @@ const u8* FaintClearSetData(u32 battler) gBattleStruct->lastTakenMoveFrom[battler][3] = 0; gBattleStruct->palaceFlags &= ~(gBitTable[battler]); + gBattleStruct->boosterEnergyActivates &= ~(gBitTable[battler]); for (i = 0; i < ARRAY_COUNT(gSideTimers); i++) { diff --git a/src/battle_message.c b/src/battle_message.c index 3ad1dc409b..5cfff87fd9 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -791,6 +791,7 @@ static const u8 sText_AttackerSwitchedStatWithTarget[] = _("{B_ATK_NAME_WITH_PRE static const u8 sText_BeingHitChargedPkmnWithPower[] = _("Being hit by {B_CURRENT_MOVE}\ncharged {B_DEF_NAME_WITH_PREFIX} with power!"); static const u8 sText_SunlightActivatedAbility[] = _("The harsh sunlight activated\n{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_LAST_ABILITY}!"); static const u8 sText_StatWasHeightened[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_BUFF1} was heightened!"); +static const u8 sText_BoosterEnergyActivates[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s used its Booster Energy\nto activate {B_SCR_ACTIVE_ABILITY}!"); static const u8 sText_ElectricTerrainActivatedAbility[] = _("The Electric Terrain activated\n{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_LAST_ABILITY}!"); static const u8 sText_AbilityWeakenedSurroundingMonsStat[] = _("{B_ATK_NAME_WITH_PREFIX}'s {B_ATK_ABILITY}\nweakened the {B_BUFF1} of\lall surrounding Pokémon!\p"); static const u8 sText_AttackerGainedStrengthFromTheFallen[] = _("{B_ATK_NAME_WITH_PREFIX} gained strength\nfrom the fallen!"); @@ -892,6 +893,7 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = [STRINGID_ABILITYWEAKENEDFSURROUNDINGMONSSTAT - BATTLESTRINGS_TABLE_START] = sText_AbilityWeakenedSurroundingMonsStat, [STRINGID_ELECTRICTERRAINACTIVATEDABILITY - BATTLESTRINGS_TABLE_START] = sText_ElectricTerrainActivatedAbility, [STRINGID_STATWASHEIGHTENED - BATTLESTRINGS_TABLE_START] = sText_StatWasHeightened, + [STRINGID_BOOSTERENERGYACTIVATES - BATTLESTRINGS_TABLE_START] = sText_BoosterEnergyActivates, [STRINGID_SUNLIGHTACTIVATEDABILITY - BATTLESTRINGS_TABLE_START] = sText_SunlightActivatedAbility, [STRINGID_BEINGHITCHARGEDPKMNWITHPOWER - BATTLESTRINGS_TABLE_START] = sText_BeingHitChargedPkmnWithPower, [STRINGID_ATTACKERSWITCHEDSTATWITHTARGET - BATTLESTRINGS_TABLE_START] = sText_AttackerSwitchedStatWithTarget, @@ -1571,7 +1573,7 @@ const u16 gMentalHerbCureStringIds[] = [B_MSG_MENTALHERBCURE_DISABLE] = STRINGID_PKMNMOVEDISABLEDNOMORE, }; -const u16 gStartingStatusStringIds[B_MSG_STARTING_STATUS_COUNT] = +const u16 gStartingStatusStringIds[B_MSG_STARTING_STATUS_COUNT] = { [B_MSG_TERRAIN_SET_MISTY] = STRINGID_TERRAINBECOMESMISTY, [B_MSG_TERRAIN_SET_ELECTRIC] = STRINGID_TERRAINBECOMESELECTRIC, diff --git a/src/battle_util.c b/src/battle_util.c index 45b0566bae..8e92f3a885 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -7272,6 +7272,18 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn) BattleScriptPushCursorAndCallback(BattleScript_BerserkGeneRet); effect = ITEM_STATS_CHANGE; break; + case HOLD_EFFECT_BOOSTER_ENERGY: + if (!(gBattleStruct->boosterEnergyActivates & gBitTable[battler]) + && (((GetBattlerAbility(battler) == ABILITY_PROTOSYNTHESIS) && !(gBattleWeather & B_WEATHER_SUN)) + || ((GetBattlerAbility(battler) == ABILITY_QUARK_DRIVE) && !(gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN)))) + { + PREPARE_STAT_BUFFER(gBattleTextBuff1, GetHighestStatId(battler)); + gBattleScripting.battler = battler; + gBattleStruct->boosterEnergyActivates |= gBitTable[battler]; + BattleScriptExecute(BattleScript_BoosterEnergyEnd2); + effect = ITEM_EFFECT_OTHER; + } + break; } if (effect != 0) { @@ -7536,6 +7548,18 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn) case HOLD_EFFECT_MIRROR_HERB: effect = TryConsumeMirrorHerb(battler, TRUE); break; + case HOLD_EFFECT_BOOSTER_ENERGY: + if (!(gBattleStruct->boosterEnergyActivates & gBitTable[battler]) + && (((GetBattlerAbility(battler) == ABILITY_PROTOSYNTHESIS) && !(gBattleWeather & B_WEATHER_SUN)) + || ((GetBattlerAbility(battler) == ABILITY_QUARK_DRIVE) && !(gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN)))) + { + PREPARE_STAT_BUFFER(gBattleTextBuff1, GetHighestStatId(battler)); + gBattlerAbility = gBattleScripting.battler = battler; + gBattleStruct->boosterEnergyActivates |= gBitTable[battler]; + BattleScriptExecute(BattleScript_BoosterEnergyEnd2); + effect = ITEM_EFFECT_OTHER; + } + break; } if (effect != 0) @@ -8940,7 +8964,7 @@ static inline u32 CalcMoveBasePowerAfterModifiers(u32 move, u32 battlerAtk, u32 case ABILITY_PROTOSYNTHESIS: { u8 atkHighestStat = GetHighestStatId(battlerAtk); - if (weather & B_WEATHER_SUN + if ((weather & B_WEATHER_SUN || gBattleStruct->boosterEnergyActivates & gBitTable[battlerAtk]) && ((IS_MOVE_PHYSICAL(move) && atkHighestStat == STAT_ATK) || (IS_MOVE_SPECIAL(move) && atkHighestStat == STAT_SPATK))) modifier = uq4_12_multiply(modifier, UQ_4_12(1.3)); } @@ -8948,7 +8972,7 @@ static inline u32 CalcMoveBasePowerAfterModifiers(u32 move, u32 battlerAtk, u32 case ABILITY_QUARK_DRIVE: { u8 atkHighestStat = GetHighestStatId(battlerAtk); - if (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN + if ((gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN || gBattleStruct->boosterEnergyActivates & gBitTable[battlerAtk]) && ((IS_MOVE_PHYSICAL(move) && atkHighestStat == STAT_ATK) || (IS_MOVE_SPECIAL(move) && atkHighestStat == STAT_SPATK))) modifier = uq4_12_multiply(modifier, UQ_4_12(1.3)); } @@ -9018,7 +9042,7 @@ static inline u32 CalcMoveBasePowerAfterModifiers(u32 move, u32 battlerAtk, u32 case ABILITY_PROTOSYNTHESIS: { u8 defHighestStat = GetHighestStatId(battlerDef); - if (weather & B_WEATHER_SUN + if ((weather & B_WEATHER_SUN || gBattleStruct->boosterEnergyActivates & gBitTable[battlerDef]) && ((IS_MOVE_PHYSICAL(move) && defHighestStat == STAT_DEF) || (IS_MOVE_SPECIAL(move) && defHighestStat == STAT_SPDEF))) modifier = uq4_12_multiply(modifier, UQ_4_12(0.7)); } @@ -9026,7 +9050,7 @@ static inline u32 CalcMoveBasePowerAfterModifiers(u32 move, u32 battlerAtk, u32 case ABILITY_QUARK_DRIVE: { u8 defHighestStat = GetHighestStatId(battlerDef); - if (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN + if ((gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN || gBattleStruct->boosterEnergyActivates & gBitTable[battlerDef]) && ((IS_MOVE_PHYSICAL(move) && defHighestStat == STAT_DEF) || (IS_MOVE_SPECIAL(move) && defHighestStat == STAT_SPDEF))) modifier = uq4_12_multiply(modifier, UQ_4_12(0.7)); } @@ -10492,6 +10516,9 @@ bool32 CanBattlerGetOrLoseItem(u32 battler, u16 itemId) return FALSE; else if (holdEffect == HOLD_EFFECT_Z_CRYSTAL) return FALSE; + else if (holdEffect == HOLD_EFFECT_BOOSTER_ENERGY + && (gSpeciesInfo[gBattleMons[gBattlerAttacker].species].isParadoxForm || gSpeciesInfo[gBattleMons[gBattlerTarget].species].isParadoxForm)) + return FALSE; else return TRUE; } diff --git a/src/data/pokemon/species_info/gen_9_families.h b/src/data/pokemon/species_info/gen_9_families.h index 06653c20de..3efa35edb8 100644 --- a/src/data/pokemon/species_info/gen_9_families.h +++ b/src/data/pokemon/species_info/gen_9_families.h @@ -5708,7 +5708,6 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .iconPalIndex = 0, //FOOTPRINT(Koraidon) .isLegendary = TRUE, - .isParadoxForm = TRUE, .levelUpLearnset = sKoraidonLevelUpLearnset, .teachableLearnset = sKoraidonTeachableLearnset, }, @@ -5764,7 +5763,6 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .iconPalIndex = 2, //FOOTPRINT(Miraidon) .isLegendary = TRUE, - .isParadoxForm = TRUE, .levelUpLearnset = sMiraidonLevelUpLearnset, .teachableLearnset = sMiraidonTeachableLearnset, }, diff --git a/test/battle/ability/booster_energy.c b/test/battle/ability/booster_energy.c new file mode 100644 index 0000000000..b4fa45eaed --- /dev/null +++ b/test/battle/ability/booster_energy.c @@ -0,0 +1,211 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(gItemsInfo[ITEM_BOOSTER_ENERGY].holdEffect == HOLD_EFFECT_BOOSTER_ENERGY); +} + +SINGLE_BATTLE_TEST("Booster Energy will activate Quark Drive after Electric Terrain ends") +{ + GIVEN { + PLAYER(SPECIES_IRON_MOTH) { Attack(100); Defense(100); Speed(100); SpAttack(110); SpDefense(100); Ability(ABILITY_QUARK_DRIVE); Item(ITEM_BOOSTER_ENERGY); } + OPPONENT(SPECIES_TAPU_KOKO) { Speed(100); Ability(ABILITY_ELECTRIC_SURGE); }; + } WHEN { + TURN {} + TURN {} + TURN {} + TURN {} + TURN {} + } SCENE { + ABILITY_POPUP(opponent, ABILITY_ELECTRIC_SURGE); + NONE_OF { + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player); + MESSAGE("Iron Moth's Booster Energy to activate Quark Drive!"); + MESSAGE("Iron Moth's Sp. Atk was heightened!"); + } + ABILITY_POPUP(player, ABILITY_QUARK_DRIVE); + MESSAGE("The Electric Terrain activated Iron Moth's Quark Drive!"); + MESSAGE("Iron Moth's Sp. Atk was heightened!"); + MESSAGE("The electricity disappeared from the battlefield."); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player); + ABILITY_POPUP(player, ABILITY_QUARK_DRIVE); + MESSAGE("Iron Moth's used its Booster Energy to activate Quark Drive!"); + MESSAGE("Iron Moth's Sp. Atk was heightened!"); + } +} + +SINGLE_BATTLE_TEST("Booster Energy will activate Protosynthesis after harsh sunlight ends") +{ + GIVEN { + PLAYER(SPECIES_RAGING_BOLT) { Attack(100); Defense(100); Speed(100); SpAttack(110); SpDefense(100); Ability(ABILITY_PROTOSYNTHESIS); Item(ITEM_BOOSTER_ENERGY); } + OPPONENT(SPECIES_TORKOAL) { Speed(100); Ability(ABILITY_DROUGHT); }; + } WHEN { + TURN {} + TURN {} + TURN {} + TURN {} + TURN {} + } SCENE { + ABILITY_POPUP(opponent, ABILITY_DROUGHT); + NONE_OF { + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player); + MESSAGE("RagingBolt's used its Booster Energy to activate Protosynthesis!"); + MESSAGE("RagingBolt's Sp. Atk was heightened!"); + } + ABILITY_POPUP(player, ABILITY_PROTOSYNTHESIS); + MESSAGE("The harsh sunlight activated RagingBolt's Protosynthesis!"); + MESSAGE("RagingBolt's Sp. Atk was heightened!"); + MESSAGE("The sunlight faded."); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player); + ABILITY_POPUP(player, ABILITY_PROTOSYNTHESIS); + MESSAGE("RagingBolt's used its Booster Energy to activate Protosynthesis!"); + MESSAGE("RagingBolt's Sp. Atk was heightened!"); + } +} + +SINGLE_BATTLE_TEST("Booster Energy activates Protosynthesis and increases highest stat") +{ + u32 attack, defense, speed, spAttack, spDefense; + + PARAMETRIZE { attack = 110; defense = 100; speed = 100; spAttack = 100; spDefense = 100; } + PARAMETRIZE { attack = 100; defense = 110; speed = 100; spAttack = 100; spDefense = 100; } + PARAMETRIZE { attack = 100; defense = 100; speed = 110; spAttack = 100; spDefense = 100; } + PARAMETRIZE { attack = 100; defense = 100; speed = 100; spAttack = 110; spDefense = 100; } + PARAMETRIZE { attack = 100; defense = 100; speed = 100; spAttack = 100; spDefense = 110; } + + GIVEN { + PLAYER(SPECIES_RAGING_BOLT) { Attack(attack); Defense(defense); Speed(speed); SpAttack(spAttack); SpDefense(spDefense); Ability(ABILITY_PROTOSYNTHESIS); Item(ITEM_BOOSTER_ENERGY); } + OPPONENT(SPECIES_WOBBUFFET) { Speed(50); }; + } WHEN { + TURN { } + } SCENE { + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player); + ABILITY_POPUP(player, ABILITY_PROTOSYNTHESIS); + MESSAGE("RagingBolt's used its Booster Energy to activate Protosynthesis!"); + if (attack == 110) + MESSAGE("RagingBolt's Attack was heightened!"); + else if (defense == 110) + MESSAGE("RagingBolt's Defense was heightened!"); + else if (speed == 110) + MESSAGE("RagingBolt's Speed was heightened!"); + else if (spAttack == 110) + MESSAGE("RagingBolt's Sp. Atk was heightened!"); + else if (spDefense == 110) + MESSAGE("RagingBolt's Sp. Def was heightened!"); + } THEN { + EXPECT(player->item == ITEM_NONE); + } +} + +SINGLE_BATTLE_TEST("Booster Energy activates Quark Drive and increases highest stat") +{ + u32 attack, defense, speed, spAttack, spDefense; + + PARAMETRIZE { attack = 110; defense = 100; speed = 100; spAttack = 100; spDefense = 100; } + PARAMETRIZE { attack = 100; defense = 110; speed = 100; spAttack = 100; spDefense = 100; } + PARAMETRIZE { attack = 100; defense = 100; speed = 110; spAttack = 100; spDefense = 100; } + PARAMETRIZE { attack = 100; defense = 100; speed = 100; spAttack = 110; spDefense = 100; } + PARAMETRIZE { attack = 100; defense = 100; speed = 100; spAttack = 100; spDefense = 110; } + + GIVEN { + PLAYER(SPECIES_IRON_MOTH) { Attack(attack); Defense(defense); Speed(speed); SpAttack(spAttack); SpDefense(spDefense); Ability(ABILITY_QUARK_DRIVE); Item(ITEM_BOOSTER_ENERGY); } + OPPONENT(SPECIES_WOBBUFFET) { Speed(50); }; + } WHEN { + TURN { } + } SCENE { + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player); + if (attack == 110) + MESSAGE("Iron Moth's Attack was heightened!"); + else if (defense == 110) + MESSAGE("Iron Moth's Defense was heightened!"); + else if (speed == 110) + MESSAGE("Iron Moth's Speed was heightened!"); + else if (spAttack == 110) + MESSAGE("Iron Moth's Sp. Atk was heightened!"); + else if (spDefense == 110) + MESSAGE("Iron Moth's Sp. Def was heightened!"); + } THEN { + EXPECT(player->item == ITEM_NONE); + } +} + +SINGLE_BATTLE_TEST("Booster Energy increases special attack by 30% if it is the highest stat", s16 damage) +{ + u32 species; + u32 ability; + u32 item; + + PARAMETRIZE { species = SPECIES_RAGING_BOLT; ability = ABILITY_PROTOSYNTHESIS; item = ITEM_NONE; } + PARAMETRIZE { species = SPECIES_RAGING_BOLT; ability = ABILITY_PROTOSYNTHESIS; item = ITEM_BOOSTER_ENERGY; } + + PARAMETRIZE { species = SPECIES_IRON_MOTH; ability = ABILITY_QUARK_DRIVE; item = ITEM_NONE; } + PARAMETRIZE { species = SPECIES_IRON_MOTH; ability = ABILITY_QUARK_DRIVE; item = ITEM_BOOSTER_ENERGY; } + + GIVEN { + ASSUME(gMovesInfo[MOVE_ROUND].category == DAMAGE_CATEGORY_SPECIAL); + PLAYER(species) { Attack(100); Defense(100); Speed(100); SpAttack(110); SpDefense(100); Ability(ability); Item(item); } + OPPONENT(SPECIES_WOBBUFFET) { Speed(100); }; + } WHEN { + TURN { MOVE(player, MOVE_ROUND); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_ROUND, player); + HP_BAR(opponent, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_MUL_EQ(results[0].damage, Q_4_12(1.3), results[1].damage); + } +} + +SINGLE_BATTLE_TEST("Booster Energy increases special defense by 30% if it is the highest stat", s16 damage) +{ + u32 species; + u32 ability; + u32 item; + + PARAMETRIZE { species = SPECIES_RAGING_BOLT; ability = ABILITY_PROTOSYNTHESIS; item = ITEM_NONE; } + PARAMETRIZE { species = SPECIES_RAGING_BOLT; ability = ABILITY_PROTOSYNTHESIS; item = ITEM_BOOSTER_ENERGY; } + + PARAMETRIZE { species = SPECIES_IRON_MOTH; ability = ABILITY_QUARK_DRIVE; item = ITEM_NONE; } + PARAMETRIZE { species = SPECIES_IRON_MOTH; ability = ABILITY_QUARK_DRIVE; item = ITEM_BOOSTER_ENERGY; } + + GIVEN { + ASSUME(gMovesInfo[MOVE_ROUND].category == DAMAGE_CATEGORY_SPECIAL); + PLAYER(species) { Attack(100); Defense(100); Speed(100); SpAttack(100); SpDefense(110); Ability(ability); Item(item); } + OPPONENT(SPECIES_WOBBUFFET) { Speed(100); }; + } WHEN { + TURN { MOVE(opponent, MOVE_ROUND); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_ROUND, opponent); + HP_BAR(player, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_MUL_EQ(results[0].damage, Q_4_12(0.7), results[1].damage); + } +} + +SINGLE_BATTLE_TEST("Booster Energy can't be flung if a Paradox species is involved") +{ + GIVEN { + ASSUME(gSpeciesInfo[SPECIES_IRON_MOTH].isParadoxForm == TRUE); + PLAYER(SPECIES_IRON_MOTH); + OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_BOOSTER_ENERGY); } + } WHEN { + TURN { MOVE(opponent, MOVE_FLING); } + } SCENE { + NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_FLING, opponent); + MESSAGE("But it failed!"); + } +} + +SINGLE_BATTLE_TEST("Booster Energy can't be tricked if a Paradox species is involved") +{ + GIVEN { + ASSUME(gSpeciesInfo[SPECIES_IRON_MOTH].isParadoxForm == TRUE); + PLAYER(SPECIES_IRON_MOTH) { Item(ITEM_BERRY_JUICE); } + OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_BOOSTER_ENERGY); } + } WHEN { + TURN { MOVE(opponent, MOVE_TRICK); } + } SCENE { + NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_TRICK, opponent); + MESSAGE("But it failed!"); + } +}