Applied linter fixes

This commit is contained in:
Bertie690 2025-08-14 00:06:36 -04:00
parent 5d267d045e
commit 618a4b5fc3
59 changed files with 760 additions and 850 deletions

View File

@ -1463,7 +1463,6 @@ export class PostDefendAbilityGiveAbAttr extends PostDefendAbAttr {
export class PostDefendMoveDisableAbAttr extends PostDefendAbAttr { export class PostDefendMoveDisableAbAttr extends PostDefendAbAttr {
private chance: number; private chance: number;
private attacker: Pokemon; private attacker: Pokemon;
private move: Move;
constructor(chance: number) { constructor(chance: number) {
super(); super();
@ -1479,11 +1478,9 @@ export class PostDefendMoveDisableAbAttr extends PostDefendAbAttr {
); );
} }
override apply({ simulated, opponent: attacker, move, pokemon }: PostMoveInteractionAbAttrParams): void { override apply({ simulated, opponent: attacker, pokemon }: PostMoveInteractionAbAttrParams): void {
// TODO: investigate why this is setting properties
if (!simulated) { if (!simulated) {
this.attacker = attacker; this.attacker = attacker;
this.move = move;
this.attacker.addTag(BattlerTagType.DISABLED, 4, 0, pokemon.id); this.attacker.addTag(BattlerTagType.DISABLED, 4, 0, pokemon.id);
} }
} }
@ -6345,11 +6342,14 @@ class ForceSwitchOutHelper {
return !blockedByAbility.value; return !blockedByAbility.value;
} }
if (!player && globalScene.currentBattle.battleType === BattleType.WILD) { if (
if (!globalScene.currentBattle.waveIndex && globalScene.currentBattle.waveIndex % 10 === 0) { !player &&
globalScene.currentBattle.battleType === BattleType.WILD &&
!globalScene.currentBattle.waveIndex &&
globalScene.currentBattle.waveIndex % 10 === 0
) {
return false; return false;
} }
}
if ( if (
!player && !player &&

View File

@ -616,7 +616,7 @@ export const speciesStarterCosts = {
[SpeciesId.PALDEA_TAUROS]: 5, [SpeciesId.PALDEA_TAUROS]: 5,
[SpeciesId.PALDEA_WOOPER]: 3, [SpeciesId.PALDEA_WOOPER]: 3,
[SpeciesId.BLOODMOON_URSALUNA]: 5, [SpeciesId.BLOODMOON_URSALUNA]: 5,
}; } as const;
const starterCandyCosts: { passive: number; costReduction: [number, number]; egg: number; }[] = [ const starterCandyCosts: { passive: number; costReduction: [number, number]; egg: number; }[] = [
{ passive: 40, costReduction: [ 25, 60 ], egg: 30 }, // 1 Cost { passive: 40, costReduction: [ 25, 60 ], egg: 30 }, // 1 Cost
@ -657,4 +657,3 @@ export function getValueReductionCandyCounts(starterCost: number): [number, numb
export function getSameSpeciesEggCandyCounts(starterCost: number): number { export function getSameSpeciesEggCandyCounts(starterCost: number): number {
return starterCandyCosts[starterCost - 1].egg; return starterCandyCosts[starterCost - 1].egg;
} }

View File

@ -1397,6 +1397,7 @@ export class EncounterBattleAnim extends BattleAnim {
} }
} }
// biome-ignore-start lint/style/useForOf: This is being removed
export async function populateAnims() { export async function populateAnims() {
const commonAnimNames = getEnumKeys(CommonAnim).map(k => k.toLowerCase()); const commonAnimNames = getEnumKeys(CommonAnim).map(k => k.toLowerCase());
const commonAnimMatchNames = commonAnimNames.map(k => k.replace(/_/g, "")); const commonAnimMatchNames = commonAnimNames.map(k => k.replace(/_/g, ""));
@ -1672,3 +1673,5 @@ export async function populateAnims() {
})(); })();
}*/ }*/
} }
// biome-ignore-end lint/style/useForOf: This is being removed

View File

@ -2537,13 +2537,11 @@ export class RoostedTag extends BattlerTag {
let modifiedTypes: PokemonType[]; let modifiedTypes: PokemonType[];
if (this.isBasePureFlying && !isCurrentlyDualType) { if (this.isBasePureFlying && !isCurrentlyDualType) {
modifiedTypes = [PokemonType.NORMAL]; modifiedTypes = [PokemonType.NORMAL];
} else { } else if (!!pokemon.getTag(RemovedTypeTag) && isOriginallyDualType && !isCurrentlyDualType) {
if (!!pokemon.getTag(RemovedTypeTag) && isOriginallyDualType && !isCurrentlyDualType) {
modifiedTypes = [PokemonType.UNKNOWN]; modifiedTypes = [PokemonType.UNKNOWN];
} else { } else {
modifiedTypes = currentTypes.filter(type => type !== PokemonType.FLYING); modifiedTypes = currentTypes.filter(type => type !== PokemonType.FLYING);
} }
}
pokemon.summonData.types = modifiedTypes; pokemon.summonData.types = modifiedTypes;
pokemon.updateInfo(); pokemon.updateInfo();
} }

View File

