From ee584217adfee4a3340dd24f5ba99ee22dd93f94 Mon Sep 17 00:00:00 2001 From: GGbond Date: Sun, 4 Jan 2026 00:08:06 +0800 Subject: [PATCH] Fix Cheek Pouch not activating for Bug Bite, Pluck, and Fling berry effects (#8782) --- src/battle_script_commands.c | 16 ++- test/battle/ability/cheek_pouch.c | 179 ++++++++++++++++++++++++++++-- 2 files changed, 181 insertions(+), 14 deletions(-) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 9dd71d4733..c9b6066547 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -8773,7 +8773,7 @@ static void Cmd_setgravity(void) } } -static bool32 TryCheekPouch(u32 battler, u32 itemId) +static bool32 TryCheekPouch(u32 battler, u32 itemId, const u8 *nextInstr) { if (GetItemPocket(itemId) == POCKET_BERRIES && GetBattlerAbility(battler) == ABILITY_CHEEK_POUCH @@ -8783,7 +8783,7 @@ static bool32 TryCheekPouch(u32 battler, u32 itemId) { gBattlerAbility = battler; SetHealAmount(battler, GetNonDynamaxMaxHP(battler) / 3); - BattleScriptPush(gBattlescriptCurrInstr + 2); + BattleScriptPush(nextInstr); gBattlescriptCurrInstr = BattleScript_CheekPouchActivates; return TRUE; } @@ -8863,7 +8863,7 @@ static void Cmd_removeitem(void) MarkBattlerForControllerExec(battler); ClearBattlerItemEffectHistory(battler); - if (!TryCheekPouch(battler, itemId) && !TrySymbiosis(battler, itemId, FALSE)) + if (!TryCheekPouch(battler, itemId, cmd->nextInstr) && !TrySymbiosis(battler, itemId, FALSE)) gBattlescriptCurrInstr = cmd->nextInstr; } @@ -17894,7 +17894,15 @@ void BS_ConsumeBerry(void) if (cmd->fromBattler) gLastUsedItem = gBattleMons[battler].item; - if (GetItemPocket(gLastUsedItem) != POCKET_BERRIES || gBattleScripting.overrideBerryRequirements == 2) + if (gBattleScripting.overrideBerryRequirements == 2) + { + gBattleScripting.overrideBerryRequirements = 0; + if (!cmd->fromBattler && TryCheekPouch(battler, gLastUsedItem, cmd->nextInstr)) + return; + gBattlescriptCurrInstr = cmd->nextInstr; + return; + } + if (GetItemPocket(gLastUsedItem) != POCKET_BERRIES) { gBattleScripting.overrideBerryRequirements = 0; gBattlescriptCurrInstr = cmd->nextInstr; diff --git a/test/battle/ability/cheek_pouch.c b/test/battle/ability/cheek_pouch.c index ffd1c8416e..0e52ca3fe3 100644 --- a/test/battle/ability/cheek_pouch.c +++ b/test/battle/ability/cheek_pouch.c @@ -1,19 +1,178 @@ #include "global.h" #include "test/battle.h" -TO_DO_BATTLE_TEST("Cheek Pouch restores 33% max HP") -TO_DO_BATTLE_TEST("Cheek Pouch restores HP after the berry's effect") -TO_DO_BATTLE_TEST("Cheek Pouch activates via Bug Bite/Pluck if it would trigger an effect") -TO_DO_BATTLE_TEST("Cheek Pouch activates when receiving from Fling if it would trigger an effect") -TO_DO_BATTLE_TEST("Cheek Pouch doesn't activate when using Natural Gift") -TO_DO_BATTLE_TEST("Cheek Pouch doesn't activate when using Fling") -TO_DO_BATTLE_TEST("Cheek Pouch doesn't activate when using a berry from the bag") -TO_DO_BATTLE_TEST("Cheek Pouch doesn't activate under Heal Block's effect") +SINGLE_BATTLE_TEST("Cheek Pouch restores 33% max HP") +{ + s16 berryHeal, cheekPouchHeal; + + GIVEN { + ASSUME(GetMoveEffect(MOVE_SUPER_FANG) == EFFECT_FIXED_PERCENT_DAMAGE); + ASSUME(gItemsInfo[ITEM_ORAN_BERRY].holdEffect == HOLD_EFFECT_RESTORE_HP); + ASSUME(gItemsInfo[ITEM_ORAN_BERRY].holdEffectParam == 10); + PLAYER(SPECIES_GREEDENT) { Ability(ABILITY_CHEEK_POUCH); MaxHP(60); HP(31); Item(ITEM_ORAN_BERRY); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_SUPER_FANG); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SUPER_FANG, opponent); + HP_BAR(player); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player); + HP_BAR(player, captureDamage: &berryHeal); + ABILITY_POPUP(player, ABILITY_CHEEK_POUCH); + HP_BAR(player, captureDamage: &cheekPouchHeal); + } THEN { + EXPECT_LT(berryHeal, 0); + EXPECT_EQ(cheekPouchHeal, -(player->maxHP / 3)); + } +} + +SINGLE_BATTLE_TEST("Cheek Pouch restores HP after the berry's effect") +{ + u16 hpAfterBerry, hpAfterCheekPouch; + + GIVEN { + ASSUME(GetMoveEffect(MOVE_SUPER_FANG) == EFFECT_FIXED_PERCENT_DAMAGE); + ASSUME(gItemsInfo[ITEM_ORAN_BERRY].holdEffect == HOLD_EFFECT_RESTORE_HP); + ASSUME(gItemsInfo[ITEM_ORAN_BERRY].holdEffectParam == 10); + PLAYER(SPECIES_GREEDENT) { Ability(ABILITY_CHEEK_POUCH); MaxHP(60); HP(31); Item(ITEM_ORAN_BERRY); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_SUPER_FANG); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SUPER_FANG, opponent); + HP_BAR(player); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player); + HP_BAR(player, captureHP: &hpAfterBerry); + ABILITY_POPUP(player, ABILITY_CHEEK_POUCH); + HP_BAR(player, captureHP: &hpAfterCheekPouch); + } THEN { + EXPECT_GT(hpAfterCheekPouch, hpAfterBerry); + } +} + +SINGLE_BATTLE_TEST("Cheek Pouch activates via Bug Bite/Pluck if it would trigger an effect") +{ + u16 move; + s16 berryHeal, cheekPouchHeal; + + PARAMETRIZE { move = MOVE_BUG_BITE; } + PARAMETRIZE { move = MOVE_PLUCK; } + + GIVEN { + ASSUME(MoveHasAdditionalEffect(move, MOVE_EFFECT_BUG_BITE)); + ASSUME(gItemsInfo[ITEM_ORAN_BERRY].holdEffect == HOLD_EFFECT_RESTORE_HP); + ASSUME(gItemsInfo[ITEM_ORAN_BERRY].holdEffectParam == 10); + PLAYER(SPECIES_GREEDENT) { Ability(ABILITY_CHEEK_POUCH); MaxHP(60); HP(30); } + OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_ORAN_BERRY); } + } WHEN { + TURN { MOVE(player, move); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, move, player); + HP_BAR(opponent); + HP_BAR(player, captureDamage: &berryHeal); + ABILITY_POPUP(player, ABILITY_CHEEK_POUCH); + HP_BAR(player, captureDamage: &cheekPouchHeal); + } THEN { + EXPECT_LT(berryHeal, 0); + EXPECT_EQ(cheekPouchHeal, -(player->maxHP / 3)); + EXPECT_EQ(opponent->item, ITEM_NONE); + } +} + +SINGLE_BATTLE_TEST("Cheek Pouch activates when receiving from Fling if it would trigger an effect") +{ + s16 berryHeal, cheekPouchHeal; + + GIVEN { + ASSUME(GetMoveEffect(MOVE_FLING) == EFFECT_FLING); + ASSUME(gItemsInfo[ITEM_ORAN_BERRY].holdEffect == HOLD_EFFECT_RESTORE_HP); + ASSUME(gItemsInfo[ITEM_ORAN_BERRY].holdEffectParam == 10); + PLAYER(SPECIES_WOBBUFFET) { Attack(1); Item(ITEM_ORAN_BERRY); } + OPPONENT(SPECIES_GREEDENT) { Ability(ABILITY_CHEEK_POUCH); MaxHP(60); HP(30); } + } WHEN { + TURN { MOVE(player, MOVE_FLING); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_FLING, player); + HP_BAR(opponent); + HP_BAR(opponent, captureDamage: &berryHeal); + ABILITY_POPUP(opponent, ABILITY_CHEEK_POUCH); + HP_BAR(opponent, captureDamage: &cheekPouchHeal); + } THEN { + EXPECT_LT(berryHeal, 0); + EXPECT_EQ(cheekPouchHeal, -(opponent->maxHP / 3)); + EXPECT_EQ(player->item, ITEM_NONE); + } +} + +SINGLE_BATTLE_TEST("Cheek Pouch doesn't activate when using Natural Gift") +{ + GIVEN { + ASSUME(GetMoveEffect(MOVE_NATURAL_GIFT) == EFFECT_NATURAL_GIFT); + PLAYER(SPECIES_GREEDENT) { Ability(ABILITY_CHEEK_POUCH); MaxHP(60); HP(40); Item(ITEM_ORAN_BERRY); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_NATURAL_GIFT); } + } SCENE { + NOT ABILITY_POPUP(player, ABILITY_CHEEK_POUCH); + } THEN { + EXPECT_EQ(player->item, ITEM_NONE); + } +} + +SINGLE_BATTLE_TEST("Cheek Pouch doesn't activate when using Fling") +{ + GIVEN { + ASSUME(GetMoveEffect(MOVE_FLING) == EFFECT_FLING); + PLAYER(SPECIES_GREEDENT) { Ability(ABILITY_CHEEK_POUCH); MaxHP(60); HP(40); Item(ITEM_ORAN_BERRY); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_FLING); } + } SCENE { + NOT ABILITY_POPUP(player, ABILITY_CHEEK_POUCH); + } THEN { + EXPECT_EQ(player->item, ITEM_NONE); + } +} + +SINGLE_BATTLE_TEST("Cheek Pouch doesn't activate when using a berry from the bag") +{ + GIVEN { + ASSUME(gItemsInfo[ITEM_ORAN_BERRY].holdEffect == HOLD_EFFECT_RESTORE_HP); + ASSUME(gItemsInfo[ITEM_ORAN_BERRY].holdEffectParam == 10); + PLAYER(SPECIES_GREEDENT) { Ability(ABILITY_CHEEK_POUCH); MaxHP(60); HP(20); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { USE_ITEM(player, ITEM_ORAN_BERRY, partyIndex: 0); } + } SCENE { + NOT ABILITY_POPUP(player, ABILITY_CHEEK_POUCH); + } +} + +SINGLE_BATTLE_TEST("Cheek Pouch doesn't activate under Heal Block's effect") +{ + GIVEN { + ASSUME(GetMoveEffect(MOVE_HEAL_BLOCK) == EFFECT_HEAL_BLOCK); + ASSUME(GetMoveEffect(MOVE_SUPER_FANG) == EFFECT_FIXED_PERCENT_DAMAGE); + ASSUME(gItemsInfo[ITEM_ORAN_BERRY].holdEffect == HOLD_EFFECT_RESTORE_HP); + ASSUME(gItemsInfo[ITEM_ORAN_BERRY].holdEffectParam == 10); + PLAYER(SPECIES_GREEDENT) { Ability(ABILITY_CHEEK_POUCH); MaxHP(60); HP(31); Item(ITEM_ORAN_BERRY); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_HEAL_BLOCK); } + TURN { MOVE(opponent, MOVE_SUPER_FANG); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_HEAL_BLOCK, opponent); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SUPER_FANG, opponent); + HP_BAR(player); + NOT ABILITY_POPUP(player, ABILITY_CHEEK_POUCH); + } THEN { + EXPECT_EQ(player->item, ITEM_ORAN_BERRY); + } +} SINGLE_BATTLE_TEST("Cheek Pouch activation doesn't mutate damage when restoring HP mid battle") { - s16 damage; - s16 healing; + s16 damage, healing; GIVEN { PLAYER(SPECIES_GREEDENT) { Ability(ABILITY_CHEEK_POUCH); Item(ITEM_CHOPLE_BERRY); HP(100); }