pokerogue/src/items/held-items/berry.ts
2025-06-20 08:51:21 +02:00

97 lines
3.1 KiB
TypeScript

import { getBerryEffectDescription, getBerryEffectFunc, getBerryName, getBerryPredicate } from "#app/data/berry";
import { BerryUsedEvent } from "#app/events/battle-scene";
import type Pokemon from "#app/field/pokemon";
import { globalScene } from "#app/global-scene";
import { ConsumableHeldItem, ITEM_EFFECT } from "#app/items/held-item";
import { PreserveBerryModifier } from "#app/modifier/modifier";
import { BooleanHolder } from "#app/utils/common";
import { BerryType } from "#enums/berry-type";
import { HeldItemId } from "#enums/held-item-id";
interface BerryTypeToHeldItemMap {
[key: number]: HeldItemId;
}
export const berryTypeToHeldItem: BerryTypeToHeldItemMap = {
[BerryType.SITRUS]: HeldItemId.SITRUS_BERRY,
[BerryType.LUM]: HeldItemId.LUM_BERRY,
[BerryType.ENIGMA]: HeldItemId.ENIGMA_BERRY,
[BerryType.LIECHI]: HeldItemId.LIECHI_BERRY,
[BerryType.GANLON]: HeldItemId.GANLON_BERRY,
[BerryType.PETAYA]: HeldItemId.PETAYA_BERRY,
[BerryType.APICOT]: HeldItemId.APICOT_BERRY,
[BerryType.SALAC]: HeldItemId.SALAC_BERRY,
[BerryType.LANSAT]: HeldItemId.LANSAT_BERRY,
[BerryType.STARF]: HeldItemId.STARF_BERRY,
[BerryType.LEPPA]: HeldItemId.LEPPA_BERRY,
};
export interface BERRY_PARAMS {
/** The pokemon with the berry */
pokemon: Pokemon;
}
// TODO: Maybe split up into subclasses?
export class BerryHeldItem extends ConsumableHeldItem {
public effects: ITEM_EFFECT[] = [ITEM_EFFECT.BERRY];
public berryType: BerryType;
constructor(berryType: BerryType, maxStackCount = 1) {
const type = berryTypeToHeldItem[berryType];
super(type, maxStackCount);
this.berryType = berryType;
}
get name(): string {
return getBerryName(this.berryType);
}
get description(): string {
return getBerryEffectDescription(this.berryType);
}
get iconName(): string {
return `${BerryType[this.berryType].toLowerCase()}_berry`;
}
/**
* Checks if {@linkcode BerryModifier} should be applied
* @param pokemon The {@linkcode Pokemon} that holds the berry
* @returns `true` if {@linkcode BerryModifier} should be applied
*/
shouldApply(pokemon: Pokemon): boolean {
return getBerryPredicate(this.berryType)(pokemon);
}
/**
* Applies {@linkcode BerryHeldItem}
* @param pokemon The {@linkcode Pokemon} that holds the berry
* @returns always `true`
*/
apply(params: BERRY_PARAMS): boolean {
const pokemon = params.pokemon;
if (!this.shouldApply(pokemon)) {
return false;
}
const preserve = new BooleanHolder(false);
globalScene.applyModifiers(PreserveBerryModifier, pokemon.isPlayer(), pokemon, preserve);
const consumed = !preserve.value;
// munch the berry and trigger unburden-like effects
getBerryEffectFunc(this.berryType)(pokemon);
this.consume(pokemon, pokemon.isPlayer(), consumed);
// TODO: Update this method to work with held items
// Update berry eaten trackers for Belch, Harvest, Cud Chew, etc.
// Don't recover it if we proc berry pouch (no item duplication)
pokemon.recordEatenBerry(this.berryType, consumed);
globalScene.eventTarget.dispatchEvent(new BerryUsedEvent(pokemon, this.berryType));
return true;
}
}