mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-04-22 17:44:19 +01:00
* Move ability.ts to subfolder * Extract types out of ability.ts * Update imports in ability.ts and friends * Cleanup imports in ability.ts * Re-add imports lost during sort * Update imports forgotten during rebase * Re-import proper type from enums * Update biome.jsonc Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> * Add commit to force tests to rerun --------- Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>
2832 lines
108 KiB
TypeScript
2832 lines
108 KiB
TypeScript
import type { SpeciesFormEvolution } from "#app/data/balance/pokemon-evolutions";
|
|
import { pokemonEvolutions, pokemonPrevolutions, pokemonStarters } from "#app/data/balance/pokemon-evolutions";
|
|
import type { Variant } from "#app/sprites/variant";
|
|
import { getVariantTint, getVariantIcon } from "#app/sprites/variant";
|
|
import { argbFromRgba } from "@material/material-color-utilities";
|
|
import i18next from "i18next";
|
|
import { starterColors } from "#app/battle-scene";
|
|
import { allAbilities } from "#app/data/data-lists";
|
|
import { speciesEggMoves } from "#app/data/balance/egg-moves";
|
|
import { GrowthRate, getGrowthRateColor } from "#app/data/exp";
|
|
import { Gender, getGenderColor, getGenderSymbol } from "#app/data/gender";
|
|
import { allMoves } from "#app/data/moves/move";
|
|
import { getNatureName } from "#app/data/nature";
|
|
import type { SpeciesFormChange } from "#app/data/pokemon-forms";
|
|
import { pokemonFormChanges } from "#app/data/pokemon-forms";
|
|
import type { LevelMoves } from "#app/data/balance/pokemon-level-moves";
|
|
import { pokemonFormLevelMoves, pokemonSpeciesLevelMoves } from "#app/data/balance/pokemon-level-moves";
|
|
import type PokemonSpecies from "#app/data/pokemon-species";
|
|
import { allSpecies, getPokemonSpecies, getPokemonSpeciesForm, normalForm } from "#app/data/pokemon-species";
|
|
import { getStarterValueFriendshipCap, speciesStarterCosts } from "#app/data/balance/starters";
|
|
import { starterPassiveAbilities } from "#app/data/balance/passives";
|
|
import { PokemonType } from "#enums/pokemon-type";
|
|
import type { DexEntry, StarterAttributes } from "#app/system/game-data";
|
|
import { AbilityAttr, DexAttr } from "#app/system/game-data";
|
|
import type { OptionSelectItem } from "#app/ui/abstact-option-select-ui-handler";
|
|
import MessageUiHandler from "#app/ui/message-ui-handler";
|
|
import { StatsContainer } from "#app/ui/stats-container";
|
|
import { TextStyle, addBBCodeTextObject, addTextObject, getTextColor, getTextStyleOptions } from "#app/ui/text";
|
|
import { Mode } from "#app/ui/ui";
|
|
import { addWindow } from "#app/ui/ui-theme";
|
|
import { Egg } from "#app/data/egg";
|
|
import Overrides from "#app/overrides";
|
|
import { SettingKeyboard } from "#app/system/settings/settings-keyboard";
|
|
import { Passive as PassiveAttr } from "#enums/passive";
|
|
import MoveInfoOverlay from "#app/ui/move-info-overlay";
|
|
import PokedexInfoOverlay from "#app/ui/pokedex-info-overlay";
|
|
import { getEggTierForSpecies } from "#app/data/egg";
|
|
import { Device } from "#enums/devices";
|
|
import type { Moves } from "#enums/moves";
|
|
import { Species } from "#enums/species";
|
|
import { Button } from "#enums/buttons";
|
|
import { EggSourceType } from "#enums/egg-source-types";
|
|
import {
|
|
getPassiveCandyCount,
|
|
getValueReductionCandyCounts,
|
|
getSameSpeciesEggCandyCounts,
|
|
} from "#app/data/balance/starters";
|
|
import {
|
|
BooleanHolder,
|
|
getLocalizedSpriteKey,
|
|
isNullOrUndefined,
|
|
padInt,
|
|
rgbHexToRgba,
|
|
toReadableString,
|
|
} from "#app/utils";
|
|
import type { Nature } from "#enums/nature";
|
|
import { getEnumKeys } from "#app/utils";
|
|
import { speciesTmMoves } from "#app/data/balance/tms";
|
|
import type { BiomeTierTod } from "#app/data/balance/biomes";
|
|
import { BiomePoolTier, catchableSpecies } from "#app/data/balance/biomes";
|
|
import { Biome } from "#app/enums/biome";
|
|
import { TimeOfDay } from "#app/enums/time-of-day";
|
|
import type { Abilities } from "#app/enums/abilities";
|
|
import { BaseStatsOverlay } from "#app/ui/base-stats-overlay";
|
|
import { globalScene } from "#app/global-scene";
|
|
import type BBCodeText from "phaser3-rex-plugins/plugins/gameobjects/tagtext/bbcodetext/BBCodeText";
|
|
|
|
interface LanguageSetting {
|
|
starterInfoTextSize: string;
|
|
instructionTextSize: string;
|
|
starterInfoXPos?: number;
|
|
starterInfoYOffset?: number;
|
|
}
|
|
|
|
const languageSettings: { [key: string]: LanguageSetting } = {
|
|
en: {
|
|
starterInfoTextSize: "56px",
|
|
instructionTextSize: "38px",
|
|
},
|
|
de: {
|
|
starterInfoTextSize: "48px",
|
|
instructionTextSize: "35px",
|
|
starterInfoXPos: 33,
|
|
},
|
|
"es-ES": {
|
|
starterInfoTextSize: "56px",
|
|
instructionTextSize: "35px",
|
|
},
|
|
fr: {
|
|
starterInfoTextSize: "54px",
|
|
instructionTextSize: "38px",
|
|
},
|
|
it: {
|
|
starterInfoTextSize: "56px",
|
|
instructionTextSize: "38px",
|
|
},
|
|
pt_BR: {
|
|
starterInfoTextSize: "47px",
|
|
instructionTextSize: "38px",
|
|
starterInfoXPos: 33,
|
|
},
|
|
zh: {
|
|
starterInfoTextSize: "47px",
|
|
instructionTextSize: "38px",
|
|
starterInfoYOffset: 1,
|
|
starterInfoXPos: 24,
|
|
},
|
|
pt: {
|
|
starterInfoTextSize: "48px",
|
|
instructionTextSize: "42px",
|
|
starterInfoXPos: 33,
|
|
},
|
|
ko: {
|
|
starterInfoTextSize: "52px",
|
|
instructionTextSize: "38px",
|
|
},
|
|
ja: {
|
|
starterInfoTextSize: "51px",
|
|
instructionTextSize: "38px",
|
|
},
|
|
"ca-ES": {
|
|
starterInfoTextSize: "56px",
|
|
instructionTextSize: "38px",
|
|
},
|
|
};
|
|
|
|
const valueReductionMax = 2;
|
|
|
|
// Position of UI elements
|
|
const speciesContainerX = 109;
|
|
|
|
interface SpeciesDetails {
|
|
shiny?: boolean;
|
|
formIndex?: number;
|
|
female?: boolean;
|
|
variant?: number;
|
|
}
|
|
|
|
enum MenuOptions {
|
|
BASE_STATS,
|
|
ABILITIES,
|
|
LEVEL_MOVES,
|
|
EGG_MOVES,
|
|
TM_MOVES,
|
|
BIOMES,
|
|
NATURES,
|
|
TOGGLE_IVS,
|
|
EVOLUTIONS,
|
|
}
|
|
|
|
export default class PokedexPageUiHandler extends MessageUiHandler {
|
|
private starterSelectContainer: Phaser.GameObjects.Container;
|
|
private shinyOverlay: Phaser.GameObjects.Image;
|
|
private pokemonNumberText: Phaser.GameObjects.Text;
|
|
private pokemonSprite: Phaser.GameObjects.Sprite;
|
|
private pokemonNameText: Phaser.GameObjects.Text;
|
|
private pokemonGrowthRateLabelText: Phaser.GameObjects.Text;
|
|
private pokemonGrowthRateText: Phaser.GameObjects.Text;
|
|
private type1Icon: Phaser.GameObjects.Sprite;
|
|
private type2Icon: Phaser.GameObjects.Sprite;
|
|
private pokemonLuckLabelText: Phaser.GameObjects.Text;
|
|
private pokemonLuckText: Phaser.GameObjects.Text;
|
|
private pokemonGenderText: Phaser.GameObjects.Text;
|
|
private pokemonUncaughtText: Phaser.GameObjects.Text;
|
|
private pokemonCandyContainer: Phaser.GameObjects.Container;
|
|
private pokemonCandyIcon: Phaser.GameObjects.Sprite;
|
|
private pokemonCandyDarknessOverlay: Phaser.GameObjects.Sprite;
|
|
private pokemonCandyOverlayIcon: Phaser.GameObjects.Sprite;
|
|
private pokemonCandyCountText: Phaser.GameObjects.Text;
|
|
private pokemonCaughtHatchedContainer: Phaser.GameObjects.Container;
|
|
private pokemonCaughtCountText: Phaser.GameObjects.Text;
|
|
private pokemonFormText: Phaser.GameObjects.Text;
|
|
private pokemonHatchedIcon: Phaser.GameObjects.Sprite;
|
|
private pokemonHatchedCountText: Phaser.GameObjects.Text;
|
|
private pokemonShinyIcons: Phaser.GameObjects.Sprite[];
|
|
|
|
private activeTooltip: "ABILITY" | "PASSIVE" | "CANDY" | undefined;
|
|
private instructionsContainer: Phaser.GameObjects.Container;
|
|
private filterInstructionsContainer: Phaser.GameObjects.Container;
|
|
private shinyIconElement: Phaser.GameObjects.Sprite;
|
|
private formIconElement: Phaser.GameObjects.Sprite;
|
|
private genderIconElement: Phaser.GameObjects.Sprite;
|
|
private variantIconElement: Phaser.GameObjects.Sprite;
|
|
private shinyLabel: Phaser.GameObjects.Text;
|
|
private formLabel: Phaser.GameObjects.Text;
|
|
private genderLabel: Phaser.GameObjects.Text;
|
|
private variantLabel: Phaser.GameObjects.Text;
|
|
private candyUpgradeIconElement: Phaser.GameObjects.Sprite;
|
|
private candyUpgradeLabel: Phaser.GameObjects.Text;
|
|
private showBackSpriteIconElement: Phaser.GameObjects.Sprite;
|
|
private showBackSpriteLabel: Phaser.GameObjects.Text;
|
|
|
|
private starterSelectMessageBox: Phaser.GameObjects.NineSlice;
|
|
private starterSelectMessageBoxContainer: Phaser.GameObjects.Container;
|
|
private statsContainer: StatsContainer;
|
|
private moveInfoOverlay: MoveInfoOverlay;
|
|
private infoOverlay: PokedexInfoOverlay;
|
|
private baseStatsOverlay: BaseStatsOverlay;
|
|
|
|
private statsMode: boolean;
|
|
|
|
private allSpecies: PokemonSpecies[] = [];
|
|
private species: PokemonSpecies;
|
|
private starterId: number;
|
|
private formIndex: number;
|
|
private speciesLoaded: Map<Species, boolean> = new Map<Species, boolean>();
|
|
private levelMoves: LevelMoves;
|
|
private eggMoves: Moves[] = [];
|
|
private hasEggMoves: boolean[] = [];
|
|
private tmMoves: Moves[] = [];
|
|
private ability1: Abilities;
|
|
private ability2: Abilities | undefined;
|
|
private abilityHidden: Abilities | undefined;
|
|
private passive: Abilities;
|
|
private hasPassive: boolean;
|
|
private hasAbilities: number[];
|
|
private biomes: BiomeTierTod[];
|
|
private preBiomes: BiomeTierTod[];
|
|
private baseStats: number[];
|
|
private baseTotal: number;
|
|
private evolutions: SpeciesFormEvolution[];
|
|
private battleForms: SpeciesFormChange[];
|
|
private prevolutions: SpeciesFormEvolution[];
|
|
|
|
private speciesStarterDexEntry: DexEntry | null;
|
|
private canCycleShiny: boolean;
|
|
private canCycleForm: boolean;
|
|
private canCycleGender: boolean;
|
|
|
|
private assetLoadCancelled: BooleanHolder | null;
|
|
public cursorObj: Phaser.GameObjects.Image;
|
|
|
|
// variables to keep track of the dynamically rendered list of instruction prompts for starter select
|
|
private instructionRowX = 0;
|
|
private instructionRowY = 0;
|
|
private instructionRowTextOffset = 9;
|
|
private filterInstructionRowX = 0;
|
|
private filterInstructionRowY = 0;
|
|
|
|
private starterAttributes: StarterAttributes;
|
|
private savedStarterAttributes: StarterAttributes;
|
|
|
|
private previousSpecies: PokemonSpecies[];
|
|
private previousStarterAttributes: StarterAttributes[];
|
|
|
|
protected blockInput = false;
|
|
protected blockInputOverlay = false;
|
|
|
|
private showBackSprite = false;
|
|
|
|
// Menu
|
|
private menuContainer: Phaser.GameObjects.Container;
|
|
private menuBg: Phaser.GameObjects.NineSlice;
|
|
protected optionSelectText: BBCodeText;
|
|
private menuOptions: MenuOptions[];
|
|
protected scale = 0.1666666667;
|
|
private menuDescriptions: string[];
|
|
private isFormGender: boolean;
|
|
private filteredIndices: Species[] | null = null;
|
|
|
|
private availableVariants: number;
|
|
private unlockedVariants: boolean[];
|
|
|
|
private canUseCandies: boolean;
|
|
private exitCallback;
|
|
|
|
constructor() {
|
|
super(Mode.POKEDEX_PAGE);
|
|
}
|
|
|
|
setup() {
|
|
const ui = this.getUi();
|
|
const currentLanguage = i18next.resolvedLanguage ?? "en";
|
|
const langSettingKey = Object.keys(languageSettings).find(lang => currentLanguage.includes(lang)) ?? "en";
|
|
const textSettings = languageSettings[langSettingKey];
|
|
|
|
this.starterSelectContainer = globalScene.add.container(0, -globalScene.game.canvas.height / 6);
|
|
this.starterSelectContainer.setVisible(false);
|
|
ui.add(this.starterSelectContainer);
|
|
|
|
const bgColor = globalScene.add.rectangle(
|
|
0,
|
|
0,
|
|
globalScene.game.canvas.width / 6,
|
|
globalScene.game.canvas.height / 6,
|
|
0x006860,
|
|
);
|
|
bgColor.setOrigin(0, 0);
|
|
this.starterSelectContainer.add(bgColor);
|
|
|
|
const starterSelectBg = globalScene.add.image(0, 0, "pokedex_summary_bg");
|
|
starterSelectBg.setOrigin(0, 0);
|
|
this.starterSelectContainer.add(starterSelectBg);
|
|
|
|
this.shinyOverlay = globalScene.add.image(6, 6, "summary_overlay_shiny");
|
|
this.shinyOverlay.setOrigin(0, 0);
|
|
this.shinyOverlay.setVisible(false);
|
|
this.starterSelectContainer.add(this.shinyOverlay);
|
|
|
|
this.pokemonNumberText = addTextObject(17, 1, "0000", TextStyle.SUMMARY);
|
|
this.pokemonNumberText.setOrigin(0, 0);
|
|
this.starterSelectContainer.add(this.pokemonNumberText);
|
|
|
|
this.pokemonNameText = addTextObject(6, 112, "", TextStyle.SUMMARY);
|
|
this.pokemonNameText.setOrigin(0, 0);
|
|
this.starterSelectContainer.add(this.pokemonNameText);
|
|
|
|
this.pokemonGrowthRateLabelText = addTextObject(
|
|
8,
|
|
106,
|
|
i18next.t("pokedexUiHandler:growthRate"),
|
|
TextStyle.SUMMARY_ALT,
|
|
{ fontSize: "36px" },
|
|
);
|
|
this.pokemonGrowthRateLabelText.setOrigin(0, 0);
|
|
this.pokemonGrowthRateLabelText.setVisible(false);
|
|
this.starterSelectContainer.add(this.pokemonGrowthRateLabelText);
|
|
|
|
this.pokemonGrowthRateText = addTextObject(34, 106, "", TextStyle.SUMMARY_PINK, { fontSize: "36px" });
|
|
this.pokemonGrowthRateText.setOrigin(0, 0);
|
|
this.starterSelectContainer.add(this.pokemonGrowthRateText);
|
|
|
|
this.pokemonGenderText = addTextObject(96, 112, "", TextStyle.SUMMARY_ALT);
|
|
this.pokemonGenderText.setOrigin(0, 0);
|
|
this.starterSelectContainer.add(this.pokemonGenderText);
|
|
|
|
this.pokemonUncaughtText = addTextObject(6, 127, i18next.t("pokedexUiHandler:uncaught"), TextStyle.WINDOW, {
|
|
fontSize: "56px",
|
|
});
|
|
this.pokemonUncaughtText.setOrigin(0, 0);
|
|
this.starterSelectContainer.add(this.pokemonUncaughtText);
|
|
|
|
const starterBoxContainer = globalScene.add.container(speciesContainerX + 6, 9); //115
|
|
|
|
for (const species of allSpecies) {
|
|
if (!speciesStarterCosts.hasOwnProperty(species.speciesId) || !species.isObtainable()) {
|
|
continue;
|
|
}
|
|
|
|
this.speciesLoaded.set(species.speciesId, false);
|
|
this.allSpecies.push(species);
|
|
}
|
|
|
|
this.starterSelectContainer.add(starterBoxContainer);
|
|
|
|
this.pokemonSprite = globalScene.add.sprite(53, 63, "pkmn__sub");
|
|
this.pokemonSprite.setPipeline(globalScene.spritePipeline, {
|
|
tone: [0.0, 0.0, 0.0, 0.0],
|
|
ignoreTimeTint: true,
|
|
});
|
|
this.starterSelectContainer.add(this.pokemonSprite);
|
|
|
|
this.type1Icon = globalScene.add.sprite(8, 98, getLocalizedSpriteKey("types"));
|
|
this.type1Icon.setScale(0.5);
|
|
this.type1Icon.setOrigin(0, 0);
|
|
this.starterSelectContainer.add(this.type1Icon);
|
|
|
|
this.type2Icon = globalScene.add.sprite(26, 98, getLocalizedSpriteKey("types"));
|
|
this.type2Icon.setScale(0.5);
|
|
this.type2Icon.setOrigin(0, 0);
|
|
this.starterSelectContainer.add(this.type2Icon);
|
|
|
|
this.pokemonLuckLabelText = addTextObject(8, 89, i18next.t("common:luckIndicator"), TextStyle.WINDOW_ALT, {
|
|
fontSize: "56px",
|
|
});
|
|
this.pokemonLuckLabelText.setOrigin(0, 0);
|
|
this.starterSelectContainer.add(this.pokemonLuckLabelText);
|
|
|
|
this.pokemonLuckText = addTextObject(8 + this.pokemonLuckLabelText.displayWidth + 2, 89, "0", TextStyle.WINDOW, {
|
|
fontSize: "56px",
|
|
});
|
|
this.pokemonLuckText.setOrigin(0, 0);
|
|
this.starterSelectContainer.add(this.pokemonLuckText);
|
|
|
|
// Candy icon and count
|
|
this.pokemonCandyContainer = globalScene.add.container(4.5, 18);
|
|
|
|
this.pokemonCandyIcon = globalScene.add.sprite(0, 0, "candy");
|
|
this.pokemonCandyIcon.setScale(0.5);
|
|
this.pokemonCandyIcon.setOrigin(0, 0);
|
|
this.pokemonCandyContainer.add(this.pokemonCandyIcon);
|
|
|
|
this.pokemonCandyOverlayIcon = globalScene.add.sprite(0, 0, "candy_overlay");
|
|
this.pokemonCandyOverlayIcon.setScale(0.5);
|
|
this.pokemonCandyOverlayIcon.setOrigin(0, 0);
|
|
this.pokemonCandyContainer.add(this.pokemonCandyOverlayIcon);
|
|
|
|
this.pokemonCandyDarknessOverlay = globalScene.add.sprite(0, 0, "candy");
|
|
this.pokemonCandyDarknessOverlay.setScale(0.5);
|
|
this.pokemonCandyDarknessOverlay.setOrigin(0, 0);
|
|
this.pokemonCandyDarknessOverlay.setTint(0x000000);
|
|
this.pokemonCandyDarknessOverlay.setAlpha(0.5);
|
|
this.pokemonCandyContainer.add(this.pokemonCandyDarknessOverlay);
|
|
|
|
this.pokemonCandyCountText = addTextObject(9.5, 0, "x0", TextStyle.WINDOW_ALT, { fontSize: "56px" });
|
|
this.pokemonCandyCountText.setOrigin(0, 0);
|
|
this.pokemonCandyContainer.add(this.pokemonCandyCountText);
|
|
|
|
this.pokemonCandyContainer.setInteractive(new Phaser.Geom.Rectangle(0, 0, 30, 20), Phaser.Geom.Rectangle.Contains);
|
|
this.starterSelectContainer.add(this.pokemonCandyContainer);
|
|
|
|
this.pokemonFormText = addTextObject(6, 42, "Form", TextStyle.WINDOW_ALT, {
|
|
fontSize: "42px",
|
|
});
|
|
this.pokemonFormText.setOrigin(0, 0);
|
|
this.starterSelectContainer.add(this.pokemonFormText);
|
|
|
|
this.pokemonCaughtHatchedContainer = globalScene.add.container(2, 25);
|
|
this.pokemonCaughtHatchedContainer.setScale(0.5);
|
|
this.starterSelectContainer.add(this.pokemonCaughtHatchedContainer);
|
|
|
|
const pokemonCaughtIcon = globalScene.add.sprite(1, 0, "items", "pb");
|
|
pokemonCaughtIcon.setOrigin(0, 0);
|
|
pokemonCaughtIcon.setScale(0.75);
|
|
this.pokemonCaughtHatchedContainer.add(pokemonCaughtIcon);
|
|
|
|
this.pokemonCaughtCountText = addTextObject(24, 4, "0", TextStyle.SUMMARY_ALT);
|
|
this.pokemonCaughtCountText.setOrigin(0, 0);
|
|
this.pokemonCaughtHatchedContainer.add(this.pokemonCaughtCountText);
|
|
|
|
this.pokemonHatchedIcon = globalScene.add.sprite(1, 14, "egg_icons");
|
|
this.pokemonHatchedIcon.setOrigin(0.15, 0.2);
|
|
this.pokemonHatchedIcon.setScale(0.8);
|
|
this.pokemonCaughtHatchedContainer.add(this.pokemonHatchedIcon);
|
|
|
|
this.pokemonShinyIcons = [];
|
|
for (let i = 0; i < 3; i++) {
|
|
const pokemonShinyIcon = globalScene.add.sprite(153 + i * 13, 160, "shiny_icons");
|
|
pokemonShinyIcon.setOrigin(0.15, 0.2);
|
|
pokemonShinyIcon.setScale(1);
|
|
pokemonShinyIcon.setFrame(getVariantIcon(i as Variant));
|
|
pokemonShinyIcon.setVisible(false);
|
|
this.pokemonCaughtHatchedContainer.add(pokemonShinyIcon);
|
|
this.pokemonShinyIcons.push(pokemonShinyIcon);
|
|
}
|
|
|
|
this.pokemonHatchedCountText = addTextObject(24, 19, "0", TextStyle.SUMMARY_ALT);
|
|
this.pokemonHatchedCountText.setOrigin(0, 0);
|
|
this.pokemonCaughtHatchedContainer.add(this.pokemonHatchedCountText);
|
|
|
|
// The font size should be set per language
|
|
const instructionTextSize = textSettings.instructionTextSize;
|
|
|
|
this.instructionsContainer = globalScene.add.container(4, 128);
|
|
this.instructionsContainer.setVisible(true);
|
|
this.starterSelectContainer.add(this.instructionsContainer);
|
|
|
|
this.candyUpgradeIconElement = new Phaser.GameObjects.Sprite(
|
|
globalScene,
|
|
this.instructionRowX,
|
|
this.instructionRowY,
|
|
"keyboard",
|
|
"C.png",
|
|
);
|
|
this.candyUpgradeIconElement.setName("sprite-candyUpgrade-icon-element");
|
|
this.candyUpgradeIconElement.setScale(0.675);
|
|
this.candyUpgradeIconElement.setOrigin(0.0, 0.0);
|
|
this.candyUpgradeLabel = addTextObject(
|
|
this.instructionRowX + this.instructionRowTextOffset,
|
|
this.instructionRowY,
|
|
i18next.t("pokedexUiHandler:candyUpgrade"),
|
|
TextStyle.PARTY,
|
|
{ fontSize: instructionTextSize },
|
|
);
|
|
this.candyUpgradeLabel.setName("text-candyUpgrade-label");
|
|
|
|
// instruction rows that will be pushed into the container dynamically based on need
|
|
// creating new sprites since they will be added to the scene later
|
|
this.shinyIconElement = new Phaser.GameObjects.Sprite(
|
|
globalScene,
|
|
this.instructionRowX,
|
|
this.instructionRowY,
|
|
"keyboard",
|
|
"R.png",
|
|
);
|
|
this.shinyIconElement.setName("sprite-shiny-icon-element");
|
|
this.shinyIconElement.setScale(0.675);
|
|
this.shinyIconElement.setOrigin(0.0, 0.0);
|
|
this.shinyLabel = addTextObject(
|
|
this.instructionRowX + this.instructionRowTextOffset,
|
|
this.instructionRowY,
|
|
i18next.t("pokedexUiHandler:cycleShiny"),
|
|
TextStyle.PARTY,
|
|
{ fontSize: instructionTextSize },
|
|
);
|
|
this.shinyLabel.setName("text-shiny-label");
|
|
|
|
this.formIconElement = new Phaser.GameObjects.Sprite(
|
|
globalScene,
|
|
this.instructionRowX,
|
|
this.instructionRowY,
|
|
"keyboard",
|
|
"F.png",
|
|
);
|
|
this.formIconElement.setName("sprite-form-icon-element");
|
|
this.formIconElement.setScale(0.675);
|
|
this.formIconElement.setOrigin(0.0, 0.0);
|
|
this.formLabel = addTextObject(
|
|
this.instructionRowX + this.instructionRowTextOffset,
|
|
this.instructionRowY,
|
|
i18next.t("pokedexUiHandler:cycleForm"),
|
|
TextStyle.PARTY,
|
|
{ fontSize: instructionTextSize },
|
|
);
|
|
this.formLabel.setName("text-form-label");
|
|
|
|
this.genderIconElement = new Phaser.GameObjects.Sprite(
|
|
globalScene,
|
|
this.instructionRowX,
|
|
this.instructionRowY,
|
|
"keyboard",
|
|
"G.png",
|
|
);
|
|
this.genderIconElement.setName("sprite-gender-icon-element");
|
|
this.genderIconElement.setScale(0.675);
|
|
this.genderIconElement.setOrigin(0.0, 0.0);
|
|
this.genderLabel = addTextObject(
|
|
this.instructionRowX + this.instructionRowTextOffset,
|
|
this.instructionRowY,
|
|
i18next.t("pokedexUiHandler:cycleGender"),
|
|
TextStyle.PARTY,
|
|
{ fontSize: instructionTextSize },
|
|
);
|
|
this.genderLabel.setName("text-gender-label");
|
|
|
|
this.variantIconElement = new Phaser.GameObjects.Sprite(
|
|
globalScene,
|
|
this.instructionRowX,
|
|
this.instructionRowY,
|
|
"keyboard",
|
|
"V.png",
|
|
);
|
|
this.variantIconElement.setName("sprite-variant-icon-element");
|
|
this.variantIconElement.setScale(0.675);
|
|
this.variantIconElement.setOrigin(0.0, 0.0);
|
|
this.variantLabel = addTextObject(
|
|
this.instructionRowX + this.instructionRowTextOffset,
|
|
this.instructionRowY,
|
|
i18next.t("pokedexUiHandler:cycleVariant"),
|
|
TextStyle.PARTY,
|
|
{ fontSize: instructionTextSize },
|
|
);
|
|
this.variantLabel.setName("text-variant-label");
|
|
|
|
this.showBackSpriteIconElement = new Phaser.GameObjects.Sprite(globalScene, 50, 7, "keyboard", "E.png");
|
|
this.showBackSpriteIconElement.setName("show-backSprite-icon-element");
|
|
this.showBackSpriteIconElement.setScale(0.675);
|
|
this.showBackSpriteIconElement.setOrigin(0.0, 0.0);
|
|
this.showBackSpriteLabel = addTextObject(60, 7, i18next.t("pokedexUiHandler:showBackSprite"), TextStyle.PARTY, {
|
|
fontSize: instructionTextSize,
|
|
});
|
|
this.showBackSpriteLabel.setName("show-backSprite-label");
|
|
this.starterSelectContainer.add(this.showBackSpriteIconElement);
|
|
this.starterSelectContainer.add(this.showBackSpriteLabel);
|
|
|
|
this.hideInstructions();
|
|
|
|
this.filterInstructionsContainer = globalScene.add.container(50, 5);
|
|
this.filterInstructionsContainer.setVisible(true);
|
|
this.starterSelectContainer.add(this.filterInstructionsContainer);
|
|
|
|
this.starterSelectMessageBoxContainer = globalScene.add.container(0, globalScene.game.canvas.height / 6);
|
|
this.starterSelectMessageBoxContainer.setVisible(false);
|
|
this.starterSelectContainer.add(this.starterSelectMessageBoxContainer);
|
|
|
|
this.starterSelectMessageBox = addWindow(1, -1, 318, 28);
|
|
this.starterSelectMessageBox.setOrigin(0, 1);
|
|
this.starterSelectMessageBoxContainer.add(this.starterSelectMessageBox);
|
|
|
|
this.message = addTextObject(8, 8, "", TextStyle.WINDOW, { maxLines: 2 });
|
|
this.message.setOrigin(0, 0);
|
|
this.starterSelectMessageBoxContainer.add(this.message);
|
|
|
|
// arrow icon for the message box
|
|
this.initPromptSprite(this.starterSelectMessageBoxContainer);
|
|
|
|
this.statsContainer = new StatsContainer(6, 16);
|
|
|
|
globalScene.add.existing(this.statsContainer);
|
|
|
|
this.statsContainer.setVisible(false);
|
|
|
|
this.starterSelectContainer.add(this.statsContainer);
|
|
|
|
// Adding menu container
|
|
this.menuContainer = globalScene.add.container(-130, 0);
|
|
this.menuContainer.setName("menu");
|
|
this.menuContainer.setInteractive(
|
|
new Phaser.Geom.Rectangle(0, 0, globalScene.game.canvas.width / 6, globalScene.game.canvas.height / 6),
|
|
Phaser.Geom.Rectangle.Contains,
|
|
);
|
|
|
|
this.menuContainer.setVisible(false);
|
|
|
|
this.menuOptions = getEnumKeys(MenuOptions).map(m => Number.parseInt(MenuOptions[m]) as MenuOptions);
|
|
|
|
this.optionSelectText = addBBCodeTextObject(
|
|
0,
|
|
0,
|
|
this.menuOptions.map(o => `${i18next.t(`pokedexUiHandler:${MenuOptions[o]}`)}`).join("\n"),
|
|
TextStyle.WINDOW,
|
|
{ maxLines: this.menuOptions.length, lineSpacing: 12 },
|
|
);
|
|
|
|
this.menuDescriptions = [
|
|
i18next.t("pokedexUiHandler:showBaseStats"),
|
|
i18next.t("pokedexUiHandler:showAbilities"),
|
|
i18next.t("pokedexUiHandler:showLevelMoves"),
|
|
i18next.t("pokedexUiHandler:showEggMoves"),
|
|
i18next.t("pokedexUiHandler:showTmMoves"),
|
|
i18next.t("pokedexUiHandler:showBiomes"),
|
|
i18next.t("pokedexUiHandler:showNatures"),
|
|
i18next.t("pokedexUiHandler:toggleIVs"),
|
|
i18next.t("pokedexUiHandler:showEvolutions"),
|
|
];
|
|
|
|
this.scale = getTextStyleOptions(TextStyle.WINDOW, globalScene.uiTheme).scale;
|
|
this.menuBg = addWindow(
|
|
globalScene.game.canvas.width / 6 - 83,
|
|
0,
|
|
this.optionSelectText.displayWidth + 19 + 24 * this.scale,
|
|
globalScene.game.canvas.height / 6 - 2,
|
|
);
|
|
this.menuBg.setOrigin(0, 0);
|
|
|
|
this.optionSelectText.setPosition(this.menuBg.x + 10 + 24 * this.scale, this.menuBg.y + 6);
|
|
|
|
this.menuContainer.add(this.menuBg);
|
|
|
|
this.menuContainer.add(this.optionSelectText);
|
|
|
|
ui.add(this.menuContainer);
|
|
|
|
this.starterSelectContainer.add(this.menuContainer);
|
|
|
|
// adding base stats
|
|
this.baseStatsOverlay = new BaseStatsOverlay({ x: 317, y: 0, width: 133 });
|
|
this.menuContainer.add(this.baseStatsOverlay);
|
|
this.menuContainer.bringToTop(this.baseStatsOverlay);
|
|
|
|
// add the info overlay last to be the top most ui element and prevent the IVs from overlaying this
|
|
const overlayScale = 1;
|
|
this.moveInfoOverlay = new MoveInfoOverlay({
|
|
scale: overlayScale,
|
|
top: true,
|
|
x: 1,
|
|
y: globalScene.game.canvas.height / 6 - MoveInfoOverlay.getHeight(overlayScale) - 29,
|
|
});
|
|
this.starterSelectContainer.add(this.moveInfoOverlay);
|
|
|
|
this.infoOverlay = new PokedexInfoOverlay({
|
|
scale: overlayScale,
|
|
x: 1,
|
|
y: globalScene.game.canvas.height / 6 - PokedexInfoOverlay.getHeight(overlayScale) - 29,
|
|
});
|
|
this.starterSelectContainer.add(this.infoOverlay);
|
|
|
|
// Filter bar sits above everything, except the message box
|
|
this.starterSelectContainer.bringToTop(this.starterSelectMessageBoxContainer);
|
|
|
|
this.previousSpecies = [];
|
|
this.previousStarterAttributes = [];
|
|
}
|
|
|
|
show(args: any[]): boolean {
|
|
// Allow the use of candies if we are in one of the whitelisted phases
|
|
this.canUseCandies = ["TitlePhase", "SelectStarterPhase", "CommandPhase"].includes(
|
|
globalScene.getCurrentPhase()?.constructor.name ?? "",
|
|
);
|
|
|
|
if (args.length >= 1 && args[0] === "refresh") {
|
|
return false;
|
|
}
|
|
this.species = args[0];
|
|
this.savedStarterAttributes = args[1] ?? {
|
|
shiny: false,
|
|
female: true,
|
|
variant: 0,
|
|
form: 0,
|
|
};
|
|
this.formIndex = this.savedStarterAttributes.form ?? 0;
|
|
this.filteredIndices = args[2] ?? null;
|
|
this.starterSetup();
|
|
|
|
if (args[4] instanceof Function) {
|
|
this.exitCallback = args[4];
|
|
}
|
|
|
|
this.moveInfoOverlay.clear(); // clear this when removing a menu; the cancel button doesn't seem to trigger this automatically on controllers
|
|
this.infoOverlay.clear();
|
|
|
|
super.show(args);
|
|
|
|
this.starterSelectContainer.setVisible(true);
|
|
this.getUi().bringToTop(this.starterSelectContainer);
|
|
|
|
this.starterAttributes = this.initStarterPrefs();
|
|
|
|
this.menuOptions = getEnumKeys(MenuOptions).map(m => Number.parseInt(MenuOptions[m]) as MenuOptions);
|
|
|
|
this.menuContainer.setVisible(true);
|
|
|
|
this.speciesStarterDexEntry = this.species ? globalScene.gameData.dexData[this.species.speciesId] : null;
|
|
this.setSpecies();
|
|
this.updateInstructions();
|
|
|
|
this.optionSelectText.setText(this.getMenuText());
|
|
|
|
this.setCursor(0);
|
|
|
|
return true;
|
|
}
|
|
|
|
getMenuText(): string {
|
|
const isSeen = this.isSeen();
|
|
const isStarterCaught = !!this.isCaught(this.getStarterSpecies(this.species));
|
|
|
|
return this.menuOptions
|
|
.map(o => {
|
|
const label = `${i18next.t(`pokedexUiHandler:${MenuOptions[o]}`)}`;
|
|
const isDark =
|
|
!isSeen ||
|
|
(!isStarterCaught && (o === MenuOptions.TOGGLE_IVS || o === MenuOptions.NATURES)) ||
|
|
(this.tmMoves.length < 1 && o === MenuOptions.TM_MOVES);
|
|
const color = getTextColor(
|
|
isDark ? TextStyle.SHADOW_TEXT : TextStyle.SETTINGS_VALUE,
|
|
false,
|
|
globalScene.uiTheme,
|
|
);
|
|
const shadow = getTextColor(
|
|
isDark ? TextStyle.SHADOW_TEXT : TextStyle.SETTINGS_VALUE,
|
|
true,
|
|
globalScene.uiTheme,
|
|
);
|
|
return `[shadow=${shadow}][color=${color}]${label}[/color][/shadow]`;
|
|
})
|
|
.join("\n");
|
|
}
|
|
|
|
starterSetup(): void {
|
|
this.evolutions = [];
|
|
this.prevolutions = [];
|
|
this.battleForms = [];
|
|
|
|
const species = this.species;
|
|
|
|
let formKey = this.species?.forms.length > 0 ? this.species.forms[this.formIndex].formKey : "";
|
|
this.isFormGender = formKey === "male" || formKey === "female";
|
|
if (
|
|
this.isFormGender &&
|
|
((this.savedStarterAttributes.female === true && formKey === "male") ||
|
|
(this.savedStarterAttributes.female === false && formKey === "female"))
|
|
) {
|
|
this.formIndex = (this.formIndex + 1) % 2;
|
|
formKey = this.species.forms[this.formIndex].formKey;
|
|
}
|
|
|
|
const formIndex = this.formIndex ?? 0;
|
|
|
|
this.starterId = this.getStarterSpeciesId(this.species.speciesId);
|
|
|
|
const allEvolutions = pokemonEvolutions.hasOwnProperty(species.speciesId)
|
|
? pokemonEvolutions[species.speciesId]
|
|
: [];
|
|
|
|
if (species.forms.length > 0) {
|
|
const form = species.forms[formIndex];
|
|
|
|
// If this form has a specific set of moves, we get them.
|
|
this.levelMoves =
|
|
formIndex > 0 &&
|
|
pokemonFormLevelMoves.hasOwnProperty(species.speciesId) &&
|
|
pokemonFormLevelMoves[species.speciesId].hasOwnProperty(formIndex)
|
|
? pokemonFormLevelMoves[species.speciesId][formIndex]
|
|
: pokemonSpeciesLevelMoves[species.speciesId];
|
|
this.ability1 = form.ability1;
|
|
this.ability2 = form.ability2 === form.ability1 ? undefined : form.ability2;
|
|
this.abilityHidden = form.abilityHidden === form.ability1 ? undefined : form.abilityHidden;
|
|
|
|
this.evolutions = allEvolutions.filter(e => e.preFormKey === form.formKey || e.preFormKey === null);
|
|
this.baseStats = form.baseStats;
|
|
this.baseTotal = form.baseTotal;
|
|
} else {
|
|
this.levelMoves = pokemonSpeciesLevelMoves[species.speciesId];
|
|
this.ability1 = species.ability1;
|
|
this.ability2 = species.ability2 === species.ability1 ? undefined : species.ability2;
|
|
this.abilityHidden = species.abilityHidden === species.ability1 ? undefined : species.abilityHidden;
|
|
|
|
this.evolutions = allEvolutions;
|
|
this.baseStats = species.baseStats;
|
|
this.baseTotal = species.baseTotal;
|
|
}
|
|
|
|
this.eggMoves = speciesEggMoves[this.starterId] ?? [];
|
|
this.hasEggMoves = Array.from(
|
|
{ length: 4 },
|
|
(_, em) => (globalScene.gameData.starterData[this.starterId].eggMoves & (1 << em)) !== 0,
|
|
);
|
|
|
|
this.tmMoves =
|
|
speciesTmMoves[species.speciesId]
|
|
?.filter(m => (Array.isArray(m) ? m[0] === formKey : true))
|
|
.map(m => (Array.isArray(m) ? m[1] : m))
|
|
.sort((a, b) => (allMoves[a].name > allMoves[b].name ? 1 : -1)) ?? [];
|
|
|
|
const passiveId = starterPassiveAbilities.hasOwnProperty(species.speciesId)
|
|
? species.speciesId
|
|
: starterPassiveAbilities.hasOwnProperty(this.starterId)
|
|
? this.starterId
|
|
: pokemonPrevolutions[this.starterId];
|
|
const passives = starterPassiveAbilities[passiveId];
|
|
this.passive = this.formIndex in passives ? passives[formIndex] : passives[0];
|
|
|
|
const starterData = globalScene.gameData.starterData[this.starterId];
|
|
const abilityAttr = starterData.abilityAttr;
|
|
this.hasPassive = starterData.passiveAttr > 0;
|
|
|
|
const hasAbility1 = abilityAttr & AbilityAttr.ABILITY_1;
|
|
const hasAbility2 = abilityAttr & AbilityAttr.ABILITY_2;
|
|
const hasHiddenAbility = abilityAttr & AbilityAttr.ABILITY_HIDDEN;
|
|
|
|
this.hasAbilities = [hasAbility1, hasAbility2, hasHiddenAbility];
|
|
|
|
const allBiomes = catchableSpecies[species.speciesId] ?? [];
|
|
this.preBiomes = this.sanitizeBiomes(
|
|
(catchableSpecies[this.starterId] ?? []).filter(
|
|
b => !allBiomes.some(bm => b.biome === bm.biome && b.tier === bm.tier) && !(b.biome === Biome.TOWN),
|
|
),
|
|
this.starterId,
|
|
);
|
|
this.biomes = this.sanitizeBiomes(allBiomes, species.speciesId);
|
|
|
|
const allFormChanges = pokemonFormChanges.hasOwnProperty(species.speciesId)
|
|
? pokemonFormChanges[species.speciesId]
|
|
: [];
|
|
this.battleForms = allFormChanges.filter(f => f.preFormKey === this.species.forms[this.formIndex].formKey);
|
|
|
|
const preSpecies = pokemonPrevolutions.hasOwnProperty(this.species.speciesId)
|
|
? allSpecies.find(sp => sp.speciesId === pokemonPrevolutions[this.species.speciesId])
|
|
: null;
|
|
if (preSpecies) {
|
|
const preEvolutions = pokemonEvolutions.hasOwnProperty(preSpecies.speciesId)
|
|
? pokemonEvolutions[preSpecies.speciesId]
|
|
: [];
|
|
this.prevolutions = preEvolutions.filter(
|
|
e =>
|
|
e.speciesId === species.speciesId &&
|
|
(((e.evoFormKey === "" || e.evoFormKey === null) &&
|
|
// This takes care of Cosplay Pikachu (Pichu is not shown)
|
|
(preSpecies.forms.some(form => form.formKey === species.forms[formIndex]?.formKey) ||
|
|
// This takes care of Gholdengo
|
|
(preSpecies.forms.length > 0 && species.forms.length === 0) ||
|
|
// This takes care of everything else
|
|
(preSpecies.forms.length === 0 &&
|
|
(species.forms.length === 0 || species.forms[formIndex]?.formKey === "")))) ||
|
|
// This takes care of Burmy, Shellos etc
|
|
e.evoFormKey === species.forms[formIndex]?.formKey),
|
|
);
|
|
}
|
|
|
|
this.availableVariants = species.getFullUnlocksData() & DexAttr.VARIANT_3 ? 3 : 1;
|
|
}
|
|
|
|
// Function to ensure that forms appear in the appropriate biome and tod
|
|
sanitizeBiomes(biomes: BiomeTierTod[], speciesId: number): BiomeTierTod[] {
|
|
if (speciesId === Species.BURMY || speciesId === Species.WORMADAM) {
|
|
return biomes.filter(b => {
|
|
const formIndex = (() => {
|
|
switch (b.biome) {
|
|
case Biome.BEACH:
|
|
return 1;
|
|
case Biome.SLUM:
|
|
return 2;
|
|
default:
|
|
return 0;
|
|
}
|
|
})();
|
|
return this.formIndex === formIndex;
|
|
});
|
|
}
|
|
if (speciesId === Species.ROTOM) {
|
|
return biomes.filter(b => {
|
|
const formIndex = (() => {
|
|
switch (b.biome) {
|
|
case Biome.VOLCANO:
|
|
return 1;
|
|
case Biome.SEA:
|
|
return 2;
|
|
case Biome.ICE_CAVE:
|
|
return 3;
|
|
case Biome.MOUNTAIN:
|
|
return 4;
|
|
case Biome.TALL_GRASS:
|
|
return 5;
|
|
default:
|
|
return 0;
|
|
}
|
|
})();
|
|
return this.formIndex === formIndex;
|
|
});
|
|
}
|
|
if (speciesId === Species.LYCANROC) {
|
|
return biomes.filter(b => {
|
|
const formIndex = (() => {
|
|
switch (b.tod[0]) {
|
|
case TimeOfDay.DAY:
|
|
case TimeOfDay.DAWN:
|
|
return 0;
|
|
case TimeOfDay.DUSK:
|
|
return 2;
|
|
case TimeOfDay.NIGHT:
|
|
return 1;
|
|
default:
|
|
return 0;
|
|
}
|
|
})();
|
|
return this.formIndex === formIndex;
|
|
});
|
|
}
|
|
|
|
return biomes;
|
|
}
|
|
|
|
isCaught(otherSpecies?: PokemonSpecies): bigint {
|
|
if (globalScene.dexForDevs) {
|
|
return 255n;
|
|
}
|
|
|
|
const species = otherSpecies ? otherSpecies : this.species;
|
|
const dexEntry = globalScene.gameData.dexData[species.speciesId];
|
|
const starterDexEntry = globalScene.gameData.dexData[this.getStarterSpeciesId(species.speciesId)];
|
|
|
|
return (dexEntry?.caughtAttr ?? 0n) & (starterDexEntry?.caughtAttr ?? 0n) & species.getFullUnlocksData();
|
|
}
|
|
|
|
/**
|
|
* Check whether a given form is caught for a given species.
|
|
* All forms that can be reached through a form change during battle are considered caught and show up in the dex as such.
|
|
*
|
|
* @param otherSpecies The species to check; defaults to current species
|
|
* @param otherFormIndex The form index of the form to check; defaults to current form
|
|
* @returns StarterAttributes for the species
|
|
*/
|
|
isFormCaught(otherSpecies?: PokemonSpecies, otherFormIndex?: number | undefined): boolean {
|
|
if (globalScene.dexForDevs) {
|
|
return true;
|
|
}
|
|
const species = otherSpecies ? otherSpecies : this.species;
|
|
const formIndex = otherFormIndex !== undefined ? otherFormIndex : this.formIndex;
|
|
const caughtAttr = this.isCaught(species);
|
|
|
|
if (caughtAttr && (!species.forms.length || species.forms.length === 1)) {
|
|
return true;
|
|
}
|
|
|
|
const isFormCaught = (caughtAttr & globalScene.gameData.getFormAttr(formIndex ?? 0)) > 0n;
|
|
return isFormCaught;
|
|
}
|
|
|
|
isSeen(): boolean {
|
|
if (this.speciesStarterDexEntry?.seenAttr) {
|
|
return true;
|
|
}
|
|
const starterCaughtAttr = this.isCaught(this.getStarterSpecies(this.species));
|
|
return !!starterCaughtAttr;
|
|
}
|
|
|
|
/**
|
|
* Get the starter attributes for the given PokemonSpecies, after sanitizing them.
|
|
* If somehow a preference is set for a form, variant, gender, ability or nature
|
|
* that wasn't actually unlocked or is invalid it will be cleared here
|
|
*
|
|
* @param species The species to get Starter Preferences for
|
|
* @returns StarterAttributes for the species
|
|
*/
|
|
initStarterPrefs(): StarterAttributes {
|
|
const starterAttributes: StarterAttributes | null = this.species ? { ...this.savedStarterAttributes } : null;
|
|
const caughtAttr = this.isCaught();
|
|
|
|
// no preferences or Pokemon wasn't caught, return empty attribute
|
|
if (!starterAttributes || !this.isSeen()) {
|
|
return {};
|
|
}
|
|
|
|
const hasShiny = caughtAttr & DexAttr.SHINY;
|
|
const hasNonShiny = caughtAttr & DexAttr.NON_SHINY;
|
|
if (!hasShiny || (starterAttributes.shiny === undefined && hasNonShiny)) {
|
|
// shiny form wasn't unlocked, purging shiny and variant setting
|
|
starterAttributes.shiny = false;
|
|
starterAttributes.variant = 0;
|
|
} else if (!hasNonShiny || (starterAttributes.shiny === undefined && hasShiny)) {
|
|
starterAttributes.shiny = true;
|
|
starterAttributes.variant = 0;
|
|
}
|
|
|
|
this.unlockedVariants = [
|
|
!!(hasShiny && caughtAttr & DexAttr.DEFAULT_VARIANT),
|
|
!!(hasShiny && caughtAttr & DexAttr.VARIANT_2),
|
|
!!(hasShiny && caughtAttr & DexAttr.VARIANT_3),
|
|
];
|
|
if (
|
|
starterAttributes.variant === undefined ||
|
|
Number.isNaN(starterAttributes.variant) ||
|
|
starterAttributes.variant < 0
|
|
) {
|
|
starterAttributes.variant = 0;
|
|
} else if (!this.unlockedVariants[starterAttributes.variant]) {
|
|
let highestValidIndex = -1;
|
|
for (let i = 0; i <= starterAttributes.variant && i < this.unlockedVariants.length; i++) {
|
|
if (this.unlockedVariants[i]) {
|
|
highestValidIndex = i;
|
|
}
|
|
}
|
|
// Set to the highest valid index found or default to 0
|
|
starterAttributes.variant = highestValidIndex !== -1 ? highestValidIndex : 0;
|
|
}
|
|
|
|
if (starterAttributes.female !== undefined) {
|
|
if (
|
|
(starterAttributes.female && !(caughtAttr & DexAttr.FEMALE)) ||
|
|
(!starterAttributes.female && !(caughtAttr & DexAttr.MALE))
|
|
) {
|
|
starterAttributes.female = !starterAttributes.female;
|
|
}
|
|
} else {
|
|
if (caughtAttr & DexAttr.FEMALE) {
|
|
starterAttributes.female = true;
|
|
} else if (caughtAttr & DexAttr.MALE) {
|
|
starterAttributes.female = false;
|
|
}
|
|
}
|
|
|
|
return starterAttributes;
|
|
}
|
|
|
|
showText(
|
|
text: string,
|
|
delay?: number,
|
|
callback?: Function,
|
|
callbackDelay?: number,
|
|
prompt?: boolean,
|
|
promptDelay?: number,
|
|
moveToTop?: boolean,
|
|
) {
|
|
super.showText(text, delay, callback, callbackDelay, prompt, promptDelay);
|
|
|
|
const singleLine = text?.indexOf("\n") === -1;
|
|
|
|
this.starterSelectMessageBox.setSize(318, singleLine ? 28 : 42);
|
|
|
|
if (moveToTop) {
|
|
this.starterSelectMessageBox.setOrigin(0, 0);
|
|
this.starterSelectMessageBoxContainer.setY(0);
|
|
this.message.setY(4);
|
|
} else {
|
|
this.starterSelectMessageBoxContainer.setY(globalScene.game.canvas.height / 6);
|
|
this.starterSelectMessageBox.setOrigin(0, 1);
|
|
this.message.setY(singleLine ? -22 : -37);
|
|
}
|
|
|
|
this.starterSelectMessageBoxContainer.setVisible(!!text?.length);
|
|
}
|
|
|
|
/**
|
|
* Determines if 'Icon' based upgrade notifications should be shown
|
|
* @returns true if upgrade notifications are enabled and set to display an 'Icon'
|
|
*/
|
|
isUpgradeIconEnabled(): boolean {
|
|
return globalScene.candyUpgradeNotification !== 0 && globalScene.candyUpgradeDisplay === 0;
|
|
}
|
|
/**
|
|
* Determines if 'Animation' based upgrade notifications should be shown
|
|
* @returns true if upgrade notifications are enabled and set to display an 'Animation'
|
|
*/
|
|
isUpgradeAnimationEnabled(): boolean {
|
|
return globalScene.candyUpgradeNotification !== 0 && globalScene.candyUpgradeDisplay === 1;
|
|
}
|
|
|
|
/**
|
|
* If the pokemon is an evolution, find speciesId of its starter.
|
|
* @param speciesId the id of the species to check
|
|
* @returns the id of the corresponding starter
|
|
*/
|
|
getStarterSpeciesId(speciesId): number {
|
|
if (speciesId === Species.PIKACHU) {
|
|
if ([0, 1, 8].includes(this.formIndex)) {
|
|
return Species.PICHU;
|
|
}
|
|
return Species.PIKACHU;
|
|
}
|
|
if (speciesStarterCosts.hasOwnProperty(speciesId)) {
|
|
return speciesId;
|
|
}
|
|
return pokemonStarters[speciesId];
|
|
}
|
|
|
|
getStarterSpecies(species): PokemonSpecies {
|
|
if (speciesStarterCosts.hasOwnProperty(species.speciesId)) {
|
|
return species;
|
|
}
|
|
return allSpecies.find(sp => sp.speciesId === pokemonStarters[species.speciesId]) ?? species;
|
|
}
|
|
|
|
processInput(button: Button): boolean {
|
|
if (this.blockInput) {
|
|
return false;
|
|
}
|
|
|
|
const ui = this.getUi();
|
|
|
|
let success = false;
|
|
let error = false;
|
|
|
|
const isCaught = this.isCaught();
|
|
const isFormCaught = this.isFormCaught();
|
|
const isSeen = this.isSeen();
|
|
const isStarterCaught = !!this.isCaught(this.getStarterSpecies(this.species));
|
|
|
|
if (this.blockInputOverlay) {
|
|
if (button === Button.CANCEL || button === Button.ACTION) {
|
|
this.blockInputOverlay = false;
|
|
this.baseStatsOverlay.clear();
|
|
ui.showText("");
|
|
return true;
|
|
}
|
|
if (button === Button.UP || button === Button.DOWN) {
|
|
this.blockInputOverlay = false;
|
|
this.baseStatsOverlay.clear();
|
|
ui.showText("");
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if (button === Button.SUBMIT) {
|
|
success = true;
|
|
} else if (button === Button.CANCEL) {
|
|
if (this.statsMode) {
|
|
this.toggleStatsMode(false);
|
|
success = true;
|
|
} else if (this.previousSpecies.length > 0) {
|
|
this.blockInput = true;
|
|
ui.setModeWithoutClear(Mode.OPTION_SELECT).then(() => {
|
|
const species = this.previousSpecies.pop();
|
|
const starterAttributes = this.previousStarterAttributes.pop();
|
|
this.moveInfoOverlay.clear();
|
|
this.clearText();
|
|
ui.setModeForceTransition(Mode.POKEDEX_PAGE, species, starterAttributes);
|
|
success = true;
|
|
});
|
|
this.blockInput = false;
|
|
} else {
|
|
ui.revertMode().then(() => {
|
|
console.log("exitCallback", this.exitCallback);
|
|
if (this.exitCallback instanceof Function) {
|
|
const exitCallback = this.exitCallback;
|
|
this.exitCallback = null;
|
|
exitCallback();
|
|
}
|
|
});
|
|
success = true;
|
|
}
|
|
} else {
|
|
const starterData = globalScene.gameData.starterData[this.starterId];
|
|
// prepare persistent starter data to store changes
|
|
const starterAttributes = this.starterAttributes;
|
|
|
|
if (button === Button.ACTION) {
|
|
switch (this.cursor) {
|
|
case MenuOptions.BASE_STATS:
|
|
if (!isSeen) {
|
|
error = true;
|
|
} else {
|
|
this.blockInput = true;
|
|
|
|
ui.setMode(Mode.POKEDEX_PAGE, "refresh").then(() => {
|
|
ui.showText(i18next.t("pokedexUiHandler:showBaseStats"), null, () => {
|
|
this.baseStatsOverlay.show(this.baseStats, this.baseTotal);
|
|
|
|
this.blockInput = false;
|
|
this.blockInputOverlay = true;
|
|
|
|
return true;
|
|
});
|
|
success = true;
|
|
});
|
|
}
|
|
break;
|
|
|
|
case MenuOptions.LEVEL_MOVES:
|
|
if (!isSeen) {
|
|
error = true;
|
|
} else {
|
|
this.blockInput = true;
|
|
|
|
ui.setMode(Mode.POKEDEX_PAGE, "refresh").then(() => {
|
|
ui.showText(i18next.t("pokedexUiHandler:showLevelMoves"), null, () => {
|
|
this.moveInfoOverlay.show(allMoves[this.levelMoves[0][1]]);
|
|
|
|
ui.setModeWithoutClear(Mode.OPTION_SELECT, {
|
|
options: this.levelMoves
|
|
.map(m => {
|
|
const levelNumber = m[0] > 0 ? String(m[0]) : "";
|
|
const option: OptionSelectItem = {
|
|
label: levelNumber.padEnd(4, " ") + allMoves[m[1]].name,
|
|
handler: () => {
|
|
return false;
|
|
},
|
|
onHover: () => {
|
|
this.moveInfoOverlay.show(allMoves[m[1]]);
|
|
if (m[0] === 0) {
|
|
this.showText(i18next.t("pokedexUiHandler:onlyEvolutionMove"));
|
|
} else if (m[0] === -1) {
|
|
this.showText(i18next.t("pokedexUiHandler:onlyRecallMove"));
|
|
} else if (m[0] <= 5) {
|
|
this.showText(i18next.t("pokedexUiHandler:onStarterSelectMove"));
|
|
} else {
|
|
this.showText(i18next.t("pokedexUiHandler:byLevelUpMove"));
|
|
}
|
|
},
|
|
};
|
|
return option;
|
|
})
|
|
.concat({
|
|
label: i18next.t("menu:cancel"),
|
|
handler: () => {
|
|
this.moveInfoOverlay.clear();
|
|
this.clearText();
|
|
ui.setMode(Mode.POKEDEX_PAGE, "refresh");
|
|
return true;
|
|
},
|
|
onHover: () => {
|
|
this.moveInfoOverlay.clear();
|
|
},
|
|
}),
|
|
supportHover: true,
|
|
maxOptions: 8,
|
|
yOffset: 19,
|
|
});
|
|
|
|
this.blockInput = false;
|
|
});
|
|
});
|
|
success = true;
|
|
}
|
|
break;
|
|
|
|
case MenuOptions.EGG_MOVES:
|
|
if (!isSeen) {
|
|
error = true;
|
|
} else {
|
|
this.blockInput = true;
|
|
|
|
ui.setMode(Mode.POKEDEX_PAGE, "refresh").then(() => {
|
|
if (this.eggMoves.length === 0) {
|
|
ui.showText(i18next.t("pokedexUiHandler:noEggMoves"));
|
|
this.blockInput = false;
|
|
return true;
|
|
}
|
|
|
|
ui.showText(i18next.t("pokedexUiHandler:showEggMoves"), null, () => {
|
|
this.moveInfoOverlay.show(allMoves[this.eggMoves[0]]);
|
|
|
|
ui.setModeWithoutClear(Mode.OPTION_SELECT, {
|
|
options: [
|
|
{
|
|
label: i18next.t("pokedexUiHandler:common"),
|
|
skip: true,
|
|
style: TextStyle.MONEY_WINDOW,
|
|
handler: () => false, // Non-selectable, but handler is required
|
|
onHover: () => this.moveInfoOverlay.clear(), // No hover behavior for titles
|
|
},
|
|
...this.eggMoves.slice(0, 3).map((m, i) => ({
|
|
label: allMoves[m].name,
|
|
style: this.hasEggMoves[i] ? TextStyle.SETTINGS_VALUE : TextStyle.SHADOW_TEXT,
|
|
handler: () => false,
|
|
onHover: () => this.moveInfoOverlay.show(allMoves[m]),
|
|
})),
|
|
{
|
|
label: i18next.t("pokedexUiHandler:rare"),
|
|
skip: true,
|
|
style: TextStyle.MONEY_WINDOW,
|
|
handler: () => false,
|
|
onHover: () => this.moveInfoOverlay.clear(),
|
|
},
|
|
{
|
|
label: allMoves[this.eggMoves[3]].name,
|
|
style: this.hasEggMoves[3] ? TextStyle.SETTINGS_VALUE : TextStyle.SHADOW_TEXT,
|
|
handler: () => false,
|
|
onHover: () => this.moveInfoOverlay.show(allMoves[this.eggMoves[3]]),
|
|
},
|
|
{
|
|
label: i18next.t("menu:cancel"),
|
|
handler: () => {
|
|
this.moveInfoOverlay.clear();
|
|
this.clearText();
|
|
ui.setMode(Mode.POKEDEX_PAGE, "refresh");
|
|
return true;
|
|
},
|
|
onHover: () => this.moveInfoOverlay.clear(),
|
|
},
|
|
],
|
|
supportHover: true,
|
|
maxOptions: 8,
|
|
yOffset: 19,
|
|
});
|
|
|
|
this.blockInput = false;
|
|
});
|
|
});
|
|
success = true;
|
|
}
|
|
break;
|
|
|
|
case MenuOptions.TM_MOVES:
|
|
if (!isSeen) {
|
|
error = true;
|
|
} else if (this.tmMoves.length < 1) {
|
|
ui.showText(i18next.t("pokedexUiHandler:noTmMoves"));
|
|
error = true;
|
|
} else {
|
|
this.blockInput = true;
|
|
|
|
ui.setMode(Mode.POKEDEX_PAGE, "refresh").then(() => {
|
|
ui.showText(i18next.t("pokedexUiHandler:showTmMoves"), null, () => {
|
|
this.moveInfoOverlay.show(allMoves[this.tmMoves[0]]);
|
|
|
|
ui.setModeWithoutClear(Mode.OPTION_SELECT, {
|
|
options: this.tmMoves
|
|
.map(m => {
|
|
const option: OptionSelectItem = {
|
|
label: allMoves[m].name,
|
|
handler: () => {
|
|
return false;
|
|
},
|
|
onHover: () => {
|
|
this.moveInfoOverlay.show(allMoves[m]);
|
|
},
|
|
};
|
|
return option;
|
|
})
|
|
.concat({
|
|
label: i18next.t("menu:cancel"),
|
|
handler: () => {
|
|
this.moveInfoOverlay.clear();
|
|
this.clearText();
|
|
ui.setMode(Mode.POKEDEX_PAGE, "refresh");
|
|
return true;
|
|
},
|
|
onHover: () => {
|
|
this.moveInfoOverlay.clear();
|
|
},
|
|
}),
|
|
supportHover: true,
|
|
maxOptions: 8,
|
|
yOffset: 19,
|
|
});
|
|
|
|
this.blockInput = false;
|
|
});
|
|
});
|
|
success = true;
|
|
}
|
|
break;
|
|
|
|
case MenuOptions.ABILITIES:
|
|
if (!isSeen) {
|
|
error = true;
|
|
} else {
|
|
this.blockInput = true;
|
|
|
|
ui.setMode(Mode.POKEDEX_PAGE, "refresh").then(() => {
|
|
ui.showText(i18next.t("pokedexUiHandler:showAbilities"), null, () => {
|
|
this.infoOverlay.show(allAbilities[this.ability1].description);
|
|
|
|
const options: any[] = [];
|
|
|
|
if (this.ability1) {
|
|
options.push({
|
|
label: allAbilities[this.ability1].name,
|
|
style: this.hasAbilities[0] > 0 ? TextStyle.SETTINGS_VALUE : TextStyle.SHADOW_TEXT,
|
|
handler: () => false,
|
|
onHover: () => this.infoOverlay.show(allAbilities[this.ability1].description),
|
|
});
|
|
}
|
|
if (this.ability2) {
|
|
const ability = allAbilities[this.ability2];
|
|
options.push({
|
|
label: ability?.name,
|
|
style: this.hasAbilities[1] > 0 ? TextStyle.SETTINGS_VALUE : TextStyle.SHADOW_TEXT,
|
|
handler: () => false,
|
|
onHover: () => this.infoOverlay.show(ability?.description),
|
|
});
|
|
}
|
|
|
|
if (this.abilityHidden) {
|
|
options.push({
|
|
label: i18next.t("pokedexUiHandler:hidden"),
|
|
skip: true,
|
|
style: TextStyle.MONEY_WINDOW,
|
|
handler: () => false,
|
|
onHover: () => this.infoOverlay.clear(),
|
|
});
|
|
const ability = allAbilities[this.abilityHidden];
|
|
options.push({
|
|
label: allAbilities[this.abilityHidden].name,
|
|
style: this.hasAbilities[2] > 0 ? TextStyle.SETTINGS_VALUE : TextStyle.SHADOW_TEXT,
|
|
handler: () => false,
|
|
onHover: () => this.infoOverlay.show(ability?.description),
|
|
});
|
|
}
|
|
|
|
if (this.passive) {
|
|
options.push({
|
|
label: i18next.t("pokedexUiHandler:passive"),
|
|
skip: true,
|
|
style: TextStyle.MONEY_WINDOW,
|
|
handler: () => false,
|
|
onHover: () => this.infoOverlay.clear(),
|
|
});
|
|
options.push({
|
|
label: allAbilities[this.passive].name,
|
|
style: this.hasPassive ? TextStyle.SETTINGS_VALUE : TextStyle.SHADOW_TEXT,
|
|
handler: () => false,
|
|
onHover: () => this.infoOverlay.show(allAbilities[this.passive].description),
|
|
});
|
|
}
|
|
|
|
options.push({
|
|
label: i18next.t("menu:cancel"),
|
|
handler: () => {
|
|
this.infoOverlay.clear();
|
|
this.clearText();
|
|
ui.setMode(Mode.POKEDEX_PAGE, "refresh");
|
|
return true;
|
|
},
|
|
onHover: () => this.infoOverlay.clear(),
|
|
});
|
|
|
|
ui.setModeWithoutClear(Mode.OPTION_SELECT, {
|
|
options: options,
|
|
supportHover: true,
|
|
maxOptions: 8,
|
|
yOffset: 19,
|
|
});
|
|
|
|
this.blockInput = false;
|
|
});
|
|
});
|
|
success = true;
|
|
}
|
|
break;
|
|
|
|
case MenuOptions.BIOMES:
|
|
if (!isSeen) {
|
|
error = true;
|
|
} else {
|
|
this.blockInput = true;
|
|
|
|
ui.setMode(Mode.POKEDEX_PAGE, "refresh").then(() => {
|
|
if ((!this.biomes || this.biomes?.length === 0) && (!this.preBiomes || this.preBiomes?.length === 0)) {
|
|
ui.showText(i18next.t("pokedexUiHandler:noBiomes"));
|
|
ui.playError();
|
|
this.blockInput = false;
|
|
return true;
|
|
}
|
|
|
|
const options: any[] = [];
|
|
|
|
ui.showText(i18next.t("pokedexUiHandler:showBiomes"), null, () => {
|
|
this.biomes.map(b => {
|
|
options.push({
|
|
label:
|
|
i18next.t(`biome:${Biome[b.biome].toUpperCase()}`) +
|
|
" - " +
|
|
i18next.t(`biome:${BiomePoolTier[b.tier].toUpperCase()}`) +
|
|
(b.tod.length === 1 && b.tod[0] === -1
|
|
? ""
|
|
: " (" +
|
|
b.tod.map(tod => i18next.t(`biome:${TimeOfDay[tod].toUpperCase()}`)).join(", ") +
|
|
")"),
|
|
handler: () => false,
|
|
});
|
|
});
|
|
|
|
if (this.preBiomes.length > 0) {
|
|
options.push({
|
|
label: i18next.t("pokedexUiHandler:preBiomes"),
|
|
skip: true,
|
|
handler: () => false,
|
|
});
|
|
this.preBiomes.map(b => {
|
|
options.push({
|
|
label:
|
|
i18next.t(`biome:${Biome[b.biome].toUpperCase()}`) +
|
|
" - " +
|
|
i18next.t(`biome:${BiomePoolTier[b.tier].toUpperCase()}`) +
|
|
(b.tod.length === 1 && b.tod[0] === -1
|
|
? ""
|
|
: " (" +
|
|
b.tod.map(tod => i18next.t(`biome:${TimeOfDay[tod].toUpperCase()}`)).join(", ") +
|
|
")"),
|
|
handler: () => false,
|
|
});
|
|
});
|
|
}
|
|
|
|
options.push({
|
|
label: i18next.t("menu:cancel"),
|
|
handler: () => {
|
|
this.moveInfoOverlay.clear();
|
|
this.clearText();
|
|
ui.setMode(Mode.POKEDEX_PAGE, "refresh");
|
|
return true;
|
|
},
|
|
onHover: () => this.moveInfoOverlay.clear(),
|
|
});
|
|
|
|
ui.setModeWithoutClear(Mode.OPTION_SELECT, {
|
|
options: options,
|
|
supportHover: true,
|
|
maxOptions: 8,
|
|
yOffset: 19,
|
|
});
|
|
|
|
this.blockInput = false;
|
|
});
|
|
});
|
|
success = true;
|
|
}
|
|
break;
|
|
|
|
case MenuOptions.EVOLUTIONS:
|
|
if (!isSeen) {
|
|
error = true;
|
|
} else {
|
|
this.blockInput = true;
|
|
|
|
ui.setMode(Mode.POKEDEX_PAGE, "refresh").then(() => {
|
|
const options: any[] = [];
|
|
|
|
if (
|
|
(!this.prevolutions || this.prevolutions?.length === 0) &&
|
|
(!this.evolutions || this.evolutions?.length === 0) &&
|
|
(!this.battleForms || this.battleForms?.length === 0)
|
|
) {
|
|
ui.showText(i18next.t("pokedexUiHandler:noEvolutions"));
|
|
ui.playError();
|
|
this.blockInput = false;
|
|
return true;
|
|
}
|
|
|
|
ui.showText(i18next.t("pokedexUiHandler:showEvolutions"), null, () => {
|
|
if (this.prevolutions?.length > 0) {
|
|
options.push({
|
|
label: i18next.t("pokedexUiHandler:prevolutions"),
|
|
style: TextStyle.MONEY_WINDOW,
|
|
skip: true,
|
|
handler: () => false,
|
|
});
|
|
this.prevolutions.map(pre => {
|
|
const preSpecies = allSpecies.find(
|
|
species => species.speciesId === pokemonPrevolutions[this.species.speciesId],
|
|
);
|
|
const preFormIndex: number =
|
|
preSpecies?.forms.find(f => f.formKey === pre.preFormKey)?.formIndex ?? 0;
|
|
|
|
const conditionText: string = pre.description;
|
|
|
|
options.push({
|
|
label: pre.preFormKey
|
|
? (preSpecies ?? this.species).getFormNameToDisplay(preFormIndex, true)
|
|
: (preSpecies ?? this.species).getExpandedSpeciesName(),
|
|
handler: () => {
|
|
this.previousSpecies.push(this.species);
|
|
this.previousStarterAttributes.push({ ...this.savedStarterAttributes });
|
|
const newSpecies = allSpecies.find(
|
|
species => species.speciesId === pokemonPrevolutions[pre.speciesId],
|
|
);
|
|
// Attempts to find the formIndex of the prevolved species
|
|
const newFormKey = pre.preFormKey
|
|
? pre.preFormKey
|
|
: this.species.forms.length > 0
|
|
? this.species.forms[this.formIndex].formKey
|
|
: "";
|
|
const matchingForm = newSpecies?.forms.find(form => form.formKey === newFormKey);
|
|
const newFormIndex = matchingForm ? matchingForm.formIndex : 0;
|
|
this.starterAttributes.form = newFormIndex;
|
|
this.savedStarterAttributes.form = newFormIndex;
|
|
this.moveInfoOverlay.clear();
|
|
this.clearText();
|
|
ui.setMode(Mode.POKEDEX_PAGE, newSpecies, this.savedStarterAttributes);
|
|
return true;
|
|
},
|
|
onHover: () => this.showText(conditionText),
|
|
});
|
|
});
|
|
}
|
|
|
|
if (this.evolutions.length > 0) {
|
|
options.push({
|
|
label: i18next.t("pokedexUiHandler:evolutions"),
|
|
style: TextStyle.MONEY_WINDOW,
|
|
skip: true,
|
|
handler: () => false,
|
|
});
|
|
this.evolutions.map(evo => {
|
|
const evoSpecies = allSpecies.find(species => species.speciesId === evo.speciesId);
|
|
const isCaughtEvo = !!this.isCaught(evoSpecies);
|
|
// Attempts to find the formIndex of the evolved species
|
|
const newFormKey = evo.evoFormKey
|
|
? evo.evoFormKey
|
|
: this.species.forms.length > 0
|
|
? this.species.forms[this.formIndex].formKey
|
|
: "";
|
|
const matchingForm = evoSpecies?.forms.find(form => form.formKey === newFormKey);
|
|
const newFormIndex = matchingForm ? matchingForm.formIndex : 0;
|
|
const isFormCaughtEvo = this.isFormCaught(evoSpecies, newFormIndex);
|
|
|
|
const conditionText: string = evo.description;
|
|
|
|
options.push({
|
|
label: evo.evoFormKey
|
|
? (evoSpecies ?? this.species).getFormNameToDisplay(newFormIndex, true)
|
|
: (evoSpecies ?? this.species).getExpandedSpeciesName(),
|
|
style: isCaughtEvo && isFormCaughtEvo ? TextStyle.WINDOW : TextStyle.SHADOW_TEXT,
|
|
handler: () => {
|
|
this.previousSpecies.push(this.species);
|
|
this.previousStarterAttributes.push({ ...this.savedStarterAttributes });
|
|
this.starterAttributes.form = newFormIndex;
|
|
this.savedStarterAttributes.form = newFormIndex;
|
|
this.moveInfoOverlay.clear();
|
|
this.clearText();
|
|
ui.setMode(Mode.POKEDEX_PAGE, evoSpecies, this.savedStarterAttributes);
|
|
return true;
|
|
},
|
|
onHover: () => this.showText(conditionText),
|
|
});
|
|
});
|
|
}
|
|
|
|
if (this.battleForms.length > 0) {
|
|
options.push({
|
|
label: i18next.t("pokedexUiHandler:forms"),
|
|
style: TextStyle.MONEY_WINDOW,
|
|
skip: true,
|
|
handler: () => false,
|
|
});
|
|
this.battleForms.map(bf => {
|
|
const matchingForm = this.species?.forms.find(form => form.formKey === bf.formKey);
|
|
const newFormIndex = matchingForm ? matchingForm.formIndex : 0;
|
|
|
|
let conditionText = "";
|
|
if (bf.trigger) {
|
|
conditionText = bf.trigger.description;
|
|
} else {
|
|
conditionText = "";
|
|
}
|
|
let label: string = this.species.getFormNameToDisplay(newFormIndex);
|
|
if (label === "") {
|
|
label = this.species.name;
|
|
}
|
|
const isFormCaught = this.isFormCaught(this.species, newFormIndex);
|
|
|
|
if (conditionText) {
|
|
options.push({
|
|
label: label,
|
|
style: isFormCaught ? TextStyle.WINDOW : TextStyle.SHADOW_TEXT,
|
|
handler: () => {
|
|
this.previousSpecies.push(this.species);
|
|
this.previousStarterAttributes.push({ ...this.savedStarterAttributes });
|
|
const newSpecies = this.species;
|
|
const newFormIndex = this.species.forms.find(f => f.formKey === bf.formKey)?.formIndex;
|
|
this.starterAttributes.form = newFormIndex;
|
|
this.savedStarterAttributes.form = newFormIndex;
|
|
this.moveInfoOverlay.clear();
|
|
this.clearText();
|
|
ui.setMode(
|
|
Mode.POKEDEX_PAGE,
|
|
newSpecies,
|
|
this.savedStarterAttributes,
|
|
this.filteredIndices,
|
|
);
|
|
return true;
|
|
},
|
|
onHover: () => this.showText(conditionText),
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
options.push({
|
|
label: i18next.t("menu:cancel"),
|
|
handler: () => {
|
|
this.moveInfoOverlay.clear();
|
|
this.clearText();
|
|
ui.setMode(Mode.POKEDEX_PAGE, "refresh");
|
|
return true;
|
|
},
|
|
onHover: () => this.moveInfoOverlay.clear(),
|
|
});
|
|
|
|
ui.setModeWithoutClear(Mode.OPTION_SELECT, {
|
|
options: options,
|
|
supportHover: true,
|
|
maxOptions: 8,
|
|
yOffset: 19,
|
|
});
|
|
|
|
this.blockInput = false;
|
|
});
|
|
});
|
|
success = true;
|
|
}
|
|
break;
|
|
|
|
case MenuOptions.TOGGLE_IVS:
|
|
if (!isStarterCaught) {
|
|
error = true;
|
|
} else {
|
|
this.toggleStatsMode();
|
|
ui.setMode(Mode.POKEDEX_PAGE, "refresh");
|
|
success = true;
|
|
}
|
|
break;
|
|
|
|
case MenuOptions.NATURES:
|
|
if (!isStarterCaught) {
|
|
error = true;
|
|
} else {
|
|
this.blockInput = true;
|
|
ui.setMode(Mode.POKEDEX_PAGE, "refresh").then(() => {
|
|
ui.showText(i18next.t("pokedexUiHandler:showNature"), null, () => {
|
|
const natures = globalScene.gameData.getNaturesForAttr(this.speciesStarterDexEntry?.natureAttr);
|
|
ui.setModeWithoutClear(Mode.OPTION_SELECT, {
|
|
options: natures
|
|
.map((n: Nature, _i: number) => {
|
|
const option: OptionSelectItem = {
|
|
label: getNatureName(n, true, true, true, globalScene.uiTheme),
|
|
handler: () => {
|
|
return false;
|
|
},
|
|
};
|
|
return option;
|
|
})
|
|
.concat({
|
|
label: i18next.t("menu:cancel"),
|
|
handler: () => {
|
|
this.clearText();
|
|
ui.setMode(Mode.POKEDEX_PAGE, "refresh");
|
|
this.blockInput = false;
|
|
return true;
|
|
},
|
|
}),
|
|
maxOptions: 8,
|
|
yOffset: 19,
|
|
});
|
|
});
|
|
});
|
|
success = true;
|
|
}
|
|
break;
|
|
}
|
|
} else {
|
|
const props = globalScene.gameData.getSpeciesDexAttrProps(
|
|
this.species,
|
|
this.getCurrentDexProps(this.species.speciesId),
|
|
);
|
|
switch (button) {
|
|
case Button.CYCLE_SHINY:
|
|
if (this.canCycleShiny) {
|
|
if (!starterAttributes.shiny) {
|
|
// Change to shiny, we need to get the proper default variant
|
|
const newVariant = starterAttributes.variant ? (starterAttributes.variant as Variant) : 0;
|
|
this.setSpeciesDetails(this.species, {
|
|
shiny: true,
|
|
variant: newVariant,
|
|
});
|
|
|
|
globalScene.playSound("se/sparkle");
|
|
|
|
starterAttributes.shiny = true;
|
|
this.savedStarterAttributes.shiny = starterAttributes.shiny;
|
|
} else {
|
|
let newVariant = props.variant;
|
|
do {
|
|
newVariant = (newVariant + 1) % 3;
|
|
if (newVariant === 0) {
|
|
if (this.isCaught() & DexAttr.DEFAULT_VARIANT) {
|
|
break;
|
|
}
|
|
} else if (newVariant === 1) {
|
|
if (this.isCaught() & DexAttr.VARIANT_2) {
|
|
break;
|
|
}
|
|
} else {
|
|
if (this.isCaught() & DexAttr.VARIANT_3) {
|
|
break;
|
|
}
|
|
}
|
|
} while (newVariant !== props.variant);
|
|
|
|
starterAttributes.variant = newVariant; // store the selected variant
|
|
this.savedStarterAttributes.variant = starterAttributes.variant;
|
|
if (this.isCaught() & DexAttr.NON_SHINY && newVariant <= props.variant) {
|
|
this.setSpeciesDetails(this.species, {
|
|
shiny: false,
|
|
variant: 0,
|
|
});
|
|
success = true;
|
|
starterAttributes.shiny = false;
|
|
this.savedStarterAttributes.shiny = starterAttributes.shiny;
|
|
} else {
|
|
this.setSpeciesDetails(this.species, {
|
|
variant: newVariant as Variant,
|
|
});
|
|
success = true;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case Button.CYCLE_FORM:
|
|
if (this.canCycleForm) {
|
|
const formCount = this.species.forms.length;
|
|
let newFormIndex = this.formIndex;
|
|
do {
|
|
newFormIndex = (newFormIndex + 1) % formCount;
|
|
if (this.species.forms[newFormIndex].isStarterSelectable || globalScene.dexForDevs) {
|
|
// TODO: are those bangs correct?
|
|
break;
|
|
}
|
|
} while (newFormIndex !== props.formIndex || this.species.forms[newFormIndex].isUnobtainable);
|
|
starterAttributes.form = newFormIndex; // store the selected form
|
|
this.savedStarterAttributes.form = starterAttributes.form;
|
|
this.formIndex = newFormIndex;
|
|
// Some forms are tied to the gender and should change accordingly
|
|
let newFemale = props.female;
|
|
if (this.isFormGender) {
|
|
newFemale = !props.female;
|
|
}
|
|
starterAttributes.female = newFemale;
|
|
this.savedStarterAttributes.female = starterAttributes.female;
|
|
this.starterSetup();
|
|
this.setSpeciesDetails(this.species, {
|
|
formIndex: newFormIndex,
|
|
female: newFemale,
|
|
});
|
|
success = this.setCursor(this.cursor);
|
|
}
|
|
break;
|
|
case Button.CYCLE_GENDER:
|
|
if (this.canCycleGender) {
|
|
starterAttributes.female = !props.female;
|
|
this.savedStarterAttributes.female = starterAttributes.female;
|
|
let newFormIndex = this.formIndex;
|
|
// Some forms are tied to the gender and should change accordingly
|
|
if (this.isFormGender) {
|
|
newFormIndex = this.formIndex === 0 ? 1 : 0;
|
|
}
|
|
starterAttributes.form = newFormIndex; // store the selected form
|
|
this.savedStarterAttributes.form = starterAttributes.form;
|
|
this.formIndex = newFormIndex;
|
|
this.starterSetup();
|
|
this.setSpeciesDetails(this.species, {
|
|
female: !props.female,
|
|
formIndex: newFormIndex,
|
|
});
|
|
success = true;
|
|
}
|
|
break;
|
|
case Button.STATS:
|
|
if (!isCaught || !isFormCaught || !this.canUseCandies) {
|
|
error = true;
|
|
} else {
|
|
const ui = this.getUi();
|
|
ui.showText("");
|
|
const options: any[] = []; // TODO: add proper type
|
|
|
|
const passiveAttr = starterData.passiveAttr;
|
|
const candyCount = starterData.candyCount;
|
|
|
|
if (!(passiveAttr & PassiveAttr.UNLOCKED)) {
|
|
const passiveCost = getPassiveCandyCount(speciesStarterCosts[this.starterId]);
|
|
options.push({
|
|
label: `x${passiveCost} ${i18next.t("pokedexUiHandler:unlockPassive")} (${allAbilities[this.passive].name})`,
|
|
handler: () => {
|
|
if (Overrides.FREE_CANDY_UPGRADE_OVERRIDE || candyCount >= passiveCost) {
|
|
starterData.passiveAttr |= PassiveAttr.UNLOCKED | PassiveAttr.ENABLED;
|
|
if (!Overrides.FREE_CANDY_UPGRADE_OVERRIDE) {
|
|
starterData.candyCount -= passiveCost;
|
|
}
|
|
this.pokemonCandyCountText.setText(`x${starterData.candyCount}`);
|
|
globalScene.gameData.saveSystem().then(success => {
|
|
if (!success) {
|
|
return globalScene.reset(true);
|
|
}
|
|
});
|
|
this.setSpeciesDetails(this.species);
|
|
globalScene.playSound("se/buy");
|
|
ui.setMode(Mode.POKEDEX_PAGE, "refresh");
|
|
|
|
return true;
|
|
}
|
|
return false;
|
|
},
|
|
style: this.isPassiveAvailable() ? TextStyle.WINDOW : TextStyle.SHADOW_TEXT,
|
|
item: "candy",
|
|
itemArgs: this.isPassiveAvailable() ? starterColors[this.starterId] : ["808080", "808080"],
|
|
});
|
|
}
|
|
|
|
// Reduce cost option
|
|
const valueReduction = starterData.valueReduction;
|
|
if (valueReduction < valueReductionMax) {
|
|
const reductionCost = getValueReductionCandyCounts(speciesStarterCosts[this.starterId])[valueReduction];
|
|
options.push({
|
|
label: `x${reductionCost} ${i18next.t("pokedexUiHandler:reduceCost")}`,
|
|
handler: () => {
|
|
if (Overrides.FREE_CANDY_UPGRADE_OVERRIDE || candyCount >= reductionCost) {
|
|
starterData.valueReduction++;
|
|
if (!Overrides.FREE_CANDY_UPGRADE_OVERRIDE) {
|
|
starterData.candyCount -= reductionCost;
|
|
}
|
|
this.pokemonCandyCountText.setText(`x${starterData.candyCount}`);
|
|
globalScene.gameData.saveSystem().then(success => {
|
|
if (!success) {
|
|
return globalScene.reset(true);
|
|
}
|
|
});
|
|
ui.setMode(Mode.POKEDEX_PAGE, "refresh");
|
|
globalScene.playSound("se/buy");
|
|
|
|
return true;
|
|
}
|
|
return false;
|
|
},
|
|
style: this.isValueReductionAvailable() ? TextStyle.WINDOW : TextStyle.SHADOW_TEXT,
|
|
item: "candy",
|
|
itemArgs: this.isValueReductionAvailable() ? starterColors[this.starterId] : ["808080", "808080"],
|
|
});
|
|
}
|
|
|
|
// Same species egg menu option.
|
|
const sameSpeciesEggCost = getSameSpeciesEggCandyCounts(speciesStarterCosts[this.starterId]);
|
|
options.push({
|
|
label: `x${sameSpeciesEggCost} ${i18next.t("pokedexUiHandler:sameSpeciesEgg")}`,
|
|
handler: () => {
|
|
if (Overrides.FREE_CANDY_UPGRADE_OVERRIDE || candyCount >= sameSpeciesEggCost) {
|
|
if (globalScene.gameData.eggs.length >= 99 && !Overrides.UNLIMITED_EGG_COUNT_OVERRIDE) {
|
|
// Egg list full, show error message at the top of the screen and abort
|
|
this.showText(
|
|
i18next.t("egg:tooManyEggs"),
|
|
undefined,
|
|
() => this.showText("", 0, () => (this.tutorialActive = false)),
|
|
2000,
|
|
false,
|
|
undefined,
|
|
true,
|
|
);
|
|
return false;
|
|
}
|
|
if (!Overrides.FREE_CANDY_UPGRADE_OVERRIDE) {
|
|
starterData.candyCount -= sameSpeciesEggCost;
|
|
}
|
|
this.pokemonCandyCountText.setText(`x${starterData.candyCount}`);
|
|
|
|
const egg = new Egg({
|
|
scene: globalScene,
|
|
species: this.starterId,
|
|
sourceType: EggSourceType.SAME_SPECIES_EGG,
|
|
});
|
|
egg.addEggToGameData();
|
|
|
|
globalScene.gameData.saveSystem().then(success => {
|
|
if (!success) {
|
|
return globalScene.reset(true);
|
|
}
|
|
});
|
|
ui.setMode(Mode.POKEDEX_PAGE, "refresh");
|
|
globalScene.playSound("se/buy");
|
|
|
|
return true;
|
|
}
|
|
return false;
|
|
},
|
|
style: this.isSameSpeciesEggAvailable() ? TextStyle.WINDOW : TextStyle.SHADOW_TEXT,
|
|
item: "candy",
|
|
itemArgs: this.isSameSpeciesEggAvailable() ? starterColors[this.starterId] : ["808080", "808080"],
|
|
});
|
|
options.push({
|
|
label: i18next.t("menu:cancel"),
|
|
handler: () => {
|
|
ui.setMode(Mode.POKEDEX_PAGE, "refresh");
|
|
return true;
|
|
},
|
|
});
|
|
ui.setModeWithoutClear(Mode.OPTION_SELECT, {
|
|
options: options,
|
|
yOffset: 47,
|
|
});
|
|
success = true;
|
|
}
|
|
break;
|
|
case Button.CYCLE_ABILITY:
|
|
this.showBackSprite = !this.showBackSprite;
|
|
if (this.showBackSprite) {
|
|
this.showBackSpriteLabel.setText(i18next.t("pokedexUiHandler:showFrontSprite"));
|
|
} else {
|
|
this.showBackSpriteLabel.setText(i18next.t("pokedexUiHandler:showBackSprite"));
|
|
}
|
|
this.setSpeciesDetails(this.species, {}, true);
|
|
success = true;
|
|
break;
|
|
case Button.UP:
|
|
if (this.cursor) {
|
|
success = this.setCursor(this.cursor - 1);
|
|
} else {
|
|
success = this.setCursor(this.menuOptions.length - 1);
|
|
}
|
|
break;
|
|
case Button.DOWN:
|
|
if (this.cursor + 1 < this.menuOptions.length) {
|
|
success = this.setCursor(this.cursor + 1);
|
|
} else {
|
|
success = this.setCursor(0);
|
|
}
|
|
break;
|
|
case Button.LEFT:
|
|
if (this.filteredIndices && this.filteredIndices.length <= 1) {
|
|
ui.playError();
|
|
this.blockInput = false;
|
|
return true;
|
|
}
|
|
this.blockInput = true;
|
|
ui.setModeWithoutClear(Mode.OPTION_SELECT).then(() => {
|
|
// Always go back to first selection after scrolling around
|
|
if (this.previousSpecies.length === 0) {
|
|
this.previousSpecies.push(this.species);
|
|
this.previousStarterAttributes.push({ ...this.savedStarterAttributes });
|
|
}
|
|
let newSpecies: PokemonSpecies;
|
|
if (this.filteredIndices) {
|
|
const index = this.filteredIndices.findIndex(id => id === this.species.speciesId);
|
|
const newIndex = index <= 0 ? this.filteredIndices.length - 1 : index - 1;
|
|
newSpecies = getPokemonSpecies(this.filteredIndices[newIndex]);
|
|
} else {
|
|
const index = allSpecies.findIndex(species => species.speciesId === this.species.speciesId);
|
|
const newIndex = index <= 0 ? allSpecies.length - 1 : index - 1;
|
|
newSpecies = allSpecies[newIndex];
|
|
}
|
|
const matchingForm = newSpecies?.forms.find(
|
|
form => form.formKey === this.species?.forms[this.formIndex]?.formKey,
|
|
);
|
|
const newFormIndex = matchingForm ? matchingForm.formIndex : 0;
|
|
this.starterAttributes.form = newFormIndex;
|
|
this.savedStarterAttributes.form = newFormIndex;
|
|
this.moveInfoOverlay.clear();
|
|
this.clearText();
|
|
ui.setModeForceTransition(
|
|
Mode.POKEDEX_PAGE,
|
|
newSpecies,
|
|
this.savedStarterAttributes,
|
|
this.filteredIndices,
|
|
);
|
|
});
|
|
this.blockInput = false;
|
|
break;
|
|
case Button.RIGHT:
|
|
if (this.filteredIndices && this.filteredIndices.length <= 1) {
|
|
ui.playError();
|
|
this.blockInput = false;
|
|
return true;
|
|
}
|
|
ui.setModeWithoutClear(Mode.OPTION_SELECT).then(() => {
|
|
// Always go back to first selection after scrolling around
|
|
if (this.previousSpecies.length === 0) {
|
|
this.previousSpecies.push(this.species);
|
|
this.previousStarterAttributes.push({ ...this.savedStarterAttributes });
|
|
}
|
|
let newSpecies: PokemonSpecies;
|
|
if (this.filteredIndices) {
|
|
const index = this.filteredIndices.findIndex(id => id === this.species.speciesId);
|
|
const newIndex = index >= this.filteredIndices.length - 1 ? 0 : index + 1;
|
|
newSpecies = getPokemonSpecies(this.filteredIndices[newIndex]);
|
|
} else {
|
|
const index = allSpecies.findIndex(species => species.speciesId === this.species.speciesId);
|
|
const newIndex = index >= allSpecies.length - 1 ? 0 : index + 1;
|
|
newSpecies = allSpecies[newIndex];
|
|
}
|
|
const matchingForm = newSpecies?.forms.find(
|
|
form => form.formKey === this.species?.forms[this.formIndex]?.formKey,
|
|
);
|
|
const newFormIndex = matchingForm ? matchingForm.formIndex : 0;
|
|
this.starterAttributes.form = newFormIndex;
|
|
this.savedStarterAttributes.form = newFormIndex;
|
|
this.moveInfoOverlay.clear();
|
|
this.clearText();
|
|
ui.setModeForceTransition(
|
|
Mode.POKEDEX_PAGE,
|
|
newSpecies,
|
|
this.savedStarterAttributes,
|
|
this.filteredIndices,
|
|
);
|
|
});
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (success) {
|
|
ui.playSelect();
|
|
} else if (error) {
|
|
ui.playError();
|
|
}
|
|
|
|
return success || error;
|
|
}
|
|
|
|
updateButtonIcon(iconSetting, gamepadType, iconElement, controlLabel): void {
|
|
// biome-ignore lint/suspicious/noImplicitAnyLet: TODO
|
|
let iconPath;
|
|
// touch controls cannot be rebound as is, and are just emulating a keyboard event.
|
|
// Additionally, since keyboard controls can be rebound (and will be displayed when they are), we need to have special handling for the touch controls
|
|
if (gamepadType === "touch") {
|
|
gamepadType = "keyboard";
|
|
switch (iconSetting) {
|
|
case SettingKeyboard.Button_Cycle_Shiny:
|
|
iconPath = "R.png";
|
|
break;
|
|
case SettingKeyboard.Button_Cycle_Form:
|
|
iconPath = "F.png";
|
|
break;
|
|
case SettingKeyboard.Button_Cycle_Gender:
|
|
iconPath = "G.png";
|
|
break;
|
|
case SettingKeyboard.Button_Cycle_Ability:
|
|
iconPath = "E.png";
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
} else {
|
|
iconPath = globalScene.inputController?.getIconForLatestInputRecorded(iconSetting);
|
|
}
|
|
iconElement.setTexture(gamepadType, iconPath);
|
|
iconElement.setPosition(this.instructionRowX, this.instructionRowY);
|
|
controlLabel.setPosition(this.instructionRowX + this.instructionRowTextOffset, this.instructionRowY);
|
|
iconElement.setVisible(true);
|
|
controlLabel.setVisible(true);
|
|
this.instructionsContainer.add([iconElement, controlLabel]);
|
|
this.instructionRowY += 8;
|
|
if (this.instructionRowY >= 24) {
|
|
this.instructionRowY = 8;
|
|
this.instructionRowX += 50;
|
|
}
|
|
}
|
|
|
|
updateInstructions(): void {
|
|
this.instructionRowX = 0;
|
|
this.instructionRowY = 0;
|
|
this.filterInstructionRowX = 0;
|
|
this.filterInstructionRowY = 0;
|
|
this.hideInstructions();
|
|
this.instructionsContainer.removeAll();
|
|
this.filterInstructionsContainer.removeAll();
|
|
|
|
// biome-ignore lint/suspicious/noImplicitAnyLet: TODO
|
|
let gamepadType;
|
|
if (globalScene.inputMethod === "gamepad") {
|
|
gamepadType = globalScene.inputController.getConfig(
|
|
globalScene.inputController.selectedDevice[Device.GAMEPAD],
|
|
).padType;
|
|
} else {
|
|
gamepadType = globalScene.inputMethod;
|
|
}
|
|
|
|
if (!gamepadType) {
|
|
return;
|
|
}
|
|
|
|
const isFormCaught = this.isFormCaught();
|
|
|
|
if (this.isCaught()) {
|
|
if (isFormCaught) {
|
|
if (this.canUseCandies) {
|
|
this.updateButtonIcon(
|
|
SettingKeyboard.Button_Stats,
|
|
gamepadType,
|
|
this.candyUpgradeIconElement,
|
|
this.candyUpgradeLabel,
|
|
);
|
|
}
|
|
if (this.canCycleShiny) {
|
|
this.updateButtonIcon(
|
|
SettingKeyboard.Button_Cycle_Shiny,
|
|
gamepadType,
|
|
this.shinyIconElement,
|
|
this.shinyLabel,
|
|
);
|
|
}
|
|
if (this.canCycleGender) {
|
|
this.updateButtonIcon(
|
|
SettingKeyboard.Button_Cycle_Gender,
|
|
gamepadType,
|
|
this.genderIconElement,
|
|
this.genderLabel,
|
|
);
|
|
}
|
|
} else {
|
|
// Making space for "Uncaught" text
|
|
this.instructionRowY += 8;
|
|
}
|
|
if (this.canCycleForm) {
|
|
this.updateButtonIcon(SettingKeyboard.Button_Cycle_Form, gamepadType, this.formIconElement, this.formLabel);
|
|
}
|
|
}
|
|
}
|
|
|
|
setCursor(cursor: number): boolean {
|
|
const ret = super.setCursor(cursor);
|
|
|
|
if (!this.cursorObj) {
|
|
this.cursorObj = globalScene.add.image(0, 0, "cursor");
|
|
this.cursorObj.setOrigin(0, 0);
|
|
this.menuContainer.add(this.cursorObj);
|
|
}
|
|
|
|
this.cursorObj.setScale(this.scale * 6);
|
|
this.cursorObj.setPositionRelative(this.menuBg, 7, 6 + (18 + this.cursor * 96) * this.scale);
|
|
|
|
const ui = this.getUi();
|
|
|
|
if ((this.isCaught() && this.isFormCaught()) || this.isSeen()) {
|
|
ui.showText(this.menuDescriptions[cursor]);
|
|
} else {
|
|
ui.showText("");
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
getFriendship(_speciesId: number) {
|
|
let currentFriendship = globalScene.gameData.starterData[this.starterId].friendship;
|
|
if (!currentFriendship || currentFriendship === undefined) {
|
|
currentFriendship = 0;
|
|
}
|
|
|
|
const friendshipCap = getStarterValueFriendshipCap(speciesStarterCosts[this.starterId]);
|
|
|
|
return { currentFriendship, friendshipCap };
|
|
}
|
|
|
|
/**
|
|
* Determines if a passive upgrade is available for the current species
|
|
* @returns true if the user has enough candies and a passive has not been unlocked already
|
|
*/
|
|
isPassiveAvailable(): boolean {
|
|
// Get this species ID's starter data
|
|
const starterData = globalScene.gameData.starterData[this.starterId];
|
|
|
|
return (
|
|
starterData.candyCount >= getPassiveCandyCount(speciesStarterCosts[this.starterId]) &&
|
|
!(starterData.passiveAttr & PassiveAttr.UNLOCKED)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Determines if a value reduction upgrade is available for the current species
|
|
* @returns true if the user has enough candies and all value reductions have not been unlocked already
|
|
*/
|
|
isValueReductionAvailable(): boolean {
|
|
// Get this species ID's starter data
|
|
const starterData = globalScene.gameData.starterData[this.starterId];
|
|
|
|
return (
|
|
starterData.candyCount >=
|
|
getValueReductionCandyCounts(speciesStarterCosts[this.starterId])[starterData.valueReduction] &&
|
|
starterData.valueReduction < valueReductionMax
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Determines if an same species egg can be bought for the current species
|
|
* @returns true if the user has enough candies
|
|
*/
|
|
isSameSpeciesEggAvailable(): boolean {
|
|
// Get this species ID's starter data
|
|
const starterData = globalScene.gameData.starterData[this.starterId];
|
|
|
|
return starterData.candyCount >= getSameSpeciesEggCandyCounts(speciesStarterCosts[this.starterId]);
|
|
}
|
|
|
|
setSpecies() {
|
|
const species = this.species;
|
|
const starterAttributes: StarterAttributes | null = species ? { ...this.starterAttributes } : null;
|
|
|
|
if (!species && globalScene.ui.getTooltip().visible) {
|
|
globalScene.ui.hideTooltip();
|
|
}
|
|
|
|
if (this.statsMode) {
|
|
if (this.isCaught()) {
|
|
this.statsContainer.setVisible(true);
|
|
this.showStats();
|
|
} else {
|
|
this.statsContainer.setVisible(false);
|
|
//@ts-ignore
|
|
this.statsContainer.updateIvs(null); // TODO: resolve ts-ignore. what. how? huh?
|
|
}
|
|
}
|
|
|
|
if (species && (this.isSeen() || this.isCaught())) {
|
|
this.pokemonNumberText.setText(padInt(species.speciesId, 4));
|
|
|
|
if (this.isCaught()) {
|
|
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;
|
|
}
|
|
}
|
|
props.form = starterAttributes?.form ?? props.form;
|
|
props.female = starterAttributes?.female ?? props.female;
|
|
|
|
this.setSpeciesDetails(species, {
|
|
shiny: props.shiny,
|
|
formIndex: props.form,
|
|
female: props.female,
|
|
variant: props.variant ?? 0,
|
|
});
|
|
} else {
|
|
this.pokemonGrowthRateText.setText("");
|
|
this.pokemonGrowthRateLabelText.setVisible(false);
|
|
this.type1Icon.setVisible(true);
|
|
this.type2Icon.setVisible(true);
|
|
this.pokemonLuckLabelText.setVisible(false);
|
|
this.pokemonLuckText.setVisible(false);
|
|
for (const icon of this.pokemonShinyIcons) {
|
|
icon.setVisible(false);
|
|
}
|
|
this.pokemonUncaughtText.setVisible(true);
|
|
this.pokemonCaughtHatchedContainer.setVisible(true);
|
|
this.pokemonCandyContainer.setVisible(false);
|
|
this.pokemonFormText.setVisible(false);
|
|
|
|
const defaultDexAttr = globalScene.gameData.getSpeciesDefaultDexAttr(species, true, true);
|
|
const props = globalScene.gameData.getSpeciesDexAttrProps(species, defaultDexAttr);
|
|
|
|
this.setSpeciesDetails(species, {
|
|
shiny: props.shiny,
|
|
formIndex: props.formIndex,
|
|
female: props.female,
|
|
variant: props.variant,
|
|
});
|
|
this.pokemonSprite.setTint(0x808080);
|
|
}
|
|
} else {
|
|
this.pokemonNumberText.setText(species ? padInt(species.speciesId, 4) : "");
|
|
this.pokemonNameText.setText(species ? "???" : "");
|
|
this.pokemonGrowthRateText.setText("");
|
|
this.pokemonGrowthRateLabelText.setVisible(false);
|
|
this.type1Icon.setVisible(false);
|
|
this.type2Icon.setVisible(false);
|
|
this.pokemonLuckLabelText.setVisible(false);
|
|
this.pokemonLuckText.setVisible(false);
|
|
for (const icon of this.pokemonShinyIcons) {
|
|
icon.setVisible(false);
|
|
}
|
|
this.pokemonUncaughtText.setVisible(!!species);
|
|
this.pokemonCaughtHatchedContainer.setVisible(false);
|
|
this.pokemonCandyContainer.setVisible(false);
|
|
this.pokemonFormText.setVisible(false);
|
|
|
|
this.setSpeciesDetails(species!, {
|
|
// TODO: is this bang correct?
|
|
shiny: false,
|
|
formIndex: 0,
|
|
female: false,
|
|
variant: 0,
|
|
});
|
|
this.pokemonSprite.setTint(0x000000);
|
|
}
|
|
}
|
|
|
|
setSpeciesDetails(species: PokemonSpecies, options: SpeciesDetails = {}, forceUpdate?: boolean): void {
|
|
let { shiny, formIndex, female, variant } = options;
|
|
const oldProps = species ? this.starterAttributes : null;
|
|
|
|
// We will only update the sprite if there is a change to form, shiny/variant
|
|
// or gender for species with gender sprite differences
|
|
const shouldUpdateSprite =
|
|
(species?.genderDiffs && !isNullOrUndefined(female)) ||
|
|
!isNullOrUndefined(formIndex) ||
|
|
!isNullOrUndefined(shiny) ||
|
|
!isNullOrUndefined(variant) ||
|
|
forceUpdate;
|
|
|
|
if (this.activeTooltip === "CANDY") {
|
|
if (this.species && this.pokemonCandyContainer.visible) {
|
|
const { currentFriendship, friendshipCap } = this.getFriendship(this.species.speciesId);
|
|
globalScene.ui.editTooltip("", `${currentFriendship}/${friendshipCap}`);
|
|
} else {
|
|
globalScene.ui.hideTooltip();
|
|
}
|
|
}
|
|
|
|
if (species?.forms?.find(f => f.formKey === "female")) {
|
|
if (female !== undefined) {
|
|
formIndex = female ? 1 : 0;
|
|
} else if (formIndex !== undefined) {
|
|
female = formIndex === 1;
|
|
}
|
|
}
|
|
|
|
if (species) {
|
|
// Only assign shiny, female, and variant if they are undefined
|
|
if (shiny === undefined) {
|
|
shiny = oldProps?.shiny ?? false;
|
|
}
|
|
if (female === undefined) {
|
|
female = oldProps?.female ?? false;
|
|
}
|
|
if (variant === undefined) {
|
|
variant = oldProps?.variant ?? 0;
|
|
}
|
|
if (formIndex === undefined) {
|
|
formIndex = oldProps?.form ?? 0;
|
|
}
|
|
}
|
|
|
|
this.pokemonSprite.setVisible(false);
|
|
|
|
if (this.assetLoadCancelled) {
|
|
this.assetLoadCancelled.value = true;
|
|
this.assetLoadCancelled = null;
|
|
}
|
|
|
|
if (species) {
|
|
const caughtAttr = this.isCaught(species);
|
|
|
|
if (!caughtAttr) {
|
|
const props = this.starterAttributes;
|
|
|
|
if (shiny === undefined || shiny !== props.shiny) {
|
|
shiny = props.shiny;
|
|
}
|
|
if (formIndex === undefined || formIndex !== props.form) {
|
|
formIndex = props.form;
|
|
}
|
|
if (female === undefined || female !== props.female) {
|
|
female = props.female;
|
|
}
|
|
if (variant === undefined || variant !== props.variant) {
|
|
variant = props.variant;
|
|
}
|
|
}
|
|
|
|
const isFormCaught = this.isFormCaught();
|
|
const isFormSeen = this.isSeen();
|
|
|
|
this.shinyOverlay.setVisible(shiny ?? false); // TODO: is false the correct default?
|
|
this.pokemonNumberText.setColor(this.getTextColor(shiny ? TextStyle.SUMMARY_GOLD : TextStyle.SUMMARY, false));
|
|
this.pokemonNumberText.setShadowColor(
|
|
this.getTextColor(shiny ? TextStyle.SUMMARY_GOLD : TextStyle.SUMMARY, true),
|
|
);
|
|
|
|
const assetLoadCancelled = new BooleanHolder(false);
|
|
this.assetLoadCancelled = assetLoadCancelled;
|
|
|
|
if (shouldUpdateSprite) {
|
|
const back = !!this.showBackSprite;
|
|
species.loadAssets(female!, formIndex, shiny, variant as Variant, true, back).then(() => {
|
|
// TODO: is this bang correct?
|
|
if (assetLoadCancelled.value) {
|
|
return;
|
|
}
|
|
this.assetLoadCancelled = null;
|
|
this.speciesLoaded.set(species.speciesId, true);
|
|
this.pokemonSprite.play(species.getSpriteKey(female!, formIndex, shiny, variant, back)); // TODO: is this bang correct?
|
|
this.pokemonSprite.setPipelineData("shiny", shiny);
|
|
this.pokemonSprite.setPipelineData("variant", variant);
|
|
this.pokemonSprite.setPipelineData(
|
|
"spriteKey",
|
|
species.getSpriteKey(female!, formIndex, shiny, variant, back),
|
|
); // TODO: is this bang correct?
|
|
this.pokemonSprite.setVisible(!this.statsMode);
|
|
});
|
|
} else {
|
|
this.pokemonSprite.setVisible(!this.statsMode);
|
|
}
|
|
|
|
const isNonShinyCaught = !!(caughtAttr & DexAttr.NON_SHINY);
|
|
const isShinyCaught = !!(caughtAttr & DexAttr.SHINY);
|
|
|
|
const caughtVariants = [DexAttr.DEFAULT_VARIANT, DexAttr.VARIANT_2, DexAttr.VARIANT_3].filter(
|
|
v => caughtAttr & v,
|
|
);
|
|
this.canCycleShiny = (isNonShinyCaught && isShinyCaught) || (isShinyCaught && caughtVariants.length > 1);
|
|
|
|
const isMaleCaught = !!(caughtAttr & DexAttr.MALE);
|
|
const isFemaleCaught = !!(caughtAttr & DexAttr.FEMALE);
|
|
this.canCycleGender = isMaleCaught && isFemaleCaught;
|
|
|
|
// If the dev option for the dex is selected, all forms can be cycled through
|
|
this.canCycleForm = globalScene.dexForDevs
|
|
? species.forms.length > 1
|
|
: species.forms.filter(f => f.isStarterSelectable).filter(f => f).length > 1;
|
|
|
|
if (caughtAttr && species.malePercent !== null) {
|
|
const gender = !female ? Gender.MALE : Gender.FEMALE;
|
|
this.pokemonGenderText.setText(getGenderSymbol(gender));
|
|
this.pokemonGenderText.setColor(getGenderColor(gender));
|
|
this.pokemonGenderText.setShadowColor(getGenderColor(gender, true));
|
|
} else {
|
|
this.pokemonGenderText.setText("");
|
|
}
|
|
|
|
// Setting the name
|
|
if (isFormCaught || isFormSeen) {
|
|
this.pokemonNameText.setText(species.name);
|
|
} else {
|
|
this.pokemonNameText.setText(species ? "???" : "");
|
|
}
|
|
|
|
// Setting tint of the sprite
|
|
if (isFormCaught) {
|
|
this.species.loadAssets(female!, formIndex, shiny, variant as Variant, true).then(() => {
|
|
const crier =
|
|
this.species.forms && this.species.forms.length > 0
|
|
? this.species.forms[formIndex ?? this.formIndex]
|
|
: this.species;
|
|
crier.cry();
|
|
});
|
|
this.pokemonSprite.clearTint();
|
|
} else if (isFormSeen) {
|
|
this.pokemonSprite.setTint(0x808080);
|
|
} else {
|
|
this.pokemonSprite.setTint(0);
|
|
}
|
|
|
|
// Setting luck text and sparks
|
|
if (isFormCaught) {
|
|
const luck = globalScene.gameData.getDexAttrLuck(this.isCaught());
|
|
this.pokemonLuckText.setVisible(!!luck);
|
|
this.pokemonLuckText.setText(luck.toString());
|
|
this.pokemonLuckText.setTint(getVariantTint(Math.min(luck - 1, 2) as Variant));
|
|
this.pokemonLuckLabelText.setVisible(this.pokemonLuckText.visible);
|
|
} else {
|
|
this.pokemonLuckText.setVisible(false);
|
|
this.pokemonLuckLabelText.setVisible(false);
|
|
}
|
|
|
|
// Setting growth rate text
|
|
if (isFormCaught) {
|
|
let growthReadable = toReadableString(GrowthRate[species.growthRate]);
|
|
const growthAux = growthReadable.replace(" ", "_");
|
|
if (i18next.exists("growth:" + growthAux)) {
|
|
growthReadable = i18next.t(("growth:" + growthAux) as any);
|
|
}
|
|
this.pokemonGrowthRateText.setText(growthReadable);
|
|
|
|
this.pokemonGrowthRateText.setColor(getGrowthRateColor(species.growthRate));
|
|
this.pokemonGrowthRateText.setShadowColor(getGrowthRateColor(species.growthRate, true));
|
|
this.pokemonGrowthRateLabelText.setVisible(true);
|
|
} else {
|
|
this.pokemonGrowthRateText.setText("");
|
|
this.pokemonGrowthRateLabelText.setVisible(false);
|
|
}
|
|
|
|
// Caught and hatched
|
|
if (isFormCaught) {
|
|
const colorScheme = starterColors[this.starterId];
|
|
|
|
this.pokemonUncaughtText.setVisible(false);
|
|
this.pokemonCaughtCountText.setText(`${this.speciesStarterDexEntry?.caughtCount}`);
|
|
if (species.speciesId === Species.MANAPHY || species.speciesId === Species.PHIONE) {
|
|
this.pokemonHatchedIcon.setFrame("manaphy");
|
|
} else {
|
|
this.pokemonHatchedIcon.setFrame(getEggTierForSpecies(species));
|
|
}
|
|
this.pokemonHatchedCountText.setText(`${this.speciesStarterDexEntry?.hatchedCount}`);
|
|
|
|
const defaultDexAttr = this.getCurrentDexProps(species.speciesId);
|
|
const defaultProps = globalScene.gameData.getSpeciesDexAttrProps(species, defaultDexAttr);
|
|
|
|
const variant = defaultProps.variant;
|
|
for (let v = 0; v < 3; v++) {
|
|
const icon = this.pokemonShinyIcons[v];
|
|
if (v < this.availableVariants) {
|
|
if (!this.unlockedVariants[v]) {
|
|
icon.setTint(0x000000);
|
|
} else if (shiny && v === variant) {
|
|
const tint = getVariantTint(v as Variant);
|
|
icon.setTint(tint);
|
|
} else {
|
|
icon.setTint(0x808080);
|
|
}
|
|
icon.setVisible(true);
|
|
} else {
|
|
icon.setVisible(false);
|
|
}
|
|
}
|
|
|
|
this.pokemonCaughtHatchedContainer.setVisible(true);
|
|
this.pokemonCaughtHatchedContainer.setY(25);
|
|
this.pokemonCandyIcon.setTint(argbFromRgba(rgbHexToRgba(colorScheme[0])));
|
|
this.pokemonCandyOverlayIcon.setTint(argbFromRgba(rgbHexToRgba(colorScheme[1])));
|
|
this.pokemonCandyCountText.setText(
|
|
`x${species.speciesId === Species.PIKACHU ? 0 : globalScene.gameData.starterData[this.starterId].candyCount}`,
|
|
);
|
|
this.pokemonCandyContainer.setVisible(true);
|
|
|
|
if (pokemonPrevolutions.hasOwnProperty(species.speciesId)) {
|
|
this.pokemonHatchedIcon.setVisible(false);
|
|
this.pokemonHatchedCountText.setVisible(false);
|
|
this.pokemonFormText.setY(36);
|
|
} else {
|
|
this.pokemonHatchedIcon.setVisible(true);
|
|
this.pokemonHatchedCountText.setVisible(true);
|
|
this.pokemonFormText.setY(42);
|
|
|
|
const { currentFriendship, friendshipCap } = this.getFriendship(this.species.speciesId);
|
|
const candyCropY = 16 - 16 * (currentFriendship / friendshipCap);
|
|
this.pokemonCandyDarknessOverlay.setCrop(0, 0, 16, candyCropY);
|
|
|
|
this.pokemonCandyContainer.on("pointerover", () => {
|
|
globalScene.ui.showTooltip("", `${currentFriendship}/${friendshipCap}`, true);
|
|
this.activeTooltip = "CANDY";
|
|
});
|
|
this.pokemonCandyContainer.on("pointerout", () => {
|
|
globalScene.ui.hideTooltip();
|
|
this.activeTooltip = undefined;
|
|
});
|
|
}
|
|
} else {
|
|
this.pokemonUncaughtText.setVisible(true);
|
|
this.pokemonCaughtHatchedContainer.setVisible(false);
|
|
this.pokemonCandyContainer.setVisible(false);
|
|
for (const icon of this.pokemonShinyIcons) {
|
|
icon.setVisible(false);
|
|
}
|
|
}
|
|
|
|
// Setting type icons and form text
|
|
if (isFormCaught || isFormSeen) {
|
|
const speciesForm = getPokemonSpeciesForm(species.speciesId, formIndex!); // TODO: is the bang correct?
|
|
this.setTypeIcons(speciesForm.type1, speciesForm.type2);
|
|
// TODO: change this once forms are refactored
|
|
if (normalForm.includes(species.speciesId) && !formIndex) {
|
|
this.pokemonFormText.setText("");
|
|
} else {
|
|
this.pokemonFormText.setText(species.getFormNameToDisplay(formIndex));
|
|
}
|
|
this.pokemonFormText.setVisible(true);
|
|
if (!isFormCaught) {
|
|
this.pokemonFormText.setY(18);
|
|
}
|
|
} else {
|
|
this.setTypeIcons(null, null);
|
|
this.pokemonFormText.setText("");
|
|
this.pokemonFormText.setVisible(false);
|
|
}
|
|
} else {
|
|
this.shinyOverlay.setVisible(false);
|
|
this.pokemonNumberText.setColor(this.getTextColor(TextStyle.SUMMARY));
|
|
this.pokemonNumberText.setShadowColor(this.getTextColor(TextStyle.SUMMARY, true));
|
|
this.pokemonGenderText.setText("");
|
|
this.setTypeIcons(null, null);
|
|
}
|
|
|
|
this.updateInstructions();
|
|
}
|
|
|
|
setTypeIcons(type1: PokemonType | null, type2: PokemonType | null): void {
|
|
if (type1 !== null) {
|
|
this.type1Icon.setVisible(true);
|
|
this.type1Icon.setFrame(PokemonType[type1].toLowerCase());
|
|
} else {
|
|
this.type1Icon.setVisible(false);
|
|
}
|
|
if (type2 !== null) {
|
|
this.type2Icon.setVisible(true);
|
|
this.type2Icon.setFrame(PokemonType[type2].toLowerCase());
|
|
} else {
|
|
this.type2Icon.setVisible(false);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Creates a temporary dex attr props that will be used to display the correct shiny, variant, and form based on this.starterAttributes
|
|
*
|
|
* @param speciesId the id of the species to get props for
|
|
* @returns the dex props
|
|
*/
|
|
getCurrentDexProps(speciesId: number): bigint {
|
|
let props = 0n;
|
|
const species = allSpecies.find(sp => sp.speciesId === speciesId);
|
|
const caughtAttr =
|
|
globalScene.gameData.dexData[speciesId].caughtAttr &
|
|
globalScene.gameData.dexData[this.getStarterSpeciesId(speciesId)].caughtAttr &
|
|
(species?.getFullUnlocksData() ?? 0n);
|
|
|
|
/* this checks the gender of the pokemon; this works by checking a) that the starter preferences for the species exist, and if so, is it female. If so, it'll add DexAttr.FEMALE to our temp props
|
|
* It then checks b) if the caughtAttr for the pokemon is female and NOT male - this means that the ONLY gender we've gotten is female, and we need to add DexAttr.FEMALE to our temp props
|
|
* If neither of these pass, we add DexAttr.MALE to our temp props
|
|
*/
|
|
if (this.starterAttributes?.female || ((caughtAttr & DexAttr.FEMALE) > 0n && (caughtAttr & DexAttr.MALE) === 0n)) {
|
|
props += DexAttr.FEMALE;
|
|
} else {
|
|
props += DexAttr.MALE;
|
|
}
|
|
/* This part is very similar to above, but instead of for gender, it checks for shiny within starter preferences.
|
|
* If they're not there, it enables shiny state by default if any shiny was caught
|
|
*/
|
|
if (
|
|
this.starterAttributes?.shiny ||
|
|
((caughtAttr & DexAttr.SHINY) > 0n && this.starterAttributes?.shiny !== false)
|
|
) {
|
|
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 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 {
|
|
props += DexAttr.NON_SHINY;
|
|
props += DexAttr.DEFAULT_VARIANT; // we add the default variant here because non shiny versions are listed as default variant
|
|
}
|
|
if (this.starterAttributes?.form) {
|
|
// this checks for the form of the pokemon
|
|
props += BigInt(Math.pow(2, this.starterAttributes?.form)) * DexAttr.DEFAULT_FORM;
|
|
} else {
|
|
// Get the first unlocked form
|
|
props += globalScene.gameData.getFormAttr(globalScene.gameData.getFormIndex(caughtAttr));
|
|
}
|
|
|
|
return props;
|
|
}
|
|
|
|
toggleStatsMode(on?: boolean): void {
|
|
if (on === undefined) {
|
|
on = !this.statsMode;
|
|
}
|
|
if (on) {
|
|
this.showStats();
|
|
this.statsMode = true;
|
|
this.pokemonSprite.setVisible(false);
|
|
} else {
|
|
this.statsMode = false;
|
|
this.statsContainer.setVisible(false);
|
|
this.pokemonSprite.setVisible(true);
|
|
//@ts-ignore
|
|
this.statsContainer.updateIvs(null); // TODO: resolve ts-ignore. !?!?
|
|
}
|
|
}
|
|
|
|
showStats(): void {
|
|
if (!this.speciesStarterDexEntry) {
|
|
return;
|
|
}
|
|
|
|
this.statsContainer.setVisible(true);
|
|
|
|
this.statsContainer.updateIvs(this.speciesStarterDexEntry.ivs);
|
|
}
|
|
|
|
clearText() {
|
|
this.starterSelectMessageBoxContainer.setVisible(false);
|
|
super.clearText();
|
|
}
|
|
|
|
hideInstructions(): void {
|
|
this.candyUpgradeIconElement.setVisible(false);
|
|
this.candyUpgradeLabel.setVisible(false);
|
|
this.shinyIconElement.setVisible(false);
|
|
this.shinyLabel.setVisible(false);
|
|
this.formIconElement.setVisible(false);
|
|
this.formLabel.setVisible(false);
|
|
this.genderIconElement.setVisible(false);
|
|
this.genderLabel.setVisible(false);
|
|
this.variantIconElement.setVisible(false);
|
|
this.variantLabel.setVisible(false);
|
|
}
|
|
|
|
clear(): void {
|
|
super.clear();
|
|
|
|
this.cursor = -1;
|
|
this.hideInstructions();
|
|
this.activeTooltip = undefined;
|
|
globalScene.ui.hideTooltip();
|
|
|
|
this.starterSelectContainer.setVisible(false);
|
|
this.blockInput = false;
|
|
|
|
this.showBackSprite = false;
|
|
this.showBackSpriteLabel.setText(i18next.t("pokedexUiHandler:showBackSprite"));
|
|
|
|
if (this.statsMode) {
|
|
this.toggleStatsMode(false);
|
|
}
|
|
}
|
|
|
|
checkIconId(
|
|
icon: Phaser.GameObjects.Sprite,
|
|
species: PokemonSpecies,
|
|
female: boolean,
|
|
formIndex: number,
|
|
shiny: boolean,
|
|
variant: number,
|
|
) {
|
|
if (icon.frame.name !== species.getIconId(female, formIndex, shiny, variant)) {
|
|
console.log(
|
|
`${species.name}'s icon ${icon.frame.name} does not match getIconId with female: ${female}, formIndex: ${formIndex}, shiny: ${shiny}, variant: ${variant}`,
|
|
);
|
|
icon.setTexture(species.getIconAtlasKey(formIndex, false, variant));
|
|
icon.setFrame(species.getIconId(female, formIndex, false, variant));
|
|
}
|
|
}
|
|
}
|