pokerogue/src/data/berry.ts

144 lines
5.8 KiB
TypeScript
Raw Normal View History

import { PokemonHealPhase, StatChangePhase } from "../phases";
2023-04-20 20:46:05 +01:00
import { getPokemonMessage } from "../messages";
2024-03-01 01:08:50 +00:00
import Pokemon, { HitResult } from "../field/pokemon";
2023-04-25 06:32:48 +01:00
import { getBattleStatName } from "./battle-stat";
import { BattleStat } from "./battle-stat";
import { BattlerTagType } from "./enums/battler-tag-type";
2023-04-20 20:46:05 +01:00
import { getStatusEffectHealText } from "./status-effect";
import * as Utils from "../utils";
2024-01-16 05:28:03 +00:00
import { DoubleBerryEffectAbAttr, ReduceBerryUseThresholdAbAttr, applyAbAttrs } from "./ability";
2023-04-20 20:46:05 +01:00
export enum BerryType {
SITRUS,
2023-04-25 06:32:48 +01:00
LUM,
ENIGMA,
LIECHI,
GANLON,
PETAYA,
APICOT,
2023-07-04 21:35:40 +01:00
SALAC,
2023-04-25 06:32:48 +01:00
LANSAT,
2024-03-20 03:14:06 +00:00
STARF,
LEPPA
2023-04-20 20:46:05 +01:00
}
export function getBerryName(berryType: BerryType) {
return `${Utils.toReadableString(BerryType[berryType])} Berry`;
2023-04-20 20:46:05 +01:00
}
export function getBerryEffectDescription(berryType: BerryType) {
switch (berryType) {
case BerryType.SITRUS:
return 'Restores 25% HP if HP is below 50%';
case BerryType.LUM:
return 'Cures any non-volatile status condition and confusion';
2023-04-25 06:32:48 +01:00
case BerryType.ENIGMA:
return 'Restores 25% HP if hit by a super effective move';
case BerryType.LIECHI:
case BerryType.GANLON:
case BerryType.PETAYA:
case BerryType.APICOT:
2023-07-04 21:35:40 +01:00
case BerryType.SALAC:
2023-04-25 06:32:48 +01:00
const stat = (berryType - BerryType.LIECHI) as BattleStat;
return `Raises ${getBattleStatName(stat)} if HP is below 25%`;
case BerryType.LANSAT:
return 'Raises critical hit ratio if HP is below 25%';
case BerryType.STARF:
return 'Sharply raises a random stat if HP is below 25%';
2024-03-20 03:14:06 +00:00
case BerryType.LEPPA:
return 'Restores 10 PP to a move if its PP reaches 0';
2023-04-20 20:46:05 +01:00
}
}
export type BerryPredicate = (pokemon: Pokemon) => boolean;
export function getBerryPredicate(berryType: BerryType): BerryPredicate {
switch (berryType) {
case BerryType.SITRUS:
return (pokemon: Pokemon) => pokemon.getHpRatio() < 0.5;
case BerryType.LUM:
2023-04-22 00:30:04 +01:00
return (pokemon: Pokemon) => !!pokemon.status || !!pokemon.getTag(BattlerTagType.CONFUSED);
2023-04-25 06:32:48 +01:00
case BerryType.ENIGMA:
return (pokemon: Pokemon) => !!pokemon.turnData.attacksReceived.filter(a => a.result === HitResult.SUPER_EFFECTIVE).length;
2023-04-25 06:32:48 +01:00
case BerryType.LIECHI:
case BerryType.GANLON:
case BerryType.PETAYA:
case BerryType.APICOT:
2023-07-04 21:35:40 +01:00
case BerryType.SALAC:
2023-04-25 06:32:48 +01:00
return (pokemon: Pokemon) => {
2024-01-16 05:28:03 +00:00
const threshold = new Utils.NumberHolder(0.25);
2023-04-25 06:32:48 +01:00
const battleStat = (berryType - BerryType.LIECHI) as BattleStat;
2024-01-16 05:28:03 +00:00
applyAbAttrs(ReduceBerryUseThresholdAbAttr, pokemon, null, threshold);
return pokemon.getHpRatio() < threshold.value && pokemon.summonData.battleStats[battleStat] < 6;
2023-04-25 06:32:48 +01:00
};
case BerryType.LANSAT:
2024-01-16 05:28:03 +00:00
return (pokemon: Pokemon) => {
const threshold = new Utils.NumberHolder(0.25);
applyAbAttrs(ReduceBerryUseThresholdAbAttr, pokemon, null, threshold);
return pokemon.getHpRatio() < 0.25 && !pokemon.getTag(BattlerTagType.CRIT_BOOST);
2024-03-20 03:14:06 +00:00
};
2023-04-25 06:32:48 +01:00
case BerryType.STARF:
2024-01-16 05:28:03 +00:00
return (pokemon: Pokemon) => {
const threshold = new Utils.NumberHolder(0.25);
applyAbAttrs(ReduceBerryUseThresholdAbAttr, pokemon, null, threshold);
return pokemon.getHpRatio() < 0.25;
2024-03-20 03:14:06 +00:00
};
case BerryType.LEPPA:
return (pokemon: Pokemon) => {
const threshold = new Utils.NumberHolder(0.25);
applyAbAttrs(ReduceBerryUseThresholdAbAttr, pokemon, null, threshold);
return !!pokemon.getMoveset().find(m => !m.getPpRatio());
};
2023-04-20 20:46:05 +01:00
}
}
export type BerryEffectFunc = (pokemon: Pokemon) => void;
export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc {
switch (berryType) {
case BerryType.SITRUS:
2023-12-22 06:16:56 +00:00
case BerryType.ENIGMA:
2023-04-20 20:46:05 +01:00
return (pokemon: Pokemon) => {
2023-12-22 06:16:56 +00:00
const hpHealed = new Utils.NumberHolder(Math.floor(pokemon.getMaxHp() / 4));
applyAbAttrs(DoubleBerryEffectAbAttr, pokemon, null, hpHealed);
pokemon.scene.unshiftPhase(new PokemonHealPhase(pokemon.scene, pokemon.getBattlerIndex(),
2023-12-22 06:16:56 +00:00
hpHealed.value, getPokemonMessage(pokemon, `'s ${getBerryName(berryType)}\nrestored its HP!`), true));
2023-04-20 20:46:05 +01:00
};
case BerryType.LUM:
return (pokemon: Pokemon) => {
if (pokemon.status) {
2023-04-22 00:30:04 +01:00
pokemon.scene.queueMessage(getPokemonMessage(pokemon, getStatusEffectHealText(pokemon.status.effect)));
2023-04-20 20:46:05 +01:00
pokemon.resetStatus();
pokemon.updateInfo();
2023-04-22 00:30:04 +01:00
} else if (pokemon.getTag(BattlerTagType.CONFUSED))
pokemon.lapseTag(BattlerTagType.CONFUSED);
2023-04-20 20:46:05 +01:00
};
2023-04-25 06:32:48 +01:00
case BerryType.LIECHI:
case BerryType.GANLON:
case BerryType.PETAYA:
case BerryType.APICOT:
2023-07-04 21:35:40 +01:00
case BerryType.SALAC:
2023-04-25 06:32:48 +01:00
return (pokemon: Pokemon) => {
const battleStat = (berryType - BerryType.LIECHI) as BattleStat;
2023-12-22 06:16:56 +00:00
const statLevels = new Utils.NumberHolder(1);
applyAbAttrs(DoubleBerryEffectAbAttr, pokemon, null, statLevels);
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ battleStat ], statLevels.value));
2023-04-25 06:32:48 +01:00
};
case BerryType.LANSAT:
return (pokemon: Pokemon) => {
pokemon.addTag(BattlerTagType.CRIT_BOOST);
};
case BerryType.STARF:
2023-12-22 06:16:56 +00:00
return (pokemon: Pokemon) => {
const statLevels = new Utils.NumberHolder(2);
applyAbAttrs(DoubleBerryEffectAbAttr, pokemon, null, statLevels);
2024-03-20 03:14:06 +00:00
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ BattleStat.RAND ], statLevels.value));
};
case BerryType.LEPPA:
return (pokemon: Pokemon) => {
const ppRestoreMove = pokemon.getMoveset().find(m => !m.getPpRatio());
ppRestoreMove.ppUsed = Math.max(ppRestoreMove.ppUsed - 10, 0);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` restored PP to its move ${ppRestoreMove.getName()}\nusing its ${getBerryName(berryType)}!`));
2023-12-22 06:16:56 +00:00
};
2023-04-20 20:46:05 +01:00
}
}