mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-09-23 15:03:24 +02:00
Merge 10a69a2387
into cffbafe4bd
This commit is contained in:
commit
aad5b89a90
@ -91,11 +91,11 @@ export interface StarterMoveData {
|
||||
[key: number]: StarterMoveset | StarterFormMoveData;
|
||||
}
|
||||
|
||||
export interface StarterAttributes {
|
||||
export interface StarterPreferences {
|
||||
nature?: number;
|
||||
ability?: number;
|
||||
abilityIndex?: number;
|
||||
variant?: number;
|
||||
form?: number;
|
||||
formIndex?: number;
|
||||
female?: boolean;
|
||||
shiny?: boolean;
|
||||
favorite?: boolean;
|
||||
|
@ -107,3 +107,8 @@ export const FAKE_TITLE_LOGO_CHANCE = 10000;
|
||||
* Using rare candies will never increase friendship beyond this value.
|
||||
*/
|
||||
export const RARE_CANDY_FRIENDSHIP_CAP = 200;
|
||||
|
||||
/**
|
||||
* The maximum number of cost reduction upgrades that can be bought with candy.
|
||||
*/
|
||||
export const VALUE_REDUCTION_MAX = 2;
|
||||
|
@ -1991,6 +1991,29 @@ export class GameData {
|
||||
return ret;
|
||||
}
|
||||
|
||||
getSpeciesDefaultDexAttrProps(species: PokemonSpecies): DexAttrProps {
|
||||
const dexAttr = this.dexData[species.speciesId].caughtAttr;
|
||||
// Default shiny is true if caught
|
||||
const shiny = !!(dexAttr & DexAttr.SHINY);
|
||||
// Default is female only for species where malePercent is not null but 0
|
||||
const female = species.malePercent === 0;
|
||||
// Default is the highest variant
|
||||
let variant: Variant = 0;
|
||||
if (dexAttr & DexAttr.VARIANT_3) {
|
||||
variant = 2;
|
||||
} else if (dexAttr & DexAttr.VARIANT_2) {
|
||||
variant = 1;
|
||||
}
|
||||
const formIndex = 0;
|
||||
|
||||
return {
|
||||
shiny,
|
||||
female,
|
||||
variant,
|
||||
formIndex,
|
||||
};
|
||||
}
|
||||
|
||||
getSpeciesDexAttrProps(_species: PokemonSpecies, dexAttr: bigint): DexAttrProps {
|
||||
const shiny = !(dexAttr & DexAttr.NON_SHINY);
|
||||
const female = !(dexAttr & DexAttr.MALE);
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { globalScene } from "#app/global-scene";
|
||||
import type { PokemonSpecies } from "#data/pokemon-species";
|
||||
import { TextStyle } from "#enums/text-style";
|
||||
import type { DexAttrProps } from "#types/save-data";
|
||||
import { addTextObject } from "#ui/text";
|
||||
|
||||
export class StarterContainer extends Phaser.GameObjects.Container {
|
||||
@ -19,10 +20,9 @@ export class StarterContainer extends Phaser.GameObjects.Container {
|
||||
constructor(species: PokemonSpecies) {
|
||||
super(globalScene, 0, 0);
|
||||
|
||||
this.species = species;
|
||||
|
||||
const defaultDexAttr = globalScene.gameData.getSpeciesDefaultDexAttr(species, false, true);
|
||||
const defaultProps = globalScene.gameData.getSpeciesDexAttrProps(species, defaultDexAttr);
|
||||
this.setSpecies(species, defaultProps);
|
||||
|
||||
// starter passive bg
|
||||
const starterPassiveBg = globalScene.add.image(2, 5, "passive_bg");
|
||||
@ -32,21 +32,6 @@ export class StarterContainer extends Phaser.GameObjects.Container {
|
||||
this.add(starterPassiveBg);
|
||||
this.starterPassiveBgs = starterPassiveBg;
|
||||
|
||||
// icon
|
||||
this.icon = globalScene.add.sprite(
|
||||
-2,
|
||||
2,
|
||||
species.getIconAtlasKey(defaultProps.formIndex, defaultProps.shiny, defaultProps.variant),
|
||||
);
|
||||
this.icon.setScale(0.5);
|
||||
this.icon.setOrigin(0, 0);
|
||||
this.icon.setFrame(
|
||||
species.getIconId(defaultProps.female, defaultProps.formIndex, defaultProps.shiny, defaultProps.variant),
|
||||
);
|
||||
this.checkIconId(defaultProps.female, defaultProps.formIndex, defaultProps.shiny, defaultProps.variant);
|
||||
this.icon.setTint(0);
|
||||
this.add(this.icon);
|
||||
|
||||
// shiny icons
|
||||
for (let i = 0; i < 3; i++) {
|
||||
const shinyIcon = globalScene.add.image(i * -3 + 12, 2, "shiny_star_small");
|
||||
@ -108,6 +93,39 @@ export class StarterContainer extends Phaser.GameObjects.Container {
|
||||
this.candyUpgradeOverlayIcon = candyUpgradeOverlayIcon;
|
||||
}
|
||||
|
||||
setSpecies(species: PokemonSpecies, props: DexAttrProps) {
|
||||
this.species = species;
|
||||
|
||||
const { shiny, formIndex, female, variant } = props;
|
||||
|
||||
if (this.icon) {
|
||||
this.remove(this.icon);
|
||||
this.icon.destroy(); // Properly removes the sprite from memory
|
||||
}
|
||||
|
||||
// icon
|
||||
this.icon = globalScene.add.sprite(-2, 2, species.getIconAtlasKey(formIndex, shiny, variant));
|
||||
this.icon.setScale(0.5);
|
||||
this.icon.setOrigin(0, 0);
|
||||
this.icon.setFrame(species.getIconId(female, formIndex, shiny, variant));
|
||||
this.checkIconId(female, formIndex, shiny, variant);
|
||||
this.icon.setTint(0);
|
||||
this.add(this.icon);
|
||||
this.icon.setBelow(this.label);
|
||||
|
||||
[
|
||||
this.hiddenAbilityIcon,
|
||||
this.favoriteIcon,
|
||||
this.classicWinIcon,
|
||||
this.candyUpgradeIcon,
|
||||
this.candyUpgradeOverlayIcon,
|
||||
].forEach(icon => {
|
||||
if (icon) {
|
||||
this.bringToTop(icon);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
checkIconId(female, formIndex, shiny, variant) {
|
||||
if (this.icon.frame.name !== this.species.getIconId(female, formIndex, shiny, variant)) {
|
||||
console.log(`${this.species.name}'s variant icon does not exist. Replacing with default.`);
|
||||
|
866
src/ui/containers/starter-summary.ts
Normal file
866
src/ui/containers/starter-summary.ts
Normal file
@ -0,0 +1,866 @@
|
||||
import { globalScene } from "#app/global-scene";
|
||||
import { starterColors } from "#app/global-vars/starter-colors";
|
||||
import { speciesEggMoves } from "#balance/egg-moves";
|
||||
import { pokemonPrevolutions } from "#balance/pokemon-evolutions";
|
||||
import { allAbilities, allMoves } from "#data/data-lists";
|
||||
import { getEggTierForSpecies } from "#data/egg";
|
||||
import { GrowthRate, getGrowthRateColor } from "#data/exp";
|
||||
import { Gender, getGenderColor, getGenderSymbol } from "#data/gender";
|
||||
import { getNatureName } from "#data/nature";
|
||||
import type { PokemonSpecies } from "#data/pokemon-species";
|
||||
import { Challenges } from "#enums/challenges";
|
||||
import type { Nature } from "#enums/nature";
|
||||
import { Passive } from "#enums/passive";
|
||||
import { PokemonType } from "#enums/pokemon-type";
|
||||
import { SpeciesId } from "#enums/species-id";
|
||||
import { TextStyle } from "#enums/text-style";
|
||||
import { getVariantIcon, getVariantTint, type Variant } from "#sprites/variant";
|
||||
import { achvs } from "#system/achv";
|
||||
import type { Ability } from "#types/ability-types";
|
||||
import type { StarterMoveset, StarterPreferences } from "#types/save-data";
|
||||
import { BooleanHolder, getLocalizedSpriteKey, padInt, rgbHexToRgba } from "#utils/common";
|
||||
import { getPokemonSpecies, getPokemonSpeciesForm } from "#utils/pokemon-utils";
|
||||
import { toCamelCase, toTitleCase } from "#utils/strings";
|
||||
import { argbFromRgba } from "@material/material-color-utilities";
|
||||
import i18next from "i18next";
|
||||
import type { GameObjects } from "phaser";
|
||||
import type BBCodeText from "phaser3-rex-plugins/plugins/bbcodetext";
|
||||
import { addBBCodeTextObject, addTextObject, getTextColor } from "../text";
|
||||
import {
|
||||
getDexAttrFromPreferences,
|
||||
getFriendship,
|
||||
getSpeciesData,
|
||||
getStarterSelectTextSettings,
|
||||
type SpeciesDetails,
|
||||
} from "../utils/starter-select-ui-utils";
|
||||
import { StatsContainer } from "./stats-container";
|
||||
|
||||
export class StarterSummary extends Phaser.GameObjects.Container {
|
||||
private pokemonSprite: Phaser.GameObjects.Sprite;
|
||||
private pokemonNumberText: Phaser.GameObjects.Text;
|
||||
private shinyOverlay: Phaser.GameObjects.Image;
|
||||
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 pokemonAbilityLabelText: Phaser.GameObjects.Text;
|
||||
private pokemonAbilityText: Phaser.GameObjects.Text;
|
||||
private pokemonPassiveLabelText: Phaser.GameObjects.Text;
|
||||
private pokemonPassiveText: Phaser.GameObjects.Text;
|
||||
private pokemonNatureLabelText: Phaser.GameObjects.Text;
|
||||
private pokemonNatureText: BBCodeText;
|
||||
private pokemonMovesContainer: Phaser.GameObjects.Container;
|
||||
private pokemonMoveContainers: Phaser.GameObjects.Container[];
|
||||
private pokemonMoveBgs: Phaser.GameObjects.NineSlice[];
|
||||
private pokemonMoveLabels: Phaser.GameObjects.Text[];
|
||||
private pokemonAdditionalMoveCountLabel: Phaser.GameObjects.Text;
|
||||
private eggMovesLabel: Phaser.GameObjects.Text;
|
||||
private pokemonEggMovesContainer: Phaser.GameObjects.Container;
|
||||
private pokemonEggMoveContainers: Phaser.GameObjects.Container[];
|
||||
private pokemonEggMoveBgs: Phaser.GameObjects.NineSlice[];
|
||||
private pokemonEggMoveLabels: 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 pokemonShinyIcon: Phaser.GameObjects.Sprite;
|
||||
private pokemonPassiveDisabledIcon: Phaser.GameObjects.Sprite;
|
||||
private pokemonPassiveLockedIcon: Phaser.GameObjects.Sprite;
|
||||
private teraIcon: Phaser.GameObjects.Sprite;
|
||||
|
||||
// Whether the tera type icon should be displayed
|
||||
private allowTera: boolean;
|
||||
|
||||
// Container for ivs, whether they should be shown
|
||||
private statsContainer: StatsContainer;
|
||||
private statsMode = false;
|
||||
|
||||
private assetLoadCancelled: BooleanHolder | null;
|
||||
|
||||
// Which of the tooltips is displayed (on mouse hover)
|
||||
private activeTooltip: "ABILITY" | "PASSIVE" | "CANDY" | undefined;
|
||||
|
||||
// Container for type, growth rate, luck
|
||||
private pokemonPermanentInfoContainer: GameObjects.Container;
|
||||
// Container for numbers of caught pokémon, eggs
|
||||
private pokemonStatisticsContainer: GameObjects.Container;
|
||||
// Container for everything that's a preference (abilities, nature, form...)
|
||||
private pokemonPreferencesContainer: GameObjects.Container;
|
||||
|
||||
private speciesId: SpeciesId;
|
||||
|
||||
constructor(x: number, y: number) {
|
||||
super(globalScene, x, y);
|
||||
|
||||
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.shinyOverlay = globalScene.add
|
||||
.image(6, 111, getLocalizedSpriteKey("summary_dexnb_label_overlay_shiny"))
|
||||
.setOrigin(0, 1)
|
||||
.setVisible(false); // Pixel text 'No' shiny
|
||||
|
||||
this.pokemonNumberText = addTextObject(17, 1, "0000", TextStyle.SUMMARY_DEX_NUM).setOrigin(0);
|
||||
|
||||
this.pokemonNameText = addTextObject(6, 112, "", TextStyle.SUMMARY).setOrigin(0);
|
||||
|
||||
this.pokemonUncaughtText = addTextObject(
|
||||
6,
|
||||
127,
|
||||
i18next.t("starterSelectUiHandler:uncaught"),
|
||||
TextStyle.SUMMARY_ALT,
|
||||
{ fontSize: "56px" },
|
||||
).setOrigin(0);
|
||||
|
||||
this.pokemonMoveContainers = [];
|
||||
this.pokemonMoveBgs = [];
|
||||
this.pokemonMoveLabels = [];
|
||||
|
||||
this.pokemonEggMoveContainers = [];
|
||||
this.pokemonEggMoveBgs = [];
|
||||
this.pokemonEggMoveLabels = [];
|
||||
|
||||
this.pokemonPreferencesContainer = this.setupPokemonPreferencesContainer();
|
||||
this.pokemonPermanentInfoContainer = this.setupPokemonPermanentInfoContainer();
|
||||
this.pokemonStatisticsContainer = this.setupPokemonStatisticsContainer();
|
||||
|
||||
for (let m = 0; m < 4; m++) {
|
||||
const moveContainer = globalScene.add.container(0, 14 * m);
|
||||
|
||||
const moveBg = globalScene.add.nineslice(0, 0, "type_bgs", "unknown", 92, 14, 2, 2, 2, 2);
|
||||
moveBg.setOrigin(1, 0);
|
||||
|
||||
const moveLabel = addTextObject(-moveBg.width / 2, 0, "-", TextStyle.MOVE_LABEL);
|
||||
moveLabel.setOrigin(0.5, 0);
|
||||
|
||||
this.pokemonMoveBgs.push(moveBg);
|
||||
this.pokemonMoveLabels.push(moveLabel);
|
||||
|
||||
moveContainer.add([moveBg, moveLabel]);
|
||||
|
||||
this.pokemonMoveContainers.push(moveContainer);
|
||||
this.pokemonMovesContainer.add(moveContainer);
|
||||
}
|
||||
|
||||
this.pokemonAdditionalMoveCountLabel = addTextObject(
|
||||
-this.pokemonMoveBgs[0].width / 2,
|
||||
56,
|
||||
"(+0)",
|
||||
TextStyle.MOVE_LABEL,
|
||||
).setOrigin(0.5, 0);
|
||||
|
||||
this.pokemonMovesContainer.add(this.pokemonAdditionalMoveCountLabel);
|
||||
|
||||
this.pokemonEggMovesContainer = globalScene.add.container(102, 85).setScale(0.375);
|
||||
|
||||
this.eggMovesLabel = addTextObject(
|
||||
-46,
|
||||
0,
|
||||
i18next.t("starterSelectUiHandler:eggMoves"),
|
||||
TextStyle.WINDOW_ALT,
|
||||
).setOrigin(0.5, 0);
|
||||
|
||||
this.pokemonEggMovesContainer.add(this.eggMovesLabel);
|
||||
|
||||
for (let m = 0; m < 4; m++) {
|
||||
const eggMoveContainer = globalScene.add.container(0, 16 + 14 * m);
|
||||
|
||||
const eggMoveBg = globalScene.add.nineslice(0, 0, "type_bgs", "unknown", 92, 14, 2, 2, 2, 2);
|
||||
eggMoveBg.setOrigin(1, 0);
|
||||
|
||||
const eggMoveLabel = addTextObject(-eggMoveBg.width / 2, 0, "???", TextStyle.MOVE_LABEL);
|
||||
eggMoveLabel.setOrigin(0.5, 0);
|
||||
|
||||
this.pokemonEggMoveBgs.push(eggMoveBg);
|
||||
this.pokemonEggMoveLabels.push(eggMoveLabel);
|
||||
|
||||
eggMoveContainer.add([eggMoveBg, eggMoveLabel]);
|
||||
|
||||
this.pokemonEggMoveContainers.push(eggMoveContainer);
|
||||
|
||||
this.pokemonEggMovesContainer.add(eggMoveContainer);
|
||||
}
|
||||
|
||||
this.statsContainer = new StatsContainer(6, 16).setVisible(false);
|
||||
|
||||
globalScene.add.existing(this.statsContainer);
|
||||
|
||||
this.add([
|
||||
this.pokemonSprite,
|
||||
this.shinyOverlay,
|
||||
this.pokemonNumberText,
|
||||
this.pokemonNameText,
|
||||
this.pokemonUncaughtText,
|
||||
this.pokemonPreferencesContainer,
|
||||
this.pokemonPermanentInfoContainer,
|
||||
this.pokemonStatisticsContainer,
|
||||
this.pokemonMovesContainer,
|
||||
this.pokemonEggMovesContainer,
|
||||
this.statsContainer,
|
||||
]);
|
||||
|
||||
this.allowTera = globalScene.gameData.achvUnlocks.hasOwnProperty(achvs.TERASTALLIZE.id);
|
||||
}
|
||||
|
||||
setupPokemonPreferencesContainer(): GameObjects.Container {
|
||||
const pokemonPreferencesContainer = globalScene.add.container(0, 0);
|
||||
|
||||
const textSettings = getStarterSelectTextSettings();
|
||||
|
||||
// The position should be set per language
|
||||
const starterInfoXPos = textSettings?.starterInfoXPos || 31;
|
||||
const starterInfoYOffset = textSettings?.starterInfoYOffset || 0;
|
||||
|
||||
// The font size should be set per language
|
||||
const starterInfoTextSize = textSettings?.starterInfoTextSize || 56;
|
||||
|
||||
this.pokemonGenderText = addTextObject(96, 112, "", TextStyle.SUMMARY_ALT).setOrigin(0);
|
||||
|
||||
this.pokemonFormText = addTextObject(6, 42, "Form", TextStyle.WINDOW_ALT, {
|
||||
fontSize: "42px",
|
||||
}).setOrigin(0);
|
||||
|
||||
this.pokemonAbilityLabelText = addTextObject(
|
||||
6,
|
||||
127 + starterInfoYOffset,
|
||||
i18next.t("starterSelectUiHandler:ability"),
|
||||
TextStyle.SUMMARY_ALT,
|
||||
{ fontSize: starterInfoTextSize },
|
||||
).setOrigin(0);
|
||||
|
||||
this.pokemonAbilityText = addTextObject(starterInfoXPos, 127 + starterInfoYOffset, "", TextStyle.SUMMARY_ALT, {
|
||||
fontSize: starterInfoTextSize,
|
||||
})
|
||||
.setOrigin(0)
|
||||
.setInteractive(new Phaser.Geom.Rectangle(0, 0, 250, 55), Phaser.Geom.Rectangle.Contains);
|
||||
|
||||
this.pokemonPassiveLabelText = addTextObject(
|
||||
6,
|
||||
136 + starterInfoYOffset,
|
||||
i18next.t("starterSelectUiHandler:passive"),
|
||||
TextStyle.SUMMARY_ALT,
|
||||
{ fontSize: starterInfoTextSize },
|
||||
).setOrigin(0);
|
||||
|
||||
this.pokemonPassiveText = addTextObject(starterInfoXPos, 136 + starterInfoYOffset, "", TextStyle.SUMMARY_ALT, {
|
||||
fontSize: starterInfoTextSize,
|
||||
})
|
||||
.setOrigin(0)
|
||||
.setInteractive(new Phaser.Geom.Rectangle(0, 0, 250, 55), Phaser.Geom.Rectangle.Contains);
|
||||
|
||||
this.pokemonPassiveDisabledIcon = globalScene.add
|
||||
.sprite(starterInfoXPos, 137 + starterInfoYOffset, "icon_stop")
|
||||
.setOrigin(0, 0.5)
|
||||
.setScale(0.35)
|
||||
.setVisible(false);
|
||||
|
||||
this.pokemonPassiveLockedIcon = globalScene.add
|
||||
.sprite(starterInfoXPos, 137 + starterInfoYOffset, "icon_lock")
|
||||
.setOrigin(0, 0.5)
|
||||
.setScale(0.42, 0.38)
|
||||
.setVisible(false);
|
||||
|
||||
this.pokemonNatureLabelText = addTextObject(
|
||||
6,
|
||||
145 + starterInfoYOffset,
|
||||
i18next.t("starterSelectUiHandler:nature"),
|
||||
TextStyle.SUMMARY_ALT,
|
||||
{ fontSize: starterInfoTextSize },
|
||||
).setOrigin(0);
|
||||
|
||||
this.pokemonNatureText = addBBCodeTextObject(starterInfoXPos, 145 + starterInfoYOffset, "", TextStyle.SUMMARY_ALT, {
|
||||
fontSize: starterInfoTextSize,
|
||||
}).setOrigin(0);
|
||||
|
||||
this.pokemonShinyIcon = globalScene.add.sprite(12, 0, "shiny_icons").setScale(0.5);
|
||||
|
||||
this.teraIcon = globalScene.add.sprite(85, 63, "button_tera").setName("terastallize-icon").setFrame("fire");
|
||||
|
||||
pokemonPreferencesContainer.add([
|
||||
this.pokemonGenderText,
|
||||
this.pokemonFormText,
|
||||
this.pokemonAbilityLabelText,
|
||||
this.pokemonAbilityText,
|
||||
this.pokemonPassiveLabelText,
|
||||
this.pokemonPassiveText,
|
||||
this.pokemonPassiveDisabledIcon,
|
||||
this.pokemonPassiveLockedIcon,
|
||||
this.pokemonNatureLabelText,
|
||||
this.pokemonNatureText,
|
||||
this.pokemonShinyIcon,
|
||||
this.teraIcon,
|
||||
]);
|
||||
|
||||
return pokemonPreferencesContainer;
|
||||
}
|
||||
|
||||
setupPokemonPermanentInfoContainer(): GameObjects.Container {
|
||||
const pokemonPermanentInfoContainer = globalScene.add.container(0, 0);
|
||||
|
||||
this.type1Icon = globalScene.add.sprite(8, 98, getLocalizedSpriteKey("types")).setScale(0.5).setOrigin(0);
|
||||
this.type2Icon = globalScene.add.sprite(26, 98, getLocalizedSpriteKey("types")).setScale(0.5).setOrigin(0);
|
||||
|
||||
this.pokemonGrowthRateLabelText = addTextObject(
|
||||
8,
|
||||
106,
|
||||
i18next.t("starterSelectUiHandler:growthRate"),
|
||||
TextStyle.SUMMARY_ALT,
|
||||
{ fontSize: "36px" },
|
||||
).setOrigin(0);
|
||||
|
||||
this.pokemonGrowthRateText = addTextObject(34, 106, "", TextStyle.GROWTH_RATE_TYPE, { fontSize: "36px" }).setOrigin(
|
||||
0,
|
||||
);
|
||||
|
||||
this.pokemonLuckLabelText = addTextObject(8, 89, i18next.t("common:luckIndicator"), TextStyle.WINDOW_ALT, {
|
||||
fontSize: "56px",
|
||||
}).setOrigin(0);
|
||||
|
||||
this.pokemonLuckText = addTextObject(
|
||||
8 + this.pokemonLuckLabelText.displayWidth + 2,
|
||||
89,
|
||||
"0",
|
||||
TextStyle.LUCK_VALUE,
|
||||
{ fontSize: "56px" },
|
||||
).setOrigin(0);
|
||||
|
||||
pokemonPermanentInfoContainer.add([
|
||||
this.type1Icon,
|
||||
this.type2Icon,
|
||||
this.pokemonGrowthRateLabelText,
|
||||
this.pokemonGrowthRateText,
|
||||
this.pokemonLuckLabelText,
|
||||
this.pokemonLuckText,
|
||||
]);
|
||||
|
||||
return pokemonPermanentInfoContainer;
|
||||
}
|
||||
|
||||
setupPokemonStatisticsContainer(): GameObjects.Container {
|
||||
const pokemonStatisticsContainer = globalScene.add.container(0, 0);
|
||||
|
||||
// Candy icon and count
|
||||
this.pokemonCandyContainer = globalScene.add
|
||||
.container(4.5, 18)
|
||||
.setInteractive(new Phaser.Geom.Rectangle(0, 0, 30, 20), Phaser.Geom.Rectangle.Contains);
|
||||
this.pokemonCandyIcon = globalScene.add.sprite(0, 0, "candy").setScale(0.5).setOrigin(0);
|
||||
this.pokemonCandyOverlayIcon = globalScene.add.sprite(0, 0, "candy_overlay").setScale(0.5).setOrigin(0);
|
||||
this.pokemonCandyDarknessOverlay = globalScene.add
|
||||
.sprite(0, 0, "candy")
|
||||
.setScale(0.5)
|
||||
.setOrigin(0)
|
||||
.setTint(0x000000)
|
||||
.setAlpha(0.5);
|
||||
|
||||
this.pokemonCandyCountText = addTextObject(9.5, 0, "x0", TextStyle.WINDOW_ALT, { fontSize: "56px" }).setOrigin(0);
|
||||
this.pokemonCandyContainer.add([
|
||||
this.pokemonCandyIcon,
|
||||
this.pokemonCandyOverlayIcon,
|
||||
this.pokemonCandyDarknessOverlay,
|
||||
this.pokemonCandyCountText,
|
||||
]);
|
||||
|
||||
this.pokemonCaughtHatchedContainer = globalScene.add.container(2, 25).setScale(0.5);
|
||||
|
||||
const pokemonCaughtIcon = globalScene.add.sprite(1, 0, "items", "pb").setOrigin(0).setScale(0.75);
|
||||
|
||||
this.pokemonCaughtCountText = addTextObject(24, 4, "0", TextStyle.SUMMARY_ALT).setOrigin(0);
|
||||
this.pokemonHatchedIcon = globalScene.add.sprite(1, 14, "egg_icons").setOrigin(0.15, 0.2).setScale(0.8);
|
||||
this.pokemonHatchedCountText = addTextObject(24, 19, "0", TextStyle.SUMMARY_ALT).setOrigin(0);
|
||||
this.pokemonMovesContainer = globalScene.add.container(102, 16).setScale(0.375);
|
||||
this.pokemonCaughtHatchedContainer.add([
|
||||
pokemonCaughtIcon,
|
||||
this.pokemonCaughtCountText,
|
||||
this.pokemonHatchedIcon,
|
||||
this.pokemonHatchedCountText,
|
||||
]);
|
||||
|
||||
pokemonStatisticsContainer.add([this.pokemonCandyContainer, this.pokemonCaughtHatchedContainer]);
|
||||
|
||||
return pokemonStatisticsContainer;
|
||||
}
|
||||
|
||||
applyChallengeVisibility() {
|
||||
const notFreshStart = !globalScene.gameMode.hasChallenge(Challenges.FRESH_START);
|
||||
|
||||
for (const container of this.pokemonEggMoveContainers) {
|
||||
container.setVisible(notFreshStart);
|
||||
}
|
||||
this.eggMovesLabel.setVisible(notFreshStart);
|
||||
// This is not enough, we need individual checks in setStarterSpecies too! :)
|
||||
this.pokemonPassiveDisabledIcon.setVisible(notFreshStart);
|
||||
this.pokemonPassiveLabelText.setVisible(notFreshStart);
|
||||
this.pokemonPassiveLockedIcon.setVisible(notFreshStart);
|
||||
this.pokemonPassiveText.setVisible(notFreshStart);
|
||||
}
|
||||
|
||||
updateName(name: string) {
|
||||
this.pokemonNameText.setText(name);
|
||||
}
|
||||
|
||||
updateCandyCount(count: number) {
|
||||
this.pokemonCandyCountText.setText(`×${count}`);
|
||||
}
|
||||
|
||||
setNameAndNumber(species: PokemonSpecies, starterPreferences: StarterPreferences) {
|
||||
this.pokemonNumberText.setText(padInt(species.speciesId, 4));
|
||||
|
||||
if (starterPreferences?.nickname) {
|
||||
const name = decodeURIComponent(escape(atob(starterPreferences.nickname)));
|
||||
this.pokemonNameText.setText(name);
|
||||
} else {
|
||||
this.pokemonNameText.setText(species.name);
|
||||
}
|
||||
}
|
||||
|
||||
setTypeIcons(type1: PokemonType | null, type2: PokemonType | null): void {
|
||||
if (type1 !== null) {
|
||||
this.type1Icon.setVisible(true).setFrame(PokemonType[type1].toLowerCase());
|
||||
} else {
|
||||
this.type1Icon.setVisible(false);
|
||||
}
|
||||
if (type2 !== null) {
|
||||
this.type2Icon.setVisible(true).setFrame(PokemonType[type2].toLowerCase());
|
||||
} else {
|
||||
this.type2Icon.setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
setShinyIcon(shiny = true, variant: Variant = 0) {
|
||||
const tint = getVariantTint(variant);
|
||||
this.pokemonShinyIcon.setFrame(getVariantIcon(variant)).setTint(tint).setVisible(shiny);
|
||||
}
|
||||
|
||||
setNoSpecies() {
|
||||
if (globalScene.ui.getTooltip().visible) {
|
||||
globalScene.ui.hideTooltip();
|
||||
}
|
||||
|
||||
this.pokemonAbilityText.off("pointerover");
|
||||
this.pokemonPassiveText.off("pointerover");
|
||||
|
||||
if (this.statsMode) {
|
||||
this.statsContainer.setVisible(false);
|
||||
}
|
||||
|
||||
this.cleanStarterSprite();
|
||||
}
|
||||
|
||||
setSpecies(species: PokemonSpecies, starterPreferences: StarterPreferences) {
|
||||
this.speciesId = species.speciesId;
|
||||
|
||||
// First, we load from the dex entry to get defaults
|
||||
const { dexEntry } = getSpeciesData(species.speciesId);
|
||||
|
||||
this.pokemonAbilityText.off("pointerover");
|
||||
this.pokemonPassiveText.off("pointerover");
|
||||
|
||||
// Hiding ivs container if the species is not caught
|
||||
if (this.statsMode) {
|
||||
if (dexEntry?.caughtAttr) {
|
||||
this.statsContainer.setVisible(true);
|
||||
this.showStats();
|
||||
} else {
|
||||
this.statsContainer.setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (dexEntry.caughtAttr) {
|
||||
this.setNameAndNumber(species, starterPreferences);
|
||||
|
||||
const colorScheme = starterColors[species.speciesId];
|
||||
|
||||
this.pokemonUncaughtText.setVisible(false);
|
||||
this.pokemonPermanentInfoContainer.setVisible(true);
|
||||
this.pokemonStatisticsContainer.setVisible(true);
|
||||
|
||||
const luck = globalScene.gameData.getDexAttrLuck(dexEntry.caughtAttr);
|
||||
this.pokemonLuckText
|
||||
.setVisible(!!luck)
|
||||
.setText(luck.toString())
|
||||
.setTint(getVariantTint(Math.min(luck - 1, 2) as Variant));
|
||||
this.pokemonLuckLabelText.setVisible(this.pokemonLuckText.visible);
|
||||
|
||||
//Growth translate
|
||||
let growthReadable = toTitleCase(GrowthRate[species.growthRate]);
|
||||
const growthAux = toCamelCase(growthReadable);
|
||||
if (i18next.exists("growth:" + growthAux)) {
|
||||
growthReadable = i18next.t(("growth:" + growthAux) as any);
|
||||
}
|
||||
this.pokemonGrowthRateText
|
||||
.setText(growthReadable)
|
||||
.setColor(getGrowthRateColor(species.growthRate))
|
||||
.setShadowColor(getGrowthRateColor(species.growthRate, true));
|
||||
this.pokemonCaughtCountText.setText(`${dexEntry.caughtCount}`);
|
||||
if (species.speciesId === SpeciesId.MANAPHY || species.speciesId === SpeciesId.PHIONE) {
|
||||
this.pokemonHatchedIcon.setFrame("manaphy");
|
||||
} else {
|
||||
this.pokemonHatchedIcon.setFrame(getEggTierForSpecies(species));
|
||||
}
|
||||
this.pokemonHatchedCountText.setText(`${dexEntry.hatchedCount}`);
|
||||
|
||||
const defaultDexAttr = getDexAttrFromPreferences(species.speciesId, starterPreferences);
|
||||
|
||||
if (pokemonPrevolutions.hasOwnProperty(species.speciesId)) {
|
||||
this.pokemonCaughtHatchedContainer.setVisible(false);
|
||||
this.pokemonShinyIcon.setY(104);
|
||||
this.pokemonFormText.setY(25);
|
||||
} else {
|
||||
this.pokemonCaughtHatchedContainer.setVisible(true);
|
||||
this.pokemonShinyIcon.setY(86);
|
||||
this.pokemonCandyIcon.setTint(argbFromRgba(rgbHexToRgba(colorScheme[0])));
|
||||
this.pokemonCandyOverlayIcon.setTint(argbFromRgba(rgbHexToRgba(colorScheme[1])));
|
||||
this.pokemonCandyCountText.setText(`×${globalScene.gameData.starterData[species.speciesId].candyCount}`);
|
||||
this.pokemonFormText.setY(42);
|
||||
this.pokemonHatchedIcon.setVisible(true);
|
||||
this.pokemonHatchedCountText.setVisible(true);
|
||||
|
||||
const { currentFriendship, friendshipCap } = getFriendship(species.speciesId);
|
||||
const candyCropY = 16 - 16 * (currentFriendship / friendshipCap);
|
||||
this.pokemonCandyDarknessOverlay.setCrop(0, 0, 16, candyCropY);
|
||||
|
||||
this.pokemonCandyContainer
|
||||
.setVisible(true)
|
||||
.on("pointerover", () => {
|
||||
globalScene.ui.showTooltip("", `${currentFriendship}/${friendshipCap}`, true);
|
||||
this.activeTooltip = "CANDY";
|
||||
})
|
||||
.on("pointerout", () => {
|
||||
globalScene.ui.hideTooltip();
|
||||
this.activeTooltip = undefined;
|
||||
});
|
||||
}
|
||||
|
||||
const props = globalScene.gameData.getSpeciesDexAttrProps(species, defaultDexAttr);
|
||||
props.formIndex = starterPreferences?.formIndex ?? props.formIndex;
|
||||
const speciesForm = getPokemonSpeciesForm(species.speciesId, props.formIndex);
|
||||
this.setTypeIcons(speciesForm.type1, speciesForm.type2);
|
||||
|
||||
this.pokemonSprite.clearTint();
|
||||
} else if (dexEntry.seenAttr) {
|
||||
this.cleanStarterSprite(species, true);
|
||||
|
||||
const props = globalScene.gameData.getSpeciesDefaultDexAttrProps(species);
|
||||
|
||||
const formIndex = props.formIndex;
|
||||
const female = props.female;
|
||||
const shiny = props.shiny;
|
||||
const variant = props.variant;
|
||||
|
||||
this.updateSprite(species, female, formIndex, shiny, variant);
|
||||
this.pokemonSprite.setVisible(true);
|
||||
this.pokemonSprite.setTint(0x808080);
|
||||
} else {
|
||||
this.cleanStarterSprite(species);
|
||||
|
||||
const props = globalScene.gameData.getSpeciesDefaultDexAttrProps(species);
|
||||
|
||||
const formIndex = props.formIndex;
|
||||
const female = props.female;
|
||||
const shiny = props.shiny;
|
||||
const variant = props.variant;
|
||||
|
||||
this.updateSprite(species, female, formIndex, shiny, variant);
|
||||
this.pokemonSprite.setVisible(true);
|
||||
this.pokemonSprite.setTint(0x000000);
|
||||
}
|
||||
}
|
||||
|
||||
cleanStarterSprite(species?: PokemonSpecies, isSeen = false) {
|
||||
if (isSeen && species) {
|
||||
this.setNameAndNumber(species, {});
|
||||
} else {
|
||||
this.pokemonNumberText.setText(padInt(0, 4));
|
||||
this.pokemonNameText.setText(species ? "???" : "");
|
||||
}
|
||||
|
||||
this.pokemonSprite.setVisible(!!species);
|
||||
this.pokemonUncaughtText.setVisible(!!species);
|
||||
|
||||
this.pokemonPermanentInfoContainer.setVisible(false);
|
||||
this.pokemonStatisticsContainer.setVisible(false);
|
||||
this.resetSpeciesDetails();
|
||||
}
|
||||
|
||||
resetSpeciesDetails() {
|
||||
globalScene.ui.hideTooltip();
|
||||
|
||||
this.pokemonPreferencesContainer.setVisible(false);
|
||||
|
||||
if (this.assetLoadCancelled) {
|
||||
this.assetLoadCancelled.value = true;
|
||||
this.assetLoadCancelled = null;
|
||||
}
|
||||
|
||||
this.shinyOverlay.setVisible(false);
|
||||
this.pokemonNumberText
|
||||
.setColor(getTextColor(TextStyle.SUMMARY))
|
||||
.setShadowColor(getTextColor(TextStyle.SUMMARY, true));
|
||||
|
||||
for (let m = 0; m < 4; m++) {
|
||||
this.pokemonMoveContainers[m].setVisible(false);
|
||||
}
|
||||
this.pokemonEggMovesContainer.setVisible(false);
|
||||
this.pokemonAdditionalMoveCountLabel.setVisible(false);
|
||||
}
|
||||
|
||||
setSpeciesDetails(species: PokemonSpecies, options: SpeciesDetails = {}): void {
|
||||
// Here we pass some options to override everything else
|
||||
let { shiny, formIndex, female, variant, abilityIndex, natureIndex, teraType } = options;
|
||||
console.log("OPTIONS", options);
|
||||
|
||||
// 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 && female != null) || formIndex != null || shiny != null || variant != null;
|
||||
|
||||
this.updateCandyTooltip();
|
||||
|
||||
this.pokemonSprite.setVisible(false);
|
||||
this.teraIcon.setVisible(false);
|
||||
|
||||
if (this.assetLoadCancelled) {
|
||||
this.assetLoadCancelled.value = true;
|
||||
this.assetLoadCancelled = null;
|
||||
}
|
||||
|
||||
this.pokemonPreferencesContainer.setVisible(true);
|
||||
|
||||
this.shinyOverlay.setVisible(shiny ?? false); // TODO: is false the correct default?
|
||||
this.pokemonNumberText.setColor(
|
||||
getTextColor(shiny ? TextStyle.SUMMARY_DEX_NUM_GOLD : TextStyle.SUMMARY_DEX_NUM, false),
|
||||
);
|
||||
this.pokemonNumberText.setShadowColor(
|
||||
getTextColor(shiny ? TextStyle.SUMMARY_DEX_NUM_GOLD : TextStyle.SUMMARY_DEX_NUM, true),
|
||||
);
|
||||
|
||||
this.setShinyIcon(shiny, variant);
|
||||
|
||||
const assetLoadCancelled = new BooleanHolder(false);
|
||||
this.assetLoadCancelled = assetLoadCancelled;
|
||||
|
||||
// TODO: should this line be here, or in .updateSprite?
|
||||
female ??= false;
|
||||
if (shouldUpdateSprite) {
|
||||
this.updateSprite(species, female, formIndex, shiny, variant);
|
||||
} else {
|
||||
this.pokemonSprite.setVisible(!this.statsMode);
|
||||
}
|
||||
|
||||
// Set the gender text
|
||||
if (species.malePercent !== null) {
|
||||
const gender = !female ? Gender.MALE : Gender.FEMALE;
|
||||
this.pokemonGenderText
|
||||
.setText(getGenderSymbol(gender))
|
||||
.setColor(getGenderColor(gender))
|
||||
.setShadowColor(getGenderColor(gender, true));
|
||||
} else {
|
||||
this.pokemonGenderText.setText("");
|
||||
}
|
||||
|
||||
// Update ability text
|
||||
let ability: Ability;
|
||||
if (species.forms?.length > 1) {
|
||||
ability = allAbilities[species.forms[formIndex ?? 0].getAbility(abilityIndex!)];
|
||||
} else {
|
||||
ability = allAbilities[species.getAbility(abilityIndex!)]; // TODO: is this bang correct?
|
||||
}
|
||||
|
||||
const isHidden = abilityIndex === (species.ability2 ? 2 : 1);
|
||||
this.pokemonAbilityText
|
||||
.setText(ability.name)
|
||||
.setColor(getTextColor(!isHidden ? TextStyle.SUMMARY_ALT : TextStyle.SUMMARY_GOLD))
|
||||
.setShadowColor(getTextColor(!isHidden ? TextStyle.SUMMARY_ALT : TextStyle.SUMMARY_GOLD, true));
|
||||
|
||||
if (this.pokemonAbilityText.visible) {
|
||||
if (this.activeTooltip === "ABILITY") {
|
||||
globalScene.ui.editTooltip(`${ability.name}`, `${ability.description}`);
|
||||
}
|
||||
|
||||
this.pokemonAbilityText.on("pointerover", () => {
|
||||
globalScene.ui.showTooltip(`${ability.name}`, `${ability.description}`, true);
|
||||
this.activeTooltip = "ABILITY";
|
||||
});
|
||||
this.pokemonAbilityText.on("pointerout", () => {
|
||||
globalScene.ui.hideTooltip();
|
||||
this.activeTooltip = undefined;
|
||||
});
|
||||
}
|
||||
|
||||
this.updatePassiveDisplay(species.speciesId, formIndex);
|
||||
|
||||
// Update nature text
|
||||
this.pokemonNatureText.setText(getNatureName(natureIndex as unknown as Nature, true, true, false));
|
||||
|
||||
// Update form text
|
||||
const speciesForm = getPokemonSpeciesForm(species.speciesId, formIndex!); // TODO: is the bang correct?
|
||||
const formText = species.getFormNameToDisplay(formIndex);
|
||||
this.pokemonFormText.setText(formText);
|
||||
|
||||
// Update type icons
|
||||
this.setTypeIcons(speciesForm.type1, speciesForm.type2);
|
||||
|
||||
// Update tera icon
|
||||
const newTeraType = teraType ?? speciesForm.type1;
|
||||
this.teraIcon.setFrame(PokemonType[newTeraType].toLowerCase());
|
||||
this.teraIcon.setVisible(!this.statsMode && this.allowTera);
|
||||
}
|
||||
|
||||
showStats(): void {
|
||||
const { dexEntry } = getSpeciesData(this.speciesId);
|
||||
this.statsContainer.setVisible(true);
|
||||
this.statsContainer.updateIvs(dexEntry.ivs);
|
||||
}
|
||||
|
||||
updatePassiveDisplay(speciesId: SpeciesId, formIndex = 0) {
|
||||
this.pokemonPassiveLabelText.setVisible(false);
|
||||
this.pokemonPassiveText.setVisible(false);
|
||||
this.pokemonPassiveDisabledIcon.setVisible(false);
|
||||
this.pokemonPassiveLockedIcon.setVisible(false);
|
||||
|
||||
const isFreshStartChallenge = globalScene.gameMode.hasChallenge(Challenges.FRESH_START);
|
||||
|
||||
const { starterDataEntry } = getSpeciesData(speciesId);
|
||||
|
||||
const passiveAttr = starterDataEntry.passiveAttr;
|
||||
const passiveAbility = allAbilities[getPokemonSpecies(speciesId).getPassiveAbility(formIndex)];
|
||||
|
||||
if (passiveAbility) {
|
||||
const isUnlocked = !!(passiveAttr & Passive.UNLOCKED);
|
||||
const isEnabled = !!(passiveAttr & Passive.ENABLED);
|
||||
|
||||
const textStyle = isUnlocked && isEnabled ? TextStyle.SUMMARY_ALT : TextStyle.SUMMARY_GRAY;
|
||||
const textAlpha = isUnlocked && isEnabled ? 1 : 0.5;
|
||||
|
||||
this.pokemonPassiveLabelText
|
||||
.setVisible(!isFreshStartChallenge)
|
||||
.setColor(getTextColor(TextStyle.SUMMARY_ALT))
|
||||
.setShadowColor(getTextColor(TextStyle.SUMMARY_ALT, true));
|
||||
this.pokemonPassiveText
|
||||
.setVisible(!isFreshStartChallenge)
|
||||
.setText(passiveAbility.name)
|
||||
.setColor(getTextColor(textStyle))
|
||||
.setAlpha(textAlpha)
|
||||
.setShadowColor(getTextColor(textStyle, true));
|
||||
|
||||
if (this.activeTooltip === "PASSIVE") {
|
||||
globalScene.ui.editTooltip(`${passiveAbility.name}`, `${passiveAbility.description}`);
|
||||
}
|
||||
|
||||
if (this.pokemonPassiveText.visible) {
|
||||
this.pokemonPassiveText.on("pointerover", () => {
|
||||
globalScene.ui.showTooltip(`${passiveAbility.name}`, `${passiveAbility.description}`, true);
|
||||
this.activeTooltip = "PASSIVE";
|
||||
});
|
||||
this.pokemonPassiveText.on("pointerout", () => {
|
||||
globalScene.ui.hideTooltip();
|
||||
this.activeTooltip = undefined;
|
||||
});
|
||||
}
|
||||
|
||||
const iconPosition = {
|
||||
x: this.pokemonPassiveText.x + this.pokemonPassiveText.displayWidth + 1,
|
||||
y: this.pokemonPassiveText.y + this.pokemonPassiveText.displayHeight / 2,
|
||||
};
|
||||
this.pokemonPassiveDisabledIcon
|
||||
.setVisible(isUnlocked && !isEnabled && !isFreshStartChallenge)
|
||||
.setPosition(iconPosition.x, iconPosition.y);
|
||||
this.pokemonPassiveLockedIcon
|
||||
.setVisible(!isUnlocked && !isFreshStartChallenge)
|
||||
.setPosition(iconPosition.x, iconPosition.y);
|
||||
} else if (this.activeTooltip === "PASSIVE") {
|
||||
// No passive and passive tooltip is active > hide it
|
||||
globalScene.ui.hideTooltip();
|
||||
}
|
||||
}
|
||||
|
||||
updateSprite(
|
||||
species: PokemonSpecies,
|
||||
female: boolean,
|
||||
formIndex?: number | undefined,
|
||||
shiny?: boolean,
|
||||
variant?: Variant | undefined,
|
||||
) {
|
||||
species.loadAssets(female, formIndex, shiny, variant, true).then(() => {
|
||||
if (this.assetLoadCancelled?.value) {
|
||||
return;
|
||||
}
|
||||
this.assetLoadCancelled = null;
|
||||
// Note: Bangs are correct due to `female ??= false` above
|
||||
this.pokemonSprite
|
||||
.play(species.getSpriteKey(female!, formIndex, shiny, variant))
|
||||
.setPipelineData("shiny", shiny)
|
||||
.setPipelineData("variant", variant)
|
||||
.setPipelineData("spriteKey", species.getSpriteKey(female!, formIndex, shiny, variant))
|
||||
.setVisible(!this.statsMode);
|
||||
});
|
||||
}
|
||||
|
||||
updateCandyTooltip() {
|
||||
if (this.activeTooltip === "CANDY") {
|
||||
if (this.speciesId && this.pokemonCandyContainer.visible) {
|
||||
const { currentFriendship, friendshipCap } = getFriendship(this.speciesId);
|
||||
globalScene.ui.editTooltip("", `${currentFriendship}/${friendshipCap}`);
|
||||
} else {
|
||||
globalScene.ui.hideTooltip();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updateMoveset(starterMoveset: StarterMoveset, totalMoves: number) {
|
||||
for (let m = 0; m < 4; m++) {
|
||||
const move = m < starterMoveset.length ? allMoves[starterMoveset[m]] : null;
|
||||
this.pokemonMoveBgs[m].setFrame(PokemonType[move ? move.type : PokemonType.UNKNOWN].toString().toLowerCase());
|
||||
this.pokemonMoveLabels[m].setText(move ? move.name : "-");
|
||||
this.pokemonMoveContainers[m].setVisible(!!move);
|
||||
}
|
||||
|
||||
this.pokemonAdditionalMoveCountLabel.setText(`(+${Math.max(totalMoves - 4, 0)})`).setVisible(totalMoves > 4);
|
||||
}
|
||||
|
||||
updateEggMoves(eggMoves: number) {
|
||||
for (let em = 0; em < 4; em++) {
|
||||
const eggMove = allMoves[speciesEggMoves[this.speciesId][em]];
|
||||
const eggMoveUnlocked = eggMove && eggMoves & (1 << em);
|
||||
this.pokemonEggMoveBgs[em].setFrame(
|
||||
PokemonType[eggMove ? eggMove.type : PokemonType.UNKNOWN].toString().toLowerCase(),
|
||||
);
|
||||
this.pokemonEggMoveLabels[em].setText(eggMove && eggMoveUnlocked ? eggMove.name : "???");
|
||||
}
|
||||
|
||||
this.pokemonEggMovesContainer.setVisible(true);
|
||||
}
|
||||
|
||||
showIvs() {
|
||||
this.showStats();
|
||||
this.statsMode = true;
|
||||
this.pokemonSprite.setVisible(false);
|
||||
this.teraIcon.setVisible(false);
|
||||
}
|
||||
|
||||
hideIvs(caught = true) {
|
||||
this.statsMode = false;
|
||||
this.statsContainer.setVisible(false);
|
||||
this.pokemonSprite.setVisible(caught);
|
||||
this.teraIcon.setVisible(this.allowTera);
|
||||
}
|
||||
|
||||
clear() {
|
||||
globalScene.ui.hideTooltip();
|
||||
this.activeTooltip = undefined;
|
||||
}
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
import { VALUE_REDUCTION_MAX } from "#app/constants";
|
||||
import { globalScene } from "#app/global-scene";
|
||||
import { starterColors } from "#app/global-vars/starter-colors";
|
||||
import Overrides from "#app/overrides";
|
||||
@ -45,7 +46,7 @@ import type { Variant } from "#sprites/variant";
|
||||
import { getVariantIcon, getVariantTint } from "#sprites/variant";
|
||||
import { SettingKeyboard } from "#system/settings-keyboard";
|
||||
import type { DexEntry } from "#types/dex-data";
|
||||
import type { StarterAttributes } from "#types/save-data";
|
||||
import type { StarterPreferences } from "#types/save-data";
|
||||
import type { OptionSelectItem } from "#ui/abstract-option-select-ui-handler";
|
||||
import { BaseStatsOverlay } from "#ui/base-stats-overlay";
|
||||
import { MessageUiHandler } from "#ui/message-ui-handler";
|
||||
@ -61,6 +62,11 @@ import { toCamelCase, toTitleCase } from "#utils/strings";
|
||||
import { argbFromRgba } from "@material/material-color-utilities";
|
||||
import i18next from "i18next";
|
||||
import type BBCodeText from "phaser3-rex-plugins/plugins/gameobjects/tagtext/bbcodetext/BBCodeText";
|
||||
import {
|
||||
isPassiveAvailable,
|
||||
isSameSpeciesEggAvailable,
|
||||
isValueReductionAvailable,
|
||||
} from "../utils/starter-select-ui-utils";
|
||||
|
||||
interface LanguageSetting {
|
||||
starterInfoTextSize: string;
|
||||
@ -148,8 +154,6 @@ const languageSettings: { [key: string]: LanguageSetting } = {
|
||||
},
|
||||
};
|
||||
|
||||
const valueReductionMax = 2;
|
||||
|
||||
// Position of UI elements
|
||||
const speciesContainerX = 109;
|
||||
|
||||
@ -261,11 +265,11 @@ export class PokedexPageUiHandler extends MessageUiHandler {
|
||||
private instructionRowY = 0;
|
||||
private instructionRowTextOffset = 9;
|
||||
|
||||
private starterAttributes: StarterAttributes;
|
||||
private savedStarterAttributes: StarterAttributes;
|
||||
private starterPreferences: StarterPreferences;
|
||||
private savedStarterPreferences: StarterPreferences;
|
||||
|
||||
private previousSpecies: PokemonSpecies[];
|
||||
private previousStarterAttributes: StarterAttributes[];
|
||||
private previousStarterPreferences: StarterPreferences[];
|
||||
|
||||
protected blockInput = false;
|
||||
protected blockInputOverlay = false;
|
||||
@ -702,7 +706,7 @@ export class PokedexPageUiHandler extends MessageUiHandler {
|
||||
this.starterSelectContainer.bringToTop(this.starterSelectMessageBoxContainer);
|
||||
|
||||
this.previousSpecies = [];
|
||||
this.previousStarterAttributes = [];
|
||||
this.previousStarterPreferences = [];
|
||||
}
|
||||
|
||||
show(args: any[]): boolean {
|
||||
@ -715,13 +719,13 @@ export class PokedexPageUiHandler extends MessageUiHandler {
|
||||
return false;
|
||||
}
|
||||
this.species = args[0];
|
||||
this.savedStarterAttributes = args[1] ?? {
|
||||
this.savedStarterPreferences = args[1] ?? {
|
||||
shiny: false,
|
||||
female: true,
|
||||
variant: 0,
|
||||
form: 0,
|
||||
};
|
||||
this.formIndex = this.savedStarterAttributes.form ?? 0;
|
||||
this.formIndex = this.savedStarterPreferences.formIndex ?? 0;
|
||||
this.filteredIndices = args[2] ?? null;
|
||||
this.starterSetup();
|
||||
|
||||
@ -737,7 +741,7 @@ export class PokedexPageUiHandler extends MessageUiHandler {
|
||||
this.starterSelectContainer.setVisible(true);
|
||||
this.getUi().bringToTop(this.starterSelectContainer);
|
||||
|
||||
this.starterAttributes = this.initStarterPrefs();
|
||||
this.starterPreferences = this.initStarterPrefs();
|
||||
|
||||
this.menuOptions = getEnumValues(MenuOptions);
|
||||
|
||||
@ -783,8 +787,8 @@ export class PokedexPageUiHandler extends MessageUiHandler {
|
||||
this.isFormGender = formKey === "male" || formKey === "female";
|
||||
if (
|
||||
this.isFormGender
|
||||
&& ((this.savedStarterAttributes.female === true && formKey === "male")
|
||||
|| (this.savedStarterAttributes.female === false && formKey === "female"))
|
||||
&& ((this.savedStarterPreferences.female === true && formKey === "male")
|
||||
|| (this.savedStarterPreferences.female === false && formKey === "female"))
|
||||
) {
|
||||
this.formIndex = (this.formIndex + 1) % 2;
|
||||
formKey = this.species.forms[this.formIndex].formKey;
|
||||
@ -1009,26 +1013,26 @@ export class PokedexPageUiHandler extends MessageUiHandler {
|
||||
* 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
|
||||
* @returns StarterPreferences for the species
|
||||
*/
|
||||
initStarterPrefs(): StarterAttributes {
|
||||
const starterAttributes: StarterAttributes | null = this.species ? { ...this.savedStarterAttributes } : null;
|
||||
initStarterPrefs(): StarterPreferences {
|
||||
const starterPreferences: StarterPreferences | null = this.species ? { ...this.savedStarterPreferences } : null;
|
||||
const caughtAttr = this.isCaught();
|
||||
|
||||
// no preferences or Pokemon wasn't caught, return empty attribute
|
||||
if (!starterAttributes || !this.isSeen()) {
|
||||
if (!starterPreferences || !this.isSeen()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const hasShiny = caughtAttr & DexAttr.SHINY;
|
||||
const hasNonShiny = caughtAttr & DexAttr.NON_SHINY;
|
||||
if (!hasShiny || (starterAttributes.shiny === undefined && hasNonShiny)) {
|
||||
if (!hasShiny || (starterPreferences.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;
|
||||
starterPreferences.shiny = false;
|
||||
starterPreferences.variant = 0;
|
||||
} else if (!hasNonShiny || (starterPreferences.shiny === undefined && hasShiny)) {
|
||||
starterPreferences.shiny = true;
|
||||
starterPreferences.variant = 0;
|
||||
}
|
||||
|
||||
this.unlockedVariants = [
|
||||
@ -1037,36 +1041,36 @@ export class PokedexPageUiHandler extends MessageUiHandler {
|
||||
!!(hasShiny && caughtAttr & DexAttr.VARIANT_3),
|
||||
];
|
||||
if (
|
||||
starterAttributes.variant === undefined
|
||||
|| Number.isNaN(starterAttributes.variant)
|
||||
|| starterAttributes.variant < 0
|
||||
starterPreferences.variant === undefined
|
||||
|| Number.isNaN(starterPreferences.variant)
|
||||
|| starterPreferences.variant < 0
|
||||
) {
|
||||
starterAttributes.variant = 0;
|
||||
} else if (!this.unlockedVariants[starterAttributes.variant]) {
|
||||
starterPreferences.variant = 0;
|
||||
} else if (!this.unlockedVariants[starterPreferences.variant]) {
|
||||
let highestValidIndex = -1;
|
||||
for (let i = 0; i <= starterAttributes.variant && i < this.unlockedVariants.length; i++) {
|
||||
for (let i = 0; i <= starterPreferences.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;
|
||||
starterPreferences.variant = highestValidIndex !== -1 ? highestValidIndex : 0;
|
||||
}
|
||||
|
||||
if (starterAttributes.female !== undefined) {
|
||||
if (starterPreferences.female !== undefined) {
|
||||
if (
|
||||
(starterAttributes.female && !(caughtAttr & DexAttr.FEMALE))
|
||||
|| (!starterAttributes.female && !(caughtAttr & DexAttr.MALE))
|
||||
(starterPreferences.female && !(caughtAttr & DexAttr.FEMALE))
|
||||
|| (!starterPreferences.female && !(caughtAttr & DexAttr.MALE))
|
||||
) {
|
||||
starterAttributes.female = !starterAttributes.female;
|
||||
starterPreferences.female = !starterPreferences.female;
|
||||
}
|
||||
} else if (caughtAttr & DexAttr.FEMALE) {
|
||||
starterAttributes.female = true;
|
||||
starterPreferences.female = true;
|
||||
} else if (caughtAttr & DexAttr.MALE) {
|
||||
starterAttributes.female = false;
|
||||
starterPreferences.female = false;
|
||||
}
|
||||
|
||||
return starterAttributes;
|
||||
return starterPreferences;
|
||||
}
|
||||
|
||||
showText(
|
||||
@ -1178,10 +1182,10 @@ export class PokedexPageUiHandler extends MessageUiHandler {
|
||||
this.blockInput = true;
|
||||
ui.setModeWithoutClear(UiMode.OPTION_SELECT).then(() => {
|
||||
const species = this.previousSpecies.pop();
|
||||
const starterAttributes = this.previousStarterAttributes.pop();
|
||||
const starterPreferences = this.previousStarterPreferences.pop();
|
||||
this.moveInfoOverlay.clear();
|
||||
this.clearText();
|
||||
ui.setModeForceTransition(UiMode.POKEDEX_PAGE, species, starterAttributes);
|
||||
ui.setModeForceTransition(UiMode.POKEDEX_PAGE, species, starterPreferences);
|
||||
success = true;
|
||||
});
|
||||
this.blockInput = false;
|
||||
@ -1198,7 +1202,7 @@ export class PokedexPageUiHandler extends MessageUiHandler {
|
||||
} else {
|
||||
const starterData = globalScene.gameData.starterData[this.starterId];
|
||||
// prepare persistent starter data to store changes
|
||||
const starterAttributes = this.starterAttributes;
|
||||
const starterPreferences = this.starterPreferences;
|
||||
|
||||
if (button === Button.ACTION) {
|
||||
switch (this.cursor) {
|
||||
@ -1608,7 +1612,7 @@ export class PokedexPageUiHandler extends MessageUiHandler {
|
||||
: (preSpecies ?? this.species).getExpandedSpeciesName(),
|
||||
handler: () => {
|
||||
this.previousSpecies.push(this.species);
|
||||
this.previousStarterAttributes.push({ ...this.savedStarterAttributes });
|
||||
this.previousStarterPreferences.push({ ...this.savedStarterPreferences });
|
||||
const newSpecies = allSpecies.find(
|
||||
species => species.speciesId === pokemonPrevolutions[pre.speciesId],
|
||||
);
|
||||
@ -1620,11 +1624,11 @@ export class PokedexPageUiHandler extends MessageUiHandler {
|
||||
: "";
|
||||
const matchingForm = newSpecies?.forms.find(form => form.formKey === newFormKey);
|
||||
const newFormIndex = matchingForm ? matchingForm.formIndex : 0;
|
||||
this.starterAttributes.form = newFormIndex;
|
||||
this.savedStarterAttributes.form = newFormIndex;
|
||||
this.starterPreferences.formIndex = newFormIndex;
|
||||
this.savedStarterPreferences.formIndex = newFormIndex;
|
||||
this.moveInfoOverlay.clear();
|
||||
this.clearText();
|
||||
ui.setMode(UiMode.POKEDEX_PAGE, newSpecies, this.savedStarterAttributes);
|
||||
ui.setMode(UiMode.POKEDEX_PAGE, newSpecies, this.savedStarterPreferences);
|
||||
return true;
|
||||
},
|
||||
onHover: () => this.showText(conditionText),
|
||||
@ -1661,12 +1665,12 @@ export class PokedexPageUiHandler extends MessageUiHandler {
|
||||
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.previousStarterPreferences.push({ ...this.savedStarterPreferences });
|
||||
this.starterPreferences.formIndex = newFormIndex;
|
||||
this.savedStarterPreferences.formIndex = newFormIndex;
|
||||
this.moveInfoOverlay.clear();
|
||||
this.clearText();
|
||||
ui.setMode(UiMode.POKEDEX_PAGE, evoSpecies, this.savedStarterAttributes);
|
||||
ui.setMode(UiMode.POKEDEX_PAGE, evoSpecies, this.savedStarterPreferences);
|
||||
return true;
|
||||
},
|
||||
onHover: () => this.showText(conditionText),
|
||||
@ -1703,17 +1707,17 @@ export class PokedexPageUiHandler extends MessageUiHandler {
|
||||
style: isFormCaught ? TextStyle.WINDOW : TextStyle.SHADOW_TEXT,
|
||||
handler: () => {
|
||||
this.previousSpecies.push(this.species);
|
||||
this.previousStarterAttributes.push({ ...this.savedStarterAttributes });
|
||||
this.previousStarterPreferences.push({ ...this.savedStarterPreferences });
|
||||
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.starterPreferences.formIndex = newFormIndex;
|
||||
this.savedStarterPreferences.formIndex = newFormIndex;
|
||||
this.moveInfoOverlay.clear();
|
||||
this.clearText();
|
||||
ui.setMode(
|
||||
UiMode.POKEDEX_PAGE,
|
||||
newSpecies,
|
||||
this.savedStarterAttributes,
|
||||
this.savedStarterPreferences,
|
||||
this.filteredIndices,
|
||||
);
|
||||
return true;
|
||||
@ -1806,9 +1810,9 @@ export class PokedexPageUiHandler extends MessageUiHandler {
|
||||
switch (button) {
|
||||
case Button.CYCLE_SHINY:
|
||||
if (this.canCycleShiny) {
|
||||
if (!starterAttributes.shiny) {
|
||||
if (!starterPreferences.shiny) {
|
||||
// Change to shiny, we need to get the proper default variant
|
||||
const newVariant = starterAttributes.variant ? (starterAttributes.variant as Variant) : 0;
|
||||
const newVariant = starterPreferences.variant ? (starterPreferences.variant as Variant) : 0;
|
||||
this.setSpeciesDetails(this.species, {
|
||||
shiny: true,
|
||||
variant: newVariant,
|
||||
@ -1816,8 +1820,8 @@ export class PokedexPageUiHandler extends MessageUiHandler {
|
||||
|
||||
globalScene.playSound("se/sparkle");
|
||||
|
||||
starterAttributes.shiny = true;
|
||||
this.savedStarterAttributes.shiny = starterAttributes.shiny;
|
||||
starterPreferences.shiny = true;
|
||||
this.savedStarterPreferences.shiny = starterPreferences.shiny;
|
||||
} else {
|
||||
let newVariant = props.variant;
|
||||
do {
|
||||
@ -1835,16 +1839,16 @@ export class PokedexPageUiHandler extends MessageUiHandler {
|
||||
}
|
||||
} while (newVariant !== props.variant);
|
||||
|
||||
starterAttributes.variant = newVariant; // store the selected variant
|
||||
this.savedStarterAttributes.variant = starterAttributes.variant;
|
||||
starterPreferences.variant = newVariant; // store the selected variant
|
||||
this.savedStarterPreferences.variant = starterPreferences.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;
|
||||
starterPreferences.shiny = false;
|
||||
this.savedStarterPreferences.shiny = starterPreferences.shiny;
|
||||
} else {
|
||||
this.setSpeciesDetails(this.species, {
|
||||
variant: newVariant as Variant,
|
||||
@ -1865,16 +1869,16 @@ export class PokedexPageUiHandler extends MessageUiHandler {
|
||||
break;
|
||||
}
|
||||
} while (newFormIndex !== props.formIndex || this.species.forms[newFormIndex].isUnobtainable);
|
||||
starterAttributes.form = newFormIndex; // store the selected form
|
||||
this.savedStarterAttributes.form = starterAttributes.form;
|
||||
starterPreferences.formIndex = newFormIndex; // store the selected form
|
||||
this.savedStarterPreferences.formIndex = starterPreferences.formIndex;
|
||||
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;
|
||||
starterPreferences.female = newFemale;
|
||||
this.savedStarterPreferences.female = starterPreferences.female;
|
||||
this.starterSetup();
|
||||
this.setSpeciesDetails(this.species, {
|
||||
formIndex: newFormIndex,
|
||||
@ -1885,15 +1889,15 @@ export class PokedexPageUiHandler extends MessageUiHandler {
|
||||
break;
|
||||
case Button.CYCLE_GENDER:
|
||||
if (this.canCycleGender) {
|
||||
starterAttributes.female = !props.female;
|
||||
this.savedStarterAttributes.female = starterAttributes.female;
|
||||
starterPreferences.female = !props.female;
|
||||
this.savedStarterPreferences.female = starterPreferences.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;
|
||||
starterPreferences.formIndex = newFormIndex; // store the selected form
|
||||
this.savedStarterPreferences.formIndex = starterPreferences.formIndex;
|
||||
this.formIndex = newFormIndex;
|
||||
this.starterSetup();
|
||||
this.setSpeciesDetails(this.species, {
|
||||
@ -1938,15 +1942,17 @@ export class PokedexPageUiHandler extends MessageUiHandler {
|
||||
}
|
||||
return false;
|
||||
},
|
||||
style: this.isPassiveAvailable() ? TextStyle.WINDOW : TextStyle.SHADOW_TEXT,
|
||||
style: isPassiveAvailable(this.species.speciesId) ? TextStyle.WINDOW : TextStyle.SHADOW_TEXT,
|
||||
item: "candy",
|
||||
itemArgs: this.isPassiveAvailable() ? starterColors[this.starterId] : ["808080", "808080"],
|
||||
itemArgs: isPassiveAvailable(this.species.speciesId)
|
||||
? starterColors[this.starterId]
|
||||
: ["808080", "808080"],
|
||||
});
|
||||
}
|
||||
|
||||
// Reduce cost option
|
||||
const valueReduction = starterData.valueReduction;
|
||||
if (valueReduction < valueReductionMax) {
|
||||
if (valueReduction < VALUE_REDUCTION_MAX) {
|
||||
const reductionCost = getValueReductionCandyCounts(speciesStarterCosts[this.starterId])[valueReduction];
|
||||
options.push({
|
||||
label: `×${reductionCost} ${i18next.t("pokedexUiHandler:reduceCost")}`,
|
||||
@ -1969,9 +1975,11 @@ export class PokedexPageUiHandler extends MessageUiHandler {
|
||||
}
|
||||
return false;
|
||||
},
|
||||
style: this.isValueReductionAvailable() ? TextStyle.WINDOW : TextStyle.SHADOW_TEXT,
|
||||
style: isValueReductionAvailable(this.species.speciesId) ? TextStyle.WINDOW : TextStyle.SHADOW_TEXT,
|
||||
item: "candy",
|
||||
itemArgs: this.isValueReductionAvailable() ? starterColors[this.starterId] : ["808080", "808080"],
|
||||
itemArgs: isValueReductionAvailable(this.species.speciesId)
|
||||
? starterColors[this.starterId]
|
||||
: ["808080", "808080"],
|
||||
});
|
||||
}
|
||||
|
||||
@ -2018,9 +2026,11 @@ export class PokedexPageUiHandler extends MessageUiHandler {
|
||||
}
|
||||
return false;
|
||||
},
|
||||
style: this.isSameSpeciesEggAvailable() ? TextStyle.WINDOW : TextStyle.SHADOW_TEXT,
|
||||
style: isSameSpeciesEggAvailable(this.species.speciesId) ? TextStyle.WINDOW : TextStyle.SHADOW_TEXT,
|
||||
item: "candy",
|
||||
itemArgs: this.isSameSpeciesEggAvailable() ? starterColors[this.starterId] : ["808080", "808080"],
|
||||
itemArgs: isSameSpeciesEggAvailable(this.species.speciesId)
|
||||
? starterColors[this.starterId]
|
||||
: ["808080", "808080"],
|
||||
});
|
||||
options.push({
|
||||
label: i18next.t("menu:cancel"),
|
||||
@ -2071,7 +2081,7 @@ export class PokedexPageUiHandler extends MessageUiHandler {
|
||||
// Always go back to first selection after scrolling around
|
||||
if (this.previousSpecies.length === 0) {
|
||||
this.previousSpecies.push(this.species);
|
||||
this.previousStarterAttributes.push({ ...this.savedStarterAttributes });
|
||||
this.previousStarterPreferences.push({ ...this.savedStarterPreferences });
|
||||
}
|
||||
let newSpecies: PokemonSpecies;
|
||||
if (this.filteredIndices) {
|
||||
@ -2087,14 +2097,14 @@ export class PokedexPageUiHandler extends MessageUiHandler {
|
||||
form => form.formKey === this.species?.forms[this.formIndex]?.formKey,
|
||||
);
|
||||
const newFormIndex = matchingForm ? matchingForm.formIndex : 0;
|
||||
this.starterAttributes.form = newFormIndex;
|
||||
this.savedStarterAttributes.form = newFormIndex;
|
||||
this.starterPreferences.formIndex = newFormIndex;
|
||||
this.savedStarterPreferences.formIndex = newFormIndex;
|
||||
this.moveInfoOverlay.clear();
|
||||
this.clearText();
|
||||
ui.setModeForceTransition(
|
||||
UiMode.POKEDEX_PAGE,
|
||||
newSpecies,
|
||||
this.savedStarterAttributes,
|
||||
this.savedStarterPreferences,
|
||||
this.filteredIndices,
|
||||
);
|
||||
});
|
||||
@ -2110,7 +2120,7 @@ export class PokedexPageUiHandler extends MessageUiHandler {
|
||||
// Always go back to first selection after scrolling around
|
||||
if (this.previousSpecies.length === 0) {
|
||||
this.previousSpecies.push(this.species);
|
||||
this.previousStarterAttributes.push({ ...this.savedStarterAttributes });
|
||||
this.previousStarterPreferences.push({ ...this.savedStarterPreferences });
|
||||
}
|
||||
let newSpecies: PokemonSpecies;
|
||||
if (this.filteredIndices) {
|
||||
@ -2126,14 +2136,14 @@ export class PokedexPageUiHandler extends MessageUiHandler {
|
||||
form => form.formKey === this.species?.forms[this.formIndex]?.formKey,
|
||||
);
|
||||
const newFormIndex = matchingForm ? matchingForm.formIndex : 0;
|
||||
this.starterAttributes.form = newFormIndex;
|
||||
this.savedStarterAttributes.form = newFormIndex;
|
||||
this.starterPreferences.formIndex = newFormIndex;
|
||||
this.savedStarterPreferences.formIndex = newFormIndex;
|
||||
this.moveInfoOverlay.clear();
|
||||
this.clearText();
|
||||
ui.setModeForceTransition(
|
||||
UiMode.POKEDEX_PAGE,
|
||||
newSpecies,
|
||||
this.savedStarterAttributes,
|
||||
this.savedStarterPreferences,
|
||||
this.filteredIndices,
|
||||
);
|
||||
});
|
||||
@ -2283,49 +2293,9 @@ export class PokedexPageUiHandler extends MessageUiHandler {
|
||||
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;
|
||||
const starterPreferences: StarterPreferences | null = species ? { ...this.starterPreferences } : null;
|
||||
|
||||
if (!species && globalScene.ui.getTooltip().visible) {
|
||||
globalScene.ui.hideTooltip();
|
||||
@ -2347,17 +2317,17 @@ export class PokedexPageUiHandler extends MessageUiHandler {
|
||||
|
||||
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) && props.shiny) {
|
||||
props.variant = starterAttributes.variant as Variant;
|
||||
// Set default attributes if for some reason starterPreferences does not exist or attributes missing
|
||||
const props: StarterPreferences = globalScene.gameData.getSpeciesDexAttrProps(species, defaultDexAttr);
|
||||
if (starterPreferences?.variant && !Number.isNaN(starterPreferences.variant) && props.shiny) {
|
||||
props.variant = starterPreferences.variant as Variant;
|
||||
}
|
||||
props.form = starterAttributes?.form ?? props.form;
|
||||
props.female = starterAttributes?.female ?? props.female;
|
||||
props.formIndex = starterPreferences?.formIndex ?? props.formIndex;
|
||||
props.female = starterPreferences?.female ?? props.female;
|
||||
|
||||
this.setSpeciesDetails(species, {
|
||||
shiny: props.shiny,
|
||||
formIndex: props.form,
|
||||
formIndex: props.formIndex,
|
||||
female: props.female,
|
||||
variant: props.variant ?? 0,
|
||||
});
|
||||
@ -2419,7 +2389,7 @@ export class PokedexPageUiHandler extends MessageUiHandler {
|
||||
|
||||
setSpeciesDetails(species: PokemonSpecies, options: SpeciesDetails = {}, forceUpdate?: boolean): void {
|
||||
let { shiny, formIndex, female, variant } = options;
|
||||
const oldProps = species ? this.starterAttributes : null;
|
||||
const oldProps = species ? this.starterPreferences : null;
|
||||
|
||||
// We will only update the sprite if there is a change to form, shiny/variant
|
||||
// or gender for species with gender sprite differences
|
||||
@ -2455,7 +2425,7 @@ export class PokedexPageUiHandler extends MessageUiHandler {
|
||||
variant = oldProps?.variant ?? 0;
|
||||
}
|
||||
if (formIndex === undefined) {
|
||||
formIndex = oldProps?.form ?? 0;
|
||||
formIndex = oldProps?.formIndex ?? 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2470,13 +2440,13 @@ export class PokedexPageUiHandler extends MessageUiHandler {
|
||||
const caughtAttr = this.isCaught(species);
|
||||
|
||||
if (!caughtAttr) {
|
||||
const props = this.starterAttributes;
|
||||
const props = this.starterPreferences;
|
||||
|
||||
if (shiny === undefined || shiny !== props.shiny) {
|
||||
shiny = props.shiny;
|
||||
}
|
||||
if (formIndex === undefined || formIndex !== props.form) {
|
||||
formIndex = props.form;
|
||||
if (formIndex === undefined || formIndex !== props.formIndex) {
|
||||
formIndex = props.formIndex;
|
||||
}
|
||||
if (female === undefined || female !== props.female) {
|
||||
female = props.female;
|
||||
@ -2727,7 +2697,7 @@ export class PokedexPageUiHandler extends MessageUiHandler {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a temporary dex attr props that will be used to display the correct shiny, variant, and form based on this.starterAttributes
|
||||
* Creates a temporary dex attr props that will be used to display the correct shiny, variant, and form based on this.starterPreferences
|
||||
*
|
||||
* @param speciesId the id of the species to get props for
|
||||
* @returns the dex props
|
||||
@ -2744,7 +2714,7 @@ export class PokedexPageUiHandler extends MessageUiHandler {
|
||||
* 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)) {
|
||||
if (this.starterPreferences?.female || ((caughtAttr & DexAttr.FEMALE) > 0n && (caughtAttr & DexAttr.MALE) === 0n)) {
|
||||
props += DexAttr.FEMALE;
|
||||
} else {
|
||||
props += DexAttr.MALE;
|
||||
@ -2753,12 +2723,12 @@ export class PokedexPageUiHandler extends MessageUiHandler {
|
||||
* 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)
|
||||
this.starterPreferences?.shiny
|
||||
|| ((caughtAttr & DexAttr.SHINY) > 0n && this.starterPreferences?.shiny !== false)
|
||||
) {
|
||||
props += DexAttr.SHINY;
|
||||
if (this.starterAttributes?.variant !== undefined) {
|
||||
props += BigInt(Math.pow(2, this.starterAttributes?.variant)) * DexAttr.DEFAULT_VARIANT;
|
||||
if (this.starterPreferences?.variant !== undefined) {
|
||||
props += BigInt(Math.pow(2, this.starterPreferences?.variant)) * DexAttr.DEFAULT_VARIANT;
|
||||
/* This chunk calculates the correct variant if there's no starter preferences for it.
|
||||
* This gets the highest tier variant that you've caught and adds it to the temp props
|
||||
*/
|
||||
@ -2773,9 +2743,9 @@ export class PokedexPageUiHandler extends MessageUiHandler {
|
||||
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) {
|
||||
if (this.starterPreferences?.formIndex) {
|
||||
// this checks for the form of the pokemon
|
||||
props += BigInt(Math.pow(2, this.starterAttributes?.form)) * DexAttr.DEFAULT_FORM;
|
||||
props += BigInt(Math.pow(2, this.starterPreferences?.formIndex)) * DexAttr.DEFAULT_FORM;
|
||||
} else {
|
||||
// Get the first unlocked form
|
||||
props += globalScene.gameData.getFormAttr(globalScene.gameData.getFormIndex(caughtAttr));
|
||||
|
@ -4,14 +4,7 @@ import { catchableSpecies } from "#balance/biomes";
|
||||
import { speciesEggMoves } from "#balance/egg-moves";
|
||||
import { pokemonStarters } from "#balance/pokemon-evolutions";
|
||||
import { pokemonFormLevelMoves, pokemonSpeciesLevelMoves } from "#balance/pokemon-level-moves";
|
||||
import {
|
||||
getPassiveCandyCount,
|
||||
getSameSpeciesEggCandyCounts,
|
||||
getStarterValueFriendshipCap,
|
||||
getValueReductionCandyCounts,
|
||||
POKERUS_STARTER_COUNT,
|
||||
speciesStarterCosts,
|
||||
} from "#balance/starters";
|
||||
import { getStarterValueFriendshipCap, POKERUS_STARTER_COUNT, speciesStarterCosts } from "#balance/starters";
|
||||
import { speciesTmMoves } from "#balance/tms";
|
||||
import { allAbilities, allMoves, allSpecies } from "#data/data-lists";
|
||||
import type { PokemonForm, PokemonSpecies } from "#data/pokemon-species";
|
||||
@ -23,7 +16,6 @@ import { Button } from "#enums/buttons";
|
||||
import { DexAttr } from "#enums/dex-attr";
|
||||
import { DropDownColumn } from "#enums/drop-down-column";
|
||||
import type { Nature } from "#enums/nature";
|
||||
import { Passive as PassiveAttr } from "#enums/passive";
|
||||
import { PokemonType } from "#enums/pokemon-type";
|
||||
import type { SpeciesId } from "#enums/species-id";
|
||||
import { TextStyle } from "#enums/text-style";
|
||||
@ -33,7 +25,7 @@ import type { Variant } from "#sprites/variant";
|
||||
import { getVariantIcon, getVariantTint } from "#sprites/variant";
|
||||
import { SettingKeyboard } from "#system/settings-keyboard";
|
||||
import type { DexEntry } from "#types/dex-data";
|
||||
import type { DexAttrProps, StarterAttributes } from "#types/save-data";
|
||||
import type { DexAttrProps, StarterPreferences } from "#types/save-data";
|
||||
import type { OptionSelectConfig } from "#ui/abstract-option-select-ui-handler";
|
||||
import { DropDown, DropDownLabel, DropDownOption, DropDownState, DropDownType, SortCriteria } from "#ui/dropdown";
|
||||
import { FilterBar } from "#ui/filter-bar";
|
||||
@ -45,12 +37,17 @@ import { ScrollBar } from "#ui/scroll-bar";
|
||||
import { addTextObject, getTextColor } from "#ui/text";
|
||||
import { addWindow } from "#ui/ui-theme";
|
||||
import { BooleanHolder, fixedInt, getLocalizedSpriteKey, padInt, randIntRange, rgbHexToRgba } from "#utils/common";
|
||||
import type { StarterPreferences } from "#utils/data";
|
||||
import type { AllStarterPreferences } from "#utils/data";
|
||||
import { loadStarterPreferences } from "#utils/data";
|
||||
import { getPokemonSpeciesForm, getPokerusStarters } from "#utils/pokemon-utils";
|
||||
import { toCamelCase } from "#utils/strings";
|
||||
import { argbFromRgba } from "@material/material-color-utilities";
|
||||
import i18next from "i18next";
|
||||
import {
|
||||
isPassiveAvailable,
|
||||
isSameSpeciesEggAvailable,
|
||||
isValueReductionAvailable,
|
||||
} from "../utils/starter-select-ui-utils";
|
||||
|
||||
interface LanguageSetting {
|
||||
starterInfoTextSize: string;
|
||||
@ -131,8 +128,6 @@ interface ContainerData {
|
||||
passive2?: boolean;
|
||||
}
|
||||
|
||||
const valueReductionMax = 2;
|
||||
|
||||
// Position of UI elements
|
||||
const filterBarHeight = 17;
|
||||
const speciesContainerX = 143;
|
||||
@ -193,7 +188,7 @@ export class PokedexUiHandler extends MessageUiHandler {
|
||||
|
||||
private iconAnimHandler: PokemonIconAnimHelper;
|
||||
|
||||
private starterPreferences: StarterPreferences;
|
||||
private starterPreferences: AllStarterPreferences;
|
||||
|
||||
protected blockInput = false;
|
||||
|
||||
@ -681,15 +676,15 @@ export class PokedexUiHandler extends MessageUiHandler {
|
||||
* 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
|
||||
* @returns StarterPreferences for the species
|
||||
*/
|
||||
initStarterPrefs(species: PokemonSpecies): StarterAttributes {
|
||||
const starterAttributes = this.starterPreferences[species.speciesId];
|
||||
initStarterPrefs(species: PokemonSpecies): StarterPreferences {
|
||||
const starterPreferences = this.starterPreferences[species.speciesId];
|
||||
const dexEntry = globalScene.gameData.dexData[species.speciesId];
|
||||
const starterData = globalScene.gameData.starterData[species.speciesId];
|
||||
|
||||
// no preferences or Pokemon wasn't caught, return empty attribute
|
||||
if (!starterAttributes || !dexEntry.caughtAttr) {
|
||||
if (!starterPreferences || !dexEntry.caughtAttr) {
|
||||
return {};
|
||||
}
|
||||
|
||||
@ -697,41 +692,41 @@ export class PokedexUiHandler extends MessageUiHandler {
|
||||
|
||||
const hasShiny = caughtAttr & DexAttr.SHINY;
|
||||
const hasNonShiny = caughtAttr & DexAttr.NON_SHINY;
|
||||
if (starterAttributes.shiny && !hasShiny) {
|
||||
if (starterPreferences.shiny && !hasShiny) {
|
||||
// shiny form wasn't unlocked, purging shiny and variant setting
|
||||
|
||||
starterAttributes.shiny = undefined;
|
||||
starterAttributes.variant = undefined;
|
||||
} else if (starterAttributes.shiny === false && !hasNonShiny) {
|
||||
starterPreferences.shiny = undefined;
|
||||
starterPreferences.variant = undefined;
|
||||
} else if (starterPreferences.shiny === false && !hasNonShiny) {
|
||||
// non shiny form wasn't unlocked, purging shiny setting
|
||||
starterAttributes.shiny = undefined;
|
||||
starterPreferences.shiny = undefined;
|
||||
}
|
||||
|
||||
if (starterAttributes.variant !== undefined) {
|
||||
if (starterPreferences.variant !== undefined) {
|
||||
const unlockedVariants = [
|
||||
hasShiny && caughtAttr & DexAttr.DEFAULT_VARIANT,
|
||||
hasShiny && caughtAttr & DexAttr.VARIANT_2,
|
||||
hasShiny && caughtAttr & DexAttr.VARIANT_3,
|
||||
];
|
||||
if (
|
||||
Number.isNaN(starterAttributes.variant)
|
||||
|| starterAttributes.variant < 0
|
||||
|| !unlockedVariants[starterAttributes.variant]
|
||||
Number.isNaN(starterPreferences.variant)
|
||||
|| starterPreferences.variant < 0
|
||||
|| !unlockedVariants[starterPreferences.variant]
|
||||
) {
|
||||
// variant value is invalid or requested variant wasn't unlocked, purging setting
|
||||
starterAttributes.variant = undefined;
|
||||
starterPreferences.variant = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
starterAttributes.female !== undefined
|
||||
&& !(starterAttributes.female ? caughtAttr & DexAttr.FEMALE : caughtAttr & DexAttr.MALE)
|
||||
starterPreferences.female !== undefined
|
||||
&& !(starterPreferences.female ? caughtAttr & DexAttr.FEMALE : caughtAttr & DexAttr.MALE)
|
||||
) {
|
||||
// requested gender wasn't unlocked, purging setting
|
||||
starterAttributes.female = undefined;
|
||||
starterPreferences.female = undefined;
|
||||
}
|
||||
|
||||
if (starterAttributes.ability !== undefined) {
|
||||
if (starterPreferences.abilityIndex !== undefined) {
|
||||
const speciesHasSingleAbility = species.ability2 === species.ability1;
|
||||
const abilityAttr = starterData.abilityAttr;
|
||||
const hasAbility1 = abilityAttr & AbilityAttr.ABILITY_1;
|
||||
@ -744,31 +739,31 @@ export class PokedexUiHandler extends MessageUiHandler {
|
||||
speciesHasSingleAbility ? hasAbility2 && !hasAbility1 : hasAbility2,
|
||||
hasHiddenAbility,
|
||||
];
|
||||
if (!unlockedAbilities[starterAttributes.ability]) {
|
||||
if (!unlockedAbilities[starterPreferences.abilityIndex]) {
|
||||
// requested ability wasn't unlocked, purging setting
|
||||
starterAttributes.ability = undefined;
|
||||
starterPreferences.abilityIndex = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
const selectedForm = starterAttributes.form;
|
||||
const selectedForm = starterPreferences.formIndex;
|
||||
if (
|
||||
selectedForm !== undefined
|
||||
&& (!species.forms[selectedForm]?.isStarterSelectable
|
||||
|| !(caughtAttr & globalScene.gameData.getFormAttr(selectedForm)))
|
||||
) {
|
||||
// requested form wasn't unlocked/isn't a starter form, purging setting
|
||||
starterAttributes.form = undefined;
|
||||
starterPreferences.formIndex = undefined;
|
||||
}
|
||||
|
||||
if (starterAttributes.nature !== undefined) {
|
||||
if (starterPreferences.nature !== undefined) {
|
||||
const unlockedNatures = globalScene.gameData.getNaturesForAttr(dexEntry.natureAttr);
|
||||
if (unlockedNatures.indexOf(starterAttributes.nature as unknown as Nature) < 0) {
|
||||
if (unlockedNatures.indexOf(starterPreferences.nature as unknown as Nature) < 0) {
|
||||
// requested nature wasn't unlocked, purging setting
|
||||
starterAttributes.nature = undefined;
|
||||
starterPreferences.nature = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
return starterAttributes;
|
||||
return starterPreferences;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -844,52 +839,6 @@ export class PokedexUiHandler extends MessageUiHandler {
|
||||
return pokemonStarters[speciesId];
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if a passive upgrade is available for the given species ID
|
||||
* @param speciesId The ID of the species to check the passive of
|
||||
* @returns true if the user has enough candies and a passive has not been unlocked already
|
||||
*/
|
||||
isPassiveAvailable(speciesId: number): boolean {
|
||||
// Get this species ID's starter data
|
||||
const starterData = globalScene.gameData.starterData[this.getStarterSpeciesId(speciesId)];
|
||||
|
||||
return (
|
||||
starterData.candyCount >= getPassiveCandyCount(speciesStarterCosts[this.getStarterSpeciesId(speciesId)])
|
||||
&& !(starterData.passiveAttr & PassiveAttr.UNLOCKED)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if a value reduction upgrade is available for the given species ID
|
||||
* @param speciesId The ID of the species to check the value reduction of
|
||||
* @returns true if the user has enough candies and all value reductions have not been unlocked already
|
||||
*/
|
||||
isValueReductionAvailable(speciesId: number): boolean {
|
||||
// Get this species ID's starter data
|
||||
const starterData = globalScene.gameData.starterData[this.getStarterSpeciesId(speciesId)];
|
||||
|
||||
return (
|
||||
starterData.candyCount
|
||||
>= getValueReductionCandyCounts(speciesStarterCosts[this.getStarterSpeciesId(speciesId)])[
|
||||
starterData.valueReduction
|
||||
] && starterData.valueReduction < valueReductionMax
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if an same species egg can be bought for the given species ID
|
||||
* @param speciesId The ID of the species to check the value reduction of
|
||||
* @returns true if the user has enough candies
|
||||
*/
|
||||
isSameSpeciesEggAvailable(speciesId: number): boolean {
|
||||
// Get this species ID's starter data
|
||||
const starterData = globalScene.gameData.starterData[this.getStarterSpeciesId(speciesId)];
|
||||
|
||||
return (
|
||||
starterData.candyCount >= getSameSpeciesEggCandyCounts(speciesStarterCosts[this.getStarterSpeciesId(speciesId)])
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a bounce animation if enabled and the Pokemon has an upgrade
|
||||
* @param icon {@linkcode Phaser.GameObjects.GameObject} to animate
|
||||
@ -931,9 +880,9 @@ export class PokedexUiHandler extends MessageUiHandler {
|
||||
};
|
||||
|
||||
if (
|
||||
this.isPassiveAvailable(species.speciesId)
|
||||
isPassiveAvailable(species.speciesId)
|
||||
|| (globalScene.candyUpgradeNotification === 2
|
||||
&& (this.isValueReductionAvailable(species.speciesId) || this.isSameSpeciesEggAvailable(species.speciesId)))
|
||||
&& (isValueReductionAvailable(species.speciesId) || isSameSpeciesEggAvailable(species.speciesId)))
|
||||
) {
|
||||
const chain = globalScene.tweens.chain(tweenChain);
|
||||
if (!startPaused) {
|
||||
@ -959,19 +908,19 @@ export class PokedexUiHandler extends MessageUiHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
const isPassiveAvailable = this.isPassiveAvailable(species.speciesId);
|
||||
const isValueReductionAvailable = this.isValueReductionAvailable(species.speciesId);
|
||||
const isSameSpeciesEggAvailable = this.isSameSpeciesEggAvailable(species.speciesId);
|
||||
const passiveAvailable = isPassiveAvailable(species.speciesId);
|
||||
const valueReductionAvailable = isValueReductionAvailable(species.speciesId);
|
||||
const sameSpeciesEggAvailable = isSameSpeciesEggAvailable(species.speciesId);
|
||||
|
||||
// 'Passive Only' mode
|
||||
if (globalScene.candyUpgradeNotification === 1) {
|
||||
starter.candyUpgradeIcon.setVisible(slotVisible && isPassiveAvailable);
|
||||
starter.candyUpgradeIcon.setVisible(slotVisible && passiveAvailable);
|
||||
starter.candyUpgradeOverlayIcon.setVisible(slotVisible && starter.candyUpgradeIcon.visible);
|
||||
|
||||
// 'On' mode
|
||||
} else if (globalScene.candyUpgradeNotification === 2) {
|
||||
starter.candyUpgradeIcon.setVisible(
|
||||
slotVisible && (isPassiveAvailable || isValueReductionAvailable || isSameSpeciesEggAvailable),
|
||||
slotVisible && (passiveAvailable || valueReductionAvailable || sameSpeciesEggAvailable),
|
||||
);
|
||||
starter.candyUpgradeOverlayIcon.setVisible(slotVisible && starter.candyUpgradeIcon.visible);
|
||||
}
|
||||
@ -1533,7 +1482,7 @@ export class PokedexUiHandler extends MessageUiHandler {
|
||||
|
||||
// Passive Filter
|
||||
const isPassiveUnlocked = starterData.passiveAttr > 0;
|
||||
const isPassiveUnlockable = this.isPassiveAvailable(species.speciesId) && !isPassiveUnlocked;
|
||||
const isPassiveUnlockable = isPassiveAvailable(species.speciesId) && !isPassiveUnlocked;
|
||||
const fitsPassive = this.filterBar.getVals(DropDownColumn.UNLOCKS).some(unlocks => {
|
||||
if (unlocks.val === "PASSIVE" && unlocks.state === DropDownState.ON) {
|
||||
return isPassiveUnlocked;
|
||||
@ -1552,7 +1501,7 @@ export class PokedexUiHandler extends MessageUiHandler {
|
||||
// Cost Reduction Filter
|
||||
const isCostReducedByOne = starterData.valueReduction === 1;
|
||||
const isCostReducedByTwo = starterData.valueReduction === 2;
|
||||
const isCostReductionUnlockable = this.isValueReductionAvailable(species.speciesId);
|
||||
const isCostReductionUnlockable = isValueReductionAvailable(species.speciesId);
|
||||
const fitsCostReduction = this.filterBar.getVals(DropDownColumn.UNLOCKS).some(unlocks => {
|
||||
if (unlocks.val === "COST_REDUCTION" && unlocks.state === DropDownState.ON) {
|
||||
return isCostReducedByOne || isCostReducedByTwo;
|
||||
@ -1664,7 +1613,7 @@ export class PokedexUiHandler extends MessageUiHandler {
|
||||
});
|
||||
|
||||
// Egg Purchasable Filter
|
||||
const isEggPurchasable = this.isSameSpeciesEggAvailable(species.speciesId);
|
||||
const isEggPurchasable = isSameSpeciesEggAvailable(species.speciesId);
|
||||
const fitsEgg = this.filterBar.getVals(DropDownColumn.MISC).some(misc => {
|
||||
if (misc.val === "EGG" && misc.state === DropDownState.ON) {
|
||||
return isEggPurchasable;
|
||||
@ -2347,7 +2296,7 @@ export class PokedexUiHandler extends MessageUiHandler {
|
||||
|
||||
/**
|
||||
* Creates a temporary dex attr props that will be used to
|
||||
* display the correct shiny, variant, and form based on the StarterPreferences
|
||||
* display the correct shiny, variant, and form based on the AllStarterPreferences
|
||||
*
|
||||
* @param speciesId the id of the species to get props for
|
||||
* @returns the dex props
|
||||
@ -2396,9 +2345,9 @@ export class PokedexUiHandler extends MessageUiHandler {
|
||||
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.starterPreferences[speciesId]?.form) {
|
||||
if (this.starterPreferences[speciesId]?.formIndex) {
|
||||
// this checks for the form of the pokemon
|
||||
props += BigInt(Math.pow(2, this.starterPreferences[speciesId]?.form)) * DexAttr.DEFAULT_FORM;
|
||||
props += BigInt(Math.pow(2, this.starterPreferences[speciesId]?.formIndex)) * DexAttr.DEFAULT_FORM;
|
||||
} else {
|
||||
// Get the first unlocked form
|
||||
props += globalScene.gameData.getFormAttr(globalScene.gameData.getFormIndex(caughtAttr));
|
||||
|
File diff suppressed because it is too large
Load Diff
351
src/ui/utils/starter-select-ui-utils.ts
Normal file
351
src/ui/utils/starter-select-ui-utils.ts
Normal file
@ -0,0 +1,351 @@
|
||||
import { VALUE_REDUCTION_MAX } from "#app/constants";
|
||||
import { globalScene } from "#app/global-scene";
|
||||
import {
|
||||
getPassiveCandyCount,
|
||||
getSameSpeciesEggCandyCounts,
|
||||
getStarterValueFriendshipCap,
|
||||
getValueReductionCandyCounts,
|
||||
speciesStarterCosts,
|
||||
} from "#balance/starters";
|
||||
import type { PokemonSpecies } from "#data/pokemon-species";
|
||||
import { ChallengeType } from "#enums/challenge-type";
|
||||
import { DexAttr } from "#enums/dex-attr";
|
||||
import { GameModes } from "#enums/game-modes";
|
||||
import { Passive } from "#enums/passive";
|
||||
import type { PokemonType } from "#enums/pokemon-type";
|
||||
import type { SpeciesId } from "#enums/species-id";
|
||||
import type { Variant } from "#sprites/variant";
|
||||
import type { DexEntry } from "#types/dex-data";
|
||||
import type { DexAttrProps, StarterDataEntry, StarterPreferences } from "#types/save-data";
|
||||
import { applyChallenges, checkStarterValidForChallenge } from "#utils/challenge-utils";
|
||||
import { NumberHolder } from "#utils/common";
|
||||
import i18next from "i18next";
|
||||
|
||||
export interface SpeciesDetails {
|
||||
shiny?: boolean;
|
||||
formIndex?: number;
|
||||
female?: boolean;
|
||||
variant?: Variant;
|
||||
abilityIndex?: number;
|
||||
natureIndex?: number;
|
||||
teraType?: PokemonType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if a passive upgrade is available for the given species ID
|
||||
* @param speciesId The ID of the species to check the passive of
|
||||
* @returns true if the user has enough candies and a passive has not been unlocked already
|
||||
*/
|
||||
export function isPassiveAvailable(speciesId: number): boolean {
|
||||
// Get this species ID's starter data
|
||||
const starterData = globalScene.gameData.starterData[speciesId];
|
||||
|
||||
return (
|
||||
starterData.candyCount >= getPassiveCandyCount(speciesStarterCosts[speciesId])
|
||||
&& !(starterData.passiveAttr & Passive.UNLOCKED)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if a value reduction upgrade is available for the given species ID
|
||||
* @param speciesId The ID of the species to check the value reduction of
|
||||
* @returns true if the user has enough candies and all value reductions have not been unlocked already
|
||||
*/
|
||||
export function isValueReductionAvailable(speciesId: number): boolean {
|
||||
// Get this species ID's starter data
|
||||
const starterData = globalScene.gameData.starterData[speciesId];
|
||||
|
||||
return (
|
||||
starterData.candyCount >= getValueReductionCandyCounts(speciesStarterCosts[speciesId])[starterData.valueReduction]
|
||||
&& starterData.valueReduction < VALUE_REDUCTION_MAX
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if an same species egg can be bought for the given species ID
|
||||
* @param speciesId The ID of the species to check the value reduction of
|
||||
* @returns true if the user has enough candies
|
||||
*/
|
||||
export function isSameSpeciesEggAvailable(speciesId: number): boolean {
|
||||
// Get this species ID's starter data
|
||||
const starterData = globalScene.gameData.starterData[speciesId];
|
||||
|
||||
return starterData.candyCount >= getSameSpeciesEggCandyCounts(speciesStarterCosts[speciesId]);
|
||||
}
|
||||
|
||||
export function isStarterValidForChallenge(species: PokemonSpecies) {
|
||||
let allFormsValid = false;
|
||||
if (species.forms?.length > 0) {
|
||||
for (let i = 0; i < species.forms.length; i++) {
|
||||
/* Here we are making a fake form index dex props for challenges
|
||||
* Since some pokemon rely on forms to be valid (i.e. blaze tauros for fire challenges), we make a fake form and dex props to use in the challenge
|
||||
*/
|
||||
if (!species.forms[i].isStarterSelectable) {
|
||||
continue;
|
||||
}
|
||||
const tempFormProps = BigInt(Math.pow(2, i)) * DexAttr.DEFAULT_FORM;
|
||||
const isValidForChallenge = checkStarterValidForChallenge(
|
||||
species,
|
||||
globalScene.gameData.getSpeciesDexAttrProps(species, tempFormProps),
|
||||
true,
|
||||
);
|
||||
allFormsValid ||= isValidForChallenge;
|
||||
}
|
||||
} else {
|
||||
const isValidForChallenge = checkStarterValidForChallenge(
|
||||
species,
|
||||
globalScene.gameData.getSpeciesDexAttrProps(
|
||||
species,
|
||||
globalScene.gameData.getSpeciesDefaultDexAttr(species, false, true),
|
||||
),
|
||||
true,
|
||||
);
|
||||
allFormsValid = isValidForChallenge;
|
||||
}
|
||||
|
||||
return allFormsValid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if 'Icon' based upgrade notifications should be shown
|
||||
* @returns true if upgrade notifications are enabled and set to display an 'Icon'
|
||||
*/
|
||||
export function 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'
|
||||
*/
|
||||
export function isUpgradeAnimationEnabled(): boolean {
|
||||
return globalScene.candyUpgradeNotification !== 0 && globalScene.candyUpgradeDisplay === 1;
|
||||
}
|
||||
|
||||
interface StarterSelectLanguageSetting {
|
||||
starterInfoTextSize: string;
|
||||
instructionTextSize: string;
|
||||
starterInfoXPos?: number;
|
||||
starterInfoYOffset?: number;
|
||||
}
|
||||
|
||||
const languageSettings: { [key: string]: StarterSelectLanguageSetting } = {
|
||||
en: {
|
||||
starterInfoTextSize: "56px",
|
||||
instructionTextSize: "38px",
|
||||
},
|
||||
de: {
|
||||
starterInfoTextSize: "54px",
|
||||
instructionTextSize: "35px",
|
||||
starterInfoXPos: 35,
|
||||
},
|
||||
"es-ES": {
|
||||
starterInfoTextSize: "50px",
|
||||
instructionTextSize: "38px",
|
||||
starterInfoYOffset: 0.5,
|
||||
starterInfoXPos: 38,
|
||||
},
|
||||
"es-419": {
|
||||
starterInfoTextSize: "50px",
|
||||
instructionTextSize: "38px",
|
||||
starterInfoYOffset: 0.5,
|
||||
starterInfoXPos: 38,
|
||||
},
|
||||
fr: {
|
||||
starterInfoTextSize: "54px",
|
||||
instructionTextSize: "38px",
|
||||
},
|
||||
it: {
|
||||
starterInfoTextSize: "56px",
|
||||
instructionTextSize: "38px",
|
||||
},
|
||||
"pt-BR": {
|
||||
starterInfoTextSize: "48px",
|
||||
instructionTextSize: "42px",
|
||||
starterInfoYOffset: 0.5,
|
||||
starterInfoXPos: 33,
|
||||
},
|
||||
zh: {
|
||||
starterInfoTextSize: "56px",
|
||||
instructionTextSize: "36px",
|
||||
starterInfoXPos: 26,
|
||||
},
|
||||
ko: {
|
||||
starterInfoTextSize: "60px",
|
||||
instructionTextSize: "38px",
|
||||
starterInfoYOffset: -0.5,
|
||||
starterInfoXPos: 30,
|
||||
},
|
||||
ja: {
|
||||
starterInfoTextSize: "48px",
|
||||
instructionTextSize: "40px",
|
||||
starterInfoYOffset: 1,
|
||||
starterInfoXPos: 32,
|
||||
},
|
||||
ca: {
|
||||
starterInfoTextSize: "48px",
|
||||
instructionTextSize: "38px",
|
||||
starterInfoYOffset: 0.5,
|
||||
starterInfoXPos: 29,
|
||||
},
|
||||
da: {
|
||||
starterInfoTextSize: "56px",
|
||||
instructionTextSize: "38px",
|
||||
},
|
||||
tr: {
|
||||
starterInfoTextSize: "56px",
|
||||
instructionTextSize: "38px",
|
||||
},
|
||||
ro: {
|
||||
starterInfoTextSize: "56px",
|
||||
instructionTextSize: "38px",
|
||||
},
|
||||
ru: {
|
||||
starterInfoTextSize: "46px",
|
||||
instructionTextSize: "38px",
|
||||
starterInfoYOffset: 0.5,
|
||||
starterInfoXPos: 26,
|
||||
},
|
||||
tl: {
|
||||
starterInfoTextSize: "56px",
|
||||
instructionTextSize: "38px",
|
||||
},
|
||||
};
|
||||
|
||||
export function getStarterSelectTextSettings(): StarterSelectLanguageSetting {
|
||||
const currentLanguage = i18next.resolvedLanguage ?? "en";
|
||||
const langSettingKey = Object.keys(languageSettings).find(lang => currentLanguage.includes(lang)) ?? "en";
|
||||
const textSettings = languageSettings[langSettingKey];
|
||||
return textSettings;
|
||||
}
|
||||
|
||||
export function getSpeciesData(
|
||||
speciesId: SpeciesId,
|
||||
applyChallenge = true,
|
||||
): { dexEntry: DexEntry; starterDataEntry: StarterDataEntry } {
|
||||
const dexEntry = globalScene.gameData.dexData[speciesId];
|
||||
const starterDataEntry = globalScene.gameData.starterData[speciesId];
|
||||
|
||||
// Unpacking to make a copy by values, not references
|
||||
const copiedDexEntry = { ...dexEntry };
|
||||
copiedDexEntry.ivs = [...dexEntry.ivs];
|
||||
const copiedStarterDataEntry = { ...starterDataEntry };
|
||||
if (applyChallenge) {
|
||||
applyChallenges(ChallengeType.STARTER_SELECT_MODIFY, speciesId, copiedDexEntry, copiedStarterDataEntry);
|
||||
}
|
||||
return { dexEntry: { ...copiedDexEntry }, starterDataEntry: { ...copiedStarterDataEntry } };
|
||||
}
|
||||
|
||||
export function getFriendship(speciesId: number) {
|
||||
let currentFriendship = globalScene.gameData.starterData[speciesId].friendship;
|
||||
if (!currentFriendship || currentFriendship === undefined) {
|
||||
currentFriendship = 0;
|
||||
}
|
||||
|
||||
const friendshipCap = getStarterValueFriendshipCap(speciesStarterCosts[speciesId]);
|
||||
|
||||
return { currentFriendship, friendshipCap };
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a temporary dex attr props that will be used to check whether a pokemon is valid for a challenge
|
||||
* and to display the correct shiny, variant, and form based on the AllStarterPreferences
|
||||
*
|
||||
* @param speciesId the id of the species to get props for
|
||||
* @returns the dex props
|
||||
*/
|
||||
export function getDexAttrFromPreferences(speciesId: number, starterPreferences: StarterPreferences = {}): bigint {
|
||||
let props = 0n;
|
||||
const { dexEntry } = getSpeciesData(speciesId);
|
||||
const caughtAttr = dexEntry.caughtAttr;
|
||||
|
||||
/* 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 (
|
||||
starterPreferences[speciesId]?.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 (
|
||||
starterPreferences[speciesId]?.shiny
|
||||
|| ((caughtAttr & DexAttr.SHINY) > 0n && starterPreferences[speciesId]?.shiny !== false)
|
||||
) {
|
||||
props += DexAttr.SHINY;
|
||||
if (starterPreferences[speciesId]?.variant !== undefined) {
|
||||
props += BigInt(Math.pow(2, starterPreferences[speciesId]?.variant)) * DexAttr.DEFAULT_VARIANT;
|
||||
} else if ((caughtAttr & DexAttr.VARIANT_3) > 0) {
|
||||
props += DexAttr.VARIANT_3;
|
||||
} else if ((caughtAttr & DexAttr.VARIANT_2) > 0) {
|
||||
props += DexAttr.VARIANT_2;
|
||||
} else {
|
||||
props += DexAttr.DEFAULT_VARIANT;
|
||||
}
|
||||
} else {
|
||||
props += DexAttr.NON_SHINY;
|
||||
props += DexAttr.DEFAULT_VARIANT; // we add the default variant here because non shiny versions are listed as default variant
|
||||
}
|
||||
if (starterPreferences[speciesId]?.form) {
|
||||
// this checks for the form of the pokemon
|
||||
props += BigInt(Math.pow(2, starterPreferences[speciesId]?.form)) * DexAttr.DEFAULT_FORM;
|
||||
} else {
|
||||
// Get the first unlocked form
|
||||
props += globalScene.gameData.getFormAttr(globalScene.gameData.getFormIndex(caughtAttr));
|
||||
}
|
||||
|
||||
return props;
|
||||
}
|
||||
|
||||
export function getSpeciesPropsFromPreferences(
|
||||
species: PokemonSpecies,
|
||||
starterPreferences: StarterPreferences = {},
|
||||
): DexAttrProps {
|
||||
const defaults = globalScene.gameData.getSpeciesDefaultDexAttrProps(species);
|
||||
return {
|
||||
shiny: starterPreferences.shiny != null ? starterPreferences.shiny : defaults.shiny,
|
||||
variant: starterPreferences.variant != null ? (starterPreferences.variant as Variant) : defaults.variant,
|
||||
female: starterPreferences.female ?? defaults.female,
|
||||
formIndex: starterPreferences.formIndex ?? defaults.formIndex,
|
||||
};
|
||||
}
|
||||
|
||||
// TODO: Do we actually need props?
|
||||
export function getSpeciesDetailsFromPreferences(species: PokemonSpecies, starterPreferences: StarterPreferences = {}) {
|
||||
const props = getSpeciesPropsFromPreferences(species, starterPreferences);
|
||||
const abilityIndex =
|
||||
starterPreferences.abilityIndex ?? globalScene.gameData.getStarterSpeciesDefaultAbilityIndex(species);
|
||||
const nature = starterPreferences.nature ?? globalScene.gameData.getSpeciesDefaultNature(species);
|
||||
const teraType = starterPreferences.tera ?? species.type1;
|
||||
return {
|
||||
shiny: props.shiny,
|
||||
formIndex: props.formIndex,
|
||||
female: props.female,
|
||||
variant: props.variant,
|
||||
abilityIndex,
|
||||
natureIndex: nature,
|
||||
teraType,
|
||||
};
|
||||
}
|
||||
|
||||
export function getRunValueLimit(): number {
|
||||
const valueLimit = new NumberHolder(0);
|
||||
switch (globalScene.gameMode.modeId) {
|
||||
case GameModes.ENDLESS:
|
||||
case GameModes.SPLICED_ENDLESS:
|
||||
valueLimit.value = 15;
|
||||
break;
|
||||
default:
|
||||
valueLimit.value = 10;
|
||||
}
|
||||
|
||||
applyChallenges(ChallengeType.STARTER_POINTS, valueLimit);
|
||||
|
||||
return valueLimit.value;
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
import { loggedInUser } from "#app/account";
|
||||
import { saveKey } from "#app/constants";
|
||||
import type { StarterAttributes } from "#types/save-data";
|
||||
import type { StarterPreferences } from "#types/save-data";
|
||||
import { AES, enc } from "crypto-js";
|
||||
|
||||
/**
|
||||
@ -78,19 +78,19 @@ export function isBareObject(obj: any): boolean {
|
||||
const StarterPrefers_DEFAULT: string = "{}";
|
||||
let StarterPrefers_private_latest: string = StarterPrefers_DEFAULT;
|
||||
|
||||
export interface StarterPreferences {
|
||||
[key: number]: StarterAttributes | undefined;
|
||||
export interface AllStarterPreferences {
|
||||
[key: number]: StarterPreferences | undefined;
|
||||
}
|
||||
// called on starter selection show once
|
||||
|
||||
export function loadStarterPreferences(): StarterPreferences {
|
||||
// called on starter selection show once
|
||||
export function loadStarterPreferences(): AllStarterPreferences {
|
||||
return JSON.parse(
|
||||
(StarterPrefers_private_latest =
|
||||
localStorage.getItem(`starterPrefs_${loggedInUser?.username}`) || StarterPrefers_DEFAULT),
|
||||
);
|
||||
}
|
||||
|
||||
export function saveStarterPreferences(prefs: StarterPreferences): void {
|
||||
export function saveStarterPreferences(prefs: AllStarterPreferences): void {
|
||||
// Fastest way to check if an object has any properties (does no allocation)
|
||||
if (isBareObject(prefs)) {
|
||||
console.warn("Refusing to save empty starter preferences");
|
||||
|
@ -7,7 +7,7 @@ import { PokemonType } from "#enums/pokemon-type";
|
||||
import { SpeciesId } from "#enums/species-id";
|
||||
import { UiMode } from "#enums/ui-mode";
|
||||
import { GameManager } from "#test/test-utils/game-manager";
|
||||
import type { StarterAttributes } from "#types/save-data";
|
||||
import type { StarterPreferences } from "#types/save-data";
|
||||
import { FilterTextRow } from "#ui/filter-text";
|
||||
import { PokedexPageUiHandler } from "#ui/pokedex-page-ui-handler";
|
||||
import { PokedexUiHandler } from "#ui/pokedex-ui-handler";
|
||||
@ -84,12 +84,12 @@ describe("UI - Pokedex", () => {
|
||||
*/
|
||||
async function runToPokedexPage(
|
||||
species: PokemonSpecies,
|
||||
starterAttributes: StarterAttributes = {},
|
||||
starterPreferences: StarterPreferences = {},
|
||||
): Promise<PokedexPageUiHandler> {
|
||||
// Open the pokedex UI.
|
||||
await game.runToTitle();
|
||||
|
||||
await game.scene.ui.setOverlayMode(UiMode.POKEDEX_PAGE, species, starterAttributes);
|
||||
await game.scene.ui.setOverlayMode(UiMode.POKEDEX_PAGE, species, starterPreferences);
|
||||
|
||||
// Get the handler for the current UI.
|
||||
const handler = game.scene.ui.getHandler();
|
||||
@ -514,7 +514,7 @@ describe("UI - Pokedex", () => {
|
||||
|
||||
it("should show caught battle form as caught", async () => {
|
||||
await game.importData("./test/test-utils/saves/data_pokedex_tests_v2.prsv");
|
||||
const pageHandler = await runToPokedexPage(getPokemonSpecies(SpeciesId.VENUSAUR), { form: 1 });
|
||||
const pageHandler = await runToPokedexPage(getPokemonSpecies(SpeciesId.VENUSAUR), { formIndex: 1 });
|
||||
|
||||
// @ts-expect-error - `species` is private
|
||||
expect(pageHandler.species.speciesId).toEqual(SpeciesId.VENUSAUR);
|
||||
@ -529,7 +529,7 @@ describe("UI - Pokedex", () => {
|
||||
//TODO: check tint of the sprite
|
||||
it("should show uncaught battle form as seen", async () => {
|
||||
await game.importData("./test/test-utils/saves/data_pokedex_tests_v2.prsv");
|
||||
const pageHandler = await runToPokedexPage(getPokemonSpecies(SpeciesId.VENUSAUR), { form: 2 });
|
||||
const pageHandler = await runToPokedexPage(getPokemonSpecies(SpeciesId.VENUSAUR), { formIndex: 2 });
|
||||
|
||||
// @ts-expect-error - `species` is private
|
||||
expect(pageHandler.species.speciesId).toEqual(SpeciesId.VENUSAUR);
|
||||
|
Loading…
Reference in New Issue
Block a user