Skip to content

Commit

Permalink
Small Ability Effect Move Block refactor (#4635)
Browse files Browse the repository at this point in the history
* Small Ability Effect Move Block refactor

* combine tests
  • Loading branch information
AlexOn1ine authored May 28, 2024
1 parent e0499f8 commit 0570609
Show file tree
Hide file tree
Showing 4 changed files with 174 additions and 22 deletions.
2 changes: 1 addition & 1 deletion data/battle_scripts_1.s
Original file line number Diff line number Diff line change
Expand Up @@ -8215,7 +8215,7 @@ BattleScript_DazzlingProtected::
attackstring
ppreduce
pause B_WAIT_TIME_SHORT
call BattleScript_AbilityPopUp
call BattleScript_AbilityPopUpScripting
printstring STRINGID_POKEMONCANNOTUSEMOVE
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd
Expand Down
72 changes: 51 additions & 21 deletions src/battle_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -4977,46 +4977,76 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
case ABILITYEFFECT_MOVES_BLOCK: // 2
{
u16 moveTarget = GetBattlerMoveTargetType(battler, move);
u16 battlerAbility = GetBattlerAbility(battler);
u16 targetAbility = GetBattlerAbility(gBattlerTarget);

if ((gLastUsedAbility == ABILITY_SOUNDPROOF && gMovesInfo[move].soundMove && !(moveTarget & MOVE_TARGET_USER))
|| (gLastUsedAbility == ABILITY_BULLETPROOF && gMovesInfo[move].ballisticMove))
switch (gLastUsedAbility)
{
case ABILITY_SOUNDPROOF:
if (gMovesInfo[move].soundMove && !(moveTarget & MOVE_TARGET_USER))
effect = 1;
break;
case ABILITY_BULLETPROOF:
if (gMovesInfo[move].ballisticMove)
effect = 1;
break;
case ABILITY_DAZZLING:
case ABILITY_QUEENLY_MAJESTY:
case ABILITY_ARMOR_TAIL:
if (GetChosenMovePriority(gBattlerAttacker) > 0 && GetBattlerSide(gBattlerAttacker) != GetBattlerSide(battler))
effect = 2;
break;
case ABILITY_GOOD_AS_GOLD:
if (IS_MOVE_STATUS(gCurrentMove)
&& !(moveTarget & MOVE_TARGET_USER)
&& !(moveTarget & MOVE_TARGET_OPPONENTS_FIELD)
&& !(moveTarget & MOVE_TARGET_ALL_BATTLERS))
effect = 3;
break;
}

if (!effect)
{
switch (GetBattlerAbility(BATTLE_PARTNER(battler)))
{
case ABILITY_DAZZLING:
case ABILITY_QUEENLY_MAJESTY:
case ABILITY_ARMOR_TAIL:
if (GetChosenMovePriority(gBattlerAttacker) > 0 && GetBattlerSide(gBattlerAttacker) != GetBattlerSide(battler))
effect = 4;
break;
}
}

if (effect == 1)
{
if (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS)
gHitMarker |= HITMARKER_NO_PPDEDUCT;
gBattlescriptCurrInstr = BattleScript_SoundproofProtected;
effect = 1;
}
else if ((gLastUsedAbility == ABILITY_DAZZLING || gLastUsedAbility == ABILITY_QUEENLY_MAJESTY || gLastUsedAbility == ABILITY_ARMOR_TAIL || IsBattlerAlive(battler ^= BIT_FLANK))
&& (battlerAbility == ABILITY_DAZZLING || battlerAbility == ABILITY_QUEENLY_MAJESTY || battlerAbility == ABILITY_ARMOR_TAIL)
&& GetChosenMovePriority(gBattlerAttacker) > 0
&& GetBattlerSide(gBattlerAttacker) != GetBattlerSide(battler))
else if (effect == 2 || effect == 4)
{
if (effect == 4)
gBattleScripting.battler = BATTLE_PARTNER(battler);
else
gBattleScripting.battler = battler;

if (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS)
gHitMarker |= HITMARKER_NO_PPDEDUCT;
gBattlescriptCurrInstr = BattleScript_DazzlingProtected;
effect = 1;
}
else if (effect == 3)
{
gBattlescriptCurrInstr = BattleScript_GoodAsGoldActivates;
}
else if (GetChosenMovePriority(gBattlerAttacker) > 0
&& BlocksPrankster(move, gBattlerAttacker, gBattlerTarget, TRUE)
&& !(IS_MOVE_STATUS(move) && (targetAbility == ABILITY_MAGIC_BOUNCE || gProtectStructs[gBattlerTarget].bounceMove)))
&& BlocksPrankster(move, gBattlerAttacker, gBattlerTarget, TRUE)
&& !(IS_MOVE_STATUS(move) && (gLastUsedAbility == ABILITY_MAGIC_BOUNCE || gProtectStructs[gBattlerTarget].bounceMove)))
{
if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE) || !(moveTarget & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY)))
CancelMultiTurnMoves(gBattlerAttacker); // Don't cancel moves that can hit two targets bc one target might not be protected
gBattleScripting.battler = gBattlerAbility = gBattlerTarget;
gBattlescriptCurrInstr = BattleScript_DarkTypePreventsPrankster;
effect = 1;
}
else if (GetBattlerAbility(gBattlerTarget) == ABILITY_GOOD_AS_GOLD
&& IS_MOVE_STATUS(gCurrentMove)
&& !(moveTarget & MOVE_TARGET_USER)
&& !(moveTarget & MOVE_TARGET_OPPONENTS_FIELD)
&& !(moveTarget & MOVE_TARGET_ALL_BATTLERS))
{
gBattlescriptCurrInstr = BattleScript_GoodAsGoldActivates;
effect = 1;
}
break;
}
case ABILITYEFFECT_ABSORBING: // 3
Expand Down
52 changes: 52 additions & 0 deletions test/battle/ability/dazzling.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#include "global.h"
#include "test/battle.h"


