diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 183e7796bb..7f323dbd8b 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -452,28 +452,15 @@ BattleScript_EffectSyrupBomb:: goto BattleScript_MoveEnd BattleScript_SyrupBombEndTurn:: - setbyte sSTAT_ANIM_PLAYED, FALSE - copybyte sBATTLER, gBattlerTarget - jumpifholdeffect BS_TARGET, HOLD_EFFECT_CLEAR_AMULET, BattleScript_SyrupBombItemNoStatLoss - jumpifability BS_TARGET, ABILITY_CLEAR_BODY, BattleScript_SyrupBombAbilityNoStatLoss - jumpifability BS_TARGET, ABILITY_FULL_METAL_BODY, BattleScript_SyrupBombAbilityNoStatLoss - jumpifability BS_TARGET, ABILITY_WHITE_SMOKE, BattleScript_SyrupBombAbilityNoStatLoss - jumpifstat BS_TARGET, CMP_GREATER_THAN, BIT_SPEED, MIN_STAT_STAGE, BattleScript_SyrupBombLowerSpeed - goto BattleScript_SyrupBombEnd2 -BattleScript_SyrupBombLowerSpeed: playstatchangeanimation BS_ATTACKER, BIT_SPEED, STAT_CHANGE_NEGATIVE - setbyte sSTAT_ANIM_PLAYED, TRUE setstatchanger STAT_SPEED, 1, TRUE - statbuffchange STAT_CHANGE_ALLOW_PTR, BattleScript_SyrupBombEnd2 - jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_DECREASE, BattleScript_SyrupBombEnd2 + statbuffchange STAT_CHANGE_ALLOW_PTR | STAT_CHANGE_NOT_PROTECT_AFFECTED, BattleScript_SyrupBombTurnDmgEnd +BattleScript_SyrupBombTurnDmgPrintMsg: + jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, 3, BattleScript_SyrupBombTurnDmgEnd + jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, 4, BattleScript_SyrupBombTurnDmgEnd printfromtable gStatDownStringIds waitmessage B_WAIT_TIME_LONG -BattleScript_SyrupBombItemNoStatLoss:: - call BattleScript_ItemNoStatLoss - goto BattleScript_SyrupBombEnd2 -BattleScript_SyrupBombAbilityNoStatLoss:: - call BattleScript_AbilityNoStatLoss -BattleScript_SyrupBombEnd2:: +BattleScript_SyrupBombTurnDmgEnd: end2 BattleScript_EffectMatchaGotcha:: @@ -1079,29 +1066,23 @@ BattleScript_EffectOctolock: goto BattleScript_MoveEnd BattleScript_OctolockEndTurn:: - setbyte sSTAT_ANIM_PLAYED, FALSE - jumpifstat BS_TARGET, CMP_GREATER_THAN, STAT_DEF, MIN_STAT_STAGE, BattleScript_OctolockLowerDef - jumpifstat BS_TARGET, CMP_GREATER_THAN, STAT_SPDEF, MIN_STAT_STAGE, BattleScript_OctolockTryLowerSpDef - goto BattleScript_OctolockEnd2 -BattleScript_OctolockLowerDef: - jumpifability BS_TARGET, ABILITY_BIG_PECKS, BattleScript_OctolockTryLowerSpDef playstatchangeanimation BS_ATTACKER, BIT_DEF | BIT_SPDEF, STAT_CHANGE_NEGATIVE - setbyte sSTAT_ANIM_PLAYED, TRUE setstatchanger STAT_DEF, 1, TRUE - statbuffchange STAT_CHANGE_ALLOW_PTR, BattleScript_OctolockTryLowerSpDef - jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_DECREASE, BattleScript_OctolockTryLowerSpDef - printfromtable gStatUpStringIds + statbuffchange STAT_CHANGE_ALLOW_PTR | STAT_CHANGE_NOT_PROTECT_AFFECTED, BattleScript_OctolockTryLowerDef +BattleScript_OctolockTryLowerDef: + jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, 3, BattleScript_OctolockTryLowerSpDef + jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, 4, BattleScript_OctolockTryLowerSpDef + printfromtable gStatDownStringIds waitmessage B_WAIT_TIME_LONG BattleScript_OctolockTryLowerSpDef: - jumpifbyte CMP_EQUAL, sSTAT_ANIM_PLAYED, TRUE, BattleScript_OctolockSkipSpDefAnim - playstatchangeanimation BS_ATTACKER, BIT_SPDEF, STAT_CHANGE_NEGATIVE -BattleScript_OctolockSkipSpDefAnim: setstatchanger STAT_SPDEF, 1, TRUE - statbuffchange STAT_CHANGE_ALLOW_PTR, BattleScript_OctolockEnd2 - jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_DECREASE, BattleScript_OctolockEnd2 - printfromtable gStatUpStringIds + statbuffchange STAT_CHANGE_ALLOW_PTR | STAT_CHANGE_NOT_PROTECT_AFFECTED, BattleScript_OctolockTurnDmgPrintMsg +BattleScript_OctolockTurnDmgPrintMsg: + jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, 3, BattleScript_OctlockTurnDmgEnd + jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, 4, BattleScript_OctlockTurnDmgEnd + printfromtable gStatDownStringIds waitmessage B_WAIT_TIME_LONG -BattleScript_OctolockEnd2:: +BattleScript_OctlockTurnDmgEnd: end2 BattleScript_EffectPoltergeist: diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index cc365dbf82..b415f25d52 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -3010,7 +3010,7 @@ void SetMoveEffect(bool32 primary, u32 certain) gBattleMons[gEffectBattler].status1 |= STATUS1_SLEEP_TURN(1 + RandomUniform(RNG_SLEEP_TURNS, 1, 3)); else gBattleMons[gEffectBattler].status1 |= STATUS1_SLEEP_TURN(1 + RandomUniform(RNG_SLEEP_TURNS, 2, 5)); - } + } else { gBattleMons[gEffectBattler].status1 |= sStatusFlagsForMoveEffects[gBattleScripting.moveEffect]; @@ -11406,11 +11406,6 @@ static u32 ChangeStatBuffs(s8 statValue, u32 statId, u32 flags, const u8 *BS_ptr || battlerAbility == ABILITY_WHITE_SMOKE) && (!affectsUser || mirrorArmored) && !certain && gCurrentMove != MOVE_CURSE) { - if (battlerHoldEffect == HOLD_EFFECT_CLEAR_AMULET) - { - RecordItemEffectBattle(battler, HOLD_EFFECT_CLEAR_AMULET); - } - if (flags == STAT_CHANGE_ALLOW_PTR) { if (gSpecialStatuses[battler].statLowered) @@ -11424,6 +11419,7 @@ static u32 ChangeStatBuffs(s8 statValue, u32 statId, u32 flags, const u8 *BS_ptr if (battlerHoldEffect == HOLD_EFFECT_CLEAR_AMULET) { gBattlescriptCurrInstr = BattleScript_ItemNoStatLoss; + RecordItemEffectBattle(battler, HOLD_EFFECT_CLEAR_AMULET); } else { diff --git a/src/battle_util.c b/src/battle_util.c index a619b505e4..32bbf7f7e0 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -2793,11 +2793,7 @@ u8 DoBattlerEndTurnEffects(void) case ENDTURN_OCTOLOCK: { u16 battlerAbility = GetBattlerAbility(battler); - if (gDisableStructs[battler].octolock - && !(GetBattlerHoldEffect(battler, TRUE) == HOLD_EFFECT_CLEAR_AMULET - || battlerAbility == ABILITY_CLEAR_BODY - || battlerAbility == ABILITY_FULL_METAL_BODY - || battlerAbility == ABILITY_WHITE_SMOKE)) + if (gDisableStructs[battler].octolock) { gBattlerTarget = battler; BattleScriptExecute(BattleScript_OctolockEndTurn); @@ -3094,9 +3090,6 @@ u8 DoBattlerEndTurnEffects(void) case ENDTURN_SYRUP_BOMB: if ((gStatuses4[battler] & STATUS4_SYRUP_BOMB) && (gBattleMons[battler].hp != 0)) { - u16 battlerAbility = GetBattlerAbility(battler); - u32 battlerHoldEffect = GetBattlerHoldEffect(battler, TRUE); - gDisableStructs[battler].syrupBombTimer--; if (gDisableStructs[battler].syrupBombTimer == 0) { @@ -5760,7 +5753,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 case ABILITYEFFECT_OPPORTUNIST: /* Similar to ABILITYEFFECT_IMMUNITY in that it loops through all battlers. * Is called after ABILITYEFFECT_ON_SWITCHIN to copy any boosts - * from switch in abilities e.g. intrepid sword, as + * from switch in abilities e.g. intrepid sword, as */ for (battler = 0; battler < gBattlersCount; battler++) { @@ -5836,7 +5829,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 effect = 4; break; } - + if (effect != 0) { switch (effect) diff --git a/test/battle/damage_formula.c b/test/battle/damage_formula.c index 98aa197ca1..a4b0a03f58 100644 --- a/test/battle/damage_formula.c +++ b/test/battle/damage_formula.c @@ -76,3 +76,40 @@ SINGLE_BATTLE_TEST("Damage calculation matches Gen5+ (Muscle Band, crit)") EXPECT_EQ(expectedDamage, dmg); } } + +SINGLE_BATTLE_TEST("Damage calculation matches Gen5+ (Marshadow vs Mawile)") +{ + s16 dmg; + s16 expectedDamage; + PARAMETRIZE { expectedDamage = 145; } + PARAMETRIZE { expectedDamage = 144; } + PARAMETRIZE { expectedDamage = 142; } + PARAMETRIZE { expectedDamage = 141; } + PARAMETRIZE { expectedDamage = 139; } + PARAMETRIZE { expectedDamage = 138; } + PARAMETRIZE { expectedDamage = 136; } + PARAMETRIZE { expectedDamage = 135; } + PARAMETRIZE { expectedDamage = 133; } + PARAMETRIZE { expectedDamage = 132; } + PARAMETRIZE { expectedDamage = 130; } + PARAMETRIZE { expectedDamage = 129; } + PARAMETRIZE { expectedDamage = 127; } + PARAMETRIZE { expectedDamage = 126; } + PARAMETRIZE { expectedDamage = 124; } + PARAMETRIZE { expectedDamage = 123; } + GIVEN { + PLAYER(SPECIES_MARSHADOW) { Level(100); Attack(286); } + OPPONENT(SPECIES_MAWILE) { Level(100); Defense(226); HP(241); } + } WHEN { + TURN { + MOVE(player, MOVE_SPECTRAL_THIEF, WITH_RNG(RNG_DAMAGE_MODIFIER, i), criticalHit: FALSE); + } + } + SCENE{ + MESSAGE("Marshadow used SpectrlThief!"); + HP_BAR(opponent, captureDamage: &dmg); + } + THEN{ + EXPECT_EQ(expectedDamage, dmg); + } +} diff --git a/test/battle/move_effect/octolock.c b/test/battle/move_effect/octolock.c new file mode 100644 index 0000000000..f3249dd5ce --- /dev/null +++ b/test/battle/move_effect/octolock.c @@ -0,0 +1,97 @@ +#include "global.h" +#include "test/battle.h" + +SINGLE_BATTLE_TEST("Octolock") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_OCTOLOCK); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_OCTOLOCK, player); + MESSAGE("Foe Wobbuffet can no longer escape because of Octolock!"); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); + MESSAGE("Foe Wobbuffet's Defense fell!"); + NOT ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); + MESSAGE("Foe Wobbuffet's Sp. Def fell!"); + } +} + +SINGLE_BATTLE_TEST("Octolock 2") +{ + u32 species; + u32 ability; + + PARAMETRIZE { species = SPECIES_BELDUM; ability = ABILITY_CLEAR_BODY; } + PARAMETRIZE { species = SPECIES_TORKOAL; ability = ABILITY_WHITE_SMOKE; } + PARAMETRIZE { species = SPECIES_SOLGALEO; ability = ABILITY_FULL_METAL_BODY; } + + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(species) { Ability(ability); } + } WHEN { + TURN { MOVE(player, MOVE_OCTOLOCK); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_OCTOLOCK, player); + NOT ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); + if (species == SPECIES_BELDUM) + { + MESSAGE("Foe Beldum can no longer escape because of Octolock!"); + ABILITY_POPUP(opponent, ABILITY_CLEAR_BODY); + MESSAGE("Foe Beldum's Clear Body prevents stat loss!"); + NOT MESSAGE("Foe Beldum's Defense fell!"); + NOT MESSAGE("Foe Beldum's Sp. Def fell!"); + } + else if (species == SPECIES_TORKOAL) + { + MESSAGE("Foe Torkoal can no longer escape because of Octolock!"); + ABILITY_POPUP(opponent, ABILITY_WHITE_SMOKE); + MESSAGE("Foe Torkoal's White Smoke prevents stat loss!"); + NOT MESSAGE("Foe Torkoal's Defense fell!"); + NOT MESSAGE("Foe Torkoal's Sp. Def fell!"); + } + else if (species == SPECIES_SOLGALEO) + { + MESSAGE("Foe Solgaleo can no longer escape because of Octolock!"); + ABILITY_POPUP(opponent, ABILITY_FULL_METAL_BODY); + MESSAGE("Foe Solgaleo's Full Metal Body prevents stat loss!"); + NOT MESSAGE("Foe Solgaleo's Defense fell!"); + NOT MESSAGE("Foe Solgaleo's Sp. Def fell!"); + } + } +} + +SINGLE_BATTLE_TEST("Octolock 3") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_PIDGEY) { Ability(ABILITY_BIG_PECKS); } + } WHEN { + TURN { MOVE(player, MOVE_OCTOLOCK); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_OCTOLOCK, player); + MESSAGE("Foe Pidgey can no longer escape because of Octolock!"); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); + NOT MESSAGE("Foe Pidgey's Defense fell!"); + ABILITY_POPUP(opponent, ABILITY_BIG_PECKS); + MESSAGE("Foe Pidgey's Big Pecks prevents stat loss!"); + MESSAGE("Foe Wobbuffet's Sp. Def fell!"); + } +} + +SINGLE_BATTLE_TEST("Octolock 4") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_CLEAR_AMULET); } + } WHEN { + TURN { MOVE(player, MOVE_OCTOLOCK); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_OCTOLOCK, player); + MESSAGE("Foe Wobbuffet can no longer escape because of Octolock!"); + NOT ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); + NOT MESSAGE("Foe Wobbuffet's Defense fell!"); + NOT MESSAGE("Foe Wobbuffet's Sp. Def fell!"); + } +} diff --git a/test/battle/move_effect/syrup_bomb.c b/test/battle/move_effect/syrup_bomb.c index ae689b3629..08a3af95f9 100644 --- a/test/battle/move_effect/syrup_bomb.c +++ b/test/battle/move_effect/syrup_bomb.c @@ -32,9 +32,9 @@ SINGLE_BATTLE_TEST("Syrup Bomb is prevented by Bulletproof") TURN { MOVE(player, MOVE_SYRUP_BOMB); } } SCENE { ABILITY_POPUP(opponent, ABILITY_BULLETPROOF); - MESSAGE("Foe Chespin's Bulletproof blocks Syrup Bomb!"); NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_SYRUP_BOMB, player); NOT HP_BAR(opponent); + MESSAGE("Foe Chespin's Bulletproof blocks Syrup Bomb!"); } } @@ -57,6 +57,7 @@ SINGLE_BATTLE_TEST("Clear Body, White Smoke and Full Metal Body prevent Sticky S } SCENE { ANIMATION(ANIM_TYPE_MOVE, MOVE_SYRUP_BOMB, player); HP_BAR(opponent); + NOT ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); if (species == SPECIES_BELDUM) { MESSAGE("Foe Beldum got covered in sticky syrup!"); @@ -75,8 +76,6 @@ SINGLE_BATTLE_TEST("Clear Body, White Smoke and Full Metal Body prevent Sticky S ABILITY_POPUP(opponent, ABILITY_FULL_METAL_BODY); MESSAGE("Foe Solgaleo's Full Metal Body prevents stat loss!"); } - NOT ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); - NOT MESSAGE("Foe Beldum's Speed fell!"); } } @@ -91,8 +90,8 @@ SINGLE_BATTLE_TEST("Clear Amulet prevents Sticky Syrup speed reduction") ANIMATION(ANIM_TYPE_MOVE, MOVE_SYRUP_BOMB, player); HP_BAR(opponent); MESSAGE("Foe Wobbuffet got covered in sticky syrup!"); - MESSAGE("Foe Wobbuffet's Speed was not lowered!"); NOT ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); NOT MESSAGE("Foe Wobbuffet's Speed fell!"); + MESSAGE("Foe Wobbuffet's Speed was not lowered!"); } }