Skip to content

Commit

Permalink
Stuff Cheeks cleanup (#3950)
Browse files Browse the repository at this point in the history
Co-authored-by: Biffalo XIII <--global>
  • Loading branch information
AsparagusEduardo authored Jan 9, 2024
1 parent d73c9b0 commit 0d75ccd
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 21 deletions.
41 changes: 22 additions & 19 deletions src/battle_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -1409,7 +1409,7 @@ u32 TrySetCantSelectMoveBattleScript(u32 battler)
}
}

if (DYNAMAX_BYPASS_CHECK && move == MOVE_STUFF_CHEEKS && ItemId_GetPocket(gBattleMons[battler].item) != POCKET_BERRIES)
if (DYNAMAX_BYPASS_CHECK && gBattleMoves[move].effect == EFFECT_STUFF_CHEEKS && ItemId_GetPocket(gBattleMons[battler].item) != POCKET_BERRIES)
{
gCurrentMove = move;
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
Expand Down Expand Up @@ -1456,7 +1456,7 @@ u32 TrySetCantSelectMoveBattleScript(u32 battler)
limitations++;
}
}
else if (holdEffect == HOLD_EFFECT_ASSAULT_VEST && IS_MOVE_STATUS(move) && move != MOVE_ME_FIRST)
else if (holdEffect == HOLD_EFFECT_ASSAULT_VEST && IS_MOVE_STATUS(move) && gBattleMoves[move].effect != EFFECT_ME_FIRST)
{
if (IsDynamaxed(gBattlerAttacker))
gCurrentMove = MOVE_MAX_GUARD;
Expand Down Expand Up @@ -1523,64 +1523,67 @@ u32 TrySetCantSelectMoveBattleScript(u32 battler)

u8 CheckMoveLimitations(u32 battler, u8 unusableMoves, u16 check)
{
u8 holdEffect = GetBattlerHoldEffect(battler, TRUE);
u32 move, moveEffect;
u32 holdEffect = GetBattlerHoldEffect(battler, TRUE);
u16 *choicedMove = &gBattleStruct->choicedMove[battler];
s32 i;

gPotentialItemEffectBattler = battler;

for (i = 0; i < MAX_MON_MOVES; i++)
{
move = gBattleMons[battler].moves[i];
moveEffect = gBattleMoves[move].effect;
// No move
if (check & MOVE_LIMITATION_ZEROMOVE && gBattleMons[battler].moves[i] == MOVE_NONE)
if (check & MOVE_LIMITATION_ZEROMOVE && move == MOVE_NONE)
unusableMoves |= gBitTable[i];
// No PP
else if (check & MOVE_LIMITATION_PP && gBattleMons[battler].pp[i] == 0)
unusableMoves |= gBitTable[i];
// Placeholder
else if (check & MOVE_LIMITATION_PLACEHOLDER && gBattleMoves[gBattleMons[battler].moves[i]].effect == EFFECT_PLACEHOLDER)
else if (check & MOVE_LIMITATION_PLACEHOLDER && moveEffect == EFFECT_PLACEHOLDER)
unusableMoves |= gBitTable[i];
// Disable
else if (check & MOVE_LIMITATION_DISABLED && gBattleMons[battler].moves[i] == gDisableStructs[battler].disabledMove)
else if (check & MOVE_LIMITATION_DISABLED && move == gDisableStructs[battler].disabledMove)
unusableMoves |= gBitTable[i];
// Torment
else if (check & MOVE_LIMITATION_TORMENTED && gBattleMons[battler].moves[i] == gLastMoves[battler] && gBattleMons[battler].status2 & STATUS2_TORMENT)
else if (check & MOVE_LIMITATION_TORMENTED && move == gLastMoves[battler] && gBattleMons[battler].status2 & STATUS2_TORMENT)
unusableMoves |= gBitTable[i];
// Taunt
else if (check & MOVE_LIMITATION_TAUNT && gDisableStructs[battler].tauntTimer && IS_MOVE_STATUS(gBattleMons[battler].moves[i]))
else if (check & MOVE_LIMITATION_TAUNT && gDisableStructs[battler].tauntTimer && IS_MOVE_STATUS(move))
unusableMoves |= gBitTable[i];
// Imprison
else if (check & MOVE_LIMITATION_IMPRISON && GetImprisonedMovesCount(battler, gBattleMons[battler].moves[i]))
else if (check & MOVE_LIMITATION_IMPRISON && GetImprisonedMovesCount(battler, move))
unusableMoves |= gBitTable[i];
// Encore
else if (check & MOVE_LIMITATION_ENCORE && gDisableStructs[battler].encoreTimer && gDisableStructs[battler].encoredMove != gBattleMons[battler].moves[i])
else if (check & MOVE_LIMITATION_ENCORE && gDisableStructs[battler].encoreTimer && gDisableStructs[battler].encoredMove != move)
unusableMoves |= gBitTable[i];
// Choice Items
else if (check & MOVE_LIMITATION_CHOICE_ITEM && HOLD_EFFECT_CHOICE(holdEffect) && *choicedMove != MOVE_NONE && *choicedMove != MOVE_UNAVAILABLE && *choicedMove != gBattleMons[battler].moves[i])
else if (check & MOVE_LIMITATION_CHOICE_ITEM && HOLD_EFFECT_CHOICE(holdEffect) && *choicedMove != MOVE_NONE && *choicedMove != MOVE_UNAVAILABLE && *choicedMove != move)
unusableMoves |= gBitTable[i];
// Assault Vest
else if (check & MOVE_LIMITATION_ASSAULT_VEST && holdEffect == HOLD_EFFECT_ASSAULT_VEST && IS_MOVE_STATUS(gBattleMons[battler].moves[i]) && gBattleMons[battler].moves[i] != MOVE_ME_FIRST)
else if (check & MOVE_LIMITATION_ASSAULT_VEST && holdEffect == HOLD_EFFECT_ASSAULT_VEST && IS_MOVE_STATUS(move) && gBattleMoves[move].effect != EFFECT_ME_FIRST)
unusableMoves |= gBitTable[i];
// Gravity
else if (check & MOVE_LIMITATION_GRAVITY && IsGravityPreventingMove(gBattleMons[battler].moves[i]))
else if (check & MOVE_LIMITATION_GRAVITY && IsGravityPreventingMove(move))
unusableMoves |= gBitTable[i];
// Heal Block
else if (check & MOVE_LIMITATION_HEAL_BLOCK && IsHealBlockPreventingMove(battler, gBattleMons[battler].moves[i]))
else if (check & MOVE_LIMITATION_HEAL_BLOCK && IsHealBlockPreventingMove(battler, move))
unusableMoves |= gBitTable[i];
// Belch
else if (check & MOVE_LIMITATION_BELCH && IsBelchPreventingMove(battler, gBattleMons[battler].moves[i]))
else if (check & MOVE_LIMITATION_BELCH && IsBelchPreventingMove(battler, move))
unusableMoves |= gBitTable[i];
// Throat Chop
else if (check & MOVE_LIMITATION_THROAT_CHOP && gDisableStructs[battler].throatChopTimer && gBattleMoves[gBattleMons[battler].moves[i]].soundMove)
else if (check & MOVE_LIMITATION_THROAT_CHOP && gDisableStructs[battler].throatChopTimer && gBattleMoves[move].soundMove)
unusableMoves |= gBitTable[i];
// Stuff Cheeks
else if (check & MOVE_LIMITATION_STUFF_CHEEKS && gBattleMons[battler].moves[i] == MOVE_STUFF_CHEEKS && ItemId_GetPocket(gBattleMons[battler].item) != POCKET_BERRIES)
else if (check & MOVE_LIMITATION_STUFF_CHEEKS && moveEffect == EFFECT_STUFF_CHEEKS && ItemId_GetPocket(gBattleMons[battler].item) != POCKET_BERRIES)
unusableMoves |= gBitTable[i];
// Gorilla Tactics
else if (check & MOVE_LIMITATION_CHOICE_ITEM && GetBattlerAbility(battler) == ABILITY_GORILLA_TACTICS && *choicedMove != MOVE_NONE && *choicedMove != MOVE_UNAVAILABLE && *choicedMove != gBattleMons[battler].moves[i])
else if (check & MOVE_LIMITATION_CHOICE_ITEM && GetBattlerAbility(battler) == ABILITY_GORILLA_TACTICS && *choicedMove != MOVE_NONE && *choicedMove != MOVE_UNAVAILABLE && *choicedMove != move)
unusableMoves |= gBitTable[i];
// Can't Use Twice flag
else if (check & MOVE_LIMITATION_CANT_USE_TWICE && gBattleMoves[gBattleMons[battler].moves[i]].cantUseTwice && gBattleMons[battler].moves[i] == gLastResultingMoves[battler])
else if (check & MOVE_LIMITATION_CANT_USE_TWICE && gBattleMoves[move].cantUseTwice && move == gLastResultingMoves[battler])
unusableMoves |= gBitTable[i];
}
return unusableMoves;
Expand Down
106 changes: 106 additions & 0 deletions test/battle/move_effect/stuff_cheeks.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
#include "global.h"
#include "test/battle.h"

ASSUMPTIONS
{
ASSUME(gBattleMoves[MOVE_STUFF_CHEEKS].effect == EFFECT_STUFF_CHEEKS);
ASSUME(gItems[ITEM_LIECHI_BERRY].pocket == POCKET_BERRIES);
ASSUME(gItems[ITEM_LIECHI_BERRY].holdEffect == HOLD_EFFECT_ATTACK_UP);
}

SINGLE_BATTLE_TEST("Stuff Cheeks cannot be used if the user doesn't hold a berry")
{
u16 item = 0;
PARAMETRIZE { item = ITEM_NONE; }
PARAMETRIZE { item = ITEM_LIECHI_BERRY; }
GIVEN {
PLAYER(SPECIES_SKWOVET) { Item(item); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
if (item == ITEM_NONE)
TURN { MOVE(player, MOVE_STUFF_CHEEKS, allowed: FALSE); MOVE(player, MOVE_CELEBRATE); }
else
TURN { MOVE(player, MOVE_STUFF_CHEEKS); }
} SCENE {
if (item == ITEM_NONE)
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player);
else
ANIMATION(ANIM_TYPE_MOVE, MOVE_STUFF_CHEEKS, player);
}
}

SINGLE_BATTLE_TEST("Stuff Cheeks forces Struggle if it's the only move is blocked")
{
GIVEN {
PLAYER(SPECIES_SKWOVET) { Moves(MOVE_STUFF_CHEEKS); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_STUFF_CHEEKS, allowed: FALSE); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_STRUGGLE, player);
}
}

SINGLE_BATTLE_TEST("Stuff Cheeks raises Defense by 2 stages after consuming the berry and gaining its effect")
{
GIVEN {
PLAYER(SPECIES_SKWOVET) { Item(ITEM_LIECHI_BERRY); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_STUFF_CHEEKS); }
} SCENE {
MESSAGE("Skwovet used Stuff Cheeks!");
ANIMATION(ANIM_TYPE_MOVE, MOVE_STUFF_CHEEKS, player);
MESSAGE("Using Liechi Berry, the Attack of Skwovet rose!");
MESSAGE("Skwovet's Defense sharply rose!");
} THEN {
EXPECT_EQ(player->statStages[STAT_DEF], DEFAULT_STAT_STAGE + 2);
EXPECT_EQ(player->item, ITEM_NONE);
}
}