ASSUMPTIONS
{
ASSUME(gMovesInfo[MOVE_QUICK_ATTACK].priority > 0);
}

DOUBLE_BATTLE_TEST("Dazzling, Queenly Majesty and Armor Tail protect the user from priority moves")
{
u32 species, ability;

PARAMETRIZE { species = SPECIES_BRUXISH; ability = ABILITY_DAZZLING; }
PARAMETRIZE { species = SPECIES_FARIGIRAF; ability = ABILITY_ARMOR_TAIL; }
PARAMETRIZE { species = SPECIES_TSAREENA; ability = ABILITY_QUEENLY_MAJESTY; }

GIVEN {
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(species) { Ability(ability); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(playerLeft, MOVE_QUICK_ATTACK, target: opponentLeft); }
} SCENE {
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_QUICK_ATTACK, opponentRight);
ABILITY_POPUP(opponentLeft, ability);
MESSAGE("Wobbuffet cannot use Quick Attack!");
}
}

DOUBLE_BATTLE_TEST("Dazzling, Queenly Majesty and Armor Tail protect users partner from priority moves")
{
u32 species, ability;

PARAMETRIZE { species = SPECIES_BRUXISH; ability = ABILITY_DAZZLING; }
PARAMETRIZE { species = SPECIES_FARIGIRAF; ability = ABILITY_ARMOR_TAIL; }
PARAMETRIZE { species = SPECIES_TSAREENA; ability = ABILITY_QUEENLY_MAJESTY; }

GIVEN {
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(species) { Ability(ability); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(playerLeft, MOVE_QUICK_ATTACK, target: opponentRight); }
} SCENE {
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_QUICK_ATTACK, opponentRight);
ABILITY_POPUP(opponentLeft, ability);
MESSAGE("Wobbuffet cannot use Quick Attack!");
}
}
70 changes: 70 additions & 0 deletions test/battle/ability/good_as_gold.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#include "global.h"
#include "test/battle.h"


SINGLE_BATTLE_TEST("Good as Gold protects from status moves")
{
GIVEN {
ASSUME(gMovesInfo[MOVE_TOXIC].category == DAMAGE_CATEGORY_STATUS);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_GHOLDENGO) { Ability(ABILITY_GOOD_AS_GOLD); }
} WHEN {
TURN { MOVE(player, MOVE_TOXIC); }
} SCENE {
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_TOXIC, player);
ABILITY_POPUP(opponent, ABILITY_GOOD_AS_GOLD);
MESSAGE("It doesn't affect Foe Gholdengo…");
}
}

SINGLE_BATTLE_TEST("Good as Gold doesn't protect the user from it's own moves")
{
GIVEN {
ASSUME(gMovesInfo[MOVE_NASTY_PLOT].category == DAMAGE_CATEGORY_STATUS);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_GHOLDENGO) { Ability(ABILITY_GOOD_AS_GOLD); }
} WHEN {
TURN { MOVE(opponent, MOVE_NASTY_PLOT); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_NASTY_PLOT, opponent);
NONE_OF {
ABILITY_POPUP(opponent, ABILITY_GOOD_AS_GOLD);
MESSAGE("It doesn't affect Foe Gholdengo…");
}
}
}

SINGLE_BATTLE_TEST("Good as Gold doesn't protect from moves that target the field")
{
GIVEN {
ASSUME(gMovesInfo[MOVE_STEALTH_ROCK].category == DAMAGE_CATEGORY_STATUS);
ASSUME(gMovesInfo[MOVE_STEALTH_ROCK].target == MOVE_TARGET_OPPONENTS_FIELD);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_GHOLDENGO) { Ability(ABILITY_GOOD_AS_GOLD); }
} WHEN {
TURN { MOVE(player, MOVE_STEALTH_ROCK); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_STEALTH_ROCK, player);
NONE_OF {
ABILITY_POPUP(opponent, ABILITY_GOOD_AS_GOLD);
MESSAGE("It doesn't affect Foe Gholdengo…");
}
}
}

DOUBLE_BATTLE_TEST("Good as Gold protects from partner's status moves")
{
GIVEN {
ASSUME(gMovesInfo[MOVE_HELPING_HAND].category == DAMAGE_CATEGORY_STATUS);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_GHOLDENGO) { Ability(ABILITY_GOOD_AS_GOLD); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(opponentRight, MOVE_HELPING_HAND); }
} SCENE {
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_HELPING_HAND, opponentRight);
ABILITY_POPUP(opponentLeft, ABILITY_GOOD_AS_GOLD);
MESSAGE("It doesn't affect Foe Gholdengo…");
}
}

0 comments on commit 0570609

Please sign in to comment.