Skip to content

Commit be0f3b2

Browse files
authored
[Bug][UI/UX] Dex bug fixes 12 feb (#5307)
* Fixed bug when setting tint of eggs for egg move filter * Form text is properly hidden when going to filters * Displaying level up moves of alternate forms * Offsetting form cycle button when uncaught text is shown * Pokedex buttons now appear on mobile touchpad * Hotfix to prevent "Normal" form to showing the text * Preventing filter texts from showing gibberish * Moving cursor to input text when pressing on filter * Introducing method to get full obtainable unlocks for a given species * Filtering obtainable unlocks in dex * Buying eggs in dex does not crash the game * Shiny icon does not overlap with luck text for evolutions * Shiny is maintained correctly when cycling through different pages * Displacing text elements to avoid overlap for localized form names * Checking starter caughtAttr in addition to pokemon caughtAttr
1 parent 595413e commit be0f3b2

File tree

6 files changed

+127
-47
lines changed

6 files changed

+127
-47
lines changed

index.css

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -164,13 +164,13 @@ input:-internal-autofill-selected {
164164
}
165165

166166
/* Show cycle buttons only on STARTER_SELECT and on touch configuration panel */
167-
#touchControls:not(.config-mode):not([data-ui-mode='STARTER_SELECT']) #apadOpenFilters,
168-
#touchControls:not(.config-mode):not([data-ui-mode='STARTER_SELECT'], [data-ui-mode='RUN_INFO']) #apadCycleForm,
169-
#touchControls:not(.config-mode):not([data-ui-mode='STARTER_SELECT'], [data-ui-mode='RUN_INFO']) #apadCycleShiny,
167+
#touchControls:not(.config-mode):not([data-ui-mode='STARTER_SELECT'], [data-ui-mode='POKEDEX'], [data-ui-mode='POKEDEX_PAGE']) #apadOpenFilters,
168+
#touchControls:not(.config-mode):not([data-ui-mode='STARTER_SELECT'], [data-ui-mode='POKEDEX'], [data-ui-mode='POKEDEX_PAGE'], [data-ui-mode='RUN_INFO']) #apadCycleForm,
169+
#touchControls:not(.config-mode):not([data-ui-mode='STARTER_SELECT'], [data-ui-mode='POKEDEX'], [data-ui-mode='POKEDEX_PAGE'], [data-ui-mode='RUN_INFO']) #apadCycleShiny,
170170
#touchControls:not(.config-mode):not([data-ui-mode='STARTER_SELECT']) #apadCycleNature,
171-
#touchControls:not(.config-mode):not([data-ui-mode='STARTER_SELECT'], [data-ui-mode='RUN_INFO']) #apadCycleAbility,
172-
#touchControls:not(.config-mode):not([data-ui-mode='STARTER_SELECT']) #apadCycleGender,
173-
#touchControls:not(.config-mode):not([data-ui-mode='STARTER_SELECT']) #apadCycleVariant {
171+
#touchControls:not(.config-mode):not([data-ui-mode='STARTER_SELECT'], [data-ui-mode='POKEDEX_PAGE'], [data-ui-mode='RUN_INFO']) #apadCycleAbility,
172+
#touchControls:not(.config-mode):not([data-ui-mode='STARTER_SELECT'], [data-ui-mode='POKEDEX_PAGE']) #apadCycleGender,
173+
#touchControls:not(.config-mode):not([data-ui-mode='STARTER_SELECT'], [data-ui-mode='POKEDEX']) #apadCycleVariant {
174174
display: none;
175175
}
176176

src/data/pokemon-species.ts

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import i18next from "i18next";
77
import type { AnySound } from "#app/battle-scene";
88
import { globalScene } from "#app/global-scene";
99
import type { GameMode } from "#app/game-mode";
10-
import type { StarterMoveset } from "#app/system/game-data";
10+
import { DexAttr, type StarterMoveset } from "#app/system/game-data";
1111
import * as Utils from "#app/utils";
1212
import { uncatchableSpecies } from "#app/data/balance/biomes";
1313
import { speciesEggMoves } from "#app/data/balance/egg-moves";
@@ -32,6 +32,37 @@ export enum Region {
3232
PALDEA
3333
}
3434

