pokerogue/src/data/berry.ts
flx-sta a07d2c57a4
[Refactor] use typescript strict-null (#3259)
* TS: enable strict-null

* fix battle-scene.ts

* fix voucher.ts

* adapt more files to strict-null

* adapt more files to strict-null ( 2)

* adapt ability.ts to strict-null

* adapt `arena.ts` to strict-null

* adapt TagAddedEvent constructor to strict-null

* adapt phases.ts.to strict-null

* adapt status-effect.ts to strict-null

* adapt `account.ts` to strict-null

* adapt `configHandler.ts` to strict-null

* adapt `ability.ts` to strict-null

* adapt `biomes.ts` to strict-null

* adapt `challenge.ts` to strict-null

* adapt `daily-run.ts` to strict-null

* adapt `nature.ts` to strict-null

* adapt `pokemon-forms.ts` to strict-null

* adapt `tainer-names.ts` to strict-null

* adapt `types.ts` to strict-null

* adapt `weather.ts` to strict-null

* adapt `egg-hatch-phase.ts` to strict-null

* adapt `evolution-phase.ts` to strict-null

* adapt `pokemon-sprite-sparkle-handler.ts` to strict-null

* adapt `evolution-phase.ts` to strict-null

* adapt `game-mode.ts` to strict-null

* adapt `utils.ts` to strict-null

* adapt `voucher-ui-handler.ts` to strict-null

* adapt `src/ui/unavailable-modal-ui-handler.ts` to strict-null

* adapt `src/ui/ui.ts` to strict-null

* adapt `src/ui/ui-theme.ts` to strict-null

* adapt `src/ui/title-ui-handler.ts` to strict-null

* adapt `src/ui/time-of-day-widget.ts` to strict-null

* adapt `src/ui/text.ts` to strict-null

* adapt `src/ui/target-select-ui-handler.ts` to strict-null

* adapt `src/ui/settings/settings-keyboard-ui-handler.ts` to strict-null

* adapt more files to strict-null (3)

* adapt more files to strict-null (4)

* adapt more files (mostly tests) to strict-null (5)

* adapt more files to strict-null (6)

* adapt more files to strict-null (7)

* Update `src/data/pokemon-evolutions.ts` for strict-null

Partial update `src/data/pokemon-species.ts` for strict-null

* adapt more files to strict-null (8)

* adapt more files to strict-null (9)

* Strict some more nulls (still a few errors remaining)

* adapt rest of the files to strict-null (9)

* fix tests (check for null instead of undefined)

* repalce a lot of `??` with bangs

And added TODO notice as usual

* fix more tests

* all tests pass now

* fix broken game-loop after trainer battle

add some console.warn for missing cases and falling back to default

* remove guessed fallback from utils.rgbHexToRgba

* add TODO for this.currentBattle = null

* adjust   getPokemonById() return to include `null`

* fix compilation errors

* add test for pokemon.trySetStatus

* `chanceMultiplier` shouldn't be optional

* allow `null` for currentPhase

* adjust hasExpSprite logic for no keymatch found

* reduce bang usage in account.updateUserInfo()

* fix new strict-null issues after merge

* fix `strict-null` issues in dropdown.ts

and sand_spit.test.ts

* fix egg-gacha

* adapt gul_missile.test.ts to strict-null

* fix move.ts strict-null

* fix i18n.ts strict-null

* fix strict-null issues

* fix baton_pass test

after accidentially breaking it

* chore: fix compiler errors

* revert accidential changes in baton_pass.test.ts

---------

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>
2024-08-07 17:23:12 +01:00

131 lines
5.5 KiB
TypeScript

import { PokemonHealPhase, StatChangePhase } from "../phases";
import { getPokemonNameWithAffix } from "../messages";
import Pokemon, { HitResult } from "../field/pokemon";
import { BattleStat } from "./battle-stat";
import { getStatusEffectHealText } from "./status-effect";
import * as Utils from "../utils";
import { DoubleBerryEffectAbAttr, ReduceBerryUseThresholdAbAttr, applyAbAttrs } from "./ability";
import i18next from "i18next";
import { BattlerTagType } from "#enums/battler-tag-type";
import { BerryType } from "#enums/berry-type";
export function getBerryName(berryType: BerryType): string {
return i18next.t(`berry:${BerryType[berryType]}.name`);
}
export function getBerryEffectDescription(berryType: BerryType): string {
return i18next.t(`berry:${BerryType[berryType]}.effect`);
}
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:
return (pokemon: Pokemon) => !!pokemon.status || !!pokemon.getTag(BattlerTagType.CONFUSED);
case BerryType.ENIGMA:
return (pokemon: Pokemon) => !!pokemon.turnData.attacksReceived.filter(a => a.result === HitResult.SUPER_EFFECTIVE).length;
case BerryType.LIECHI:
case BerryType.GANLON:
case BerryType.PETAYA:
case BerryType.APICOT:
case BerryType.SALAC:
return (pokemon: Pokemon) => {
const threshold = new Utils.NumberHolder(0.25);
const battleStat = (berryType - BerryType.LIECHI) as BattleStat;
applyAbAttrs(ReduceBerryUseThresholdAbAttr, pokemon, null, threshold);
return pokemon.getHpRatio() < threshold.value && pokemon.summonData.battleStats[battleStat] < 6;
};
case BerryType.LANSAT:
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);
};
case BerryType.STARF:
return (pokemon: Pokemon) => {
const threshold = new Utils.NumberHolder(0.25);
applyAbAttrs(ReduceBerryUseThresholdAbAttr, pokemon, null, threshold);
return pokemon.getHpRatio() < 0.25;
};
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());
};
}
}
export type BerryEffectFunc = (pokemon: Pokemon) => void;
export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc {
switch (berryType) {
case BerryType.SITRUS:
case BerryType.ENIGMA:
return (pokemon: Pokemon) => {
if (pokemon.battleData) {
pokemon.battleData.berriesEaten.push(berryType);
}
const hpHealed = new Utils.NumberHolder(Math.floor(pokemon.getMaxHp() / 4));
applyAbAttrs(DoubleBerryEffectAbAttr, pokemon, null, hpHealed);
pokemon.scene.unshiftPhase(new PokemonHealPhase(pokemon.scene, pokemon.getBattlerIndex(),
hpHealed.value, i18next.t("battle:hpHealBerry", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), berryName: getBerryName(berryType) }), true));
};
case BerryType.LUM:
return (pokemon: Pokemon) => {
if (pokemon.battleData) {
pokemon.battleData.berriesEaten.push(berryType);
}
if (pokemon.status) {
pokemon.scene.queueMessage(getStatusEffectHealText(pokemon.status.effect, getPokemonNameWithAffix(pokemon)));
}
pokemon.resetStatus(true, true);
pokemon.updateInfo();
};
case BerryType.LIECHI:
case BerryType.GANLON:
case BerryType.PETAYA:
case BerryType.APICOT:
case BerryType.SALAC:
return (pokemon: Pokemon) => {
if (pokemon.battleData) {
pokemon.battleData.berriesEaten.push(berryType);
}
const battleStat = (berryType - BerryType.LIECHI) as BattleStat;
const statLevels = new Utils.NumberHolder(1);
applyAbAttrs(DoubleBerryEffectAbAttr, pokemon, null, statLevels);
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ battleStat ], statLevels.value));
};
case BerryType.LANSAT:
return (pokemon: Pokemon) => {
if (pokemon.battleData) {
pokemon.battleData.berriesEaten.push(berryType);
}
pokemon.addTag(BattlerTagType.CRIT_BOOST);
};
case BerryType.STARF:
return (pokemon: Pokemon) => {
if (pokemon.battleData) {
pokemon.battleData.berriesEaten.push(berryType);
}
const statLevels = new Utils.NumberHolder(2);
applyAbAttrs(DoubleBerryEffectAbAttr, pokemon, null, statLevels);
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ BattleStat.RAND ], statLevels.value));
};
case BerryType.LEPPA:
return (pokemon: Pokemon) => {
if (pokemon.battleData) {
pokemon.battleData.berriesEaten.push(berryType);
}
const ppRestoreMove = pokemon.getMoveset().find(m => !m?.getPpRatio()) ? pokemon.getMoveset().find(m => !m?.getPpRatio()) : pokemon.getMoveset().find(m => m!.getPpRatio() < 1); // TODO: is this bang correct?
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) }));
}
};
}
}