pokerogue/src/phases/berry-phase.ts
Sirz Benjie 1029afcdbf
[Refactor] Remove circular dependencies (part 4) (#5964)
* Add abilityAttr.is methods

* [WIP] move modifier stuff around

* Untangle circular deps from modifiers

* Move unlockables to own file

* Untangle all circular deps outside of MEs

* Move constants in MEs to their own files

* Re-add missing import to battle.ts

* Add necessary overload for getTag

* Add missing type import in weather.ts

* Init modifier types and pools in loading-scene

* Remove stray commented code

* Apply kev's suggestions from code review

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>

---------

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>
2025-06-11 19:42:04 -07:00

76 lines
2.5 KiB
TypeScript

import { applyAbAttrs } from "#app/data/abilities/apply-ab-attrs";
import { CommonAnim } from "#enums/move-anims-common";
import { BerryUsedEvent } from "#app/events/battle-scene";
import { getPokemonNameWithAffix } from "#app/messages";
import { BerryModifier } from "#app/modifier/modifier";
import i18next from "i18next";
import { BooleanHolder } from "#app/utils/common";
import { FieldPhase } from "./field-phase";
import { globalScene } from "#app/global-scene";
import type Pokemon from "#app/field/pokemon";
/**
* The phase after attacks where the pokemon eat berries.
* Also triggers Cud Chew's "repeat berry use" effects
*/
export class BerryPhase extends FieldPhase {
public readonly phaseName = "BerryPhase";
start() {
super.start();
this.executeForAll(pokemon => {
this.eatBerries(pokemon);
applyAbAttrs("RepeatBerryNextTurnAbAttr", pokemon, null);
});
this.end();
}
/**
* Attempt to eat all of a given {@linkcode Pokemon}'s berries once.
* @param pokemon - The {@linkcode Pokemon} to check
*/
eatBerries(pokemon: Pokemon): void {
const hasUsableBerry = !!globalScene.findModifier(
m => m instanceof BerryModifier && m.shouldApply(pokemon),
pokemon.isPlayer(),
);
if (!hasUsableBerry) {
return;
}
// TODO: If both opponents on field have unnerve, which one displays its message?
const cancelled = new BooleanHolder(false);
pokemon.getOpponents().forEach(opp => applyAbAttrs("PreventBerryUseAbAttr", opp, cancelled));
if (cancelled.value) {
globalScene.phaseManager.queueMessage(
i18next.t("abilityTriggers:preventBerryUse", {
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
}),
);
return;
}
globalScene.phaseManager.unshiftNew(
"CommonAnimPhase",
pokemon.getBattlerIndex(),
pokemon.getBattlerIndex(),
CommonAnim.USE_ITEM,
);
for (const berryModifier of globalScene.applyModifiers(BerryModifier, pokemon.isPlayer(), pokemon)) {
// No need to track berries being eaten; already done inside applyModifiers
if (berryModifier.consumed) {
berryModifier.consumed = false;
pokemon.loseHeldItem(berryModifier);
}
globalScene.eventTarget.dispatchEvent(new BerryUsedEvent(berryModifier));
}
globalScene.updateModifiers(pokemon.isPlayer());
// AbilityId.CHEEK_POUCH only works once per round of nom noms
applyAbAttrs("HealFromBerryUseAbAttr", pokemon, new BooleanHolder(false));
}
}