SINGLE_BATTLE_TEST("Stuff Cheeks can be used even if Unnerve is present")
{
GIVEN {
PLAYER(SPECIES_SKWOVET) { Item(ITEM_LIECHI_BERRY); }
OPPONENT(SPECIES_EKANS) { Ability(ABILITY_UNNERVE); }
} WHEN {
TURN { MOVE(player, MOVE_STUFF_CHEEKS); }
} SCENE {
MESSAGE("Skwovet used Stuff Cheeks!");
ANIMATION(ANIM_TYPE_MOVE, MOVE_STUFF_CHEEKS, player);
}
}

SINGLE_BATTLE_TEST("Stuff Cheeks can be used even if Magic Room is active")
{
GIVEN {
PLAYER(SPECIES_SKWOVET) { Item(ITEM_LIECHI_BERRY); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN {
MOVE(opponent, MOVE_MAGIC_ROOM);
MOVE(player, MOVE_STUFF_CHEEKS);
}
} SCENE {
MESSAGE("Skwovet used Stuff Cheeks!");
ANIMATION(ANIM_TYPE_MOVE, MOVE_STUFF_CHEEKS, player);
MESSAGE("Using Liechi Berry, the Attack of Skwovet rose!");
}
}

SINGLE_BATTLE_TEST("Stuff Cheeks fails if the user's berry is removed before they use the move")
{
GIVEN {
ASSUME(gBattleMoves[MOVE_KNOCK_OFF].effect == EFFECT_KNOCK_OFF);
PLAYER(SPECIES_SKWOVET) { Item(ITEM_LIECHI_BERRY); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(opponent, MOVE_KNOCK_OFF); MOVE(player, MOVE_STUFF_CHEEKS); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_KNOCK_OFF, opponent);
MESSAGE("Skwovet used Stuff Cheeks!");
MESSAGE("But it failed!");
}
}

4 changes: 2 additions & 2 deletions test/battle/move_effect/teatime.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,14 @@ SINGLE_BATTLE_TEST("Teatime causes the user to consume its Berry, even in the pr
}
}

SINGLE_BATTLE_TEST("Teatime causes the user to consume its Berry, even under the effects of Wonder Room")
SINGLE_BATTLE_TEST("Teatime causes the user to consume its Berry, even under the effects of Magic Room")
{
GIVEN {
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_LIECHI_BERRY); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN {
MOVE(opponent, MOVE_WONDER_ROOM);
MOVE(opponent, MOVE_MAGIC_ROOM);
MOVE(player, MOVE_TEATIME);
}
} SCENE {
Expand Down

0 comments on commit 0d75ccd

Please sign in to comment.