diff --git a/src/battle_hold_effects.c b/src/battle_hold_effects.c index 9f363ea120..27b6f0247b 100644 --- a/src/battle_hold_effects.c +++ b/src/battle_hold_effects.c @@ -891,43 +891,66 @@ static u32 ItemRestorePp(u32 battler, u32 itemId, ActivationTiming timing) { enum ItemEffect effect = ITEM_NO_EFFECT; struct Pokemon *mon = GetBattlerMon(battler); - u32 i, changedPP = 0; + u32 changedPP = 0; + u32 restoreMove = MAX_MON_MOVES; + u32 missingMove = MAX_MON_MOVES; + u32 ppBonuses = GetMonData(mon, MON_DATA_PP_BONUSES); + bool32 override = gBattleScripting.overrideBerryRequirements; enum Ability ability = GetBattlerAbility(battler); - for (i = 0; i < MAX_MON_MOVES; i++) + for (u32 i = 0; i < MAX_MON_MOVES; i++) { u32 move = GetMonData(mon, MON_DATA_MOVE1 + i); u32 currentPP = GetMonData(mon, MON_DATA_PP1 + i); - u32 ppBonuses = GetMonData(mon, MON_DATA_PP_BONUSES); - u32 maxPP = CalculatePPWithBonus(move, ppBonuses, i); - if (move && (currentPP == 0 || (gBattleScripting.overrideBerryRequirements && currentPP != maxPP))) + if (move == MOVE_NONE) + continue; + + if (currentPP == 0) { - u32 ppRestored = GetItemHoldEffectParam(itemId); - - if (ability == ABILITY_RIPEN) - { - ppRestored *= 2; - gBattlerAbility = battler; - } - if (currentPP + ppRestored > maxPP) - changedPP = maxPP; - else - changedPP = currentPP + ppRestored; - - PREPARE_MOVE_BUFFER(gBattleTextBuff1, move); - - if (timing == IsOnSwitchInFirstTurnActivation) - BattleScriptExecute(BattleScript_BerryPPHealEnd2); - else - BattleScriptCall(BattleScript_BerryPPHealRet); - - gBattleScripting.battler = battler; - BtlController_EmitSetMonData(battler, B_COMM_TO_CONTROLLER, i + REQUEST_PPMOVE1_BATTLE, 0, 1, &changedPP); - MarkBattlerForControllerExec(battler); - if (MOVE_IS_PERMANENT(battler, i)) - gBattleMons[battler].pp[i] = changedPP; - effect = ITEM_PP_CHANGE; + restoreMove = i; + break; } + + if (override && missingMove == MAX_MON_MOVES) + { + u32 maxPP = CalculatePPWithBonus(move, ppBonuses, i); + if (currentPP < maxPP) + missingMove = i; + } + } + + if (restoreMove == MAX_MON_MOVES && override) + restoreMove = missingMove; + + if (restoreMove != MAX_MON_MOVES) + { + u32 move = GetMonData(mon, MON_DATA_MOVE1 + restoreMove); + u32 currentPP = GetMonData(mon, MON_DATA_PP1 + restoreMove); + u32 maxPP = CalculatePPWithBonus(move, ppBonuses, restoreMove); + u32 ppRestored = GetItemHoldEffectParam(itemId); + + if (ability == ABILITY_RIPEN) + { + ppRestored *= 2; + gBattlerAbility = battler; + } + changedPP = currentPP + ppRestored; + if (changedPP > maxPP) + changedPP = maxPP; + + PREPARE_MOVE_BUFFER(gBattleTextBuff1, move); + + if (timing == IsOnSwitchInFirstTurnActivation) + BattleScriptExecute(BattleScript_BerryPPHealEnd2); + else + BattleScriptCall(BattleScript_BerryPPHealRet); + + gBattleScripting.battler = battler; + BtlController_EmitSetMonData(battler, B_COMM_TO_CONTROLLER, restoreMove + REQUEST_PPMOVE1_BATTLE, 0, 1, &changedPP); + MarkBattlerForControllerExec(battler); + if (MOVE_IS_PERMANENT(battler, restoreMove)) + gBattleMons[battler].pp[restoreMove] = changedPP; + effect = ITEM_PP_CHANGE; } return effect; } diff --git a/test/battle/hold_effect/restore_pp.c b/test/battle/hold_effect/restore_pp.c index c3810652a4..8b3ae83141 100644 --- a/test/battle/hold_effect/restore_pp.c +++ b/test/battle/hold_effect/restore_pp.c @@ -21,3 +21,31 @@ SINGLE_BATTLE_TEST("Restore PP berry activates immediately on switch in") EXPECT(player->item == ITEM_NONE); } } + +SINGLE_BATTLE_TEST("Forced Leppa Berry consumption restores a move at 0 PP before other missing PP") +{ + GIVEN { + ASSUME(GetMoveEffect(MOVE_FLING) == EFFECT_FLING); + PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_LEPPA_BERRY); Moves(MOVE_FLING); } + OPPONENT(SPECIES_WYNAUT) { MovesWithPP({MOVE_SCRATCH, 6}, {MOVE_CELEBRATE, 0}, {MOVE_POUND, 35}); } + } WHEN { + TURN { MOVE(player, MOVE_FLING); MOVE(opponent, MOVE_POUND); } + } THEN { + EXPECT_EQ(opponent->pp[0], 6); + EXPECT_EQ(opponent->pp[1], 10); + } +} + +SINGLE_BATTLE_TEST("Forced Leppa Berry consumption restores the first move found missing PP when none are at 0") +{ + GIVEN { + ASSUME(GetMoveEffect(MOVE_FLING) == EFFECT_FLING); + PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_LEPPA_BERRY); Moves(MOVE_FLING); } + OPPONENT(SPECIES_WYNAUT) { MovesWithPP({MOVE_SCRATCH, 6}, {MOVE_CELEBRATE, 6}, {MOVE_POUND, 35}); } + } WHEN { + TURN { MOVE(player, MOVE_FLING); MOVE(opponent, MOVE_POUND); } + } THEN { + EXPECT_EQ(opponent->pp[0], 16); + EXPECT_EQ(opponent->pp[1], 6); + } +}