[Biome] Add and apply lint/style/noNamespaceImport (#5650)

* Add `lint/style/noNamespaceImport` Biome rule

* Apply Biome rule, add exception for `*.test.ts` files
This commit is contained in:
NightKev 2025-04-11 22:31:56 -07:00 committed by GitHub
parent 81f424dc71
commit 6f56dce771
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
86 changed files with 1112 additions and 1103 deletions

View File

@ -65,7 +65,8 @@
"useDefaultParameterLast": "off", // TODO: Fix spots in the codebase where this flag would be triggered, and then enable
"useSingleVarDeclarator": "off",
"useNodejsImportProtocol": "off",
"useTemplate": "off" // string concatenation is faster: https://stackoverflow.com/questions/29055518/are-es6-template-literals-faster-than-string-concatenation
"useTemplate": "off", // string concatenation is faster: https://stackoverflow.com/questions/29055518/are-es6-template-literals-faster-than-string-concatenation
"noNamespaceImport": "error"
},
"suspicious": {
"noDoubleEquals": "error",
@ -99,6 +100,9 @@
"rules": {
"performance": {
"noDelete": "off"
},
"style": {
"noNamespaceImport": "off"
}
}
}

View File

@ -1,11 +1,11 @@
import { pokerogueApi } from "#app/plugins/api/pokerogue-api";
import type { UserInfo } from "#app/@types/UserInfo";
import { bypassLogin } from "./battle-scene";
import * as Utils from "./utils";
import { bypassLogin } from "#app/battle-scene";
import { randomString } from "#app/utils";
export let loggedInUser: UserInfo | null = null;
// This is a random string that is used to identify the client session - unique per session (tab or window) so that the game will only save on the one that the server is expecting
export const clientSessionId = Utils.randomString(32);
export const clientSessionId = randomString(32);
export function initLoggedInUser(): void {
loggedInUser = {

View File

@ -5,9 +5,20 @@ import { EnemyPokemon, PlayerPokemon } from "#app/field/pokemon";
import type { PokemonSpeciesFilter } from "#app/data/pokemon-species";
import type PokemonSpecies from "#app/data/pokemon-species";
import { allSpecies, getPokemonSpecies } from "#app/data/pokemon-species";
import type { Constructor } from "#app/utils";
import { isNullOrUndefined, randSeedInt } from "#app/utils";
import * as Utils from "#app/utils";
import {
fixedInt,
deepMergeObjects,
getIvsFromId,
randSeedInt,
getEnumValues,
randomString,
NumberHolder,
shiftCharCodes,
formatMoney,
isNullOrUndefined,
BooleanHolder,
type Constructor,
} from "#app/utils";
import type { Modifier, ModifierPredicate, TurnHeldItemTransferModifier } from "./modifier/modifier";
import {
ConsumableModifier,
@ -733,7 +744,7 @@ export default class BattleScene extends SceneBase {
}
this.playTimeTimer = this.time.addEvent({
delay: Utils.fixedInt(1000),
delay: fixedInt(1000),
repeat: -1,
callback: () => {
if (this.gameData) {
@ -783,7 +794,7 @@ export default class BattleScene extends SceneBase {
return;
}
const expVariantData = await this.cachedFetch("./images/pokemon/variant/_exp_masterlist.json").then(r => r.json());
Utils.deepMergeObjects(variantData, expVariantData);
deepMergeObjects(variantData, expVariantData);
}
cachedFetch(url: string, init?: RequestInit): Promise<Response> {
@ -988,7 +999,7 @@ export default class BattleScene extends SceneBase {
}
if (boss && !dataSource) {
const secondaryIvs = Utils.getIvsFromId(Utils.randSeedInt(4294967296));
const secondaryIvs = getIvsFromId(randSeedInt(4294967296));
for (let s = 0; s < pokemon.ivs.length; s++) {
pokemon.ivs[s] = Math.round(
@ -1147,7 +1158,7 @@ export default class BattleScene extends SceneBase {
* Generates a random number using the current battle's seed
*
* This calls {@linkcode Battle.randSeedInt}({@linkcode range}, {@linkcode min}) in `src/battle.ts`
* which calls {@linkcode Utils.randSeedInt randSeedInt}({@linkcode range}, {@linkcode min}) in `src/utils.ts`
* which calls {@linkcode randSeedInt randSeedInt}({@linkcode range}, {@linkcode min}) in `src/utils.ts`
*
* @param range How large of a range of random numbers to choose from. If {@linkcode range} <= 1, returns {@linkcode min}
* @param min The minimum integer to pick, default `0`
@ -1172,7 +1183,7 @@ export default class BattleScene extends SceneBase {
this.lockModifierTiers = false;
this.pokeballCounts = Object.fromEntries(
Utils.getEnumValues(PokeballType)
getEnumValues(PokeballType)
.filter(p => p <= PokeballType.MASTER_BALL)
.map(t => [t, 0]),
);
@ -1204,7 +1215,7 @@ export default class BattleScene extends SceneBase {
// Reset RNG after end of game or save & quit.
// This needs to happen after clearing this.currentBattle or the seed will be affected by the last wave played
this.setSeed(Overrides.SEED_OVERRIDE || Utils.randomString(24));
this.setSeed(Overrides.SEED_OVERRIDE || randomString(24));
console.log("Seed:", this.seed);
this.resetSeed();
@ -1245,7 +1256,7 @@ export default class BattleScene extends SceneBase {
...allSpecies,
...allMoves,
...allAbilities,
...Utils.getEnumValues(ModifierPoolType)
...getEnumValues(ModifierPoolType)
.map(mpt => getModifierPoolForType(mpt))
.flatMap(mp =>
Object.values(mp)
@ -1285,7 +1296,7 @@ export default class BattleScene extends SceneBase {
}
getDoubleBattleChance(newWaveIndex: number, playerField: PlayerPokemon[]) {
const doubleChance = new Utils.NumberHolder(newWaveIndex % 10 === 0 ? 32 : 8);
const doubleChance = new NumberHolder(newWaveIndex % 10 === 0 ? 32 : 8);
this.applyModifiers(DoubleBattleChanceBoosterModifier, true, doubleChance);
for (const p of playerField) {
applyAbAttrs(DoubleBattleChanceAbAttr, p, null, false, doubleChance);
@ -1342,7 +1353,7 @@ export default class BattleScene extends SceneBase {
if (trainerConfigs[trainerType].doubleOnly) {
doubleTrainer = true;
} else if (trainerConfigs[trainerType].hasDouble) {
doubleTrainer = !Utils.randSeedInt(this.getDoubleBattleChance(newWaveIndex, playerField));
doubleTrainer = !randSeedInt(this.getDoubleBattleChance(newWaveIndex, playerField));
// Add a check that special trainers can't be double except for tate and liza - they should use the normal double chance
if (
trainerConfigs[trainerType].trainerTypeDouble &&
@ -1353,7 +1364,7 @@ export default class BattleScene extends SceneBase {
}
const variant = doubleTrainer
? TrainerVariant.DOUBLE
: Utils.randSeedInt(2)
: randSeedInt(2)
? TrainerVariant.FEMALE
: TrainerVariant.DEFAULT;
newTrainer = trainerData !== undefined ? trainerData.toTrainer() : new Trainer(trainerType, variant);
@ -1371,7 +1382,7 @@ export default class BattleScene extends SceneBase {
if (double === undefined && newWaveIndex > 1) {
if (newBattleType === BattleType.WILD && !this.gameMode.isWaveFinal(newWaveIndex)) {
newDouble = !Utils.randSeedInt(this.getDoubleBattleChance(newWaveIndex, playerField));
newDouble = !randSeedInt(this.getDoubleBattleChance(newWaveIndex, playerField));
} else if (newBattleType === BattleType.TRAINER) {
newDouble = newTrainer?.variant === TrainerVariant.DOUBLE;
}
@ -1559,7 +1570,7 @@ export default class BattleScene extends SceneBase {
scale: scale,
x: (defaultWidth - scaledWidth) / 2,
y: defaultHeight - scaledHeight,
duration: !instant ? Utils.fixedInt(Math.abs(this.field.scale - scale) * 200) : 0,
duration: !instant ? fixedInt(Math.abs(this.field.scale - scale) * 200) : 0,
ease: "Sine.easeInOut",
onComplete: () => resolve(),
});
@ -1656,12 +1667,12 @@ export default class BattleScene extends SceneBase {
case Species.SQUAWKABILLY:
case Species.TATSUGIRI:
case Species.PALDEA_TAUROS:
return Utils.randSeedInt(species.forms.length);
return randSeedInt(species.forms.length);
case Species.PIKACHU:
if (this.currentBattle?.battleType === BattleType.TRAINER && this.currentBattle?.waveIndex < 30) {
return 0; // Ban Cosplay and Partner Pika from Trainers before wave 30
}
return Utils.randSeedInt(8);
return randSeedInt(8);
case Species.EEVEE:
if (
this.currentBattle?.battleType === BattleType.TRAINER &&
@ -1670,22 +1681,22 @@ export default class BattleScene extends SceneBase {
) {
return 0; // No Partner Eevee for Wave 12 Preschoolers
}
return Utils.randSeedInt(2);
return randSeedInt(2);
case Species.FROAKIE:
case Species.FROGADIER:
case Species.GRENINJA:
if (this.currentBattle?.battleType === BattleType.TRAINER && !isEggPhase) {
return 0; // Don't give trainers Battle Bond Greninja, Froakie or Frogadier
}
return Utils.randSeedInt(2);
return randSeedInt(2);
case Species.URSHIFU:
return Utils.randSeedInt(2);
return randSeedInt(2);
case Species.ZYGARDE:
return Utils.randSeedInt(4);
return randSeedInt(4);
case Species.MINIOR:
return Utils.randSeedInt(7);
return randSeedInt(7);
case Species.ALCREMIE:
return Utils.randSeedInt(9);
return randSeedInt(9);
case Species.MEOWSTIC:
case Species.INDEEDEE:
case Species.BASCULEGION:
@ -1716,7 +1727,7 @@ export default class BattleScene extends SceneBase {
if (this.gameMode.hasMysteryEncounters && !isEggPhase) {
return 1; // Wandering form
}
return Utils.randSeedInt(species.forms.length);
return randSeedInt(species.forms.length);
}
if (ignoreArena) {
@ -1725,7 +1736,7 @@ export default class BattleScene extends SceneBase {
case Species.WORMADAM:
case Species.ROTOM:
case Species.LYCANROC:
return Utils.randSeedInt(species.forms.length);
return randSeedInt(species.forms.length);
}
return 0;
}
@ -1737,7 +1748,7 @@ export default class BattleScene extends SceneBase {
let ret = false;
this.executeWithSeedOffset(
() => {
ret = !Utils.randSeedInt(2);
ret = !randSeedInt(2);
},
0,
this.seed.toString(),
@ -1749,7 +1760,7 @@ export default class BattleScene extends SceneBase {
let ret = 0;
this.executeWithSeedOffset(
() => {
ret = Utils.randSeedInt(8) * 5;
ret = randSeedInt(8) * 5;
},
0,
this.seed.toString(),
@ -1778,7 +1789,7 @@ export default class BattleScene extends SceneBase {
isBoss =
waveIndex % 10 === 0 ||
(this.gameMode.hasRandomBosses &&
Utils.randSeedInt(100) < Math.min(Math.max(Math.ceil((waveIndex - 250) / 50), 0) * 2, 30));
randSeedInt(100) < Math.min(Math.max(Math.ceil((waveIndex - 250) / 50), 0) * 2, 30));
}, waveIndex << 2);
}
if (!isBoss) {
@ -1805,7 +1816,7 @@ export default class BattleScene extends SceneBase {
const infectedIndexes: number[] = [];
const spread = (index: number, spreadTo: number) => {
const partyMember = party[index + spreadTo];
if (!partyMember.pokerus && !Utils.randSeedInt(10)) {
if (!partyMember.pokerus && !randSeedInt(10)) {
partyMember.pokerus = true;
infectedIndexes.push(index + spreadTo);
}
@ -1831,7 +1842,7 @@ export default class BattleScene extends SceneBase {
resetSeed(waveIndex?: number): void {
const wave = waveIndex || this.currentBattle?.waveIndex || 0;
this.waveSeed = Utils.shiftCharCodes(this.seed, wave);
this.waveSeed = shiftCharCodes(this.seed, wave);
Phaser.Math.RND.sow([this.waveSeed]);
console.log("Wave Seed:", this.waveSeed, wave);
this.rngCounter = 0;
@ -1850,7 +1861,7 @@ export default class BattleScene extends SceneBase {
const tempRngOffset = this.rngOffset;
const tempRngSeedOverride = this.rngSeedOverride;
const state = Phaser.Math.RND.state();
Phaser.Math.RND.sow([Utils.shiftCharCodes(seedOverride || this.seed, offset)]);
Phaser.Math.RND.sow([shiftCharCodes(seedOverride || this.seed, offset)]);
this.rngCounter = 0;
this.rngOffset = offset;
this.rngSeedOverride = seedOverride || "";
@ -1995,7 +2006,7 @@ export default class BattleScene extends SceneBase {
if (this.money === undefined) {
return;
}
const formattedMoney = Utils.formatMoney(this.moneyFormat, this.money);
const formattedMoney = formatMoney(this.moneyFormat, this.money);
this.moneyText.setText(i18next.t("battleScene:moneyOwned", { formattedMoney }));
this.fieldUI.moveAbove(this.moneyText, this.luckText);
if (forceVisible) {
@ -2152,12 +2163,12 @@ export default class BattleScene extends SceneBase {
),
]
: allSpecies.filter(s => s.isCatchable());
return filteredSpecies[Utils.randSeedInt(filteredSpecies.length)];
return filteredSpecies[randSeedInt(filteredSpecies.length)];
}
generateRandomBiome(waveIndex: number): Biome {
const relWave = waveIndex % 250;
const biomes = Utils.getEnumValues(Biome).filter(b => b !== Biome.TOWN && b !== Biome.END);
const biomes = getEnumValues(Biome).filter(b => b !== Biome.TOWN && b !== Biome.END);
const maxDepth = biomeDepths[Biome.END][0] - 2;
const depthWeights = new Array(maxDepth + 1)
.fill(null)
@ -2169,7 +2180,7 @@ export default class BattleScene extends SceneBase {
biomeThresholds.push(totalWeight);
}
const randInt = Utils.randSeedInt(totalWeight);
const randInt = randSeedInt(totalWeight);
for (let i = 0; i < biomes.length; i++) {
if (randInt < biomeThresholds[i]) {
@ -2177,7 +2188,7 @@ export default class BattleScene extends SceneBase {
}
}
return biomes[Utils.randSeedInt(biomes.length)];
return biomes[randSeedInt(biomes.length)];
}
isBgmPlaying(): boolean {
@ -2362,7 +2373,7 @@ export default class BattleScene extends SceneBase {
this.bgmResumeTimer.destroy();
}
if (resumeBgm) {
this.bgmResumeTimer = this.time.delayedCall(pauseDuration || Utils.fixedInt(sound.totalDuration * 1000), () => {
this.bgmResumeTimer = this.time.delayedCall(pauseDuration || fixedInt(sound.totalDuration * 1000), () => {
this.resumeBgm();
this.bgmResumeTimer = null;
});
@ -2955,7 +2966,7 @@ export default class BattleScene extends SceneBase {
const args: unknown[] = [];
if (modifier instanceof PokemonHpRestoreModifier) {
if (!(modifier as PokemonHpRestoreModifier).fainted) {
const hpRestoreMultiplier = new Utils.NumberHolder(1);
const hpRestoreMultiplier = new NumberHolder(1);
this.applyModifiers(HealingBoosterModifier, true, hpRestoreMultiplier);
args.push(hpRestoreMultiplier.value);
} else {
@ -2963,7 +2974,7 @@ export default class BattleScene extends SceneBase {
}
} else if (modifier instanceof FusePokemonModifier) {
args.push(this.getPokemonById(modifier.fusePokemonId) as PlayerPokemon);
} else if (modifier instanceof RememberMoveModifier && !Utils.isNullOrUndefined(cost)) {
} else if (modifier instanceof RememberMoveModifier && !isNullOrUndefined(cost)) {
args.push(cost);
}
@ -3032,7 +3043,7 @@ export default class BattleScene extends SceneBase {
itemLost = true,
): boolean {
const source = itemModifier.pokemonId ? itemModifier.getPokemon() : null;
const cancelled = new Utils.BooleanHolder(false);
const cancelled = new BooleanHolder(false);
if (source && source.isPlayer() !== target.isPlayer()) {
applyAbAttrs(BlockItemTheftAbAttr, source, cancelled);
@ -3101,7 +3112,7 @@ export default class BattleScene extends SceneBase {
canTransferHeldItemModifier(itemModifier: PokemonHeldItemModifier, target: Pokemon, transferQuantity = 1): boolean {
const mod = itemModifier.clone() as PokemonHeldItemModifier;
const source = mod.pokemonId ? mod.getPokemon() : null;
const cancelled = new Utils.BooleanHolder(false);
const cancelled = new BooleanHolder(false);
if (source && source.isPlayer() !== target.isPlayer()) {
applyAbAttrs(BlockItemTheftAbAttr, source, cancelled);
@ -3195,7 +3206,7 @@ export default class BattleScene extends SceneBase {
}
let count = 0;
for (let c = 0; c < chances; c++) {
if (!Utils.randSeedInt(this.gameMode.getEnemyModifierChance(isBoss))) {
if (!randSeedInt(this.gameMode.getEnemyModifierChance(isBoss))) {
count++;
}
}
@ -3371,7 +3382,7 @@ export default class BattleScene extends SceneBase {
if (mods.length < 1) {
return mods;
}
const rand = Utils.randSeedInt(mods.length);
const rand = randSeedInt(mods.length);
return [mods[rand], ...shuffleModifiers(mods.filter((_, i) => i !== rand))];
};
modifiers = shuffleModifiers(modifiers);
@ -3597,7 +3608,7 @@ export default class BattleScene extends SceneBase {
*/
initFinalBossPhaseTwo(pokemon: Pokemon): void {
if (pokemon instanceof EnemyPokemon && pokemon.isBoss() && !pokemon.formIndex && pokemon.bossSegmentIndex < 1) {
this.fadeOutBgm(Utils.fixedInt(2000), false);
this.fadeOutBgm(fixedInt(2000), false);
this.ui.showDialogue(
battleSpecDialogue[BattleSpec.FINAL_BOSS].firstStageWin,
pokemon.species.name,
@ -3700,7 +3711,7 @@ export default class BattleScene extends SceneBase {
if (Overrides.XP_MULTIPLIER_OVERRIDE !== null) {
expMultiplier = Overrides.XP_MULTIPLIER_OVERRIDE;
}
const pokemonExp = new Utils.NumberHolder(expValue * expMultiplier);
const pokemonExp = new NumberHolder(expValue * expMultiplier);
this.applyModifiers(PokemonExpBoosterModifier, true, partyMember, pokemonExp);
partyMemberExp.push(Math.floor(pokemonExp.value));
}
@ -3849,7 +3860,7 @@ export default class BattleScene extends SceneBase {
while (i < this.mysteryEncounterSaveData.queuedEncounters.length && !!encounter) {
const candidate = this.mysteryEncounterSaveData.queuedEncounters[i];
const forcedChance = candidate.spawnPercent;
if (Utils.randSeedInt(100) < forcedChance) {
if (randSeedInt(100) < forcedChance) {
encounter = allMysteryEncounters[candidate.type];
}
@ -3882,7 +3893,7 @@ export default class BattleScene extends SceneBase {
}
const totalWeight = tierWeights.reduce((a, b) => a + b);
const tierValue = Utils.randSeedInt(totalWeight);
const tierValue = randSeedInt(totalWeight);
const commonThreshold = totalWeight - tierWeights[0];
const greatThreshold = totalWeight - tierWeights[0] - tierWeights[1];
const ultraThreshold = totalWeight - tierWeights[0] - tierWeights[1] - tierWeights[2];
@ -3974,7 +3985,7 @@ export default class BattleScene extends SceneBase {
console.log("No Mystery Encounters found, falling back to Mysterious Challengers.");
return allMysteryEncounters[MysteryEncounterType.MYSTERIOUS_CHALLENGERS];
}
encounter = availableEncounters[Utils.randSeedInt(availableEncounters.length)];
encounter = availableEncounters[randSeedInt(availableEncounters.length)];
// New encounter object to not dirty flags
encounter = new MysteryEncounter(encounter);
encounter.populateDialogueTokensFromRequirements();

View File

@ -1,6 +1,14 @@
import { globalScene } from "#app/global-scene";
import type { Command } from "./ui/command-ui-handler";
import * as Utils from "./utils";
import {
randomString,
getEnumValues,
NumberHolder,
randSeedInt,
shiftCharCodes,
randSeedItem,
randInt,
} from "#app/utils";
import Trainer, { TrainerVariant } from "./field/trainer";
import type { GameMode } from "./game-mode";
import { MoneyMultiplierModifier, PokemonHeldItemModifier } from "./modifier/modifier";
@ -99,7 +107,7 @@ export default class Battle {
public postBattleLoot: PokemonHeldItemModifier[] = [];
public escapeAttempts = 0;
public lastMove: Moves;
public battleSeed: string = Utils.randomString(16, true);
public battleSeed: string = randomString(16, true);
private battleSeedState: string | null = null;
public moneyScattered = 0;
/** Primarily for double battles, keeps track of last enemy and player pokemon that triggered its ability or used a move */
@ -181,8 +189,8 @@ export default class Battle {
incrementTurn(): void {
this.turn++;
this.turnCommands = Object.fromEntries(Utils.getEnumValues(BattlerIndex).map(bt => [bt, null]));
this.preTurnCommands = Object.fromEntries(Utils.getEnumValues(BattlerIndex).map(bt => [bt, null]));
this.turnCommands = Object.fromEntries(getEnumValues(BattlerIndex).map(bt => [bt, null]));
this.preTurnCommands = Object.fromEntries(getEnumValues(BattlerIndex).map(bt => [bt, null]));
this.battleSeedState = null;
}
@ -211,7 +219,7 @@ export default class Battle {
}
pickUpScatteredMoney(): void {
const moneyAmount = new Utils.NumberHolder(globalScene.currentBattle.moneyScattered);
const moneyAmount = new NumberHolder(globalScene.currentBattle.moneyScattered);
globalScene.applyModifiers(MoneyMultiplierModifier, true, moneyAmount);
if (globalScene.arena.getTag(ArenaTagType.HAPPY_HOUR)) {
@ -448,7 +456,7 @@ export default class Battle {
}
/**
* Generates a random number using the current battle's seed. Calls {@linkcode Utils.randSeedInt}
* Generates a random number using the current battle's seed. Calls {@linkcode randSeedInt}
* @param range How large of a range of random numbers to choose from. If {@linkcode range} <= 1, returns {@linkcode min}
* @param min The minimum integer to pick, default `0`
* @returns A random integer between {@linkcode min} and ({@linkcode min} + {@linkcode range} - 1)
@ -463,12 +471,12 @@ export default class Battle {
if (this.battleSeedState) {
Phaser.Math.RND.state(this.battleSeedState);
} else {
Phaser.Math.RND.sow([Utils.shiftCharCodes(this.battleSeed, this.turn << 6)]);
Phaser.Math.RND.sow([shiftCharCodes(this.battleSeed, this.turn << 6)]);
console.log("Battle Seed:", this.battleSeed);
}
globalScene.rngCounter = this.rngCounter++;
globalScene.rngSeedOverride = this.battleSeed;
const ret = Utils.randSeedInt(range, min);
const ret = randSeedInt(range, min);
this.battleSeedState = Phaser.Math.RND.state();
Phaser.Math.RND.state(state);
globalScene.rngCounter = tempRngCounter;
@ -554,19 +562,19 @@ export function getRandomTrainerFunc(
seedOffset = 0,
): GetTrainerFunc {
return () => {
const rand = Utils.randSeedInt(trainerPool.length);
const rand = randSeedInt(trainerPool.length);
const trainerTypes: TrainerType[] = [];
globalScene.executeWithSeedOffset(() => {
for (const trainerPoolEntry of trainerPool) {
const trainerType = Array.isArray(trainerPoolEntry) ? Utils.randSeedItem(trainerPoolEntry) : trainerPoolEntry;
const trainerType = Array.isArray(trainerPoolEntry) ? randSeedItem(trainerPoolEntry) : trainerPoolEntry;
trainerTypes.push(trainerType);
}
}, seedOffset);
let trainerGender = TrainerVariant.DEFAULT;
if (randomGender) {
trainerGender = Utils.randInt(2) === 0 ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT;
trainerGender = randInt(2) === 0 ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT;
}
/* 1/3 chance for evil team grunts to be double battles */
@ -585,7 +593,7 @@ export function getRandomTrainerFunc(
const isEvilTeamGrunt = evilTeamGrunts.includes(trainerTypes[rand]);
if (trainerConfigs[trainerTypes[rand]].hasDouble && isEvilTeamGrunt) {
return new Trainer(trainerTypes[rand], Utils.randInt(3) === 0 ? TrainerVariant.DOUBLE : trainerGender);
return new Trainer(trainerTypes[rand], randInt(3) === 0 ? TrainerVariant.DOUBLE : trainerGender);
}
return new Trainer(trainerTypes[rand], trainerGender);
@ -608,7 +616,7 @@ export const classicFixedBattles: FixedBattleConfigs = {
[ClassicFixedBossWaves.TOWN_YOUNGSTER]: new FixedBattleConfig()
.setBattleType(BattleType.TRAINER)
.setGetTrainerFunc(
() => new Trainer(TrainerType.YOUNGSTER, Utils.randSeedInt(2) ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT),
() => new Trainer(TrainerType.YOUNGSTER, randSeedInt(2) ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT),
),
[ClassicFixedBossWaves.RIVAL_1]: new FixedBattleConfig()
.setBattleType(BattleType.TRAINER)

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
import { PokemonType } from "#enums/pokemon-type";
import * as Utils from "#app/utils";
import { randSeedInt, getEnumValues } from "#app/utils";
import type { SpeciesFormEvolution } from "#app/data/balance/pokemon-evolutions";
import { pokemonEvolutions } from "#app/data/balance/pokemon-evolutions";
import i18next from "i18next";
@ -7710,7 +7710,7 @@ export function initBiomes() {
if (biome === Biome.END) {
const biomeList = Object.keys(Biome).filter(key => !Number.isNaN(Number(key)));
biomeList.pop(); // Removes Biome.END from the list
const randIndex = Utils.randSeedInt(biomeList.length, 1); // Will never be Biome.TOWN
const randIndex = randSeedInt(biomeList.length, 1); // Will never be Biome.TOWN
biome = Biome[biomeList[randIndex]];
}
const linkedBiomes: (Biome | [ Biome, number ])[] = Array.isArray(biomeLinks[biome])
@ -7733,15 +7733,15 @@ export function initBiomes() {
traverseBiome(Biome.TOWN, 0);
biomeDepths[Biome.END] = [ Object.values(biomeDepths).map(d => d[0]).reduce((max: number, value: number) => Math.max(max, value), 0) + 1, 1 ];
for (const biome of Utils.getEnumValues(Biome)) {
for (const biome of getEnumValues(Biome)) {
biomePokemonPools[biome] = {};
biomeTrainerPools[biome] = {};
for (const tier of Utils.getEnumValues(BiomePoolTier)) {
for (const tier of getEnumValues(BiomePoolTier)) {
biomePokemonPools[biome][tier] = {};
biomeTrainerPools[biome][tier] = [];
for (const tod of Utils.getEnumValues(TimeOfDay)) {
for (const tod of getEnumValues(TimeOfDay)) {
biomePokemonPools[biome][tier][tod] = [];
}
}

View File

@ -1,5 +1,5 @@
import { allMoves } from "#app/data/moves/move";
import * as Utils from "#app/utils";
import { getEnumKeys, getEnumValues } from "#app/utils";
import { Moves } from "#enums/moves";
import { Species } from "#enums/species";
@ -587,8 +587,8 @@ export const speciesEggMoves = {
function parseEggMoves(content: string): void {
let output = "";
const speciesNames = Utils.getEnumKeys(Species);
const speciesValues = Utils.getEnumValues(Species);
const speciesNames = getEnumKeys(Species);
const speciesValues = getEnumValues(Species);
const lines = content.split(/\n/g);
for (const line of lines) {

View File

@ -3,7 +3,7 @@ import { Gender } from "#app/data/gender";
import { PokeballType } from "#enums/pokeball";
import type Pokemon from "#app/field/pokemon";
import { PokemonType } from "#enums/pokemon-type";
import * as Utils from "#app/utils";
import { randSeedInt } from "#app/utils";
import { WeatherType } from "#enums/weather-type";
import { Nature } from "#enums/nature";
import { Biome } from "#enums/biome";
@ -333,7 +333,7 @@ class DunsparceEvolutionCondition extends SpeciesEvolutionCondition {
super(p => {
let ret = false;
if (p.moveset.filter(m => m.moveId === Moves.HYPER_DRILL).length > 0) {
globalScene.executeWithSeedOffset(() => ret = !Utils.randSeedInt(4), p.id);
globalScene.executeWithSeedOffset(() => ret = !randSeedInt(4), p.id);
}
return ret;
});
@ -346,7 +346,7 @@ class TandemausEvolutionCondition extends SpeciesEvolutionCondition {
constructor() {
super(p => {
let ret = false;
globalScene.executeWithSeedOffset(() => ret = !Utils.randSeedInt(4), p.id);
globalScene.executeWithSeedOffset(() => ret = !randSeedInt(4), p.id);
return ret;
});
}

View File

@ -42,7 +42,7 @@ import { Species } from "#enums/species";
import { EFFECTIVE_STATS, getStatKey, Stat, type BattleStat, type EffectiveStat } from "#enums/stat";
import { StatusEffect } from "#enums/status-effect";
import { WeatherType } from "#enums/weather-type";
import * as Utils from "../utils";
import { isNullOrUndefined } from "#app/utils";
export enum BattlerTagLapseType {
FAINT,
@ -302,7 +302,7 @@ export class DisabledTag extends MoveRestrictionBattlerTag {
super.onAdd(pokemon);
const move = pokemon.getLastXMoves(-1).find(m => !m.virtual);
if (Utils.isNullOrUndefined(move) || move.move === Moves.STRUGGLE || move.move === Moves.NONE) {
if (isNullOrUndefined(move) || move.move === Moves.STRUGGLE || move.move === Moves.NONE) {
return;
}

View File

@ -2,7 +2,7 @@ import { getPokemonNameWithAffix } from "../messages";
import type Pokemon from "../field/pokemon";
import { HitResult } from "../field/pokemon";
import { getStatusEffectHealText } from "./status-effect";
import * as Utils from "../utils";
import { NumberHolder, toDmgValue, randSeedInt } from "#app/utils";
import {
DoubleBerryEffectAbAttr,
PostItemLostAbAttr,
@ -43,7 +43,7 @@ export function getBerryPredicate(berryType: BerryType): BerryPredicate {
case BerryType.APICOT:
case BerryType.SALAC:
return (pokemon: Pokemon) => {
const threshold = new Utils.NumberHolder(0.25);
const threshold = new NumberHolder(0.25);
// Offset BerryType such that LIECHI -> Stat.ATK = 1, GANLON -> Stat.DEF = 2, so on and so forth
const stat: BattleStat = berryType - BerryType.ENIGMA;
applyAbAttrs(ReduceBerryUseThresholdAbAttr, pokemon, null, false, threshold);
@ -51,19 +51,19 @@ export function getBerryPredicate(berryType: BerryType): BerryPredicate {
};
case BerryType.LANSAT:
return (pokemon: Pokemon) => {
const threshold = new Utils.NumberHolder(0.25);
const threshold = new NumberHolder(0.25);
applyAbAttrs(ReduceBerryUseThresholdAbAttr, pokemon, null, false, threshold);
return pokemon.getHpRatio() < 0.25 && !pokemon.getTag(BattlerTagType.CRIT_BOOST);
};
case BerryType.STARF:
return (pokemon: Pokemon) => {
const threshold = new Utils.NumberHolder(0.25);
const threshold = new NumberHolder(0.25);
applyAbAttrs(ReduceBerryUseThresholdAbAttr, pokemon, null, false, threshold);
return pokemon.getHpRatio() < 0.25;
};
case BerryType.LEPPA:
return (pokemon: Pokemon) => {
const threshold = new Utils.NumberHolder(0.25);
const threshold = new NumberHolder(0.25);
applyAbAttrs(ReduceBerryUseThresholdAbAttr, pokemon, null, false, threshold);
return !!pokemon.getMoveset().find(m => !m.getPpRatio());
};
@ -80,7 +80,7 @@ export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc {
if (pokemon.battleData) {
pokemon.battleData.berriesEaten.push(berryType);
}
const hpHealed = new Utils.NumberHolder(Utils.toDmgValue(pokemon.getMaxHp() / 4));
const hpHealed = new NumberHolder(toDmgValue(pokemon.getMaxHp() / 4));
applyAbAttrs(DoubleBerryEffectAbAttr, pokemon, null, false, hpHealed);
globalScene.unshiftPhase(
new PokemonHealPhase(
@ -118,7 +118,7 @@ export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc {
}
// Offset BerryType such that LIECHI -> Stat.ATK = 1, GANLON -> Stat.DEF = 2, so on and so forth
const stat: BattleStat = berryType - BerryType.ENIGMA;
const statStages = new Utils.NumberHolder(1);
const statStages = new NumberHolder(1);
applyAbAttrs(DoubleBerryEffectAbAttr, pokemon, null, false, statStages);
globalScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [stat], statStages.value));
applyPostItemLostAbAttrs(PostItemLostAbAttr, berryOwner ?? pokemon, false);
@ -136,8 +136,8 @@ export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc {
if (pokemon.battleData) {
pokemon.battleData.berriesEaten.push(berryType);
}
const randStat = Utils.randSeedInt(Stat.SPD, Stat.ATK);
const stages = new Utils.NumberHolder(2);
const randStat = randSeedInt(Stat.SPD, Stat.ATK);
const stages = new NumberHolder(2);
applyAbAttrs(DoubleBerryEffectAbAttr, pokemon, null, false, stages);
globalScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [randStat], stages.value));
applyPostItemLostAbAttrs(PostItemLostAbAttr, berryOwner ?? pokemon, false);

View File

@ -1,4 +1,4 @@
import * as Utils from "#app/utils";
import { BooleanHolder, type NumberHolder, randSeedItem, deepCopy } from "#app/utils";
import i18next from "i18next";
import type { DexAttrProps, GameData } from "#app/system/game-data";
import { defaultStarterSpecies } from "#app/system/game-data";
@ -283,30 +283,30 @@ export abstract class Challenge {
/**
* An apply function for STARTER_CHOICE challenges. Derived classes should alter this.
* @param _pokemon {@link PokemonSpecies} The pokemon to check the validity of.
* @param _valid {@link Utils.BooleanHolder} A BooleanHolder, the value gets set to false if the pokemon isn't allowed.
* @param _valid {@link BooleanHolder} A BooleanHolder, the value gets set to false if the pokemon isn't allowed.
* @param _dexAttr {@link DexAttrProps} The dex attributes of the pokemon.
* @returns {@link boolean} Whether this function did anything.
*/
applyStarterChoice(_pokemon: PokemonSpecies, _valid: Utils.BooleanHolder, _dexAttr: DexAttrProps): boolean {
applyStarterChoice(_pokemon: PokemonSpecies, _valid: BooleanHolder, _dexAttr: DexAttrProps): boolean {
return false;
}
/**
* An apply function for STARTER_POINTS challenges. Derived classes should alter this.
* @param _points {@link Utils.NumberHolder} The amount of points you have available.
* @param _points {@link NumberHolder} The amount of points you have available.
* @returns {@link boolean} Whether this function did anything.
*/
applyStarterPoints(_points: Utils.NumberHolder): boolean {
applyStarterPoints(_points: NumberHolder): boolean {
return false;
}
/**
* An apply function for STARTER_COST challenges. Derived classes should alter this.
* @param _species {@link Species} The pokemon to change the cost of.
* @param _cost {@link Utils.NumberHolder} The cost of the starter.
* @param _cost {@link NumberHolder} The cost of the starter.
* @returns {@link boolean} Whether this function did anything.
*/
applyStarterCost(_species: Species, _cost: Utils.NumberHolder): boolean {
applyStarterCost(_species: Species, _cost: NumberHolder): boolean {
return false;
}
@ -322,10 +322,10 @@ export abstract class Challenge {
/**
* An apply function for POKEMON_IN_BATTLE challenges. Derived classes should alter this.
* @param _pokemon {@link Pokemon} The pokemon to check the validity of.
* @param _valid {@link Utils.BooleanHolder} A BooleanHolder, the value gets set to false if the pokemon isn't allowed.
* @param _valid {@link BooleanHolder} A BooleanHolder, the value gets set to false if the pokemon isn't allowed.
* @returns {@link boolean} Whether this function did anything.
*/
applyPokemonInBattle(_pokemon: Pokemon, _valid: Utils.BooleanHolder): boolean {
applyPokemonInBattle(_pokemon: Pokemon, _valid: BooleanHolder): boolean {
return false;
}
@ -341,42 +341,42 @@ export abstract class Challenge {
/**
* An apply function for TYPE_EFFECTIVENESS challenges. Derived classes should alter this.
* @param _effectiveness {@linkcode Utils.NumberHolder} The current effectiveness of the move.
* @param _effectiveness {@linkcode NumberHolder} The current effectiveness of the move.
* @returns Whether this function did anything.
*/
applyTypeEffectiveness(_effectiveness: Utils.NumberHolder): boolean {
applyTypeEffectiveness(_effectiveness: NumberHolder): boolean {
return false;
}
/**
* An apply function for AI_LEVEL challenges. Derived classes should alter this.
* @param _level {@link Utils.NumberHolder} The generated level.
* @param _level {@link NumberHolder} The generated level.
* @param _levelCap {@link Number} The current level cap.
* @param _isTrainer {@link Boolean} Whether this is a trainer pokemon.
* @param _isBoss {@link Boolean} Whether this is a non-trainer boss pokemon.
* @returns {@link boolean} Whether this function did anything.
*/
applyLevelChange(_level: Utils.NumberHolder, _levelCap: number, _isTrainer: boolean, _isBoss: boolean): boolean {
applyLevelChange(_level: NumberHolder, _levelCap: number, _isTrainer: boolean, _isBoss: boolean): boolean {
return false;
}
/**
* An apply function for AI_MOVE_SLOTS challenges. Derived classes should alter this.
* @param pokemon {@link Pokemon} The pokemon that is being considered.
* @param moveSlots {@link Utils.NumberHolder} The amount of move slots.
* @param moveSlots {@link NumberHolder} The amount of move slots.
* @returns {@link boolean} Whether this function did anything.
*/
applyMoveSlot(_pokemon: Pokemon, _moveSlots: Utils.NumberHolder): boolean {
applyMoveSlot(_pokemon: Pokemon, _moveSlots: NumberHolder): boolean {
return false;
}
/**
* An apply function for PASSIVE_ACCESS challenges. Derived classes should alter this.
* @param pokemon {@link Pokemon} The pokemon to change.
* @param hasPassive {@link Utils.BooleanHolder} Whether it should have its passive.
* @param hasPassive {@link BooleanHolder} Whether it should have its passive.
* @returns {@link boolean} Whether this function did anything.
*/
applyPassiveAccess(_pokemon: Pokemon, _hasPassive: Utils.BooleanHolder): boolean {
applyPassiveAccess(_pokemon: Pokemon, _hasPassive: BooleanHolder): boolean {
return false;
}
@ -393,15 +393,10 @@ export abstract class Challenge {
* @param _pokemon {@link Pokemon} What pokemon would learn the move.
* @param _moveSource {@link MoveSourceType} What source the pokemon would get the move from.
* @param _move {@link Moves} The move in question.
* @param _level {@link Utils.NumberHolder} The level threshold for access.
* @param _level {@link NumberHolder} The level threshold for access.
* @returns {@link boolean} Whether this function did anything.
*/
applyMoveAccessLevel(
_pokemon: Pokemon,
_moveSource: MoveSourceType,
_move: Moves,
_level: Utils.NumberHolder,
): boolean {
applyMoveAccessLevel(_pokemon: Pokemon, _moveSource: MoveSourceType, _move: Moves, _level: NumberHolder): boolean {
return false;
}
@ -410,10 +405,10 @@ export abstract class Challenge {
* @param _pokemon {@link Pokemon} What pokemon would learn the move.
* @param _moveSource {@link MoveSourceType} What source the pokemon would get the move from.
* @param _move {@link Moves} The move in question.
* @param _weight {@link Utils.NumberHolder} The base weight of the move
* @param _weight {@link NumberHolder} The base weight of the move
* @returns {@link boolean} Whether this function did anything.
*/
applyMoveWeight(_pokemon: Pokemon, _moveSource: MoveSourceType, _move: Moves, _level: Utils.NumberHolder): boolean {
applyMoveWeight(_pokemon: Pokemon, _moveSource: MoveSourceType, _move: Moves, _level: NumberHolder): boolean {
return false;
}
@ -438,7 +433,7 @@ export class SingleGenerationChallenge extends Challenge {
super(Challenges.SINGLE_GENERATION, 9);
}
applyStarterChoice(pokemon: PokemonSpecies, valid: Utils.BooleanHolder): boolean {
applyStarterChoice(pokemon: PokemonSpecies, valid: BooleanHolder): boolean {
if (pokemon.generation !== this.value) {
valid.value = false;
return true;
@ -446,7 +441,7 @@ export class SingleGenerationChallenge extends Challenge {
return false;
}
applyPokemonInBattle(pokemon: Pokemon, valid: Utils.BooleanHolder): boolean {
applyPokemonInBattle(pokemon: Pokemon, valid: BooleanHolder): boolean {
const baseGeneration = getPokemonSpecies(pokemon.species.speciesId).generation;
const fusionGeneration = pokemon.isFusion() ? getPokemonSpecies(pokemon.fusionSpecies!.speciesId).generation : 0;
if (
@ -575,7 +570,7 @@ export class SingleGenerationChallenge extends Challenge {
TrainerType.AARON,
TrainerType.SHAUNTAL,
TrainerType.MALVA,
Utils.randSeedItem([TrainerType.HALA, TrainerType.MOLAYNE]),
randSeedItem([TrainerType.HALA, TrainerType.MOLAYNE]),
TrainerType.MARNIE_ELITE,
TrainerType.RIKA,
];
@ -602,7 +597,7 @@ export class SingleGenerationChallenge extends Challenge {
TrainerType.GRIMSLEY,
TrainerType.WIKSTROM,
TrainerType.ACEROLA,
Utils.randSeedItem([TrainerType.BEA_ELITE, TrainerType.ALLISTER_ELITE]),
randSeedItem([TrainerType.BEA_ELITE, TrainerType.ALLISTER_ELITE]),
TrainerType.LARRY_ELITE,
];
break;
@ -622,14 +617,14 @@ export class SingleGenerationChallenge extends Challenge {
case ClassicFixedBossWaves.CHAMPION:
trainerTypes = [
TrainerType.BLUE,
Utils.randSeedItem([TrainerType.RED, TrainerType.LANCE_CHAMPION]),
Utils.randSeedItem([TrainerType.STEVEN, TrainerType.WALLACE]),
randSeedItem([TrainerType.RED, TrainerType.LANCE_CHAMPION]),
randSeedItem([TrainerType.STEVEN, TrainerType.WALLACE]),
TrainerType.CYNTHIA,
Utils.randSeedItem([TrainerType.ALDER, TrainerType.IRIS]),
randSeedItem([TrainerType.ALDER, TrainerType.IRIS]),
TrainerType.DIANTHA,
Utils.randSeedItem([TrainerType.KUKUI, TrainerType.HAU]),
Utils.randSeedItem([TrainerType.LEON, TrainerType.MUSTARD]),
Utils.randSeedItem([TrainerType.GEETA, TrainerType.NEMONA]),
randSeedItem([TrainerType.KUKUI, TrainerType.HAU]),
randSeedItem([TrainerType.LEON, TrainerType.MUSTARD]),
randSeedItem([TrainerType.GEETA, TrainerType.NEMONA]),
];
break;
}
@ -718,7 +713,7 @@ export class SingleTypeChallenge extends Challenge {
super(Challenges.SINGLE_TYPE, 18);
}
override applyStarterChoice(pokemon: PokemonSpecies, valid: Utils.BooleanHolder, dexAttr: DexAttrProps): boolean {
override applyStarterChoice(pokemon: PokemonSpecies, valid: BooleanHolder, dexAttr: DexAttrProps): boolean {
const speciesForm = getPokemonSpeciesForm(pokemon.speciesId, dexAttr.formIndex);
const types = [speciesForm.type1, speciesForm.type2];
if (!types.includes(this.value - 1)) {
@ -728,7 +723,7 @@ export class SingleTypeChallenge extends Challenge {
return false;
}
applyPokemonInBattle(pokemon: Pokemon, valid: Utils.BooleanHolder): boolean {
applyPokemonInBattle(pokemon: Pokemon, valid: BooleanHolder): boolean {
if (
pokemon.isPlayer() &&
!pokemon.isOfType(this.value - 1, false, false, true) &&
@ -798,7 +793,7 @@ export class FreshStartChallenge extends Challenge {
super(Challenges.FRESH_START, 1);
}
applyStarterChoice(pokemon: PokemonSpecies, valid: Utils.BooleanHolder): boolean {
applyStarterChoice(pokemon: PokemonSpecies, valid: BooleanHolder): boolean {
if (!defaultStarterSpecies.includes(pokemon.speciesId)) {
valid.value = false;
return true;
@ -806,7 +801,7 @@ export class FreshStartChallenge extends Challenge {
return false;
}
applyStarterCost(species: Species, cost: Utils.NumberHolder): boolean {
applyStarterCost(species: Species, cost: NumberHolder): boolean {
if (defaultStarterSpecies.includes(species)) {
cost.value = speciesStarterCosts[species];
return true;
@ -864,7 +859,7 @@ export class InverseBattleChallenge extends Challenge {
return 0;
}
applyTypeEffectiveness(effectiveness: Utils.NumberHolder): boolean {
applyTypeEffectiveness(effectiveness: NumberHolder): boolean {
if (effectiveness.value < 1) {
effectiveness.value = 2;
return true;
@ -887,7 +882,7 @@ export class FlipStatChallenge extends Challenge {
}
override applyFlipStat(_pokemon: Pokemon, baseStats: number[]) {
const origStats = Utils.deepCopy(baseStats);
const origStats = deepCopy(baseStats);
baseStats[0] = origStats[5];
baseStats[1] = origStats[4];
baseStats[2] = origStats[3];
@ -923,7 +918,7 @@ export class LowerStarterMaxCostChallenge extends Challenge {
return (DEFAULT_PARTY_MAX_COST - overrideValue).toString();
}
applyStarterChoice(pokemon: PokemonSpecies, valid: Utils.BooleanHolder): boolean {
applyStarterChoice(pokemon: PokemonSpecies, valid: BooleanHolder): boolean {
if (speciesStarterCosts[pokemon.speciesId] > DEFAULT_PARTY_MAX_COST - this.value) {
valid.value = false;
return true;
@ -957,7 +952,7 @@ export class LowerStarterPointsChallenge extends Challenge {
return (DEFAULT_PARTY_MAX_COST - overrideValue).toString();
}
applyStarterPoints(points: Utils.NumberHolder): boolean {
applyStarterPoints(points: NumberHolder): boolean {
points.value -= this.value;
return true;
}
@ -974,34 +969,34 @@ export class LowerStarterPointsChallenge extends Challenge {
* Apply all challenges that modify starter choice.
* @param challengeType {@link ChallengeType} ChallengeType.STARTER_CHOICE
* @param pokemon {@link PokemonSpecies} The pokemon to check the validity of.
* @param valid {@link Utils.BooleanHolder} A BooleanHolder, the value gets set to false if the pokemon isn't allowed.
* @param valid {@link BooleanHolder} A BooleanHolder, the value gets set to false if the pokemon isn't allowed.
* @param dexAttr {@link DexAttrProps} The dex attributes of the pokemon.
* @returns True if any challenge was successfully applied.
*/
export function applyChallenges(
challengeType: ChallengeType.STARTER_CHOICE,
pokemon: PokemonSpecies,
valid: Utils.BooleanHolder,
valid: BooleanHolder,
dexAttr: DexAttrProps,
): boolean;
/**
* Apply all challenges that modify available total starter points.
* @param challengeType {@link ChallengeType} ChallengeType.STARTER_POINTS
* @param points {@link Utils.NumberHolder} The amount of points you have available.
* @param points {@link NumberHolder} The amount of points you have available.
* @returns True if any challenge was successfully applied.
*/
export function applyChallenges(challengeType: ChallengeType.STARTER_POINTS, points: Utils.NumberHolder): boolean;
export function applyChallenges(challengeType: ChallengeType.STARTER_POINTS, points: NumberHolder): boolean;
/**
* Apply all challenges that modify the cost of a starter.
* @param challengeType {@link ChallengeType} ChallengeType.STARTER_COST
* @param species {@link Species} The pokemon to change the cost of.
* @param points {@link Utils.NumberHolder} The cost of the pokemon.
* @param points {@link NumberHolder} The cost of the pokemon.
* @returns True if any challenge was successfully applied.
*/
export function applyChallenges(
challengeType: ChallengeType.STARTER_COST,
species: Species,
cost: Utils.NumberHolder,
cost: NumberHolder,
): boolean;
/**
* Apply all challenges that modify a starter after selection.
@ -1014,13 +1009,13 @@ export function applyChallenges(challengeType: ChallengeType.STARTER_MODIFY, pok
* Apply all challenges that what pokemon you can have in battle.
* @param challengeType {@link ChallengeType} ChallengeType.POKEMON_IN_BATTLE
* @param pokemon {@link Pokemon} The pokemon to check the validity of.
* @param valid {@link Utils.BooleanHolder} A BooleanHolder, the value gets set to false if the pokemon isn't allowed.
* @param valid {@link BooleanHolder} A BooleanHolder, the value gets set to false if the pokemon isn't allowed.
* @returns True if any challenge was successfully applied.
*/
export function applyChallenges(
challengeType: ChallengeType.POKEMON_IN_BATTLE,
pokemon: Pokemon,
valid: Utils.BooleanHolder,
valid: BooleanHolder,
): boolean;
/**
* Apply all challenges that modify what fixed battles there are.
@ -1037,17 +1032,14 @@ export function applyChallenges(
/**
* Apply all challenges that modify type effectiveness.
* @param challengeType {@linkcode ChallengeType} ChallengeType.TYPE_EFFECTIVENESS
* @param effectiveness {@linkcode Utils.NumberHolder} The current effectiveness of the move.
* @param effectiveness {@linkcode NumberHolder} The current effectiveness of the move.
* @returns True if any challenge was successfully applied.
*/
export function applyChallenges(
challengeType: ChallengeType.TYPE_EFFECTIVENESS,
effectiveness: Utils.NumberHolder,
): boolean;
export function applyChallenges(challengeType: ChallengeType.TYPE_EFFECTIVENESS, effectiveness: NumberHolder): boolean;
/**
* Apply all challenges that modify what level AI are.
* @param challengeType {@link ChallengeType} ChallengeType.AI_LEVEL
* @param level {@link Utils.NumberHolder} The generated level of the pokemon.
* @param level {@link NumberHolder} The generated level of the pokemon.
* @param levelCap {@link Number} The maximum level cap for the current wave.
* @param isTrainer {@link Boolean} Whether this is a trainer pokemon.
* @param isBoss {@link Boolean} Whether this is a non-trainer boss pokemon.
@ -1055,7 +1047,7 @@ export function applyChallenges(
*/
export function applyChallenges(
challengeType: ChallengeType.AI_LEVEL,
level: Utils.NumberHolder,
level: NumberHolder,
levelCap: number,
isTrainer: boolean,
isBoss: boolean,
@ -1064,25 +1056,25 @@ export function applyChallenges(
* Apply all challenges that modify how many move slots the AI has.
* @param challengeType {@link ChallengeType} ChallengeType.AI_MOVE_SLOTS
* @param pokemon {@link Pokemon} The pokemon being considered.
* @param moveSlots {@link Utils.NumberHolder} The amount of move slots.
* @param moveSlots {@link NumberHolder} The amount of move slots.
* @returns True if any challenge was successfully applied.
*/
export function applyChallenges(
challengeType: ChallengeType.AI_MOVE_SLOTS,
pokemon: Pokemon,
moveSlots: Utils.NumberHolder,
moveSlots: NumberHolder,
): boolean;
/**
* Apply all challenges that modify whether a pokemon has its passive.
* @param challengeType {@link ChallengeType} ChallengeType.PASSIVE_ACCESS
* @param pokemon {@link Pokemon} The pokemon to modify.
* @param hasPassive {@link Utils.BooleanHolder} Whether it has its passive.
* @param hasPassive {@link BooleanHolder} Whether it has its passive.
* @returns True if any challenge was successfully applied.
*/
export function applyChallenges(
challengeType: ChallengeType.PASSIVE_ACCESS,
pokemon: Pokemon,
hasPassive: Utils.BooleanHolder,
hasPassive: BooleanHolder,
): boolean;
/**
* Apply all challenges that modify the game modes settings.
@ -1096,7 +1088,7 @@ export function applyChallenges(challengeType: ChallengeType.GAME_MODE_MODIFY):
* @param pokemon {@link Pokemon} What pokemon would learn the move.
* @param moveSource {@link MoveSourceType} What source the pokemon would get the move from.
* @param move {@link Moves} The move in question.
* @param level {@link Utils.NumberHolder} The level threshold for access.
* @param level {@link NumberHolder} The level threshold for access.
* @returns True if any challenge was successfully applied.
*/
export function applyChallenges(
@ -1104,7 +1096,7 @@ export function applyChallenges(
pokemon: Pokemon,
moveSource: MoveSourceType,
move: Moves,
level: Utils.NumberHolder,
level: NumberHolder,
): boolean;
/**
* Apply all challenges that modify what weight a pokemon gives to move generation
@ -1112,7 +1104,7 @@ export function applyChallenges(
* @param pokemon {@link Pokemon} What pokemon would learn the move.
* @param moveSource {@link MoveSourceType} What source the pokemon would get the move from.
* @param move {@link Moves} The move in question.
* @param weight {@link Utils.NumberHolder} The weight of the move.
* @param weight {@link NumberHolder} The weight of the move.
* @returns True if any challenge was successfully applied.
*/
export function applyChallenges(
@ -1120,7 +1112,7 @@ export function applyChallenges(
pokemon: Pokemon,
moveSource: MoveSourceType,
move: Moves,
weight: Utils.NumberHolder,
weight: NumberHolder,
): boolean;
export function applyChallenges(challengeType: ChallengeType.FLIP_STAT, pokemon: Pokemon, baseStats: number[]): boolean;
@ -1225,7 +1217,7 @@ export function initChallenges() {
*/
export function checkStarterValidForChallenge(species: PokemonSpecies, props: DexAttrProps, soft: boolean) {
if (!soft) {
const isValidForChallenge = new Utils.BooleanHolder(true);
const isValidForChallenge = new BooleanHolder(true);
applyChallenges(ChallengeType.STARTER_CHOICE, species, isValidForChallenge, props);
return isValidForChallenge.value;
}
@ -1263,7 +1255,7 @@ export function checkStarterValidForChallenge(species: PokemonSpecies, props: De
* @returns `true` if the species is considered valid.
*/
function checkSpeciesValidForChallenge(species: PokemonSpecies, props: DexAttrProps, soft: boolean) {
const isValidForChallenge = new Utils.BooleanHolder(true);
const isValidForChallenge = new BooleanHolder(true);
applyChallenges(ChallengeType.STARTER_CHOICE, species, isValidForChallenge, props);
if (!soft || !pokemonFormChanges.hasOwnProperty(species.speciesId)) {
return isValidForChallenge.value;
@ -1282,7 +1274,7 @@ function checkSpeciesValidForChallenge(species: PokemonSpecies, props: DexAttrPr
return species.forms.some((f2, formIndex) => {
if (f1.formKey === f2.formKey) {
const formProps = { ...props, formIndex };
const isFormValidForChallenge = new Utils.BooleanHolder(true);
const isFormValidForChallenge = new BooleanHolder(true);
applyChallenges(ChallengeType.STARTER_CHOICE, species, isFormValidForChallenge, formProps);
return isFormValidForChallenge.value;
}

View File

@ -3,7 +3,7 @@ import type { Species } from "#enums/species";
import { globalScene } from "#app/global-scene";
import { PlayerPokemon } from "#app/field/pokemon";
import type { Starter } from "#app/ui/starter-select-ui-handler";
import * as Utils from "#app/utils";
import { randSeedGauss, randSeedInt, randSeedItem, getEnumValues } from "#app/utils";
import type { PokemonSpeciesForm } from "#app/data/pokemon-species";
import PokemonSpecies, { getPokemonSpecies, getPokemonSpeciesForm } from "#app/data/pokemon-species";
import { speciesStarterCosts } from "#app/data/balance/starters";
@ -43,8 +43,8 @@ export function getDailyRunStarters(seed: string): Starter[] {
}
const starterCosts: number[] = [];
starterCosts.push(Math.min(Math.round(3.5 + Math.abs(Utils.randSeedGauss(1))), 8));
starterCosts.push(Utils.randSeedInt(9 - starterCosts[0], 1));
starterCosts.push(Math.min(Math.round(3.5 + Math.abs(randSeedGauss(1))), 8));
starterCosts.push(randSeedInt(9 - starterCosts[0], 1));
starterCosts.push(10 - (starterCosts[0] + starterCosts[1]));
for (let c = 0; c < starterCosts.length; c++) {
@ -52,7 +52,7 @@ export function getDailyRunStarters(seed: string): Starter[] {
const costSpecies = Object.keys(speciesStarterCosts)
.map(s => Number.parseInt(s) as Species)
.filter(s => speciesStarterCosts[s] === cost);
const randPkmSpecies = getPokemonSpecies(Utils.randSeedItem(costSpecies));
const randPkmSpecies = getPokemonSpecies(randSeedItem(costSpecies));
const starterSpecies = getPokemonSpecies(
randPkmSpecies.getTrainerSpeciesForLevel(startingLevel, true, PartyMemberStrength.STRONGER),
);
@ -143,7 +143,7 @@ const dailyBiomeWeights: BiomeWeights = {
};
export function getDailyStartingBiome(): Biome {
const biomes = Utils.getEnumValues(Biome).filter(b => b !== Biome.TOWN && b !== Biome.END);
const biomes = getEnumValues(Biome).filter(b => b !== Biome.TOWN && b !== Biome.END);
let totalWeight = 0;
const biomeThresholds: number[] = [];
@ -155,7 +155,7 @@ export function getDailyStartingBiome(): Biome {
biomeThresholds.push(totalWeight);
}
const randInt = Utils.randSeedInt(totalWeight);
const randInt = randSeedInt(totalWeight);
for (let i = 0; i < biomes.length; i++) {
if (randInt < biomeThresholds[i]) {
@ -164,5 +164,5 @@ export function getDailyStartingBiome(): Biome {
}
// Fallback in case something went wrong
return biomes[Utils.randSeedInt(biomes.length)];
return biomes[randSeedInt(biomes.length)];
}

View File

@ -4,7 +4,7 @@ import type PokemonSpecies from "#app/data/pokemon-species";
import { getPokemonSpecies } from "#app/data/pokemon-species";
import { speciesStarterCosts } from "#app/data/balance/starters";
import { VariantTier } from "#enums/variant-tier";
import * as Utils from "#app/utils";
import { randInt, randomString, randSeedInt, getIvsFromId } from "#app/utils";
import Overrides from "#app/overrides";
import { pokemonPrevolutions } from "#app/data/balance/pokemon-evolutions";
import type { PlayerPokemon } from "#app/field/pokemon";
@ -171,7 +171,7 @@ export class Egg {
this.checkForPityTierOverrides();
}
this._id = eggOptions?.id ?? Utils.randInt(EGG_SEED, EGG_SEED * this._tier);
this._id = eggOptions?.id ?? randInt(EGG_SEED, EGG_SEED * this._tier);
this._sourceType = eggOptions?.sourceType ?? undefined;
this._hatchWaves = eggOptions?.hatchWaves ?? this.getEggTierDefaultHatchWaves();
@ -203,7 +203,7 @@ export class Egg {
}
};
const seedOverride = Utils.randomString(24);
const seedOverride = randomString(24);
globalScene.executeWithSeedOffset(
() => {
generateEggProperties(eggOptions);
@ -248,18 +248,15 @@ export class Egg {
let pokemonSpecies = getPokemonSpecies(this._species);
// Special condition to have Phione eggs also have a chance of generating Manaphy
if (this._species === Species.PHIONE && this._sourceType === EggSourceType.SAME_SPECIES_EGG) {
pokemonSpecies = getPokemonSpecies(
Utils.randSeedInt(MANAPHY_EGG_MANAPHY_RATE) ? Species.PHIONE : Species.MANAPHY,
);
pokemonSpecies = getPokemonSpecies(randSeedInt(MANAPHY_EGG_MANAPHY_RATE) ? Species.PHIONE : Species.MANAPHY);
}
// Sets the hidden ability if a hidden ability exists and
// the override is set or the egg hits the chance
let abilityIndex: number | undefined = undefined;
const sameSpeciesEggHACheck =
this._sourceType === EggSourceType.SAME_SPECIES_EGG && !Utils.randSeedInt(SAME_SPECIES_EGG_HA_RATE);
const gachaEggHACheck =
!(this._sourceType === EggSourceType.SAME_SPECIES_EGG) && !Utils.randSeedInt(GACHA_EGG_HA_RATE);
this._sourceType === EggSourceType.SAME_SPECIES_EGG && !randSeedInt(SAME_SPECIES_EGG_HA_RATE);
const gachaEggHACheck = !(this._sourceType === EggSourceType.SAME_SPECIES_EGG) && !randSeedInt(GACHA_EGG_HA_RATE);
if (pokemonSpecies.abilityHidden && (this._overrideHiddenAbility || sameSpeciesEggHACheck || gachaEggHACheck)) {
abilityIndex = 2;
}
@ -269,7 +266,7 @@ export class Egg {
ret.shiny = this._isShiny;
ret.variant = this._variantTier;
const secondaryIvs = Utils.getIvsFromId(Utils.randSeedInt(4294967295));
const secondaryIvs = getIvsFromId(randSeedInt(4294967295));
for (let s = 0; s < ret.ivs.length; s++) {
ret.ivs[s] = Math.max(ret.ivs[s], secondaryIvs[s]);
@ -370,7 +367,7 @@ export class Egg {
}
const tierMultiplier = this.isManaphyEgg() ? 2 : Math.pow(2, 3 - this.tier);
return Utils.randSeedInt(baseChance * tierMultiplier) ? Utils.randSeedInt(3) : 3;
return randSeedInt(baseChance * tierMultiplier) ? randSeedInt(3) : 3;
}
private getEggTierDefaultHatchWaves(eggTier?: EggTier): number {
@ -392,7 +389,7 @@ export class Egg {
private rollEggTier(): EggTier {
const tierValueOffset =
this._sourceType === EggSourceType.GACHA_LEGENDARY ? GACHA_LEGENDARY_UP_THRESHOLD_OFFSET : 0;
const tierValue = Utils.randInt(256);
const tierValue = randInt(256);
return tierValue >= GACHA_DEFAULT_COMMON_EGG_THRESHOLD + tierValueOffset
? EggTier.COMMON
: tierValue >= GACHA_DEFAULT_RARE_EGG_THRESHOLD + tierValueOffset
@ -417,11 +414,11 @@ export class Egg {
* when Utils.randSeedInt(8) = 1, and by making the generatePlayerPokemon() species
* check pass when Utils.randSeedInt(8) = 0, we can tell them apart during tests.
*/
const rand = Utils.randSeedInt(MANAPHY_EGG_MANAPHY_RATE) !== 1;
const rand = randSeedInt(MANAPHY_EGG_MANAPHY_RATE) !== 1;
return rand ? Species.PHIONE : Species.MANAPHY;
}
if (this.tier === EggTier.LEGENDARY && this._sourceType === EggSourceType.GACHA_LEGENDARY) {
if (!Utils.randSeedInt(2)) {
if (!randSeedInt(2)) {
return getLegendaryGachaSpeciesForTimestamp(this.timestamp);
}
}
@ -501,7 +498,7 @@ export class Egg {
let species: Species;
const rand = Utils.randSeedInt(totalWeight);
const rand = randSeedInt(totalWeight);
for (let s = 0; s < speciesWeights.length; s++) {
if (rand < speciesWeights[s]) {
species = speciesPool[s];
@ -539,7 +536,7 @@ export class Egg {
break;
}
return !Utils.randSeedInt(shinyChance);
return !randSeedInt(shinyChance);
}
// Uses the same logic as pokemon.generateVariant(). I would like to only have this logic in one
@ -550,7 +547,7 @@ export class Egg {
return VariantTier.STANDARD;
}
const rand = Utils.randSeedInt(10);
const rand = randSeedInt(10);
if (rand >= SHINY_VARIANT_CHANCE) {
return VariantTier.STANDARD; // 6/10
}

File diff suppressed because it is too large Load Diff

View File

@ -12,7 +12,7 @@ import { modifierTypes } from "#app/modifier/modifier-type";
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
import { PartyMemberStrength } from "#enums/party-member-strength";
import { globalScene } from "#app/global-scene";
import * as Utils from "#app/utils";
import { randSeedInt } from "#app/utils";
import type MysteryEncounter from "#app/data/mystery-encounters/mystery-encounter";
import { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
@ -46,7 +46,7 @@ export const MysteriousChallengersEncounter: MysteryEncounter = MysteryEncounter
const normalConfig = trainerConfigs[normalTrainerType].clone();
let female = false;
if (normalConfig.hasGenders) {
female = !!Utils.randSeedInt(2);
female = !!randSeedInt(2);
}
const normalSpriteKey = normalConfig.getSpriteKey(female, normalConfig.doubleOnly);
encounter.enemyPartyConfigs.push({
@ -76,7 +76,7 @@ export const MysteriousChallengersEncounter: MysteryEncounter = MysteryEncounter
hardConfig.setPartyTemplates(hardTemplate);
female = false;
if (hardConfig.hasGenders) {
female = !!Utils.randSeedInt(2);
female = !!randSeedInt(2);
}
const hardSpriteKey = hardConfig.getSpriteKey(female, hardConfig.doubleOnly);
encounter.enemyPartyConfigs.push({
@ -96,7 +96,7 @@ export const MysteriousChallengersEncounter: MysteryEncounter = MysteryEncounter
brutalConfig.partyTemplateFunc = null; // Overrides gym leader party template func
female = false;
if (brutalConfig.hasGenders) {
female = !!Utils.randSeedInt(2);
female = !!randSeedInt(2);
}
const brutalSpriteKey = brutalConfig.getSpriteKey(female, brutalConfig.doubleOnly);
encounter.enemyPartyConfigs.push({

View File

@ -5,7 +5,7 @@ import { capitalizeFirstLetter, isNullOrUndefined } from "#app/utils";
import type { MysteryEncounterType } from "#enums/mystery-encounter-type";
import type { MysteryEncounterSpriteConfig } from "#app/field/mystery-encounter-intro";
import MysteryEncounterIntroVisuals from "#app/field/mystery-encounter-intro";
import * as Utils from "#app/utils";
import { randSeedInt } from "#app/utils";
import type { StatusEffect } from "#enums/status-effect";
import type { OptionTextDisplay } from "./mystery-encounter-dialogue";
import type MysteryEncounterDialogue from "./mystery-encounter-dialogue";
@ -378,13 +378,13 @@ export default class MysteryEncounter implements IMysteryEncounter {
}
if (truePrimaryPool.length > 0) {
// Always choose from the non-overlapping pokemon first
this.primaryPokemon = truePrimaryPool[Utils.randSeedInt(truePrimaryPool.length, 0)];
this.primaryPokemon = truePrimaryPool[randSeedInt(truePrimaryPool.length, 0)];
return true;
}
// If there are multiple overlapping pokemon, we're okay - just choose one and take it out of the primary pokemon pool
if (overlap.length > 1 || this.secondaryPokemon.length - overlap.length >= 1) {
// is this working?
this.primaryPokemon = overlap[Utils.randSeedInt(overlap.length, 0)];
this.primaryPokemon = overlap[randSeedInt(overlap.length, 0)];
this.secondaryPokemon = this.secondaryPokemon.filter(supp => supp !== this.primaryPokemon);
return true;
}
@ -394,7 +394,7 @@ export default class MysteryEncounter implements IMysteryEncounter {
return false;
}
// this means we CAN have the same pokemon be a primary and secondary pokemon, so just choose any qualifying one randomly.
this.primaryPokemon = qualified[Utils.randSeedInt(qualified.length, 0)];
this.primaryPokemon = qualified[randSeedInt(qualified.length, 0)];
return true;
}

View File

@ -30,8 +30,7 @@ import type { OptionSelectConfig, OptionSelectItem } from "#app/ui/abstact-optio
import type { PartyOption, PokemonSelectFilter } from "#app/ui/party-ui-handler";
import { PartyUiMode } from "#app/ui/party-ui-handler";
import { Mode } from "#app/ui/ui";
import * as Utils from "#app/utils";
import { isNullOrUndefined, randSeedInt, randSeedItem } from "#app/utils";
import { isNullOrUndefined, randSeedInt, randomString, randSeedItem } from "#app/utils";
import type { BattlerTagType } from "#enums/battler-tag-type";
import { Biome } from "#enums/biome";
import type { TrainerType } from "#enums/trainer-type";
@ -168,7 +167,7 @@ export async function initBattleWithEnemyConfig(partyConfig: EnemyPartyConfig):
const doubleTrainer = trainerConfig.doubleOnly || (trainerConfig.hasDouble && !!partyConfig.doubleBattle);
doubleBattle = doubleTrainer;
const trainerFemale = isNullOrUndefined(partyConfig.female) ? !!Utils.randSeedInt(2) : partyConfig.female;
const trainerFemale = isNullOrUndefined(partyConfig.female) ? !!randSeedInt(2) : partyConfig.female;
const newTrainer = new Trainer(
trainerConfig.trainerType,
doubleTrainer ? TrainerVariant.DOUBLE : trainerFemale ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT,
@ -286,7 +285,7 @@ export async function initBattleWithEnemyConfig(partyConfig: EnemyPartyConfig):
// Generate new id, reset status and HP in case using data source
if (config.dataSource) {
enemyPokemon.id = Utils.randSeedInt(4294967296);
enemyPokemon.id = randSeedInt(4294967296);
}
// Set form
@ -1115,7 +1114,7 @@ export function calculateMEAggregateStats(baseSpawnWeight: number) {
const validMEfloorsByBiome = new Map<string, number>(biomes.map(b => [b, 0]));
let currentBiome = Biome.TOWN;
let currentArena = globalScene.newArena(currentBiome);
globalScene.setSeed(Utils.randomString(24));
globalScene.setSeed(randomString(24));
globalScene.resetSeed();
for (let i = 10; i < 180; i++) {
// Boss
@ -1130,16 +1129,16 @@ export function calculateMEAggregateStats(baseSpawnWeight: number) {
globalScene.executeWithSeedOffset(() => {
biomes = (biomeLinks[currentBiome] as (Biome | [Biome, number])[])
.filter(b => {
return !Array.isArray(b) || !Utils.randSeedInt(b[1]);
return !Array.isArray(b) || !randSeedInt(b[1]);
})
.map(b => (!Array.isArray(b) ? b : b[0]));
}, i * 100);
if (biomes! && biomes.length > 0) {
const specialBiomes = biomes.filter(b => alwaysPickTheseBiomes.includes(b));
if (specialBiomes.length > 0) {
currentBiome = specialBiomes[Utils.randSeedInt(specialBiomes.length)];
currentBiome = specialBiomes[randSeedInt(specialBiomes.length)];
} else {
currentBiome = biomes[Utils.randSeedInt(biomes.length)];
currentBiome = biomes[randSeedInt(biomes.length)];
}
}
} else if (biomeLinks.hasOwnProperty(currentBiome)) {
@ -1167,7 +1166,7 @@ export function calculateMEAggregateStats(baseSpawnWeight: number) {
// Otherwise, roll encounter
const roll = Utils.randSeedInt(256);
const roll = randSeedInt(256);
validMEfloorsByBiome.set(Biome[currentBiome], (validMEfloorsByBiome.get(Biome[currentBiome]) ?? 0) + 1);
// If total number of encounters is lower than expected for the run, slightly favor a new encounter
@ -1192,7 +1191,7 @@ export function calculateMEAggregateStats(baseSpawnWeight: number) {
tierWeights[1] = tierWeights[1] - 4 * numEncounters[1];
const totalWeight = tierWeights.reduce((a, b) => a + b);
const tierValue = Utils.randSeedInt(totalWeight);
const tierValue = randSeedInt(totalWeight);
const commonThreshold = totalWeight - tierWeights[0]; // 64 - 32 = 32
const uncommonThreshold = totalWeight - tierWeights[0] - tierWeights[1]; // 64 - 32 - 16 = 16
const rareThreshold = totalWeight - tierWeights[0] - tierWeights[1] - tierWeights[2]; // 64 - 32 - 16 - 10 = 6
@ -1281,7 +1280,7 @@ export function calculateRareSpawnAggregateStats(luckValue: number) {
const calculateNumRareEncounters = (): any[] => {
const bossEncountersByRarity = [0, 0, 0, 0];
globalScene.setSeed(Utils.randomString(24));
globalScene.setSeed(randomString(24));
globalScene.resetSeed();
// There are 12 wild boss floors
for (let i = 0; i < 12; i++) {
@ -1291,7 +1290,7 @@ export function calculateRareSpawnAggregateStats(luckValue: number) {
if (!Number.isNaN(luckValue)) {
luckModifier = luckValue * 0.5;
}
const tierValue = Utils.randSeedInt(64 - luckModifier);
const tierValue = randSeedInt(64 - luckModifier);
const tier =
tierValue >= 20
? BiomePoolTier.BOSS

View File

@ -1,4 +1,4 @@
import * as Utils from "../utils";
import { toReadableString } from "#app/utils";
import { TextStyle, getBBCodeFrag } from "../ui/text";
import { Nature } from "#enums/nature";
import { UiTheme } from "#enums/ui-theme";
@ -12,7 +12,7 @@ export function getNatureName(
ignoreBBCode = false,
uiTheme: UiTheme = UiTheme.DEFAULT,
): string {
let ret = Utils.toReadableString(Nature[nature]);
let ret = toReadableString(Nature[nature]);
//Translating nature
if (i18next.exists(`nature:${ret}`)) {
ret = i18next.t(`nature:${ret}` as any);

View File

@ -8,7 +8,7 @@ import type { AnySound } from "#app/battle-scene";
import { globalScene } from "#app/global-scene";
import type { GameMode } from "#app/game-mode";
import { DexAttr, type StarterMoveset } from "#app/system/game-data";
import * as Utils from "#app/utils";
import { isNullOrUndefined, capitalizeString, randSeedInt, randSeedGauss, randSeedItem } from "#app/utils";
import { uncatchableSpecies } from "#app/data/balance/biomes";
import { speciesEggMoves } from "#app/data/balance/egg-moves";
import { GrowthRate } from "#app/data/exp";
@ -290,7 +290,7 @@ export abstract class PokemonSpeciesForm {
* @returns The id of the ability
*/
getPassiveAbility(formIndex?: number): Abilities {
if (Utils.isNullOrUndefined(formIndex)) {
if (isNullOrUndefined(formIndex)) {
formIndex = this.formIndex;
}
let starterSpeciesId = this.speciesId;
@ -626,7 +626,7 @@ export abstract class PokemonSpeciesForm {
const spritePath = this.getSpriteAtlasPath(female, formIndex, shiny, variant, back)
.replace("variant/", "")
.replace(/_[1-3]$/, "");
if (!Utils.isNullOrUndefined(variant)) {
if (!isNullOrUndefined(variant)) {
loadPokemonVariantAssets(spriteKey, spritePath, variant).then(() => resolve());
}
});
@ -852,8 +852,8 @@ export default class PokemonSpecies extends PokemonSpeciesForm implements Locali
*/
getFormNameToDisplay(formIndex = 0, append = false): string {
const formKey = this.forms?.[formIndex!]?.formKey;
const formText = Utils.capitalizeString(formKey, "-", false, false) || "";
const speciesName = Utils.capitalizeString(Species[this.speciesId], "_", true, false);
const formText = capitalizeString(formKey, "-", false, false) || "";
const speciesName = capitalizeString(Species[this.speciesId], "_", true, false);
let ret = "";
const region = this.getRegion();
@ -884,7 +884,7 @@ export default class PokemonSpecies extends PokemonSpeciesForm implements Locali
if (i18next.exists(i18key)) {
ret = i18next.t(i18key);
} else {
const rootSpeciesName = Utils.capitalizeString(Species[this.getRootSpeciesId()], "_", true, false);
const rootSpeciesName = capitalizeString(Species[this.getRootSpeciesId()], "_", true, false);
const i18RootKey = `pokemonForm:${rootSpeciesName}${formText}`;
ret = i18next.exists(i18RootKey) ? i18next.t(i18RootKey) : formText;
}
@ -1079,7 +1079,7 @@ export default class PokemonSpecies extends PokemonSpeciesForm implements Locali
return this.speciesId;
}
const randValue = evolutionPool.size === 1 ? 0 : Utils.randSeedInt(totalWeight);
const randValue = evolutionPool.size === 1 ? 0 : randSeedInt(totalWeight);
for (const weight of evolutionPool.keys()) {
if (randValue < weight) {
@ -1164,7 +1164,7 @@ export default class PokemonSpecies extends PokemonSpeciesForm implements Locali
Math.min(
Math.max(
evolution?.level! +
Math.round(Utils.randSeedGauss(0.5, 1 + levelDiff * 0.2) * Math.max(evolution?.wildDelay!, 0.5) * 5) -
Math.round(randSeedGauss(0.5, 1 + levelDiff * 0.2) * Math.max(evolution?.wildDelay!, 0.5) * 5) -
1,
2,
evolution?.level!,
@ -1182,7 +1182,7 @@ export default class PokemonSpecies extends PokemonSpeciesForm implements Locali
Math.min(
Math.max(
lastPrevolutionLevel +
Math.round(Utils.randSeedGauss(0.5, 1 + levelDiff * 0.2) * Math.max(evolution?.wildDelay!, 0.5) * 5),
Math.round(randSeedGauss(0.5, 1 + levelDiff * 0.2) * Math.max(evolution?.wildDelay!, 0.5) * 5),
lastPrevolutionLevel + 1,
evolution?.level!,
),
@ -1367,7 +1367,7 @@ export function getPokerusStarters(): PokemonSpecies[] {
globalScene.executeWithSeedOffset(
() => {
while (pokerusStarters.length < POKERUS_STARTER_COUNT) {
const randomSpeciesId = Number.parseInt(Utils.randSeedItem(Object.keys(speciesStarterCosts)), 10);
const randomSpeciesId = Number.parseInt(randSeedItem(Object.keys(speciesStarterCosts)), 10);
const species = getPokemonSpecies(randomSpeciesId);
if (!pokerusStarters.includes(species)) {
pokerusStarters.push(species);

View File

@ -1,12 +1,12 @@
import { TrainerType } from "#enums/trainer-type";
import * as Utils from "../utils";
import { toReadableString } from "#app/utils";
class TrainerNameConfig {
public urls: string[];
public femaleUrls: string[] | null;
constructor(type: TrainerType, ...urls: string[]) {
this.urls = urls.length ? urls : [Utils.toReadableString(TrainerType[type]).replace(/ /g, "_")];
this.urls = urls.length ? urls : [toReadableString(TrainerType[type]).replace(/ /g, "_")];
}
hasGenderVariant(...femaleUrls: string[]): TrainerNameConfig {

View File

@ -1,7 +1,7 @@
import { globalScene } from "#app/global-scene";
import { modifierTypes } from "#app/modifier/modifier-type";
import { PokemonMove } from "#app/field/pokemon";
import * as Utils from "#app/utils";
import { toReadableString, isNullOrUndefined, randSeedItem, randSeedInt } from "#app/utils";
import { pokemonEvolutions, pokemonPrevolutions } from "#app/data/balance/pokemon-evolutions";
import { getPokemonSpecies } from "#app/data/pokemon-species";
import { tmSpecies } from "#app/data/balance/tms";
@ -139,7 +139,7 @@ export class TrainerConfig {
constructor(trainerType: TrainerType, allowLegendaries?: boolean) {
this.trainerType = trainerType;
this.trainerAI = new TrainerAI();
this.name = Utils.toReadableString(TrainerType[this.getDerivedType()]);
this.name = toReadableString(TrainerType[this.getDerivedType()]);
this.battleBgm = "battle_trainer";
this.mixedBattleBgm = "battle_trainer";
this.victoryBgm = "victory_trainer";
@ -482,10 +482,10 @@ export class TrainerConfig {
.fill(null)
.map((_, i) => i)
.filter(i => shedinjaCanTera || party[i].species.speciesId !== Species.SHEDINJA); // Shedinja can only Tera on Bug specialty type (or no specialty type)
const setPartySlot = !Utils.isNullOrUndefined(slot) ? Phaser.Math.Wrap(slot, 0, party.length) : -1; // If we have a tera slot defined, wrap it to party size.
const setPartySlot = !isNullOrUndefined(slot) ? Phaser.Math.Wrap(slot, 0, party.length) : -1; // If we have a tera slot defined, wrap it to party size.
for (let t = 0; t < Math.min(count(), party.length); t++) {
const randomIndex =
partyMemberIndexes.indexOf(setPartySlot) > -1 ? setPartySlot : Utils.randSeedItem(partyMemberIndexes);
partyMemberIndexes.indexOf(setPartySlot) > -1 ? setPartySlot : randSeedItem(partyMemberIndexes);
partyMemberIndexes.splice(partyMemberIndexes.indexOf(randomIndex), 1);
if (this.hasSpecialtyType()) {
party[randomIndex].teraType = this.specialtyType;
@ -555,7 +555,7 @@ export class TrainerConfig {
initI18n();
}
if (!Utils.isNullOrUndefined(specialtyType)) {
if (!isNullOrUndefined(specialtyType)) {
this.setSpecialtyType(specialtyType);
}
@ -636,7 +636,7 @@ export class TrainerConfig {
}
this.setPartyMemberFunc(-(s + 1), getRandomPartyMemberFunc(speciesPool));
});
if (!Utils.isNullOrUndefined(specialtyType)) {
if (!isNullOrUndefined(specialtyType)) {
this.setSpeciesFilter(p => p.isOfType(specialtyType));
this.setSpecialtyType(specialtyType);
}
@ -749,7 +749,7 @@ export class TrainerConfig {
});
// Set species filter and specialty type if provided, otherwise filter by base total.
if (!Utils.isNullOrUndefined(specialtyType)) {
if (!isNullOrUndefined(specialtyType)) {
this.setSpeciesFilter(p => p.isOfType(specialtyType) && p.baseTotal >= ELITE_FOUR_MINIMUM_BST);
this.setSpecialtyType(specialtyType);
} else {
@ -927,7 +927,7 @@ export class TrainerConfig {
* @returns true if specialtyType is defined and not Type.UNKNOWN
*/
hasSpecialtyType(): boolean {
return !Utils.isNullOrUndefined(this.specialtyType) && this.specialtyType !== PokemonType.UNKNOWN;
return !isNullOrUndefined(this.specialtyType) && this.specialtyType !== PokemonType.UNKNOWN;
}
/**
@ -1006,7 +1006,7 @@ export function getRandomPartyMemberFunc(
postProcess?: (enemyPokemon: EnemyPokemon) => void,
) {
return (level: number, strength: PartyMemberStrength) => {
let species = Utils.randSeedItem(speciesPool);
let species = randSeedItem(speciesPool);
if (!ignoreEvolution) {
species = getPokemonSpecies(species).getTrainerSpeciesForLevel(
level,
@ -3549,7 +3549,7 @@ export const trainerConfigs: TrainerConfigs = {
.setPartyMemberFunc(
5,
getRandomPartyMemberFunc([Species.URSHIFU], TrainerSlot.TRAINER, true, p => {
p.formIndex = Utils.randSeedInt(2, 2); // Random G-Max Urshifu
p.formIndex = randSeedInt(2, 2); // Random G-Max Urshifu
p.generateAndPopulateMoveset();
p.generateName();
p.gender = Gender.MALE;
@ -3659,10 +3659,10 @@ export const trainerConfigs: TrainerConfigs = {
.setPartyMemberFunc(
4,
getRandomPartyMemberFunc([Species.OGERPON], TrainerSlot.TRAINER, true, p => {
p.formIndex = Utils.randSeedInt(4); // Random Ogerpon Tera Mask
p.formIndex = randSeedInt(4); // Random Ogerpon Tera Mask
p.generateAndPopulateMoveset();
p.pokeball = PokeballType.ULTRA_BALL;
if (!p.moveset.some(move => !Utils.isNullOrUndefined(move) && move.moveId === Moves.IVY_CUDGEL)) {
if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.IVY_CUDGEL)) {
// Check if Ivy Cudgel is in the moveset, if not, replace the first move with Ivy Cudgel.
p.moveset[0] = new PokemonMove(Moves.IVY_CUDGEL);
}
@ -4713,10 +4713,10 @@ export const trainerConfigs: TrainerConfigs = {
.setPartyMemberFunc(
2,
getRandomPartyMemberFunc([Species.SILVALLY], TrainerSlot.TRAINER, true, p => {
p.formIndex = Utils.randSeedInt(18); // Random Silvally Form
p.formIndex = randSeedInt(18); // Random Silvally Form
p.generateAndPopulateMoveset();
p.pokeball = PokeballType.ROGUE_BALL;
if (!p.moveset.some(move => !Utils.isNullOrUndefined(move) && move.moveId === Moves.MULTI_ATTACK)) {
if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.MULTI_ATTACK)) {
// Check if Multi Attack is in the moveset, if not, replace the first move with Multi Attack.
p.moveset[0] = new PokemonMove(Moves.MULTI_ATTACK);
}
@ -4833,8 +4833,8 @@ export const trainerConfigs: TrainerConfigs = {
p.setBoss(true, 2);
p.generateAndPopulateMoveset();
p.pokeball = PokeballType.ULTRA_BALL;
p.formIndex = Utils.randSeedInt(4, 1); // Shock, Burn, Chill, or Douse Drive
if (!p.moveset.some(move => !Utils.isNullOrUndefined(move) && move.moveId === Moves.TECHNO_BLAST)) {
p.formIndex = randSeedInt(4, 1); // Shock, Burn, Chill, or Douse Drive
if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.TECHNO_BLAST)) {
// Check if Techno Blast is in the moveset, if not, replace the first move with Techno Blast.
p.moveset[2] = new PokemonMove(Moves.TECHNO_BLAST);
}
@ -5006,7 +5006,7 @@ export const trainerConfigs: TrainerConfigs = {
1,
getRandomPartyMemberFunc([Species.ROTOM], TrainerSlot.TRAINER, true, p => {
p.generateAndPopulateMoveset();
p.formIndex = Utils.randSeedInt(5, 1); // Heat, Wash, Frost, Fan, or Mow
p.formIndex = randSeedInt(5, 1); // Heat, Wash, Frost, Fan, or Mow
}),
)
.setPartyMemberFunc(
@ -5019,7 +5019,7 @@ export const trainerConfigs: TrainerConfigs = {
.setPartyMemberFunc(
3,
getRandomPartyMemberFunc([Species.REVAVROOM], TrainerSlot.TRAINER, true, p => {
p.formIndex = Utils.randSeedInt(5, 1); // Random Starmobile form
p.formIndex = randSeedInt(5, 1); // Random Starmobile form
p.generateAndPopulateMoveset();
p.pokeball = PokeballType.ROGUE_BALL;
}),

View File

@ -5,7 +5,7 @@ import type Pokemon from "../field/pokemon";
import { PokemonType } from "#enums/pokemon-type";
import type Move from "./moves/move";
import { AttackMove } from "./moves/move";
import * as Utils from "../utils";
import { randSeedInt } from "#app/utils";
import { SuppressWeatherEffectAbAttr } from "./ability";
import { TerrainType, getTerrainName } from "./terrain";
import i18next from "i18next";
@ -416,7 +416,7 @@ export function getRandomWeatherType(arena: Arena): WeatherType {
totalWeight += w.weight;
}
const rand = Utils.randSeedInt(totalWeight);
const rand = randSeedInt(totalWeight);
let w = 0;
for (const weather of weatherPool) {
w += weather.weight;

View File

@ -1,8 +1,7 @@
import { globalScene } from "#app/global-scene";
import type { BiomeTierTrainerPools, PokemonPools } from "#app/data/balance/biomes";
import { biomePokemonPools, BiomePoolTier, biomeTrainerPools } from "#app/data/balance/biomes";
import type { Constructor } from "#app/utils";
import * as Utils from "#app/utils";
import { randSeedInt, NumberHolder, isNullOrUndefined, type Constructor } from "#app/utils";
import type PokemonSpecies from "#app/data/pokemon-species";
import { getPokemonSpecies } from "#app/data/pokemon-species";
import {
@ -124,7 +123,7 @@ export class Arena {
if (typeof luckValue !== "undefined") {
luckModifier = luckValue * (isBossSpecies ? 0.5 : 2);
}
const tierValue = Utils.randSeedInt(randVal - luckModifier);
const tierValue = randSeedInt(randVal - luckModifier);
let tier = !isBossSpecies
? tierValue >= 156
? BiomePoolTier.COMMON
@ -153,7 +152,7 @@ export class Arena {
if (!tierPool.length) {
ret = globalScene.randomSpecies(waveIndex, level);
} else {
const entry = tierPool[Utils.randSeedInt(tierPool.length)];
const entry = tierPool[randSeedInt(tierPool.length)];
let species: Species;
if (typeof entry === "number") {
species = entry as Species;
@ -164,7 +163,7 @@ export class Arena {
if (level >= levelThreshold) {
const speciesIds = entry[levelThreshold];
if (speciesIds.length > 1) {
species = speciesIds[Utils.randSeedInt(speciesIds.length)];
species = speciesIds[randSeedInt(speciesIds.length)];
} else {
species = speciesIds[0];
}
@ -211,7 +210,7 @@ export class Arena {
!!this.trainerPool[BiomePoolTier.BOSS].length &&
(globalScene.gameMode.isTrainerBoss(waveIndex, this.biomeType, globalScene.offsetGym) || isBoss);
console.log(isBoss, this.trainerPool);
const tierValue = Utils.randSeedInt(!isTrainerBoss ? 512 : 64);
const tierValue = randSeedInt(!isTrainerBoss ? 512 : 64);
let tier = !isTrainerBoss
? tierValue >= 156
? BiomePoolTier.COMMON
@ -235,7 +234,7 @@ export class Arena {
tier--;
}
const tierPool = this.trainerPool[tier] || [];
return !tierPool.length ? TrainerType.BREEDER : tierPool[Utils.randSeedInt(tierPool.length)];
return !tierPool.length ? TrainerType.BREEDER : tierPool[randSeedInt(tierPool.length)];
}
getSpeciesFormIndex(species: PokemonSpecies): number {
@ -336,9 +335,9 @@ export class Arena {
return false;
}
const weatherDuration = new Utils.NumberHolder(0);
const weatherDuration = new NumberHolder(0);
if (!Utils.isNullOrUndefined(user)) {
if (!isNullOrUndefined(user)) {
weatherDuration.value = 5;
globalScene.applyModifier(FieldEffectModifier, user.isPlayer(), user, weatherDuration);
}
@ -417,9 +416,9 @@ export class Arena {
const oldTerrainType = this.terrain?.terrainType || TerrainType.NONE;
const terrainDuration = new Utils.NumberHolder(0);
const terrainDuration = new NumberHolder(0);
if (!Utils.isNullOrUndefined(user)) {
if (!isNullOrUndefined(user)) {
terrainDuration.value = 5;
globalScene.applyModifier(FieldEffectModifier, user.isPlayer(), user, terrainDuration);
}
@ -1013,7 +1012,7 @@ export class ArenaBase extends Phaser.GameObjects.Container {
if (!this.player) {
globalScene.executeWithSeedOffset(
() => {
this.propValue = propValue === undefined ? (hasProps ? Utils.randSeedInt(8) : 0) : propValue;
this.propValue = propValue === undefined ? (hasProps ? randSeedInt(8) : 0) : propValue;
this.props.forEach((prop, p) => {
const propKey = `${biomeKey}_b${hasProps ? `_${p + 1}` : ""}`;
prop.setTexture(propKey);

View File

@ -2,7 +2,7 @@ import { TextStyle, addTextObject } from "../ui/text";
import type { DamageResult } from "./pokemon";
import type Pokemon from "./pokemon";
import { HitResult } from "./pokemon";
import * as Utils from "../utils";
import { formatStat, fixedInt } from "#app/utils";
import type { BattlerIndex } from "../battle";
import { globalScene } from "#app/global-scene";
@ -30,7 +30,7 @@ export default class DamageNumberHandler {
const damageNumber = addTextObject(
target.x,
-(globalScene.game.canvas.height / 6) + target.y - target.getSprite().height / 2,
Utils.formatStat(amount, true),
formatStat(amount, true),
TextStyle.SUMMARY,
);
damageNumber.setName("text-damage-number");
@ -86,14 +86,14 @@ export default class DamageNumberHandler {
if (globalScene.damageNumbersMode === 1) {
globalScene.tweens.add({
targets: damageNumber,
duration: Utils.fixedInt(750),
duration: fixedInt(750),
alpha: 1,
y: "-=32",
});
globalScene.tweens.add({
delay: 375,
targets: damageNumber,
duration: Utils.fixedInt(625),
duration: fixedInt(625),
alpha: 0,
ease: "Sine.easeIn",
onComplete: () => {
@ -110,7 +110,7 @@ export default class DamageNumberHandler {
targets: damageNumber,
tweens: [
{
duration: Utils.fixedInt(250),
duration: fixedInt(250),
alpha: 1,
scaleX: 0.75 * baseScale,
scaleY: 1.25 * baseScale,
@ -118,7 +118,7 @@ export default class DamageNumberHandler {
ease: "Cubic.easeOut",
},
{
duration: Utils.fixedInt(175),
duration: fixedInt(175),
alpha: 1,
scaleX: 0.875 * baseScale,
scaleY: 1.125 * baseScale,
@ -126,59 +126,59 @@ export default class DamageNumberHandler {
ease: "Cubic.easeIn",
},
{
duration: Utils.fixedInt(100),
duration: fixedInt(100),
scaleX: 1.25 * baseScale,
scaleY: 0.75 * baseScale,
ease: "Cubic.easeOut",
},
{
duration: Utils.fixedInt(175),
duration: fixedInt(175),
scaleX: 0.875 * baseScale,
scaleY: 1.125 * baseScale,
y: "-=8",
ease: "Cubic.easeOut",
},
{
duration: Utils.fixedInt(50),
duration: fixedInt(50),
scaleX: 0.925 * baseScale,
scaleY: 1.075 * baseScale,
y: "+=8",
ease: "Cubic.easeIn",
},
{
duration: Utils.fixedInt(100),
duration: fixedInt(100),
scaleX: 1.125 * baseScale,
scaleY: 0.875 * baseScale,
ease: "Cubic.easeOut",
},
{
duration: Utils.fixedInt(175),
duration: fixedInt(175),
scaleX: 0.925 * baseScale,
scaleY: 1.075 * baseScale,
y: "-=4",
ease: "Cubic.easeOut",
},
{
duration: Utils.fixedInt(50),
duration: fixedInt(50),
scaleX: 0.975 * baseScale,
scaleY: 1.025 * baseScale,
y: "+=4",
ease: "Cubic.easeIn",
},
{
duration: Utils.fixedInt(100),
duration: fixedInt(100),
scaleX: 1.075 * baseScale,
scaleY: 0.925 * baseScale,
ease: "Cubic.easeOut",
},
{
duration: Utils.fixedInt(25),
duration: fixedInt(25),
scaleX: baseScale,
scaleY: baseScale,
ease: "Cubic.easeOut",
},
{
delay: Utils.fixedInt(500),
delay: fixedInt(500),
alpha: 0,
onComplete: () => {
this.damageNumbers

View File

@ -1,6 +1,6 @@
import { globalScene } from "#app/global-scene";
import Pokemon from "./pokemon";
import * as Utils from "../utils";
import { fixedInt, randInt } from "#app/utils";
export default class PokemonSpriteSparkleHandler {
private sprites: Set<Phaser.GameObjects.Sprite>;
@ -9,7 +9,7 @@ export default class PokemonSpriteSparkleHandler {
this.sprites = new Set();
globalScene.tweens.addCounter({
duration: Utils.fixedInt(200),
duration: fixedInt(200),
from: 0,
to: 1,
yoyo: true,
@ -36,7 +36,7 @@ export default class PokemonSpriteSparkleHandler {
const parent = (pokemon || s).parentContainer;
const texture = s.texture;
const [width, height] = [texture.source[0].width, texture.source[0].height];
const [pixelX, pixelY] = [Utils.randInt(width), Utils.randInt(height)];
const [pixelX, pixelY] = [randInt(width), randInt(height)];
const ratioX = s.width / width;
const ratioY = s.height / height;
const pixel = texture.manager.getPixel(pixelX, pixelY, texture.key, "__BASE");
@ -51,7 +51,7 @@ export default class PokemonSpriteSparkleHandler {
sparkle.setName("sprite-tera-sparkle");
sparkle.play("tera_sparkle");
parent.add(sparkle);
s.scene.time.delayedCall(Utils.fixedInt(Math.floor((1000 / 12) * 13)), () => sparkle.destroy());
s.scene.time.delayedCall(fixedInt(Math.floor((1000 / 12) * 13)), () => sparkle.destroy());
}
}
}

View File

@ -2,7 +2,7 @@ import Phaser from "phaser";
import type { AnySound } from "#app/battle-scene";
import type BattleScene from "#app/battle-scene";
import { globalScene } from "#app/global-scene";
import type { Variant, VariantSet } from "#app/sprites/variant";
import type { Variant } from "#app/sprites/variant";
import { populateVariantColors, variantColorCache } from "#app/sprites/variant";
import { variantData } from "#app/sprites/variant";
import BattleInfo, {
@ -55,9 +55,7 @@ import {
getStarterValueFriendshipCap,
speciesStarterCosts,
} from "#app/data/balance/starters";
import type { Constructor } from "#app/utils";
import { isNullOrUndefined, randSeedInt, type nil } from "#app/utils";
import * as Utils from "#app/utils";
import { NumberHolder, randSeedInt, getIvsFromId, BooleanHolder, randSeedItem, isNullOrUndefined, getEnumValues, toDmgValue, fixedInt, rgbaToInt, rgbHexToRgba, rgbToHsv, deltaRgb, isBetween, type nil, type Constructor } from "#app/utils";
import type { TypeDamageMultiplier } from "#app/data/type";
import { getTypeDamageMultiplier, getTypeRgb } from "#app/data/type";
import { PokemonType } from "#enums/pokemon-type";
@ -96,7 +94,6 @@ import {
} from "#app/modifier/modifier";
import { PokeballType } from "#enums/pokeball";
import { Gender } from "#app/data/gender";
import { initMoveAnim, loadMoveAnimAssets } from "#app/data/battle-anims";
import { Status, getRandomStatus } from "#app/data/status-effect";
import type {
SpeciesFormEvolution,
@ -176,10 +173,7 @@ import {
MoveTypeChangeAbAttr,
FullHpResistTypeAbAttr,
applyCheckTrappedAbAttrs,
CheckTrappedAbAttr,
PostSetStatusAbAttr,
applyPostSetStatusAbAttrs,
InfiltratorAbAttr,
CheckTrappedAbAttr, InfiltratorAbAttr,
AlliedFieldDamageReductionAbAttr,
PostDamageAbAttr,
applyPostDamageAbAttrs,
@ -193,7 +187,7 @@ import {
PreLeaveFieldRemoveSuppressAbilitiesSourceAbAttr,
applyAllyStatMultiplierAbAttrs,
AllyStatMultiplierAbAttr,
MoveAbilityBypassAbAttr,
MoveAbilityBypassAbAttr
} from "#app/data/ability";
import type PokemonData from "#app/system/pokemon-data";
import { BattlerIndex } from "#app/battle";
@ -220,8 +214,7 @@ import {
SpeciesFormChangeActiveTrigger,
SpeciesFormChangeLapseTeraTrigger,
SpeciesFormChangeMoveLearnedTrigger,
SpeciesFormChangePostMoveTrigger,
SpeciesFormChangeStatusEffectTrigger,
SpeciesFormChangePostMoveTrigger
} from "#app/data/pokemon-forms";
import { TerrainType } from "#app/data/terrain";
import type { TrainerSlot } from "#enums/trainer-slot";
@ -263,7 +256,6 @@ import { Nature } from "#enums/nature";
import { StatusEffect } from "#enums/status-effect";
import { doShinySparkleAnim } from "#app/field/anims";
import { MoveFlags } from "#enums/MoveFlags";
import { hasExpSprite } from "#app/sprites/sprite-utils";
import { timedEventManager } from "#app/global-event-manager";
import { loadMoveAnimations } from "#app/sprites/pokemon-asset-loader";
import { ResetStatusPhase } from "#app/phases/reset-status-phase";
@ -369,7 +361,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
throw `Cannot create a player Pokemon for species '${species.getName(formIndex)}'`;
}
const hiddenAbilityChance = new Utils.NumberHolder(
const hiddenAbilityChance = new NumberHolder(
BASE_HIDDEN_ABILITY_CHANCE,
);
if (!this.hasTrainer()) {
@ -390,8 +382,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
this.abilityIndex = abilityIndex; // Use the provided ability index if it is defined
} else {
// If abilityIndex is not provided, determine it based on species and hidden ability
const hasHiddenAbility = !Utils.randSeedInt(hiddenAbilityChance.value);
const randAbilityIndex = Utils.randSeedInt(2);
const hasHiddenAbility = !randSeedInt(hiddenAbilityChance.value);
const randAbilityIndex = randSeedInt(2);
if (species.abilityHidden && hasHiddenAbility) {
// If the species has a hidden ability and the hidden ability is present
this.abilityIndex = 2;
@ -467,8 +459,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
this.isTerastallized = dataSource.isTerastallized;
this.stellarTypesBoosted = dataSource.stellarTypesBoosted ?? [];
} else {
this.id = Utils.randSeedInt(4294967296);
this.ivs = ivs || Utils.getIvsFromId(this.id);
this.id = randSeedInt(4294967296);
this.ivs = ivs || getIvsFromId(this.id);
if (this.gender === undefined) {
this.generateGender();
@ -511,7 +503,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
this.pokerus = false;
if (level > 1) {
const fused = new Utils.BooleanHolder(
const fused = new BooleanHolder(
globalScene.gameMode.isSplicedOnly,
);
if (!fused.value && !this.isPlayer() && !this.hasTrainer()) {
@ -528,7 +520,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
(this.fusionShiny ? this.fusionVariant + 1 : 0);
this.fusionLuck = this.luck;
this.teraType = Utils.randSeedItem(this.getTypes(false, false, true));
this.teraType = randSeedItem(this.getTypes(false, false, true));
this.isTerastallized = false;
this.stellarTypesBoosted = [];
}
@ -636,7 +628,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
* @returns {boolean} `true` if pokemon is allowed in battle
*/
public isAllowedInChallenge(): boolean {
const challengeAllowed = new Utils.BooleanHolder(true);
const challengeAllowed = new BooleanHolder(true);
applyChallenges(
ChallengeType.POKEMON_IN_BATTLE,
this,
@ -1315,7 +1307,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
* @returns the final critical-hit stage value
*/
getCritStage(source: Pokemon, move: Move): number {
const critStage = new Utils.NumberHolder(0);
const critStage = new NumberHolder(0);
applyMoveAttrs(HighCritAttr, source, this, move, critStage);
globalScene.applyModifiers(
CritBoosterModifier,
@ -1370,7 +1362,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
simulated = true,
ignoreHeldItems = false,
): number {
const statValue = new Utils.NumberHolder(this.getStat(stat, false));
const statValue = new NumberHolder(this.getStat(stat, false));
if (!ignoreHeldItems) {
globalScene.applyModifiers(
StatBoosterModifier,
@ -1382,7 +1374,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
}
// The Ruin abilities here are never ignored, but they reveal themselves on summon anyway
const fieldApplied = new Utils.BooleanHolder(false);
const fieldApplied = new BooleanHolder(false);
for (const pokemon of globalScene.getField(true)) {
applyFieldStatMultiplierAbAttrs(
FieldMultiplyStatAbAttr,
@ -1408,7 +1400,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
}
const ally = this.getAlly();
if (!Utils.isNullOrUndefined(ally)) {
if (!isNullOrUndefined(ally)) {
applyAllyStatMultiplierAbAttrs(AllyStatMultiplierAbAttr, ally, stat, statValue, simulated, this, move?.hasFlag(MoveFlags.IGNORE_ABILITIES) || ignoreAllyAbility);
}
@ -1495,7 +1487,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
const baseStats = this.calculateBaseStats();
// Using base stats, calculate and store stats one by one
for (const s of PERMANENT_STATS) {
const statHolder = new Utils.NumberHolder(
const statHolder = new NumberHolder(
Math.floor((2 * baseStats[s] + this.ivs[s]) * this.level * 0.01),
);
if (s === Stat.HP) {
@ -1520,7 +1512,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
}
} else {
statHolder.value += 5;
const natureStatMultiplier = new Utils.NumberHolder(
const natureStatMultiplier = new NumberHolder(
getNatureStatMultiplier(this.getNature(), s),
);
globalScene.applyModifier(
@ -1622,9 +1614,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
generateNature(naturePool?: Nature[]): void {
if (naturePool === undefined) {
naturePool = Utils.getEnumValues(Nature);
naturePool = getEnumValues(Nature);
}
const nature = naturePool[Utils.randSeedInt(naturePool.length)];
const nature = naturePool[randSeedInt(naturePool.length)];
this.setNature(nature);
}
@ -1708,7 +1700,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
* @returns `true` if the pokemon is the species or is fused with it, `false` otherwise
*/
hasSpecies(species: Species, formKey?: string): boolean {
if (Utils.isNullOrUndefined(formKey)) {
if (isNullOrUndefined(formKey)) {
return (
this.species.speciesId === species ||
this.fusionSpecies?.speciesId === species
@ -1870,7 +1862,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
if (
secondType === PokemonType.UNKNOWN &&
Utils.isNullOrUndefined(fusionType2)
isNullOrUndefined(fusionType2)
) {
// If second pokemon was monotype and shared its primary type
secondType =
@ -2240,11 +2232,11 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
public getWeight(): number {
const autotomizedTag = this.getTag(AutotomizedTag);
let weightRemoved = 0;
if (!Utils.isNullOrUndefined(autotomizedTag)) {
if (!isNullOrUndefined(autotomizedTag)) {
weightRemoved = 100 * autotomizedTag!.autotomizeCount;
}
const minWeight = 0.1;
const weight = new Utils.NumberHolder(this.species.weight - weightRemoved);
const weight = new NumberHolder(this.species.weight - weightRemoved);
// This will trigger the ability overlay so only call this function when necessary
applyAbAttrs(WeightMultiplierAbAttr, this, null, false, weight);
@ -2315,7 +2307,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
return false;
}
const trappedByAbility = new Utils.BooleanHolder(false);
const trappedByAbility = new BooleanHolder(false);
/**
* Contains opposing Pokemon (Enemy/Player Pokemon) depending on perspective
* Afterwards, it filters out Pokemon that have been switched out of the field so trapped abilities/moves do not trigger
@ -2354,7 +2346,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
* @returns The {@linkcode PokemonType} of the move after attributes are applied
*/
public getMoveType(move: Move, simulated = true): PokemonType {
const moveTypeHolder = new Utils.NumberHolder(move.type);
const moveTypeHolder = new NumberHolder(move.type);
applyMoveAttrs(VariableMoveTypeAttr, this, null, move, moveTypeHolder);
applyPreAttackAbAttrs(
@ -2385,7 +2377,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
* @param move {@linkcode Move} The move being used by the attacking Pokémon.
* @param ignoreAbility Whether to ignore abilities that might affect type effectiveness or immunity (defaults to `false`).
* @param simulated Whether to apply abilities via simulated calls (defaults to `true`)
* @param cancelled {@linkcode Utils.BooleanHolder} Stores whether the move was cancelled by a non-type-based immunity.
* @param cancelled {@linkcode BooleanHolder} Stores whether the move was cancelled by a non-type-based immunity.
* Currently only used by {@linkcode Pokemon.apply} to determine whether a "No effect" message should be shown.
* @returns The type damage multiplier, indicating the effectiveness of the move
*/
@ -2394,9 +2386,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
move: Move,
ignoreAbility = false,
simulated = true,
cancelled?: Utils.BooleanHolder,
cancelled?: BooleanHolder,
): TypeDamageMultiplier {
if (!Utils.isNullOrUndefined(this.turnData?.moveEffectiveness)) {
if (!isNullOrUndefined(this.turnData?.moveEffectiveness)) {
return this.turnData?.moveEffectiveness;
}
@ -2405,7 +2397,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
}
const moveType = source.getMoveType(move);
const typeMultiplier = new Utils.NumberHolder(
const typeMultiplier = new NumberHolder(
move.category !== MoveCategory.STATUS ||
move.hasAttr(RespectAttackTypeImmunityAttr)
? this.getAttackTypeEffectiveness(
@ -2435,7 +2427,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
typeMultiplier.value *= 2;
}
const cancelledHolder = cancelled ?? new Utils.BooleanHolder(false);
const cancelledHolder = cancelled ?? new BooleanHolder(false);
if (!ignoreAbility) {
applyPreDefendAbAttrs(
TypeImmunityAbAttr,
@ -2549,7 +2541,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
let multiplier = types
.map(defType => {
const multiplier = new Utils.NumberHolder(
const multiplier = new NumberHolder(
getTypeDamageMultiplier(moveType, defType),
);
applyChallenges(
@ -2567,7 +2559,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
);
}
if (source) {
const ignoreImmunity = new Utils.BooleanHolder(false);
const ignoreImmunity = new BooleanHolder(false);
if (
source.isActive(true) &&
source.hasAbilityWithAttr(IgnoreTypeImmunityAbAttr)
@ -2600,7 +2592,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
})
.reduce((acc, cur) => acc * cur, 1) as TypeDamageMultiplier;
const typeMultiplierAgainstFlying = new Utils.NumberHolder(
const typeMultiplierAgainstFlying = new NumberHolder(
getTypeDamageMultiplier(moveType, PokemonType.FLYING),
);
applyChallenges(
@ -2943,7 +2935,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
const E = globalScene.gameData.trainerId ^ globalScene.gameData.secretId;
const F = rand1 ^ rand2;
const shinyThreshold = new Utils.NumberHolder(BASE_SHINY_CHANCE);
const shinyThreshold = new NumberHolder(BASE_SHINY_CHANCE);
if (thresholdOverride === undefined) {
if (timedEventManager.isEventActive()) {
const tchance = timedEventManager.getClassicTrainerShinyChance();
@ -2986,7 +2978,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
thresholdOverride?: number,
applyModifiersToOverride?: boolean,
): boolean {
const shinyThreshold = new Utils.NumberHolder(BASE_SHINY_CHANCE);
const shinyThreshold = new NumberHolder(BASE_SHINY_CHANCE);
if (thresholdOverride === undefined || applyModifiersToOverride) {
if (thresholdOverride !== undefined && applyModifiersToOverride) {
shinyThreshold.value = thresholdOverride;
@ -3041,10 +3033,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
) {
return 0;
}
const rand = new Utils.NumberHolder(0);
const rand = new NumberHolder(0);
globalScene.executeWithSeedOffset(
() => {
rand.value = Utils.randSeedInt(10);
rand.value = randSeedInt(10);
},
this.id,
globalScene.waveSeed,
@ -3074,7 +3066,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
if (!this.species.abilityHidden) {
return false;
}
const haThreshold = new Utils.NumberHolder(BASE_HIDDEN_ABILITY_CHANCE);
const haThreshold = new NumberHolder(BASE_HIDDEN_ABILITY_CHANCE);
if (thresholdOverride === undefined || applyModifiersToOverride) {
if (thresholdOverride !== undefined && applyModifiersToOverride) {
haThreshold.value = thresholdOverride;
@ -3098,7 +3090,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
}
public generateFusionSpecies(forStarter?: boolean): void {
const hiddenAbilityChance = new Utils.NumberHolder(
const hiddenAbilityChance = new NumberHolder(
BASE_HIDDEN_ABILITY_CHANCE,
);
if (!this.hasTrainer()) {
@ -3109,8 +3101,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
);
}
const hasHiddenAbility = !Utils.randSeedInt(hiddenAbilityChance.value);
const randAbilityIndex = Utils.randSeedInt(2);
const hasHiddenAbility = !randSeedInt(hiddenAbilityChance.value);
const randAbilityIndex = randSeedInt(2);
const filter = !forStarter
? this.species.getCompatibleFusionSpeciesFilter()
@ -3427,7 +3419,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
if (stabMovePool.length) {
const totalWeight = stabMovePool.reduce((v, m) => v + m[1], 0);
let rand = Utils.randSeedInt(totalWeight);
let rand = randSeedInt(totalWeight);
let index = 0;
while (rand > stabMovePool[index][1]) {
rand -= stabMovePool[index++][1];
@ -3441,7 +3433,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
);
if (attackMovePool.length) {
const totalWeight = attackMovePool.reduce((v, m) => v + m[1], 0);
let rand = Utils.randSeedInt(totalWeight);
let rand = randSeedInt(totalWeight);
let index = 0;
while (rand > attackMovePool[index][1]) {
rand -= attackMovePool[index++][1];
@ -3493,7 +3485,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
movePool = baseWeights.filter(m => !this.moveset.some(mo => m[0] === mo.moveId));
}
const totalWeight = movePool.reduce((v, m) => v + m[1], 0);
let rand = Utils.randSeedInt(totalWeight);
let rand = randSeedInt(totalWeight);
let index = 0;
while (rand > movePool[index][1]) {
rand -= movePool[index++][1];
@ -3717,8 +3709,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
simulated = true,
ignoreHeldItems = false,
): number {
const statStage = new Utils.NumberHolder(this.getStatStage(stat));
const ignoreStatStage = new Utils.BooleanHolder(false);
const statStage = new NumberHolder(this.getStatStage(stat));
const ignoreStatStage = new BooleanHolder(false);
if (opponent) {
if (isCritical) {
@ -3755,7 +3747,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
}
if (!ignoreStatStage.value) {
const statStageMultiplier = new Utils.NumberHolder(
const statStageMultiplier = new NumberHolder(
Math.max(2, 2 + statStage.value) / Math.max(2, 2 - statStage.value),
);
if (!ignoreHeldItems) {
@ -3787,13 +3779,13 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
return 1;
}
const userAccStage = new Utils.NumberHolder(this.getStatStage(Stat.ACC));
const targetEvaStage = new Utils.NumberHolder(
const userAccStage = new NumberHolder(this.getStatStage(Stat.ACC));
const targetEvaStage = new NumberHolder(
target.getStatStage(Stat.EVA),
);
const ignoreAccStatStage = new Utils.BooleanHolder(false);
const ignoreEvaStatStage = new Utils.BooleanHolder(false);
const ignoreAccStatStage = new BooleanHolder(false);
const ignoreEvaStatStage = new BooleanHolder(false);
applyAbAttrs(
IgnoreOpponentStatStagesAbAttr,
@ -3835,7 +3827,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
targetEvaStage.value = Math.min(0, targetEvaStage.value);
}
const accuracyMultiplier = new Utils.NumberHolder(1);
const accuracyMultiplier = new NumberHolder(1);
if (userAccStage.value !== targetEvaStage.value) {
accuracyMultiplier.value =
userAccStage.value > targetEvaStage.value
@ -3852,7 +3844,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
sourceMove,
);
const evasionMultiplier = new Utils.NumberHolder(1);
const evasionMultiplier = new NumberHolder(1);
applyStatMultiplierAbAttrs(
StatMultiplierAbAttr,
target,
@ -3907,7 +3899,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
* The attacker's offensive stat for the given move's category.
* Critical hits cause negative stat stages to be ignored.
*/
const sourceAtk = new Utils.NumberHolder(
const sourceAtk = new NumberHolder(
source.getEffectiveStat(
isPhysical ? Stat.ATK : Stat.SPATK,
this,
@ -3925,7 +3917,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
* This Pokemon's defensive stat for the given move's category.
* Critical hits cause positive stat stages to be ignored.
*/
const targetDef = new Utils.NumberHolder(
const targetDef = new NumberHolder(
this.getEffectiveStat(
isPhysical ? Stat.DEF : Stat.SPDEF,
source,
@ -3986,12 +3978,12 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
isCritical = false,
simulated = true,
): DamageCalculationResult {
const damage = new Utils.NumberHolder(0);
const damage = new NumberHolder(0);
const defendingSide = this.isPlayer()
? ArenaTagSide.PLAYER
: ArenaTagSide.ENEMY;
const variableCategory = new Utils.NumberHolder(move.category);
const variableCategory = new NumberHolder(move.category);
applyMoveAttrs(
VariableMoveCategoryAttr,
source,
@ -4005,7 +3997,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
const moveType = source.getMoveType(move);
/** If `value` is `true`, cancels the move and suppresses "No Effect" messages */
const cancelled = new Utils.BooleanHolder(false);
const cancelled = new BooleanHolder(false);
/**
* The effectiveness of the move being used. Along with type matchups, this
@ -4025,7 +4017,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
const isPhysical = moveCategory === MoveCategory.PHYSICAL;
/** Combined damage multiplier from field effects such as weather, terrain, etc. */
const arenaAttackTypeMultiplier = new Utils.NumberHolder(
const arenaAttackTypeMultiplier = new NumberHolder(
globalScene.arena.getAttackTypeMultiplier(moveType, source.isGrounded()),
);
applyMoveAttrs(
@ -4048,10 +4040,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
}
// If the attack deals fixed damage, return a result with that much damage
const fixedDamage = new Utils.NumberHolder(0);
const fixedDamage = new NumberHolder(0);
applyMoveAttrs(FixedDamageAttr, source, this, move, fixedDamage);
if (fixedDamage.value) {
const multiLensMultiplier = new Utils.NumberHolder(1);
const multiLensMultiplier = new NumberHolder(1);
globalScene.applyModifiers(
PokemonMultiHitModifier,
source.isPlayer(),
@ -4060,7 +4052,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
null,
multiLensMultiplier,
);
fixedDamage.value = Utils.toDmgValue(
fixedDamage.value = toDmgValue(
fixedDamage.value * multiLensMultiplier.value,
);
@ -4072,7 +4064,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
}
// If the attack is a one-hit KO move, return a result with damage equal to this Pokemon's HP
const isOneHitKo = new Utils.BooleanHolder(false);
const isOneHitKo = new BooleanHolder(false);
applyMoveAttrs(OneHitKOAttr, source, this, move, isOneHitKo);
if (isOneHitKo.value) {
return {
@ -4104,7 +4096,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
const targetMultiplier = numTargets > 1 ? 0.75 : 1;
/** Multiplier for moves enhanced by Multi-Lens and/or Parental Bond */
const multiStrikeEnhancementMultiplier = new Utils.NumberHolder(1);
const multiStrikeEnhancementMultiplier = new NumberHolder(1);
globalScene.applyModifiers(
PokemonMultiHitModifier,
source.isPlayer(),
@ -4126,13 +4118,13 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
}
/** Doubles damage if this Pokemon's last move was Glaive Rush */
const glaiveRushMultiplier = new Utils.NumberHolder(1);
const glaiveRushMultiplier = new NumberHolder(1);
if (this.getTag(BattlerTagType.RECEIVE_DOUBLE_DAMAGE)) {
glaiveRushMultiplier.value = 2;
}
/** The damage multiplier when the given move critically hits */
const criticalMultiplier = new Utils.NumberHolder(isCritical ? 1.5 : 1);
const criticalMultiplier = new NumberHolder(isCritical ? 1.5 : 1);
applyAbAttrs(MultCritAbAttr, source, null, simulated, criticalMultiplier);
/**
@ -4147,7 +4139,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
const sourceTeraType = source.getTeraType();
const matchesSourceType = sourceTypes.includes(moveType);
/** A damage multiplier for when the attack is of the attacker's type and/or Tera type. */
const stabMultiplier = new Utils.NumberHolder(1);
const stabMultiplier = new NumberHolder(1);
if (matchesSourceType && moveType !== PokemonType.STELLAR) {
stabMultiplier.value += 0.5;
}
@ -4188,14 +4180,14 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
stabMultiplier.value = Math.min(stabMultiplier.value, 2.25);
/** Halves damage if the attacker is using a physical attack while burned */
const burnMultiplier = new Utils.NumberHolder(1);
const burnMultiplier = new NumberHolder(1);
if (
isPhysical &&
source.status &&
source.status.effect === StatusEffect.BURN
) {
if (!move.hasAttr(BypassBurnDamageReductionAttr)) {
const burnDamageReductionCancelled = new Utils.BooleanHolder(false);
const burnDamageReductionCancelled = new BooleanHolder(false);
if (!ignoreSourceAbility) {
applyAbAttrs(
BypassBurnDamageReductionAbAttr,
@ -4211,7 +4203,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
}
/** Reduces damage if this Pokemon has a relevant screen (e.g. Light Screen for special attacks) */
const screenMultiplier = new Utils.NumberHolder(1);
const screenMultiplier = new NumberHolder(1);
// Critical hits should bypass screens
if (!isCritical) {
@ -4231,7 +4223,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
* AND
* The move doubles damage when used against that tag
*/
const hitsTagMultiplier = new Utils.NumberHolder(1);
const hitsTagMultiplier = new NumberHolder(1);
move
.getAttrs(HitsTagAttr)
.filter(hta => hta.doubleDamage)
@ -4249,7 +4241,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
? 0.5
: 1;
damage.value = Utils.toDmgValue(
damage.value = toDmgValue(
baseDamage *
targetMultiplier *
multiStrikeEnhancementMultiplier.value *
@ -4358,10 +4350,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
const defendingSide = this.isPlayer()
? ArenaTagSide.PLAYER
: ArenaTagSide.ENEMY;
const moveCategory = new Utils.NumberHolder(move.category);
const moveCategory = new NumberHolder(move.category);
applyMoveAttrs(VariableMoveCategoryAttr, source, this, move, moveCategory);
if (moveCategory.value === MoveCategory.STATUS) {
const cancelled = new Utils.BooleanHolder(false);
const cancelled = new BooleanHolder(false);
const typeMultiplier = this.getMoveEffectiveness(
source,
move,
@ -4381,7 +4373,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
}
/** Determines whether the attack critically hits */
let isCritical: boolean;
const critOnly = new Utils.BooleanHolder(false);
const critOnly = new BooleanHolder(false);
const critAlways = source.getTag(BattlerTagType.ALWAYS_CRIT);
applyMoveAttrs(CritOnlyAttr, source, this, move, critOnly);
applyAbAttrs(
@ -4404,7 +4396,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
}
const noCritTag = globalScene.arena.getTagOnSide(NoCritTag, defendingSide);
const blockCrit = new Utils.BooleanHolder(false);
const blockCrit = new BooleanHolder(false);
applyAbAttrs(BlockCritAbAttr, this, null, false, blockCrit);
if (noCritTag || blockCrit.value || Overrides.NEVER_CRIT_OVERRIDE) {
isCritical = false;
@ -4486,7 +4478,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
if (damage > 0) {
if (source.isPlayer()) {
globalScene.validateAchvs(DamageAchv, new Utils.NumberHolder(damage));
globalScene.validateAchvs(DamageAchv, new NumberHolder(damage));
if (damage > globalScene.gameData.gameStats.highestDamage) {
globalScene.gameData.gameStats.highestDamage = damage;
}
@ -4510,7 +4502,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
DamageMoneyRewardModifier,
true,
source,
new Utils.NumberHolder(damage),
new NumberHolder(damage),
);
}
}
@ -4575,7 +4567,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
if (this.isFainted()) {
return 0;
}
const surviveDamage = new Utils.BooleanHolder(false);
const surviveDamage = new BooleanHolder(false);
if (!preventEndure && this.hp - damage <= 0) {
if (this.hp >= 1 && this.getTag(BattlerTagType.ENDURING)) {
@ -4710,7 +4702,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
const stubTag = new BattlerTag(tagType, 0, 0);
const cancelled = new Utils.BooleanHolder(false);
const cancelled = new BooleanHolder(false);
applyPreApplyBattlerTagAbAttrs(
BattlerTagImmunityAbAttr,
this,
@ -4748,7 +4740,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
const newTag = getBattlerTag(tagType, turnCount, sourceMove!, sourceId!); // TODO: are the bangs correct?
const cancelled = new Utils.BooleanHolder(false);
const cancelled = new BooleanHolder(false);
applyPreApplyBattlerTagAbAttrs(
BattlerTagImmunityAbAttr,
this,
@ -5081,12 +5073,12 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
let fusionCry = this.getFusionSpeciesForm().cry(soundConfig, true);
duration = Math.min(duration, fusionCry.totalDuration * 1000);
fusionCry.destroy();
scene.time.delayedCall(Utils.fixedInt(Math.ceil(duration * 0.4)), () => {
scene.time.delayedCall(fixedInt(Math.ceil(duration * 0.4)), () => {
try {
SoundFade.fadeOut(
scene,
cry,
Utils.fixedInt(Math.ceil(duration * 0.2)),
fixedInt(Math.ceil(duration * 0.2)),
);
fusionCry = this.getFusionSpeciesForm().cry(
Object.assign(
@ -5097,7 +5089,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
SoundFade.fadeIn(
scene,
fusionCry,
Utils.fixedInt(Math.ceil(duration * 0.2)),
fixedInt(Math.ceil(duration * 0.2)),
scene.masterVolume * scene.fieldVolume,
0,
);
@ -5137,7 +5129,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
let faintCryTimer: Phaser.Time.TimerEvent | null =
globalScene.time.addEvent({
delay: Utils.fixedInt(delay),
delay: fixedInt(delay),
repeat: -1,
callback: () => {
frameThreshold = sprite.anims.msPerFrame / rate;
@ -5163,7 +5155,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
});
// Failsafe
globalScene.time.delayedCall(Utils.fixedInt(3000), () => {
globalScene.time.delayedCall(fixedInt(3000), () => {
if (!faintCryTimer || !globalScene) {
return;
}
@ -5222,7 +5214,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
let faintCryTimer: Phaser.Time.TimerEvent | null =
globalScene.time.addEvent({
delay: Utils.fixedInt(delay),
delay: fixedInt(delay),
repeat: -1,
callback: () => {
++i;
@ -5239,7 +5231,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
SoundFade.fadeOut(
globalScene,
cry,
Utils.fixedInt(Math.ceil((duration / rate) * 0.2)),
fixedInt(Math.ceil((duration / rate) * 0.2)),
);
fusionCry = globalScene.playSound(
fusionCryKey,
@ -5251,7 +5243,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
SoundFade.fadeIn(
globalScene,
fusionCry,
Utils.fixedInt(Math.ceil((duration / rate) * 0.2)),
fixedInt(Math.ceil((duration / rate) * 0.2)),
globalScene.masterVolume * globalScene.fieldVolume,
0,
);
@ -5277,7 +5269,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
});
// Failsafe
globalScene.time.delayedCall(Utils.fixedInt(3000), () => {
globalScene.time.delayedCall(fixedInt(3000), () => {
if (!faintCryTimer || !globalScene) {
return;
}
@ -5352,7 +5344,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
}
// Check if the source Pokemon has an ability that cancels the Poison/Toxic immunity
const cancelImmunity = new Utils.BooleanHolder(false);
const cancelImmunity = new BooleanHolder(false);
if (sourcePokemon) {
applyAbAttrs(
IgnoreTypeStatusEffectImmunityAbAttr,
@ -5408,7 +5400,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
break;
}
const cancelled = new Utils.BooleanHolder(false);
const cancelled = new BooleanHolder(false);
applyPreSetStatusAbAttrs(
StatusEffectImmunityAbAttr,
this,
@ -5479,10 +5471,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
return true;
}
let sleepTurnsRemaining: Utils.NumberHolder;
let sleepTurnsRemaining: NumberHolder;
if (effect === StatusEffect.SLEEP) {
sleepTurnsRemaining = new Utils.NumberHolder(this.randSeedIntRange(2, 4));
sleepTurnsRemaining = new NumberHolder(this.randSeedIntRange(2, 4));
this.setFrameRate(4);
@ -5533,7 +5525,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
? ArenaTagSide.PLAYER
: ArenaTagSide.ENEMY;
if (globalScene.arena.getTagOnSide(ArenaTagType.SAFEGUARD, defendingSide)) {
const bypassed = new Utils.BooleanHolder(false);
const bypassed = new BooleanHolder(false);
if (attacker) {
applyAbAttrs(InfiltratorAbAttr, attacker, null, false, bypassed);
}
@ -5829,9 +5821,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
if (this.shiny && variantColors && variantColors[this.variant]) {
Object.keys(variantColors[this.variant]).forEach(k => {
variantColorSet.set(
Utils.rgbaToInt(Array.from(Object.values(Utils.rgbHexToRgba(k)))),
rgbaToInt(Array.from(Object.values(rgbHexToRgba(k)))),
Array.from(
Object.values(Utils.rgbHexToRgba(variantColors[this.variant][k])),
Object.values(rgbHexToRgba(variantColors[this.variant][k])),
),
);
});
@ -5842,7 +5834,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
const pixel = pixelData[f].slice(i, i + 4);
let [r, g, b, a] = pixel;
if (variantColors) {
const color = Utils.rgbaToInt([r, g, b, a]);
const color = rgbaToInt([r, g, b, a]);
if (variantColorSet.has(color)) {
const mappedPixel = variantColorSet.get(color);
if (mappedPixel) {
@ -5891,10 +5883,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
) {
for (const k of Object.keys(variantColors[this.fusionVariant])) {
variantColorSet.set(
Utils.rgbaToInt(Array.from(Object.values(Utils.rgbHexToRgba(k)))),
rgbaToInt(Array.from(Object.values(rgbHexToRgba(k)))),
Array.from(
Object.values(
Utils.rgbHexToRgba(variantColors[this.fusionVariant][k]),
rgbHexToRgba(variantColors[this.fusionVariant][k]),
),
),
);
@ -5914,7 +5906,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
pixelData[2 + f][i + 3],
];
if (variantColors) {
const color = Utils.rgbaToInt([r, g, b, a]);
const color = rgbaToInt([r, g, b, a]);
if (variantColorSet.has(color)) {
const mappedPixel = variantColorSet.get(color);
if (mappedPixel) {
@ -5972,7 +5964,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
hsvColors = Array.from(rgbaColors.keys()).reduce(
(map: Map<number, number[]>, k: number) => {
const rgb = rgbaColors.get(k)!.slice(0, 3);
map.set(k, Utils.rgbToHsv(rgb[0], rgb[1], rgb[2]));
map.set(k, rgbToHsv(rgb[0], rgb[1], rgb[2]));
return map;
},
new Map<number, number[]>(),
@ -6052,7 +6044,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
spriteColors.forEach((sc: number[], i: number) => {
paletteDeltas.push([]);
for (let p = 0; p < palette.length; p++) {
paletteDeltas[i].push(Utils.deltaRgb(sc, palette[p]));
paletteDeltas[i].push(deltaRgb(sc, palette[p]));
}
});
@ -6097,8 +6089,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
* <!-- @import "../battle".Battle -->
* This calls either {@linkcode BattleScene.randBattleSeedInt}({@linkcode range}, {@linkcode min}) in `src/battle-scene.ts`
* which calls {@linkcode Battle.randSeedInt}({@linkcode range}, {@linkcode min}) in `src/battle.ts`
* which calls {@linkcode Utils.randSeedInt randSeedInt}({@linkcode range}, {@linkcode min}) in `src/utils.ts`,
* or it directly calls {@linkcode Utils.randSeedInt randSeedInt}({@linkcode range}, {@linkcode min}) in `src/utils.ts` if there is no current battle
* which calls {@linkcode randSeedInt randSeedInt}({@linkcode range}, {@linkcode min}) in `src/utils.ts`,
* or it directly calls {@linkcode randSeedInt randSeedInt}({@linkcode range}, {@linkcode min}) in `src/utils.ts` if there is no current battle
*
* @param range How large of a range of random numbers to choose from. If {@linkcode range} <= 1, returns {@linkcode min}
* @param min The minimum integer to pick, default `0`
@ -6107,7 +6099,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
randSeedInt(range: number, min = 0): number {
return globalScene.currentBattle
? globalScene.randBattleSeedInt(range, min)
: Utils.randSeedInt(range, min);
: randSeedInt(range, min);
}
/**
@ -6403,7 +6395,7 @@ export class PlayerPokemon extends Pokemon {
? globalScene.gameData.starterData[fusionStarterSpeciesId]
: null,
].filter(d => !!d);
const amount = new Utils.NumberHolder(friendship);
const amount = new NumberHolder(friendship);
globalScene.applyModifier(
PokemonFriendshipBoosterModifier,
true,
@ -6418,7 +6410,7 @@ export class PlayerPokemon extends Pokemon {
? 1.5 // Divide candy gain for fusions by 1.5 during events
: 2 // 2 for fusions outside events
: 1; // 1 for non-fused mons
const starterAmount = new Utils.NumberHolder(
const starterAmount = new NumberHolder(
Math.floor(
(amount.value * candyFriendshipMultiplier) / fusionReduction,
),
@ -7381,7 +7373,7 @@ export class EnemyPokemon extends Pokemon {
//console.log('damage', damage, 'segment', segmentsBypassed + 1, 'segment size', segmentSize, 'damage needed', Math.round(segmentSize * Math.pow(2, segmentsBypassed + 1)));
}
damage = Utils.toDmgValue(
damage = toDmgValue(
this.hp - hpThreshold + segmentSize * segmentsBypassed,
);
clearedBossSegmentIndex = s - segmentsBypassed;
@ -7459,7 +7451,7 @@ export class EnemyPokemon extends Pokemon {
}
// Pick a random stat from the leftover stats to increase its stages
const randInt = Utils.randSeedInt(totalWeight);
const randInt = randSeedInt(totalWeight);
for (const i in statThresholds) {
if (randInt < statThresholds[i]) {
boostedStat = leftoverStats[i];
@ -7530,7 +7522,7 @@ export class EnemyPokemon extends Pokemon {
this,
);
if (Utils.isBetween(slotIndex, 0, PLAYER_PARTY_MAX_SIZE - 1)) {
if (isBetween(slotIndex, 0, PLAYER_PARTY_MAX_SIZE - 1)) {
party.splice(slotIndex, 0, newPokemon);
} else {
party.push(newPokemon);
@ -7772,7 +7764,7 @@ export class PokemonMove {
getMovePp(): number {
return (
this.maxPpOverride ||
this.getMove().pp + this.ppUp * Utils.toDmgValue(this.getMove().pp / 5)
this.getMove().pp + this.ppUp * toDmgValue(this.getMove().pp / 5)
);
}

View File

@ -11,7 +11,7 @@ import { TrainerSlot } from "#enums/trainer-slot";
import { TrainerPoolTier } from "#enums/trainer-pool-tier";
import { TeraAIMode } from "#enums/tera-ai-mode";
import type { EnemyPokemon } from "#app/field/pokemon";
import * as Utils from "#app/utils";
import { randSeedWeightedItem, randSeedItem, randSeedInt } from "#app/utils";
import type { PersistentModifier } from "#app/modifier/modifier";
import { ArenaTagSide, ArenaTrapTag } from "#app/data/arena-tag";
import { getIsInitialized, initI18n } from "#app/plugins/i18n";
@ -58,7 +58,7 @@ export default class Trainer extends Phaser.GameObjects.Container {
this.partyTemplateIndex = Math.min(
partyTemplateIndex !== undefined
? partyTemplateIndex
: Utils.randSeedWeightedItem(this.config.partyTemplates.map((_, i) => i)),
: randSeedWeightedItem(this.config.partyTemplates.map((_, i) => i)),
this.config.partyTemplates.length - 1,
);
const classKey = `trainersCommon:${TrainerType[trainerType]}`;
@ -71,9 +71,7 @@ export default class Trainer extends Phaser.GameObjects.Container {
? ".FEMALE"
: ".MALE"
: "";
const trainerKey = Utils.randSeedItem(
Object.keys(i18next.t(`${classKey}${genderKey}`, { returnObjects: true })),
);
const trainerKey = randSeedItem(Object.keys(i18next.t(`${classKey}${genderKey}`, { returnObjects: true })));
this.nameKey = `${classKey}${genderKey}.${trainerKey}`;
}
this.name = i18next.t(this.nameKey);
@ -87,7 +85,7 @@ export default class Trainer extends Phaser.GameObjects.Container {
}
} else {
const partnerGenderKey = i18next.exists(`${classKey}.FEMALE`) ? ".FEMALE" : "";
const partnerTrainerKey = Utils.randSeedItem(
const partnerTrainerKey = randSeedItem(
Object.keys(
i18next.t(`${classKey}${partnerGenderKey}`, {
returnObjects: true,
@ -420,7 +418,7 @@ export default class Trainer extends Phaser.GameObjects.Container {
// If useNewSpeciesPool is true, we need to generate a new species from the new species pool, otherwise we generate a random species
let species = useNewSpeciesPool
? getPokemonSpecies(newSpeciesPool[Math.floor(Utils.randSeedInt(newSpeciesPool.length))])
? getPokemonSpecies(newSpeciesPool[Math.floor(randSeedInt(newSpeciesPool.length))])
: template.isSameSpecies(index) && index > offset
? getPokemonSpecies(
battle.enemyParty[offset].species.getTrainerSpeciesForLevel(
@ -461,7 +459,7 @@ export default class Trainer extends Phaser.GameObjects.Container {
let baseSpecies: PokemonSpecies;
if (this.config.speciesPools) {
const tierValue = Utils.randSeedInt(512);
const tierValue = randSeedInt(512);
let tier =
tierValue >= 156
? TrainerPoolTier.COMMON
@ -480,7 +478,7 @@ export default class Trainer extends Phaser.GameObjects.Container {
tier--;
}
const tierPool = this.config.speciesPools[tier];
baseSpecies = getPokemonSpecies(Utils.randSeedItem(tierPool));
baseSpecies = getPokemonSpecies(randSeedItem(tierPool));
} else {
baseSpecies = globalScene.randomSpecies(battle.waveIndex, level, false, this.config.speciesFilter);
}
@ -619,7 +617,7 @@ export default class Trainer extends Phaser.GameObjects.Container {
if (maxScorePartyMemberIndexes.length > 1) {
let rand: number;
globalScene.executeWithSeedOffset(
() => (rand = Utils.randSeedInt(maxScorePartyMemberIndexes.length)),
() => (rand = randSeedInt(maxScorePartyMemberIndexes.length)),
globalScene.currentBattle.turn << 2,
);
return maxScorePartyMemberIndexes[rand!];

View File

@ -7,7 +7,7 @@ import type PokemonSpecies from "./data/pokemon-species";
import { allSpecies } from "./data/pokemon-species";
import type { Arena } from "./field/arena";
import Overrides from "#app/overrides";
import * as Utils from "./utils";
import { randSeedInt, randSeedItem } from "#app/utils";
import { Biome } from "#enums/biome";
import { Species } from "#enums/species";
import { Challenges } from "./enums/challenges";
@ -186,7 +186,7 @@ export class GameMode implements GameModeConfig {
if (w < waveIndex) {
globalScene.executeWithSeedOffset(() => {
const waveTrainerChance = arena.getTrainerChance();
if (!Utils.randSeedInt(waveTrainerChance)) {
if (!randSeedInt(waveTrainerChance)) {
allowTrainerBattle = false;
}
}, w);
@ -196,7 +196,7 @@ export class GameMode implements GameModeConfig {
}
}
}
return Boolean(allowTrainerBattle && trainerChance && !Utils.randSeedInt(trainerChance));
return Boolean(allowTrainerBattle && trainerChance && !randSeedInt(trainerChance));
}
return false;
}
@ -222,7 +222,7 @@ export class GameMode implements GameModeConfig {
s.speciesId !== Species.ETERNATUS &&
s.speciesId !== Species.ARCEUS,
);
return Utils.randSeedItem(allFinalBossSpecies);
return randSeedItem(allFinalBossSpecies);
}
return null;

View File

@ -1,6 +1,5 @@
import Phaser from "phaser";
import * as Utils from "./utils";
import { deepCopy } from "./utils";
import { deepCopy, getEnumValues } from "#app/utils";
import pad_generic from "./configs/inputs/pad_generic";
import pad_unlicensedSNES from "./configs/inputs/pad_unlicensedSNES";
import pad_xbox360 from "./configs/inputs/pad_xbox360";
@ -102,7 +101,7 @@ export class InputsController {
[Device.KEYBOARD]: "default",
};
for (const b of Utils.getEnumValues(Button)) {
for (const b of getEnumValues(Button)) {
this.interactions[b] = {
pressTime: false,
isPressed: false,

View File

@ -4,7 +4,7 @@ import CacheBustedLoaderPlugin from "#app/plugins/cache-busted-loader-plugin";
import { SceneBase } from "#app/scene-base";
import { WindowVariant, getWindowVariantSuffix } from "#app/ui/ui-theme";
import { isMobile } from "#app/touch-controls";
import * as Utils from "#app/utils";
import { localPing, getEnumValues, hasAllLocalizedSprites, getEnumKeys } from "#app/utils";
import { initPokemonPrevolutions, initPokemonStarters } from "#app/data/balance/pokemon-evolutions";
import { initBiomes } from "#app/data/balance/biomes";
import { initEggMoves } from "#app/data/balance/egg-moves";
@ -34,7 +34,7 @@ export class LoadingScene extends SceneBase {
}
preload() {
Utils.localPing();
localPing();
this.load["manifest"] = this.game["manifest"];
this.loadImage("loading_bg", "arenas");
@ -49,7 +49,7 @@ export class LoadingScene extends SceneBase {
this.loadImage("friendship_overlay", "ui");
this.loadImage("cursor", "ui");
this.loadImage("cursor_reverse", "ui");
for (const wv of Utils.getEnumValues(WindowVariant)) {
for (const wv of getEnumValues(WindowVariant)) {
for (let w = 1; w <= 5; w++) {
this.loadImage(`window_${w}${getWindowVariantSuffix(wv)}`, "ui/windows");
}
@ -177,7 +177,7 @@ export class LoadingScene extends SceneBase {
this.loadImage("default_bg", "arenas");
// Load arena images
Utils.getEnumValues(Biome).map(bt => {
getEnumValues(Biome).map(bt => {
const btKey = Biome[bt].toLowerCase();
const isBaseAnimated = btKey === "end";
const baseAKey = `${btKey}_a`;
@ -239,7 +239,7 @@ export class LoadingScene extends SceneBase {
// Get current lang and load the types atlas for it. English will only load types while all other languages will load types and types_<lang>
const lang = i18next.resolvedLanguage;
if (lang !== "en") {
if (Utils.hasAllLocalizedSprites(lang)) {
if (hasAllLocalizedSprites(lang)) {
this.loadAtlas(`statuses_${lang}`, "");
this.loadAtlas(`types_${lang}`, "");
} else {
@ -268,7 +268,7 @@ export class LoadingScene extends SceneBase {
this.loadAtlas("egg_icons", "egg");
this.loadAtlas("egg_shard", "egg");
this.loadAtlas("egg_lightrays", "egg");
for (const gt of Utils.getEnumKeys(GachaType)) {
for (const gt of getEnumKeys(GachaType)) {
const key = gt.toLowerCase();
this.loadImage(`gacha_${key}`, "egg");
this.loadAtlas(`gacha_underlay_${key}`, "egg");

View File

@ -297,16 +297,16 @@ export class MoveEffectPhase extends PokemonPhase {
);
}
/** Is the target protected by Protect, etc. or a relevant conditional protection effect? */
const isProtected =
![MoveTarget.ENEMY_SIDE, MoveTarget.BOTH_SIDES].includes(this.move.getMove().moveTarget) &&
(bypassIgnoreProtect.value ||
!this.move.getMove().doesFlagEffectApply({ flag: MoveFlags.IGNORE_PROTECT, user, target })) &&
(hasConditionalProtectApplied.value ||
(!target.findTags(t => t instanceof DamageProtectedTag).length &&
target.findTags(t => t instanceof ProtectedTag).find(t => target.lapseTag(t.tagType))) ||
(this.move.getMove().category !== MoveCategory.STATUS &&
target.findTags(t => t instanceof DamageProtectedTag).find(t => target.lapseTag(t.tagType))));
/** Is the target protected by Protect, etc. or a relevant conditional protection effect? */
const isProtected =
![MoveTarget.ENEMY_SIDE, MoveTarget.BOTH_SIDES].includes(this.move.getMove().moveTarget) &&
(bypassIgnoreProtect.value ||
!this.move.getMove().doesFlagEffectApply({ flag: MoveFlags.IGNORE_PROTECT, user, target })) &&
(hasConditionalProtectApplied.value ||
(!target.findTags(t => t instanceof DamageProtectedTag).length &&
target.findTags(t => t instanceof ProtectedTag).find(t => target.lapseTag(t.tagType))) ||
(this.move.getMove().category !== MoveCategory.STATUS &&
target.findTags(t => t instanceof DamageProtectedTag).find(t => target.lapseTag(t.tagType))));
/** Is the target hidden by the effects of its Commander ability? */
const isCommanding =
@ -316,11 +316,11 @@ export class MoveEffectPhase extends PokemonPhase {
/** Is the target reflecting status moves from the magic coat move? */
const isReflecting = !!target.getTag(BattlerTagType.MAGIC_COAT);
/** Is the target's magic bounce ability not ignored and able to reflect this move? */
const canMagicBounce =
!isReflecting &&
!move.doesFlagEffectApply({ flag: MoveFlags.IGNORE_ABILITIES, user, target }) &&
target.hasAbilityWithAttr(ReflectStatusMoveAbAttr);
/** Is the target's magic bounce ability not ignored and able to reflect this move? */
const canMagicBounce =
!isReflecting &&
!move.doesFlagEffectApply({ flag: MoveFlags.IGNORE_ABILITIES, user, target }) &&
target.hasAbilityWithAttr(ReflectStatusMoveAbAttr);
const semiInvulnerableTag = target.getTag(SemiInvulnerableTag);
@ -333,21 +333,19 @@ export class MoveEffectPhase extends PokemonPhase {
(isReflecting || canMagicBounce) &&
!semiInvulnerableTag;
// If the move will bounce, then queue the bounce and move on to the next target
if (!target.switchOutStatus && willBounce) {
const newTargets = move.isMultiTarget()
? getMoveTargets(target, move.id).targets
: [user.getBattlerIndex()];
if (!isReflecting) {
// TODO: Ability displays should be handled by the ability
queuedPhases.push(
new ShowAbilityPhase(
target.getBattlerIndex(),
target.getPassiveAbility().hasAttr(ReflectStatusMoveAbAttr),
),
);
queuedPhases.push(new HideAbilityPhase());
}
// If the move will bounce, then queue the bounce and move on to the next target
if (!target.switchOutStatus && willBounce) {
const newTargets = move.isMultiTarget() ? getMoveTargets(target, move.id).targets : [user.getBattlerIndex()];
if (!isReflecting) {
// TODO: Ability displays should be handled by the ability
queuedPhases.push(
new ShowAbilityPhase(
target.getBattlerIndex(),
target.getPassiveAbility().hasAttr(ReflectStatusMoveAbAttr),
),
);
queuedPhases.push(new HideAbilityPhase());
}
queuedPhases.push(new MovePhase(target, newTargets, new PokemonMove(move.id, 0, 0, true), true, true, true));
continue;

View File

@ -4,7 +4,7 @@ import type { PartyOption } from "#app/ui/party-ui-handler";
import PartyUiHandler, { PartyUiMode } from "#app/ui/party-ui-handler";
import { Mode } from "#app/ui/ui";
import i18next from "i18next";
import * as Utils from "#app/utils";
import { toDmgValue, isNullOrUndefined } from "#app/utils";
import { BattlePhase } from "#app/phases/battle-phase";
import { SwitchSummonPhase } from "#app/phases/switch-summon-phase";
import { ToggleDoublePositionPhase } from "#app/phases/toggle-double-position-phase";
@ -33,7 +33,7 @@ export class RevivalBlessingPhase extends BattlePhase {
pokemon.resetTurnData();
pokemon.resetStatus();
pokemon.heal(Math.min(Utils.toDmgValue(0.5 * pokemon.getMaxHp()), pokemon.getMaxHp()));
pokemon.heal(Math.min(toDmgValue(0.5 * pokemon.getMaxHp()), pokemon.getMaxHp()));
globalScene.queueMessage(
i18next.t("moveTriggers:revivalBlessing", {
pokemonName: pokemon.name,
@ -46,7 +46,7 @@ export class RevivalBlessingPhase extends BattlePhase {
if (
globalScene.currentBattle.double &&
globalScene.getPlayerParty().length > 1 &&
!Utils.isNullOrUndefined(allyPokemon)
!isNullOrUndefined(allyPokemon)
) {
if (slotIndex <= 1) {
// Revived ally pokemon

View File

@ -12,7 +12,7 @@ import type { Starter } from "#app/ui/starter-select-ui-handler";
import { Mode } from "#app/ui/ui";
import type { Species } from "#enums/species";
import SoundFade from "phaser3-rex-plugins/plugins/soundfade";
import * as Utils from "../utils";
import { isNullOrUndefined } from "#app/utils";
export class SelectStarterPhase extends Phase {
start() {
@ -49,7 +49,7 @@ export class SelectStarterPhase extends Phase {
let starterFormIndex = Math.min(starterProps.formIndex, Math.max(starter.species.forms.length - 1, 0));
if (
starter.species.speciesId in Overrides.STARTER_FORM_OVERRIDES &&
!Utils.isNullOrUndefined(Overrides.STARTER_FORM_OVERRIDES[starter.species.speciesId]) &&
!isNullOrUndefined(Overrides.STARTER_FORM_OVERRIDES[starter.species.speciesId]) &&
starter.species.forms[Overrides.STARTER_FORM_OVERRIDES[starter.species.speciesId]!]
) {
starterFormIndex = Overrides.STARTER_FORM_OVERRIDES[starter.species.speciesId]!;
@ -87,7 +87,7 @@ export class SelectStarterPhase extends Phase {
starterPokemon.nickname = starter.nickname;
}
if (!Utils.isNullOrUndefined(starter.teraType)) {
if (!isNullOrUndefined(starter.teraType)) {
starterPokemon.teraType = starter.teraType;
} else {
starterPokemon.teraType = starterPokemon.species.type1;

View File

@ -1,6 +1,6 @@
import { globalScene } from "#app/global-scene";
import { TerrainType, getTerrainColor } from "../data/terrain";
import * as Utils from "../utils";
import { getCurrentTime } from "#app/utils";
import fieldSpriteFragShader from "./glsl/fieldSpriteFragShader.frag?raw";
import spriteVertShader from "./glsl/spriteShader.vert?raw";
@ -34,7 +34,7 @@ export default class FieldSpritePipeline extends Phaser.Renderer.WebGL.Pipelines
const time = globalScene.currentBattle?.waveIndex
? ((globalScene.currentBattle.waveIndex + globalScene.waveCycleOffset) % 40) / 40 // ((new Date().getSeconds() * 1000 + new Date().getMilliseconds()) % 10000) / 10000
: Utils.getCurrentTime();
: getCurrentTime();
this.set1f("time", time);
this.set1i("ignoreTimeTint", ignoreTimeTint ? 1 : 0);
this.set1i("isOutside", globalScene.arena.isOutside() ? 1 : 0);

View File

@ -3,7 +3,7 @@ import MysteryEncounterIntroVisuals from "#app/field/mystery-encounter-intro";
import Pokemon from "#app/field/pokemon";
import Trainer from "#app/field/trainer";
import { globalScene } from "#app/global-scene";
import * as Utils from "#app/utils";
import { rgbHexToRgba } from "#app/utils";
import FieldSpritePipeline from "./field-sprite";
import spriteFragShader from "./glsl/spriteFragShader.frag?raw";
import spriteVertShader from "./glsl/spriteShader.vert?raw";
@ -144,8 +144,8 @@ export default class SpritePipeline extends FieldSpritePipeline {
const baseColors = Object.keys(variantColors[variant]);
for (let c = 0; c < 32; c++) {
if (c < baseColors.length) {
const baseColor = Array.from(Object.values(Utils.rgbHexToRgba(baseColors[c])));
const variantColor = Array.from(Object.values(Utils.rgbHexToRgba(variantColors[variant][baseColors[c]])));
const baseColor = Array.from(Object.values(rgbHexToRgba(baseColors[c])));
const variantColor = Array.from(Object.values(rgbHexToRgba(variantColors[variant][baseColors[c]])));
flatBaseColors.splice(flatBaseColors.length, 0, ...baseColor);
flatVariantColors.splice(flatVariantColors.length, 0, ...variantColor.map(c => c / 255.0));
} else {

View File

@ -2,7 +2,7 @@ import type { Modifier } from "typescript";
import { TurnHeldItemTransferModifier } from "../modifier/modifier";
import { pokemonEvolutions } from "#app/data/balance/pokemon-evolutions";
import i18next from "i18next";
import * as Utils from "../utils";
import { NumberHolder } from "#app/utils";
import { PlayerGender } from "#enums/player-gender";
import type { Challenge } from "#app/data/challenge";
import {
@ -138,7 +138,7 @@ export class DamageAchv extends Achv {
"",
iconImage,
score,
(args: any[]) => (args[0] instanceof Utils.NumberHolder ? args[0].value : args[0]) >= this.damageAmount,
(args: any[]) => (args[0] instanceof NumberHolder ? args[0].value : args[0]) >= this.damageAmount,
);
this.damageAmount = damageAmount;
}
@ -154,7 +154,7 @@ export class HealAchv extends Achv {
"",
iconImage,
score,
(args: any[]) => (args[0] instanceof Utils.NumberHolder ? args[0].value : args[0]) >= this.healAmount,
(args: any[]) => (args[0] instanceof NumberHolder ? args[0].value : args[0]) >= this.healAmount,
);
this.healAmount = healAmount;
}
@ -170,7 +170,7 @@ export class LevelAchv extends Achv {
"",
iconImage,
score,
(args: any[]) => (args[0] instanceof Utils.NumberHolder ? args[0].value : args[0]) >= this.level,
(args: any[]) => (args[0] instanceof NumberHolder ? args[0].value : args[0]) >= this.level,
);
this.level = level;
}

View File

@ -8,7 +8,7 @@ import { pokemonPrevolutions } from "#app/data/balance/pokemon-evolutions";
import type PokemonSpecies from "#app/data/pokemon-species";
import { allSpecies, getPokemonSpecies } from "#app/data/pokemon-species";
import { speciesStarterCosts } from "#app/data/balance/starters";
import * as Utils from "#app/utils";
import { randInt, getEnumKeys, isLocal, executeIf, fixedInt, randSeedItem, NumberHolder } from "#app/utils";
import Overrides from "#app/overrides";
import PokemonData from "#app/system/pokemon-data";
import PersistentModifierData from "#app/system/modifier-data";
@ -37,6 +37,7 @@ import { setSettingGamepad, SettingGamepad, settingGamepadDefaults } from "#app/
import type { SettingKeyboard } from "#app/system/settings/settings-keyboard";
import { setSettingKeyboard } from "#app/system/settings/settings-keyboard";
import { TagAddedEvent, TerrainChangedEvent, WeatherChangedEvent } from "#app/events/arena";
// biome-ignore lint/style/noNamespaceImport: Something weird is going on here and I don't want to touch it
import * as Modifier from "#app/modifier/modifier";
import { StatusEffect } from "#enums/status-effect";
import ChallengeData from "#app/system/challenge-data";
@ -360,8 +361,8 @@ export class GameData {
this.loadSettings();
this.loadGamepadSettings();
this.loadMappingConfigs();
this.trainerId = Utils.randInt(65536);
this.secretId = Utils.randInt(65536);
this.trainerId = randInt(65536);
this.secretId = randInt(65536);
this.starterData = {};
this.gameStats = new GameStats();
this.runHistory = {};
@ -589,7 +590,7 @@ export class GameData {
}
if (systemData.voucherCounts) {
Utils.getEnumKeys(VoucherType).forEach(key => {
getEnumKeys(VoucherType).forEach(key => {
const index = VoucherType[key];
this.voucherCounts[index] = systemData.voucherCounts[index] || 0;
});
@ -617,7 +618,7 @@ export class GameData {
* At the moment, only retrievable from locale cache
*/
async getRunHistoryData(): Promise<RunHistoryData> {
if (!Utils.isLocal) {
if (!isLocal) {
/**
* Networking Code DO NOT DELETE!
* Note: Might have to be migrated to `pokerogue-api.ts`
@ -1035,6 +1036,7 @@ export class GameData {
}
getSession(slotId: number): Promise<SessionSaveData | null> {
// biome-ignore lint/suspicious/noAsyncPromiseExecutor: <explanation>
return new Promise(async (resolve, reject) => {
if (slotId < 0) {
return resolve(null);
@ -1075,6 +1077,7 @@ export class GameData {
}
loadSession(slotId: number, sessionData?: SessionSaveData): Promise<boolean> {
// biome-ignore lint/suspicious/noAsyncPromiseExecutor: <explanation>
return new Promise(async (resolve, reject) => {
try {
const initSessionFromData = async (sessionData: SessionSaveData) => {
@ -1406,7 +1409,7 @@ export class GameData {
saveAll(skipVerification = false, sync = false, useCachedSession = false, useCachedSystem = false): Promise<boolean> {
return new Promise<boolean>(resolve => {
Utils.executeIf(!skipVerification, updateUserInfo).then(success => {
executeIf(!skipVerification, updateUserInfo).then(success => {
if (success !== null && !success) {
return resolve(false);
}
@ -1586,7 +1589,7 @@ export class GameData {
}
const displayError = (error: string) =>
globalScene.ui.showText(error, null, () => globalScene.ui.showText("", 0), Utils.fixedInt(1500));
globalScene.ui.showText(error, null, () => globalScene.ui.showText("", 0), fixedInt(1500));
dataName = dataName!; // tell TS compiler that dataName is defined!
if (!valid) {
@ -1594,7 +1597,7 @@ export class GameData {
`Your ${dataName} data could not be loaded. It may be corrupted.`,
null,
() => globalScene.ui.showText("", 0),
Utils.fixedInt(1500),
fixedInt(1500),
);
}
@ -1687,7 +1690,7 @@ export class GameData {
() => {
const neutralNatures = [Nature.HARDY, Nature.DOCILE, Nature.SERIOUS, Nature.BASHFUL, Nature.QUIRKY];
for (let s = 0; s < defaultStarterSpecies.length; s++) {
defaultStarterNatures.push(Utils.randSeedItem(neutralNatures));
defaultStarterNatures.push(randSeedItem(neutralNatures));
}
},
0,
@ -2188,7 +2191,7 @@ export class GameData {
value = decrementValue(value);
}
const cost = new Utils.NumberHolder(value);
const cost = new NumberHolder(value);
applyChallenges(ChallengeType.STARTER_COST, speciesId, cost);
return cost.value;
@ -2216,7 +2219,7 @@ export class GameData {
entry.hatchedCount = 0;
}
if (!entry.hasOwnProperty("natureAttr") || (entry.caughtAttr && !entry.natureAttr)) {
entry.natureAttr = this.defaultDexData?.[k].natureAttr || 1 << Utils.randInt(25, 1);
entry.natureAttr = this.defaultDexData?.[k].natureAttr || 1 << randInt(25, 1);
}
}
}

View File

@ -3,7 +3,7 @@ import type FadeIn from "phaser3-rex-plugins/plugins/audio/fade/FadeIn";
import type FadeOut from "phaser3-rex-plugins/plugins/audio/fade/FadeOut";
import type BattleScene from "#app/battle-scene";
import { globalScene } from "#app/global-scene";
import * as Utils from "../utils";
import { FixedInt } from "#app/utils";
type FadeInType = typeof FadeIn;
type FadeOutType = typeof FadeOut;
@ -11,9 +11,9 @@ type FadeOutType = typeof FadeOut;
export function initGameSpeed() {
const thisArg = this as BattleScene;
const transformValue = (value: number | Utils.FixedInt): number => {
if (value instanceof Utils.FixedInt) {
return (value as Utils.FixedInt).value;
const transformValue = (value: number | FixedInt): number => {
if (value instanceof FixedInt) {
return (value as FixedInt).value;
}
return thisArg.gameSpeed === 1 ? value : Math.ceil((value /= thisArg.gameSpeed));
};

View File

@ -48,12 +48,15 @@ export const settingsMigrators: Readonly<SettingsSaveMigrator[]> = [settingsMigr
// import * as vA_B_C from "./versions/vA_B_C";
// --- v1.0.4 (and below) PATCHES --- //
// biome-ignore lint/style/noNamespaceImport: Convenience (TODO: make this a file-wide ignore when Biome supports those)
import * as v1_0_4 from "./versions/v1_0_4";
// --- v1.7.0 PATCHES --- //
// biome-ignore lint/style/noNamespaceImport: Convenience
import * as v1_7_0 from "./versions/v1_7_0";
// --- v1.8.3 PATCHES --- //
// biome-ignore lint/style/noNamespaceImport: Convenience
import * as v1_8_3 from "./versions/v1_8_3";
/** Current game version */

View File

@ -3,7 +3,7 @@ import { TextStyle, addBBCodeTextObject, getTextColor, getTextStyleOptions } fro
import { Mode } from "./ui";
import UiHandler from "./ui-handler";
import { addWindow } from "./ui-theme";
import * as Utils from "../utils";
import { rgbHexToRgba, fixedInt } from "#app/utils";
import { argbFromRgba } from "@material/material-color-utilities";
import { Button } from "#enums/buttons";
import BBCodeText from "phaser3-rex-plugins/plugins/gameobjects/tagtext/bbcodetext/BBCodeText";
@ -178,8 +178,8 @@ export default abstract class AbstractOptionSelectUiHandler extends UiHandler {
itemOverlayIcon.setPositionRelative(this.optionSelectText, 36 * this.scale, 7 + i * (114 * this.scale - 3));
if (option.itemArgs) {
itemIcon.setTint(argbFromRgba(Utils.rgbHexToRgba(option.itemArgs[0])));
itemOverlayIcon.setTint(argbFromRgba(Utils.rgbHexToRgba(option.itemArgs[1])));
itemIcon.setTint(argbFromRgba(rgbHexToRgba(option.itemArgs[0])));
itemOverlayIcon.setTint(argbFromRgba(rgbHexToRgba(option.itemArgs[1])));
}
}
}
@ -207,7 +207,7 @@ export default abstract class AbstractOptionSelectUiHandler extends UiHandler {
this.blockInput = true;
this.optionSelectTextContainer.setAlpha(0.5);
this.cursorObj?.setAlpha(0.8);
globalScene.time.delayedCall(Utils.fixedInt(this.config.delay), () => this.unblockInput());
globalScene.time.delayedCall(fixedInt(this.config.delay), () => this.unblockInput());
}
if (this.config?.supportHover) {

View File

@ -16,7 +16,7 @@ import type { TurnEndEvent } from "../events/battle-scene";
import { BattleSceneEventType } from "../events/battle-scene";
import { ArenaTagType } from "#enums/arena-tag-type";
import TimeOfDayWidget from "./time-of-day-widget";
import * as Utils from "../utils";
import { toCamelCaseString, formatText, fixedInt } from "#app/utils";
import type { ParseKeys } from "i18next";
import i18next from "i18next";
@ -47,10 +47,10 @@ export function getFieldEffectText(arenaTagType: string): string {
if (!arenaTagType || arenaTagType === ArenaTagType.NONE) {
return arenaTagType;
}
const effectName = Utils.toCamelCaseString(arenaTagType);
const effectName = toCamelCaseString(arenaTagType);
const i18nKey = `arenaFlyout:${effectName}` as ParseKeys;
const resultName = i18next.t(i18nKey);
return !resultName || resultName === i18nKey ? Utils.formatText(arenaTagType) : resultName;
return !resultName || resultName === i18nKey ? formatText(arenaTagType) : resultName;
}
export class ArenaFlyout extends Phaser.GameObjects.Container {
@ -411,7 +411,7 @@ export class ArenaFlyout extends Phaser.GameObjects.Container {
globalScene.tweens.add({
targets: this.flyoutParent,
x: visible ? this.anchorX : this.anchorX - this.translationX,
duration: Utils.fixedInt(125),
duration: fixedInt(125),
ease: "Sine.easeInOut",
alpha: visible ? 1 : 0,
onComplete: () => (this.timeOfDayWidget.parentVisible = visible),

View File

@ -1,7 +1,7 @@
import type { InfoToggle } from "../battle-scene";
import { TextStyle, addTextObject } from "./text";
import { addWindow } from "./ui-theme";
import * as Utils from "../utils";
import { fixedInt } from "#app/utils";
import i18next from "i18next";
import { globalScene } from "#app/global-scene";
@ -93,7 +93,7 @@ export class BaseStatsOverlay extends Phaser.GameObjects.Container implements In
}
globalScene.tweens.add({
targets: this.statsLabels,
duration: Utils.fixedInt(125),
duration: fixedInt(125),
ease: "Sine.easeInOut",
alpha: visible ? 1 : 0,
});

View File

@ -1,6 +1,6 @@
import type { default as Pokemon } from "../field/pokemon";
import { addTextObject, TextStyle } from "./text";
import * as Utils from "../utils";
import { fixedInt } from "#app/utils";
import { globalScene } from "#app/global-scene";
import type Move from "#app/data/moves/move";
import type { BerryUsedEvent, MoveUsedEvent } from "../events/battle-scene";
@ -201,7 +201,7 @@ export default class BattleFlyout extends Phaser.GameObjects.Container {
globalScene.tweens.add({
targets: this.flyoutParent,
x: visible ? this.anchorX : this.anchorX - this.translationX,
duration: Utils.fixedInt(125),
duration: fixedInt(125),
ease: "Sine.easeInOut",
alpha: visible ? 1 : 0,
});

View File

@ -1,6 +1,6 @@
import type { EnemyPokemon, default as Pokemon } from "../field/pokemon";
import { getLevelTotalExp, getLevelRelExp } from "../data/exp";
import * as Utils from "../utils";
import { getLocalizedSpriteKey, fixedInt } from "#app/utils";
import { addTextObject, TextStyle } from "./text";
import { getGenderSymbol, getGenderColor, Gender } from "../data/gender";
import { StatusEffect } from "#enums/status-effect";
@ -163,7 +163,7 @@ export default class BattleInfo extends Phaser.GameObjects.Container {
this.splicedIcon.setInteractive(new Phaser.Geom.Rectangle(0, 0, 12, 15), Phaser.Geom.Rectangle.Contains);
this.add(this.splicedIcon);
this.statusIndicator = globalScene.add.sprite(0, 0, Utils.getLocalizedSpriteKey("statuses"));
this.statusIndicator = globalScene.add.sprite(0, 0, getLocalizedSpriteKey("statuses"));
this.statusIndicator.setName("icon_status");
this.statusIndicator.setVisible(false);
this.statusIndicator.setOrigin(0, 0);
@ -536,7 +536,7 @@ export default class BattleInfo extends Phaser.GameObjects.Container {
toggleStats(visible: boolean): void {
globalScene.tweens.add({
targets: this.statsContainer,
duration: Utils.fixedInt(125),
duration: fixedInt(125),
ease: "Sine.easeInOut",
alpha: visible ? 1 : 0,
});

View File

@ -1,6 +1,6 @@
import { addTextObject, TextStyle } from "./text";
import i18next from "i18next";
import * as Utils from "#app/utils";
import { formatText } from "#app/utils";
import { globalScene } from "#app/global-scene";
const hiddenX = -150;
@ -100,7 +100,7 @@ export default class BgmBar extends Phaser.GameObjects.Container {
getRealBgmName(bgmName: string): string {
return i18next.t([`bgmName:${bgmName}`, "bgmName:missing_entries"], {
name: Utils.formatText(bgmName),
name: formatText(bgmName),
});
}
}

View File

@ -2,7 +2,7 @@ import { starterColors } from "#app/battle-scene";
import { globalScene } from "#app/global-scene";
import { TextStyle, addTextObject } from "./text";
import { argbFromRgba } from "@material/material-color-utilities";
import * as Utils from "../utils";
import { rgbHexToRgba } from "#app/utils";
import type { Species } from "#enums/species";
export default class CandyBar extends Phaser.GameObjects.Container {
@ -60,8 +60,8 @@ export default class CandyBar extends Phaser.GameObjects.Container {
const colorScheme = starterColors[starterSpeciesId];
this.candyIcon.setTint(argbFromRgba(Utils.rgbHexToRgba(colorScheme[0])));
this.candyOverlayIcon.setTint(argbFromRgba(Utils.rgbHexToRgba(colorScheme[1])));
this.candyIcon.setTint(argbFromRgba(rgbHexToRgba(colorScheme[0])));
this.candyOverlayIcon.setTint(argbFromRgba(rgbHexToRgba(colorScheme[1])));
this.countText.setText(
`${globalScene.gameData.starterData[starterSpeciesId].candyCount + count} (+${count.toString()})`,

View File

@ -5,7 +5,7 @@ import { addWindow } from "./ui-theme";
import { Button } from "#enums/buttons";
import i18next from "i18next";
import type { Challenge } from "#app/data/challenge";
import * as Utils from "../utils";
import { getLocalizedSpriteKey } from "#app/utils";
import { Challenges } from "#app/enums/challenges";
import BBCodeText from "phaser3-rex-plugins/plugins/bbcodetext";
import { Color, ShadowColor } from "#app/enums/color";
@ -193,7 +193,7 @@ export default class GameChallengesUiHandler extends UiHandler {
};
}
this.monoTypeValue = globalScene.add.sprite(8, 98, Utils.getLocalizedSpriteKey("types"));
this.monoTypeValue = globalScene.add.sprite(8, 98, getLocalizedSpriteKey("types"));
this.monoTypeValue.setName("challenge-value-monotype-sprite");
this.monoTypeValue.setScale(0.86);
this.monoTypeValue.setVisible(false);

View File

@ -1,5 +1,5 @@
import { globalScene } from "#app/global-scene";
import * as Utils from "../utils";
import { MissingTextureKey } from "#app/utils";
export default class CharSprite extends Phaser.GameObjects.Container {
private sprite: Phaser.GameObjects.Sprite;
@ -57,7 +57,7 @@ export default class CharSprite extends Phaser.GameObjects.Container {
},
});
this.setVisible(globalScene.textures.get(key).key !== Utils.MissingTextureKey);
this.setVisible(globalScene.textures.get(key).key !== MissingTextureKey);
this.shown = true;
this.key = key;

View File

@ -1,6 +1,6 @@
import i18next from "i18next";
import { globalScene } from "#app/global-scene";
import * as Utils from "../utils";
import { getEnumKeys, executeIf } from "#app/utils";
import { TextStyle, addTextObject } from "./text";
import { WindowVariant, addWindow } from "./ui-theme";
import { pokerogueApi } from "#app/plugins/api/pokerogue-api";
@ -89,7 +89,7 @@ export class DailyRunScoreboard extends Phaser.GameObjects.Container {
this.prevCategoryButton.setInteractive(new Phaser.Geom.Rectangle(0, 0, 6, 10), Phaser.Geom.Rectangle.Contains);
this.prevCategoryButton.on("pointerup", () => {
this.update(this.category ? this.category - 1 : Utils.getEnumKeys(ScoreboardCategory).length - 1);
this.update(this.category ? this.category - 1 : getEnumKeys(ScoreboardCategory).length - 1);
});
this.nextCategoryButton = globalScene.add.sprite(window.displayWidth - 4, 4, "cursor");
@ -98,7 +98,7 @@ export class DailyRunScoreboard extends Phaser.GameObjects.Container {
this.nextCategoryButton.setInteractive(new Phaser.Geom.Rectangle(0, 0, 6, 10), Phaser.Geom.Rectangle.Contains);
this.nextCategoryButton.on("pointerup", () => {
this.update(this.category < Utils.getEnumKeys(ScoreboardCategory).length - 1 ? this.category + 1 : 0);
this.update(this.category < getEnumKeys(ScoreboardCategory).length - 1 ? this.category + 1 : 0);
});
this.prevPageButton = globalScene.add.sprite(
@ -226,7 +226,7 @@ export class DailyRunScoreboard extends Phaser.GameObjects.Container {
this.page = page = 1;
}
Utils.executeIf(category !== this.category || this.pageCount === undefined, () =>
executeIf(category !== this.category || this.pageCount === undefined, () =>
pokerogueApi.daily.getRankingsPageCount({ category }).then(count => (this.pageCount = count)),
)
.then(() => {

View File

@ -1,7 +1,7 @@
import { Mode } from "./ui";
import { TextStyle, addTextObject, getEggTierTextTint, getTextStyleOptions } from "./text";
import MessageUiHandler from "./message-ui-handler";
import * as Utils from "../utils";
import { getEnumValues, getEnumKeys, fixedInt, randSeedShuffle } from "#app/utils";
import type { IEggOptions } from "../data/egg";
import { Egg, getLegendaryGachaSpeciesForTimestamp } from "../data/egg";
import { VoucherType, getVoucherTypeIcon } from "../system/voucher";
@ -83,7 +83,7 @@ export default class EggGachaUiHandler extends MessageUiHandler {
});
}
Utils.getEnumValues(GachaType).forEach((gachaType, g) => {
getEnumValues(GachaType).forEach((gachaType, g) => {
const gachaTypeKey = GachaType[gachaType].toString().toLowerCase();
const gachaContainer = globalScene.add.container(180 * g, 18);
@ -272,7 +272,7 @@ export default class EggGachaUiHandler extends MessageUiHandler {
this.eggGachaContainer.add(this.eggGachaOptionsContainer);
new Array(Utils.getEnumKeys(VoucherType).length).fill(null).map((_, i) => {
new Array(getEnumKeys(VoucherType).length).fill(null).map((_, i) => {
const container = globalScene.add.container(globalScene.game.canvas.width / 6 - 56 * i, 0);
const bg = addWindow(0, 0, 56, 22);
@ -355,7 +355,7 @@ export default class EggGachaUiHandler extends MessageUiHandler {
if (this.transitioning && this.transitionCancelled) {
delay = Math.ceil(delay / 5);
}
return Utils.fixedInt(delay);
return fixedInt(delay);
}
pull(pullCount = 0, count = 0, eggs?: Egg[]): void {
@ -476,7 +476,7 @@ export default class EggGachaUiHandler extends MessageUiHandler {
eggs.push(egg);
}
// Shuffle the eggs in case the guaranteed one got added as last egg
eggs = Utils.randSeedShuffle<Egg>(eggs);
eggs = randSeedShuffle<Egg>(eggs);
(globalScene.currentBattle
? globalScene.gameData.saveAll(true, true, true)
@ -643,7 +643,7 @@ export default class EggGachaUiHandler extends MessageUiHandler {
}
showError(text: string): void {
this.showText(text, undefined, () => this.showText(this.defaultText), Utils.fixedInt(1500));
this.showText(text, undefined, () => this.showText(this.defaultText), fixedInt(1500));
}
setTransitioning(transitioning: boolean): void {
@ -783,7 +783,7 @@ export default class EggGachaUiHandler extends MessageUiHandler {
}
break;
case Button.RIGHT:
if (this.gachaCursor < Utils.getEnumKeys(GachaType).length - 1) {
if (this.gachaCursor < getEnumKeys(GachaType).length - 1) {
success = this.setGachaCursor(this.gachaCursor + 1);
}
break;

View File

@ -6,7 +6,7 @@ import { PokemonType } from "#enums/pokemon-type";
import { Command } from "./command-ui-handler";
import { Mode } from "./ui";
import UiHandler from "./ui-handler";
import * as Utils from "../utils";
import { getLocalizedSpriteKey, fixedInt, padInt } from "#app/utils";
import { MoveCategory } from "#enums/MoveCategory";
import i18next from "i18next";
import { Button } from "#enums/buttons";
@ -54,7 +54,7 @@ export default class FightUiHandler extends UiHandler implements InfoToggle {
this.typeIcon = globalScene.add.sprite(
globalScene.scaledCanvas.width - 57,
-36,
Utils.getLocalizedSpriteKey("types"),
getLocalizedSpriteKey("types"),
"unknown",
);
this.typeIcon.setVisible(false);
@ -199,7 +199,7 @@ export default class FightUiHandler extends UiHandler implements InfoToggle {
}
globalScene.tweens.add({
targets: [this.movesContainer, this.cursorObj],
duration: Utils.fixedInt(125),
duration: fixedInt(125),
ease: "Sine.easeInOut",
alpha: visible ? 0 : 1,
});
@ -245,7 +245,7 @@ export default class FightUiHandler extends UiHandler implements InfoToggle {
if (hasMove) {
const pokemonMove = moveset[cursor];
const moveType = pokemon.getMoveType(pokemonMove.getMove());
const textureKey = Utils.getLocalizedSpriteKey("types");
const textureKey = getLocalizedSpriteKey("types");
this.typeIcon.setTexture(textureKey, PokemonType[moveType].toLowerCase()).setScale(0.8);
const moveCategory = pokemonMove.getMove().category;
@ -255,8 +255,8 @@ export default class FightUiHandler extends UiHandler implements InfoToggle {
const maxPP = pokemonMove.getMovePp();
const pp = maxPP - pokemonMove.ppUsed;
const ppLeftStr = Utils.padInt(pp, 2, " ");
const ppMaxStr = Utils.padInt(maxPP, 2, " ");
const ppLeftStr = padInt(pp, 2, " ");
const ppMaxStr = padInt(maxPP, 2, " ");
this.ppText.setText(`${ppLeftStr}/${ppMaxStr}`);
this.powerText.setText(`${power >= 0 ? power : "---"}`);
this.accuracyText.setText(`${accuracy >= 0 ? accuracy : "---"}`);

View File

@ -4,7 +4,7 @@ import type { Mode } from "./ui";
import { TextStyle, addTextInputObject, addTextObject } from "./text";
import { WindowVariant, addWindow } from "./ui-theme";
import type InputText from "phaser3-rex-plugins/plugins/inputtext";
import * as Utils from "../utils";
import { fixedInt } from "#app/utils";
import { Button } from "#enums/buttons";
import { globalScene } from "#app/global-scene";
@ -135,7 +135,7 @@ export abstract class FormModalUiHandler extends ModalUiHandler {
this.tween = globalScene.tweens.add({
targets: this.modalContainer,
duration: Utils.fixedInt(1000),
duration: fixedInt(1000),
ease: "Sine.easeInOut",
y: "-=24",
alpha: 1,

View File

@ -3,7 +3,7 @@ import { TextStyle, addTextObject } from "#app/ui/text";
import type { Mode } from "#app/ui/ui";
import UiHandler from "#app/ui/ui-handler";
import { addWindow } from "#app/ui/ui-theme";
import * as Utils from "#app/utils";
import { getPlayTimeString, formatFancyLargeNumber, toReadableString } from "#app/utils";
import type { GameData } from "#app/system/game-data";
import { DexAttr } from "#app/system/game-data";
import { speciesStarterCosts } from "#app/data/balance/starters";
@ -25,7 +25,7 @@ interface DisplayStats {
const displayStats: DisplayStats = {
playTime: {
label_key: "playTime",
sourceFunc: gameData => Utils.getPlayTimeString(gameData.gameStats.playTime),
sourceFunc: gameData => getPlayTimeString(gameData.gameStats.playTime),
},
battles: {
label_key: "totalBattles",
@ -91,7 +91,7 @@ const displayStats: DisplayStats = {
},
highestMoney: {
label_key: "highestMoney",
sourceFunc: gameData => Utils.formatFancyLargeNumber(gameData.gameStats.highestMoney),
sourceFunc: gameData => formatFancyLargeNumber(gameData.gameStats.highestMoney),
},
highestDamage: {
label_key: "highestDamage",
@ -435,7 +435,7 @@ export function initStatsKeys() {
}
if (!(displayStats[key] as DisplayStat).label_key) {
const splittableKey = key.replace(/([a-z]{2,})([A-Z]{1}(?:[^A-Z]|$))/g, "$1_$2");
(displayStats[key] as DisplayStat).label_key = Utils.toReadableString(
(displayStats[key] as DisplayStat).label_key = toReadableString(
`${splittableKey[0].toUpperCase()}${splittableKey.slice(1)}`,
);
}

View File

@ -1,7 +1,7 @@
import type { InputFieldConfig } from "./form-modal-ui-handler";
import { FormModalUiHandler } from "./form-modal-ui-handler";
import type { ModalConfig } from "./modal-ui-handler";
import * as Utils from "../utils";
import { fixedInt } from "#app/utils";
import { Mode } from "./ui";
import i18next from "i18next";
import { addTextObject, TextStyle } from "./text";
@ -283,7 +283,7 @@ export default class LoginFormUiHandler extends FormModalUiHandler {
this.externalPartyContainer.setAlpha(0);
globalScene.tweens.add({
targets: this.externalPartyContainer,
duration: Utils.fixedInt(1000),
duration: fixedInt(1000),
ease: "Sine.easeInOut",
y: "-=24",
alpha: 1,
@ -292,7 +292,7 @@ export default class LoginFormUiHandler extends FormModalUiHandler {
this.infoContainer.setAlpha(0);
globalScene.tweens.add({
targets: this.infoContainer,
duration: Utils.fixedInt(1000),
duration: fixedInt(1000),
ease: "Sine.easeInOut",
y: "-=24",
alpha: 1,

View File

@ -2,7 +2,7 @@ import { bypassLogin } from "#app/battle-scene";
import { globalScene } from "#app/global-scene";
import { TextStyle, addTextObject, getTextStyleOptions } from "./text";
import { Mode } from "./ui";
import * as Utils from "../utils";
import { getEnumKeys, isLocal, isBeta, fixedInt, getCookie, sessionIdKey } from "#app/utils";
import { addWindow, WindowVariant } from "./ui-theme";
import MessageUiHandler from "./message-ui-handler";
import type { OptionSelectConfig, OptionSelectItem } from "./abstact-option-select-ui-handler";
@ -75,7 +75,7 @@ export default class MenuUiHandler extends MessageUiHandler {
{ condition: bypassLogin, options: [MenuOptions.LOG_OUT] },
];
this.menuOptions = Utils.getEnumKeys(MenuOptions)
this.menuOptions = getEnumKeys(MenuOptions)
.map(m => Number.parseInt(MenuOptions[m]) as MenuOptions)
.filter(m => {
return !this.excludedMenus().some(exclusion => exclusion.condition && exclusion.options.includes(m));
@ -130,7 +130,7 @@ export default class MenuUiHandler extends MessageUiHandler {
{ condition: bypassLogin, options: [MenuOptions.LOG_OUT] },
];
this.menuOptions = Utils.getEnumKeys(MenuOptions)
this.menuOptions = getEnumKeys(MenuOptions)
.map(m => Number.parseInt(MenuOptions[m]) as MenuOptions)
.filter(m => {
return !this.excludedMenus().some(exclusion => exclusion.condition && exclusion.options.includes(m));
@ -238,7 +238,7 @@ export default class MenuUiHandler extends MessageUiHandler {
});
};
if (Utils.isLocal || Utils.isBeta) {
if (isLocal || isBeta) {
manageDataOptions.push({
label: i18next.t("menuUiHandler:importSession"),
handler: () => {
@ -292,7 +292,7 @@ export default class MenuUiHandler extends MessageUiHandler {
},
keepOpen: true,
});
if (Utils.isLocal || Utils.isBeta) {
if (isLocal || isBeta) {
manageDataOptions.push({
label: i18next.t("menuUiHandler:importData"),
handler: () => {
@ -328,7 +328,7 @@ export default class MenuUiHandler extends MessageUiHandler {
keepOpen: true,
},
);
if (Utils.isLocal || Utils.isBeta) {
if (isLocal || isBeta) {
// this should make sure we don't have this option in live
manageDataOptions.push({
label: "Test Dialogue",
@ -510,7 +510,7 @@ export default class MenuUiHandler extends MessageUiHandler {
this.render();
super.show(args);
this.menuOptions = Utils.getEnumKeys(MenuOptions)
this.menuOptions = getEnumKeys(MenuOptions)
.map(m => Number.parseInt(MenuOptions[m]) as MenuOptions)
.filter(m => {
return !this.excludedMenus().some(exclusion => exclusion.condition && exclusion.options.includes(m));
@ -574,7 +574,7 @@ export default class MenuUiHandler extends MessageUiHandler {
ui.setOverlayMode(Mode.EGG_LIST);
success = true;
} else {
ui.showText(i18next.t("menuUiHandler:noEggs"), null, () => ui.showText(""), Utils.fixedInt(1500));
ui.showText(i18next.t("menuUiHandler:noEggs"), null, () => ui.showText(""), fixedInt(1500));
error = true;
}
break;
@ -607,7 +607,7 @@ export default class MenuUiHandler extends MessageUiHandler {
: i18next.t("menuUiHandler:unlinkDiscord"),
handler: () => {
if (loggedInUser?.discordId === "") {
const token = Utils.getCookie(Utils.sessionIdKey);
const token = getCookie(sessionIdKey);
const redirectUri = encodeURIComponent(`${import.meta.env.VITE_SERVER_URL}/auth/discord/callback`);
const discordId = import.meta.env.VITE_DISCORD_CLIENT_ID;
const discordUrl = `https://discord.com/api/oauth2/authorize?client_id=${discordId}&redirect_uri=${redirectUri}&response_type=code&scope=identify&state=${token}&prompt=none`;
@ -627,7 +627,7 @@ export default class MenuUiHandler extends MessageUiHandler {
: i18next.t("menuUiHandler:unlinkGoogle"),
handler: () => {
if (loggedInUser?.googleId === "") {
const token = Utils.getCookie(Utils.sessionIdKey);
const token = getCookie(sessionIdKey);
const redirectUri = encodeURIComponent(`${import.meta.env.VITE_SERVER_URL}/auth/google/callback`);
const googleId = import.meta.env.VITE_GOOGLE_CLIENT_ID;
const googleUrl = `https://accounts.google.com/o/oauth2/auth?client_id=${googleId}&response_type=code&redirect_uri=${redirectUri}&scope=openid&state=${token}`;

View File

@ -1,6 +1,6 @@
import AwaitableUiHandler from "./awaitable-ui-handler";
import type { Mode } from "./ui";
import * as Utils from "../utils";
import { getFrameMs } from "#app/utils";
import { globalScene } from "#app/global-scene";
export default abstract class MessageUiHandler extends AwaitableUiHandler {
@ -183,7 +183,7 @@ export default abstract class MessageUiHandler extends AwaitableUiHandler {
if (charDelay) {
this.textTimer!.paused = true; // TODO: is the bang correct?
globalScene.tweens.addCounter({
duration: Utils.getFrameMs(charDelay),
duration: getFrameMs(charDelay),
onComplete: () => {
this.textTimer!.paused = false; // TODO: is the bang correct?
advance();
@ -193,7 +193,7 @@ export default abstract class MessageUiHandler extends AwaitableUiHandler {
this.textTimer!.paused = true;
globalScene.time.delayedCall(150, () => {
globalScene.ui.fadeOut(750).then(() => {
const delay = Utils.getFrameMs(charFade);
const delay = getFrameMs(charFade);
globalScene.time.delayedCall(delay, () => {
globalScene.ui.fadeIn(500).then(() => {
this.textTimer!.paused = false;

View File

@ -10,11 +10,10 @@ import { handleTutorial, Tutorial } from "../tutorial";
import { Button } from "#enums/buttons";
import MoveInfoOverlay from "./move-info-overlay";
import { allMoves } from "../data/moves/move";
import * as Utils from "./../utils";
import { formatMoney, NumberHolder } from "#app/utils";
import Overrides from "#app/overrides";
import i18next from "i18next";
import { ShopCursorTarget } from "#app/enums/shop-cursor-target";
import { NumberHolder } from "./../utils";
import Phaser from "phaser";
import type { PokeballType } from "#enums/pokeball";
@ -645,7 +644,7 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler {
this.rerollCostText.setVisible(true);
const canReroll = globalScene.money >= this.rerollCost;
const formattedMoney = Utils.formatMoney(globalScene.moneyFormat, this.rerollCost);
const formattedMoney = formatMoney(globalScene.moneyFormat, this.rerollCost);
this.rerollCostText.setText(i18next.t("modifierSelectUiHandler:rerollCost", { formattedMoney }));
this.rerollCostText.setColor(this.getTextColor(canReroll ? TextStyle.MONEY : TextStyle.PARTY_RED));
@ -933,7 +932,7 @@ class ModifierOption extends Phaser.GameObjects.Container {
const cost = Overrides.WAIVE_ROLL_FEE_OVERRIDE ? 0 : this.modifierTypeOption.cost;
const textStyle = cost <= globalScene.money ? TextStyle.MONEY : TextStyle.PARTY_RED;
const formattedMoney = Utils.formatMoney(globalScene.moneyFormat, cost);
const formattedMoney = formatMoney(globalScene.moneyFormat, cost);
this.itemCostText.setText(i18next.t("modifierSelectUiHandler:itemCost", { formattedMoney }));
this.itemCostText.setColor(getTextColor(textStyle, false, globalScene.uiTheme));

View File

@ -2,7 +2,7 @@ import type { InfoToggle } from "#app/battle-scene";
import { globalScene } from "#app/global-scene";
import { TextStyle, addTextObject } from "./text";
import { addWindow } from "./ui-theme";
import * as Utils from "../utils";
import { getLocalizedSpriteKey, fixedInt } from "#app/utils";
import type Move from "../data/moves/move";
import { MoveCategory } from "#enums/MoveCategory";
import { PokemonType } from "#enums/pokemon-type";
@ -120,7 +120,7 @@ export default class MoveInfoOverlay extends Phaser.GameObjects.Container implem
valuesBg.setOrigin(0, 0);
this.val.add(valuesBg);
this.typ = globalScene.add.sprite(25, EFF_HEIGHT - 35, Utils.getLocalizedSpriteKey("types"), "unknown");
this.typ = globalScene.add.sprite(25, EFF_HEIGHT - 35, getLocalizedSpriteKey("types"), "unknown");
this.typ.setScale(0.8);
this.val.add(this.typ);
@ -175,7 +175,7 @@ export default class MoveInfoOverlay extends Phaser.GameObjects.Container implem
this.pow.setText(move.power >= 0 ? move.power.toString() : "---");
this.acc.setText(move.accuracy >= 0 ? move.accuracy.toString() : "---");
this.pp.setText(move.pp >= 0 ? move.pp.toString() : "---");
this.typ.setTexture(Utils.getLocalizedSpriteKey("types"), PokemonType[move.type].toLowerCase());
this.typ.setTexture(getLocalizedSpriteKey("types"), PokemonType[move.type].toLowerCase());
this.cat.setFrame(MoveCategory[move.category].toLowerCase());
this.desc.setText(move?.effect || "");
@ -193,10 +193,10 @@ export default class MoveInfoOverlay extends Phaser.GameObjects.Container implem
// generate scrolling effects
this.descScroll = globalScene.tweens.add({
targets: this.desc,
delay: Utils.fixedInt(2000),
delay: fixedInt(2000),
loop: -1,
hold: Utils.fixedInt(2000),
duration: Utils.fixedInt((moveDescriptionLineCount - 3) * 2000),
hold: fixedInt(2000),
duration: fixedInt((moveDescriptionLineCount - 3) * 2000),
y: `-=${14.83 * (72 / 96) * (moveDescriptionLineCount - 3)}`,
});
}
@ -219,7 +219,7 @@ export default class MoveInfoOverlay extends Phaser.GameObjects.Container implem
}
globalScene.tweens.add({
targets: this.desc,
duration: Utils.fixedInt(125),
duration: fixedInt(125),
ease: "Sine.easeInOut",
alpha: visible ? 1 : 0,
});

View File

@ -6,8 +6,7 @@ import { addWindow, WindowVariant } from "./ui-theme";
import type { MysteryEncounterPhase } from "../phases/mystery-encounter-phases";
import { PartyUiMode } from "./party-ui-handler";
import type MysteryEncounterOption from "#app/data/mystery-encounters/mystery-encounter-option";
import * as Utils from "../utils";
import { isNullOrUndefined } from "../utils";
import { fixedInt, isNullOrUndefined } from "#app/utils";
import { getPokeballAtlasKey } from "../data/pokeball";
import type { OptionSelectSettings } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
import { getEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
@ -456,10 +455,10 @@ export default class MysteryEncounterUiHandler extends UiHandler {
if (optionTextWidth > nonScrollWidth) {
this.optionScrollTweens[i] = globalScene.tweens.add({
targets: optionText,
delay: Utils.fixedInt(2000),
delay: fixedInt(2000),
loop: -1,
hold: Utils.fixedInt(2000),
duration: Utils.fixedInt(((optionTextWidth - nonScrollWidth) / 15) * 2000),
hold: fixedInt(2000),
duration: fixedInt(((optionTextWidth - nonScrollWidth) / 15) * 2000),
x: `-=${optionTextWidth - nonScrollWidth}`,
});
}
@ -527,10 +526,10 @@ export default class MysteryEncounterUiHandler extends UiHandler {
if (descriptionLineCount > 6) {
this.descriptionScrollTween = globalScene.tweens.add({
targets: descriptionTextObject,
delay: Utils.fixedInt(2000),
delay: fixedInt(2000),
loop: -1,
hold: Utils.fixedInt(2000),
duration: Utils.fixedInt((descriptionLineCount - 6) * 2000),
hold: fixedInt(2000),
duration: fixedInt((descriptionLineCount - 6) * 2000),
y: `-=${10 * (descriptionLineCount - 6)}`,
});
}
@ -637,10 +636,10 @@ export default class MysteryEncounterUiHandler extends UiHandler {
if (tooltipLineCount > 3) {
this.tooltipScrollTween = globalScene.tweens.add({
targets: tooltipTextObject,
delay: Utils.fixedInt(1200),
delay: fixedInt(1200),
loop: -1,
hold: Utils.fixedInt(1200),
duration: Utils.fixedInt((tooltipLineCount - 3) * 1200),
hold: fixedInt(1200),
duration: fixedInt((tooltipLineCount - 3) * 1200),
y: `-=${11.2 * (tooltipLineCount - 3)}`,
});
}

View File

@ -5,7 +5,7 @@ import { addBBCodeTextObject, addTextObject, getTextColor, TextStyle } from "#ap
import { Command } from "#app/ui/command-ui-handler";
import MessageUiHandler from "#app/ui/message-ui-handler";
import { Mode } from "#app/ui/ui";
import * as Utils from "#app/utils";
import { BooleanHolder, toReadableString, randInt, getLocalizedSpriteKey } from "#app/utils";
import {
PokemonFormChangeItemModifier,
PokemonHeldItemModifier,
@ -215,7 +215,7 @@ export default class PartyUiHandler extends MessageUiHandler {
* @returns
*/
private FilterChallengeLegal = (pokemon: PlayerPokemon) => {
const challengeAllowed = new Utils.BooleanHolder(true);
const challengeAllowed = new BooleanHolder(true);
applyChallenges(ChallengeType.POKEMON_IN_BATTLE, pokemon, challengeAllowed);
if (!challengeAllowed.value) {
return i18next.t("partyUiHandler:cantBeUsed", {
@ -1201,7 +1201,7 @@ export default class PartyUiHandler extends MessageUiHandler {
if (this.localizedOptions.includes(option)) {
optionName = i18next.t(`partyUiHandler:${PartyOption[option]}`);
} else {
optionName = Utils.toReadableString(PartyOption[option]);
optionName = toReadableString(PartyOption[option]);
}
}
break;
@ -1309,7 +1309,7 @@ export default class PartyUiHandler extends MessageUiHandler {
}
getReleaseMessage(pokemonName: string): string {
const rand = Utils.randInt(128);
const rand = randInt(128);
if (rand < 20) {
return i18next.t("partyUiHandler:goodbye", { pokemonName: pokemonName });
}
@ -1566,7 +1566,7 @@ class PartySlot extends Phaser.GameObjects.Container {
}
if (this.pokemon.status) {
const statusIndicator = globalScene.add.sprite(0, 0, Utils.getLocalizedSpriteKey("statuses"));
const statusIndicator = globalScene.add.sprite(0, 0, getLocalizedSpriteKey("statuses"));
statusIndicator.setFrame(StatusEffect[this.pokemon.status?.effect].toLowerCase());
statusIndicator.setOrigin(0, 0);
statusIndicator.setPositionRelative(slotLevelLabel, this.slotIndex >= battlerCount ? 43 : 55, 0);

View File

@ -1,7 +1,7 @@
import type { InfoToggle } from "../battle-scene";
import { TextStyle, addTextObject } from "./text";
import { addWindow } from "./ui-theme";
import * as Utils from "../utils";
import { fixedInt } from "#app/utils";
import i18next from "i18next";
import { globalScene } from "#app/global-scene";
@ -128,10 +128,10 @@ export default class PokedexInfoOverlay extends Phaser.GameObjects.Container imp
// generate scrolling effects
this.descScroll = globalScene.tweens.add({
targets: this.desc,
delay: Utils.fixedInt(2000),
delay: fixedInt(2000),
loop: -1,
hold: Utils.fixedInt(2000),
duration: Utils.fixedInt((lineCount - 3) * 2000),
hold: fixedInt(2000),
duration: fixedInt((lineCount - 3) * 2000),
y: `-=${14.83 * (72 / 96) * (lineCount - 3)}`,
});
}
@ -154,7 +154,7 @@ export default class PokedexInfoOverlay extends Phaser.GameObjects.Container imp
}
globalScene.tweens.add({
targets: this.desc,
duration: Utils.fixedInt(125),
duration: fixedInt(125),
ease: "Sine.easeInOut",
alpha: visible ? 1 : 0,
});

View File

@ -54,7 +54,7 @@ import {
toReadableString,
} from "#app/utils";
import type { Nature } from "#enums/nature";
import * as Utils from "../utils";
import { getEnumKeys } from "#app/utils";
import { speciesTmMoves } from "#app/data/balance/tms";
import type { BiomeTierTod } from "#app/data/balance/biomes";
import { BiomePoolTier, catchableSpecies } from "#app/data/balance/biomes";
@ -592,7 +592,7 @@ export default class PokedexPageUiHandler extends MessageUiHandler {
this.menuContainer.setVisible(false);
this.menuOptions = Utils.getEnumKeys(MenuOptions).map(m => Number.parseInt(MenuOptions[m]) as MenuOptions);
this.menuOptions = getEnumKeys(MenuOptions).map(m => Number.parseInt(MenuOptions[m]) as MenuOptions);
this.optionSelectText = addBBCodeTextObject(
0,
@ -696,7 +696,7 @@ export default class PokedexPageUiHandler extends MessageUiHandler {
this.starterAttributes = this.initStarterPrefs();
this.menuOptions = Utils.getEnumKeys(MenuOptions).map(m => Number.parseInt(MenuOptions[m]) as MenuOptions);
this.menuOptions = getEnumKeys(MenuOptions).map(m => Number.parseInt(MenuOptions[m]) as MenuOptions);
this.menuContainer.setVisible(true);

View File

@ -1,7 +1,7 @@
import PokemonInfoContainer from "#app/ui/pokemon-info-container";
import { Gender } from "#app/data/gender";
import { PokemonType } from "#enums/pokemon-type";
import * as Utils from "#app/utils";
import { rgbHexToRgba, padInt } from "#app/utils";
import { TextStyle, addTextObject } from "#app/ui/text";
import { speciesEggMoves } from "#app/data/balance/egg-moves";
import { allMoves } from "#app/data/moves/move";
@ -154,14 +154,14 @@ export default class PokemonHatchInfoContainer extends PokemonInfoContainer {
super.show(pokemon, false, 1, hatchInfo.getDex(), hatchInfo.getStarterEntry(), true);
const colorScheme = starterColors[species.speciesId];
this.pokemonCandyIcon.setTint(argbFromRgba(Utils.rgbHexToRgba(colorScheme[0])));
this.pokemonCandyIcon.setTint(argbFromRgba(rgbHexToRgba(colorScheme[0])));
this.pokemonCandyIcon.setVisible(true);
this.pokemonCandyOverlayIcon.setTint(argbFromRgba(Utils.rgbHexToRgba(colorScheme[1])));
this.pokemonCandyOverlayIcon.setTint(argbFromRgba(rgbHexToRgba(colorScheme[1])));
this.pokemonCandyOverlayIcon.setVisible(true);
this.pokemonCandyCountText.setText(`x${globalScene.gameData.starterData[species.speciesId].candyCount}`);
this.pokemonCandyCountText.setVisible(true);
this.pokemonNumberText.setText(Utils.padInt(species.speciesId, 4));
this.pokemonNumberText.setText(padInt(species.speciesId, 4));
this.pokemonNameText.setText(species.name);
const hasEggMoves = species && speciesEggMoves.hasOwnProperty(species.speciesId);

View File

@ -1,5 +1,5 @@
import { globalScene } from "#app/global-scene";
import * as Utils from "../utils";
import { fixedInt } from "#app/utils";
export enum PokemonIconAnimMode {
NONE,
@ -27,7 +27,7 @@ export default class PokemonIconAnimHandler {
}
};
globalScene.tweens.addCounter({
duration: Utils.fixedInt(200),
duration: fixedInt(200),
from: 0,
to: 1,
yoyo: true,

View File

@ -8,7 +8,7 @@ import type Pokemon from "../field/pokemon";
import i18next from "i18next";
import type { DexEntry, StarterDataEntry } from "../system/game-data";
import { DexAttr } from "../system/game-data";
import * as Utils from "../utils";
import { fixedInt } from "#app/utils";
import ConfirmUiHandler from "./confirm-ui-handler";
import { StatsContainer } from "./stats-container";
import { TextStyle, addBBCodeTextObject, addTextObject, getTextColor } from "./text";
@ -393,7 +393,7 @@ export default class PokemonInfoContainer extends Phaser.GameObjects.Container {
if (!eggInfo) {
globalScene.tweens.add({
targets: this,
duration: Utils.fixedInt(Math.floor(750 / speedMultiplier)),
duration: fixedInt(Math.floor(750 / speedMultiplier)),
ease: "Cubic.easeInOut",
x: this.initialX - this.infoWindowWidth,
onComplete: () => {
@ -403,9 +403,9 @@ export default class PokemonInfoContainer extends Phaser.GameObjects.Container {
if (showMoves) {
globalScene.tweens.add({
delay: Utils.fixedInt(Math.floor(325 / speedMultiplier)),
delay: fixedInt(Math.floor(325 / speedMultiplier)),
targets: this.pokemonMovesContainer,
duration: Utils.fixedInt(Math.floor(325 / speedMultiplier)),
duration: fixedInt(Math.floor(325 / speedMultiplier)),
ease: "Cubic.easeInOut",
x: this.movesContainerInitialX - 57,
onComplete: () => resolve(),
@ -463,7 +463,7 @@ export default class PokemonInfoContainer extends Phaser.GameObjects.Container {
return new Promise<void>(resolve => {
globalScene.tweens.add({
targets: this,
duration: Utils.fixedInt(Math.floor(150 / speedMultiplier)),
duration: fixedInt(Math.floor(150 / speedMultiplier)),
ease: "Cubic.easeInOut",
x: xPosition,
onComplete: () => {
@ -482,14 +482,14 @@ export default class PokemonInfoContainer extends Phaser.GameObjects.Container {
globalScene.tweens.add({
targets: this.pokemonMovesContainer,
duration: Utils.fixedInt(Math.floor(750 / speedMultiplier)),
duration: fixedInt(Math.floor(750 / speedMultiplier)),
ease: "Cubic.easeInOut",
x: this.movesContainerInitialX,
});
globalScene.tweens.add({
targets: this,
duration: Utils.fixedInt(Math.floor(750 / speedMultiplier)),
duration: fixedInt(Math.floor(750 / speedMultiplier)),
ease: "Cubic.easeInOut",
x: this.initialX,
onComplete: () => {

View File

@ -3,7 +3,7 @@ import { GameModes } from "../game-mode";
import { TextStyle, addTextObject } from "./text";
import { Mode } from "./ui";
import { addWindow } from "./ui-theme";
import * as Utils from "../utils";
import { fixedInt, formatLargeNumber } from "#app/utils";
import type PokemonData from "../system/pokemon-data";
import MessageUiHandler from "./message-ui-handler";
import i18next from "i18next";
@ -218,7 +218,7 @@ export default class RunHistoryUiHandler extends MessageUiHandler {
globalScene.tweens.add({
targets: this.runsContainer,
y: this.runContainerInitialY - 56 * scrollCursor,
duration: Utils.fixedInt(325),
duration: fixedInt(325),
ease: "Sine.easeInOut",
});
}
@ -314,7 +314,7 @@ class RunEntryContainer extends Phaser.GameObjects.Container {
const enemyLevel = addTextObject(
32,
20,
`${i18next.t("saveSlotSelectUiHandler:lv")}${Utils.formatLargeNumber(enemy.level, 1000)}`,
`${i18next.t("saveSlotSelectUiHandler:lv")}${formatLargeNumber(enemy.level, 1000)}`,
TextStyle.PARTY,
{ fontSize: "54px", color: "#f8f8f8" },
);
@ -408,7 +408,7 @@ class RunEntryContainer extends Phaser.GameObjects.Container {
const text = addTextObject(
32,
20,
`${i18next.t("saveSlotSelectUiHandler:lv")}${Utils.formatLargeNumber(pokemon.level, 1000)}`,
`${i18next.t("saveSlotSelectUiHandler:lv")}${formatLargeNumber(pokemon.level, 1000)}`,
TextStyle.PARTY,
{ fontSize: "54px", color: "#f8f8f8" },
);

View File

@ -5,7 +5,7 @@ import { TextStyle, addTextObject, addBBCodeTextObject, getTextColor } from "./t
import { Mode } from "./ui";
import { addWindow } from "./ui-theme";
import { getPokeballAtlasKey } from "#app/data/pokeball";
import * as Utils from "../utils";
import { formatLargeNumber, getPlayTimeString, formatMoney, formatFancyLargeNumber } from "#app/utils";
import type PokemonData from "../system/pokemon-data";
import i18next from "i18next";
import { Button } from "../enums/buttons";
@ -19,7 +19,8 @@ import { PokemonType } from "#enums/pokemon-type";
import { TypeColor, TypeShadow } from "#app/enums/color";
import { getNatureStatMultiplier, getNatureName } from "../data/nature";
import { getVariantTint } from "#app/sprites/variant";
import * as Modifier from "../modifier/modifier";
// biome-ignore lint/style/noNamespaceImport: See `src/system/game-data.ts`
import * as Modifier from "#app/modifier/modifier";
import type { Species } from "#enums/species";
import { PlayerGender } from "#enums/player-gender";
import { SettingKeyboard } from "#app/system/settings/settings-keyboard";
@ -411,7 +412,7 @@ export default class RunInfoUiHandler extends UiHandler {
const enemyLevel = addTextObject(
36,
26,
`${i18next.t("saveSlotSelectUiHandler:lv")}${Utils.formatLargeNumber(enemy.level, 1000)}`,
`${i18next.t("saveSlotSelectUiHandler:lv")}${formatLargeNumber(enemy.level, 1000)}`,
enemyLevelStyle,
{ fontSize: "44px", color: "#f8f8f8" },
);
@ -441,7 +442,7 @@ export default class RunInfoUiHandler extends UiHandler {
const enemyLevel = addTextObject(
36,
26,
`${i18next.t("saveSlotSelectUiHandler:lv")}${Utils.formatLargeNumber(enemy.level, 1000)}`,
`${i18next.t("saveSlotSelectUiHandler:lv")}${formatLargeNumber(enemy.level, 1000)}`,
bossStatus ? TextStyle.PARTY_RED : TextStyle.PARTY,
{ fontSize: "44px", color: "#f8f8f8" },
);
@ -527,7 +528,7 @@ export default class RunInfoUiHandler extends UiHandler {
const enemyLevel = addTextObject(
43 * (e % 3),
27 * (pokemonRowHeight + 1),
`${i18next.t("saveSlotSelectUiHandler:lv")}${Utils.formatLargeNumber(enemy.level, 1000)}`,
`${i18next.t("saveSlotSelectUiHandler:lv")}${formatLargeNumber(enemy.level, 1000)}`,
isBoss ? TextStyle.PARTY_RED : TextStyle.PARTY,
{ fontSize: "54px" },
);
@ -606,9 +607,9 @@ export default class RunInfoUiHandler extends UiHandler {
fontSize: "50px",
lineSpacing: lineSpacing,
});
const runTime = Utils.getPlayTimeString(this.runInfo.playTime);
const runTime = getPlayTimeString(this.runInfo.playTime);
runInfoText.appendText(`${i18next.t("runHistory:runLength")}: ${runTime}`, false);
const runMoney = Utils.formatMoney(globalScene.moneyFormat, this.runInfo.money);
const runMoney = formatMoney(globalScene.moneyFormat, this.runInfo.money);
const moneyTextColor = getTextColor(TextStyle.MONEY_WINDOW, false, globalScene.uiTheme);
runInfoText.appendText(
`[color=${moneyTextColor}]${i18next.t("battleScene:moneyOwned", { formattedMoney: runMoney })}[/color]`,
@ -770,7 +771,7 @@ export default class RunInfoUiHandler extends UiHandler {
lineSpacing: lineSpacing,
});
pokeInfoText.appendText(
`${i18next.t("saveSlotSelectUiHandler:lv")}${Utils.formatFancyLargeNumber(pokemon.level, 1)} - ${pNatureName}`,
`${i18next.t("saveSlotSelectUiHandler:lv")}${formatFancyLargeNumber(pokemon.level, 1)} - ${pNatureName}`,
);
pokeInfoText.appendText(pAbilityInfo);
pokeInfoText.appendText(pPassiveInfo);
@ -780,7 +781,7 @@ export default class RunInfoUiHandler extends UiHandler {
// Colored Arrows (Red/Blue) are placed by stats that are boosted from natures
const pokeStatTextContainer = globalScene.add.container(-35, 6);
const pStats: string[] = [];
pokemon.stats.forEach(element => pStats.push(Utils.formatFancyLargeNumber(element, 1)));
pokemon.stats.forEach(element => pStats.push(formatFancyLargeNumber(element, 1)));
for (let i = 0; i < pStats.length; i++) {
const isMult = getNatureStatMultiplier(pNature, i);
pStats[i] = isMult < 1 ? pStats[i] + "[color=#40c8f8]↓[/color]" : pStats[i];

View File

@ -2,10 +2,11 @@ import i18next from "i18next";
import { globalScene } from "#app/global-scene";
import { Button } from "#enums/buttons";
import { GameMode } from "../game-mode";
import * as Modifier from "../modifier/modifier";
// biome-ignore lint/style/noNamespaceImport: See `src/system/game-data.ts`
import * as Modifier from "#app/modifier/modifier";
import type { SessionSaveData } from "../system/game-data";
import type PokemonData from "../system/pokemon-data";
import * as Utils from "../utils";
import { isNullOrUndefined, fixedInt, getPlayTimeString, formatLargeNumber } from "#app/utils";
import MessageUiHandler from "./message-ui-handler";
import { TextStyle, addTextObject } from "./text";
import { Mode } from "./ui";
@ -296,7 +297,7 @@ export default class SaveSlotSelectUiHandler extends MessageUiHandler {
}
this.setArrowVisibility(hasData);
}
if (!Utils.isNullOrUndefined(prevSlotIndex)) {
if (!isNullOrUndefined(prevSlotIndex)) {
this.revertSessionSlot(prevSlotIndex);
}
@ -339,7 +340,7 @@ export default class SaveSlotSelectUiHandler extends MessageUiHandler {
globalScene.tweens.add({
targets: this.sessionSlotsContainer,
y: this.sessionSlotsContainerInitialY - 56 * scrollCursor,
duration: Utils.fixedInt(325),
duration: fixedInt(325),
ease: "Sine.easeInOut",
});
}
@ -407,7 +408,7 @@ class SessionSlot extends Phaser.GameObjects.Container {
const timestampLabel = addTextObject(8, 19, new Date(data.timestamp).toLocaleString(), TextStyle.WINDOW);
this.add(timestampLabel);
const playTimeLabel = addTextObject(8, 33, Utils.getPlayTimeString(data.playTime), TextStyle.WINDOW);
const playTimeLabel = addTextObject(8, 33, getPlayTimeString(data.playTime), TextStyle.WINDOW);
this.add(playTimeLabel);
const pokemonIconsContainer = globalScene.add.container(144, 4);
@ -421,7 +422,7 @@ class SessionSlot extends Phaser.GameObjects.Container {
const text = addTextObject(
32,
20,
`${i18next.t("saveSlotSelectUiHandler:lv")}${Utils.formatLargeNumber(pokemon.level, 1000)}`,
`${i18next.t("saveSlotSelectUiHandler:lv")}${formatLargeNumber(pokemon.level, 1000)}`,
TextStyle.PARTY,
{ fontSize: "54px", color: "#f8f8f8" },
);

View File

@ -1,5 +1,5 @@
import { globalScene } from "#app/global-scene";
import * as Utils from "../utils";
import { fixedInt } from "#app/utils";
export default class SavingIconHandler extends Phaser.GameObjects.Container {
private icon: Phaser.GameObjects.Sprite;
@ -36,10 +36,10 @@ export default class SavingIconHandler extends Phaser.GameObjects.Container {
globalScene.tweens.add({
targets: this,
alpha: 1,
duration: Utils.fixedInt(250),
duration: fixedInt(250),
ease: "Sine.easeInOut",
onComplete: () => {
globalScene.time.delayedCall(Utils.fixedInt(500), () => {
globalScene.time.delayedCall(fixedInt(500), () => {
this.animActive = false;
if (!this.shown) {
this.hide();
@ -64,7 +64,7 @@ export default class SavingIconHandler extends Phaser.GameObjects.Container {
globalScene.tweens.add({
targets: this,
alpha: 0,
duration: Utils.fixedInt(250),
duration: fixedInt(250),
ease: "Sine.easeInOut",
onComplete: () => {
this.animActive = false;

View File

@ -43,7 +43,7 @@ import { Egg } from "#app/data/egg";
import Overrides from "#app/overrides";
import { SettingKeyboard } from "#app/system/settings/settings-keyboard";
import { Passive as PassiveAttr } from "#enums/passive";
import * as Challenge from "#app/data/challenge";
import { applyChallenges, ChallengeType } from "#app/data/challenge";
import MoveInfoOverlay from "#app/ui/move-info-overlay";
import { getEggTierForSpecies } from "#app/data/egg";
import { Device } from "#enums/devices";
@ -78,7 +78,6 @@ import {
import type { Nature } from "#enums/nature";
import { PLAYER_PARTY_MAX_SIZE } from "#app/constants";
import { achvs } from "#app/system/achv";
import * as Utils from "../utils";
import type { GameObjects } from "phaser";
import { checkStarterValidForChallenge } from "#app/data/challenge";
@ -2518,7 +2517,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
case Button.CYCLE_TERA:
if (this.canCycleTera) {
const speciesForm = getPokemonSpeciesForm(this.lastSpecies.speciesId, starterAttributes.form ?? 0);
if (speciesForm.type1 === this.teraCursor && !Utils.isNullOrUndefined(speciesForm.type2)) {
if (speciesForm.type1 === this.teraCursor && !isNullOrUndefined(speciesForm.type2)) {
starterAttributes.tera = speciesForm.type2!;
this.setSpeciesDetails(this.lastSpecies, {
teraType: speciesForm.type2!,
@ -2960,7 +2959,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
valueLimit.value = 10;
}
Challenge.applyChallenges(Challenge.ChallengeType.STARTER_POINTS, valueLimit);
applyChallenges(ChallengeType.STARTER_POINTS, valueLimit);
return valueLimit.value;
}
@ -3748,7 +3747,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
); // TODO: is this bang correct?
this.abilityCursor = abilityIndex !== undefined ? abilityIndex : (abilityIndex = oldAbilityIndex);
this.natureCursor = natureIndex !== undefined ? natureIndex : (natureIndex = oldNatureIndex);
this.teraCursor = !Utils.isNullOrUndefined(teraType) ? teraType : (teraType = species.type1);
this.teraCursor = !isNullOrUndefined(teraType) ? teraType : (teraType = species.type1);
const [isInParty, partyIndex]: [boolean, number] = this.isInParty(species); // we use this to firstly check if the pokemon is in the party, and if so, to get the party index in order to update the icon image
if (isInParty) {
this.updatePartyIcon(species, partyIndex);
@ -3886,7 +3885,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
this.canCycleTera =
!this.statsMode &&
globalScene.gameData.achvUnlocks.hasOwnProperty(achvs.TERASTALLIZE.id) &&
!Utils.isNullOrUndefined(getPokemonSpeciesForm(species.speciesId, formIndex ?? 0).type2);
!isNullOrUndefined(getPokemonSpeciesForm(species.speciesId, formIndex ?? 0).type2);
}
if (dexEntry.caughtAttr && species.malePercent !== null) {
@ -4483,7 +4482,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
this.canCycleTera =
!this.statsMode &&
globalScene.gameData.achvUnlocks.hasOwnProperty(achvs.TERASTALLIZE.id) &&
!Utils.isNullOrUndefined(getPokemonSpeciesForm(this.lastSpecies.speciesId, formIndex ?? 0).type2);
!isNullOrUndefined(getPokemonSpeciesForm(this.lastSpecies.speciesId, formIndex ?? 0).type2);
this.updateInstructions();
}
}

View File

@ -2,7 +2,16 @@ import { starterColors } from "#app/battle-scene";
import { globalScene } from "#app/global-scene";
import { Mode } from "#app/ui/ui";
import UiHandler from "#app/ui/ui-handler";
import * as Utils from "#app/utils";
import {
getLocalizedSpriteKey,
rgbHexToRgba,
padInt,
getEnumValues,
fixedInt,
isNullOrUndefined,
toReadableString,
formatStat,
} from "#app/utils";
import type { PlayerPokemon, PokemonMove } from "#app/field/pokemon";
import { getStarterValueFriendshipCap, speciesStarterCosts } from "#app/data/balance/starters";
import { argbFromRgba } from "@material/material-color-utilities";
@ -255,7 +264,7 @@ export default class SummaryUiHandler extends UiHandler {
this.statusContainer.add(statusLabel);
this.status = globalScene.add.sprite(91, 4, Utils.getLocalizedSpriteKey("statuses"));
this.status = globalScene.add.sprite(91, 4, getLocalizedSpriteKey("statuses"));
this.status.setOrigin(0.5, 0);
this.statusContainer.add(this.status);
@ -330,10 +339,10 @@ export default class SummaryUiHandler extends UiHandler {
this.shinyOverlay.setVisible(this.pokemon.isShiny());
const colorScheme = starterColors[this.pokemon.species.getRootSpeciesId()];
this.candyIcon.setTint(argbFromRgba(Utils.rgbHexToRgba(colorScheme[0])));
this.candyOverlay.setTint(argbFromRgba(Utils.rgbHexToRgba(colorScheme[1])));
this.candyIcon.setTint(argbFromRgba(rgbHexToRgba(colorScheme[0])));
this.candyOverlay.setTint(argbFromRgba(rgbHexToRgba(colorScheme[1])));
this.numberText.setText(Utils.padInt(this.pokemon.species.speciesId, 4));
this.numberText.setText(padInt(this.pokemon.species.speciesId, 4));
this.numberText.setColor(this.getTextColor(!this.pokemon.isShiny() ? TextStyle.SUMMARY : TextStyle.SUMMARY_GOLD));
this.numberText.setShadowColor(
this.getTextColor(!this.pokemon.isShiny() ? TextStyle.SUMMARY : TextStyle.SUMMARY_GOLD, true),
@ -600,7 +609,7 @@ export default class SummaryUiHandler extends UiHandler {
}
success = true;
} else {
const pages = Utils.getEnumValues(Page);
const pages = getEnumValues(Page);
switch (button) {
case Button.UP:
case Button.DOWN: {
@ -675,10 +684,10 @@ export default class SummaryUiHandler extends UiHandler {
if (moveDescriptionLineCount > 3) {
this.descriptionScrollTween = globalScene.tweens.add({
targets: this.moveDescriptionText,
delay: Utils.fixedInt(2000),
delay: fixedInt(2000),
loop: -1,
hold: Utils.fixedInt(2000),
duration: Utils.fixedInt((moveDescriptionLineCount - 3) * 2000),
hold: fixedInt(2000),
duration: fixedInt((moveDescriptionLineCount - 3) * 2000),
y: `-=${14.83 * (moveDescriptionLineCount - 3)}`,
});
}
@ -697,10 +706,10 @@ export default class SummaryUiHandler extends UiHandler {
this.moveCursorObj.setVisible(true);
this.moveCursorBlinkTimer = globalScene.time.addEvent({
loop: true,
delay: Utils.fixedInt(600),
delay: fixedInt(600),
callback: () => {
this.moveCursorObj?.setVisible(false);
globalScene.time.delayedCall(Utils.fixedInt(100), () => {
globalScene.time.delayedCall(fixedInt(100), () => {
if (!this.moveCursorObj) {
return;
}
@ -818,7 +827,7 @@ export default class SummaryUiHandler extends UiHandler {
const getTypeIcon = (index: number, type: PokemonType, tera = false) => {
const xCoord = typeLabel.width * typeLabel.scale + 9 + 34 * index;
const typeIcon = !tera
? globalScene.add.sprite(xCoord, 42, Utils.getLocalizedSpriteKey("types"), PokemonType[type].toLowerCase())
? globalScene.add.sprite(xCoord, 42, getLocalizedSpriteKey("types"), PokemonType[type].toLowerCase())
: globalScene.add.sprite(xCoord, 42, "type_tera");
if (tera) {
typeIcon.setScale(0.5);
@ -853,7 +862,7 @@ export default class SummaryUiHandler extends UiHandler {
if (
globalScene.gameData.achvUnlocks.hasOwnProperty(achvs.TERASTALLIZE.id) &&
!Utils.isNullOrUndefined(this.pokemon)
!isNullOrUndefined(this.pokemon)
) {
const teraIcon = globalScene.add.sprite(123, 26, "button_tera");
teraIcon.setName("terrastallize-icon");
@ -925,10 +934,10 @@ export default class SummaryUiHandler extends UiHandler {
abilityInfo.descriptionText.setY(69);
this.descriptionScrollTween = globalScene.tweens.add({
targets: abilityInfo.descriptionText,
delay: Utils.fixedInt(2000),
delay: fixedInt(2000),
loop: -1,
hold: Utils.fixedInt(2000),
duration: Utils.fixedInt((abilityDescriptionLineCount - 2) * 2000),
hold: fixedInt(2000),
duration: fixedInt((abilityDescriptionLineCount - 2) * 2000),
y: `-=${14.83 * (abilityDescriptionLineCount - 2)}`,
});
}
@ -939,8 +948,8 @@ export default class SummaryUiHandler extends UiHandler {
this.passiveContainer?.descriptionText?.setVisible(false);
const closeFragment = getBBCodeFrag("", TextStyle.WINDOW_ALT);
const rawNature = Utils.toReadableString(Nature[this.pokemon?.getNature()!]); // TODO: is this bang correct?
const nature = `${getBBCodeFrag(Utils.toReadableString(getNatureName(this.pokemon?.getNature()!)), TextStyle.SUMMARY_RED)}${closeFragment}`; // TODO: is this bang correct?
const rawNature = toReadableString(Nature[this.pokemon?.getNature()!]); // TODO: is this bang correct?
const nature = `${getBBCodeFrag(toReadableString(getNatureName(this.pokemon?.getNature()!)), TextStyle.SUMMARY_RED)}${closeFragment}`; // TODO: is this bang correct?
const memoString = i18next.t("pokemonSummary:memoString", {
metFragment: i18next.t(
@ -999,8 +1008,8 @@ export default class SummaryUiHandler extends UiHandler {
const statValueText =
stat !== Stat.HP
? Utils.formatStat(this.pokemon?.getStat(stat)!) // TODO: is this bang correct?
: `${Utils.formatStat(this.pokemon?.hp!, true)}/${Utils.formatStat(this.pokemon?.getMaxHp()!, true)}`; // TODO: are those bangs correct?
? formatStat(this.pokemon?.getStat(stat)!) // TODO: is this bang correct?
: `${formatStat(this.pokemon?.hp!, true)}/${formatStat(this.pokemon?.getMaxHp()!, true)}`; // TODO: are those bangs correct?
const ivText = `${this.pokemon?.ivs[stat]}/31`;
const statValue = addTextObject(93 + 88 * colIndex, 16 * rowIndex, statValueText, TextStyle.WINDOW_ALT);
@ -1106,7 +1115,7 @@ export default class SummaryUiHandler extends UiHandler {
this.extraMoveRowContainer.setVisible(true);
if (this.newMove && this.pokemon) {
const spriteKey = Utils.getLocalizedSpriteKey("types");
const spriteKey = getLocalizedSpriteKey("types");
const moveType = this.pokemon.getMoveType(this.newMove);
const newMoveTypeIcon = globalScene.add.sprite(0, 0, spriteKey, PokemonType[moveType].toLowerCase());
newMoveTypeIcon.setOrigin(0, 1);
@ -1116,7 +1125,7 @@ export default class SummaryUiHandler extends UiHandler {
ppOverlay.setOrigin(0, 1);
this.extraMoveRowContainer.add(ppOverlay);
const pp = Utils.padInt(this.newMove?.pp!, 2, " "); // TODO: is this bang correct?
const pp = padInt(this.newMove?.pp!, 2, " "); // TODO: is this bang correct?
const ppText = addTextObject(173, 1, `${pp}/${pp}`, TextStyle.WINDOW);
ppText.setOrigin(0, 1);
this.extraMoveRowContainer.add(ppText);
@ -1132,7 +1141,7 @@ export default class SummaryUiHandler extends UiHandler {
this.moveRowsContainer.add(moveRowContainer);
if (move && this.pokemon) {
const spriteKey = Utils.getLocalizedSpriteKey("types");
const spriteKey = getLocalizedSpriteKey("types");
const moveType = this.pokemon.getMoveType(move.getMove());
const typeIcon = globalScene.add.sprite(0, 0, spriteKey, PokemonType[moveType].toLowerCase());
typeIcon.setOrigin(0, 1);
@ -1153,7 +1162,7 @@ export default class SummaryUiHandler extends UiHandler {
if (move) {
const maxPP = move.getMovePp();
const pp = maxPP - move.ppUsed;
ppText.setText(`${Utils.padInt(pp, 2, " ")}/${Utils.padInt(maxPP, 2, " ")}`);
ppText.setText(`${padInt(pp, 2, " ")}/${padInt(maxPP, 2, " ")}`);
}
moveRowContainer.add(ppText);

View File

@ -1,7 +1,7 @@
import { BattlerIndex } from "../battle";
import { Mode } from "./ui";
import UiHandler from "./ui-handler";
import * as Utils from "../utils";
import { isNullOrUndefined, fixedInt } from "#app/utils";
import { getMoveTargets } from "../data/moves/move";
import { Button } from "#enums/buttons";
import type { Moves } from "#enums/moves";
@ -70,7 +70,7 @@ export default class TargetSelectUiHandler extends UiHandler {
* @param user the Pokemon using the move
*/
resetCursor(cursorN: number, user: Pokemon): void {
if (!Utils.isNullOrUndefined(cursorN)) {
if (!isNullOrUndefined(cursorN)) {
if ([BattlerIndex.PLAYER, BattlerIndex.PLAYER_2].includes(cursorN) || user.battleSummonData.waveTurnCount === 1) {
// Reset cursor on the first turn of a fight or if an ally was targeted last turn
cursorN = -1;
@ -89,11 +89,11 @@ export default class TargetSelectUiHandler extends UiHandler {
this.targetSelectCallback(button === Button.ACTION ? targetIndexes : []);
success = true;
if (this.fieldIndex === BattlerIndex.PLAYER) {
if (Utils.isNullOrUndefined(this.cursor0) || this.cursor0 !== this.cursor) {
if (isNullOrUndefined(this.cursor0) || this.cursor0 !== this.cursor) {
this.cursor0 = this.cursor;
}
} else if (this.fieldIndex === BattlerIndex.PLAYER_2) {
if (Utils.isNullOrUndefined(this.cursor1) || this.cursor1 !== this.cursor) {
if (isNullOrUndefined(this.cursor1) || this.cursor1 !== this.cursor) {
this.cursor1 = this.cursor;
}
}
@ -152,7 +152,7 @@ export default class TargetSelectUiHandler extends UiHandler {
key: { start: 1, to: 0.25 },
loop: -1,
loopDelay: 150,
duration: Utils.fixedInt(450),
duration: fixedInt(450),
ease: "Sine.easeInOut",
yoyo: true,
onUpdate: t => {
@ -178,7 +178,7 @@ export default class TargetSelectUiHandler extends UiHandler {
targets: [info],
y: { start: info.getBaseY(), to: info.getBaseY() + 1 },
loop: -1,
duration: Utils.fixedInt(250),
duration: fixedInt(250),
ease: "Linear",
yoyo: true,
}),

View File

@ -1,4 +1,4 @@
import * as Utils from "../utils";
import { fixedInt } from "#app/utils";
import { globalScene } from "#app/global-scene";
import { BattleSceneEventType } from "../events/battle-scene";
import { EaseType } from "#enums/ease-type";
@ -75,14 +75,14 @@ export default class TimeOfDayWidget extends Phaser.GameObjects.Container {
const rotate = {
targets: [this.timeOfDayIconMgs[0], this.timeOfDayIconMgs[1]],
angle: "+=90",
duration: Utils.fixedInt(1500),
duration: fixedInt(1500),
ease: "Back.easeOut",
paused: !this.parentVisible,
};
const fade = {
targets: [this.timeOfDayIconBgs[1], this.timeOfDayIconMgs[1], this.timeOfDayIconFgs[1]],
alpha: 0,
duration: Utils.fixedInt(500),
duration: fixedInt(500),
ease: "Linear",
paused: !this.parentVisible,
};
@ -98,14 +98,14 @@ export default class TimeOfDayWidget extends Phaser.GameObjects.Container {
const bounce = {
targets: [this.timeOfDayIconMgs[0], this.timeOfDayIconMgs[1]],
angle: "+=90",
duration: Utils.fixedInt(2000),
duration: fixedInt(2000),
ease: "Bounce.easeOut",
paused: !this.parentVisible,
};
const fade = {
targets: [this.timeOfDayIconBgs[1], this.timeOfDayIconMgs[1], this.timeOfDayIconFgs[1]],
alpha: 0,
duration: Utils.fixedInt(800),
duration: fixedInt(800),
ease: "Linear",
paused: !this.parentVisible,
};

View File

@ -1,6 +1,6 @@
import OptionSelectUiHandler from "./settings/option-select-ui-handler";
import { Mode } from "./ui";
import * as Utils from "../utils";
import { fixedInt, randInt, randItem } from "#app/utils";
import { TextStyle, addTextObject } from "./text";
import { getSplashMessages } from "../data/splash-messages";
import i18next from "i18next";
@ -72,7 +72,7 @@ export default class TitleUiHandler extends OptionSelectUiHandler {
globalScene.tweens.add({
targets: this.splashMessageText,
duration: Utils.fixedInt(350),
duration: fixedInt(350),
scale: originalSplashMessageScale * 1.25,
loop: -1,
yoyo: true,
@ -104,7 +104,7 @@ export default class TitleUiHandler extends OptionSelectUiHandler {
/** Used solely to display a random Pokémon name in a splash message. */
randomPokemon(): void {
const rand = Utils.randInt(1025, 1);
const rand = randInt(1025, 1);
const pokemon = getPokemonSpecies(rand as Species);
if (
this.splashMessage === "splashMessages:underratedPokemon" ||
@ -132,7 +132,7 @@ export default class TitleUiHandler extends OptionSelectUiHandler {
// Moving player count to top of the menu
this.playerCountLabel.setY(globalScene.game.canvas.height / 6 - 13 - this.getWindowHeight());
this.splashMessage = Utils.randItem(getSplashMessages());
this.splashMessage = randItem(getSplashMessages());
this.splashMessageText.setText(
i18next.t(this.splashMessage, {
count: TitleUiHandler.BATTLES_WON_FALLBACK,
@ -159,7 +159,7 @@ export default class TitleUiHandler extends OptionSelectUiHandler {
globalScene.tweens.add({
targets: [this.titleContainer, ui.getMessageHandler().bg],
duration: Utils.fixedInt(325),
duration: fixedInt(325),
alpha: (target: any) => (target === this.titleContainer ? 1 : 0),
ease: "Sine.easeInOut",
});
@ -180,7 +180,7 @@ export default class TitleUiHandler extends OptionSelectUiHandler {
globalScene.tweens.add({
targets: [this.titleContainer, ui.getMessageHandler().bg],
duration: Utils.fixedInt(325),
duration: fixedInt(325),
alpha: (target: any) => (target === this.titleContainer ? 0 : 1),
ease: "Sine.easeInOut",
});

View File

@ -28,7 +28,7 @@ import { addWindow } from "./ui-theme";
import LoginFormUiHandler from "./login-form-ui-handler";
import RegistrationFormUiHandler from "./registration-form-ui-handler";
import LoadingModalUiHandler from "./loading-modal-ui-handler";
import * as Utils from "../utils";
import { executeIf } from "#app/utils";
import GameStatsUiHandler from "./game-stats-ui-handler";
import AwaitableUiHandler from "./awaitable-ui-handler";
import SaveSlotSelectUiHandler from "./save-slot-select-ui-handler";
@ -674,7 +674,7 @@ export default class UI extends Phaser.GameObjects.Container {
if (!this?.modeChain?.length) {
return resolve();
}
this.revertMode().then(success => Utils.executeIf(success, this.revertModes).then(() => resolve()));
this.revertMode().then(success => executeIf(success, this.revertModes).then(() => resolve()));
});
}

View File

@ -3,7 +3,7 @@ import { ModalUiHandler } from "./modal-ui-handler";
import { addTextObject, TextStyle } from "./text";
import type { Mode } from "./ui";
import { updateUserInfo } from "#app/account";
import * as Utils from "#app/utils";
import { removeCookie, sessionIdKey } from "#app/utils";
import i18next from "i18next";
import { globalScene } from "#app/global-scene";
@ -65,7 +65,7 @@ export default class UnavailableModalUiHandler extends ModalUiHandler {
globalScene.playSound("se/pb_bounce_1");
this.reconnectCallback();
} else if (response[1] === 401) {
Utils.removeCookie(Utils.sessionIdKey);
removeCookie(sessionIdKey);
globalScene.reset(true, true);
} else {
this.reconnectDuration = Math.min(this.reconnectDuration * 2, this.maxTime); // Set a max delay so it isn't infinite

View File

@ -1,7 +1,7 @@
import { AttemptRunPhase } from "#app/phases/attempt-run-phase";
import type { CommandPhase } from "#app/phases/command-phase";
import { Command } from "#app/ui/command-ui-handler";
import * as Utils from "#app/utils";
import { NumberHolder } from "#app/utils";
import { Abilities } from "#enums/abilities";
import { Species } from "#enums/species";
import GameManager from "#test/testUtils/gameManager";
@ -45,7 +45,7 @@ describe("Escape chance calculations", () => {
await game.phaseInterceptor.to(AttemptRunPhase, false);
const phase = game.scene.getCurrentPhase() as AttemptRunPhase;
const escapePercentage = new Utils.NumberHolder(0);
const escapePercentage = new NumberHolder(0);
// this sets up an object for multiple attempts. The pokemonSpeedRatio is your speed divided by the enemy speed, the escapeAttempts are the number of escape attempts and the expectedEscapeChance is the chance it should be escaping
const escapeChances: {
@ -118,7 +118,7 @@ describe("Escape chance calculations", () => {
await game.phaseInterceptor.to(AttemptRunPhase, false);
const phase = game.scene.getCurrentPhase() as AttemptRunPhase;
const escapePercentage = new Utils.NumberHolder(0);
const escapePercentage = new NumberHolder(0);
// this sets up an object for multiple attempts. The pokemonSpeedRatio is your speed divided by the enemy speed, the escapeAttempts are the number of escape attempts and the expectedEscapeChance is the chance it should be escaping
const escapeChances: {
@ -197,7 +197,7 @@ describe("Escape chance calculations", () => {
await game.phaseInterceptor.to(AttemptRunPhase, false);
const phase = game.scene.getCurrentPhase() as AttemptRunPhase;
const escapePercentage = new Utils.NumberHolder(0);
const escapePercentage = new NumberHolder(0);
// this sets up an object for multiple attempts. The pokemonSpeedRatio is your speed divided by the enemy speed, the escapeAttempts are the number of escape attempts and the expectedEscapeChance is the chance it should be escaping
const escapeChances: {
@ -284,7 +284,7 @@ describe("Escape chance calculations", () => {
await game.phaseInterceptor.to(AttemptRunPhase, false);
const phase = game.scene.getCurrentPhase() as AttemptRunPhase;
const escapePercentage = new Utils.NumberHolder(0);
const escapePercentage = new NumberHolder(0);
// this sets up an object for multiple attempts. The pokemonSpeedRatio is your speed divided by the enemy speed, the escapeAttempts are the number of escape attempts and the expectedEscapeChance is the chance it should be escaping
const escapeChances: {

View File

@ -1,6 +1,6 @@
import { Abilities } from "#app/enums/abilities";
import { PokemonExpBoosterModifier } from "#app/modifier/modifier";
import * as Utils from "#app/utils";
import { NumberHolder } from "#app/utils";
import GameManager from "#test/testUtils/gameManager";
import Phase from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
@ -33,7 +33,7 @@ describe("EXP Modifier Items", () => {
const partyMember = game.scene.getPlayerPokemon()!;
partyMember.exp = 100;
const expHolder = new Utils.NumberHolder(partyMember.exp);
const expHolder = new NumberHolder(partyMember.exp);
game.scene.applyModifiers(PokemonExpBoosterModifier, true, partyMember, expHolder);
expect(expHolder.value).toBe(440);
}, 20000);

View File

@ -1,5 +1,5 @@
import { TurnEndPhase } from "#app/phases/turn-end-phase";
import * as Utils from "#app/utils";
import { randInt } from "#app/utils";
import { Moves } from "#enums/moves";
import { Species } from "#enums/species";
import GameManager from "#test/testUtils/gameManager";
@ -78,7 +78,7 @@ describe("Items - Leek", () => {
// Randomly choose from the Farfetch'd line
const species = [Species.FARFETCHD, Species.GALAR_FARFETCHD, Species.SIRFETCHD];
await game.startBattle([species[Utils.randInt(species.length)], Species.PIKACHU]);
await game.startBattle([species[randInt(species.length)], Species.PIKACHU]);
const [partyMember, ally] = game.scene.getPlayerParty();
@ -106,7 +106,7 @@ describe("Items - Leek", () => {
// Randomly choose from the Farfetch'd line
const species = [Species.FARFETCHD, Species.GALAR_FARFETCHD, Species.SIRFETCHD];
await game.startBattle([Species.PIKACHU, species[Utils.randInt(species.length)]]);
await game.startBattle([Species.PIKACHU, species[randInt(species.length)]]);
const [partyMember, ally] = game.scene.getPlayerParty();

View File

@ -2,7 +2,7 @@ import { Stat } from "#enums/stat";
import { SpeciesStatBoosterModifier } from "#app/modifier/modifier";
import { modifierTypes } from "#app/modifier/modifier-type";
import i18next from "#app/plugins/i18n";
import * as Utils from "#app/utils";
import { NumberHolder } from "#app/utils";
import { Species } from "#enums/species";
import GameManager from "#test/testUtils/gameManager";
import Phase from "phaser";
@ -90,9 +90,9 @@ describe("Items - Light Ball", () => {
const spAtkStat = partyMember.getStat(Stat.SPATK);
// Making sure modifier is not applied without holding item
const atkValue = new Utils.NumberHolder(atkStat);
const atkValue = new NumberHolder(atkStat);
game.scene.applyModifiers(SpeciesStatBoosterModifier, true, partyMember, Stat.DEF, atkValue);
const spAtkValue = new Utils.NumberHolder(spAtkStat);
const spAtkValue = new NumberHolder(spAtkStat);
game.scene.applyModifiers(SpeciesStatBoosterModifier, true, partyMember, Stat.SPDEF, spAtkValue);
expect(atkValue.value / atkStat).toBe(1);
@ -129,9 +129,9 @@ describe("Items - Light Ball", () => {
const spAtkStat = partyMember.getStat(Stat.SPATK);
// Making sure modifier is not applied without holding item
const atkValue = new Utils.NumberHolder(atkStat);
const atkValue = new NumberHolder(atkStat);
game.scene.applyModifiers(SpeciesStatBoosterModifier, true, partyMember, Stat.DEF, atkValue);
const spAtkValue = new Utils.NumberHolder(spAtkStat);
const spAtkValue = new NumberHolder(spAtkStat);
game.scene.applyModifiers(SpeciesStatBoosterModifier, true, partyMember, Stat.SPDEF, spAtkValue);
expect(atkValue.value / atkStat).toBe(1);
@ -168,9 +168,9 @@ describe("Items - Light Ball", () => {
const spAtkStat = partyMember.getStat(Stat.SPATK);
// Making sure modifier is not applied without holding item
const atkValue = new Utils.NumberHolder(atkStat);
const atkValue = new NumberHolder(atkStat);
game.scene.applyModifiers(SpeciesStatBoosterModifier, true, partyMember, Stat.DEF, atkValue);
const spAtkValue = new Utils.NumberHolder(spAtkStat);
const spAtkValue = new NumberHolder(spAtkStat);
game.scene.applyModifiers(SpeciesStatBoosterModifier, true, partyMember, Stat.SPDEF, spAtkValue);
expect(atkValue.value / atkStat).toBe(1);
@ -197,9 +197,9 @@ describe("Items - Light Ball", () => {
const spAtkStat = partyMember.getStat(Stat.SPATK);
// Making sure modifier is not applied without holding item
const atkValue = new Utils.NumberHolder(atkStat);
const atkValue = new NumberHolder(atkStat);
game.scene.applyModifiers(SpeciesStatBoosterModifier, true, partyMember, Stat.DEF, atkValue);
const spAtkValue = new Utils.NumberHolder(spAtkStat);
const spAtkValue = new NumberHolder(spAtkStat);
game.scene.applyModifiers(SpeciesStatBoosterModifier, true, partyMember, Stat.SPDEF, spAtkValue);
expect(atkValue.value / atkStat).toBe(1);

View File

@ -2,7 +2,7 @@ import { Stat } from "#enums/stat";
import { SpeciesStatBoosterModifier } from "#app/modifier/modifier";
import { modifierTypes } from "#app/modifier/modifier-type";
import i18next from "#app/plugins/i18n";
import * as Utils from "#app/utils";
import { NumberHolder } from "#app/utils";
import { Species } from "#enums/species";
import GameManager from "#test/testUtils/gameManager";
import Phase from "phaser";
@ -89,7 +89,7 @@ describe("Items - Metal Powder", () => {
const defStat = partyMember.getStat(Stat.DEF);
// Making sure modifier is not applied without holding item
const defValue = new Utils.NumberHolder(defStat);
const defValue = new NumberHolder(defStat);
game.scene.applyModifiers(SpeciesStatBoosterModifier, true, partyMember, Stat.DEF, defValue);
expect(defValue.value / defStat).toBe(1);
@ -122,7 +122,7 @@ describe("Items - Metal Powder", () => {
const defStat = partyMember.getStat(Stat.DEF);
// Making sure modifier is not applied without holding item
const defValue = new Utils.NumberHolder(defStat);
const defValue = new NumberHolder(defStat);
game.scene.applyModifiers(SpeciesStatBoosterModifier, true, partyMember, Stat.DEF, defValue);
expect(defValue.value / defStat).toBe(1);
@ -155,7 +155,7 @@ describe("Items - Metal Powder", () => {
const defStat = partyMember.getStat(Stat.DEF);
// Making sure modifier is not applied without holding item
const defValue = new Utils.NumberHolder(defStat);
const defValue = new NumberHolder(defStat);
game.scene.applyModifiers(SpeciesStatBoosterModifier, true, partyMember, Stat.DEF, defValue);
expect(defValue.value / defStat).toBe(1);
@ -178,7 +178,7 @@ describe("Items - Metal Powder", () => {
const defStat = partyMember.getStat(Stat.DEF);
// Making sure modifier is not applied without holding item
const defValue = new Utils.NumberHolder(defStat);
const defValue = new NumberHolder(defStat);
game.scene.applyModifiers(SpeciesStatBoosterModifier, true, partyMember, Stat.DEF, defValue);
expect(defValue.value / defStat).toBe(1);

View File

@ -2,7 +2,7 @@ import { Stat } from "#enums/stat";
import { SpeciesStatBoosterModifier } from "#app/modifier/modifier";
import { modifierTypes } from "#app/modifier/modifier-type";
import i18next from "#app/plugins/i18n";
import * as Utils from "#app/utils";
import { NumberHolder } from "#app/utils";
import { Species } from "#enums/species";
import GameManager from "#test/testUtils/gameManager";
import Phase from "phaser";
@ -89,7 +89,7 @@ describe("Items - Quick Powder", () => {
const spdStat = partyMember.getStat(Stat.SPD);
// Making sure modifier is not applied without holding item
const spdValue = new Utils.NumberHolder(spdStat);
const spdValue = new NumberHolder(spdStat);
game.scene.applyModifiers(SpeciesStatBoosterModifier, true, partyMember, Stat.SPD, spdValue);
expect(spdValue.value / spdStat).toBe(1);
@ -122,7 +122,7 @@ describe("Items - Quick Powder", () => {
const spdStat = partyMember.getStat(Stat.SPD);
// Making sure modifier is not applied without holding item
const spdValue = new Utils.NumberHolder(spdStat);
const spdValue = new NumberHolder(spdStat);
game.scene.applyModifiers(SpeciesStatBoosterModifier, true, partyMember, Stat.SPD, spdValue);
expect(spdValue.value / spdStat).toBe(1);
@ -155,7 +155,7 @@ describe("Items - Quick Powder", () => {
const spdStat = partyMember.getStat(Stat.SPD);
// Making sure modifier is not applied without holding item
const spdValue = new Utils.NumberHolder(spdStat);
const spdValue = new NumberHolder(spdStat);
game.scene.applyModifiers(SpeciesStatBoosterModifier, true, partyMember, Stat.SPD, spdValue);
expect(spdValue.value / spdStat).toBe(1);
@ -178,7 +178,7 @@ describe("Items - Quick Powder", () => {
const spdStat = partyMember.getStat(Stat.SPD);
// Making sure modifier is not applied without holding item
const spdValue = new Utils.NumberHolder(spdStat);
const spdValue = new NumberHolder(spdStat);
game.scene.applyModifiers(SpeciesStatBoosterModifier, true, partyMember, Stat.SPD, spdValue);
expect(spdValue.value / spdStat).toBe(1);

View File

@ -2,7 +2,7 @@ import { Stat } from "#enums/stat";
import { SpeciesStatBoosterModifier } from "#app/modifier/modifier";
import { modifierTypes } from "#app/modifier/modifier-type";
import i18next from "#app/plugins/i18n";
import * as Utils from "#app/utils";
import { NumberHolder, randInt } from "#app/utils";
import { Species } from "#enums/species";
import GameManager from "#test/testUtils/gameManager";
import Phase from "phaser";
@ -89,7 +89,7 @@ describe("Items - Thick Club", () => {
const atkStat = partyMember.getStat(Stat.ATK);
// Making sure modifier is not applied without holding item
const atkValue = new Utils.NumberHolder(atkStat);
const atkValue = new NumberHolder(atkStat);
game.scene.applyModifiers(SpeciesStatBoosterModifier, true, partyMember, Stat.ATK, atkValue);
expect(atkValue.value / atkStat).toBe(1);
@ -112,7 +112,7 @@ describe("Items - Thick Club", () => {
const atkStat = partyMember.getStat(Stat.ATK);
// Making sure modifier is not applied without holding item
const atkValue = new Utils.NumberHolder(atkStat);
const atkValue = new NumberHolder(atkStat);
game.scene.applyModifiers(SpeciesStatBoosterModifier, true, partyMember, Stat.ATK, atkValue);
expect(atkValue.value / atkStat).toBe(1);
@ -135,7 +135,7 @@ describe("Items - Thick Club", () => {
const atkStat = partyMember.getStat(Stat.ATK);
// Making sure modifier is not applied without holding item
const atkValue = new Utils.NumberHolder(atkStat);
const atkValue = new NumberHolder(atkStat);
game.scene.applyModifiers(SpeciesStatBoosterModifier, true, partyMember, Stat.ATK, atkValue);
expect(atkValue.value / atkStat).toBe(1);
@ -153,7 +153,7 @@ describe("Items - Thick Club", () => {
it("THICK_CLUB held by fused CUBONE line (base)", async () => {
// Randomly choose from the Cubone line
const species = [Species.CUBONE, Species.MAROWAK, Species.ALOLA_MAROWAK];
const randSpecies = Utils.randInt(species.length);
const randSpecies = randInt(species.length);
await game.classicMode.startBattle([species[randSpecies], Species.PIKACHU]);
@ -172,7 +172,7 @@ describe("Items - Thick Club", () => {
const atkStat = partyMember.getStat(Stat.ATK);
// Making sure modifier is not applied without holding item
const atkValue = new Utils.NumberHolder(atkStat);
const atkValue = new NumberHolder(atkStat);
game.scene.applyModifiers(SpeciesStatBoosterModifier, true, partyMember, Stat.ATK, atkValue);
expect(atkValue.value / atkStat).toBe(1);
@ -190,7 +190,7 @@ describe("Items - Thick Club", () => {
it("THICK_CLUB held by fused CUBONE line (part)", async () => {
// Randomly choose from the Cubone line
const species = [Species.CUBONE, Species.MAROWAK, Species.ALOLA_MAROWAK];
const randSpecies = Utils.randInt(species.length);
const randSpecies = randInt(species.length);
await game.classicMode.startBattle([Species.PIKACHU, species[randSpecies]]);
@ -209,7 +209,7 @@ describe("Items - Thick Club", () => {
const atkStat = partyMember.getStat(Stat.ATK);
// Making sure modifier is not applied without holding item
const atkValue = new Utils.NumberHolder(atkStat);
const atkValue = new NumberHolder(atkStat);
game.scene.applyModifiers(SpeciesStatBoosterModifier, true, partyMember, Stat.ATK, atkValue);
expect(atkValue.value / atkStat).toBe(1);
@ -232,7 +232,7 @@ describe("Items - Thick Club", () => {
const atkStat = partyMember.getStat(Stat.ATK);
// Making sure modifier is not applied without holding item
const atkValue = new Utils.NumberHolder(atkStat);
const atkValue = new NumberHolder(atkStat);
game.scene.applyModifiers(SpeciesStatBoosterModifier, true, partyMember, Stat.ATK, atkValue);
expect(atkValue.value / atkStat).toBe(1);

View File

@ -1,7 +1,7 @@
import { BattlerIndex } from "#app/battle";
import { Abilities } from "#app/enums/abilities";
import { Species } from "#app/enums/species";
import * as Utils from "#app/utils";
import { toDmgValue } from "#app/utils";
import { Moves } from "#enums/moves";
import GameManager from "#test/testUtils/gameManager";
import Phaser from "phaser";
@ -71,8 +71,8 @@ describe("Multi-target damage reduction", () => {
// Single target moves don't get reduced
expect(tackle1).toBe(tackle2);
// Moves that target all enemies get reduced if there's more than one enemy
expect(gleam1).toBeLessThanOrEqual(Utils.toDmgValue(gleam2 * 0.75) + 1);
expect(gleam1).toBeGreaterThanOrEqual(Utils.toDmgValue(gleam2 * 0.75) - 1);
expect(gleam1).toBeLessThanOrEqual(toDmgValue(gleam2 * 0.75) + 1);
expect(gleam1).toBeGreaterThanOrEqual(toDmgValue(gleam2 * 0.75) - 1);
});
it("should reduce earthquake when more than one pokemon other than user is not fainted", async () => {
@ -122,7 +122,7 @@ describe("Multi-target damage reduction", () => {
const damageEnemy1Turn3 = enemy1.getMaxHp() - enemy1.hp;
// Turn 3: 1 target, should be no damage reduction
expect(damageEnemy1Turn1).toBeLessThanOrEqual(Utils.toDmgValue(damageEnemy1Turn3 * 0.75) + 1);
expect(damageEnemy1Turn1).toBeGreaterThanOrEqual(Utils.toDmgValue(damageEnemy1Turn3 * 0.75) - 1);
expect(damageEnemy1Turn1).toBeLessThanOrEqual(toDmgValue(damageEnemy1Turn3 * 0.75) + 1);
expect(damageEnemy1Turn1).toBeGreaterThanOrEqual(toDmgValue(damageEnemy1Turn3 * 0.75) - 1);
});
});

View File

@ -1,3 +1,4 @@
// biome-ignore lint/style/noNamespaceImport: Necessary for mocks
import * as EncounterPhaseUtils from "#app/data/mystery-encounters/utils/encounter-phase-utils";
import { Status } from "#app/data/status-effect";
import { CommandPhase } from "#app/phases/command-phase";

View File

@ -2,7 +2,7 @@
import BattleScene, * as battleScene from "#app/battle-scene";
import { MoveAnim } from "#app/data/battle-anims";
import Pokemon from "#app/field/pokemon";
import * as Utils from "#app/utils";
import { setCookie, sessionIdKey } from "#app/utils";
import { blobToString } from "#test/testUtils/gameManagerUtils";
import { MockClock } from "#test/testUtils/mocks/mockClock";
import { MockFetch } from "#test/testUtils/mocks/mockFetch";
@ -29,7 +29,7 @@ window.URL.createObjectURL = (blob: Blob) => {
};
navigator.getGamepads = () => [];
global.fetch = vi.fn(MockFetch);
Utils.setCookie(Utils.sessionIdKey, "fake_token");
setCookie(sessionIdKey, "fake_token");
window.matchMedia = () => ({
matches: false,