35+
// TODO: this is horrible and will need to be removed once a refactor/cleanup of forms is executed.
36+
export const normalForm: Species[] = [
37+
Species.PIKACHU,
38+
Species.RAICHU,
39+
Species.EEVEE,
40+
Species.JOLTEON,
41+
Species.FLAREON,
42+
Species.VAPOREON,
43+
Species.ESPEON,
44+
Species.UMBREON,
45+
Species.LEAFEON,
46+
Species.GLACEON,
47+
Species.SYLVEON,
48+
Species.PICHU,
49+
Species.ROTOM,
50+
Species.DIALGA,
51+
Species.PALKIA,
52+
Species.KYUREM,
53+
Species.GENESECT,
54+
Species.FROAKIE,
55+
Species.FROGADIER,
56+
Species.GRENINJA,
57+
Species.ROCKRUFF,
58+
Species.NECROZMA,
59+
Species.MAGEARNA,
60+
Species.MARSHADOW,
61+
Species.CRAMORANT,
62+
Species.ZARUDE,
63+
Species.CALYREX
64+
];
65+
3566
/**
3667
* Gets the {@linkcode PokemonSpecies} object associated with the {@linkcode Species} enum given
3768
* @param species The species to fetch
@@ -997,6 +1028,33 @@ export default class PokemonSpecies extends PokemonSpeciesForm implements Locali
9971028
? this.forms[formIndex || 0].getFormSpriteKey()
9981029
: "";
9991030
}
1031+
1032+
/**
1033+
* Generates a {@linkcode bigint} corresponding to the maximum unlocks possible for this species,
1034+
* taking into account if the species has a male/female gender, and which variants are implemented.
1035+
* @returns {@linkcode bigint} Maximum unlocks, can be compared with {@linkcode DexEntry.caughtAttr}.
1036+
*/
1037+
getFullUnlocksData(): bigint {
1038+
let caughtAttr: bigint = 0n;
1039+
caughtAttr += DexAttr.NON_SHINY;
1040+
caughtAttr += DexAttr.SHINY;
1041+
if (this.malePercent !== null) {
1042+
if (this.malePercent > 0) {
1043+
caughtAttr += DexAttr.MALE;
1044+
}
1045+
if (this.malePercent < 100) {
1046+
caughtAttr += DexAttr.FEMALE;
1047+
}
1048+
}
1049+
caughtAttr += DexAttr.DEFAULT_VARIANT;
1050+
if (this.hasVariants()) {
1051+
caughtAttr += DexAttr.VARIANT_2;
1052+
caughtAttr += DexAttr.VARIANT_3;
1053+
}
1054+
caughtAttr += DexAttr.DEFAULT_FORM;
1055+
1056+
return caughtAttr;
1057+
}
10001058
}
10011059

