From 46d110e705f8ceb957dd67d3743a53f2e478a579 Mon Sep 17 00:00:00 2001 From: Wlowscha <54003515+Wlowscha@users.noreply.github.com> Date: Fri, 28 Mar 2025 04:59:05 +0100 Subject: [PATCH] =?UTF-8?q?[UI/UX]=20Grey=20options=20in=20Pok=C3=A9dex=20?= =?UTF-8?q?for=20uncaught=20mons=20(#5529)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Options in Pokédex page are dark if unselectable * Fixed docstring * Changing display of seen Pokémon in the dex * Changed visibility of icons in main Pokédex page --- src/data/pokemon-species.ts | 2 +- src/ui/pokedex-page-ui-handler.ts | 73 +++++++++++++++++++++++-------- src/ui/pokedex-ui-handler.ts | 17 ++++--- 3 files changed, 68 insertions(+), 24 deletions(-) diff --git a/src/data/pokemon-species.ts b/src/data/pokemon-species.ts index 15c60d28969..eca7d65ac6a 100644 --- a/src/data/pokemon-species.ts +++ b/src/data/pokemon-species.ts @@ -7,7 +7,7 @@ import i18next from "i18next"; import type { AnySound } from "#app/battle-scene"; import { globalScene } from "#app/global-scene"; import type { GameMode } from "#app/game-mode"; -import { DexAttr, type StarterMoveset } from "#app/system/game-data"; +import { DexAttr, DexEntry, type StarterMoveset } from "#app/system/game-data"; import * as Utils from "#app/utils"; import { uncatchableSpecies } from "#app/data/balance/biomes"; import { speciesEggMoves } from "#app/data/balance/egg-moves"; diff --git a/src/ui/pokedex-page-ui-handler.ts b/src/ui/pokedex-page-ui-handler.ts index 8f96f1e44c2..b359c188e0c 100644 --- a/src/ui/pokedex-page-ui-handler.ts +++ b/src/ui/pokedex-page-ui-handler.ts @@ -25,7 +25,7 @@ import { AbilityAttr, DexAttr } from "#app/system/game-data"; import type { OptionSelectItem } from "#app/ui/abstact-option-select-ui-handler"; import MessageUiHandler from "#app/ui/message-ui-handler"; import { StatsContainer } from "#app/ui/stats-container"; -import { TextStyle, addTextObject, getTextStyleOptions } from "#app/ui/text"; +import { TextStyle, addBBCodeTextObject, addTextObject, getTextColor, getTextStyleOptions } from "#app/ui/text"; import { Mode } from "#app/ui/ui"; import { addWindow } from "#app/ui/ui-theme"; import { Egg } from "#app/data/egg"; @@ -63,6 +63,7 @@ import { TimeOfDay } from "#app/enums/time-of-day"; import type { Abilities } from "#app/enums/abilities"; import { BaseStatsOverlay } from "#app/ui/base-stats-overlay"; import { globalScene } from "#app/global-scene"; +import type BBCodeText from "phaser3-rex-plugins/plugins/gameobjects/tagtext/bbcodetext/BBCodeText"; interface LanguageSetting { starterInfoTextSize: string; @@ -250,7 +251,7 @@ export default class PokedexPageUiHandler extends MessageUiHandler { // Menu private menuContainer: Phaser.GameObjects.Container; private menuBg: Phaser.GameObjects.NineSlice; - protected optionSelectText: Phaser.GameObjects.Text; + protected optionSelectText: BBCodeText; private menuOptions: MenuOptions[]; protected scale = 0.1666666667; private menuDescriptions: string[]; @@ -593,14 +594,13 @@ export default class PokedexPageUiHandler extends MessageUiHandler { this.menuOptions = Utils.getEnumKeys(MenuOptions).map(m => Number.parseInt(MenuOptions[m]) as MenuOptions); - this.optionSelectText = addTextObject( + this.optionSelectText = addBBCodeTextObject( 0, 0, this.menuOptions.map(o => `${i18next.t(`pokedexUiHandler:${MenuOptions[o]}`)}`).join("\n"), TextStyle.WINDOW, - { maxLines: this.menuOptions.length }, + { maxLines: this.menuOptions.length, lineSpacing: 12 }, ); - this.optionSelectText.setLineSpacing(12); this.menuDescriptions = [ i18next.t("pokedexUiHandler:showBaseStats"), @@ -623,7 +623,7 @@ export default class PokedexPageUiHandler extends MessageUiHandler { ); this.menuBg.setOrigin(0, 0); - this.optionSelectText.setPositionRelative(this.menuBg, 10 + 24 * this.scale, 6); + this.optionSelectText.setPosition(this.menuBg.x + 10 + 24 * this.scale, this.menuBg.y + 6); this.menuContainer.add(this.menuBg); @@ -704,11 +704,39 @@ export default class PokedexPageUiHandler extends MessageUiHandler { this.setSpecies(); this.updateInstructions(); + this.optionSelectText.setText(this.getMenuText()); + this.setCursor(0); return true; } + getMenuText(): string { + const isSeen = this.isSeen(); + const isStarterCaught = !!this.isCaught(this.getStarterSpecies(this.species)); + + return this.menuOptions + .map(o => { + const label = `${i18next.t(`pokedexUiHandler:${MenuOptions[o]}`)}`; + const isDark = + !isSeen || + (!isStarterCaught && (o === MenuOptions.TOGGLE_IVS || o === MenuOptions.NATURES)) || + (this.tmMoves.length < 1 && o === MenuOptions.TM_MOVES); + const color = getTextColor( + isDark ? TextStyle.SHADOW_TEXT : TextStyle.SETTINGS_VALUE, + false, + globalScene.uiTheme, + ); + const shadow = getTextColor( + isDark ? TextStyle.SHADOW_TEXT : TextStyle.SETTINGS_VALUE, + true, + globalScene.uiTheme, + ); + return `[shadow=${shadow}][color=${color}]${label}[/color][/shadow]`; + }) + .join("\n"); + } + starterSetup(): void { this.evolutions = []; this.prevolutions = []; @@ -904,6 +932,7 @@ export default class PokedexPageUiHandler extends MessageUiHandler { return (dexEntry?.caughtAttr ?? 0n) & (starterDexEntry?.caughtAttr ?? 0n) & species.getFullUnlocksData(); } + /** * Check whether a given form is caught for a given species. * All forms that can be reached through a form change during battle are considered caught and show up in the dex as such. @@ -928,6 +957,14 @@ export default class PokedexPageUiHandler extends MessageUiHandler { return isFormCaught; } + isSeen(): boolean { + if (this.speciesStarterDexEntry?.seenAttr) { + return true; + } + const starterCaughtAttr = this.isCaught(this.getStarterSpecies(this.species)); + return !!starterCaughtAttr; + } + /** * Get the starter attributes for the given PokemonSpecies, after sanitizing them. * If somehow a preference is set for a form, variant, gender, ability or nature @@ -1076,6 +1113,8 @@ export default class PokedexPageUiHandler extends MessageUiHandler { const isCaught = this.isCaught(); const isFormCaught = this.isFormCaught(); + const isSeen = this.isSeen(); + const isStarterCaught = !!this.isCaught(this.getStarterSpecies(this.species)); if (this.blockInputOverlay) { if (button === Button.CANCEL || button === Button.ACTION) { @@ -1130,7 +1169,7 @@ export default class PokedexPageUiHandler extends MessageUiHandler { if (button === Button.ACTION) { switch (this.cursor) { case MenuOptions.BASE_STATS: - if (!isCaught || !isFormCaught) { + if (!isSeen) { error = true; } else { this.blockInput = true; @@ -1150,7 +1189,7 @@ export default class PokedexPageUiHandler extends MessageUiHandler { break; case MenuOptions.LEVEL_MOVES: - if (!isCaught || !isFormCaught) { + if (!isSeen) { error = true; } else { this.blockInput = true; @@ -1208,7 +1247,7 @@ export default class PokedexPageUiHandler extends MessageUiHandler { break; case MenuOptions.EGG_MOVES: - if (!isCaught || !isFormCaught) { + if (!isSeen) { error = true; } else { this.blockInput = true; @@ -1275,7 +1314,7 @@ export default class PokedexPageUiHandler extends MessageUiHandler { break; case MenuOptions.TM_MOVES: - if (!isCaught || !isFormCaught) { + if (!isSeen) { error = true; } else if (this.tmMoves.length < 1) { ui.showText(i18next.t("pokedexUiHandler:noTmMoves")); @@ -1326,7 +1365,7 @@ export default class PokedexPageUiHandler extends MessageUiHandler { break; case MenuOptions.ABILITIES: - if (!isCaught || !isFormCaught) { + if (!isSeen) { error = true; } else { this.blockInput = true; @@ -1414,7 +1453,7 @@ export default class PokedexPageUiHandler extends MessageUiHandler { break; case MenuOptions.BIOMES: - if (!(isCaught || this.speciesStarterDexEntry?.seenAttr)) { + if (!isSeen) { error = true; } else { this.blockInput = true; @@ -1493,7 +1532,7 @@ export default class PokedexPageUiHandler extends MessageUiHandler { break; case MenuOptions.EVOLUTIONS: - if (!isCaught || !isFormCaught) { + if (!isSeen) { error = true; } else { this.blockInput = true; @@ -1677,7 +1716,7 @@ export default class PokedexPageUiHandler extends MessageUiHandler { break; case MenuOptions.TOGGLE_IVS: - if (!isCaught || !isFormCaught) { + if (!isStarterCaught) { error = true; } else { this.toggleStatsMode(); @@ -1687,7 +1726,7 @@ export default class PokedexPageUiHandler extends MessageUiHandler { break; case MenuOptions.NATURES: - if (!isCaught || !isFormCaught) { + if (!isStarterCaught) { error = true; } else { this.blockInput = true; @@ -2392,8 +2431,6 @@ export default class PokedexPageUiHandler extends MessageUiHandler { } if (species) { - const dexEntry = globalScene.gameData.dexData[species.speciesId]; - const caughtAttr = this.isCaught(species); if (!caughtAttr) { @@ -2414,7 +2451,7 @@ export default class PokedexPageUiHandler extends MessageUiHandler { } const isFormCaught = this.isFormCaught(); - const isFormSeen = dexEntry ? (dexEntry.seenAttr & globalScene.gameData.getFormAttr(formIndex ?? 0)) > 0n : false; + const isFormSeen = this.isSeen(); this.shinyOverlay.setVisible(shiny ?? false); // TODO: is false the correct default? this.pokemonNumberText.setColor(this.getTextColor(shiny ? TextStyle.SUMMARY_GOLD : TextStyle.SUMMARY, false)); diff --git a/src/ui/pokedex-ui-handler.ts b/src/ui/pokedex-ui-handler.ts index d55b278a148..198d9606258 100644 --- a/src/ui/pokedex-ui-handler.ts +++ b/src/ui/pokedex-ui-handler.ts @@ -781,6 +781,15 @@ export default class PokedexUiHandler extends MessageUiHandler { this.starterSelectMessageBoxContainer.setVisible(!!text?.length); } + isSeen(species: PokemonSpecies, dexEntry: DexEntry): boolean { + if (dexEntry?.seenAttr) { + return true; + } + + const starterDexEntry = globalScene.gameData.dexData[this.getStarterSpeciesId(species.speciesId)]; + return !!starterDexEntry?.caughtAttr; + } + /** * Determines if 'Icon' based upgrade notifications should be shown * @returns true if upgrade notifications are enabled and set to display an 'Icon' @@ -1740,7 +1749,7 @@ export default class PokedexUiHandler extends MessageUiHandler { if (caughtAttr & data.species.getFullUnlocksData() || globalScene.dexForDevs) { container.icon.clearTint(); - } else if (dexEntry.seenAttr) { + } else if (this.isSeen(data.species, dexEntry)) { container.icon.setTint(0x808080); } else { container.icon.setTint(0); @@ -1931,13 +1940,11 @@ export default class PokedexUiHandler extends MessageUiHandler { const props = this.getSanitizedProps(globalScene.gameData.getSpeciesDexAttrProps(this.lastSpecies, dexAttr)); this.trayContainers = []; + const isFormSeen = this.isSeen(species, dexEntry); this.trayForms.map((f, index) => { const isFormCaught = dexEntry ? (dexEntry.caughtAttr & species.getFullUnlocksData() & globalScene.gameData.getFormAttr(f.formIndex ?? 0)) > 0n : false; - const isFormSeen = dexEntry - ? (dexEntry.seenAttr & globalScene.gameData.getFormAttr(f.formIndex ?? 0)) > 0n - : false; const formContainer = new PokedexMonContainer(species, { formIndex: f.formIndex, female: props.female, @@ -2147,7 +2154,7 @@ export default class PokedexUiHandler extends MessageUiHandler { } const isFormCaught = dexEntry ? (caughtAttr & globalScene.gameData.getFormAttr(formIndex ?? 0)) > 0n : false; - const isFormSeen = dexEntry ? (dexEntry.seenAttr & globalScene.gameData.getFormAttr(formIndex ?? 0)) > 0n : false; + const isFormSeen = this.isSeen(species, dexEntry); const assetLoadCancelled = new BooleanHolder(false); this.assetLoadCancelled = assetLoadCancelled;