diff --git a/data/battle_anim_scripts.s b/data/battle_anim_scripts.s index a79fae484d..3943be6278 100644 --- a/data/battle_anim_scripts.s +++ b/data/battle_anim_scripts.s @@ -16929,6 +16929,29 @@ ChillyReceptionSnowballs: delay 3 return +Move_BURNING_BULWARK:: + goto Move_PROTECT + +Move_ALLURING_VOICE:: + loadspritegfx ANIM_TAG_THIN_RING + createvisualtask AnimTask_BlendBattleAnimPal, 0xa, F_PAL_BG, 0x1, 0x0, 0x8, 0x6e7d + waitforvisualfinish + createvisualtask SoundTask_PlayCryWithEcho, 5, FALSE + createsprite gHyperVoiceRingSpriteTemplate, ANIM_ATTACKER, 0, 45, 0, 0, 0, 0, 0, 1 + createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 1, 0, 6, 1 + createvisualtask AnimTask_ShakeMon2, 2, ANIM_DEF_PARTNER, 1, 0, 6, 1 + createvisualtask AnimTask_ShakeBattleTerrain, 2, 1, 0, 6, 1 + createvisualtask SoundTask_WaitForCry, 5 + delay 0xA + createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 1, 0, 26, 1 + createvisualtask AnimTask_ShakeMon2, 2, ANIM_DEF_PARTNER, 1, 0, 26, 1 + waitforvisualfinish + createvisualtask SoundTask_WaitForCry, 0x5 + waitforvisualfinish + createvisualtask AnimTask_BlendBattleAnimPal, 0xa, F_PAL_BG, 0x1, 0x8, 0x0, 0x6e7d + waitforvisualfinish + end + Move_TERA_BLAST:: Move_AXE_KICK:: Move_LAST_RESPECTS:: @@ -16980,13 +17003,11 @@ Move_IVY_CUDGEL:: Move_ELECTRO_SHOT:: Move_TERA_STARSTORM:: Move_FICKLE_BEAM:: -Move_BURNING_BULWARK:: Move_THUNDERCLAP:: Move_MIGHTY_CLEAVE:: Move_TACHYON_CUTTER:: Move_HARD_PRESS:: Move_DRAGON_CHEER:: -Move_ALLURING_VOICE:: Move_TEMPER_FLARE:: Move_SUPERCELL_SLAM:: Move_PSYCHIC_NOISE:: @@ -19353,7 +19374,7 @@ Move_TELEPORT: call UnsetPsychicBg waitforvisualfinish end - + DoubleTeamAnimRet: setalpha 12, 8 monbg ANIM_ATK_PARTNER diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 9f70bbdf8b..cddbdcc044 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -442,6 +442,7 @@ gBattleScriptsForMoveEffects:: .4byte BattleScript_EffectDoodle @ EFFECT_DOODLE .4byte BattleScript_EffectFilletAway @ EFFECT_FILLET_AWAY .4byte BattleScript_EffectHit @ EFFECT_IVY_CUDGEL + .4byte BattleScript_EffectHit @ EFFECT_FICKLE_BEAM BattleScript_EffectFilletAway: attackcanceler @@ -1062,12 +1063,25 @@ BattleScript_EffectMeteorBeam:: @ DecideTurn jumpifstatus2 BS_ATTACKER, STATUS2_MULTIPLETURNS, BattleScript_TwoTurnMovesSecondTurn jumpifword CMP_COMMON_BITS, gHitMarker, HITMARKER_NO_ATTACKSTRING, BattleScript_TwoTurnMovesSecondTurn - setbyte sTWOTURN_STRINGID, B_MSG_TURN1_METEOR_BEAM + jumpifmove MOVE_METEOR_BEAM, BattleScript_SetStringMeteorBeam + jumpifmove MOVE_ELECTRO_SHOT, BattleScript_SetStringElectroShock +BattleScript_TryCharging: call BattleScript_FirstChargingTurnMeteorBeam + jumpifmove MOVE_METEOR_BEAM, BattleScript_TryMeteorBeam + jumpifweatheraffected BS_ATTACKER, B_WEATHER_RAIN, BattleScript_TwoTurnMovesSecondTurn @ Check for move Electro Shot +BattleScript_TryMeteorBeam: jumpifnoholdeffect BS_ATTACKER, HOLD_EFFECT_POWER_HERB, BattleScript_MoveEnd call BattleScript_PowerHerbActivation goto BattleScript_TwoTurnMovesSecondTurn +BattleScript_SetStringMeteorBeam: + setbyte sTWOTURN_STRINGID, B_MSG_TURN1_METEOR_BEAM + goto BattleScript_TryCharging + +BattleScript_SetStringElectroShock: + setbyte sTWOTURN_STRINGID, B_MSG_TURN1_ELECTRO_SHOCK + goto BattleScript_TryCharging + BattleScript_FirstChargingTurnMeteorBeam:: attackcanceler flushtextbox diff --git a/include/battle.h b/include/battle.h index ecf8250774..876ed04772 100644 --- a/include/battle.h +++ b/include/battle.h @@ -162,6 +162,7 @@ struct ProtectStruct u16 shellTrap:1; u16 maxGuarded:1; u16 silkTrapped:1; + u16 burningBulwarked:1; u16 eatMirrorHerb:1; u16 activateOpportunist:2; // 2 - to copy stats. 1 - stats copied (do not repeat). 0 - no stats to copy u16 usedAllySwitch:1; @@ -813,6 +814,7 @@ STATIC_ASSERT(sizeof(((struct BattleStruct *)0)->palaceFlags) * 8 >= MAX_BATTLER || gProtectStructs[battlerId].spikyShielded \ || gProtectStructs[battlerId].kingsShielded \ || gProtectStructs[battlerId].banefulBunkered \ + || gProtectStructs[battlerId].burningBulwarked \ || gProtectStructs[battlerId].obstructed \ || gProtectStructs[battlerId].silkTrapped) diff --git a/include/constants/battle_move_effects.h b/include/constants/battle_move_effects.h index 70d8f11eec..b1662469e7 100644 --- a/include/constants/battle_move_effects.h +++ b/include/constants/battle_move_effects.h @@ -419,7 +419,8 @@ #define EFFECT_DOODLE 413 #define EFFECT_FILLET_AWAY 414 #define EFFECT_IVY_CUDGEL 415 +#define EFFECT_FICKLE_BEAM 416 -#define NUM_BATTLE_MOVE_EFFECTS 416 +#define NUM_BATTLE_MOVE_EFFECTS 417 #endif // GUARD_CONSTANTS_BATTLE_MOVE_EFFECTS_H diff --git a/include/constants/battle_string_ids.h b/include/constants/battle_string_ids.h index 5b571c9fb2..c4ca5dee43 100644 --- a/include/constants/battle_string_ids.h +++ b/include/constants/battle_string_ids.h @@ -697,8 +697,9 @@ #define STRINGID_THESWAMPDISAPPEARED 695 #define STRINGID_PKMNTELLCHILLINGRECEPTIONJOKE 696 #define STRINGID_HOSPITALITYRESTORATION 697 +#define STRINGID_ELECTROSHOCKCHARGING 698 -#define BATTLESTRINGS_COUNT 698 +#define BATTLESTRINGS_COUNT 699 // This is the string id that gBattleStringsTable starts with. // String ids before this (e.g. STRINGID_INTROMSG) are not in the table, @@ -756,6 +757,7 @@ #define B_MSG_TURN1_FREEZE_SHOCK 10 #define B_MSG_TURN1_SKY_DROP 11 #define B_MSG_TURN1_METEOR_BEAM 12 +#define B_MSG_TURN1_ELECTRO_SHOCK 13 // gMoveWeatherChangeStringIds #define B_MSG_STARTED_RAIN 0 diff --git a/include/random.h b/include/random.h index a13b28674f..8768f7c6dd 100644 --- a/include/random.h +++ b/include/random.h @@ -177,6 +177,7 @@ enum RandomTag RNG_QUICK_DRAW, RNG_QUICK_CLAW, RNG_TRACE, + RNG_FICKLE_BEAM, }; #define RandomWeighted(tag, ...) \ diff --git a/src/battle_main.c b/src/battle_main.c index 9930fa56fe..951766adcd 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -3263,6 +3263,7 @@ const u8* FaintClearSetData(u32 battler) gProtectStructs[battler].quash = FALSE; gProtectStructs[battler].obstructed = FALSE; gProtectStructs[battler].silkTrapped = FALSE; + gProtectStructs[battler].burningBulwarked = FALSE; gProtectStructs[battler].endured = FALSE; gProtectStructs[battler].noValidMoves = FALSE; gProtectStructs[battler].helpingHand = FALSE; diff --git a/src/battle_message.c b/src/battle_message.c index c0462846d3..5a52528498 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -834,9 +834,11 @@ static const u8 sText_TheSeaOfFireDisappeared[] = _("The sea of fire around {B_A static const u8 sText_SwampEnvelopedSide[] = _("A swamp enveloped\n{B_DEF_TEAM2} team!"); static const u8 sText_TheSwampDisappeared[] = _("The swamp around {B_ATK_TEAM2}\nteam disappeared!"); static const u8 sText_HospitalityRestoration[] = _("The {B_ATK_PARTNER_NAME} drank down all\nthe matcha that Sinistcha made!"); +static const u8 sText_ElectroShockCharging[] = _("{B_ATK_NAME_WITH_PREFIX} absorbed\nelectricity!"); const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = { + [STRINGID_ELECTROSHOCKCHARGING - BATTLESTRINGS_TABLE_START] = sText_ElectroShockCharging, [STRINGID_HOSPITALITYRESTORATION - BATTLESTRINGS_TABLE_START] = sText_HospitalityRestoration, [STRINGID_THESWAMPDISAPPEARED - BATTLESTRINGS_TABLE_START] = sText_TheSwampDisappeared, [STRINGID_SWAMPENVELOPEDSIDE - BATTLESTRINGS_TABLE_START] = sText_SwampEnvelopedSide, @@ -1764,6 +1766,7 @@ const u16 gFirstTurnOfTwoStringIds[] = [B_MSG_TURN1_FREEZE_SHOCK] = STRINGID_CLOAKEDINAFREEZINGLIGHT, [B_MSG_TURN1_SKY_DROP] = STRINGID_PKMNTOOKTARGETHIGH, [B_MSG_TURN1_METEOR_BEAM] = STRINGID_METEORBEAMCHARGING, + [B_MSG_TURN1_ELECTRO_SHOCK] = STRINGID_ELECTROSHOCKCHARGING, }; // Index copied from move's index in sTrappingMoves diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 77bbbe6ea2..0708a8b34f 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -3134,6 +3134,9 @@ void SetMoveEffect(bool32 primary, u32 certain) switch (gBattleScripting.moveEffect) { case MOVE_EFFECT_CONFUSION: + if (gCurrentMove == MOVE_ALLURING_VOICE && !gProtectStructs[gEffectBattler].statRaised) + break; + if (!CanBeConfused(gEffectBattler)) { gBattlescriptCurrInstr++; @@ -3523,6 +3526,7 @@ void SetMoveEffect(bool32 primary, u32 certain) gProtectStructs[gBattlerTarget].banefulBunkered = FALSE; gProtectStructs[gBattlerTarget].obstructed = FALSE; gProtectStructs[gBattlerTarget].silkTrapped = FALSE; + gProtectStructs[gBattlerAttacker].burningBulwarked = FALSE; BattleScriptPush(gBattlescriptCurrInstr + 1); if (gCurrentMove == MOVE_HYPERSPACE_FURY) gBattlescriptCurrInstr = BattleScript_HyperspaceFuryRemoveProtect; @@ -5322,6 +5326,15 @@ static void Cmd_moveend(void) gBattlescriptCurrInstr = BattleScript_KingsShieldEffect; effect = 1; } + else if (gProtectStructs[gBattlerTarget].burningBulwarked) + { + gProtectStructs[gBattlerAttacker].touchedProtectLike = FALSE; + gBattleScripting.moveEffect = MOVE_EFFECT_BURN | MOVE_EFFECT_AFFECTS_USER; + PREPARE_MOVE_BUFFER(gBattleTextBuff1, MOVE_BURNING_BULWARK); + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_BanefulBunkerEffect; + effect = 1; + } // Not strictly a protect effect, but works the same way else if (gProtectStructs[gBattlerTarget].beakBlastCharge && CanBeBurned(gBattlerAttacker) @@ -10720,6 +10733,11 @@ static void Cmd_setprotectlike(void) gProtectStructs[gBattlerAttacker].silkTrapped = TRUE; gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_PROTECTED_ITSELF; } + else if (gCurrentMove == MOVE_BURNING_BULWARK) + { + gProtectStructs[gBattlerAttacker].burningBulwarked = TRUE; + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_PROTECTED_ITSELF; + } gDisableStructs[gBattlerAttacker].protectUses++; fail = FALSE; diff --git a/src/battle_util.c b/src/battle_util.c index c3a020ace6..9a2a680ac0 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -8496,6 +8496,8 @@ bool32 IsBattlerProtected(u32 battler, u32 move) return TRUE; else if (gProtectStructs[battler].banefulBunkered) return TRUE; + else if (gProtectStructs[battler].burningBulwarked) + return TRUE; else if ((gProtectStructs[battler].obstructed || gProtectStructs[battler].silkTrapped) && !IS_MOVE_STATUS(move)) return TRUE; else if (gProtectStructs[battler].spikyShielded) @@ -9002,6 +9004,10 @@ static inline u32 CalcMoveBasePower(u32 move, u32 battlerAtk, u32 battlerDef, u3 basePower += 50 * gBattleStruct->timesGotHit[GetBattlerSide(battlerAtk)][gBattlerPartyIndexes[battlerAtk]]; basePower = (basePower > 350) ? 350 : basePower; break; + case EFFECT_FICKLE_BEAM: + if (RandomPercentage(RNG_FICKLE_BEAM, 30)) + basePower *= 2; + break; } // Move-specific base power changes diff --git a/src/data/battle_moves.h b/src/data/battle_moves.h index 292804138a..ea4876f67f 100644 --- a/src/data/battle_moves.h +++ b/src/data/battle_moves.h @@ -13902,7 +13902,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] = [MOVE_ELECTRO_SHOT] = { - .effect = EFFECT_PLACEHOLDER, //EFFECT_ELECTRO_SHOT + .effect = EFFECT_METEOR_BEAM, .power = 130, .type = TYPE_ELECTRIC, .accuracy = 100, @@ -13933,7 +13933,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] = [MOVE_FICKLE_BEAM] = { - .effect = EFFECT_PLACEHOLDER, //EFFECT_FICKLE_BEAM + .effect = EFFECT_FICKLE_BEAM, .power = 80, .type = TYPE_DRAGON, .accuracy = 100, @@ -13946,7 +13946,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] = [MOVE_BURNING_BULWARK] = { - .effect = EFFECT_PROTECT, // NEEDS ACTUAL PROTECT SIDE EFFECT + .effect = EFFECT_PROTECT, .power = 0, .type = TYPE_FIRE, .accuracy = 0, @@ -14037,16 +14037,17 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] = [MOVE_ALLURING_VOICE] = { - .effect = EFFECT_PLACEHOLDER, //EFFECT_ALLURING_VOICE + .effect = EFFECT_CONFUSE_HIT, .power = 80, .type = TYPE_FAIRY, .accuracy = 100, .pp = 10, - .secondaryEffectChance = 0, + .secondaryEffectChance = 100, .target = MOVE_TARGET_SELECTED, .priority = 0, .category = BATTLE_CATEGORY_SPECIAL, .soundMove = TRUE, + .sheerForceBoost = TRUE, .ignoresSubstitute = TRUE, }, diff --git a/test/battle/move_effect/confusion_hit.c b/test/battle/move_effect/confusion_hit.c new file mode 100644 index 0000000000..45077f42d0 --- /dev/null +++ b/test/battle/move_effect/confusion_hit.c @@ -0,0 +1,50 @@ +#include "global.h" +#include "test/battle.h" + +SINGLE_BATTLE_TEST("Alluring Voice confuses the target if the target raised a stat this turn") +{ + u16 move; + + PARAMETRIZE { move = MOVE_CELEBRATE; } + PARAMETRIZE { move = MOVE_SWORDS_DANCE; } + + GIVEN { + ASSUME(gBattleMoves[MOVE_ALLURING_VOICE].effect == EFFECT_CONFUSE_HIT); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, move); MOVE(player, MOVE_ALLURING_VOICE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, move, opponent); + ANIMATION(ANIM_TYPE_MOVE, MOVE_ALLURING_VOICE, player); + HP_BAR(opponent); + if (move == MOVE_SWORDS_DANCE) { + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_CONFUSION, opponent); + MESSAGE("Foe Wobbuffet became confused!"); + } else { + NONE_OF { + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_CONFUSION, opponent); + MESSAGE("Foe Wobbuffet became confused!"); + } + } + } +} + +SINGLE_BATTLE_TEST("Alluring Voice confuse effect is removed if it is Sheer Force boosted") +{ + GIVEN { + ASSUME(gBattleMoves[MOVE_ALLURING_VOICE].effect == EFFECT_CONFUSE_HIT); + PLAYER(SPECIES_NIDOKING) { Ability(ABILITY_SHEER_FORCE); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_SWORDS_DANCE); MOVE(player, MOVE_ALLURING_VOICE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SWORDS_DANCE, opponent); + ANIMATION(ANIM_TYPE_MOVE, MOVE_ALLURING_VOICE, player); + HP_BAR(opponent); + NONE_OF { + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_CONFUSION, opponent); + MESSAGE("Foe Wobbuffet became confused!"); + } + } +} diff --git a/test/battle/move_effect/fickle_beam.c b/test/battle/move_effect/fickle_beam.c new file mode 100644 index 0000000000..2732b641a6 --- /dev/null +++ b/test/battle/move_effect/fickle_beam.c @@ -0,0 +1,30 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(gBattleMoves[MOVE_FICKLE_BEAM].effect == EFFECT_FICKLE_BEAM); +} + +SINGLE_BATTLE_TEST("Fickle Beam deals double damage 30% of the time") +{ + s16 damage[2]; + + PASSES_RANDOMLY(30, 100, RNG_FICKLE_BEAM); + GIVEN { + ASSUME(gBattleMoves[MOVE_POWER_GEM].power == 80); + ASSUME(gBattleMoves[MOVE_FICKLE_BEAM].power == 80); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_POWER_GEM); } + TURN { MOVE(player, MOVE_FICKLE_BEAM); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_POWER_GEM, player); + HP_BAR(opponent, captureDamage: &damage[0]); + ANIMATION(ANIM_TYPE_MOVE, MOVE_FICKLE_BEAM, player); + HP_BAR(opponent, captureDamage: &damage[1]); + } THEN { + EXPECT_MUL_EQ(damage[0], Q_4_12(2.0), damage[1]); + } +} diff --git a/test/battle/move_effect/meteor_beam.c b/test/battle/move_effect/meteor_beam.c new file mode 100644 index 0000000000..600de153d4 --- /dev/null +++ b/test/battle/move_effect/meteor_beam.c @@ -0,0 +1,61 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(gBattleMoves[MOVE_ELECTRO_SHOT].effect == EFFECT_METEOR_BEAM); +} + +SINGLE_BATTLE_TEST("Electro Shot needs a charging Turn") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_ELECTRO_SHOT); } + TURN { SKIP_TURN(player); } + } SCENE { + // Charging turn + ANIMATION(ANIM_TYPE_MOVE, MOVE_ELECTRO_SHOT, player); + MESSAGE("Wobbuffet absorbed electricity!"); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Wobbuffet's Sp. Atk rose!"); + // Attack turn + MESSAGE("Wobbuffet used Electro Shot!"); + } +} + +SINGLE_BATTLE_TEST("Electro Shot doesn't need to charge when it's raining") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_RAIN_DANCE); MOVE(player, MOVE_ELECTRO_SHOT); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_RAIN_DANCE, opponent); + ANIMATION(ANIM_TYPE_MOVE, MOVE_ELECTRO_SHOT, player); + MESSAGE("Wobbuffet absorbed electricity!"); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Wobbuffet's Sp. Atk rose!"); + MESSAGE("Wobbuffet used Electro Shot!"); + } +} + +SINGLE_BATTLE_TEST("Electro Shot doesn't need to charge with Power Herb") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_POWER_HERB); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_ELECTRO_SHOT); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_ELECTRO_SHOT, player); + MESSAGE("Wobbuffet absorbed electricity!"); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Wobbuffet's Sp. Atk rose!"); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player); + MESSAGE("Wobbuffet became fully charged due to its Power Herb!"); + MESSAGE("Wobbuffet used Electro Shot!"); + } +} diff --git a/test/battle/move_effect/protect.c b/test/battle/move_effect/protect.c index 502eab46e0..c527a4881d 100644 --- a/test/battle/move_effect/protect.c +++ b/test/battle/move_effect/protect.c @@ -12,6 +12,7 @@ ASSUMPTIONS ASSUME(gBattleMoves[MOVE_QUICK_GUARD].effect == EFFECT_PROTECT); ASSUME(gBattleMoves[MOVE_CRAFTY_SHIELD].effect == EFFECT_PROTECT); ASSUME(gBattleMoves[MOVE_BANEFUL_BUNKER].effect == EFFECT_PROTECT); + ASSUME(gBattleMoves[MOVE_BURNING_BULWARK].effect == EFFECT_PROTECT); ASSUME(gBattleMoves[MOVE_TACKLE].category == BATTLE_CATEGORY_PHYSICAL); ASSUME(gBattleMoves[MOVE_TACKLE].makesContact); ASSUME(gBattleMoves[MOVE_LEER].category == BATTLE_CATEGORY_STATUS); @@ -19,7 +20,7 @@ ASSUMPTIONS ASSUME(!(gBattleMoves[MOVE_WATER_GUN].makesContact)); } -SINGLE_BATTLE_TEST("Protect, Detect, Spiky Shield and Baneful Bunker protect from all moves") +SINGLE_BATTLE_TEST("Protect, Detect, Spiky Shield, Baneful Bunker and Burning Bulwark protect from all moves") { u32 j; static const u16 protectMoves[] = { @@ -27,6 +28,7 @@ SINGLE_BATTLE_TEST("Protect, Detect, Spiky Shield and Baneful Bunker protect fro MOVE_DETECT, MOVE_SPIKY_SHIELD, MOVE_BANEFUL_BUNKER, + MOVE_BURNING_BULWARK, }; u16 protectMove = MOVE_NONE; u16 usedMove = MOVE_NONE; @@ -188,6 +190,38 @@ SINGLE_BATTLE_TEST("Baneful Bunker poisons pokemon for moves making contact") } } +SINGLE_BATTLE_TEST("Burning Bulwark burns pokemon for moves making contact") +{ + u16 usedMove = MOVE_NONE; + + PARAMETRIZE {usedMove = MOVE_TACKLE; } + PARAMETRIZE {usedMove = MOVE_LEER; } + PARAMETRIZE {usedMove = MOVE_WATER_GUN; } + + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_BURNING_BULWARK); MOVE(player, usedMove); } + TURN {} + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_BURNING_BULWARK, opponent); + MESSAGE("Foe Wobbuffet protected itself!"); + NOT ANIMATION(ANIM_TYPE_MOVE, usedMove, player); + MESSAGE("Foe Wobbuffet protected itself!"); + if (usedMove == MOVE_TACKLE) { + NOT HP_BAR(opponent); + STATUS_ICON(player, STATUS1_BURN); + } else { + NONE_OF { + HP_BAR(opponent); + STATUS_ICON(player, STATUS1_BURN); + } + } + } +} + SINGLE_BATTLE_TEST("Recoil damage is not applied if target was protected") { u32 j, k;