@ -42,10 +42,9 @@ export function getDailyRunStarters(seed: string): Starter[] {
starterCosts.push(randSeedInt(9 - starterCosts[0], 1)); starterCosts.push(randSeedInt(9 - starterCosts[0], 1));
starterCosts.push(10 - (starterCosts[0] + starterCosts[1])); starterCosts.push(10 - (starterCosts[0] + starterCosts[1]));
for (let c = 0; c < starterCosts.length; c++) { for (const cost of starterCosts) {
const cost = starterCosts[c];
const costSpecies = Object.keys(speciesStarterCosts) const costSpecies = Object.keys(speciesStarterCosts)
.map(s => Number.parseInt(s) as SpeciesId) .map(s => Number.parseInt(s) as SpeciesId) // TODO: Remove
.filter(s => speciesStarterCosts[s] === cost); .filter(s => speciesStarterCosts[s] === cost);
const randPkmSpecies = getPokemonSpecies(randSeedItem(costSpecies)); const randPkmSpecies = getPokemonSpecies(randSeedItem(costSpecies));
const starterSpecies = getPokemonSpecies( const starterSpecies = getPokemonSpecies(

View File

@ -419,11 +419,9 @@ export class Egg {
const rand = randSeedInt(MANAPHY_EGG_MANAPHY_RATE) !== 1; const rand = randSeedInt(MANAPHY_EGG_MANAPHY_RATE) !== 1;
return rand ? SpeciesId.PHIONE : SpeciesId.MANAPHY; return rand ? SpeciesId.PHIONE : SpeciesId.MANAPHY;
} }
if (this.tier === EggTier.LEGENDARY && this._sourceType === EggSourceType.GACHA_LEGENDARY) { if (this.tier === EggTier.LEGENDARY && this._sourceType === EggSourceType.GACHA_LEGENDARY && !randSeedInt(2)) {
if (!randSeedInt(2)) {
return getLegendaryGachaSpeciesForTimestamp(this.timestamp); return getLegendaryGachaSpeciesForTimestamp(this.timestamp);
} }
}
let minStarterValue: number; let minStarterValue: number;
let maxStarterValue: number; let maxStarterValue: number;

View File

@ -527,7 +527,8 @@ function doBerrySpritePile(isEat = false) {
const encounter = globalScene.currentBattle.mysteryEncounter!; const encounter = globalScene.currentBattle.mysteryEncounter!;
animationOrder.forEach((berry, i) => { animationOrder.forEach((berry, i) => {
const introVisualsIndex = encounter.spriteConfigs.findIndex(config => config.spriteKey?.includes(berry)); const introVisualsIndex = encounter.spriteConfigs.findIndex(config => config.spriteKey?.includes(berry));
let sprite: Phaser.GameObjects.Sprite, tintSprite: Phaser.GameObjects.Sprite; let sprite: Phaser.GameObjects.Sprite;
let tintSprite: Phaser.GameObjects.Sprite;
const sprites = encounter.introVisuals?.getSpriteAtIndex(introVisualsIndex); const sprites = encounter.introVisuals?.getSpriteAtIndex(introVisualsIndex);
if (sprites) { if (sprites) {
sprite = sprites[0]; sprite = sprites[0];

View File

@ -213,7 +213,8 @@ export const BugTypeSuperfanEncounter: MysteryEncounter = MysteryEncounterBuilde
female: true, female: true,
}); });
let beedrillKeys: { spriteKey: string; fileRoot: string }, butterfreeKeys: { spriteKey: string; fileRoot: string }; let beedrillKeys: { spriteKey: string; fileRoot: string };
let butterfreeKeys: { spriteKey: string; fileRoot: string };
if (globalScene.currentBattle.waveIndex < WAVE_LEVEL_BREAKPOINTS[3]) { if (globalScene.currentBattle.waveIndex < WAVE_LEVEL_BREAKPOINTS[3]) {
beedrillKeys = getSpriteKeysFromSpecies(SpeciesId.BEEDRILL, false); beedrillKeys = getSpriteKeysFromSpecies(SpeciesId.BEEDRILL, false);
butterfreeKeys = getSpriteKeysFromSpecies(SpeciesId.BUTTERFREE, false); butterfreeKeys = getSpriteKeysFromSpecies(SpeciesId.BUTTERFREE, false);

View File

@ -289,8 +289,7 @@ export const GlobalTradeSystemEncounter: MysteryEncounter = MysteryEncounterBuil
// Extra HA roll at base 1/64 odds (boosted by events and charms) // Extra HA roll at base 1/64 odds (boosted by events and charms)
const hiddenIndex = tradePokemon.species.ability2 ? 2 : 1; const hiddenIndex = tradePokemon.species.ability2 ? 2 : 1;
if (tradePokemon.species.abilityHidden) { if (tradePokemon.species.abilityHidden && tradePokemon.abilityIndex < hiddenIndex) {
if (tradePokemon.abilityIndex < hiddenIndex) {
const hiddenAbilityChance = new NumberHolder(64); const hiddenAbilityChance = new NumberHolder(64);
globalScene.applyModifiers(HiddenAbilityRateBoosterModifier, true, hiddenAbilityChance); globalScene.applyModifiers(HiddenAbilityRateBoosterModifier, true, hiddenAbilityChance);
@ -300,7 +299,6 @@ export const GlobalTradeSystemEncounter: MysteryEncounter = MysteryEncounterBuil
tradePokemon.abilityIndex = hiddenIndex; tradePokemon.abilityIndex = hiddenIndex;
} }
} }
}
// If Pokemon is still not shiny or with HA, give the Pokemon a random Common egg move in its moveset // If Pokemon is still not shiny or with HA, give the Pokemon a random Common egg move in its moveset
if (!tradePokemon.shiny && (!tradePokemon.species.abilityHidden || tradePokemon.abilityIndex < hiddenIndex)) { if (!tradePokemon.shiny && (!tradePokemon.species.abilityHidden || tradePokemon.abilityIndex < hiddenIndex)) {

View File

@ -1107,13 +1107,11 @@ export function calculateMEAggregateStats(baseSpawnWeight: number) {
} }
} else if (biomeLinks.hasOwnProperty(currentBiome)) { } else if (biomeLinks.hasOwnProperty(currentBiome)) {
currentBiome = biomeLinks[currentBiome] as BiomeId; currentBiome = biomeLinks[currentBiome] as BiomeId;
} else { } else if (!(i % 50)) {
if (!(i % 50)) {
currentBiome = BiomeId.END; currentBiome = BiomeId.END;
} else { } else {
currentBiome = globalScene.generateRandomBiome(i); currentBiome = globalScene.generateRandomBiome(i);
} }
}
currentArena = globalScene.newArena(currentBiome); currentArena = globalScene.newArena(currentBiome);
} }

View File

@ -986,8 +986,7 @@ export class PokemonSpecies extends PokemonSpeciesForm implements Localizable {
if (!forTrainer && isRegionalEvolution) { if (!forTrainer && isRegionalEvolution) {
evolutionChance = 0; evolutionChance = 0;
} else { } else if (ev.wildDelay === SpeciesWildEvolutionDelay.NONE) {
if (ev.wildDelay === SpeciesWildEvolutionDelay.NONE) {
if (strength === PartyMemberStrength.STRONGER) { if (strength === PartyMemberStrength.STRONGER) {
evolutionChance = 1; evolutionChance = 1;
} else { } else {
@ -1021,7 +1020,6 @@ export class PokemonSpecies extends PokemonSpeciesForm implements Localizable {
1, 1,
); );
} }
}
//TODO: Adjust templates and delays so we don't have to hardcode it //TODO: Adjust templates and delays so we don't have to hardcode it
/* TEMPORARY! (Most) Trainers shouldn't be using unevolved Pokemon by the third gym leader / wave 80. Exceptions to this include Breeders, whose large teams are balanced by the use of weaker pokemon */ /* TEMPORARY! (Most) Trainers shouldn't be using unevolved Pokemon by the third gym leader / wave 80. Exceptions to this include Breeders, whose large teams are balanced by the use of weaker pokemon */
@ -1210,9 +1208,9 @@ export class PokemonSpecies extends PokemonSpeciesForm implements Localizable {
} }
/** /**
* Generates a {@linkcode bigint} corresponding to the maximum unlocks possible for this species, * Generates a {@linkcode BigInt} corresponding to the maximum unlocks possible for this species,
* taking into account if the species has a male/female gender, and which variants are implemented. * taking into account if the species has a male/female gender, and which variants are implemented.
* @returns {@linkcode bigint} Maximum unlocks, can be compared with {@linkcode DexEntry.caughtAttr}. * @returns The maximum unlocks for the species as a `BigInt`; can be compared with {@linkcode DexEntry.caughtAttr}.
*/ */
getFullUnlocksData(): bigint { getFullUnlocksData(): bigint {
let caughtAttr = 0n; let caughtAttr = 0n;

View File

@ -6,6 +6,7 @@ import type { MysteryEncounter } from "#mystery-encounters/mystery-encounter";
import { loadPokemonVariantAssets } from "#sprites/pokemon-sprite"; import { loadPokemonVariantAssets } from "#sprites/pokemon-sprite";
import type { Variant } from "#sprites/variant"; import type { Variant } from "#sprites/variant";
import { isNullOrUndefined } from "#utils/common"; import { isNullOrUndefined } from "#utils/common";
import console from "node:console";
import type { GameObjects } from "phaser"; import type { GameObjects } from "phaser";
type PlayAnimationConfig = Phaser.Types.Animations.PlayAnimationConfig; type PlayAnimationConfig = Phaser.Types.Animations.PlayAnimationConfig;
@ -87,6 +88,7 @@ export class MysteryEncounterIntroVisuals extends Phaser.GameObjects.Container {
variant: Variant; variant: Variant;
}[]; }[];
// TODO: Refactor
constructor(encounter: MysteryEncounter) { constructor(encounter: MysteryEncounter) {
super(globalScene, -72, 76); super(globalScene, -72, 76);
this.encounter = encounter; this.encounter = encounter;
@ -193,9 +195,8 @@ export class MysteryEncounterIntroVisuals extends Phaser.GameObjects.Container {
sprite.setPosition(sprite.x, sprite.y + y); sprite.setPosition(sprite.x, sprite.y + y);
tintSprite.setPosition(tintSprite.x, tintSprite.y + y); tintSprite.setPosition(tintSprite.x, tintSprite.y + y);
} }
} else {
// Single sprite // Single sprite
if (this.spriteConfigs.length === 1) { } else if (this.spriteConfigs.length === 1) {
sprite.x = origin; sprite.x = origin;
tintSprite.x = origin; tintSprite.x = origin;
} else { } else {
@ -204,7 +205,6 @@ export class MysteryEncounterIntroVisuals extends Phaser.GameObjects.Container {
tintSprite.x = minX + (n + 0.5) * spacingValue + origin; tintSprite.x = minX + (n + 0.5) * spacingValue + origin;
n++; n++;
} }
}
if (!isNullOrUndefined(pokemonShinySparkle)) { if (!isNullOrUndefined(pokemonShinySparkle)) {
// Offset the sparkle to match the Pokemon's position // Offset the sparkle to match the Pokemon's position

View File

@ -2511,19 +2511,15 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
defenderType, defenderType,
}); });
} }
if (ignoreImmunity.value) { if (ignoreImmunity.value && multiplier.value === 0) {
if (multiplier.value === 0) {
return 1; return 1;
} }
}
const exposedTags = this.findTags(tag => tag instanceof ExposedTag) as ExposedTag[]; const exposedTags = this.findTags(tag => tag instanceof ExposedTag) as ExposedTag[];
if (exposedTags.some(t => t.ignoreImmunity(defenderType, moveType))) { if (exposedTags.some(t => t.ignoreImmunity(defenderType, moveType)) && multiplier.value === 0) {
if (multiplier.value === 0) {
return 1; return 1;
} }
} }
}
return multiplier.value; return multiplier.value;
}) })
.reduce((acc, cur) => acc * cur, 1) as TypeDamageMultiplier; .reduce((acc, cur) => acc * cur, 1) as TypeDamageMultiplier;
@ -2960,11 +2956,9 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
return false; return false;
} }
const haThreshold = new NumberHolder(thresholdOverride ?? BASE_HIDDEN_ABILITY_CHANCE); const haThreshold = new NumberHolder(thresholdOverride ?? BASE_HIDDEN_ABILITY_CHANCE);
if (applyModifiersToOverride) { if (applyModifiersToOverride && !this.hasTrainer()) {
if (!this.hasTrainer()) {
globalScene.applyModifiers(HiddenAbilityRateBoosterModifier, true, haThreshold); globalScene.applyModifiers(HiddenAbilityRateBoosterModifier, true, haThreshold);
} }
}
if (randSeedInt(65536) < haThreshold.value) { if (randSeedInt(65536) < haThreshold.value) {
this.abilityIndex = 2; this.abilityIndex = 2;
@ -3063,8 +3057,7 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
return; return;
} }
for (let m = 0; m < allLevelMoves.length; m++) { for (const levelMove of allLevelMoves) {
const levelMove = allLevelMoves[m];
if (this.level < levelMove[0]) { if (this.level < levelMove[0]) {
break; break;
} }
@ -4829,12 +4822,10 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
return true; return true;
}); });
if (this.isOfType(PokemonType.POISON) || this.isOfType(PokemonType.STEEL)) { if ((this.isOfType(PokemonType.POISON) || this.isOfType(PokemonType.STEEL)) && poisonImmunity.includes(true)) {
if (poisonImmunity.includes(true)) {
this.queueStatusImmuneMessage(quiet); this.queueStatusImmuneMessage(quiet);
return false; return false;
} }
}
break; break;
} }
case StatusEffect.PARALYSIS: case StatusEffect.PARALYSIS:
@ -5013,11 +5004,9 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
this.lapseTag(BattlerTagType.NIGHTMARE); this.lapseTag(BattlerTagType.NIGHTMARE);
} }
} }
if (confusion) { if (confusion && this.getTag(BattlerTagType.CONFUSED)) {
if (this.getTag(BattlerTagType.CONFUSED)) {
this.lapseTag(BattlerTagType.CONFUSED); this.lapseTag(BattlerTagType.CONFUSED);
} }
}
if (reloadAssets) { if (reloadAssets) {
this.loadAssets(false).then(() => this.playAnim()); this.loadAssets(false).then(() => this.playAnim());
} }
@ -5500,8 +5489,8 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
spriteColors.forEach((sc: number[], i: number) => { spriteColors.forEach((sc: number[], i: number) => {
paletteDeltas.push([]); paletteDeltas.push([]);
for (let p = 0; p < palette.length; p++) { for (const p of palette) {
paletteDeltas[i].push(deltaRgb(sc, palette[p])); paletteDeltas[i].push(deltaRgb(sc, p));
} }
}); });
@ -6774,11 +6763,13 @@ export class EnemyPokemon extends Pokemon {
} }
canBypassBossSegments(segmentCount = 1): boolean { canBypassBossSegments(segmentCount = 1): boolean {
if (globalScene.currentBattle.battleSpec === BattleSpec.FINAL_BOSS) { if (
if (!this.formIndex && this.bossSegmentIndex - segmentCount < 1) { globalScene.currentBattle.battleSpec === BattleSpec.FINAL_BOSS &&
!this.formIndex &&
this.bossSegmentIndex - segmentCount < 1
) {
return false; return false;
} }
}
return true; return true;
} }

View File

