mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-08-18 13:29:25 +02:00
Applied linter fixes
This commit is contained in:
parent
5d267d045e
commit
618a4b5fc3
@ -1463,7 +1463,6 @@ export class PostDefendAbilityGiveAbAttr extends PostDefendAbAttr {
|
||||
export class PostDefendMoveDisableAbAttr extends PostDefendAbAttr {
|
||||
private chance: number;
|
||||
private attacker: Pokemon;
|
||||
private move: Move;
|
||||
|
||||
constructor(chance: number) {
|
||||
super();
|
||||
@ -1479,11 +1478,9 @@ export class PostDefendMoveDisableAbAttr extends PostDefendAbAttr {
|
||||
);
|
||||
}
|
||||
|
||||
override apply({ simulated, opponent: attacker, move, pokemon }: PostMoveInteractionAbAttrParams): void {
|
||||
// TODO: investigate why this is setting properties
|
||||
override apply({ simulated, opponent: attacker, pokemon }: PostMoveInteractionAbAttrParams): void {
|
||||
if (!simulated) {
|
||||
this.attacker = attacker;
|
||||
this.move = move;
|
||||
this.attacker.addTag(BattlerTagType.DISABLED, 4, 0, pokemon.id);
|
||||
}
|
||||
}
|
||||
@ -6345,10 +6342,13 @@ class ForceSwitchOutHelper {
|
||||
return !blockedByAbility.value;
|
||||
}
|
||||
|
||||
if (!player && globalScene.currentBattle.battleType === BattleType.WILD) {
|
||||
if (!globalScene.currentBattle.waveIndex && globalScene.currentBattle.waveIndex % 10 === 0) {
|
||||
return false;
|
||||
}
|
||||
if (
|
||||
!player &&
|
||||
globalScene.currentBattle.battleType === BattleType.WILD &&
|
||||
!globalScene.currentBattle.waveIndex &&
|
||||
globalScene.currentBattle.waveIndex % 10 === 0
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (
|
||||
|
@ -616,7 +616,7 @@ export const speciesStarterCosts = {
|
||||
[SpeciesId.PALDEA_TAUROS]: 5,
|
||||
[SpeciesId.PALDEA_WOOPER]: 3,
|
||||
[SpeciesId.BLOODMOON_URSALUNA]: 5,
|
||||
};
|
||||
} as const;
|
||||
|
||||
const starterCandyCosts: { passive: number; costReduction: [number, number]; egg: number; }[] = [
|
||||
{ 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 {
|
||||
return starterCandyCosts[starterCost - 1].egg;
|
||||
}
|
||||
|
||||
|
@ -1397,6 +1397,7 @@ export class EncounterBattleAnim extends BattleAnim {
|
||||
}
|
||||
}
|
||||
|
||||
// biome-ignore-start lint/style/useForOf: This is being removed
|
||||
export async function populateAnims() {
|
||||
const commonAnimNames = getEnumKeys(CommonAnim).map(k => k.toLowerCase());
|
||||
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
|
||||
|
@ -2537,12 +2537,10 @@ export class RoostedTag extends BattlerTag {
|
||||
let modifiedTypes: PokemonType[];
|
||||
if (this.isBasePureFlying && !isCurrentlyDualType) {
|
||||
modifiedTypes = [PokemonType.NORMAL];
|
||||
} else if (!!pokemon.getTag(RemovedTypeTag) && isOriginallyDualType && !isCurrentlyDualType) {
|
||||
modifiedTypes = [PokemonType.UNKNOWN];
|
||||
} else {
|
||||
if (!!pokemon.getTag(RemovedTypeTag) && isOriginallyDualType && !isCurrentlyDualType) {
|
||||
modifiedTypes = [PokemonType.UNKNOWN];
|
||||
} else {
|
||||
modifiedTypes = currentTypes.filter(type => type !== PokemonType.FLYING);
|
||||
}
|
||||
modifiedTypes = currentTypes.filter(type => type !== PokemonType.FLYING);
|
||||
}
|
||||
pokemon.summonData.types = modifiedTypes;
|
||||
pokemon.updateInfo();
|
||||
|
@ -42,10 +42,9 @@ export function getDailyRunStarters(seed: string): Starter[] {
|
||||
starterCosts.push(randSeedInt(9 - starterCosts[0], 1));
|
||||
starterCosts.push(10 - (starterCosts[0] + starterCosts[1]));
|
||||
|
||||
for (let c = 0; c < starterCosts.length; c++) {
|
||||
const cost = starterCosts[c];
|
||||
for (const cost of starterCosts) {
|
||||
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);
|
||||
const randPkmSpecies = getPokemonSpecies(randSeedItem(costSpecies));
|
||||
const starterSpecies = getPokemonSpecies(
|
||||
|
@ -419,10 +419,8 @@ export class Egg {
|
||||
const rand = randSeedInt(MANAPHY_EGG_MANAPHY_RATE) !== 1;
|
||||
return rand ? SpeciesId.PHIONE : SpeciesId.MANAPHY;
|
||||
}
|
||||
if (this.tier === EggTier.LEGENDARY && this._sourceType === EggSourceType.GACHA_LEGENDARY) {
|
||||
if (!randSeedInt(2)) {
|
||||
return getLegendaryGachaSpeciesForTimestamp(this.timestamp);
|
||||
}
|
||||
if (this.tier === EggTier.LEGENDARY && this._sourceType === EggSourceType.GACHA_LEGENDARY && !randSeedInt(2)) {
|
||||
return getLegendaryGachaSpeciesForTimestamp(this.timestamp);
|
||||
}
|
||||
|
||||
let minStarterValue: number;
|
||||
|
@ -527,7 +527,8 @@ function doBerrySpritePile(isEat = false) {
|
||||
const encounter = globalScene.currentBattle.mysteryEncounter!;
|
||||
animationOrder.forEach((berry, i) => {
|
||||
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);
|
||||
if (sprites) {
|
||||
sprite = sprites[0];
|
||||
|
@ -213,7 +213,8 @@ export const BugTypeSuperfanEncounter: MysteryEncounter = MysteryEncounterBuilde
|
||||
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]) {
|
||||
beedrillKeys = getSpriteKeysFromSpecies(SpeciesId.BEEDRILL, false);
|
||||
butterfreeKeys = getSpriteKeysFromSpecies(SpeciesId.BUTTERFREE, false);
|
||||
|
@ -289,16 +289,14 @@ export const GlobalTradeSystemEncounter: MysteryEncounter = MysteryEncounterBuil
|
||||
|
||||
// Extra HA roll at base 1/64 odds (boosted by events and charms)
|
||||
const hiddenIndex = tradePokemon.species.ability2 ? 2 : 1;
|
||||
if (tradePokemon.species.abilityHidden) {
|
||||
if (tradePokemon.abilityIndex < hiddenIndex) {
|
||||
const hiddenAbilityChance = new NumberHolder(64);
|
||||
globalScene.applyModifiers(HiddenAbilityRateBoosterModifier, true, hiddenAbilityChance);
|
||||
if (tradePokemon.species.abilityHidden && tradePokemon.abilityIndex < hiddenIndex) {
|
||||
const hiddenAbilityChance = new NumberHolder(64);
|
||||
globalScene.applyModifiers(HiddenAbilityRateBoosterModifier, true, hiddenAbilityChance);
|
||||
|
||||
const hasHiddenAbility = !randSeedInt(hiddenAbilityChance.value);
|
||||
const hasHiddenAbility = !randSeedInt(hiddenAbilityChance.value);
|
||||
|
||||
if (hasHiddenAbility) {
|
||||
tradePokemon.abilityIndex = hiddenIndex;
|
||||
}
|
||||
if (hasHiddenAbility) {
|
||||
tradePokemon.abilityIndex = hiddenIndex;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1107,12 +1107,10 @@ export function calculateMEAggregateStats(baseSpawnWeight: number) {
|
||||
}
|
||||
} else if (biomeLinks.hasOwnProperty(currentBiome)) {
|
||||
currentBiome = biomeLinks[currentBiome] as BiomeId;
|
||||
} else if (!(i % 50)) {
|
||||
currentBiome = BiomeId.END;
|
||||
} else {
|
||||
if (!(i % 50)) {
|
||||
currentBiome = BiomeId.END;
|
||||
} else {
|
||||
currentBiome = globalScene.generateRandomBiome(i);
|
||||
}
|
||||
currentBiome = globalScene.generateRandomBiome(i);
|
||||
}
|
||||
|
||||
currentArena = globalScene.newArena(currentBiome);
|
||||
|
@ -986,41 +986,39 @@ export class PokemonSpecies extends PokemonSpeciesForm implements Localizable {
|
||||
|
||||
if (!forTrainer && isRegionalEvolution) {
|
||||
evolutionChance = 0;
|
||||
} else {
|
||||
if (ev.wildDelay === SpeciesWildEvolutionDelay.NONE) {
|
||||
if (strength === PartyMemberStrength.STRONGER) {
|
||||
evolutionChance = 1;
|
||||
} else {
|
||||
const maxLevelDiff = this.getStrengthLevelDiff(strength); //The maximum distance from the evolution level tolerated for the mon to not evolve
|
||||
const minChance: number = 0.875 - 0.125 * strength;
|
||||
|
||||
evolutionChance = Math.min(
|
||||
minChance + easeInFunc(Math.min(level - ev.level, maxLevelDiff) / maxLevelDiff) * (1 - minChance),
|
||||
1,
|
||||
);
|
||||
}
|
||||
} else if (ev.wildDelay === SpeciesWildEvolutionDelay.NONE) {
|
||||
if (strength === PartyMemberStrength.STRONGER) {
|
||||
evolutionChance = 1;
|
||||
} else {
|
||||
const preferredMinLevel = Math.max(ev.level - 1 + ev.wildDelay! * this.getStrengthLevelDiff(strength), 1); // TODO: is the bang correct?
|
||||
let evolutionLevel = Math.max(ev.level > 1 ? ev.level : Math.floor(preferredMinLevel / 2), 1);
|
||||
|
||||
if (ev.level <= 1 && pokemonPrevolutions.hasOwnProperty(this.speciesId)) {
|
||||
const prevolutionLevel = pokemonEvolutions[pokemonPrevolutions[this.speciesId]].find(
|
||||
ev => ev.speciesId === this.speciesId,
|
||||
)!.level; // TODO: is the bang correct?
|
||||
if (prevolutionLevel > 1) {
|
||||
evolutionLevel = prevolutionLevel;
|
||||
}
|
||||
}
|
||||
const maxLevelDiff = this.getStrengthLevelDiff(strength); //The maximum distance from the evolution level tolerated for the mon to not evolve
|
||||
const minChance: number = 0.875 - 0.125 * strength;
|
||||
|
||||
evolutionChance = Math.min(
|
||||
0.65 * easeInFunc(Math.min(Math.max(level - evolutionLevel, 0), preferredMinLevel) / preferredMinLevel) +
|
||||
0.35 *
|
||||
easeOutFunc(
|
||||
Math.min(Math.max(level - evolutionLevel, 0), preferredMinLevel * 2.5) / (preferredMinLevel * 2.5),
|
||||
),
|
||||
minChance + easeInFunc(Math.min(level - ev.level, maxLevelDiff) / maxLevelDiff) * (1 - minChance),
|
||||
1,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
const preferredMinLevel = Math.max(ev.level - 1 + ev.wildDelay! * this.getStrengthLevelDiff(strength), 1); // TODO: is the bang correct?
|
||||
let evolutionLevel = Math.max(ev.level > 1 ? ev.level : Math.floor(preferredMinLevel / 2), 1);
|
||||
|
||||
if (ev.level <= 1 && pokemonPrevolutions.hasOwnProperty(this.speciesId)) {
|
||||
const prevolutionLevel = pokemonEvolutions[pokemonPrevolutions[this.speciesId]].find(
|
||||
ev => ev.speciesId === this.speciesId,
|
||||
)!.level; // TODO: is the bang correct?
|
||||
if (prevolutionLevel > 1) {
|
||||
evolutionLevel = prevolutionLevel;
|
||||
}
|
||||
}
|
||||
|
||||
evolutionChance = Math.min(
|
||||
0.65 * easeInFunc(Math.min(Math.max(level - evolutionLevel, 0), preferredMinLevel) / preferredMinLevel) +
|
||||
0.35 *
|
||||
easeOutFunc(
|
||||
Math.min(Math.max(level - evolutionLevel, 0), preferredMinLevel * 2.5) / (preferredMinLevel * 2.5),
|
||||
),
|
||||
1,
|
||||
);
|
||||
}
|
||||
|
||||
//TODO: Adjust templates and delays so we don't have to hardcode it
|
||||
@ -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.
|
||||
* @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 {
|
||||
let caughtAttr = 0n;
|
||||
|
@ -6,6 +6,7 @@ import type { MysteryEncounter } from "#mystery-encounters/mystery-encounter";
|
||||
import { loadPokemonVariantAssets } from "#sprites/pokemon-sprite";
|
||||
import type { Variant } from "#sprites/variant";
|
||||
import { isNullOrUndefined } from "#utils/common";
|
||||
import console from "node:console";
|
||||
import type { GameObjects } from "phaser";
|
||||
|
||||
type PlayAnimationConfig = Phaser.Types.Animations.PlayAnimationConfig;
|
||||
@ -87,6 +88,7 @@ export class MysteryEncounterIntroVisuals extends Phaser.GameObjects.Container {
|
||||
variant: Variant;
|
||||
}[];
|
||||
|
||||
// TODO: Refactor
|
||||
constructor(encounter: MysteryEncounter) {
|
||||
super(globalScene, -72, 76);
|
||||
this.encounter = encounter;
|
||||
@ -193,17 +195,15 @@ export class MysteryEncounterIntroVisuals extends Phaser.GameObjects.Container {
|
||||
sprite.setPosition(sprite.x, sprite.y + y);
|
||||
tintSprite.setPosition(tintSprite.x, tintSprite.y + y);
|
||||
}
|
||||
} else {
|
||||
// Single sprite
|
||||
if (this.spriteConfigs.length === 1) {
|
||||
sprite.x = origin;
|
||||
tintSprite.x = origin;
|
||||
} else {
|
||||
// Do standard sprite spacing (not including offset sprites)
|
||||
sprite.x = minX + (n + 0.5) * spacingValue + origin;
|
||||
tintSprite.x = minX + (n + 0.5) * spacingValue + origin;
|
||||
n++;
|
||||
}
|
||||
} else if (this.spriteConfigs.length === 1) {
|
||||
sprite.x = origin;
|
||||
tintSprite.x = origin;
|
||||
} else {
|
||||
// Do standard sprite spacing (not including offset sprites)
|
||||
sprite.x = minX + (n + 0.5) * spacingValue + origin;
|
||||
tintSprite.x = minX + (n + 0.5) * spacingValue + origin;
|
||||
n++;
|
||||
}
|
||||
|
||||
if (!isNullOrUndefined(pokemonShinySparkle)) {
|
||||
|
@ -2511,17 +2511,13 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
defenderType,
|
||||
});
|
||||
}
|
||||
if (ignoreImmunity.value) {
|
||||
if (multiplier.value === 0) {
|
||||
return 1;
|
||||
}
|
||||
if (ignoreImmunity.value && multiplier.value === 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
const exposedTags = this.findTags(tag => tag instanceof ExposedTag) as ExposedTag[];
|
||||
if (exposedTags.some(t => t.ignoreImmunity(defenderType, moveType))) {
|
||||
if (multiplier.value === 0) {
|
||||
return 1;
|
||||
}
|
||||
if (exposedTags.some(t => t.ignoreImmunity(defenderType, moveType)) && multiplier.value === 0) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return multiplier.value;
|
||||
@ -2960,10 +2956,8 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
return false;
|
||||
}
|
||||
const haThreshold = new NumberHolder(thresholdOverride ?? BASE_HIDDEN_ABILITY_CHANCE);
|
||||
if (applyModifiersToOverride) {
|
||||
if (!this.hasTrainer()) {
|
||||
globalScene.applyModifiers(HiddenAbilityRateBoosterModifier, true, haThreshold);
|
||||
}
|
||||
if (applyModifiersToOverride && !this.hasTrainer()) {
|
||||
globalScene.applyModifiers(HiddenAbilityRateBoosterModifier, true, haThreshold);
|
||||
}
|
||||
|
||||
if (randSeedInt(65536) < haThreshold.value) {
|
||||
@ -3063,8 +3057,7 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
return;
|
||||
}
|
||||
|
||||
for (let m = 0; m < allLevelMoves.length; m++) {
|
||||
const levelMove = allLevelMoves[m];
|
||||
for (const levelMove of allLevelMoves) {
|
||||
if (this.level < levelMove[0]) {
|
||||
break;
|
||||
}
|
||||
@ -4829,11 +4822,9 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
return true;
|
||||
});
|
||||
|
||||
if (this.isOfType(PokemonType.POISON) || this.isOfType(PokemonType.STEEL)) {
|
||||
if (poisonImmunity.includes(true)) {
|
||||
this.queueStatusImmuneMessage(quiet);
|
||||
return false;
|
||||
}
|
||||
if ((this.isOfType(PokemonType.POISON) || this.isOfType(PokemonType.STEEL)) && poisonImmunity.includes(true)) {
|
||||
this.queueStatusImmuneMessage(quiet);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -5013,10 +5004,8 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
this.lapseTag(BattlerTagType.NIGHTMARE);
|
||||
}
|
||||
}
|
||||
if (confusion) {
|
||||
if (this.getTag(BattlerTagType.CONFUSED)) {
|
||||
this.lapseTag(BattlerTagType.CONFUSED);
|
||||
}
|
||||
if (confusion && this.getTag(BattlerTagType.CONFUSED)) {
|
||||
this.lapseTag(BattlerTagType.CONFUSED);
|
||||
}
|
||||
if (reloadAssets) {
|
||||
this.loadAssets(false).then(() => this.playAnim());
|
||||
@ -5500,8 +5489,8 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
|
||||
spriteColors.forEach((sc: number[], i: number) => {
|
||||
paletteDeltas.push([]);
|
||||
for (let p = 0; p < palette.length; p++) {
|
||||
paletteDeltas[i].push(deltaRgb(sc, palette[p]));
|
||||
for (const p of palette) {
|
||||
paletteDeltas[i].push(deltaRgb(sc, p));
|
||||
}
|
||||
});
|
||||
|
||||
@ -6774,10 +6763,12 @@ export class EnemyPokemon extends Pokemon {
|
||||
}
|
||||
|
||||
canBypassBossSegments(segmentCount = 1): boolean {
|
||||
if (globalScene.currentBattle.battleSpec === BattleSpec.FINAL_BOSS) {
|
||||
if (!this.formIndex && this.bossSegmentIndex - segmentCount < 1) {
|
||||
return false;
|
||||
}
|
||||
if (
|
||||
globalScene.currentBattle.battleSpec === BattleSpec.FINAL_BOSS &&
|
||||
!this.formIndex &&
|
||||
this.bossSegmentIndex - segmentCount < 1
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -403,16 +403,14 @@ export class Trainer extends Phaser.GameObjects.Container {
|
||||
} else {
|
||||
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)
|
||||
// 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]) {
|
||||
newSpeciesPool = [SpeciesId.SOLROCK];
|
||||
} else if (index === 1 && TrainerType[this.config.trainerTypeDouble] === TrainerType[TrainerType.LIZA]) {
|
||||
newSpeciesPool = [SpeciesId.LUNATONE];
|
||||
} else {
|
||||
newSpeciesPool = speciesPoolPartnerFiltered;
|
||||
}
|
||||
} else if (index === 1 && TrainerType[this.config.trainerTypeDouble] === TrainerType[TrainerType.TATE]) {
|
||||
newSpeciesPool = [SpeciesId.SOLROCK];
|
||||
} else if (index === 1 && TrainerType[this.config.trainerTypeDouble] === TrainerType[TrainerType.LIZA]) {
|
||||
newSpeciesPool = [SpeciesId.LUNATONE];
|
||||
} else {
|
||||
newSpeciesPool = speciesPoolPartnerFiltered;
|
||||
}
|
||||
// Fallback for when the species pool is empty
|
||||
if (newSpeciesPool.length === 0) {
|
||||
@ -794,10 +792,12 @@ export class Trainer extends Phaser.GameObjects.Container {
|
||||
* @returns boolean Whether the EnemyPokemon should Terastalize this turn
|
||||
*/
|
||||
shouldTera(pokemon: EnemyPokemon): boolean {
|
||||
if (this.config.trainerAI.teraMode === TeraAIMode.INSTANT_TERA) {
|
||||
if (!pokemon.isTerastallized && this.config.trainerAI.instantTeras.includes(pokemon.initialTeamIndex)) {
|
||||
return true;
|
||||
}
|
||||
if (
|
||||
this.config.trainerAI.teraMode === TeraAIMode.INSTANT_TERA &&
|
||||
!pokemon.isTerastallized &&
|
||||
this.config.trainerAI.instantTeras.includes(pokemon.initialTeamIndex)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -1634,9 +1634,9 @@ export class FormChangeItemModifierTypeGenerator extends ModifierTypeGenerator {
|
||||
|
||||
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...
|
||||
let foundULTRA_Z = false,
|
||||
foundN_LUNA = false,
|
||||
foundN_SOLAR = false;
|
||||
let foundULTRA_Z = false;
|
||||
let foundN_LUNA = false;
|
||||
let foundN_SOLAR = false;
|
||||
formChangeItemTriggers.forEach((fc, _i) => {
|
||||
console.log("Checking ", fc.item);
|
||||
switch (fc.item) {
|
||||
|
@ -102,10 +102,13 @@ import { WeatherEffectPhase } from "#phases/weather-effect-phase";
|
||||
import type { PhaseMap, PhaseString } from "#types/phase-types";
|
||||
import { type Constructor, coerceArray } from "#utils/common";
|
||||
|
||||
/*
|
||||
/**
|
||||
* @module
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -604,9 +604,8 @@ export class CommandPhase extends FieldPhase {
|
||||
* @returns Whether the command was successful
|
||||
*/
|
||||
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.RUN, cursor: number): boolean;
|
||||
handleCommand(command: Command.BALL | Command.RUN, cursor: number): boolean;
|
||||
handleCommand(command: Command, cursor: number, useMode?: boolean | MoveUseMode, move?: TurnMove): boolean;
|
||||
|
||||
public handleCommand(
|
||||
|
@ -559,10 +559,11 @@ export class MoveEffectPhase extends PokemonPhase {
|
||||
|
||||
// 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.
|
||||
if (user.turnData.hitsLeft < user.turnData.hitCount) {
|
||||
if (!move.hasFlag(MoveFlags.CHECK_ALL_HITS) || user.hasAbilityWithAttr("MaxMultiHitAbAttr")) {
|
||||
return [HitCheckResult.HIT, effectiveness];
|
||||
}
|
||||
if (
|
||||
user.turnData.hitsLeft < user.turnData.hitCount &&
|
||||
(!move.hasFlag(MoveFlags.CHECK_ALL_HITS) || user.hasAbilityWithAttr("MaxMultiHitAbAttr"))
|
||||
) {
|
||||
return [HitCheckResult.HIT, effectiveness];
|
||||
}
|
||||
|
||||
const bypassAccuracy =
|
||||
|
@ -23,25 +23,24 @@ export class ScanIvsPhase extends PokemonPhase {
|
||||
let enemyIvs: number[] = [];
|
||||
let statsContainer: Phaser.GameObjects.Sprite[] = [];
|
||||
let statsContainerLabels: Phaser.GameObjects.Sprite[] = [];
|
||||
const enemyField = globalScene.getEnemyField();
|
||||
const uiTheme = globalScene.uiTheme; // Assuming uiTheme is accessible
|
||||
for (let e = 0; e < enemyField.length; e++) {
|
||||
enemyIvs = enemyField[e].ivs;
|
||||
for (const enemy of globalScene.getEnemyField()) {
|
||||
enemyIvs = enemy.ivs;
|
||||
// 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;
|
||||
statsContainer = enemyField[e].getBattleInfo().getStatsValueContainer().list as Phaser.GameObjects.Sprite[];
|
||||
const currentIvs = globalScene.gameData.dexData[enemy.species.getRootSpeciesId()].ivs;
|
||||
statsContainer = enemy.getBattleInfo().getStatsValueContainer().list as Phaser.GameObjects.Sprite[];
|
||||
statsContainerLabels = statsContainer.filter(m => m.name.indexOf("icon_stat_label") >= 0);
|
||||
for (let s = 0; s < statsContainerLabels.length; s++) {
|
||||
const ivStat = Stat[statsContainerLabels[s].frame.name];
|
||||
for (const statContainer of statsContainerLabels) {
|
||||
const ivStat = Stat[statContainer.frame.name];
|
||||
if (enemyIvs[ivStat] > currentIvs[ivStat] && PERMANENT_STATS.indexOf(Number(ivStat)) >= 0) {
|
||||
const hexColour =
|
||||
enemyIvs[ivStat] === 31
|
||||
? getTextColor(TextStyle.PERFECT_IV, false, uiTheme)
|
||||
: getTextColor(TextStyle.SUMMARY_GREEN, false, uiTheme);
|
||||
const hexTextColour = Phaser.Display.Color.HexStringToColor(hexColour).color;
|
||||
statsContainerLabels[s].setTint(hexTextColour);
|
||||
statContainer.setTint(hexTextColour);
|
||||
}
|
||||
statsContainerLabels[s].setVisible(true);
|
||||
statContainer.setVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,7 @@ export type StatStageChangeCallback = (
|
||||
relativeChanges: number[],
|
||||
) => void;
|
||||
|
||||
// TODO: Refactor this mess of a phase
|
||||
export class StatStageChangePhase extends PokemonPhase {
|
||||
public readonly phaseName = "StatStageChangePhase";
|
||||
private stats: BattleStat[];
|
||||
@ -62,13 +63,12 @@ export class StatStageChangePhase extends PokemonPhase {
|
||||
start() {
|
||||
// Check if multiple stats are being changed at the same time, then run SSCPhase for each of them
|
||||
if (this.stats.length > 1) {
|
||||
for (let i = 0; i < this.stats.length; i++) {
|
||||
const stat = [this.stats[i]];
|
||||
for (const stat of this.stats) {
|
||||
globalScene.phaseManager.unshiftNew(
|
||||
"StatStageChangePhase",
|
||||
this.battlerIndex,
|
||||
this.selfTarget,
|
||||
stat,
|
||||
[stat],
|
||||
this.stages,
|
||||
this.showMessage,
|
||||
this.ignoreAbilities,
|
||||
@ -100,20 +100,18 @@ export class StatStageChangePhase extends PokemonPhase {
|
||||
}
|
||||
});
|
||||
}
|
||||
} else if (!this.comingFromStickyWeb) {
|
||||
opponentPokemon = globalScene.getPlayerField()[globalScene.currentBattle.lastPlayerInvolved];
|
||||
} else {
|
||||
if (!this.comingFromStickyWeb) {
|
||||
opponentPokemon = globalScene.getPlayerField()[globalScene.currentBattle.lastPlayerInvolved];
|
||||
} else {
|
||||
const stickyTagID = globalScene.arena.findTagsOnSide(
|
||||
(t: ArenaTag) => t.tagType === ArenaTagType.STICKY_WEB,
|
||||
ArenaTagSide.ENEMY,
|
||||
)[0].sourceId;
|
||||
globalScene.getPlayerField().forEach(e => {
|
||||
if (e.id === stickyTagID) {
|
||||
opponentPokemon = e;
|
||||
}
|
||||
});
|
||||
}
|
||||
const stickyTagID = globalScene.arena.findTagsOnSide(
|
||||
(t: ArenaTag) => t.tagType === ArenaTagType.STICKY_WEB,
|
||||
ArenaTagSide.ENEMY,
|
||||
)[0].sourceId;
|
||||
globalScene.getPlayerField().forEach(e => {
|
||||
if (e.id === stickyTagID) {
|
||||
opponentPokemon = e;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (!pokemon.isActive(true)) {
|
||||
|
@ -27,29 +27,28 @@ export class TrainerVictoryPhase extends BattlePhase {
|
||||
|
||||
const trainerType = globalScene.currentBattle.trainer?.config.trainerType!; // TODO: is this bang correct?
|
||||
// Validate Voucher for boss trainers
|
||||
if (vouchers.hasOwnProperty(TrainerType[trainerType])) {
|
||||
if (
|
||||
!globalScene.validateVoucher(vouchers[TrainerType[trainerType]]) &&
|
||||
globalScene.currentBattle.trainer?.config.isBoss
|
||||
) {
|
||||
if (timedEventManager.getUpgradeUnlockedVouchers()) {
|
||||
globalScene.phaseManager.unshiftNew(
|
||||
"ModifierRewardPhase",
|
||||
[
|
||||
modifierTypes.VOUCHER_PLUS,
|
||||
modifierTypes.VOUCHER_PLUS,
|
||||
modifierTypes.VOUCHER_PLUS,
|
||||
modifierTypes.VOUCHER_PREMIUM,
|
||||
][vouchers[TrainerType[trainerType]].voucherType],
|
||||
);
|
||||
} else {
|
||||
globalScene.phaseManager.unshiftNew(
|
||||
"ModifierRewardPhase",
|
||||
[modifierTypes.VOUCHER, modifierTypes.VOUCHER, modifierTypes.VOUCHER_PLUS, modifierTypes.VOUCHER_PREMIUM][
|
||||
vouchers[TrainerType[trainerType]].voucherType
|
||||
],
|
||||
);
|
||||
}
|
||||
if (
|
||||
vouchers.hasOwnProperty(TrainerType[trainerType]) &&
|
||||
!globalScene.validateVoucher(vouchers[TrainerType[trainerType]]) &&
|
||||
globalScene.currentBattle.trainer?.config.isBoss
|
||||
) {
|
||||
if (timedEventManager.getUpgradeUnlockedVouchers()) {
|
||||
globalScene.phaseManager.unshiftNew(
|
||||
"ModifierRewardPhase",
|
||||
[
|
||||
modifierTypes.VOUCHER_PLUS,
|
||||
modifierTypes.VOUCHER_PLUS,
|
||||
modifierTypes.VOUCHER_PLUS,
|
||||
modifierTypes.VOUCHER_PREMIUM,
|
||||
][vouchers[TrainerType[trainerType]].voucherType],
|
||||
);
|
||||
} else {
|
||||
globalScene.phaseManager.unshiftNew(
|
||||
"ModifierRewardPhase",
|
||||
[modifierTypes.VOUCHER, modifierTypes.VOUCHER, modifierTypes.VOUCHER_PLUS, modifierTypes.VOUCHER_PREMIUM][
|
||||
vouchers[TrainerType[trainerType]].voucherType
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
// Breeders in Space achievement
|
||||
|
@ -16,8 +16,8 @@ export class PokerogueSessionSavedataApi extends ApiBase {
|
||||
//#region Public
|
||||
|
||||
/**
|
||||
* Mark a session as cleared aka "newclear".\
|
||||
* *This is **NOT** the same as {@linkcode clear | clear()}.*
|
||||
* Mark a session as cleared aka "newclear". \
|
||||
* _This is **NOT** the same as {@linkcode clear | clear()}._
|
||||
* @param params The {@linkcode NewClearSessionSavedataRequest} to send
|
||||
* @returns The raw savedata as `string`.
|
||||
* @throws Error if the request fails
|
||||
@ -94,8 +94,8 @@ export class PokerogueSessionSavedataApi extends ApiBase {
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the session savedata of the given slot.\
|
||||
* *This is **NOT** the same as {@linkcode newclear | newclear()}.*
|
||||
* Clears the session savedata of the given slot. \
|
||||
* _This is **NOT** the same as {@linkcode newclear | newclear()}._
|
||||
* @param params The {@linkcode ClearSessionSavedataRequest} to send
|
||||
* @param sessionData The {@linkcode SessionSaveData} object
|
||||
*/
|
||||
|
@ -121,8 +121,8 @@ async function initFonts(language: string | undefined) {
|
||||
}
|
||||
|
||||
/**
|
||||
* I18n money formatter with. (useful for BBCode coloring of text)\
|
||||
* *If you don't want the BBCode tag applied, just use 'number' formatter*
|
||||
* I18n money formatter with. (useful for BBCode coloring of text) \
|
||||
* _If you don't want the BBCode tag applied, just use 'number' formatter_
|
||||
* @example Input: `{{myMoneyValue, money}}`
|
||||
* Output: `@[MONEY]{₽100,000,000}`
|
||||
* @param amount the money amount
|
||||
|
@ -1595,7 +1595,7 @@ export class GameData {
|
||||
globalScene.executeWithSeedOffset(
|
||||
() => {
|
||||
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));
|
||||
}
|
||||
},
|
||||
|
@ -104,18 +104,16 @@ export function setSettingGamepad(setting: SettingGamepad, value: number): boole
|
||||
case SettingGamepad.Button_Speed_Up:
|
||||
case SettingGamepad.Button_Slow_Down:
|
||||
case SettingGamepad.Button_Submit:
|
||||
if (value) {
|
||||
if (globalScene.ui) {
|
||||
const cancelHandler = (success = false): boolean => {
|
||||
globalScene.ui.revertMode();
|
||||
(globalScene.ui.getHandler() as SettingsGamepadUiHandler).updateBindings();
|
||||
return success;
|
||||
};
|
||||
globalScene.ui.setOverlayMode(UiMode.GAMEPAD_BINDING, {
|
||||
target: setting,
|
||||
cancelHandler: cancelHandler,
|
||||
});
|
||||
}
|
||||
if (value && globalScene.ui) {
|
||||
const cancelHandler = (success = false): boolean => {
|
||||
globalScene.ui.revertMode();
|
||||
(globalScene.ui.getHandler() as SettingsGamepadUiHandler).updateBindings();
|
||||
return success;
|
||||
};
|
||||
globalScene.ui.setOverlayMode(UiMode.GAMEPAD_BINDING, {
|
||||
target: setting,
|
||||
cancelHandler: cancelHandler,
|
||||
});
|
||||
}
|
||||
break;
|
||||
case SettingGamepad.Controller:
|
||||
|
@ -167,18 +167,16 @@ export function setSettingKeyboard(setting: SettingKeyboard, value: number): boo
|
||||
case SettingKeyboard.Alt_Button_Speed_Up:
|
||||
case SettingKeyboard.Alt_Button_Slow_Down:
|
||||
case SettingKeyboard.Alt_Button_Submit:
|
||||
if (value) {
|
||||
if (globalScene.ui) {
|
||||
const cancelHandler = (success = false): boolean => {
|
||||
globalScene.ui.revertMode();
|
||||
(globalScene.ui.getHandler() as SettingsKeyboardUiHandler).updateBindings();
|
||||
return success;
|
||||
};
|
||||
globalScene.ui.setOverlayMode(UiMode.KEYBOARD_BINDING, {
|
||||
target: setting,
|
||||
cancelHandler: cancelHandler,
|
||||
});
|
||||
}
|
||||
if (value && globalScene.ui) {
|
||||
const cancelHandler = (success = false): boolean => {
|
||||
globalScene.ui.revertMode();
|
||||
(globalScene.ui.getHandler() as SettingsKeyboardUiHandler).updateBindings();
|
||||
return success;
|
||||
};
|
||||
globalScene.ui.setOverlayMode(UiMode.KEYBOARD_BINDING, {
|
||||
target: setting,
|
||||
cancelHandler: cancelHandler,
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -896,104 +896,102 @@ export function setSetting(setting: string, value: number): boolean {
|
||||
globalScene.typeHints = Setting[index].options[value].value === "On";
|
||||
break;
|
||||
case SettingKeys.Language:
|
||||
if (value) {
|
||||
if (globalScene.ui) {
|
||||
const cancelHandler = () => {
|
||||
globalScene.ui.revertMode();
|
||||
(globalScene.ui.getHandler() as SettingsUiHandler).setOptionCursor(-1, 0, true);
|
||||
};
|
||||
const changeLocaleHandler = (locale: string): boolean => {
|
||||
try {
|
||||
i18next.changeLanguage(locale);
|
||||
localStorage.setItem("prLang", locale);
|
||||
cancelHandler();
|
||||
// Reload the whole game to apply the new locale since also some constants are translated
|
||||
window.location.reload();
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error("Error changing locale:", error);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
globalScene.ui.setOverlayMode(UiMode.OPTION_SELECT, {
|
||||
options: [
|
||||
{
|
||||
label: "English",
|
||||
handler: () => changeLocaleHandler("en"),
|
||||
},
|
||||
{
|
||||
label: "Español (ES)",
|
||||
handler: () => changeLocaleHandler("es-ES"),
|
||||
},
|
||||
{
|
||||
label: "Español (LATAM)",
|
||||
handler: () => changeLocaleHandler("es-MX"),
|
||||
},
|
||||
{
|
||||
label: "Français",
|
||||
handler: () => changeLocaleHandler("fr"),
|
||||
},
|
||||
{
|
||||
label: "Deutsch",
|
||||
handler: () => changeLocaleHandler("de"),
|
||||
},
|
||||
{
|
||||
label: "Italiano",
|
||||
handler: () => changeLocaleHandler("it"),
|
||||
},
|
||||
{
|
||||
label: "Português (BR)",
|
||||
handler: () => changeLocaleHandler("pt-BR"),
|
||||
},
|
||||
{
|
||||
label: "한국어",
|
||||
handler: () => changeLocaleHandler("ko"),
|
||||
},
|
||||
{
|
||||
label: "日本語",
|
||||
handler: () => changeLocaleHandler("ja"),
|
||||
},
|
||||
{
|
||||
label: "简体中文",
|
||||
handler: () => changeLocaleHandler("zh-CN"),
|
||||
},
|
||||
{
|
||||
label: "繁體中文",
|
||||
handler: () => changeLocaleHandler("zh-TW"),
|
||||
},
|
||||
{
|
||||
label: "Català (Needs Help)",
|
||||
handler: () => changeLocaleHandler("ca"),
|
||||
},
|
||||
{
|
||||
label: "Türkçe (Needs Help)",
|
||||
handler: () => changeLocaleHandler("tr"),
|
||||
},
|
||||
{
|
||||
label: "Русский (Needs Help)",
|
||||
handler: () => changeLocaleHandler("ru"),
|
||||
},
|
||||
{
|
||||
label: "Dansk (Needs Help)",
|
||||
handler: () => changeLocaleHandler("da"),
|
||||
},
|
||||
{
|
||||
label: "Română (Needs Help)",
|
||||
handler: () => changeLocaleHandler("ro"),
|
||||
},
|
||||
{
|
||||
label: "Tagalog (Needs Help)",
|
||||
handler: () => changeLocaleHandler("tl"),
|
||||
},
|
||||
{
|
||||
label: i18next.t("settings:back"),
|
||||
handler: () => cancelHandler(),
|
||||
},
|
||||
],
|
||||
maxOptions: 7,
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (value && globalScene.ui) {
|
||||
const cancelHandler = () => {
|
||||
globalScene.ui.revertMode();
|
||||
(globalScene.ui.getHandler() as SettingsUiHandler).setOptionCursor(-1, 0, true);
|
||||
};
|
||||
const changeLocaleHandler = (locale: string): boolean => {
|
||||
try {
|
||||
i18next.changeLanguage(locale);
|
||||
localStorage.setItem("prLang", locale);
|
||||
cancelHandler();
|
||||
// Reload the whole game to apply the new locale since also some constants are translated
|
||||
window.location.reload();
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error("Error changing locale:", error);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
globalScene.ui.setOverlayMode(UiMode.OPTION_SELECT, {
|
||||
options: [
|
||||
{
|
||||
label: "English",
|
||||
handler: () => changeLocaleHandler("en"),
|
||||
},
|
||||
{
|
||||
label: "Español (ES)",
|
||||
handler: () => changeLocaleHandler("es-ES"),
|
||||
},
|
||||
{
|
||||
label: "Español (LATAM)",
|
||||
handler: () => changeLocaleHandler("es-MX"),
|
||||
},
|
||||
{
|
||||
label: "Français",
|
||||
handler: () => changeLocaleHandler("fr"),
|
||||
},
|
||||
{
|
||||
label: "Deutsch",
|
||||
handler: () => changeLocaleHandler("de"),
|
||||
},
|
||||
{
|
||||
label: "Italiano",
|
||||
handler: () => changeLocaleHandler("it"),
|
||||
},
|
||||
{
|
||||
label: "Português (BR)",
|
||||
handler: () => changeLocaleHandler("pt-BR"),
|
||||
},
|
||||
{
|
||||
label: "한국어",
|
||||
handler: () => changeLocaleHandler("ko"),
|
||||
},
|
||||
{
|
||||
label: "日本語",
|
||||
handler: () => changeLocaleHandler("ja"),
|
||||
},
|
||||
{
|
||||
label: "简体中文",
|
||||
handler: () => changeLocaleHandler("zh-CN"),
|
||||
},
|
||||
{
|
||||
label: "繁體中文",
|
||||
handler: () => changeLocaleHandler("zh-TW"),
|
||||
},
|
||||
{
|
||||
label: "Català (Needs Help)",
|
||||
handler: () => changeLocaleHandler("ca"),
|
||||
},
|
||||
{
|
||||
label: "Türkçe (Needs Help)",
|
||||
handler: () => changeLocaleHandler("tr"),
|
||||
},
|
||||
{
|
||||
label: "Русский (Needs Help)",
|
||||
handler: () => changeLocaleHandler("ru"),
|
||||
},
|
||||
{
|
||||
label: "Dansk (Needs Help)",
|
||||
handler: () => changeLocaleHandler("da"),
|
||||
},
|
||||
{
|
||||
label: "Română (Needs Help)",
|
||||
handler: () => changeLocaleHandler("ro"),
|
||||
},
|
||||
{
|
||||
label: "Tagalog (Needs Help)",
|
||||
handler: () => changeLocaleHandler("tl"),
|
||||
},
|
||||
{
|
||||
label: i18next.t("settings:back"),
|
||||
handler: () => cancelHandler(),
|
||||
},
|
||||
],
|
||||
maxOptions: 7,
|
||||
});
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case SettingKeys.Shop_Overlay_Opacity:
|
||||
|
@ -241,9 +241,7 @@ export class ArenaFlyout extends Phaser.GameObjects.Container {
|
||||
|
||||
this.fieldEffectInfo.sort((infoA, infoB) => infoA.duration - infoB.duration);
|
||||
|
||||
for (let i = 0; i < this.fieldEffectInfo.length; i++) {
|
||||
const fieldEffectInfo = this.fieldEffectInfo[i];
|
||||
|
||||
for (const fieldEffectInfo of this.fieldEffectInfo) {
|
||||
// Creates a proxy object to decide which text object needs to be updated
|
||||
let textObject: Phaser.GameObjects.Text;
|
||||
switch (fieldEffectInfo.effectType) {
|
||||
@ -389,9 +387,7 @@ export class ArenaFlyout extends Phaser.GameObjects.Container {
|
||||
const fieldEffectInfo: ArenaEffectInfo[] = [];
|
||||
this.fieldEffectInfo.forEach(i => fieldEffectInfo.push(i));
|
||||
|
||||
for (let i = 0; i < fieldEffectInfo.length; i++) {
|
||||
const info = fieldEffectInfo[i];
|
||||
|
||||
for (const info of fieldEffectInfo) {
|
||||
if (info.maxDuration === 0) {
|
||||
continue;
|
||||
}
|
||||
|
@ -68,14 +68,14 @@ export class BaseStatsOverlay extends Phaser.GameObjects.Container implements In
|
||||
// show this component with infos for the specific move
|
||||
show(values: number[], total: number): boolean {
|
||||
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.
|
||||
// TODO: change color based on value.
|
||||
this.statsShadows[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.active = true;
|
||||
|
@ -153,16 +153,12 @@ export class BattleMessageUiHandler extends MessageUiHandler {
|
||||
|
||||
processInput(button: Button): boolean {
|
||||
const ui = this.getUi();
|
||||
if (this.awaitingActionInput) {
|
||||
if (button === Button.CANCEL || button === Button.ACTION) {
|
||||
if (this.onActionInput) {
|
||||
ui.playSelect();
|
||||
const originalOnActionInput = this.onActionInput;
|
||||
this.onActionInput = null;
|
||||
originalOnActionInput();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (this.awaitingActionInput && (button === Button.CANCEL || button === Button.ACTION) && this.onActionInput) {
|
||||
ui.playSelect();
|
||||
const originalOnActionInput = this.onActionInput;
|
||||
this.onActionInput = null;
|
||||
originalOnActionInput();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -400,75 +400,73 @@ export class GameChallengesUiHandler extends UiHandler {
|
||||
} else {
|
||||
success = false;
|
||||
}
|
||||
} else {
|
||||
if (this.cursorObj?.visible && !this.startCursor.visible) {
|
||||
switch (button) {
|
||||
case Button.UP:
|
||||
if (this.cursor === 0) {
|
||||
if (this.scrollCursor === 0) {
|
||||
// When at the top of the menu and pressing UP, move to the bottommost item.
|
||||
if (globalScene.gameMode.challenges.length > rowsToDisplay) {
|
||||
// If there are more than 9 challenges, scroll to the bottom
|
||||
// First, set the cursor to the last visible element, preparing for the scroll to the end.
|
||||
const successA = this.setCursor(rowsToDisplay - 1);
|
||||
// Then, adjust the scroll to display the bottommost elements of the menu.
|
||||
const successB = this.setScrollCursor(globalScene.gameMode.challenges.length - rowsToDisplay);
|
||||
success = successA && successB; // success is just there to play the little validation sound effect
|
||||
} else {
|
||||
// If there are 9 or less challenges, just move to the bottom one
|
||||
success = this.setCursor(globalScene.gameMode.challenges.length - 1);
|
||||
}
|
||||
} else {
|
||||
success = this.setScrollCursor(this.scrollCursor - 1);
|
||||
}
|
||||
} else {
|
||||
success = this.setCursor(this.cursor - 1);
|
||||
}
|
||||
if (success) {
|
||||
this.updateText();
|
||||
}
|
||||
break;
|
||||
case Button.DOWN:
|
||||
if (this.cursor === rowsToDisplay - 1) {
|
||||
if (this.scrollCursor < globalScene.gameMode.challenges.length - rowsToDisplay) {
|
||||
// When at the bottom and pressing DOWN, scroll if possible.
|
||||
success = this.setScrollCursor(this.scrollCursor + 1);
|
||||
} else {
|
||||
// When at the bottom of a scrolling menu and pressing DOWN, move to the topmost item.
|
||||
// First, set the cursor to the first visible element, preparing for the scroll to the top.
|
||||
const successA = this.setCursor(0);
|
||||
// Then, adjust the scroll to display the topmost elements of the menu.
|
||||
const successB = this.setScrollCursor(0);
|
||||
} else if (this.cursorObj?.visible && !this.startCursor.visible) {
|
||||
switch (button) {
|
||||
case Button.UP:
|
||||
if (this.cursor === 0) {
|
||||
if (this.scrollCursor === 0) {
|
||||
// When at the top of the menu and pressing UP, move to the bottommost item.
|
||||
if (globalScene.gameMode.challenges.length > rowsToDisplay) {
|
||||
// If there are more than 9 challenges, scroll to the bottom
|
||||
// First, set the cursor to the last visible element, preparing for the scroll to the end.
|
||||
const successA = this.setCursor(rowsToDisplay - 1);
|
||||
// Then, adjust the scroll to display the bottommost elements of the menu.
|
||||
const successB = this.setScrollCursor(globalScene.gameMode.challenges.length - rowsToDisplay);
|
||||
success = successA && successB; // success is just there to play the little validation sound effect
|
||||
} else {
|
||||
// If there are 9 or less challenges, just move to the bottom one
|
||||
success = this.setCursor(globalScene.gameMode.challenges.length - 1);
|
||||
}
|
||||
} else if (
|
||||
globalScene.gameMode.challenges.length < rowsToDisplay &&
|
||||
this.cursor === globalScene.gameMode.challenges.length - 1
|
||||
) {
|
||||
// When at the bottom of a non-scrolling menu and pressing DOWN, move to the topmost item.
|
||||
success = this.setCursor(0);
|
||||
} else {
|
||||
success = this.setCursor(this.cursor + 1);
|
||||
success = this.setScrollCursor(this.scrollCursor - 1);
|
||||
}
|
||||
if (success) {
|
||||
this.updateText();
|
||||
} else {
|
||||
success = this.setCursor(this.cursor - 1);
|
||||
}
|
||||
if (success) {
|
||||
this.updateText();
|
||||
}
|
||||
break;
|
||||
case Button.DOWN:
|
||||
if (this.cursor === rowsToDisplay - 1) {
|
||||
if (this.scrollCursor < globalScene.gameMode.challenges.length - rowsToDisplay) {
|
||||
// When at the bottom and pressing DOWN, scroll if possible.
|
||||
success = this.setScrollCursor(this.scrollCursor + 1);
|
||||
} else {
|
||||
// When at the bottom of a scrolling menu and pressing DOWN, move to the topmost item.
|
||||
// First, set the cursor to the first visible element, preparing for the scroll to the top.
|
||||
const successA = this.setCursor(0);
|
||||
// Then, adjust the scroll to display the topmost elements of the menu.
|
||||
const successB = this.setScrollCursor(0);
|
||||
success = successA && successB; // success is just there to play the little validation sound effect
|
||||
}
|
||||
break;
|
||||
case Button.LEFT:
|
||||
// Moves the option cursor left, if possible.
|
||||
success = this.getActiveChallenge().decreaseValue();
|
||||
if (success) {
|
||||
this.updateText();
|
||||
}
|
||||
break;
|
||||
case Button.RIGHT:
|
||||
// Moves the option cursor right, if possible.
|
||||
success = this.getActiveChallenge().increaseValue();
|
||||
if (success) {
|
||||
this.updateText();
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else if (
|
||||
globalScene.gameMode.challenges.length < rowsToDisplay &&
|
||||
this.cursor === globalScene.gameMode.challenges.length - 1
|
||||
) {
|
||||
// When at the bottom of a non-scrolling menu and pressing DOWN, move to the topmost item.
|
||||
success = this.setCursor(0);
|
||||
} else {
|
||||
success = this.setCursor(this.cursor + 1);
|
||||
}
|
||||
if (success) {
|
||||
this.updateText();
|
||||
}
|
||||
break;
|
||||
case Button.LEFT:
|
||||
// Moves the option cursor left, if possible.
|
||||
success = this.getActiveChallenge().decreaseValue();
|
||||
if (success) {
|
||||
this.updateText();
|
||||
}
|
||||
break;
|
||||
case Button.RIGHT:
|
||||
// Moves the option cursor right, if possible.
|
||||
success = this.getActiveChallenge().increaseValue();
|
||||
if (success) {
|
||||
this.updateText();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -504,13 +504,11 @@ export class DropDown extends Phaser.GameObjects.Container {
|
||||
if (index === 0) {
|
||||
// we are on the All option > put all other options to the newState
|
||||
this.setAllOptions(newState);
|
||||
} else {
|
||||
} else if (newState === DropDownState.ON && this.checkForAllOn()) {
|
||||
// select the "all" option if all others are selected, other unselect it
|
||||
if (newState === DropDownState.ON && this.checkForAllOn()) {
|
||||
this.options[0].setOptionState(DropDownState.ON);
|
||||
} else {
|
||||
this.options[0].setOptionState(DropDownState.OFF);
|
||||
}
|
||||
this.options[0].setOptionState(DropDownState.ON);
|
||||
} else {
|
||||
this.options[0].setOptionState(DropDownState.OFF);
|
||||
}
|
||||
} else if (this.dropDownType === DropDownType.SINGLE) {
|
||||
if (option.state === DropDownState.OFF) {
|
||||
@ -653,10 +651,8 @@ export class DropDown extends Phaser.GameObjects.Container {
|
||||
this.options[i].setDirection(SortDirection.ASC);
|
||||
this.options[i].toggle.setVisible(true);
|
||||
}
|
||||
} else {
|
||||
if (this.defaultSettings[i]) {
|
||||
this.options[i].setOptionState(this.defaultSettings[i]["state"]);
|
||||
}
|
||||
} else if (this.defaultSettings[i]) {
|
||||
this.options[i].setOptionState(this.defaultSettings[i]["state"]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -699,11 +695,11 @@ export class DropDown extends Phaser.GameObjects.Container {
|
||||
autoSize(): void {
|
||||
let maxWidth = 0;
|
||||
let x = 0;
|
||||
for (let i = 0; i < this.options.length; i++) {
|
||||
const optionWidth = this.options[i].getWidth();
|
||||
for (const option of this.options) {
|
||||
const optionWidth = option.getWidth();
|
||||
if (optionWidth > maxWidth) {
|
||||
maxWidth = optionWidth;
|
||||
x = this.options[i].getCurrentLabelX() ?? 0;
|
||||
x = option.getCurrentLabelX() ?? 0;
|
||||
}
|
||||
}
|
||||
this.window.width = maxWidth + x - this.window.x + 9;
|
||||
|
@ -62,16 +62,12 @@ export class EvolutionSceneHandler extends MessageUiHandler {
|
||||
}
|
||||
|
||||
const ui = this.getUi();
|
||||
if (this.awaitingActionInput) {
|
||||
if (button === Button.CANCEL || button === Button.ACTION) {
|
||||
if (this.onActionInput) {
|
||||
ui.playSelect();
|
||||
const originalOnActionInput = this.onActionInput;
|
||||
this.onActionInput = null;
|
||||
originalOnActionInput();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (this.awaitingActionInput && (button === Button.CANCEL || button === Button.ACTION) && this.onActionInput) {
|
||||
ui.playSelect();
|
||||
const originalOnActionInput = this.onActionInput;
|
||||
this.onActionInput = null;
|
||||
originalOnActionInput();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -130,22 +130,20 @@ export class FilterBar extends Phaser.GameObjects.Container {
|
||||
* Move the leftmost dropdown to the left of the FilterBar instead of below it
|
||||
*/
|
||||
offsetHybridFilters(): void {
|
||||
for (let i = 0; i < this.dropDowns.length; i++) {
|
||||
if (this.dropDowns[i].dropDownType === DropDownType.HYBRID) {
|
||||
this.dropDowns[i].autoSize();
|
||||
this.dropDowns[i].x = -this.dropDowns[i].getWidth();
|
||||
this.dropDowns[i].y = 0;
|
||||
for (const dropDown of this.dropDowns) {
|
||||
if (dropDown.dropDownType === DropDownType.HYBRID) {
|
||||
dropDown.autoSize();
|
||||
dropDown.x = -dropDown.getWidth();
|
||||
dropDown.y = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setCursor(cursor: number): void {
|
||||
if (this.lastCursor > -1) {
|
||||
if (this.dropDowns[this.lastCursor].visible) {
|
||||
this.dropDowns[this.lastCursor].setVisible(false);
|
||||
this.dropDowns[cursor].setVisible(true);
|
||||
this.dropDowns[cursor].resetCursor();
|
||||
}
|
||||
if (this.lastCursor > -1 && this.dropDowns[this.lastCursor].visible) {
|
||||
this.dropDowns[this.lastCursor].setVisible(false);
|
||||
this.dropDowns[cursor].setVisible(true);
|
||||
this.dropDowns[cursor].resetCursor();
|
||||
}
|
||||
|
||||
this.cursorObj.setPosition(this.labels[cursor].x - this.cursorOffset + 2, 6);
|
||||
|
@ -234,9 +234,9 @@ export class LoginFormUiHandler extends FormModalUiHandler {
|
||||
const dataKeys = localStorageKeys.filter(ls => ls.indexOf(keyToFind) >= 0);
|
||||
if (dataKeys.length > 0 && dataKeys.length <= 2) {
|
||||
const options: OptionSelectItem[] = [];
|
||||
for (let i = 0; i < dataKeys.length; i++) {
|
||||
for (const key of dataKeys) {
|
||||
options.push({
|
||||
label: dataKeys[i].replace(keyToFind, ""),
|
||||
label: key.replace(keyToFind, ""),
|
||||
handler: () => {
|
||||
globalScene.ui.revertMode();
|
||||
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
|
||||
const localStorageKeys = Object.keys(localStorage); // this gets the keys for localStorage
|
||||
const keyToFind = "data_";
|
||||
@ -270,20 +270,19 @@ export class LoginFormUiHandler extends FormModalUiHandler {
|
||||
const sessionKeys = localStorageKeys.filter(ls => ls.indexOf(sessionKeyToFind) >= 0);
|
||||
if (dataKeys.length > 0 || sessionKeys.length > 0) {
|
||||
const zip = new JSZip();
|
||||
for (let i = 0; i < dataKeys.length; i++) {
|
||||
zip.file(dataKeys[i] + ".prsv", localStorage.getItem(dataKeys[i])!);
|
||||
for (const dataKey of dataKeys) {
|
||||
zip.file(dataKey + ".prsv", localStorage.getItem(dataKey)!);
|
||||
}
|
||||
for (let i = 0; i < sessionKeys.length; i++) {
|
||||
zip.file(sessionKeys[i] + ".prsv", localStorage.getItem(sessionKeys[i])!);
|
||||
for (const sessionKey of sessionKeys) {
|
||||
zip.file(sessionKey + ".prsv", localStorage.getItem(sessionKey)!);
|
||||
}
|
||||
zip.generateAsync({ type: "blob" }).then(content => {
|
||||
const url = URL.createObjectURL(content);
|
||||
const a = document.createElement("a");
|
||||
a.href = url;
|
||||
a.download = "pokerogue_saves.zip";
|
||||
a.click();
|
||||
URL.revokeObjectURL(url);
|
||||
});
|
||||
const content = await zip.generateAsync({ type: "blob" });
|
||||
const url = URL.createObjectURL(content);
|
||||
const a = document.createElement("a");
|
||||
a.href = url;
|
||||
a.download = "pokerogue_saves.zip";
|
||||
a.click();
|
||||
URL.revokeObjectURL(url);
|
||||
} else {
|
||||
return onFail(this.ERR_NO_SAVES);
|
||||
}
|
||||
|
@ -108,17 +108,17 @@ export abstract class MessageUiHandler extends AwaitableUiHandler {
|
||||
const textWords = text.split(" ");
|
||||
let lastLineCount = 1;
|
||||
let newText = "";
|
||||
for (let w = 0; w < textWords.length; w++) {
|
||||
const nextWordText = newText ? `${newText} ${textWords[w]}` : textWords[w];
|
||||
for (const textWord of textWords) {
|
||||
const nextWordText = newText ? `${newText} ${textWord}` : textWord;
|
||||
|
||||
if (textWords[w].includes("\n")) {
|
||||
if (textWord.includes("\n")) {
|
||||
newText = nextWordText;
|
||||
lastLineCount++;
|
||||
} else {
|
||||
const lineCount = this.message.runWordWrap(nextWordText).split(/\n/g).length;
|
||||
if (lineCount > lastLineCount) {
|
||||
lastLineCount = lineCount;
|
||||
newText = `${newText}\n${textWords[w]}`;
|
||||
newText = `${newText}\n${textWord}`;
|
||||
} else {
|
||||
newText = nextWordText;
|
||||
}
|
||||
|
@ -480,12 +480,10 @@ export class ModifierSelectUiHandler extends AwaitableUiHandler {
|
||||
}
|
||||
} else if (this.cursor) {
|
||||
success = this.setCursor(this.cursor - 1);
|
||||
} else if (this.rowCursor === 1 && this.options.length === 0) {
|
||||
success = false;
|
||||
} else {
|
||||
if (this.rowCursor === 1 && this.options.length === 0) {
|
||||
success = false;
|
||||
} else {
|
||||
success = this.setCursor(this.getRowItems(this.rowCursor) - 1);
|
||||
}
|
||||
success = this.setCursor(this.getRowItems(this.rowCursor) - 1);
|
||||
}
|
||||
break;
|
||||
case Button.RIGHT:
|
||||
@ -514,12 +512,10 @@ export class ModifierSelectUiHandler extends AwaitableUiHandler {
|
||||
}
|
||||
} else if (this.cursor < this.getRowItems(this.rowCursor) - 1) {
|
||||
success = this.setCursor(this.cursor + 1);
|
||||
} else if (this.rowCursor === 1 && this.options.length === 0) {
|
||||
success = this.setRowCursor(0);
|
||||
} else {
|
||||
if (this.rowCursor === 1 && this.options.length === 0) {
|
||||
success = this.setRowCursor(0);
|
||||
} else {
|
||||
success = this.setCursor(0);
|
||||
}
|
||||
success = this.setCursor(0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -156,14 +156,12 @@ export class MysteryEncounterUiHandler extends UiHandler {
|
||||
selected.optionMode === MysteryEncounterOptionMode.DISABLED_OR_SPECIAL))
|
||||
) {
|
||||
success = false;
|
||||
} else if (
|
||||
(globalScene.phaseManager.getCurrentPhase() as MysteryEncounterPhase).handleOptionSelect(selected, cursor)
|
||||
) {
|
||||
success = true;
|
||||
} else {
|
||||
if (
|
||||
(globalScene.phaseManager.getCurrentPhase() as MysteryEncounterPhase).handleOptionSelect(selected, cursor)
|
||||
) {
|
||||
success = true;
|
||||
} else {
|
||||
ui.playError();
|
||||
}
|
||||
ui.playError();
|
||||
}
|
||||
} else {
|
||||
// TODO: If we need to handle cancel option? Maybe default logic to leave/run from encounter idk
|
||||
|
@ -614,34 +614,32 @@ export class PartyUiHandler extends MessageUiHandler {
|
||||
|
||||
// TODO: Might need to check here for when this.transferMode is active.
|
||||
private processModifierTransferModeLeftRightInput(button: Button) {
|
||||
if (!this.isItemManageMode()) {
|
||||
return false;
|
||||
}
|
||||
let success = false;
|
||||
const option = this.options[this.optionsCursor];
|
||||
if (button === Button.LEFT) {
|
||||
/** Decrease quantity for the current item and update UI */
|
||||
if (this.isItemManageMode()) {
|
||||
this.transferQuantities[option] =
|
||||
this.transferQuantities[option] === 1
|
||||
? this.transferQuantitiesMax[option]
|
||||
: this.transferQuantities[option] - 1;
|
||||
this.updateOptions();
|
||||
success = this.setCursor(
|
||||
this.optionsCursor,
|
||||
); /** Place again the cursor at the same position. Necessary, otherwise the cursor disappears */
|
||||
}
|
||||
this.transferQuantities[option] =
|
||||
this.transferQuantities[option] === 1
|
||||
? this.transferQuantitiesMax[option]
|
||||
: this.transferQuantities[option] - 1;
|
||||
this.updateOptions();
|
||||
success = this.setCursor(
|
||||
this.optionsCursor,
|
||||
); /** Place again the cursor at the same position. Necessary, otherwise the cursor disappears */
|
||||
}
|
||||
|
||||
if (button === Button.RIGHT) {
|
||||
/** Increase quantity for the current item and update UI */
|
||||
if (this.isItemManageMode()) {
|
||||
this.transferQuantities[option] =
|
||||
this.transferQuantities[option] === this.transferQuantitiesMax[option]
|
||||
? 1
|
||||
: this.transferQuantities[option] + 1;
|
||||
this.updateOptions();
|
||||
success = this.setCursor(
|
||||
this.optionsCursor,
|
||||
); /** Place again the cursor at the same position. Necessary, otherwise the cursor disappears */
|
||||
}
|
||||
this.transferQuantities[option] =
|
||||
this.transferQuantities[option] === this.transferQuantitiesMax[option]
|
||||
? 1
|
||||
: this.transferQuantities[option] + 1;
|
||||
this.updateOptions();
|
||||
success = this.setCursor(
|
||||
this.optionsCursor,
|
||||
); /** Place again the cursor at the same position. Necessary, otherwise the cursor disappears */
|
||||
}
|
||||
return success;
|
||||
}
|
||||
@ -930,10 +928,8 @@ export class PartyUiHandler extends MessageUiHandler {
|
||||
return this.moveOptionCursor(button);
|
||||
}
|
||||
|
||||
if (button === Button.LEFT || button === Button.RIGHT) {
|
||||
if (this.isItemManageMode()) {
|
||||
return this.processModifierTransferModeLeftRightInput(button);
|
||||
}
|
||||
if ((button === Button.LEFT || button === Button.RIGHT) && this.isItemManageMode()) {
|
||||
return this.processModifierTransferModeLeftRightInput(button);
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -1215,11 +1211,9 @@ export class PartyUiHandler extends MessageUiHandler {
|
||||
isScroll = true;
|
||||
this.optionsScrollCursor++;
|
||||
}
|
||||
} else {
|
||||
if (!cursor && this.optionsScrollCursor) {
|
||||
isScroll = true;
|
||||
this.optionsScrollCursor--;
|
||||
}
|
||||
} else if (!cursor && this.optionsScrollCursor) {
|
||||
isScroll = true;
|
||||
this.optionsScrollCursor--;
|
||||
}
|
||||
if (isScroll && this.optionsScrollCursor === 1) {
|
||||
this.optionsScrollCursor += isDown ? 1 : -1;
|
||||
@ -1573,12 +1567,10 @@ export class PartyUiHandler extends MessageUiHandler {
|
||||
optionName = `${modifier.active ? i18next.t("partyUiHandler:DEACTIVATE") : i18next.t("partyUiHandler:ACTIVATE")} ${modifier.type.name}`;
|
||||
} else if (option === PartyOption.UNPAUSE_EVOLUTION) {
|
||||
optionName = `${pokemon.pauseEvolutions ? i18next.t("partyUiHandler:UNPAUSE_EVOLUTION") : i18next.t("partyUiHandler:PAUSE_EVOLUTION")}`;
|
||||
} else if (this.localizedOptions.includes(option)) {
|
||||
optionName = i18next.t(`partyUiHandler:${PartyOption[option]}`);
|
||||
} else {
|
||||
if (this.localizedOptions.includes(option)) {
|
||||
optionName = i18next.t(`partyUiHandler:${PartyOption[option]}`);
|
||||
} else {
|
||||
optionName = toTitleCase(PartyOption[option]);
|
||||
}
|
||||
optionName = toTitleCase(PartyOption[option]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1654,11 +1646,11 @@ export class PartyUiHandler extends MessageUiHandler {
|
||||
this.transferMode = false;
|
||||
this.transferAll = false;
|
||||
this.partySlots[this.transferCursor].setTransfer(false);
|
||||
for (let i = 0; i < this.partySlots.length; i++) {
|
||||
this.partySlots[i].slotDescriptionLabel.setVisible(false);
|
||||
this.partySlots[i].slotHpBar.setVisible(true);
|
||||
this.partySlots[i].slotHpOverlay.setVisible(true);
|
||||
this.partySlots[i].slotHpText.setVisible(true);
|
||||
for (const partySlot of this.partySlots) {
|
||||
partySlot.slotDescriptionLabel.setVisible(false);
|
||||
partySlot.slotHpBar.setVisible(true);
|
||||
partySlot.slotHpOverlay.setVisible(true);
|
||||
partySlot.slotHpText.setVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1069,12 +1069,10 @@ export class PokedexPageUiHandler extends MessageUiHandler {
|
||||
) {
|
||||
starterAttributes.female = !starterAttributes.female;
|
||||
}
|
||||
} else {
|
||||
if (caughtAttr & DexAttr.FEMALE) {
|
||||
starterAttributes.female = true;
|
||||
} else if (caughtAttr & DexAttr.MALE) {
|
||||
starterAttributes.female = false;
|
||||
}
|
||||
} else if (caughtAttr & DexAttr.FEMALE) {
|
||||
starterAttributes.female = true;
|
||||
} else if (caughtAttr & DexAttr.MALE) {
|
||||
starterAttributes.female = false;
|
||||
}
|
||||
|
||||
return starterAttributes;
|
||||
@ -1839,10 +1837,8 @@ export class PokedexPageUiHandler extends MessageUiHandler {
|
||||
if (this.isCaught() & DexAttr.VARIANT_2) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (this.isCaught() & DexAttr.VARIANT_3) {
|
||||
break;
|
||||
}
|
||||
} else if (this.isCaught() & DexAttr.VARIANT_3) {
|
||||
break;
|
||||
}
|
||||
} while (newVariant !== props.variant);
|
||||
|
||||
@ -2362,10 +2358,8 @@ export class PokedexPageUiHandler extends MessageUiHandler {
|
||||
const defaultDexAttr = this.getCurrentDexProps(species.speciesId);
|
||||
// Set default attributes if for some reason starterAttributes does not exist or attributes missing
|
||||
const props: StarterAttributes = globalScene.gameData.getSpeciesDexAttrProps(species, defaultDexAttr);
|
||||
if (starterAttributes?.variant && !Number.isNaN(starterAttributes.variant)) {
|
||||
if (props.shiny) {
|
||||
props.variant = starterAttributes.variant as Variant;
|
||||
}
|
||||
if (starterAttributes?.variant && !Number.isNaN(starterAttributes.variant) && props.shiny) {
|
||||
props.variant = starterAttributes.variant as Variant;
|
||||
}
|
||||
props.form = starterAttributes?.form ?? props.form;
|
||||
props.female = starterAttributes?.female ?? props.female;
|
||||
@ -2778,17 +2772,15 @@ export class PokedexPageUiHandler extends MessageUiHandler {
|
||||
props += DexAttr.SHINY;
|
||||
if (this.starterAttributes?.variant !== undefined) {
|
||||
props += BigInt(Math.pow(2, this.starterAttributes?.variant)) * DexAttr.DEFAULT_VARIANT;
|
||||
} else {
|
||||
/* This calculates the correct variant if there's no starter preferences for it.
|
||||
/* This chunk 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
|
||||
*/
|
||||
if ((caughtAttr & DexAttr.VARIANT_3) > 0) {
|
||||
props += DexAttr.VARIANT_3;
|
||||
} else if ((caughtAttr & DexAttr.VARIANT_2) > 0) {
|
||||
props += DexAttr.VARIANT_2;
|
||||
} else {
|
||||
props += DexAttr.DEFAULT_VARIANT;
|
||||
}
|
||||
} else if ((caughtAttr & DexAttr.VARIANT_3) > 0) {
|
||||
props += DexAttr.VARIANT_3;
|
||||
} else if ((caughtAttr & DexAttr.VARIANT_2) > 0) {
|
||||
props += DexAttr.VARIANT_2;
|
||||
} else {
|
||||
props += DexAttr.DEFAULT_VARIANT;
|
||||
}
|
||||
} else {
|
||||
props += DexAttr.NON_SHINY;
|
||||
|
@ -709,11 +709,12 @@ export class PokedexUiHandler extends MessageUiHandler {
|
||||
}
|
||||
}
|
||||
|
||||
if (starterAttributes.female !== undefined) {
|
||||
if (!(starterAttributes.female ? caughtAttr & DexAttr.FEMALE : caughtAttr & DexAttr.MALE)) {
|
||||
// requested gender wasn't unlocked, purging setting
|
||||
starterAttributes.female = undefined;
|
||||
}
|
||||
if (
|
||||
starterAttributes.female !== undefined &&
|
||||
!(starterAttributes.female ? caughtAttr & DexAttr.FEMALE : caughtAttr & DexAttr.MALE)
|
||||
) {
|
||||
// requested gender wasn't unlocked, purging setting
|
||||
starterAttributes.female = undefined;
|
||||
}
|
||||
|
||||
if (starterAttributes.ability !== undefined) {
|
||||
@ -1187,78 +1188,76 @@ export class PokedexUiHandler extends MessageUiHandler {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (button === Button.ACTION) {
|
||||
ui.setOverlayMode(UiMode.POKEDEX_PAGE, this.lastSpecies, null, this.filteredIndices);
|
||||
success = true;
|
||||
} else {
|
||||
if (button === Button.ACTION) {
|
||||
ui.setOverlayMode(UiMode.POKEDEX_PAGE, this.lastSpecies, null, this.filteredIndices);
|
||||
success = true;
|
||||
} else {
|
||||
switch (button) {
|
||||
case Button.UP:
|
||||
if (currentRow > 0) {
|
||||
if (this.scrollCursor > 0 && currentRow - this.scrollCursor === 0) {
|
||||
this.scrollCursor--;
|
||||
this.updateScroll();
|
||||
success = this.setCursor(this.cursor);
|
||||
} else {
|
||||
success = this.setCursor(this.cursor - 9);
|
||||
}
|
||||
} else {
|
||||
this.filterBarCursor = this.filterBar.getNearestFilter(this.pokemonContainers[this.cursor]);
|
||||
this.setFilterMode(true);
|
||||
success = true;
|
||||
}
|
||||
break;
|
||||
case Button.DOWN:
|
||||
if (currentRow < numOfRows - 1 && this.cursor + 9 < this.filteredPokemonData.length) {
|
||||
// not last row
|
||||
if (currentRow - this.scrollCursor === 8) {
|
||||
// last row of visible pokemon
|
||||
this.scrollCursor++;
|
||||
this.updateScroll();
|
||||
success = this.setCursor(this.cursor);
|
||||
} else {
|
||||
success = this.setCursor(this.cursor + 9);
|
||||
}
|
||||
} else if (numOfRows > 1) {
|
||||
// DOWN from last row of pokemon > Wrap around to first row
|
||||
this.scrollCursor = 0;
|
||||
switch (button) {
|
||||
case Button.UP:
|
||||
if (currentRow > 0) {
|
||||
if (this.scrollCursor > 0 && currentRow - this.scrollCursor === 0) {
|
||||
this.scrollCursor--;
|
||||
this.updateScroll();
|
||||
success = this.setCursor(this.cursor % 9);
|
||||
success = this.setCursor(this.cursor);
|
||||
} else {
|
||||
// DOWN from single row of pokemon > Go to filters
|
||||
this.filterBarCursor = this.filterBar.getNearestFilter(this.pokemonContainers[this.cursor]);
|
||||
this.setFilterMode(true);
|
||||
success = true;
|
||||
success = this.setCursor(this.cursor - 9);
|
||||
}
|
||||
break;
|
||||
case Button.LEFT:
|
||||
if (this.cursor % 9 !== 0) {
|
||||
success = this.setCursor(this.cursor - 1);
|
||||
} else {
|
||||
// LEFT from filtered pokemon, on the left edge
|
||||
this.filterTextCursor = this.filterText.getNearestFilter(this.pokemonContainers[this.cursor]);
|
||||
this.setFilterTextMode(true);
|
||||
success = true;
|
||||
}
|
||||
break;
|
||||
case Button.RIGHT:
|
||||
// is not right edge
|
||||
if (this.cursor % 9 < (currentRow < numOfRows - 1 ? 8 : (numberOfStarters - 1) % 9)) {
|
||||
success = this.setCursor(this.cursor + 1);
|
||||
} else {
|
||||
// RIGHT from filtered pokemon, on the right edge
|
||||
this.filterTextCursor = this.filterText.getNearestFilter(this.pokemonContainers[this.cursor]);
|
||||
this.setFilterTextMode(true);
|
||||
success = true;
|
||||
}
|
||||
break;
|
||||
case Button.CYCLE_FORM: {
|
||||
const species = this.pokemonContainers[this.cursor].species;
|
||||
if (this.canShowFormTray) {
|
||||
success = this.openFormTray(species);
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
this.filterBarCursor = this.filterBar.getNearestFilter(this.pokemonContainers[this.cursor]);
|
||||
this.setFilterMode(true);
|
||||
success = true;
|
||||
}
|
||||
break;
|
||||
case Button.DOWN:
|
||||
if (currentRow < numOfRows - 1 && this.cursor + 9 < this.filteredPokemonData.length) {
|
||||
// not last row
|
||||
if (currentRow - this.scrollCursor === 8) {
|
||||
// last row of visible pokemon
|
||||
this.scrollCursor++;
|
||||
this.updateScroll();
|
||||
success = this.setCursor(this.cursor);
|
||||
} else {
|
||||
success = this.setCursor(this.cursor + 9);
|
||||
}
|
||||
} else if (numOfRows > 1) {
|
||||
// DOWN from last row of pokemon > Wrap around to first row
|
||||
this.scrollCursor = 0;
|
||||
this.updateScroll();
|
||||
success = this.setCursor(this.cursor % 9);
|
||||
} else {
|
||||
// DOWN from single row of pokemon > Go to filters
|
||||
this.filterBarCursor = this.filterBar.getNearestFilter(this.pokemonContainers[this.cursor]);
|
||||
this.setFilterMode(true);
|
||||
success = true;
|
||||
}
|
||||
break;
|
||||
case Button.LEFT:
|
||||
if (this.cursor % 9 !== 0) {
|
||||
success = this.setCursor(this.cursor - 1);
|
||||
} else {
|
||||
// LEFT from filtered pokemon, on the left edge
|
||||
this.filterTextCursor = this.filterText.getNearestFilter(this.pokemonContainers[this.cursor]);
|
||||
this.setFilterTextMode(true);
|
||||
success = true;
|
||||
}
|
||||
break;
|
||||
case Button.RIGHT:
|
||||
// is not right edge
|
||||
if (this.cursor % 9 < (currentRow < numOfRows - 1 ? 8 : (numberOfStarters - 1) % 9)) {
|
||||
success = this.setCursor(this.cursor + 1);
|
||||
} else {
|
||||
// RIGHT from filtered pokemon, on the right edge
|
||||
this.filterTextCursor = this.filterText.getNearestFilter(this.pokemonContainers[this.cursor]);
|
||||
this.setFilterTextMode(true);
|
||||
success = true;
|
||||
}
|
||||
break;
|
||||
case Button.CYCLE_FORM: {
|
||||
const species = this.pokemonContainers[this.cursor].species;
|
||||
if (this.canShowFormTray) {
|
||||
success = this.openFormTray(species);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1453,12 +1452,10 @@ export class PokedexUiHandler extends MessageUiHandler {
|
||||
} else {
|
||||
data.passive1 = false;
|
||||
}
|
||||
} else if (starterData.passiveAttr > 0) {
|
||||
data.passive2 = true;
|
||||
} else {
|
||||
if (starterData.passiveAttr > 0) {
|
||||
data.passive2 = true;
|
||||
} else {
|
||||
data.passive2 = false;
|
||||
}
|
||||
data.passive2 = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2334,17 +2331,15 @@ export class PokedexUiHandler extends MessageUiHandler {
|
||||
props += DexAttr.SHINY;
|
||||
if (this.starterPreferences[speciesId]?.variant !== undefined) {
|
||||
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 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;
|
||||
} else if ((caughtAttr & DexAttr.VARIANT_2) > 0) {
|
||||
props += DexAttr.VARIANT_2;
|
||||
} else {
|
||||
props += DexAttr.DEFAULT_VARIANT;
|
||||
}
|
||||
props += DexAttr.VARIANT_3;
|
||||
} else if ((caughtAttr & DexAttr.VARIANT_2) > 0) {
|
||||
props += DexAttr.VARIANT_2;
|
||||
} else {
|
||||
props += DexAttr.DEFAULT_VARIANT;
|
||||
}
|
||||
} else {
|
||||
props += DexAttr.NON_SHINY;
|
||||
|
@ -683,32 +683,33 @@ export class RunInfoUiHandler extends UiHandler {
|
||||
*/
|
||||
private challengeParser(): string[] {
|
||||
const rules: string[] = [];
|
||||
for (let i = 0; i < this.runInfo.challenges.length; i++) {
|
||||
if (this.runInfo.challenges[i].value !== 0) {
|
||||
switch (this.runInfo.challenges[i].id) {
|
||||
case Challenges.SINGLE_GENERATION:
|
||||
rules.push(i18next.t(`runHistory:challengeMonoGen${this.runInfo.challenges[i].value}`));
|
||||
break;
|
||||
case Challenges.SINGLE_TYPE: {
|
||||
const typeRule = PokemonType[this.runInfo.challenges[i].value - 1];
|
||||
const typeTextColor = `[color=${TypeColor[typeRule]}]`;
|
||||
const typeShadowColor = `[shadow=${TypeShadow[typeRule]}]`;
|
||||
const typeText =
|
||||
typeTextColor + typeShadowColor + i18next.t(`pokemonInfo:Type.${typeRule}`)! + "[/color]" + "[/shadow]";
|
||||
rules.push(typeText);
|
||||
break;
|
||||
}
|
||||
case Challenges.INVERSE_BATTLE:
|
||||
rules.push(i18next.t("challenges:inverseBattle.shortName"));
|
||||
break;
|
||||
default: {
|
||||
const localizationKey = Challenges[this.runInfo.challenges[i].id]
|
||||
.split("_")
|
||||
.map((f, i) => (i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase()))
|
||||
.join("");
|
||||
rules.push(i18next.t(`challenges:${localizationKey}.name`));
|
||||
break;
|
||||
}
|
||||
for (const challenge of this.runInfo.challenges) {
|
||||
if (challenge.value === 0) {
|
||||
continue;
|
||||
}
|
||||
switch (challenge.id) {
|
||||
case Challenges.SINGLE_GENERATION:
|
||||
rules.push(i18next.t(`runHistory:challengeMonoGen${challenge.value}`));
|
||||
break;
|
||||
case Challenges.SINGLE_TYPE: {
|
||||
const typeRule = PokemonType[challenge.value - 1];
|
||||
const typeTextColor = `[color=${TypeColor[typeRule]}]`;
|
||||
const typeShadowColor = `[shadow=${TypeShadow[typeRule]}]`;
|
||||
const typeText =
|
||||
typeTextColor + typeShadowColor + i18next.t(`pokemonInfo:Type.${typeRule}`)! + "[/color][/shadow]";
|
||||
rules.push(typeText);
|
||||
break;
|
||||
}
|
||||
case Challenges.INVERSE_BATTLE:
|
||||
rules.push(i18next.t("challenges:inverseBattle.shortName"));
|
||||
break;
|
||||
default: {
|
||||
const localizationKey = Challenges[challenge.id]
|
||||
.split("_")
|
||||
.map((f, i) => (i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase()))
|
||||
.join("");
|
||||
rules.push(i18next.t(`challenges:${localizationKey}.name`));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -336,7 +336,7 @@ export class StarterSelectUiHandler extends MessageUiHandler {
|
||||
private teraLabel: Phaser.GameObjects.Text;
|
||||
private goFilterLabel: Phaser.GameObjects.Text;
|
||||
/** Group holding the UI elements appearing in the instructionsContainer */
|
||||
/* TODO: Uncomment this once our testing infra supports mocks of `Phaser.GameObject.Group`
|
||||
/* TODO: Uncomment this once our testing infra supports mocks of `Phaser.GameObject.Group`
|
||||
private instructionElemGroup: Phaser.GameObjects.Group;
|
||||
*/
|
||||
|
||||
@ -1217,11 +1217,12 @@ export class StarterSelectUiHandler extends MessageUiHandler {
|
||||
}
|
||||
}
|
||||
|
||||
if (starterAttributes.female !== undefined) {
|
||||
if (!(starterAttributes.female ? caughtAttr & DexAttr.FEMALE : caughtAttr & DexAttr.MALE)) {
|
||||
// requested gender wasn't unlocked, purging setting
|
||||
starterAttributes.female = undefined;
|
||||
}
|
||||
if (
|
||||
starterAttributes.female !== undefined &&
|
||||
!(starterAttributes.female ? caughtAttr & DexAttr.FEMALE : caughtAttr & DexAttr.MALE)
|
||||
) {
|
||||
// requested gender wasn't unlocked, purging setting
|
||||
starterAttributes.female = undefined;
|
||||
}
|
||||
|
||||
if (starterAttributes.ability !== undefined) {
|
||||
@ -2342,11 +2343,9 @@ export class StarterSelectUiHandler extends MessageUiHandler {
|
||||
// TODO: is this bang correct?
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (this.speciesStarterDexEntry!.caughtAttr & DexAttr.VARIANT_3) {
|
||||
// TODO: is this bang correct?
|
||||
break;
|
||||
}
|
||||
} else if (this.speciesStarterDexEntry!.caughtAttr & DexAttr.VARIANT_3) {
|
||||
// TODO: is this bang correct?
|
||||
break;
|
||||
}
|
||||
} while (newVariant !== props.variant);
|
||||
starterAttributes.variant = newVariant; // store the selected variant
|
||||
@ -2422,10 +2421,8 @@ export class StarterSelectUiHandler extends MessageUiHandler {
|
||||
newAbilityIndex = (newAbilityIndex + 1) % abilityCount;
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
if (abilityAttr & AbilityAttr.ABILITY_HIDDEN) {
|
||||
break;
|
||||
}
|
||||
} else if (abilityAttr & AbilityAttr.ABILITY_HIDDEN) {
|
||||
break;
|
||||
}
|
||||
} while (newAbilityIndex !== this.abilityCursor);
|
||||
starterAttributes.ability = newAbilityIndex; // store the selected ability
|
||||
@ -2972,8 +2969,7 @@ export class StarterSelectUiHandler extends MessageUiHandler {
|
||||
}
|
||||
|
||||
// this updates icons for previously saved pokemon
|
||||
for (let i = 0; i < this.validStarterContainers.length; i++) {
|
||||
const currentFilteredContainer = this.validStarterContainers[i];
|
||||
for (const currentFilteredContainer of this.validStarterContainers) {
|
||||
const starterSprite = currentFilteredContainer.icon as Phaser.GameObjects.Sprite;
|
||||
|
||||
const currentDexAttr = this.getCurrentDexProps(currentFilteredContainer.species.speciesId);
|
||||
@ -3562,10 +3558,8 @@ export class StarterSelectUiHandler extends MessageUiHandler {
|
||||
// load default nature from stater save data, if set
|
||||
const defaultNature = starterAttributes?.nature || globalScene.gameData.getSpeciesDefaultNature(species);
|
||||
props = globalScene.gameData.getSpeciesDexAttrProps(species, defaultDexAttr);
|
||||
if (starterAttributes?.variant && !Number.isNaN(starterAttributes.variant)) {
|
||||
if (props.shiny) {
|
||||
props.variant = starterAttributes.variant as Variant;
|
||||
}
|
||||
if (starterAttributes?.variant && !Number.isNaN(starterAttributes.variant) && props.shiny) {
|
||||
props.variant = starterAttributes.variant as Variant;
|
||||
}
|
||||
props.formIndex = starterAttributes?.form ?? props.formIndex;
|
||||
props.female = starterAttributes?.female ?? props.female;
|
||||
@ -4350,13 +4344,13 @@ export class StarterSelectUiHandler extends MessageUiHandler {
|
||||
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
|
||||
*/
|
||||
isPartyValid(): boolean {
|
||||
let canStart = false;
|
||||
for (let s = 0; s < this.starterSpecies.length; s++) {
|
||||
const species = this.starterSpecies[s];
|
||||
for (const species of this.starterSpecies) {
|
||||
const isValidForChallenge = checkStarterValidForChallenge(
|
||||
species,
|
||||
globalScene.gameData.getSpeciesDexAttrProps(species, this.getCurrentDexProps(species.speciesId)),
|
||||
@ -4400,17 +4394,15 @@ export class StarterSelectUiHandler extends MessageUiHandler {
|
||||
props += DexAttr.SHINY;
|
||||
if (this.starterPreferences[speciesId]?.variant !== undefined) {
|
||||
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 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;
|
||||
} else if ((caughtAttr & DexAttr.VARIANT_2) > 0) {
|
||||
props += DexAttr.VARIANT_2;
|
||||
} else {
|
||||
props += DexAttr.DEFAULT_VARIANT;
|
||||
}
|
||||
props += DexAttr.VARIANT_3;
|
||||
} else if ((caughtAttr & DexAttr.VARIANT_2) > 0) {
|
||||
props += DexAttr.VARIANT_2;
|
||||
} else {
|
||||
props += DexAttr.DEFAULT_VARIANT;
|
||||
}
|
||||
} else {
|
||||
props += DexAttr.NON_SHINY;
|
||||
|
@ -515,33 +515,31 @@ export class SummaryUiHandler extends UiHandler {
|
||||
if (this.pokemon && this.moveCursor < this.pokemon.moveset.length) {
|
||||
if (this.summaryUiMode === SummaryUiMode.LEARN_MOVE) {
|
||||
this.moveSelectFunction?.(this.moveCursor);
|
||||
} else if (this.selectedMoveIndex === -1) {
|
||||
this.selectedMoveIndex = this.moveCursor;
|
||||
this.setCursor(this.moveCursor);
|
||||
} else {
|
||||
if (this.selectedMoveIndex === -1) {
|
||||
this.selectedMoveIndex = this.moveCursor;
|
||||
this.setCursor(this.moveCursor);
|
||||
} else {
|
||||
if (this.selectedMoveIndex !== this.moveCursor) {
|
||||
const tempMove = this.pokemon?.moveset[this.selectedMoveIndex];
|
||||
this.pokemon.moveset[this.selectedMoveIndex] = this.pokemon.moveset[this.moveCursor];
|
||||
this.pokemon.moveset[this.moveCursor] = tempMove;
|
||||
if (this.selectedMoveIndex !== this.moveCursor) {
|
||||
const tempMove = this.pokemon?.moveset[this.selectedMoveIndex];
|
||||
this.pokemon.moveset[this.selectedMoveIndex] = this.pokemon.moveset[this.moveCursor];
|
||||
this.pokemon.moveset[this.moveCursor] = tempMove;
|
||||
|
||||
const selectedMoveRow = this.moveRowsContainer.getAt(
|
||||
this.selectedMoveIndex,
|
||||
) as Phaser.GameObjects.Container;
|
||||
const switchMoveRow = this.moveRowsContainer.getAt(this.moveCursor) as Phaser.GameObjects.Container;
|
||||
const selectedMoveRow = this.moveRowsContainer.getAt(
|
||||
this.selectedMoveIndex,
|
||||
) as Phaser.GameObjects.Container;
|
||||
const switchMoveRow = this.moveRowsContainer.getAt(this.moveCursor) as Phaser.GameObjects.Container;
|
||||
|
||||
this.moveRowsContainer.moveTo(selectedMoveRow, this.moveCursor);
|
||||
this.moveRowsContainer.moveTo(switchMoveRow, this.selectedMoveIndex);
|
||||
this.moveRowsContainer.moveTo(selectedMoveRow, this.moveCursor);
|
||||
this.moveRowsContainer.moveTo(switchMoveRow, this.selectedMoveIndex);
|
||||
|
||||
selectedMoveRow.setY(this.moveCursor * 16);
|
||||
switchMoveRow.setY(this.selectedMoveIndex * 16);
|
||||
}
|
||||
selectedMoveRow.setY(this.moveCursor * 16);
|
||||
switchMoveRow.setY(this.selectedMoveIndex * 16);
|
||||
}
|
||||
|
||||
this.selectedMoveIndex = -1;
|
||||
if (this.selectedMoveCursorObj) {
|
||||
this.selectedMoveCursorObj.destroy();
|
||||
this.selectedMoveCursorObj = null;
|
||||
}
|
||||
this.selectedMoveIndex = -1;
|
||||
if (this.selectedMoveCursorObj) {
|
||||
this.selectedMoveCursorObj.destroy();
|
||||
this.selectedMoveCursorObj = null;
|
||||
}
|
||||
}
|
||||
success = true;
|
||||
@ -575,78 +573,76 @@ export class SummaryUiHandler extends UiHandler {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (button === Button.ACTION) {
|
||||
if (this.cursor === Page.MOVES) {
|
||||
this.showMoveSelect();
|
||||
success = true;
|
||||
} else if (this.cursor === Page.PROFILE && this.pokemon?.hasPassive()) {
|
||||
// if we're on the PROFILE page and this pokemon has a passive unlocked..
|
||||
// Since abilities are displayed by default, all we need to do is toggle visibility on all elements to show passives
|
||||
this.abilityContainer.nameText?.setVisible(!this.abilityContainer.descriptionText?.visible);
|
||||
this.abilityContainer.descriptionText?.setVisible(!this.abilityContainer.descriptionText.visible);
|
||||
this.abilityContainer.labelImage.setVisible(!this.abilityContainer.labelImage.visible);
|
||||
|
||||
this.passiveContainer.nameText?.setVisible(!this.passiveContainer.descriptionText?.visible);
|
||||
this.passiveContainer.descriptionText?.setVisible(!this.passiveContainer.descriptionText.visible);
|
||||
this.passiveContainer.labelImage.setVisible(!this.passiveContainer.labelImage.visible);
|
||||
} else if (this.cursor === Page.STATS) {
|
||||
//Show IVs
|
||||
this.permStatsContainer.setVisible(!this.permStatsContainer.visible);
|
||||
this.ivContainer.setVisible(!this.ivContainer.visible);
|
||||
}
|
||||
} else if (button === Button.CANCEL) {
|
||||
if (this.summaryUiMode === SummaryUiMode.LEARN_MOVE) {
|
||||
this.hideMoveSelect();
|
||||
} else {
|
||||
if (this.selectCallback instanceof Function) {
|
||||
const selectCallback = this.selectCallback;
|
||||
this.selectCallback = null;
|
||||
selectCallback();
|
||||
}
|
||||
|
||||
if (!fromPartyMode) {
|
||||
ui.setMode(UiMode.MESSAGE);
|
||||
} else {
|
||||
ui.setMode(UiMode.PARTY);
|
||||
}
|
||||
}
|
||||
} else if (button === Button.ACTION) {
|
||||
if (this.cursor === Page.MOVES) {
|
||||
this.showMoveSelect();
|
||||
success = true;
|
||||
} else if (this.cursor === Page.PROFILE && this.pokemon?.hasPassive()) {
|
||||
// if we're on the PROFILE page and this pokemon has a passive unlocked..
|
||||
// Since abilities are displayed by default, all we need to do is toggle visibility on all elements to show passives
|
||||
this.abilityContainer.nameText?.setVisible(!this.abilityContainer.descriptionText?.visible);
|
||||
this.abilityContainer.descriptionText?.setVisible(!this.abilityContainer.descriptionText.visible);
|
||||
this.abilityContainer.labelImage.setVisible(!this.abilityContainer.labelImage.visible);
|
||||
|
||||
this.passiveContainer.nameText?.setVisible(!this.passiveContainer.descriptionText?.visible);
|
||||
this.passiveContainer.descriptionText?.setVisible(!this.passiveContainer.descriptionText.visible);
|
||||
this.passiveContainer.labelImage.setVisible(!this.passiveContainer.labelImage.visible);
|
||||
} else if (this.cursor === Page.STATS) {
|
||||
//Show IVs
|
||||
this.permStatsContainer.setVisible(!this.permStatsContainer.visible);
|
||||
this.ivContainer.setVisible(!this.ivContainer.visible);
|
||||
}
|
||||
} else if (button === Button.CANCEL) {
|
||||
if (this.summaryUiMode === SummaryUiMode.LEARN_MOVE) {
|
||||
this.hideMoveSelect();
|
||||
} else {
|
||||
const pages = getEnumValues(Page);
|
||||
switch (button) {
|
||||
case Button.UP:
|
||||
case Button.DOWN: {
|
||||
if (this.summaryUiMode === SummaryUiMode.LEARN_MOVE) {
|
||||
break;
|
||||
}
|
||||
if (!fromPartyMode) {
|
||||
break;
|
||||
}
|
||||
const isDown = button === Button.DOWN;
|
||||
const party = globalScene.getPlayerParty();
|
||||
const partyMemberIndex = this.pokemon ? party.indexOf(this.pokemon) : -1;
|
||||
if ((isDown && partyMemberIndex < party.length - 1) || (!isDown && partyMemberIndex)) {
|
||||
const page = this.cursor;
|
||||
this.clear();
|
||||
this.show([party[partyMemberIndex + (isDown ? 1 : -1)], this.summaryUiMode, page]);
|
||||
}
|
||||
if (this.selectCallback instanceof Function) {
|
||||
const selectCallback = this.selectCallback;
|
||||
this.selectCallback = null;
|
||||
selectCallback();
|
||||
}
|
||||
|
||||
if (!fromPartyMode) {
|
||||
ui.setMode(UiMode.MESSAGE);
|
||||
} else {
|
||||
ui.setMode(UiMode.PARTY);
|
||||
}
|
||||
}
|
||||
success = true;
|
||||
} else {
|
||||
const pages = getEnumValues(Page);
|
||||
switch (button) {
|
||||
case Button.UP:
|
||||
case Button.DOWN: {
|
||||
if (this.summaryUiMode === SummaryUiMode.LEARN_MOVE) {
|
||||
break;
|
||||
}
|
||||
case Button.LEFT:
|
||||
if (this.cursor) {
|
||||
success = this.setCursor(this.cursor - 1);
|
||||
}
|
||||
break;
|
||||
case Button.RIGHT:
|
||||
if (this.cursor < pages.length - 1) {
|
||||
success = this.setCursor(this.cursor + 1);
|
||||
if (this.summaryUiMode === SummaryUiMode.LEARN_MOVE && this.cursor === Page.MOVES) {
|
||||
this.moveSelect = true;
|
||||
}
|
||||
}
|
||||
if (!fromPartyMode) {
|
||||
break;
|
||||
}
|
||||
const isDown = button === Button.DOWN;
|
||||
const party = globalScene.getPlayerParty();
|
||||
const partyMemberIndex = this.pokemon ? party.indexOf(this.pokemon) : -1;
|
||||
if ((isDown && partyMemberIndex < party.length - 1) || (!isDown && partyMemberIndex)) {
|
||||
const page = this.cursor;
|
||||
this.clear();
|
||||
this.show([party[partyMemberIndex + (isDown ? 1 : -1)], this.summaryUiMode, page]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Button.LEFT:
|
||||
if (this.cursor) {
|
||||
success = this.setCursor(this.cursor - 1);
|
||||
}
|
||||
break;
|
||||
case Button.RIGHT:
|
||||
if (this.cursor < pages.length - 1) {
|
||||
success = this.setCursor(this.cursor + 1);
|
||||
if (this.summaryUiMode === SummaryUiMode.LEARN_MOVE && this.cursor === Page.MOVES) {
|
||||
this.moveSelect = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -70,11 +70,12 @@ export class TargetSelectUiHandler extends UiHandler {
|
||||
* @param user the Pokemon using the move
|
||||
*/
|
||||
resetCursor(cursorN: number, user: Pokemon): void {
|
||||
if (!isNullOrUndefined(cursorN)) {
|
||||
if ([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
|
||||
cursorN = -1;
|
||||
}
|
||||
if (
|
||||
!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
|
||||
cursorN = -1;
|
||||
}
|
||||
this.setCursor(this.targets.includes(cursorN) ? cursorN : this.targets[0]);
|
||||
}
|
||||
@ -92,10 +93,11 @@ export class TargetSelectUiHandler extends UiHandler {
|
||||
if (isNullOrUndefined(this.cursor0) || this.cursor0 !== this.cursor) {
|
||||
this.cursor0 = this.cursor;
|
||||
}
|
||||
} else if (this.fieldIndex === BattlerIndex.PLAYER_2) {
|
||||
if (isNullOrUndefined(this.cursor1) || this.cursor1 !== this.cursor) {
|
||||
this.cursor1 = this.cursor;
|
||||
}
|
||||
} else if (
|
||||
this.fieldIndex === BattlerIndex.PLAYER_2 &&
|
||||
(isNullOrUndefined(this.cursor1) || this.cursor1 !== this.cursor)
|
||||
) {
|
||||
this.cursor1 = this.cursor;
|
||||
}
|
||||
} else if (this.isMultipleTargets) {
|
||||
success = false;
|
||||
|
@ -117,10 +117,8 @@ export function updateWindowType(windowTypeIndex: number): void {
|
||||
} else if (object.texture?.key === "namebox") {
|
||||
themedObjects.push(object);
|
||||
}
|
||||
} else if (object instanceof Phaser.GameObjects.Sprite) {
|
||||
if (object.texture?.key === "bg") {
|
||||
themedObjects.push(object);
|
||||
}
|
||||
} else if (object instanceof Phaser.GameObjects.Sprite && object.texture?.key === "bg") {
|
||||
themedObjects.push(object);
|
||||
}
|
||||
};
|
||||
|
||||
|
10
src/ui/ui.ts
10
src/ui/ui.ts
@ -374,10 +374,12 @@ export class UI extends Phaser.GameObjects.Container {
|
||||
}
|
||||
|
||||
shouldSkipDialogue(i18nKey: string): boolean {
|
||||
if (i18next.exists(i18nKey)) {
|
||||
if (globalScene.skipSeenDialogues && globalScene.gameData.getSeenDialogues()[i18nKey] === true) {
|
||||
return true;
|
||||
}
|
||||
if (
|
||||
i18next.exists(i18nKey) &&
|
||||
globalScene.skipSeenDialogues &&
|
||||
globalScene.gameData.getSeenDialogues()[i18nKey] === true
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -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 { globalScene } from "#app/global-scene";
|
||||
import { pokemonEvolutions } from "#balance/pokemon-evolutions";
|
||||
|
@ -23,13 +23,11 @@ export function getCookie(cName: string): string {
|
||||
}
|
||||
const name = `${cName}=`;
|
||||
const ca = document.cookie.split(";");
|
||||
for (let i = 0; i < ca.length; i++) {
|
||||
let c = ca[i];
|
||||
while (c.charAt(0) === " ") {
|
||||
c = c.substring(1);
|
||||
}
|
||||
if (c.indexOf(name) === 0) {
|
||||
return c.substring(name.length, c.length);
|
||||
// Check all cookies in the document and see if any of them match, grabbing the first one whose value lines up
|
||||
for (const c of ca) {
|
||||
const cTrimmed = c.trim();
|
||||
if (cTrimmed.startsWith(name)) {
|
||||
return c.slice(name.length, c.length);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
|
@ -33,8 +33,8 @@ describe("Abilities - POWER CONSTRUCT", () => {
|
||||
});
|
||||
|
||||
test("check if fainted 50% Power Construct Pokemon switches to base form on arena reset", async () => {
|
||||
const baseForm = 2,
|
||||
completeForm = 4;
|
||||
const baseForm = 2;
|
||||
const completeForm = 4;
|
||||
game.override.startingWave(4).starterForms({
|
||||
[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 () => {
|
||||
const baseForm = 3,
|
||||
completeForm = 5;
|
||||
const baseForm = 3;
|
||||
const completeForm = 5;
|
||||
game.override.startingWave(4).starterForms({
|
||||
[SpeciesId.ZYGARDE]: completeForm,
|
||||
});
|
||||
|
@ -29,8 +29,8 @@ describe("Abilities - SCHOOLING", () => {
|
||||
});
|
||||
|
||||
test("check if fainted pokemon switches to base form on arena reset", async () => {
|
||||
const soloForm = 0,
|
||||
schoolForm = 1;
|
||||
const soloForm = 0;
|
||||
const schoolForm = 1;
|
||||
game.override.startingWave(4).starterForms({
|
||||
[SpeciesId.WISHIWASHI]: schoolForm,
|
||||
});
|
||||
|
@ -34,8 +34,8 @@ describe("Abilities - SHIELDS DOWN", () => {
|
||||
});
|
||||
|
||||
test("check if fainted pokemon switched to base form on arena reset", async () => {
|
||||
const meteorForm = 0,
|
||||
coreForm = 7;
|
||||
const meteorForm = 0;
|
||||
const coreForm = 7;
|
||||
game.override.startingWave(4).starterForms({
|
||||
[SpeciesId.MINIOR]: coreForm,
|
||||
});
|
||||
|
@ -76,9 +76,9 @@ describe("Escape chance calculations", () => {
|
||||
{ pokemonSpeedRatio: 2, escapeAttempts: 3, expectedEscapeChance: 80 },
|
||||
];
|
||||
|
||||
for (let i = 0; i < escapeChances.length; i++) {
|
||||
// sets the number of escape attempts to the required amount
|
||||
game.scene.currentBattle.escapeAttempts = escapeChances[i].escapeAttempts;
|
||||
for (const check of escapeChances) {
|
||||
// set the number of escape attempts to the required amount
|
||||
game.scene.currentBattle.escapeAttempts = check.escapeAttempts;
|
||||
// set playerPokemon's speed to a multiple of the enemySpeed
|
||||
vi.spyOn(playerPokemon[0], "stats", "get").mockReturnValue([
|
||||
20,
|
||||
@ -86,10 +86,10 @@ describe("Escape chance calculations", () => {
|
||||
20,
|
||||
20,
|
||||
20,
|
||||
escapeChances[i].pokemonSpeedRatio * enemySpeed,
|
||||
check.pokemonSpeedRatio * enemySpeed,
|
||||
]);
|
||||
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 },
|
||||
];
|
||||
|
||||
for (let i = 0; i < escapeChances.length; i++) {
|
||||
for (const check of escapeChances) {
|
||||
// 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
|
||||
vi.spyOn(playerPokemon[0], "stats", "get").mockReturnValue([
|
||||
20,
|
||||
@ -156,7 +156,7 @@ describe("Escape chance calculations", () => {
|
||||
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
|
||||
vi.spyOn(playerPokemon[1], "stats", "get").mockReturnValue([
|
||||
@ -165,15 +165,13 @@ describe("Escape chance calculations", () => {
|
||||
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);
|
||||
// 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
|
||||
expect(playerPokemon[0].stats[5] + playerPokemon[1].stats[5]).toBe(
|
||||
escapeChances[i].pokemonSpeedRatio * totalEnemySpeed,
|
||||
);
|
||||
expect(playerPokemon[0].stats[5] + playerPokemon[1].stats[5]).toBe(check.pokemonSpeedRatio * totalEnemySpeed);
|
||||
}
|
||||
});
|
||||
|
||||
@ -238,9 +236,9 @@ describe("Escape chance calculations", () => {
|
||||
{ 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
|
||||
game.scene.currentBattle.escapeAttempts = escapeChances[i].escapeAttempts;
|
||||
game.scene.currentBattle.escapeAttempts = check.escapeAttempts;
|
||||
// set playerPokemon's speed to a multiple of the enemySpeed
|
||||
vi.spyOn(playerPokemon[0], "stats", "get").mockReturnValue([
|
||||
20,
|
||||
@ -248,10 +246,10 @@ describe("Escape chance calculations", () => {
|
||||
20,
|
||||
20,
|
||||
20,
|
||||
escapeChances[i].pokemonSpeedRatio * enemySpeed,
|
||||
check.pokemonSpeedRatio * enemySpeed,
|
||||
]);
|
||||
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 },
|
||||
];
|
||||
|
||||
for (let i = 0; i < escapeChances.length; i++) {
|
||||
for (const check of escapeChances) {
|
||||
// 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
|
||||
vi.spyOn(playerPokemon[0], "stats", "get").mockReturnValue([
|
||||
20,
|
||||
@ -331,7 +329,7 @@ describe("Escape chance calculations", () => {
|
||||
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
|
||||
vi.spyOn(playerPokemon[1], "stats", "get").mockReturnValue([
|
||||
@ -340,15 +338,13 @@ describe("Escape chance calculations", () => {
|
||||
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);
|
||||
// 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
|
||||
expect(playerPokemon[0].stats[5] + playerPokemon[1].stats[5]).toBe(
|
||||
escapeChances[i].pokemonSpeedRatio * totalEnemySpeed,
|
||||
);
|
||||
expect(playerPokemon[0].stats[5] + playerPokemon[1].stats[5]).toBe(check.pokemonSpeedRatio * totalEnemySpeed);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -139,17 +139,15 @@ const getMockedMoveDamage = (defender: Pokemon, attacker: Pokemon, move: Move) =
|
||||
const multiplierHolder = new NumberHolder(1);
|
||||
const side = defender.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY;
|
||||
|
||||
if (globalScene.arena.getTagOnSide(ArenaTagType.AURORA_VEIL, side)) {
|
||||
if (move.getAttrs("CritOnlyAttr").length === 0) {
|
||||
globalScene.arena.applyTagsForSide(
|
||||
ArenaTagType.AURORA_VEIL,
|
||||
side,
|
||||
false,
|
||||
attacker,
|
||||
move.category,
|
||||
multiplierHolder,
|
||||
);
|
||||
}
|
||||
if (globalScene.arena.getTagOnSide(ArenaTagType.AURORA_VEIL, side) && move.getAttrs("CritOnlyAttr").length === 0) {
|
||||
globalScene.arena.applyTagsForSide(
|
||||
ArenaTagType.AURORA_VEIL,
|
||||
side,
|
||||
false,
|
||||
attacker,
|
||||
move.category,
|
||||
multiplierHolder,
|
||||
);
|
||||
}
|
||||
|
||||
return move.power * multiplierHolder.value;
|
||||
|
@ -127,17 +127,15 @@ const getMockedMoveDamage = (defender: Pokemon, attacker: Pokemon, move: Move) =
|
||||
const multiplierHolder = new NumberHolder(1);
|
||||
const side = defender.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY;
|
||||
|
||||
if (globalScene.arena.getTagOnSide(ArenaTagType.LIGHT_SCREEN, side)) {
|
||||
if (move.getAttrs("CritOnlyAttr").length === 0) {
|
||||
globalScene.arena.applyTagsForSide(
|
||||
ArenaTagType.LIGHT_SCREEN,
|
||||
side,
|
||||
false,
|
||||
attacker,
|
||||
move.category,
|
||||
multiplierHolder,
|
||||
);
|
||||
}
|
||||
if (globalScene.arena.getTagOnSide(ArenaTagType.LIGHT_SCREEN, side) && move.getAttrs("CritOnlyAttr").length === 0) {
|
||||
globalScene.arena.applyTagsForSide(
|
||||
ArenaTagType.LIGHT_SCREEN,
|
||||
side,
|
||||
false,
|
||||
attacker,
|
||||
move.category,
|
||||
multiplierHolder,
|
||||
);
|
||||
}
|
||||
|
||||
return move.power * multiplierHolder.value;
|
||||
|
@ -143,10 +143,8 @@ const getMockedMoveDamage = (defender: Pokemon, attacker: Pokemon, move: Move) =
|
||||
const multiplierHolder = new NumberHolder(1);
|
||||
const side = defender.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY;
|
||||
|
||||
if (globalScene.arena.getTagOnSide(ArenaTagType.REFLECT, side)) {
|
||||
if (move.getAttrs("CritOnlyAttr").length === 0) {
|
||||
globalScene.arena.applyTagsForSide(ArenaTagType.REFLECT, side, false, attacker, move.category, multiplierHolder);
|
||||
}
|
||||
if (globalScene.arena.getTagOnSide(ArenaTagType.REFLECT, side) && move.getAttrs("CritOnlyAttr").length === 0) {
|
||||
globalScene.arena.applyTagsForSide(ArenaTagType.REFLECT, side, false, attacker, move.category, multiplierHolder);
|
||||
}
|
||||
|
||||
return move.power * multiplierHolder.value;
|
||||
|
@ -18,8 +18,10 @@ import { GameManagerHelper } from "#test/test-utils/helpers/game-manager-helper"
|
||||
export class ClassicModeHelper extends GameManagerHelper {
|
||||
/**
|
||||
* 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.
|
||||
* @remarks
|
||||
* Do not use this when {@linkcode startBattle} can be used!
|
||||
*/
|
||||
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.
|
||||
* @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(species: SpeciesId[] | undefined): Promise<void>;
|
||||
async runToSummon(species?: SpeciesId[]): Promise<void> {
|
||||
@ -60,7 +63,7 @@ export class ClassicModeHelper extends GameManagerHelper {
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
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.
|
||||
* @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(species?: SpeciesId[]): Promise<void> {
|
||||
await this.runToSummon(species);
|
||||
|
@ -227,11 +227,9 @@ export class MoveHelper extends GameManagerHelper {
|
||||
vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([]);
|
||||
console.warn("Player moveset override disabled due to use of `game.move.changeMoveset`!");
|
||||
}
|
||||
} else {
|
||||
if (coerceArray(Overrides.OPP_MOVESET_OVERRIDE).length > 0) {
|
||||
vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([]);
|
||||
console.warn("Enemy moveset override disabled due to use of `game.move.changeMoveset`!");
|
||||
}
|
||||
} else if (coerceArray(Overrides.OPP_MOVESET_OVERRIDE).length > 0) {
|
||||
vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([]);
|
||||
console.warn("Enemy moveset override disabled due to use of `game.move.changeMoveset`!");
|
||||
}
|
||||
moveset = coerceArray(moveset);
|
||||
expect(moveset.length, "Cannot assign more than 4 moves to a moveset!").toBeLessThanOrEqual(4);
|
||||
|
@ -53,13 +53,11 @@ export class MockText implements MockGameObject {
|
||||
wordWidthWithSpace += whiteSpaceWidth;
|
||||
}
|
||||
|
||||
if (wordWidthWithSpace > spaceLeft) {
|
||||
// Skip printing the newline if it's the first word of the line that is greater
|
||||
// than the word wrap width.
|
||||
if (j > 0) {
|
||||
result += "\n";
|
||||
spaceLeft = this.wordWrapWidth;
|
||||
}
|
||||
// Skip printing the newline if it's the first word of the line that is greater
|
||||
// than the word wrap width.
|
||||
if (wordWidthWithSpace > spaceLeft && j > 0) {
|
||||
result += "\n";
|
||||
spaceLeft = this.wordWrapWidth;
|
||||
}
|
||||
|
||||
result += word;
|
||||
|
Loading…
Reference in New Issue
Block a user