diff --git a/src/battle-scene.ts b/src/battle-scene.ts index f71a7e9f243..8a8e21f978f 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -2595,14 +2595,14 @@ export default class BattleScene extends SceneBase { if (target.isPlayer()) { this.addModifier(newItemModifier, ignoreUpdate, playSound, false, instant).then(() => { if (source) { - applyPostItemLostAbAttrs(PostItemLostAbAttr, source, source.hasPassive(), false, []); + applyPostItemLostAbAttrs(PostItemLostAbAttr, source, false); } resolve(true); }); } else { this.addEnemyModifier(newItemModifier, ignoreUpdate, instant).then(() => { if (source) { - applyPostItemLostAbAttrs(PostItemLostAbAttr, source, source.hasPassive(), false, []); + applyPostItemLostAbAttrs(PostItemLostAbAttr, source, false); } resolve(true); }); diff --git a/src/data/ability.ts b/src/data/ability.ts index e0cddc1ea34..08126fbae81 100644 --- a/src/data/ability.ts +++ b/src/data/ability.ts @@ -3849,7 +3849,7 @@ export class PostDancingMoveAbAttr extends PostMoveUsedAbAttr { * @extends AbAttr */ export class PostItemLostAbAttr extends AbAttr { - applyPostItemLost(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean | Promise { + applyPostItemLost(pokemon: Pokemon, simulated: boolean, args: any[]): boolean | Promise { return false; } } @@ -3867,11 +3867,10 @@ export class PostItemLostApplyBattlerTagAbAttr extends PostItemLostAbAttr { /** * Adds the last used Pokeball back into the player's inventory * @param pokemon {@linkcode Pokemon} with this ability - * @param passive N/A * @param args N/A * @returns true if BattlerTag was applied */ - applyPostItemLost(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean | Promise { + applyPostItemLost(pokemon: Pokemon, simulated: boolean, args: any[]): boolean | Promise { if (!pokemon.getTag(this.tagType) && !simulated) { pokemon.addTag(this.tagType); return true; @@ -5252,8 +5251,8 @@ export function applyPostFaintAbAttrs(attrType: Constructor, } export function applyPostItemLostAbAttrs(attrType: Constructor, - pokemon: Pokemon, passive: boolean, simulated: boolean = false, ...args: any[]): Promise { - return applyAbAttrsInternal(attrType, pokemon, (attr, passive) => attr.applyPostItemLost(pokemon, passive, simulated, args), args); + pokemon: Pokemon, simulated: boolean = false, ...args: any[]): Promise { + return applyAbAttrsInternal(attrType, pokemon, (attr, passive) => attr.applyPostItemLost(pokemon, simulated, args), args); } function queueShowAbility(pokemon: Pokemon, passive: boolean): void { diff --git a/src/data/berry.ts b/src/data/berry.ts index f14b3bb45f5..d2bbd0fdd1c 100644 --- a/src/data/berry.ts +++ b/src/data/berry.ts @@ -75,7 +75,7 @@ export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc { applyAbAttrs(DoubleBerryEffectAbAttr, pokemon, null, false, hpHealed); pokemon.scene.unshiftPhase(new PokemonHealPhase(pokemon.scene, pokemon.getBattlerIndex(), hpHealed.value, i18next.t("battle:hpHealBerry", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), berryName: getBerryName(berryType) }), true)); - applyPostItemLostAbAttrs(PostItemLostAbAttr, pokemon, pokemon.hasPassive(), false, []); + applyPostItemLostAbAttrs(PostItemLostAbAttr, pokemon, false); }; case BerryType.LUM: return (pokemon: Pokemon) => { @@ -87,7 +87,7 @@ export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc { } pokemon.resetStatus(true, true); pokemon.updateInfo(); - applyPostItemLostAbAttrs(PostItemLostAbAttr, pokemon, pokemon.hasPassive(), false, []); + applyPostItemLostAbAttrs(PostItemLostAbAttr, pokemon, false); }; case BerryType.LIECHI: case BerryType.GANLON: @@ -103,7 +103,7 @@ export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc { const statStages = new Utils.NumberHolder(1); applyAbAttrs(DoubleBerryEffectAbAttr, pokemon, null, false, statStages); pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ stat ], statStages.value)); - applyPostItemLostAbAttrs(PostItemLostAbAttr, pokemon, pokemon.hasPassive(), false, []); + applyPostItemLostAbAttrs(PostItemLostAbAttr, pokemon, false); }; case BerryType.LANSAT: return (pokemon: Pokemon) => { @@ -111,7 +111,7 @@ export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc { pokemon.battleData.berriesEaten.push(berryType); } pokemon.addTag(BattlerTagType.CRIT_BOOST); - applyPostItemLostAbAttrs(PostItemLostAbAttr, pokemon, pokemon.hasPassive(), false, []); + applyPostItemLostAbAttrs(PostItemLostAbAttr, pokemon, false); }; case BerryType.STARF: return (pokemon: Pokemon) => { @@ -122,7 +122,7 @@ export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc { const stages = new Utils.NumberHolder(2); applyAbAttrs(DoubleBerryEffectAbAttr, pokemon, null, false, stages); pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ randStat ], stages.value)); - applyPostItemLostAbAttrs(PostItemLostAbAttr, pokemon, pokemon.hasPassive(), false, []); + applyPostItemLostAbAttrs(PostItemLostAbAttr, pokemon, false); }; case BerryType.LEPPA: return (pokemon: Pokemon) => { @@ -133,7 +133,7 @@ export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc { if (ppRestoreMove !== undefined) { ppRestoreMove!.ppUsed = Math.max(ppRestoreMove!.ppUsed - 10, 0); pokemon.scene.queueMessage(i18next.t("battle:ppHealBerry", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: ppRestoreMove!.getName(), berryName: getBerryName(berryType) })); - applyPostItemLostAbAttrs(PostItemLostAbAttr, pokemon, pokemon.hasPassive(), false, []); + applyPostItemLostAbAttrs(PostItemLostAbAttr, pokemon, false); } }; } diff --git a/src/data/move.ts b/src/data/move.ts index 754eecafc6a..8423720ab80 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -2402,7 +2402,7 @@ export class RemoveHeldItemAttr extends MoveEffectAttr { // Decrease item amount and update icon !--removedItem.stackCount; target.scene.updateModifiers(target.isPlayer()); - applyPostItemLostAbAttrs(PostItemLostAbAttr, target, target.hasPassive(), false, []); + applyPostItemLostAbAttrs(PostItemLostAbAttr, target, false); if (this.berriesOnly) { @@ -2483,7 +2483,7 @@ export class EatBerryAttr extends MoveEffectAttr { eatBerry(consumer: Pokemon) { getBerryEffectFunc(this.chosenBerry!.berryType)(consumer); // consumer eats the berry applyAbAttrs(HealFromBerryUseAbAttr, consumer, new Utils.BooleanHolder(false)); - applyPostItemLostAbAttrs(PostItemLostAbAttr, consumer, consumer.hasPassive(), false, []); + applyPostItemLostAbAttrs(PostItemLostAbAttr, consumer, false); } } @@ -2519,7 +2519,7 @@ export class StealEatBerryAttr extends EatBerryAttr { } // if the target has berries, pick a random berry and steal it this.chosenBerry = heldBerries[user.randSeedInt(heldBerries.length)]; - applyPostItemLostAbAttrs(PostItemLostAbAttr, target, target.hasPassive(), false, []); + applyPostItemLostAbAttrs(PostItemLostAbAttr, target, false); const message = i18next.t("battle:stealEatBerry", { pokemonName: user.name, targetName: target.name, berryName: this.chosenBerry.type.name }); user.scene.queueMessage(message); this.reduceBerryModifier(target); diff --git a/src/test/abilities/unburden.test.ts b/src/test/abilities/unburden.test.ts index e93b19b444a..cb2a1626c72 100644 --- a/src/test/abilities/unburden.test.ts +++ b/src/test/abilities/unburden.test.ts @@ -48,33 +48,42 @@ describe("Abilities - Unburden", () => { it("should activate when a berry is eaten", async () => { await game.classicMode.startBattle(); + const playerPokemon = game.scene.getPlayerPokemon()!; playerPokemon.abilityIndex = 2; const playerHeldItems = playerPokemon.getHeldItems().length; const initialPlayerSpeed = playerPokemon.getStat(Stat.SPD); + game.move.select(Moves.FALSE_SWIPE); await game.toNextTurn(); + expect(playerPokemon.getHeldItems().length).toBeLessThan(playerHeldItems); expect(playerPokemon.getEffectiveStat(Stat.SPD)).toBeCloseTo(initialPlayerSpeed * 2); }); it("should activate when a berry is stolen", async () => { await game.classicMode.startBattle(); + const enemyPokemon = game.scene.getEnemyPokemon()!; const enemyHeldItemCt = enemyPokemon.getHeldItems().length; const initialEnemySpeed = enemyPokemon.getStat(Stat.SPD); + game.move.select(Moves.PLUCK); await game.toNextTurn(); + expect(enemyPokemon.getHeldItems().length).toBeLessThan(enemyHeldItemCt); expect(enemyPokemon.getEffectiveStat(Stat.SPD)).toBeCloseTo(initialEnemySpeed * 2); }); it("should activate when an item is knocked off", async () => { await game.classicMode.startBattle(); + const enemyPokemon = game.scene.getEnemyPokemon()!; const enemyHeldItemCt = enemyPokemon.getHeldItems().length; const initialEnemySpeed = enemyPokemon.getStat(Stat.SPD); + game.move.select(Moves.KNOCK_OFF); await game.toNextTurn(); + expect(enemyPokemon.getHeldItems().length).toBeLessThan(enemyHeldItemCt); expect(enemyPokemon.getEffectiveStat(Stat.SPD)).toBeCloseTo(initialEnemySpeed * 2); }); @@ -85,11 +94,14 @@ describe("Abilities - Unburden", () => { { name: "MULTI_LENS", count: 3 }, ]); await game.classicMode.startBattle(); + const enemyPokemon = game.scene.getEnemyPokemon()!; const enemyHeldItemCt = enemyPokemon.getHeldItems().length; const initialEnemySpeed = enemyPokemon.getStat(Stat.SPD); + game.move.select(Moves.POPULATION_BOMB); await game.toNextTurn(); + expect(enemyPokemon.getHeldItems().length).toBeLessThan(enemyHeldItemCt); expect(enemyPokemon.getEffectiveStat(Stat.SPD)).toBeCloseTo(initialEnemySpeed * 2); }); @@ -103,12 +115,15 @@ describe("Abilities - Unburden", () => { { name: "LUCKY_EGG", count: 1 }, ]); await game.classicMode.startBattle(); + const playerPokemon = game.scene.getPlayerPokemon()!; playerPokemon.abilityIndex = 2; const playerHeldItems = playerPokemon.getHeldItems().length; const initialPlayerSpeed = playerPokemon.getStat(Stat.SPD); + game.move.select(Moves.POPULATION_BOMB); await game.toNextTurn(); + expect(playerPokemon.getHeldItems().length).toBeLessThan(playerHeldItems); expect(playerPokemon.getEffectiveStat(Stat.SPD)).toBeCloseTo(initialPlayerSpeed * 2); }); @@ -118,11 +133,14 @@ describe("Abilities - Unburden", () => { { name: "MULTI_LENS", count: 3 }, ]); await game.classicMode.startBattle(); + const enemyPokemon = game.scene.getEnemyPokemon()!; const enemyHeldItemCt = enemyPokemon.getHeldItems().length; const initialEnemySpeed = enemyPokemon.getStat(Stat.SPD); + game.move.select(Moves.THIEF); await game.toNextTurn(); + expect(enemyPokemon.getHeldItems().length).toBeLessThan(enemyHeldItemCt); expect(enemyPokemon.getEffectiveStat(Stat.SPD)).toBeCloseTo(initialEnemySpeed * 2); }); @@ -143,13 +161,16 @@ describe("Abilities - Unburden", () => { { name: "BERRY", type: BerryType.LUM, count: 1 }, ]); await game.classicMode.startBattle(); + const enemyPokemon = game.scene.getEnemyPokemon()!; const enemyHeldItemCt = enemyPokemon.getHeldItems().length; const initialEnemySpeed = enemyPokemon.getStat(Stat.SPD); + while (enemyPokemon.getHeldItems().length === enemyHeldItemCt) { game.move.select(Moves.POPULATION_BOMB); await game.toNextTurn(); } + expect(enemyPokemon.getHeldItems().length).toBeLessThan(enemyHeldItemCt); expect(enemyPokemon.getEffectiveStat(Stat.SPD)).toBeCloseTo(initialEnemySpeed * 2); }); @@ -157,22 +178,28 @@ describe("Abilities - Unburden", () => { it("should not activate when a neutralizing ability is present", async () => { game.override.enemyAbility(Abilities.NEUTRALIZING_GAS); await game.classicMode.startBattle(); + const playerPokemon = game.scene.getPlayerPokemon()!; const playerHeldItems = playerPokemon.getHeldItems().length; const initialPlayerSpeed = playerPokemon.getStat(Stat.SPD); + game.move.select(Moves.FALSE_SWIPE); await game.toNextTurn(); + expect(playerPokemon.getHeldItems().length).toBeLessThan(playerHeldItems); expect(playerPokemon.getEffectiveStat(Stat.SPD)).toBeCloseTo(initialPlayerSpeed); }); it("should activate when a move that consumes a berry is used", async () => { game.override.enemyMoveset([ Moves.STUFF_CHEEKS ]); await game.classicMode.startBattle(); + const enemyPokemon = game.scene.getEnemyPokemon()!; const enemyHeldItemCt = enemyPokemon.getHeldItems().length; const initialEnemySpeed = enemyPokemon.getStat(Stat.SPD); + game.move.select(Moves.STUFF_CHEEKS); await game.toNextTurn(); + expect(enemyPokemon.getHeldItems().length).toBeLessThan(enemyHeldItemCt); expect(enemyPokemon.getEffectiveStat(Stat.SPD)).toBeCloseTo(initialEnemySpeed * 2); }); @@ -180,16 +207,16 @@ describe("Abilities - Unburden", () => { game.override .battleType("double") .moveset([ Moves.SPLASH ]); - await game.classicMode.startBattle([ Species.TREECKO, Species.MEOWTH, Species.WEEZING ]); + const playerPokemon = game.scene.getParty(); const treecko = playerPokemon[0]; const weezing = playerPokemon[2]; treecko.abilityIndex = 2; weezing.abilityIndex = 1; - const playerHeldItems = treecko.getHeldItems().length; const initialPlayerSpeed = treecko.getStat(Stat.SPD); + game.move.select(Moves.SPLASH); game.move.select(Moves.SPLASH); await game.forceEnemyMove(Moves.FALSE_SWIPE, 0);