10021060
export class PokemonForm extends PokemonSpeciesForm {

src/ui/filter-text.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ export class FilterText extends Phaser.GameObjects.Container {
133133
const handler = ui.getHandler() as AwaitableUiHandler;
134134
handler.tutorialActive = true;
135135
// Switch to the dialog test window
136-
this.selections[index].setText(String(i18next.t(dialogueName)));
136+
this.selections[index].setText( dialogueName === "" ? this.defaultText : String(i18next.t(dialogueName)));
137137
ui.revertMode();
138138
this.onChange();
139139
},

src/ui/pokedex-page-ui-handler.ts

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { pokemonFormChanges } from "#app/data/pokemon-forms";
1616
import type { LevelMoves } from "#app/data/balance/pokemon-level-moves";
1717
import { pokemonFormLevelMoves, pokemonSpeciesLevelMoves } from "#app/data/balance/pokemon-level-moves";
1818
import type PokemonSpecies from "#app/data/pokemon-species";
19-
import { allSpecies, getPokemonSpeciesForm } from "#app/data/pokemon-species";
19+
import { allSpecies, getPokemonSpeciesForm, normalForm } from "#app/data/pokemon-species";
2020
import { getStarterValueFriendshipCap, speciesStarterCosts } from "#app/data/balance/starters";
2121
import { starterPassiveAbilities } from "#app/data/balance/passives";
2222
import { Type } from "#enums/type";
@@ -383,7 +383,7 @@ export default class PokedexPageUiHandler extends MessageUiHandler {
383383
this.pokemonHatchedIcon.setScale(0.8);
384384
this.pokemonCaughtHatchedContainer.add(this.pokemonHatchedIcon);
385385

386-
this.pokemonShinyIcon = globalScene.add.sprite(14, 76, "shiny_icons");
386+
this.pokemonShinyIcon = globalScene.add.sprite(14, 117, "shiny_icons");
387387
this.pokemonShinyIcon.setOrigin(0.15, 0.2);
388388
this.pokemonShinyIcon.setScale(1);
389389
this.pokemonCaughtHatchedContainer.add(this.pokemonShinyIcon);
@@ -601,7 +601,7 @@ export default class PokedexPageUiHandler extends MessageUiHandler {
601601
const form = species.forms[formIndex];
602602

603603
// If this form has a specific set of moves, we get them.
604-
this.levelMoves = (formIndex > 0 && pokemonFormLevelMoves.hasOwnProperty(formIndex)) ? pokemonFormLevelMoves[species.speciesId][formIndex] : pokemonSpeciesLevelMoves[species.speciesId];
604+
this.levelMoves = (formIndex > 0 && pokemonFormLevelMoves.hasOwnProperty(species.speciesId) && pokemonFormLevelMoves[species.speciesId].hasOwnProperty(formIndex)) ? pokemonFormLevelMoves[species.speciesId][formIndex] : pokemonSpeciesLevelMoves[species.speciesId];
605605
this.ability1 = form.ability1;
606606
this.ability2 = (form.ability2 === form.ability1) ? undefined : form.ability2;
607607
this.abilityHidden = (form.abilityHidden === form.ability1) ? undefined : form.abilityHidden;
@@ -741,14 +741,16 @@ export default class PokedexPageUiHandler extends MessageUiHandler {
741741
return biomes;
742742
}
743743

744-
isCaught(otherSpeciesDexEntry?: DexEntry): bigint {
744+
isCaught(otherSpecies?: PokemonSpecies): bigint {
745745
if (globalScene.dexForDevs) {
746746
return 255n;
747747
}
748748

749-
const dexEntry = otherSpeciesDexEntry ? otherSpeciesDexEntry : this.speciesStarterDexEntry;
749+
const species = otherSpecies ? otherSpecies : this.species;
750+
const dexEntry = globalScene.gameData.dexData[species.speciesId];
751+
const starterDexEntry = globalScene.gameData.dexData[this.getStarterSpeciesId(species.speciesId)];
750752

751-
return dexEntry?.caughtAttr ?? 0n;
753+
return (dexEntry?.caughtAttr ?? 0n) & (starterDexEntry?.caughtAttr ?? 0n) & species.getFullUnlocksData();
752754
}
753755
/**
754756
* Check whether a given form is caught for a given species.
@@ -765,11 +767,9 @@ export default class PokedexPageUiHandler extends MessageUiHandler {
765767
}
766768
const species = otherSpecies ? otherSpecies : this.species;
767769
const formIndex = otherFormIndex !== undefined ? otherFormIndex : this.formIndex;
768-
const dexEntry = globalScene.gameData.dexData[species.speciesId];
770+
const caughtAttr = this.isCaught(species);
769771

770-
const isFormCaught = dexEntry ?
771-
(dexEntry.caughtAttr & globalScene.gameData.getFormAttr(formIndex ?? 0)) > 0n
772-
: false;
772+
const isFormCaught = (caughtAttr & globalScene.gameData.getFormAttr(formIndex ?? 0)) > 0n;
773773
return isFormCaught;
774774
}
775775

@@ -783,8 +783,7 @@ export default class PokedexPageUiHandler extends MessageUiHandler {
783783
*/
784784
initStarterPrefs(): StarterAttributes {
785785
const starterAttributes : StarterAttributes | null = this.species ? { ...this.savedStarterAttributes } : null;
786-
const dexEntry = globalScene.gameData.dexData[this.species.speciesId];
787-
const caughtAttr = this.isCaught(dexEntry);
786+
const caughtAttr = this.isCaught();
788787

789788
// no preferences or Pokemon wasn't caught, return empty attribute
790789
if (!starterAttributes || !caughtAttr) {
@@ -1235,7 +1234,7 @@ export default class PokedexPageUiHandler extends MessageUiHandler {
12351234

12361235
case MenuOptions.BIOMES:
12371236

1238-
if (!(this.isCaught() || this.speciesStarterDexEntry?.seenAttr)) {
1237+
if (!(isCaught || this.speciesStarterDexEntry?.seenAttr)) {
12391238
error = true;
12401239
} else {
12411240
this.blockInput = true;
@@ -1372,8 +1371,7 @@ export default class PokedexPageUiHandler extends MessageUiHandler {
13721371
});
13731372
this.evolutions.map(evo => {
13741373
const evoSpecies = allSpecies.find(species => species.speciesId === evo.speciesId);
1375-
const evoSpeciesStarterDexEntry = evoSpecies ? globalScene.gameData.dexData[evoSpecies.speciesId] : undefined;
1376-
const isCaughtEvo = this.isCaught(evoSpeciesStarterDexEntry) ? true : false;
1374+
const isCaughtEvo = this.isCaught(evoSpecies) ? true : false;
13771375
// Attempts to find the formIndex of the evolved species
13781376
const newFormKey = evo.evoFormKey ? evo.evoFormKey : (this.species.forms.length > 0 ? this.species.forms[this.formIndex].formKey : "");
13791377
const matchingForm = evoSpecies?.forms.find(form => form.formKey === newFormKey);
@@ -1535,6 +1533,7 @@ export default class PokedexPageUiHandler extends MessageUiHandler {
15351533
this.pokemonShinyIcon.setVisible(true);
15361534

15371535
starterAttributes.shiny = true;
1536+
this.savedStarterAttributes.shiny = starterAttributes.shiny;
15381537
} else {
15391538
let newVariant = props.variant;
15401539
do {
@@ -1688,7 +1687,7 @@ export default class PokedexPageUiHandler extends MessageUiHandler {
16881687
}
16891688
this.pokemonCandyCountText.setText(`x${starterData.candyCount}`);
16901689

1691-
const egg = new Egg({ scene: globalScene, species: this.species.speciesId, sourceType: EggSourceType.SAME_SPECIES_EGG });
1690+
const egg = new Egg({ scene: globalScene, species: this.starterId, sourceType: EggSourceType.SAME_SPECIES_EGG });
16921691
egg.addEggToGameData();
16931692

16941693
globalScene.gameData.saveSystem().then(success => {
@@ -1856,6 +1855,9 @@ export default class PokedexPageUiHandler extends MessageUiHandler {
18561855
if (this.canCycleGender) {
18571856
this.updateButtonIcon(SettingKeyboard.Button_Cycle_Gender, gamepadType, this.genderIconElement, this.genderLabel);
18581857
}
1858+
} else {
1859+
// Making space for "Uncaught" text
1860+
this.instructionRowY += 8;
18591861
}
18601862
if (this.canCycleForm) {
18611863
this.updateButtonIcon(SettingKeyboard.Button_Cycle_Form, gamepadType, this.formIconElement, this.formLabel);
@@ -2093,7 +2095,7 @@ export default class PokedexPageUiHandler extends MessageUiHandler {
20932095
if (species) {
20942096
const dexEntry = globalScene.gameData.dexData[species.speciesId];
20952097

2096-
const caughtAttr = this.isCaught(dexEntry);
2098+
const caughtAttr = this.isCaught(species);
20972099

20982100
if (!caughtAttr) {
20992101
const props = this.starterAttributes;
@@ -2240,13 +2242,11 @@ export default class PokedexPageUiHandler extends MessageUiHandler {
22402242
this.pokemonCandyContainer.setVisible(true);
22412243

22422244
if (pokemonPrevolutions.hasOwnProperty(species.speciesId)) {
2243-
this.pokemonShinyIcon.setY(135);
22442245
this.pokemonShinyIcon.setFrame(getVariantIcon(variant));
22452246
this.pokemonHatchedIcon.setVisible(false);
22462247
this.pokemonHatchedCountText.setVisible(false);
22472248
this.pokemonFormText.setY(36);
22482249
} else {
2249-
this.pokemonShinyIcon.setY(117);
22502250
this.pokemonHatchedIcon.setVisible(true);
22512251
this.pokemonHatchedCountText.setVisible(true);
22522252
this.pokemonFormText.setY(42);
@@ -2276,7 +2276,12 @@ export default class PokedexPageUiHandler extends MessageUiHandler {
22762276
if (isFormCaught || isFormSeen) {
22772277
const speciesForm = getPokemonSpeciesForm(species.speciesId, formIndex!); // TODO: is the bang correct?
22782278
this.setTypeIcons(speciesForm.type1, speciesForm.type2);
2279-
this.pokemonFormText.setText(species.getFormNameToDisplay(formIndex));
2279+
// TODO: change this once forms are refactored
2280+
if (normalForm.includes(species.speciesId) && !formIndex) {
2281+
this.pokemonFormText.setText("");
2282+
} else {
2283+
this.pokemonFormText.setText(species.getFormNameToDisplay(formIndex));
2284+
}
22802285
this.pokemonFormText.setVisible(true);
22812286
if (!isFormCaught) {
22822287
this.pokemonFormText.setY(18);
@@ -2321,7 +2326,8 @@ export default class PokedexPageUiHandler extends MessageUiHandler {
23212326
*/
23222327
getCurrentDexProps(speciesId: number): bigint {
23232328
let props = 0n;
2324-
const caughtAttr = globalScene.gameData.dexData[speciesId].caughtAttr;
2329+
const species = allSpecies.find(sp => sp.speciesId === speciesId);
2330+
const caughtAttr = globalScene.gameData.dexData[speciesId].caughtAttr & globalScene.gameData.dexData[this.getStarterSpeciesId(speciesId)].caughtAttr & (species?.getFullUnlocksData() ?? 0n);
23252331

23262332
/* 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
23272333
* 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

src/ui/pokedex-scan-ui-handler.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,10 @@ export default class PokedexScanUiHandler extends FormModalUiHandler {
115115

116116
this.reduceKeys();
117117

118+
setTimeout(() => {
119+
input.setFocus(); // Focus after a short delay to avoid unwanted input
120+
}, 50);
121+
118122
input.on("keydown", (inputObject, evt: KeyboardEvent) => {
119123
if ([ "escape", "space" ].some((v) => v === evt.key.toLowerCase() || v === evt.code.toLowerCase()) && ui.getMode() === Mode.AUTO_COMPLETE) {
120124
// Delete autocomplete list and recovery focus.
@@ -169,7 +173,8 @@ export default class PokedexScanUiHandler extends FormModalUiHandler {
169173
this.submitAction = (_) => {
170174
if (ui.getMode() === Mode.POKEDEX_SCAN) {
171175
this.sanitizeInputs();
172-
const sanitizedName = btoa(unescape(encodeURIComponent(this.inputs[0].text)));
176+
const outputName = this.reducedKeys.includes(this.inputs[0].text) ? this.inputs[0].text : "";
177+
const sanitizedName = btoa(unescape(encodeURIComponent(outputName)));
173178
config.buttonActions[0](sanitizedName);
174179
return true;
175180
}

0 commit comments

Comments
 (0)