@ -403,17 +403,15 @@ export class Trainer extends Phaser.GameObjects.Container {
} else { } else {
newSpeciesPool = speciesPoolFiltered; newSpeciesPool = speciesPoolFiltered;
} }
} else {
// If the index is odd, use the species pool for the partner trainer (that way he only uses his own pokemon in battle) // If the index is odd, use the species pool for the partner trainer (that way he only uses his own pokemon in battle)
// Since the only currently allowed double battle with named trainers is Tate & Liza, we need to make sure that Solrock is the first pokemon in the party for Tate and Lunatone for Liza // Since the only currently allowed double battle with named trainers is Tate & Liza, we need to make sure that Solrock is the first pokemon in the party for Tate and Lunatone for Liza
if (index === 1 && TrainerType[this.config.trainerTypeDouble] === TrainerType[TrainerType.TATE]) { } else if (index === 1 && TrainerType[this.config.trainerTypeDouble] === TrainerType[TrainerType.TATE]) {
newSpeciesPool = [SpeciesId.SOLROCK]; newSpeciesPool = [SpeciesId.SOLROCK];
} else if (index === 1 && TrainerType[this.config.trainerTypeDouble] === TrainerType[TrainerType.LIZA]) { } else if (index === 1 && TrainerType[this.config.trainerTypeDouble] === TrainerType[TrainerType.LIZA]) {
newSpeciesPool = [SpeciesId.LUNATONE]; newSpeciesPool = [SpeciesId.LUNATONE];
} else { } else {
newSpeciesPool = speciesPoolPartnerFiltered; newSpeciesPool = speciesPoolPartnerFiltered;
} }
}
// Fallback for when the species pool is empty // Fallback for when the species pool is empty
if (newSpeciesPool.length === 0) { if (newSpeciesPool.length === 0) {
// If all pokemon from this pool are already in the party, generate a random species // If all pokemon from this pool are already in the party, generate a random species
@ -794,11 +792,13 @@ export class Trainer extends Phaser.GameObjects.Container {
* @returns boolean Whether the EnemyPokemon should Terastalize this turn * @returns boolean Whether the EnemyPokemon should Terastalize this turn
*/ */
shouldTera(pokemon: EnemyPokemon): boolean { shouldTera(pokemon: EnemyPokemon): boolean {
if (this.config.trainerAI.teraMode === TeraAIMode.INSTANT_TERA) { if (
if (!pokemon.isTerastallized && this.config.trainerAI.instantTeras.includes(pokemon.initialTeamIndex)) { this.config.trainerAI.teraMode === TeraAIMode.INSTANT_TERA &&
!pokemon.isTerastallized &&
this.config.trainerAI.instantTeras.includes(pokemon.initialTeamIndex)
) {
return true; return true;
} }
}
return false; return false;
} }
} }

View File

@ -1634,9 +1634,9 @@ export class FormChangeItemModifierTypeGenerator extends ModifierTypeGenerator {
if (p.species.speciesId === SpeciesId.NECROZMA) { if (p.species.speciesId === SpeciesId.NECROZMA) {
// technically we could use a simplified version and check for formChanges.length > 3, but in case any code changes later, this might break... // technically we could use a simplified version and check for formChanges.length > 3, but in case any code changes later, this might break...
let foundULTRA_Z = false, let foundULTRA_Z = false;
foundN_LUNA = false, let foundN_LUNA = false;
foundN_SOLAR = false; let foundN_SOLAR = false;
formChangeItemTriggers.forEach((fc, _i) => { formChangeItemTriggers.forEach((fc, _i) => {
console.log("Checking ", fc.item); console.log("Checking ", fc.item);
switch (fc.item) { switch (fc.item) {

View File

@ -102,10 +102,13 @@ import { WeatherEffectPhase } from "#phases/weather-effect-phase";
import type { PhaseMap, PhaseString } from "#types/phase-types"; import type { PhaseMap, PhaseString } from "#types/phase-types";
import { type Constructor, coerceArray } from "#utils/common"; import { type Constructor, coerceArray } from "#utils/common";
/* /**
* @module
* Manager for phases used by battle scene. * Manager for phases used by battle scene.
* *
* *This file must not be imported or used directly. The manager is exclusively used by the battle scene and is not intended for external use.* * @remarks
* **This file must not be imported or used directly.**
* The manager is exclusively used by the Battle Scene and is NOT intended for external use.
*/ */
/** /**

View File

@ -604,9 +604,8 @@ export class CommandPhase extends FieldPhase {
* @returns Whether the command was successful * @returns Whether the command was successful
*/ */
handleCommand(command: Command.FIGHT | Command.TERA, cursor: number, useMode?: MoveUseMode, move?: TurnMove): boolean; handleCommand(command: Command.FIGHT | Command.TERA, cursor: number, useMode?: MoveUseMode, move?: TurnMove): boolean;
handleCommand(command: Command.BALL, cursor: number): boolean;
handleCommand(command: Command.POKEMON, cursor: number, useBaton: boolean): boolean; handleCommand(command: Command.POKEMON, cursor: number, useBaton: boolean): boolean;
handleCommand(command: Command.RUN, cursor: number): boolean; handleCommand(command: Command.BALL | Command.RUN, cursor: number): boolean;
handleCommand(command: Command, cursor: number, useMode?: boolean | MoveUseMode, move?: TurnMove): boolean; handleCommand(command: Command, cursor: number, useMode?: boolean | MoveUseMode, move?: TurnMove): boolean;
public handleCommand( public handleCommand(

View File

@ -559,11 +559,12 @@ export class MoveEffectPhase extends PokemonPhase {
// Strikes after the first in a multi-strike move are guaranteed to hit, // Strikes after the first in a multi-strike move are guaranteed to hit,
// unless the move is flagged to check all hits and the user does not have Skill Link. // unless the move is flagged to check all hits and the user does not have Skill Link.
if (user.turnData.hitsLeft < user.turnData.hitCount) { if (
if (!move.hasFlag(MoveFlags.CHECK_ALL_HITS) || user.hasAbilityWithAttr("MaxMultiHitAbAttr")) { user.turnData.hitsLeft < user.turnData.hitCount &&
(!move.hasFlag(MoveFlags.CHECK_ALL_HITS) || user.hasAbilityWithAttr("MaxMultiHitAbAttr"))
) {
return [HitCheckResult.HIT, effectiveness]; return [HitCheckResult.HIT, effectiveness];
} }
}
const bypassAccuracy = const bypassAccuracy =
bypassAccAndInvuln || bypassAccAndInvuln ||

View File

@ -23,25 +23,24 @@ export class ScanIvsPhase extends PokemonPhase {
let enemyIvs: number[] = []; let enemyIvs: number[] = [];
let statsContainer: Phaser.GameObjects.Sprite[] = []; let statsContainer: Phaser.GameObjects.Sprite[] = [];
let statsContainerLabels: Phaser.GameObjects.Sprite[] = []; let statsContainerLabels: Phaser.GameObjects.Sprite[] = [];
const enemyField = globalScene.getEnemyField();
const uiTheme = globalScene.uiTheme; // Assuming uiTheme is accessible const uiTheme = globalScene.uiTheme; // Assuming uiTheme is accessible
for (let e = 0; e < enemyField.length; e++) { for (const enemy of globalScene.getEnemyField()) {
enemyIvs = enemyField[e].ivs; enemyIvs = enemy.ivs;
// we are using getRootSpeciesId() here because we want to check against the baby form, not the mid form if it exists // we are using getRootSpeciesId() here because we want to check against the baby form, not the mid form if it exists
const currentIvs = globalScene.gameData.dexData[enemyField[e].species.getRootSpeciesId()].ivs; const currentIvs = globalScene.gameData.dexData[enemy.species.getRootSpeciesId()].ivs;
statsContainer = enemyField[e].getBattleInfo().getStatsValueContainer().list as Phaser.GameObjects.Sprite[]; statsContainer = enemy.getBattleInfo().getStatsValueContainer().list as Phaser.GameObjects.Sprite[];
statsContainerLabels = statsContainer.filter(m => m.name.indexOf("icon_stat_label") >= 0); statsContainerLabels = statsContainer.filter(m => m.name.indexOf("icon_stat_label") >= 0);
for (let s = 0; s < statsContainerLabels.length; s++) { for (const statContainer of statsContainerLabels) {
const ivStat = Stat[statsContainerLabels[s].frame.name]; const ivStat = Stat[statContainer.frame.name];
if (enemyIvs[ivStat] > currentIvs[ivStat] && PERMANENT_STATS.indexOf(Number(ivStat)) >= 0) { if (enemyIvs[ivStat] > currentIvs[ivStat] && PERMANENT_STATS.indexOf(Number(ivStat)) >= 0) {
const hexColour = const hexColour =
enemyIvs[ivStat] === 31 enemyIvs[ivStat] === 31
? getTextColor(TextStyle.PERFECT_IV, false, uiTheme) ? getTextColor(TextStyle.PERFECT_IV, false, uiTheme)
: getTextColor(TextStyle.SUMMARY_GREEN, false, uiTheme); : getTextColor(TextStyle.SUMMARY_GREEN, false, uiTheme);
const hexTextColour = Phaser.Display.Color.HexStringToColor(hexColour).color; const hexTextColour = Phaser.Display.Color.HexStringToColor(hexColour).color;
statsContainerLabels[s].setTint(hexTextColour); statContainer.setTint(hexTextColour);
} }
statsContainerLabels[s].setVisible(true); statContainer.setVisible(true);
} }
} }

View File

@ -22,6 +22,7 @@ export type StatStageChangeCallback = (
relativeChanges: number[], relativeChanges: number[],
) => void; ) => void;
// TODO: Refactor this mess of a phase
export class StatStageChangePhase extends PokemonPhase { export class StatStageChangePhase extends PokemonPhase {
public readonly phaseName = "StatStageChangePhase"; public readonly phaseName = "StatStageChangePhase";
private stats: BattleStat[]; private stats: BattleStat[];
@ -62,13 +63,12 @@ export class StatStageChangePhase extends PokemonPhase {
start() { start() {
// Check if multiple stats are being changed at the same time, then run SSCPhase for each of them // Check if multiple stats are being changed at the same time, then run SSCPhase for each of them
if (this.stats.length > 1) { if (this.stats.length > 1) {
for (let i = 0; i < this.stats.length; i++) { for (const stat of this.stats) {
const stat = [this.stats[i]];
globalScene.phaseManager.unshiftNew( globalScene.phaseManager.unshiftNew(
"StatStageChangePhase", "StatStageChangePhase",
this.battlerIndex, this.battlerIndex,
this.selfTarget, this.selfTarget,
stat, [stat],
this.stages, this.stages,
this.showMessage, this.showMessage,
this.ignoreAbilities, this.ignoreAbilities,
@ -100,8 +100,7 @@ export class StatStageChangePhase extends PokemonPhase {
} }
}); });
} }
} else { } else if (!this.comingFromStickyWeb) {
if (!this.comingFromStickyWeb) {
opponentPokemon = globalScene.getPlayerField()[globalScene.currentBattle.lastPlayerInvolved]; opponentPokemon = globalScene.getPlayerField()[globalScene.currentBattle.lastPlayerInvolved];
} else { } else {
const stickyTagID = globalScene.arena.findTagsOnSide( const stickyTagID = globalScene.arena.findTagsOnSide(
@ -114,7 +113,6 @@ export class StatStageChangePhase extends PokemonPhase {
} }
}); });
} }
}
if (!pokemon.isActive(true)) { if (!pokemon.isActive(true)) {
return this.end(); return this.end();

View File

@ -27,8 +27,8 @@ export class TrainerVictoryPhase extends BattlePhase {
const trainerType = globalScene.currentBattle.trainer?.config.trainerType!; // TODO: is this bang correct? const trainerType = globalScene.currentBattle.trainer?.config.trainerType!; // TODO: is this bang correct?
// Validate Voucher for boss trainers // Validate Voucher for boss trainers
if (vouchers.hasOwnProperty(TrainerType[trainerType])) {
if ( if (
vouchers.hasOwnProperty(TrainerType[trainerType]) &&
!globalScene.validateVoucher(vouchers[TrainerType[trainerType]]) && !globalScene.validateVoucher(vouchers[TrainerType[trainerType]]) &&
globalScene.currentBattle.trainer?.config.isBoss globalScene.currentBattle.trainer?.config.isBoss
) { ) {
@ -51,7 +51,6 @@ export class TrainerVictoryPhase extends BattlePhase {
); );
} }
} }
}
// Breeders in Space achievement // Breeders in Space achievement
if ( if (
globalScene.arena.biomeType === BiomeId.SPACE && globalScene.arena.biomeType === BiomeId.SPACE &&

View File

@ -17,7 +17,7 @@ export class PokerogueSessionSavedataApi extends ApiBase {
/** /**
* Mark a session as cleared aka "newclear". \ * Mark a session as cleared aka "newclear". \
* *This is **NOT** the same as {@linkcode clear | clear()}.* * _This is **NOT** the same as {@linkcode clear | clear()}._
* @param params The {@linkcode NewClearSessionSavedataRequest} to send * @param params The {@linkcode NewClearSessionSavedataRequest} to send
* @returns The raw savedata as `string`. * @returns The raw savedata as `string`.
* @throws Error if the request fails * @throws Error if the request fails
@ -95,7 +95,7 @@ export class PokerogueSessionSavedataApi extends ApiBase {
/** /**
* Clears the session savedata of the given slot. \ * Clears the session savedata of the given slot. \
* *This is **NOT** the same as {@linkcode newclear | newclear()}.* * _This is **NOT** the same as {@linkcode newclear | newclear()}._
* @param params The {@linkcode ClearSessionSavedataRequest} to send * @param params The {@linkcode ClearSessionSavedataRequest} to send
* @param sessionData The {@linkcode SessionSaveData} object * @param sessionData The {@linkcode SessionSaveData} object
*/ */

View File

@ -122,7 +122,7 @@ async function initFonts(language: string | undefined) {
/** /**
* I18n money formatter with. (useful for BBCode coloring of text) \ * I18n money formatter with. (useful for BBCode coloring of text) \
* *If you don't want the BBCode tag applied, just use 'number' formatter* * _If you don't want the BBCode tag applied, just use 'number' formatter_
* @example Input: `{{myMoneyValue, money}}` * @example Input: `{{myMoneyValue, money}}`
* Output: `@[MONEY]{₽100,000,000}` * Output: `@[MONEY]{₽100,000,000}`
* @param amount the money amount * @param amount the money amount

View File

@ -1595,7 +1595,7 @@ export class GameData {
globalScene.executeWithSeedOffset( globalScene.executeWithSeedOffset(
() => { () => {
const neutralNatures = [Nature.HARDY, Nature.DOCILE, Nature.SERIOUS, Nature.BASHFUL, Nature.QUIRKY]; const neutralNatures = [Nature.HARDY, Nature.DOCILE, Nature.SERIOUS, Nature.BASHFUL, Nature.QUIRKY];
for (let s = 0; s < defaultStarterSpecies.length; s++) { for (const _ of defaultStarterSpecies) {
defaultStarterNatures.push(randSeedItem(neutralNatures)); defaultStarterNatures.push(randSeedItem(neutralNatures));
} }
}, },

View File

@ -104,8 +104,7 @@ export function setSettingGamepad(setting: SettingGamepad, value: number): boole
case SettingGamepad.Button_Speed_Up: case SettingGamepad.Button_Speed_Up:
case SettingGamepad.Button_Slow_Down: case SettingGamepad.Button_Slow_Down:
case SettingGamepad.Button_Submit: case SettingGamepad.Button_Submit:
if (value) { if (value && globalScene.ui) {
if (globalScene.ui) {
const cancelHandler = (success = false): boolean => { const cancelHandler = (success = false): boolean => {
globalScene.ui.revertMode(); globalScene.ui.revertMode();
(globalScene.ui.getHandler() as SettingsGamepadUiHandler).updateBindings(); (globalScene.ui.getHandler() as SettingsGamepadUiHandler).updateBindings();
@ -116,7 +115,6 @@ export function setSettingGamepad(setting: SettingGamepad, value: number): boole
cancelHandler: cancelHandler, cancelHandler: cancelHandler,
}); });
} }
}
break; break;
case SettingGamepad.Controller: case SettingGamepad.Controller:
if (value) { if (value) {

View File

@ -167,8 +167,7 @@ export function setSettingKeyboard(setting: SettingKeyboard, value: number): boo
case SettingKeyboard.Alt_Button_Speed_Up: case SettingKeyboard.Alt_Button_Speed_Up:
case SettingKeyboard.Alt_Button_Slow_Down: case SettingKeyboard.Alt_Button_Slow_Down:
case SettingKeyboard.Alt_Button_Submit: case SettingKeyboard.Alt_Button_Submit:
if (value) { if (value && globalScene.ui) {
if (globalScene.ui) {
const cancelHandler = (success = false): boolean => { const cancelHandler = (success = false): boolean => {
globalScene.ui.revertMode(); globalScene.ui.revertMode();
(globalScene.ui.getHandler() as SettingsKeyboardUiHandler).updateBindings(); (globalScene.ui.getHandler() as SettingsKeyboardUiHandler).updateBindings();
@ -179,7 +178,6 @@ export function setSettingKeyboard(setting: SettingKeyboard, value: number): boo
cancelHandler: cancelHandler, cancelHandler: cancelHandler,
}); });
} }
}
break; break;
} }
return true; return true;

View File

@ -896,8 +896,7 @@ export function setSetting(setting: string, value: number): boolean {
globalScene.typeHints = Setting[index].options[value].value === "On"; globalScene.typeHints = Setting[index].options[value].value === "On";
break; break;
case SettingKeys.Language: case SettingKeys.Language:
if (value) { if (value && globalScene.ui) {
if (globalScene.ui) {
const cancelHandler = () => { const cancelHandler = () => {
globalScene.ui.revertMode(); globalScene.ui.revertMode();
(globalScene.ui.getHandler() as SettingsUiHandler).setOptionCursor(-1, 0, true); (globalScene.ui.getHandler() as SettingsUiHandler).setOptionCursor(-1, 0, true);
@ -994,7 +993,6 @@ export function setSetting(setting: string, value: number): boolean {
}); });
return false; return false;
} }
}
break; break;
case SettingKeys.Shop_Overlay_Opacity: case SettingKeys.Shop_Overlay_Opacity:
globalScene.updateShopOverlayOpacity(Number.parseInt(Setting[index].options[value].value) * 0.01); globalScene.updateShopOverlayOpacity(Number.parseInt(Setting[index].options[value].value) * 0.01);

View File

@ -241,9 +241,7 @@ export class ArenaFlyout extends Phaser.GameObjects.Container {
this.fieldEffectInfo.sort((infoA, infoB) => infoA.duration - infoB.duration); this.fieldEffectInfo.sort((infoA, infoB) => infoA.duration - infoB.duration);
for (let i = 0; i < this.fieldEffectInfo.length; i++) { for (const fieldEffectInfo of this.fieldEffectInfo) {
const fieldEffectInfo = this.fieldEffectInfo[i];
// Creates a proxy object to decide which text object needs to be updated // Creates a proxy object to decide which text object needs to be updated
let textObject: Phaser.GameObjects.Text; let textObject: Phaser.GameObjects.Text;
switch (fieldEffectInfo.effectType) { switch (fieldEffectInfo.effectType) {
@ -389,9 +387,7 @@ export class ArenaFlyout extends Phaser.GameObjects.Container {
const fieldEffectInfo: ArenaEffectInfo[] = []; const fieldEffectInfo: ArenaEffectInfo[] = [];
this.fieldEffectInfo.forEach(i => fieldEffectInfo.push(i)); this.fieldEffectInfo.forEach(i => fieldEffectInfo.push(i));
for (let i = 0; i < fieldEffectInfo.length; i++) { for (const info of fieldEffectInfo) {
const info = fieldEffectInfo[i];
if (info.maxDuration === 0) { if (info.maxDuration === 0) {
continue; continue;
} }

View File

@ -68,14 +68,14 @@ export class BaseStatsOverlay extends Phaser.GameObjects.Container implements In
// show this component with infos for the specific move // show this component with infos for the specific move
show(values: number[], total: number): boolean { show(values: number[], total: number): boolean {
for (let i = 0; i < 6; i++) { for (let i = 0; i < 6; i++) {
this.statsLabels[i].setText(i18next.t(`pokemonInfo:Stat.${shortStats[i]}shortened`) + ": " + `${values[i]}`); this.statsLabels[i].setText(`${i18next.t(`pokemonInfo:Stat.${shortStats[i]}shortened`)}: ${values[i]}`);
// This accounts for base stats up to 200, might not be enough. // This accounts for base stats up to 200, might not be enough.
// TODO: change color based on value. // TODO: change color based on value.
this.statsShadows[i].setSize(values[i] / 2, 5); this.statsShadows[i].setSize(values[i] / 2, 5);
this.statsRectangles[i].setSize(values[i] / 2, 5); this.statsRectangles[i].setSize(values[i] / 2, 5);
} }
this.statsTotalLabel.setText(i18next.t("pokedexUiHandler:baseTotal") + ": " + `${total}`); this.statsTotalLabel.setText(`${i18next.t("pokedexUiHandler:baseTotal")}: ${total}`);
this.setVisible(true); this.setVisible(true);
this.active = true; this.active = true;

View File

@ -153,17 +153,13 @@ export class BattleMessageUiHandler extends MessageUiHandler {
processInput(button: Button): boolean { processInput(button: Button): boolean {
const ui = this.getUi(); const ui = this.getUi();
if (this.awaitingActionInput) { if (this.awaitingActionInput && (button === Button.CANCEL || button === Button.ACTION) && this.onActionInput) {
if (button === Button.CANCEL || button === Button.ACTION) {
if (this.onActionInput) {
ui.playSelect(); ui.playSelect();
const originalOnActionInput = this.onActionInput; const originalOnActionInput = this.onActionInput;
this.onActionInput = null; this.onActionInput = null;
originalOnActionInput(); originalOnActionInput();
return true; return true;
} }
}
}
return false; return false;
} }

View File

@ -400,8 +400,7 @@ export class GameChallengesUiHandler extends UiHandler {
} else { } else {
success = false; success = false;
} }
} else { } else if (this.cursorObj?.visible && !this.startCursor.visible) {
if (this.cursorObj?.visible && !this.startCursor.visible) {
switch (button) { switch (button) {
case Button.UP: case Button.UP:
if (this.cursor === 0) { if (this.cursor === 0) {
@ -470,7 +469,6 @@ export class GameChallengesUiHandler extends UiHandler {
break; break;
} }
} }
}
// Plays a select sound effect if an action was successfully processed. // Plays a select sound effect if an action was successfully processed.
if (success) { if (success) {

View File

@ -504,14 +504,12 @@ export class DropDown extends Phaser.GameObjects.Container {
if (index === 0) { if (index === 0) {
// we are on the All option > put all other options to the newState // we are on the All option > put all other options to the newState
this.setAllOptions(newState); this.setAllOptions(newState);
} else { } else if (newState === DropDownState.ON && this.checkForAllOn()) {
// select the "all" option if all others are selected, other unselect it // select the "all" option if all others are selected, other unselect it
if (newState === DropDownState.ON && this.checkForAllOn()) {
this.options[0].setOptionState(DropDownState.ON); this.options[0].setOptionState(DropDownState.ON);
} else { } else {
this.options[0].setOptionState(DropDownState.OFF); this.options[0].setOptionState(DropDownState.OFF);
} }
}
} else if (this.dropDownType === DropDownType.SINGLE) { } else if (this.dropDownType === DropDownType.SINGLE) {
if (option.state === DropDownState.OFF) { if (option.state === DropDownState.OFF) {
this.options.forEach(option => { this.options.forEach(option => {
@ -653,12 +651,10 @@ export class DropDown extends Phaser.GameObjects.Container {
this.options[i].setDirection(SortDirection.ASC); this.options[i].setDirection(SortDirection.ASC);
this.options[i].toggle.setVisible(true); this.options[i].toggle.setVisible(true);
} }
} else { } else if (this.defaultSettings[i]) {
if (this.defaultSettings[i]) {
this.options[i].setOptionState(this.defaultSettings[i]["state"]); this.options[i].setOptionState(this.defaultSettings[i]["state"]);
} }
} }
}
this.onChange(); this.onChange();
} }
@ -699,11 +695,11 @@ export class DropDown extends Phaser.GameObjects.Container {
autoSize(): void { autoSize(): void {
let maxWidth = 0; let maxWidth = 0;
let x = 0; let x = 0;
for (let i = 0; i < this.options.length; i++) { for (const option of this.options) {
const optionWidth = this.options[i].getWidth(); const optionWidth = option.getWidth();
if (optionWidth > maxWidth) { if (optionWidth > maxWidth) {
maxWidth = optionWidth; maxWidth = optionWidth;
x = this.options[i].getCurrentLabelX() ?? 0; x = option.getCurrentLabelX() ?? 0;
} }
} }
this.window.width = maxWidth + x - this.window.x + 9; this.window.width = maxWidth + x - this.window.x + 9;

View File

@ -62,17 +62,13 @@ export class EvolutionSceneHandler extends MessageUiHandler {
} }
const ui = this.getUi(); const ui = this.getUi();
if (this.awaitingActionInput) { if (this.awaitingActionInput && (button === Button.CANCEL || button === Button.ACTION) && this.onActionInput) {
if (button === Button.CANCEL || button === Button.ACTION) {
if (this.onActionInput) {
ui.playSelect(); ui.playSelect();
const originalOnActionInput = this.onActionInput; const originalOnActionInput = this.onActionInput;
this.onActionInput = null; this.onActionInput = null;
originalOnActionInput(); originalOnActionInput();
return true; return true;
} }
}
}
return false; return false;
} }

View File

@ -130,23 +130,21 @@ export class FilterBar extends Phaser.GameObjects.Container {
* Move the leftmost dropdown to the left of the FilterBar instead of below it * Move the leftmost dropdown to the left of the FilterBar instead of below it
*/ */
offsetHybridFilters(): void { offsetHybridFilters(): void {
for (let i = 0; i < this.dropDowns.length; i++) { for (const dropDown of this.dropDowns) {
if (this.dropDowns[i].dropDownType === DropDownType.HYBRID) { if (dropDown.dropDownType === DropDownType.HYBRID) {
this.dropDowns[i].autoSize(); dropDown.autoSize();
this.dropDowns[i].x = -this.dropDowns[i].getWidth(); dropDown.x = -dropDown.getWidth();
this.dropDowns[i].y = 0; dropDown.y = 0;
} }
} }
} }
setCursor(cursor: number): void { setCursor(cursor: number): void {
if (this.lastCursor > -1) { if (this.lastCursor > -1 && this.dropDowns[this.lastCursor].visible) {
if (this.dropDowns[this.lastCursor].visible) {
this.dropDowns[this.lastCursor].setVisible(false); this.dropDowns[this.lastCursor].setVisible(false);
this.dropDowns[cursor].setVisible(true); this.dropDowns[cursor].setVisible(true);
this.dropDowns[cursor].resetCursor(); this.dropDowns[cursor].resetCursor();
} }
}
this.cursorObj.setPosition(this.labels[cursor].x - this.cursorOffset + 2, 6); this.cursorObj.setPosition(this.labels[cursor].x - this.cursorOffset + 2, 6);
this.lastCursor = cursor; this.lastCursor = cursor;

View File

@ -234,9 +234,9 @@ export class LoginFormUiHandler extends FormModalUiHandler {
const dataKeys = localStorageKeys.filter(ls => ls.indexOf(keyToFind) >= 0); const dataKeys = localStorageKeys.filter(ls => ls.indexOf(keyToFind) >= 0);
if (dataKeys.length > 0 && dataKeys.length <= 2) { if (dataKeys.length > 0 && dataKeys.length <= 2) {
const options: OptionSelectItem[] = []; const options: OptionSelectItem[] = [];
for (let i = 0; i < dataKeys.length; i++) { for (const key of dataKeys) {
options.push({ options.push({
label: dataKeys[i].replace(keyToFind, ""), label: key.replace(keyToFind, ""),
handler: () => { handler: () => {
globalScene.ui.revertMode(); globalScene.ui.revertMode();
this.infoContainer.disableInteractive(); this.infoContainer.disableInteractive();
@ -261,7 +261,7 @@ export class LoginFormUiHandler extends FormModalUiHandler {
} }
}); });
this.saveDownloadImage.on("pointerdown", () => { this.saveDownloadImage.on("pointerdown", async () => {
// find all data_ and sessionData keys, put them in a .txt file and download everything in a single zip // find all data_ and sessionData keys, put them in a .txt file and download everything in a single zip
const localStorageKeys = Object.keys(localStorage); // this gets the keys for localStorage const localStorageKeys = Object.keys(localStorage); // this gets the keys for localStorage
const keyToFind = "data_"; const keyToFind = "data_";
@ -270,20 +270,19 @@ export class LoginFormUiHandler extends FormModalUiHandler {
const sessionKeys = localStorageKeys.filter(ls => ls.indexOf(sessionKeyToFind) >= 0); const sessionKeys = localStorageKeys.filter(ls => ls.indexOf(sessionKeyToFind) >= 0);
if (dataKeys.length > 0 || sessionKeys.length > 0) { if (dataKeys.length > 0 || sessionKeys.length > 0) {
const zip = new JSZip(); const zip = new JSZip();
for (let i = 0; i < dataKeys.length; i++) { for (const dataKey of dataKeys) {
zip.file(dataKeys[i] + ".prsv", localStorage.getItem(dataKeys[i])!); zip.file(dataKey + ".prsv", localStorage.getItem(dataKey)!);
} }
for (let i = 0; i < sessionKeys.length; i++) { for (const sessionKey of sessionKeys) {
zip.file(sessionKeys[i] + ".prsv", localStorage.getItem(sessionKeys[i])!); zip.file(sessionKey + ".prsv", localStorage.getItem(sessionKey)!);
} }
zip.generateAsync({ type: "blob" }).then(content => { const content = await zip.generateAsync({ type: "blob" });
const url = URL.createObjectURL(content); const url = URL.createObjectURL(content);
const a = document.createElement("a"); const a = document.createElement("a");
a.href = url; a.href = url;
a.download = "pokerogue_saves.zip"; a.download = "pokerogue_saves.zip";
a.click(); a.click();
URL.revokeObjectURL(url); URL.revokeObjectURL(url);
});
} else { } else {
return onFail(this.ERR_NO_SAVES); return onFail(this.ERR_NO_SAVES);
} }

View File

@ -108,17 +108,17 @@ export abstract class MessageUiHandler extends AwaitableUiHandler {
const textWords = text.split(" "); const textWords = text.split(" ");
let lastLineCount = 1; let lastLineCount = 1;
let newText = ""; let newText = "";
for (let w = 0; w < textWords.length; w++) { for (const textWord of textWords) {
const nextWordText = newText ? `${newText} ${textWords[w]}` : textWords[w]; const nextWordText = newText ? `${newText} ${textWord}` : textWord;
if (textWords[w].includes("\n")) { if (textWord.includes("\n")) {
newText = nextWordText; newText = nextWordText;
lastLineCount++; lastLineCount++;
} else { } else {
const lineCount = this.message.runWordWrap(nextWordText).split(/\n/g).length; const lineCount = this.message.runWordWrap(nextWordText).split(/\n/g).length;
if (lineCount > lastLineCount) { if (lineCount > lastLineCount) {
lastLineCount = lineCount; lastLineCount = lineCount;
newText = `${newText}\n${textWords[w]}`; newText = `${newText}\n${textWord}`;
} else { } else {
newText = nextWordText; newText = nextWordText;
} }

View File

@ -480,13 +480,11 @@ export class ModifierSelectUiHandler extends AwaitableUiHandler {
} }
} else if (this.cursor) { } else if (this.cursor) {
success = this.setCursor(this.cursor - 1); success = this.setCursor(this.cursor - 1);
} else { } else if (this.rowCursor === 1 && this.options.length === 0) {
if (this.rowCursor === 1 && this.options.length === 0) {
success = false; success = false;
} else { } else {
success = this.setCursor(this.getRowItems(this.rowCursor) - 1); success = this.setCursor(this.getRowItems(this.rowCursor) - 1);
} }
}
break; break;
case Button.RIGHT: case Button.RIGHT:
if (!this.rowCursor) { if (!this.rowCursor) {
@ -514,13 +512,11 @@ export class ModifierSelectUiHandler extends AwaitableUiHandler {
} }
} else if (this.cursor < this.getRowItems(this.rowCursor) - 1) { } else if (this.cursor < this.getRowItems(this.rowCursor) - 1) {
success = this.setCursor(this.cursor + 1); success = this.setCursor(this.cursor + 1);
} else { } else if (this.rowCursor === 1 && this.options.length === 0) {
if (this.rowCursor === 1 && this.options.length === 0) {
success = this.setRowCursor(0); success = this.setRowCursor(0);
} else { } else {
success = this.setCursor(0); success = this.setCursor(0);
} }
}
break; break;
} }
} }

View File

@ -156,15 +156,13 @@ export class MysteryEncounterUiHandler extends UiHandler {
selected.optionMode === MysteryEncounterOptionMode.DISABLED_OR_SPECIAL)) selected.optionMode === MysteryEncounterOptionMode.DISABLED_OR_SPECIAL))
) { ) {
success = false; success = false;
} else { } else if (
if (
(globalScene.phaseManager.getCurrentPhase() as MysteryEncounterPhase).handleOptionSelect(selected, cursor) (globalScene.phaseManager.getCurrentPhase() as MysteryEncounterPhase).handleOptionSelect(selected, cursor)
) { ) {
success = true; success = true;
} else { } else {
ui.playError(); ui.playError();
} }
}
} else { } else {
// TODO: If we need to handle cancel option? Maybe default logic to leave/run from encounter idk // TODO: If we need to handle cancel option? Maybe default logic to leave/run from encounter idk
} }

View File

@ -614,11 +614,13 @@ export class PartyUiHandler extends MessageUiHandler {
// TODO: Might need to check here for when this.transferMode is active. // TODO: Might need to check here for when this.transferMode is active.
private processModifierTransferModeLeftRightInput(button: Button) { private processModifierTransferModeLeftRightInput(button: Button) {
if (!this.isItemManageMode()) {
return false;
}
let success = false; let success = false;
const option = this.options[this.optionsCursor]; const option = this.options[this.optionsCursor];
if (button === Button.LEFT) { if (button === Button.LEFT) {
/** Decrease quantity for the current item and update UI */ /** Decrease quantity for the current item and update UI */
if (this.isItemManageMode()) {
this.transferQuantities[option] = this.transferQuantities[option] =
this.transferQuantities[option] === 1 this.transferQuantities[option] === 1
? this.transferQuantitiesMax[option] ? this.transferQuantitiesMax[option]
@ -628,11 +630,8 @@ export class PartyUiHandler extends MessageUiHandler {
this.optionsCursor, this.optionsCursor,
); /** Place again the cursor at the same position. Necessary, otherwise the cursor disappears */ ); /** Place again the cursor at the same position. Necessary, otherwise the cursor disappears */
} }
}
if (button === Button.RIGHT) { if (button === Button.RIGHT) {
/** Increase quantity for the current item and update UI */ /** Increase quantity for the current item and update UI */
if (this.isItemManageMode()) {
this.transferQuantities[option] = this.transferQuantities[option] =
this.transferQuantities[option] === this.transferQuantitiesMax[option] this.transferQuantities[option] === this.transferQuantitiesMax[option]
? 1 ? 1
@ -642,7 +641,6 @@ export class PartyUiHandler extends MessageUiHandler {
this.optionsCursor, this.optionsCursor,
); /** Place again the cursor at the same position. Necessary, otherwise the cursor disappears */ ); /** Place again the cursor at the same position. Necessary, otherwise the cursor disappears */
} }
}
return success; return success;
} }
@ -930,11 +928,9 @@ export class PartyUiHandler extends MessageUiHandler {
return this.moveOptionCursor(button); return this.moveOptionCursor(button);
} }
if (button === Button.LEFT || button === Button.RIGHT) { if ((button === Button.LEFT || button === Button.RIGHT) && this.isItemManageMode()) {
if (this.isItemManageMode()) {
return this.processModifierTransferModeLeftRightInput(button); return this.processModifierTransferModeLeftRightInput(button);
} }
}
return false; return false;
} }
@ -1215,12 +1211,10 @@ export class PartyUiHandler extends MessageUiHandler {
isScroll = true; isScroll = true;
this.optionsScrollCursor++; this.optionsScrollCursor++;
} }
} else { } else if (!cursor && this.optionsScrollCursor) {
if (!cursor && this.optionsScrollCursor) {
isScroll = true; isScroll = true;
this.optionsScrollCursor--; this.optionsScrollCursor--;
} }
}
if (isScroll && this.optionsScrollCursor === 1) { if (isScroll && this.optionsScrollCursor === 1) {
this.optionsScrollCursor += isDown ? 1 : -1; this.optionsScrollCursor += isDown ? 1 : -1;
} }
@ -1573,13 +1567,11 @@ export class PartyUiHandler extends MessageUiHandler {
optionName = `${modifier.active ? i18next.t("partyUiHandler:DEACTIVATE") : i18next.t("partyUiHandler:ACTIVATE")} ${modifier.type.name}`; optionName = `${modifier.active ? i18next.t("partyUiHandler:DEACTIVATE") : i18next.t("partyUiHandler:ACTIVATE")} ${modifier.type.name}`;
} else if (option === PartyOption.UNPAUSE_EVOLUTION) { } else if (option === PartyOption.UNPAUSE_EVOLUTION) {
optionName = `${pokemon.pauseEvolutions ? i18next.t("partyUiHandler:UNPAUSE_EVOLUTION") : i18next.t("partyUiHandler:PAUSE_EVOLUTION")}`; optionName = `${pokemon.pauseEvolutions ? i18next.t("partyUiHandler:UNPAUSE_EVOLUTION") : i18next.t("partyUiHandler:PAUSE_EVOLUTION")}`;
} else { } else if (this.localizedOptions.includes(option)) {
if (this.localizedOptions.includes(option)) {
optionName = i18next.t(`partyUiHandler:${PartyOption[option]}`); optionName = i18next.t(`partyUiHandler:${PartyOption[option]}`);
} else { } else {
optionName = toTitleCase(PartyOption[option]); optionName = toTitleCase(PartyOption[option]);
} }
}
break; break;
} }
} }
@ -1654,11 +1646,11 @@ export class PartyUiHandler extends MessageUiHandler {
this.transferMode = false; this.transferMode = false;
this.transferAll = false; this.transferAll = false;
this.partySlots[this.transferCursor].setTransfer(false); this.partySlots[this.transferCursor].setTransfer(false);
for (let i = 0; i < this.partySlots.length; i++) { for (const partySlot of this.partySlots) {
this.partySlots[i].slotDescriptionLabel.setVisible(false); partySlot.slotDescriptionLabel.setVisible(false);
this.partySlots[i].slotHpBar.setVisible(true); partySlot.slotHpBar.setVisible(true);
this.partySlots[i].slotHpOverlay.setVisible(true); partySlot.slotHpOverlay.setVisible(true);
this.partySlots[i].slotHpText.setVisible(true); partySlot.slotHpText.setVisible(true);
} }
} }

View File

@ -1069,13 +1069,11 @@ export class PokedexPageUiHandler extends MessageUiHandler {
) { ) {
starterAttributes.female = !starterAttributes.female; starterAttributes.female = !starterAttributes.female;
} }
} else { } else if (caughtAttr & DexAttr.FEMALE) {
if (caughtAttr & DexAttr.FEMALE) {
starterAttributes.female = true; starterAttributes.female = true;
} else if (caughtAttr & DexAttr.MALE) { } else if (caughtAttr & DexAttr.MALE) {
starterAttributes.female = false; starterAttributes.female = false;
} }
}
return starterAttributes; return starterAttributes;
} }
@ -1839,11 +1837,9 @@ export class PokedexPageUiHandler extends MessageUiHandler {
if (this.isCaught() & DexAttr.VARIANT_2) { if (this.isCaught() & DexAttr.VARIANT_2) {
break; break;
} }
} else { } else if (this.isCaught() & DexAttr.VARIANT_3) {
if (this.isCaught() & DexAttr.VARIANT_3) {
break; break;
} }
}
} while (newVariant !== props.variant); } while (newVariant !== props.variant);
starterAttributes.variant = newVariant; // store the selected variant starterAttributes.variant = newVariant; // store the selected variant
@ -2362,11 +2358,9 @@ export class PokedexPageUiHandler extends MessageUiHandler {
const defaultDexAttr = this.getCurrentDexProps(species.speciesId); const defaultDexAttr = this.getCurrentDexProps(species.speciesId);
// Set default attributes if for some reason starterAttributes does not exist or attributes missing // Set default attributes if for some reason starterAttributes does not exist or attributes missing
const props: StarterAttributes = globalScene.gameData.getSpeciesDexAttrProps(species, defaultDexAttr); const props: StarterAttributes = globalScene.gameData.getSpeciesDexAttrProps(species, defaultDexAttr);
if (starterAttributes?.variant && !Number.isNaN(starterAttributes.variant)) { if (starterAttributes?.variant && !Number.isNaN(starterAttributes.variant) && props.shiny) {
if (props.shiny) {
props.variant = starterAttributes.variant as Variant; props.variant = starterAttributes.variant as Variant;
} }
}
props.form = starterAttributes?.form ?? props.form; props.form = starterAttributes?.form ?? props.form;
props.female = starterAttributes?.female ?? props.female; props.female = starterAttributes?.female ?? props.female;
@ -2778,18 +2772,16 @@ export class PokedexPageUiHandler extends MessageUiHandler {
props += DexAttr.SHINY; props += DexAttr.SHINY;
if (this.starterAttributes?.variant !== undefined) { if (this.starterAttributes?.variant !== undefined) {
props += BigInt(Math.pow(2, this.starterAttributes?.variant)) * DexAttr.DEFAULT_VARIANT; props += BigInt(Math.pow(2, this.starterAttributes?.variant)) * DexAttr.DEFAULT_VARIANT;
} else { /* This chunk calculates the correct variant if there's no starter preferences for it.
/* This calculates the correct variant if there's no starter preferences for it.
* This gets the highest tier variant that you've caught and adds it to the temp props * This gets the highest tier variant that you've caught and adds it to the temp props
*/ */
if ((caughtAttr & DexAttr.VARIANT_3) > 0) { } else if ((caughtAttr & DexAttr.VARIANT_3) > 0) {
props += DexAttr.VARIANT_3; props += DexAttr.VARIANT_3;
} else if ((caughtAttr & DexAttr.VARIANT_2) > 0) { } else if ((caughtAttr & DexAttr.VARIANT_2) > 0) {
props += DexAttr.VARIANT_2; props += DexAttr.VARIANT_2;
} else { } else {
props += DexAttr.DEFAULT_VARIANT; props += DexAttr.DEFAULT_VARIANT;
} }
}
} else { } else {
props += DexAttr.NON_SHINY; props += DexAttr.NON_SHINY;
props += DexAttr.DEFAULT_VARIANT; // we add the default variant here because non shiny versions are listed as default variant props += DexAttr.DEFAULT_VARIANT; // we add the default variant here because non shiny versions are listed as default variant

View File

@ -709,12 +709,13 @@ export class PokedexUiHandler extends MessageUiHandler {
} }
} }
if (starterAttributes.female !== undefined) { if (
if (!(starterAttributes.female ? caughtAttr & DexAttr.FEMALE : caughtAttr & DexAttr.MALE)) { starterAttributes.female !== undefined &&
!(starterAttributes.female ? caughtAttr & DexAttr.FEMALE : caughtAttr & DexAttr.MALE)
) {
// requested gender wasn't unlocked, purging setting // requested gender wasn't unlocked, purging setting
starterAttributes.female = undefined; starterAttributes.female = undefined;
} }
}
if (starterAttributes.ability !== undefined) { if (starterAttributes.ability !== undefined) {
const speciesHasSingleAbility = species.ability2 === species.ability1; const speciesHasSingleAbility = species.ability2 === species.ability1;
@ -1187,8 +1188,7 @@ export class PokedexUiHandler extends MessageUiHandler {
break; break;
} }
} }
} else { } else if (button === Button.ACTION) {
if (button === Button.ACTION) {
ui.setOverlayMode(UiMode.POKEDEX_PAGE, this.lastSpecies, null, this.filteredIndices); ui.setOverlayMode(UiMode.POKEDEX_PAGE, this.lastSpecies, null, this.filteredIndices);
success = true; success = true;
} else { } else {
@ -1261,7 +1261,6 @@ export class PokedexUiHandler extends MessageUiHandler {
} }
} }
} }
}
if (success) { if (success) {
ui.playSelect(); ui.playSelect();
@ -1453,14 +1452,12 @@ export class PokedexUiHandler extends MessageUiHandler {
} else { } else {
data.passive1 = false; data.passive1 = false;
} }
} else { } else if (starterData.passiveAttr > 0) {
if (starterData.passiveAttr > 0) {
data.passive2 = true; data.passive2 = true;
} else { } else {
data.passive2 = false; data.passive2 = false;
} }
} }
}
// Gen filter // Gen filter
const fitsGen = this.filterBar.getVals(DropDownColumn.GEN).includes(species.generation); const fitsGen = this.filterBar.getVals(DropDownColumn.GEN).includes(species.generation);
@ -2334,18 +2331,16 @@ export class PokedexUiHandler extends MessageUiHandler {
props += DexAttr.SHINY; props += DexAttr.SHINY;
if (this.starterPreferences[speciesId]?.variant !== undefined) { if (this.starterPreferences[speciesId]?.variant !== undefined) {
props += BigInt(Math.pow(2, this.starterPreferences[speciesId]?.variant)) * DexAttr.DEFAULT_VARIANT; props += BigInt(Math.pow(2, this.starterPreferences[speciesId]?.variant)) * DexAttr.DEFAULT_VARIANT;
} else { } else if ((caughtAttr & DexAttr.VARIANT_3) > 0) {
/* This calculates the correct variant if there's no starter preferences for it. /* This calculates the correct variant if there's no starter preferences for it.
* This gets the highest tier variant that you've caught and adds it to the temp props * This gets the highest tier variant that you've caught and adds it to the temp props
*/ */
if ((caughtAttr & DexAttr.VARIANT_3) > 0) {
props += DexAttr.VARIANT_3; props += DexAttr.VARIANT_3;
} else if ((caughtAttr & DexAttr.VARIANT_2) > 0) { } else if ((caughtAttr & DexAttr.VARIANT_2) > 0) {
props += DexAttr.VARIANT_2; props += DexAttr.VARIANT_2;
} else { } else {
props += DexAttr.DEFAULT_VARIANT; props += DexAttr.DEFAULT_VARIANT;
} }
}
} else { } else {
props += DexAttr.NON_SHINY; props += DexAttr.NON_SHINY;
props += DexAttr.DEFAULT_VARIANT; // we add the default variant here because non shiny versions are listed as default variant props += DexAttr.DEFAULT_VARIANT; // we add the default variant here because non shiny versions are listed as default variant

View File

@ -683,18 +683,20 @@ export class RunInfoUiHandler extends UiHandler {
*/ */
private challengeParser(): string[] { private challengeParser(): string[] {
const rules: string[] = []; const rules: string[] = [];
for (let i = 0; i < this.runInfo.challenges.length; i++) { for (const challenge of this.runInfo.challenges) {
if (this.runInfo.challenges[i].value !== 0) { if (challenge.value === 0) {
switch (this.runInfo.challenges[i].id) { continue;
}
switch (challenge.id) {
case Challenges.SINGLE_GENERATION: case Challenges.SINGLE_GENERATION:
rules.push(i18next.t(`runHistory:challengeMonoGen${this.runInfo.challenges[i].value}`)); rules.push(i18next.t(`runHistory:challengeMonoGen${challenge.value}`));
break; break;
case Challenges.SINGLE_TYPE: { case Challenges.SINGLE_TYPE: {
const typeRule = PokemonType[this.runInfo.challenges[i].value - 1]; const typeRule = PokemonType[challenge.value - 1];
const typeTextColor = `[color=${TypeColor[typeRule]}]`; const typeTextColor = `[color=${TypeColor[typeRule]}]`;
const typeShadowColor = `[shadow=${TypeShadow[typeRule]}]`; const typeShadowColor = `[shadow=${TypeShadow[typeRule]}]`;
const typeText = const typeText =
typeTextColor + typeShadowColor + i18next.t(`pokemonInfo:Type.${typeRule}`)! + "[/color]" + "[/shadow]"; typeTextColor + typeShadowColor + i18next.t(`pokemonInfo:Type.${typeRule}`)! + "[/color][/shadow]";
rules.push(typeText); rules.push(typeText);
break; break;
} }
@ -702,7 +704,7 @@ export class RunInfoUiHandler extends UiHandler {
rules.push(i18next.t("challenges:inverseBattle.shortName")); rules.push(i18next.t("challenges:inverseBattle.shortName"));
break; break;
default: { default: {
const localizationKey = Challenges[this.runInfo.challenges[i].id] const localizationKey = Challenges[challenge.id]
.split("_") .split("_")
.map((f, i) => (i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase())) .map((f, i) => (i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase()))
.join(""); .join("");
@ -711,7 +713,6 @@ export class RunInfoUiHandler extends UiHandler {
} }
} }
} }
}
return rules; return rules;
} }

View File

@ -1217,12 +1217,13 @@ export class StarterSelectUiHandler extends MessageUiHandler {
} }
} }
if (starterAttributes.female !== undefined) { if (
if (!(starterAttributes.female ? caughtAttr & DexAttr.FEMALE : caughtAttr & DexAttr.MALE)) { starterAttributes.female !== undefined &&
!(starterAttributes.female ? caughtAttr & DexAttr.FEMALE : caughtAttr & DexAttr.MALE)
) {
// requested gender wasn't unlocked, purging setting // requested gender wasn't unlocked, purging setting
starterAttributes.female = undefined; starterAttributes.female = undefined;
} }
}
if (starterAttributes.ability !== undefined) { if (starterAttributes.ability !== undefined) {
const speciesHasSingleAbility = species.ability2 === species.ability1; const speciesHasSingleAbility = species.ability2 === species.ability1;
@ -2342,12 +2343,10 @@ export class StarterSelectUiHandler extends MessageUiHandler {
// TODO: is this bang correct? // TODO: is this bang correct?
break; break;
} }
} else { } else if (this.speciesStarterDexEntry!.caughtAttr & DexAttr.VARIANT_3) {
if (this.speciesStarterDexEntry!.caughtAttr & DexAttr.VARIANT_3) {
// TODO: is this bang correct? // TODO: is this bang correct?
break; break;
} }
}
} while (newVariant !== props.variant); } while (newVariant !== props.variant);
starterAttributes.variant = newVariant; // store the selected variant starterAttributes.variant = newVariant; // store the selected variant
if (this.speciesStarterDexEntry!.caughtAttr & DexAttr.NON_SHINY && newVariant <= props.variant) { if (this.speciesStarterDexEntry!.caughtAttr & DexAttr.NON_SHINY && newVariant <= props.variant) {
@ -2422,11 +2421,9 @@ export class StarterSelectUiHandler extends MessageUiHandler {
newAbilityIndex = (newAbilityIndex + 1) % abilityCount; newAbilityIndex = (newAbilityIndex + 1) % abilityCount;
} }
break; break;
} else { } else if (abilityAttr & AbilityAttr.ABILITY_HIDDEN) {
if (abilityAttr & AbilityAttr.ABILITY_HIDDEN) {
break; break;
} }
}
} while (newAbilityIndex !== this.abilityCursor); } while (newAbilityIndex !== this.abilityCursor);
starterAttributes.ability = newAbilityIndex; // store the selected ability starterAttributes.ability = newAbilityIndex; // store the selected ability
@ -2972,8 +2969,7 @@ export class StarterSelectUiHandler extends MessageUiHandler {
} }
// this updates icons for previously saved pokemon // this updates icons for previously saved pokemon
for (let i = 0; i < this.validStarterContainers.length; i++) { for (const currentFilteredContainer of this.validStarterContainers) {
const currentFilteredContainer = this.validStarterContainers[i];
const starterSprite = currentFilteredContainer.icon as Phaser.GameObjects.Sprite; const starterSprite = currentFilteredContainer.icon as Phaser.GameObjects.Sprite;
const currentDexAttr = this.getCurrentDexProps(currentFilteredContainer.species.speciesId); const currentDexAttr = this.getCurrentDexProps(currentFilteredContainer.species.speciesId);
@ -3562,11 +3558,9 @@ export class StarterSelectUiHandler extends MessageUiHandler {
// load default nature from stater save data, if set // load default nature from stater save data, if set
const defaultNature = starterAttributes?.nature || globalScene.gameData.getSpeciesDefaultNature(species); const defaultNature = starterAttributes?.nature || globalScene.gameData.getSpeciesDefaultNature(species);
props = globalScene.gameData.getSpeciesDexAttrProps(species, defaultDexAttr); props = globalScene.gameData.getSpeciesDexAttrProps(species, defaultDexAttr);
if (starterAttributes?.variant && !Number.isNaN(starterAttributes.variant)) { if (starterAttributes?.variant && !Number.isNaN(starterAttributes.variant) && props.shiny) {
if (props.shiny) {
props.variant = starterAttributes.variant as Variant; props.variant = starterAttributes.variant as Variant;
} }
}
props.formIndex = starterAttributes?.form ?? props.formIndex; props.formIndex = starterAttributes?.form ?? props.formIndex;
props.female = starterAttributes?.female ?? props.female; props.female = starterAttributes?.female ?? props.female;
@ -4350,13 +4344,13 @@ export class StarterSelectUiHandler extends MessageUiHandler {
return true; return true;
} }
/* This block checks to see if your party is valid /**
* This block checks to see if your party is valid
* It checks each pokemon against the challenge - noting that due to monotype challenges it needs to check the pokemon while ignoring their evolutions/form change items * It checks each pokemon against the challenge - noting that due to monotype challenges it needs to check the pokemon while ignoring their evolutions/form change items
*/ */
isPartyValid(): boolean { isPartyValid(): boolean {
let canStart = false; let canStart = false;
for (let s = 0; s < this.starterSpecies.length; s++) { for (const species of this.starterSpecies) {
const species = this.starterSpecies[s];
const isValidForChallenge = checkStarterValidForChallenge( const isValidForChallenge = checkStarterValidForChallenge(
species, species,
globalScene.gameData.getSpeciesDexAttrProps(species, this.getCurrentDexProps(species.speciesId)), globalScene.gameData.getSpeciesDexAttrProps(species, this.getCurrentDexProps(species.speciesId)),
@ -4400,18 +4394,16 @@ export class StarterSelectUiHandler extends MessageUiHandler {
props += DexAttr.SHINY; props += DexAttr.SHINY;
if (this.starterPreferences[speciesId]?.variant !== undefined) { if (this.starterPreferences[speciesId]?.variant !== undefined) {
props += BigInt(Math.pow(2, this.starterPreferences[speciesId]?.variant)) * DexAttr.DEFAULT_VARIANT; props += BigInt(Math.pow(2, this.starterPreferences[speciesId]?.variant)) * DexAttr.DEFAULT_VARIANT;
} else { } else if ((caughtAttr & DexAttr.VARIANT_3) > 0) {
/* This calculates the correct variant if there's no starter preferences for it. /* This calculates the correct variant if there's no starter preferences for it.
* This gets the highest tier variant that you've caught and adds it to the temp props * This gets the highest tier variant that you've caught and adds it to the temp props
*/ */
if ((caughtAttr & DexAttr.VARIANT_3) > 0) {
props += DexAttr.VARIANT_3; props += DexAttr.VARIANT_3;
} else if ((caughtAttr & DexAttr.VARIANT_2) > 0) { } else if ((caughtAttr & DexAttr.VARIANT_2) > 0) {
props += DexAttr.VARIANT_2; props += DexAttr.VARIANT_2;
} else { } else {
props += DexAttr.DEFAULT_VARIANT; props += DexAttr.DEFAULT_VARIANT;
} }
}
} else { } else {
props += DexAttr.NON_SHINY; props += DexAttr.NON_SHINY;
props += DexAttr.DEFAULT_VARIANT; // we add the default variant here because non shiny versions are listed as default variant props += DexAttr.DEFAULT_VARIANT; // we add the default variant here because non shiny versions are listed as default variant

View File

@ -515,8 +515,7 @@ export class SummaryUiHandler extends UiHandler {
if (this.pokemon && this.moveCursor < this.pokemon.moveset.length) { if (this.pokemon && this.moveCursor < this.pokemon.moveset.length) {
if (this.summaryUiMode === SummaryUiMode.LEARN_MOVE) { if (this.summaryUiMode === SummaryUiMode.LEARN_MOVE) {
this.moveSelectFunction?.(this.moveCursor); this.moveSelectFunction?.(this.moveCursor);
} else { } else if (this.selectedMoveIndex === -1) {
if (this.selectedMoveIndex === -1) {
this.selectedMoveIndex = this.moveCursor; this.selectedMoveIndex = this.moveCursor;
this.setCursor(this.moveCursor); this.setCursor(this.moveCursor);
} else { } else {
@ -543,7 +542,6 @@ export class SummaryUiHandler extends UiHandler {
this.selectedMoveCursorObj = null; this.selectedMoveCursorObj = null;
} }
} }
}
success = true; success = true;
} else if (this.moveCursor === 4) { } else if (this.moveCursor === 4) {
return this.processInput(Button.CANCEL); return this.processInput(Button.CANCEL);
@ -575,8 +573,7 @@ export class SummaryUiHandler extends UiHandler {
break; break;
} }
} }
} else { } else if (button === Button.ACTION) {
if (button === Button.ACTION) {
if (this.cursor === Page.MOVES) { if (this.cursor === Page.MOVES) {
this.showMoveSelect(); this.showMoveSelect();
success = true; success = true;
@ -648,7 +645,6 @@ export class SummaryUiHandler extends UiHandler {
break; break;
} }
} }
}
if (success) { if (success) {
ui.playSelect(); ui.playSelect();

View File

@ -70,12 +70,13 @@ export class TargetSelectUiHandler extends UiHandler {
* @param user the Pokemon using the move * @param user the Pokemon using the move
*/ */
resetCursor(cursorN: number, user: Pokemon): void { resetCursor(cursorN: number, user: Pokemon): void {
if (!isNullOrUndefined(cursorN)) { if (
if ([BattlerIndex.PLAYER, BattlerIndex.PLAYER_2].includes(cursorN) || user.tempSummonData.waveTurnCount === 1) { !isNullOrUndefined(cursorN) &&
([BattlerIndex.PLAYER, BattlerIndex.PLAYER_2].includes(cursorN) || user.tempSummonData.waveTurnCount === 1)
) {
// Reset cursor on the first turn of a fight or if an ally was targeted last turn // Reset cursor on the first turn of a fight or if an ally was targeted last turn
cursorN = -1; cursorN = -1;
} }
}
this.setCursor(this.targets.includes(cursorN) ? cursorN : this.targets[0]); this.setCursor(this.targets.includes(cursorN) ? cursorN : this.targets[0]);
} }
@ -92,11 +93,12 @@ export class TargetSelectUiHandler extends UiHandler {
if (isNullOrUndefined(this.cursor0) || this.cursor0 !== this.cursor) { if (isNullOrUndefined(this.cursor0) || this.cursor0 !== this.cursor) {
this.cursor0 = this.cursor; this.cursor0 = this.cursor;
} }
} else if (this.fieldIndex === BattlerIndex.PLAYER_2) { } else if (
if (isNullOrUndefined(this.cursor1) || this.cursor1 !== this.cursor) { this.fieldIndex === BattlerIndex.PLAYER_2 &&
(isNullOrUndefined(this.cursor1) || this.cursor1 !== this.cursor)
) {
this.cursor1 = this.cursor; this.cursor1 = this.cursor;
} }
}
} else if (this.isMultipleTargets) { } else if (this.isMultipleTargets) {
success = false; success = false;
} else { } else {

View File

@ -117,11 +117,9 @@ export function updateWindowType(windowTypeIndex: number): void {
} else if (object.texture?.key === "namebox") { } else if (object.texture?.key === "namebox") {
themedObjects.push(object); themedObjects.push(object);
} }
} else if (object instanceof Phaser.GameObjects.Sprite) { } else if (object instanceof Phaser.GameObjects.Sprite && object.texture?.key === "bg") {
if (object.texture?.key === "bg") {
themedObjects.push(object); themedObjects.push(object);
} }
}
}; };
traverse(globalScene); traverse(globalScene);

View File

@ -374,11 +374,13 @@ export class UI extends Phaser.GameObjects.Container {
} }
shouldSkipDialogue(i18nKey: string): boolean { shouldSkipDialogue(i18nKey: string): boolean {
if (i18next.exists(i18nKey)) { if (
if (globalScene.skipSeenDialogues && globalScene.gameData.getSeenDialogues()[i18nKey] === true) { i18next.exists(i18nKey) &&
globalScene.skipSeenDialogues &&
globalScene.gameData.getSeenDialogues()[i18nKey] === true
) {
return true; return true;
} }
}
return false; return false;
} }

View File

@ -1,3 +1,5 @@
// biome-ignore-all lint/nursery/useUnifiedTypeSignature: Rule does not allow stuff with JSDoc comments
import type { FixedBattleConfig } from "#app/battle"; import type { FixedBattleConfig } from "#app/battle";
import { globalScene } from "#app/global-scene"; import { globalScene } from "#app/global-scene";
import { pokemonEvolutions } from "#balance/pokemon-evolutions"; import { pokemonEvolutions } from "#balance/pokemon-evolutions";

View File

@ -23,13 +23,11 @@ export function getCookie(cName: string): string {
} }
const name = `${cName}=`; const name = `${cName}=`;
const ca = document.cookie.split(";"); const ca = document.cookie.split(";");
for (let i = 0; i < ca.length; i++) { // Check all cookies in the document and see if any of them match, grabbing the first one whose value lines up
let c = ca[i]; for (const c of ca) {
while (c.charAt(0) === " ") { const cTrimmed = c.trim();
c = c.substring(1); if (cTrimmed.startsWith(name)) {
} return c.slice(name.length, c.length);
if (c.indexOf(name) === 0) {
return c.substring(name.length, c.length);
} }
} }
return ""; return "";

View File

@ -33,8 +33,8 @@ describe("Abilities - POWER CONSTRUCT", () => {
}); });
test("check if fainted 50% Power Construct Pokemon switches to base form on arena reset", async () => { test("check if fainted 50% Power Construct Pokemon switches to base form on arena reset", async () => {
const baseForm = 2, const baseForm = 2;
completeForm = 4; const completeForm = 4;
game.override.startingWave(4).starterForms({ game.override.startingWave(4).starterForms({
[SpeciesId.ZYGARDE]: completeForm, [SpeciesId.ZYGARDE]: completeForm,
}); });
@ -59,8 +59,8 @@ describe("Abilities - POWER CONSTRUCT", () => {
}); });
test("check if fainted 10% Power Construct Pokemon switches to base form on arena reset", async () => { test("check if fainted 10% Power Construct Pokemon switches to base form on arena reset", async () => {
const baseForm = 3, const baseForm = 3;
completeForm = 5; const completeForm = 5;
game.override.startingWave(4).starterForms({ game.override.startingWave(4).starterForms({
[SpeciesId.ZYGARDE]: completeForm, [SpeciesId.ZYGARDE]: completeForm,
}); });

View File

@ -29,8 +29,8 @@ describe("Abilities - SCHOOLING", () => {
}); });
test("check if fainted pokemon switches to base form on arena reset", async () => { test("check if fainted pokemon switches to base form on arena reset", async () => {
const soloForm = 0, const soloForm = 0;
schoolForm = 1; const schoolForm = 1;
game.override.startingWave(4).starterForms({ game.override.startingWave(4).starterForms({
[SpeciesId.WISHIWASHI]: schoolForm, [SpeciesId.WISHIWASHI]: schoolForm,
}); });

View File

@ -34,8 +34,8 @@ describe("Abilities - SHIELDS DOWN", () => {
}); });
test("check if fainted pokemon switched to base form on arena reset", async () => { test("check if fainted pokemon switched to base form on arena reset", async () => {
const meteorForm = 0, const meteorForm = 0;
coreForm = 7; const coreForm = 7;
game.override.startingWave(4).starterForms({ game.override.startingWave(4).starterForms({
[SpeciesId.MINIOR]: coreForm, [SpeciesId.MINIOR]: coreForm,
}); });

View File

@ -76,9 +76,9 @@ describe("Escape chance calculations", () => {
{ pokemonSpeedRatio: 2, escapeAttempts: 3, expectedEscapeChance: 80 }, { pokemonSpeedRatio: 2, escapeAttempts: 3, expectedEscapeChance: 80 },
]; ];
for (let i = 0; i < escapeChances.length; i++) { for (const check of escapeChances) {
// sets the number of escape attempts to the required amount // set the number of escape attempts to the required amount
game.scene.currentBattle.escapeAttempts = escapeChances[i].escapeAttempts; game.scene.currentBattle.escapeAttempts = check.escapeAttempts;
// set playerPokemon's speed to a multiple of the enemySpeed // set playerPokemon's speed to a multiple of the enemySpeed
vi.spyOn(playerPokemon[0], "stats", "get").mockReturnValue([ vi.spyOn(playerPokemon[0], "stats", "get").mockReturnValue([
20, 20,
@ -86,10 +86,10 @@ describe("Escape chance calculations", () => {
20, 20,
20, 20,
20, 20,
escapeChances[i].pokemonSpeedRatio * enemySpeed, check.pokemonSpeedRatio * enemySpeed,
]); ]);
const chance = phase.calculateEscapeChance(game.scene.currentBattle.escapeAttempts); const chance = phase.calculateEscapeChance(game.scene.currentBattle.escapeAttempts);
expect(chance).toBe(escapeChances[i].expectedEscapeChance); expect(chance).toBe(check.expectedEscapeChance);
} }
}); });
@ -146,9 +146,9 @@ describe("Escape chance calculations", () => {
{ pokemonSpeedRatio: 2, escapeAttempts: 10, expectedEscapeChance: 95 }, { pokemonSpeedRatio: 2, escapeAttempts: 10, expectedEscapeChance: 95 },
]; ];
for (let i = 0; i < escapeChances.length; i++) { for (const check of escapeChances) {
// sets the number of escape attempts to the required amount // sets the number of escape attempts to the required amount
game.scene.currentBattle.escapeAttempts = escapeChances[i].escapeAttempts; game.scene.currentBattle.escapeAttempts = check.escapeAttempts;
// set the first playerPokemon's speed to a multiple of the enemySpeed // set the first playerPokemon's speed to a multiple of the enemySpeed
vi.spyOn(playerPokemon[0], "stats", "get").mockReturnValue([ vi.spyOn(playerPokemon[0], "stats", "get").mockReturnValue([
20, 20,
@ -156,7 +156,7 @@ describe("Escape chance calculations", () => {
20, 20,
20, 20,
20, 20,
Math.floor(escapeChances[i].pokemonSpeedRatio * totalEnemySpeed * playerASpeedPercentage), Math.floor(check.pokemonSpeedRatio * totalEnemySpeed * playerASpeedPercentage),
]); ]);
// set the second playerPokemon's speed to the remaining value of speed // set the second playerPokemon's speed to the remaining value of speed
vi.spyOn(playerPokemon[1], "stats", "get").mockReturnValue([ vi.spyOn(playerPokemon[1], "stats", "get").mockReturnValue([
@ -165,15 +165,13 @@ describe("Escape chance calculations", () => {
20, 20,
20, 20,
20, 20,
escapeChances[i].pokemonSpeedRatio * totalEnemySpeed - playerPokemon[0].stats[5], check.pokemonSpeedRatio * totalEnemySpeed - playerPokemon[0].stats[5],
]); ]);
const chance = phase.calculateEscapeChance(game.scene.currentBattle.escapeAttempts); const chance = phase.calculateEscapeChance(game.scene.currentBattle.escapeAttempts);
// checks to make sure the escape values are the same // checks to make sure the escape values are the same
expect(chance).toBe(escapeChances[i].expectedEscapeChance); expect(chance).toBe(check.expectedEscapeChance);
// checks to make sure the sum of the player's speed for all pokemon is equal to the appropriate ratio of the total enemy speed // checks to make sure the sum of the player's speed for all pokemon is equal to the appropriate ratio of the total enemy speed
expect(playerPokemon[0].stats[5] + playerPokemon[1].stats[5]).toBe( expect(playerPokemon[0].stats[5] + playerPokemon[1].stats[5]).toBe(check.pokemonSpeedRatio * totalEnemySpeed);
escapeChances[i].pokemonSpeedRatio * totalEnemySpeed,
);
} }
}); });
@ -238,9 +236,9 @@ describe("Escape chance calculations", () => {
{ pokemonSpeedRatio: 6.1, escapeAttempts: 3, expectedEscapeChance: 25 }, { pokemonSpeedRatio: 6.1, escapeAttempts: 3, expectedEscapeChance: 25 },
]; ];
for (let i = 0; i < escapeChances.length; i++) { for (const check of escapeChances) {
// sets the number of escape attempts to the required amount // sets the number of escape attempts to the required amount
game.scene.currentBattle.escapeAttempts = escapeChances[i].escapeAttempts; game.scene.currentBattle.escapeAttempts = check.escapeAttempts;
// set playerPokemon's speed to a multiple of the enemySpeed // set playerPokemon's speed to a multiple of the enemySpeed
vi.spyOn(playerPokemon[0], "stats", "get").mockReturnValue([ vi.spyOn(playerPokemon[0], "stats", "get").mockReturnValue([
20, 20,
@ -248,10 +246,10 @@ describe("Escape chance calculations", () => {
20, 20,
20, 20,
20, 20,
escapeChances[i].pokemonSpeedRatio * enemySpeed, check.pokemonSpeedRatio * enemySpeed,
]); ]);
const chance = phase.calculateEscapeChance(game.scene.currentBattle.escapeAttempts); const chance = phase.calculateEscapeChance(game.scene.currentBattle.escapeAttempts);
expect(chance).toBe(escapeChances[i].expectedEscapeChance); expect(chance).toBe(check.expectedEscapeChance);
} }
}); });
@ -321,9 +319,9 @@ describe("Escape chance calculations", () => {
{ pokemonSpeedRatio: 5.2, escapeAttempts: 2, expectedEscapeChance: 25 }, { pokemonSpeedRatio: 5.2, escapeAttempts: 2, expectedEscapeChance: 25 },
]; ];
for (let i = 0; i < escapeChances.length; i++) { for (const check of escapeChances) {
// sets the number of escape attempts to the required amount // sets the number of escape attempts to the required amount
game.scene.currentBattle.escapeAttempts = escapeChances[i].escapeAttempts; game.scene.currentBattle.escapeAttempts = check.escapeAttempts;
// set the first playerPokemon's speed to a multiple of the enemySpeed // set the first playerPokemon's speed to a multiple of the enemySpeed
vi.spyOn(playerPokemon[0], "stats", "get").mockReturnValue([ vi.spyOn(playerPokemon[0], "stats", "get").mockReturnValue([
20, 20,
@ -331,7 +329,7 @@ describe("Escape chance calculations", () => {
20, 20,
20, 20,
20, 20,
Math.floor(escapeChances[i].pokemonSpeedRatio * totalEnemySpeed * playerASpeedPercentage), Math.floor(check.pokemonSpeedRatio * totalEnemySpeed * playerASpeedPercentage),
]); ]);
// set the second playerPokemon's speed to the remaining value of speed // set the second playerPokemon's speed to the remaining value of speed
vi.spyOn(playerPokemon[1], "stats", "get").mockReturnValue([ vi.spyOn(playerPokemon[1], "stats", "get").mockReturnValue([
@ -340,15 +338,13 @@ describe("Escape chance calculations", () => {
20, 20,
20, 20,
20, 20,
escapeChances[i].pokemonSpeedRatio * totalEnemySpeed - playerPokemon[0].stats[5], check.pokemonSpeedRatio * totalEnemySpeed - playerPokemon[0].stats[5],
]); ]);
const chance = phase.calculateEscapeChance(game.scene.currentBattle.escapeAttempts); const chance = phase.calculateEscapeChance(game.scene.currentBattle.escapeAttempts);
// checks to make sure the escape values are the same // checks to make sure the escape values are the same
expect(chance).toBe(escapeChances[i].expectedEscapeChance); expect(chance).toBe(check.expectedEscapeChance);
// checks to make sure the sum of the player's speed for all pokemon is equal to the appropriate ratio of the total enemy speed // checks to make sure the sum of the player's speed for all pokemon is equal to the appropriate ratio of the total enemy speed
expect(playerPokemon[0].stats[5] + playerPokemon[1].stats[5]).toBe( expect(playerPokemon[0].stats[5] + playerPokemon[1].stats[5]).toBe(check.pokemonSpeedRatio * totalEnemySpeed);
escapeChances[i].pokemonSpeedRatio * totalEnemySpeed,
);
} }
}); });
}); });

View File

@ -139,8 +139,7 @@ const getMockedMoveDamage = (defender: Pokemon, attacker: Pokemon, move: Move) =
const multiplierHolder = new NumberHolder(1); const multiplierHolder = new NumberHolder(1);
const side = defender.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY; const side = defender.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY;
if (globalScene.arena.getTagOnSide(ArenaTagType.AURORA_VEIL, side)) { if (globalScene.arena.getTagOnSide(ArenaTagType.AURORA_VEIL, side) && move.getAttrs("CritOnlyAttr").length === 0) {
if (move.getAttrs("CritOnlyAttr").length === 0) {
globalScene.arena.applyTagsForSide( globalScene.arena.applyTagsForSide(
ArenaTagType.AURORA_VEIL, ArenaTagType.AURORA_VEIL,
side, side,
@ -150,7 +149,6 @@ const getMockedMoveDamage = (defender: Pokemon, attacker: Pokemon, move: Move) =
multiplierHolder, multiplierHolder,
); );
} }
}
return move.power * multiplierHolder.value; return move.power * multiplierHolder.value;
}; };

View File

@ -127,8 +127,7 @@ const getMockedMoveDamage = (defender: Pokemon, attacker: Pokemon, move: Move) =
const multiplierHolder = new NumberHolder(1); const multiplierHolder = new NumberHolder(1);
const side = defender.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY; const side = defender.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY;
if (globalScene.arena.getTagOnSide(ArenaTagType.LIGHT_SCREEN, side)) { if (globalScene.arena.getTagOnSide(ArenaTagType.LIGHT_SCREEN, side) && move.getAttrs("CritOnlyAttr").length === 0) {
if (move.getAttrs("CritOnlyAttr").length === 0) {
globalScene.arena.applyTagsForSide( globalScene.arena.applyTagsForSide(
ArenaTagType.LIGHT_SCREEN, ArenaTagType.LIGHT_SCREEN,
side, side,
@ -138,7 +137,6 @@ const getMockedMoveDamage = (defender: Pokemon, attacker: Pokemon, move: Move) =
multiplierHolder, multiplierHolder,
); );
} }
}
return move.power * multiplierHolder.value; return move.power * multiplierHolder.value;
}; };

View File

@ -143,11 +143,9 @@ const getMockedMoveDamage = (defender: Pokemon, attacker: Pokemon, move: Move) =
const multiplierHolder = new NumberHolder(1); const multiplierHolder = new NumberHolder(1);
const side = defender.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY; const side = defender.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY;
if (globalScene.arena.getTagOnSide(ArenaTagType.REFLECT, side)) { if (globalScene.arena.getTagOnSide(ArenaTagType.REFLECT, side) && move.getAttrs("CritOnlyAttr").length === 0) {
if (move.getAttrs("CritOnlyAttr").length === 0) {
globalScene.arena.applyTagsForSide(ArenaTagType.REFLECT, side, false, attacker, move.category, multiplierHolder); globalScene.arena.applyTagsForSide(ArenaTagType.REFLECT, side, false, attacker, move.category, multiplierHolder);
} }
}
return move.power * multiplierHolder.value; return move.power * multiplierHolder.value;
}; };

View File

@ -18,8 +18,10 @@ import { GameManagerHelper } from "#test/test-utils/helpers/game-manager-helper"
export class ClassicModeHelper extends GameManagerHelper { export class ClassicModeHelper extends GameManagerHelper {
/** /**
* Runs the classic game to the summon phase. * Runs the classic game to the summon phase.
* @param species - An array of {@linkcode Species} to summon. * @param species - An array of {@linkcode SpeciesId} to summon.
* @returns A promise that resolves when the summon phase is reached. * @returns A promise that resolves when the summon phase is reached.
* @remarks
* Do not use this when {@linkcode startBattle} can be used!
*/ */
async runToSummon(species: SpeciesId[]): Promise<void>; async runToSummon(species: SpeciesId[]): Promise<void>;
/** /**
@ -29,6 +31,7 @@ export class ClassicModeHelper extends GameManagerHelper {
* @returns A promise that resolves when the summon phase is reached. * @returns A promise that resolves when the summon phase is reached.
* @deprecated - Specifying the starters helps prevent inconsistencies from internal RNG changes. * @deprecated - Specifying the starters helps prevent inconsistencies from internal RNG changes.
*/ */
// biome-ignore lint/nursery/useUnifiedTypeSignature: Marks the overload for deprecation
async runToSummon(): Promise<void>; async runToSummon(): Promise<void>;
async runToSummon(species: SpeciesId[] | undefined): Promise<void>; async runToSummon(species: SpeciesId[] | undefined): Promise<void>;
async runToSummon(species?: SpeciesId[]): Promise<void> { async runToSummon(species?: SpeciesId[]): Promise<void> {
@ -60,7 +63,7 @@ export class ClassicModeHelper extends GameManagerHelper {
/** /**
* Transitions to the start of a battle. * Transitions to the start of a battle.
* @param species - An array of {@linkcode Species} to start the battle with. * @param species - An array of {@linkcode SpeciesId} to start the battle with.
* @returns A promise that resolves when the battle is started. * @returns A promise that resolves when the battle is started.
*/ */
async startBattle(species: SpeciesId[]): Promise<void>; async startBattle(species: SpeciesId[]): Promise<void>;
@ -71,6 +74,7 @@ export class ClassicModeHelper extends GameManagerHelper {
* @returns A promise that resolves when the battle is started. * @returns A promise that resolves when the battle is started.
* @deprecated - Specifying the starters helps prevent inconsistencies from internal RNG changes. * @deprecated - Specifying the starters helps prevent inconsistencies from internal RNG changes.
*/ */
// biome-ignore lint/nursery/useUnifiedTypeSignature: Marks the overload for deprecation
async startBattle(): Promise<void>; async startBattle(): Promise<void>;
async startBattle(species?: SpeciesId[]): Promise<void> { async startBattle(species?: SpeciesId[]): Promise<void> {
await this.runToSummon(species); await this.runToSummon(species);

View File

@ -227,12 +227,10 @@ export class MoveHelper extends GameManagerHelper {
vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([]); vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([]);
console.warn("Player moveset override disabled due to use of `game.move.changeMoveset`!"); console.warn("Player moveset override disabled due to use of `game.move.changeMoveset`!");
} }
} else { } else if (coerceArray(Overrides.OPP_MOVESET_OVERRIDE).length > 0) {
if (coerceArray(Overrides.OPP_MOVESET_OVERRIDE).length > 0) {
vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([]); vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([]);
console.warn("Enemy moveset override disabled due to use of `game.move.changeMoveset`!"); console.warn("Enemy moveset override disabled due to use of `game.move.changeMoveset`!");
} }
}
moveset = coerceArray(moveset); moveset = coerceArray(moveset);
expect(moveset.length, "Cannot assign more than 4 moves to a moveset!").toBeLessThanOrEqual(4); expect(moveset.length, "Cannot assign more than 4 moves to a moveset!").toBeLessThanOrEqual(4);
pokemon.moveset = []; pokemon.moveset = [];

View File

@ -53,14 +53,12 @@ export class MockText implements MockGameObject {
wordWidthWithSpace += whiteSpaceWidth; wordWidthWithSpace += whiteSpaceWidth;
} }
if (wordWidthWithSpace > spaceLeft) {
// Skip printing the newline if it's the first word of the line that is greater // Skip printing the newline if it's the first word of the line that is greater
// than the word wrap width. // than the word wrap width.
if (j > 0) { if (wordWidthWithSpace > spaceLeft && j > 0) {
result += "\n"; result += "\n";
spaceLeft = this.wordWrapWidth; spaceLeft = this.wordWrapWidth;
} }
}
result += word; result += word;