mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-07-05 16:02:20 +02:00
Compare commits
No commits in common. "aeecb67f32cb1a78b01ad5acd30e22a902143bbe" and "db9434ac11b2735ca31d32f755be84ed838f0e42" have entirely different histories.
aeecb67f32
...
db9434ac11
Binary file not shown.
Before Width: | Height: | Size: 413 B |
@ -7663,12 +7663,6 @@ export function initBiomes() {
|
|||||||
biomeDepths[Biome.TOWN] = [ 0, 1 ];
|
biomeDepths[Biome.TOWN] = [ 0, 1 ];
|
||||||
|
|
||||||
const traverseBiome = (biome: Biome, depth: integer) => {
|
const traverseBiome = (biome: Biome, depth: integer) => {
|
||||||
if (biome === Biome.END) {
|
|
||||||
const biomeList = Object.keys(Biome).filter(key => !isNaN(Number(key)));
|
|
||||||
biomeList.pop(); // Removes Biome.END from the list
|
|
||||||
const randIndex = Utils.randInt(biomeList.length, 2); // Will never be Biome.TOWN or Biome.PLAINS
|
|
||||||
biome = Biome[biomeList[randIndex]];
|
|
||||||
}
|
|
||||||
const linkedBiomes: (Biome | [ Biome, integer ])[] = Array.isArray(biomeLinks[biome])
|
const linkedBiomes: (Biome | [ Biome, integer ])[] = Array.isArray(biomeLinks[biome])
|
||||||
? biomeLinks[biome] as (Biome | [ Biome, integer ])[]
|
? biomeLinks[biome] as (Biome | [ Biome, integer ])[]
|
||||||
: [ biomeLinks[biome] as Biome ];
|
: [ biomeLinks[biome] as Biome ];
|
||||||
|
@ -14,8 +14,8 @@
|
|||||||
"importSlotSelect": "Select a slot to import to.",
|
"importSlotSelect": "Select a slot to import to.",
|
||||||
"exportSession": "Export Session",
|
"exportSession": "Export Session",
|
||||||
"exportSlotSelect": "Select a slot to export from.",
|
"exportSlotSelect": "Select a slot to export from.",
|
||||||
"importRunHistory": "Import Run History",
|
"importRunHistory":"Import Run History",
|
||||||
"exportRunHistory": "Export Run History",
|
"exportRunHistory":"Export Run History",
|
||||||
"importData": "Import Data",
|
"importData": "Import Data",
|
||||||
"exportData": "Export Data",
|
"exportData": "Export Data",
|
||||||
"consentPreferences": "Consent Preferences",
|
"consentPreferences": "Consent Preferences",
|
||||||
|
@ -791,10 +791,10 @@ export class EvolutionItemModifierType extends PokemonModifierType implements Ge
|
|||||||
super("", EvolutionItem[evolutionItem].toLowerCase(), (_type, args) => new Modifiers.EvolutionItemModifier(this, (args[0] as PlayerPokemon).id),
|
super("", EvolutionItem[evolutionItem].toLowerCase(), (_type, args) => new Modifiers.EvolutionItemModifier(this, (args[0] as PlayerPokemon).id),
|
||||||
(pokemon: PlayerPokemon) => {
|
(pokemon: PlayerPokemon) => {
|
||||||
if (pokemonEvolutions.hasOwnProperty(pokemon.species.speciesId) && pokemonEvolutions[pokemon.species.speciesId].filter(e => e.item === this.evolutionItem
|
if (pokemonEvolutions.hasOwnProperty(pokemon.species.speciesId) && pokemonEvolutions[pokemon.species.speciesId].filter(e => e.item === this.evolutionItem
|
||||||
&& (!e.condition || e.condition.predicate(pokemon)) && (e.preFormKey === null || e.preFormKey === pokemon.getFormKey())).length && (pokemon.getFormKey() !== SpeciesFormKey.GIGANTAMAX)) {
|
&& (!e.condition || e.condition.predicate(pokemon)) && (e.preFormKey === pokemon.getFormKey())).length && (pokemon.getFormKey() !== SpeciesFormKey.GIGANTAMAX)) {
|
||||||
return null;
|
return null;
|
||||||
} else if (pokemon.isFusion() && pokemon.fusionSpecies && pokemonEvolutions.hasOwnProperty(pokemon.fusionSpecies.speciesId) && pokemonEvolutions[pokemon.fusionSpecies.speciesId].filter(e => e.item === this.evolutionItem
|
} else if (pokemon.isFusion() && pokemon.fusionSpecies && pokemonEvolutions.hasOwnProperty(pokemon.fusionSpecies.speciesId) && pokemonEvolutions[pokemon.fusionSpecies.speciesId].filter(e => e.item === this.evolutionItem
|
||||||
&& (!e.condition || e.condition.predicate(pokemon)) && (e.preFormKey === null || e.preFormKey === pokemon.getFusionFormKey())).length && (pokemon.getFusionFormKey() !== SpeciesFormKey.GIGANTAMAX)) {
|
&& (!e.condition || e.condition.predicate(pokemon)) && (e.preFormKey === pokemon.getFusionFormKey())).length && (pokemon.getFusionFormKey() !== SpeciesFormKey.GIGANTAMAX)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,8 +243,6 @@ export class StarterPrefs {
|
|||||||
if (pStr !== StarterPrefers_private_latest) {
|
if (pStr !== StarterPrefers_private_latest) {
|
||||||
// something changed, store the update
|
// something changed, store the update
|
||||||
localStorage.setItem(`starterPrefs_${loggedInUser?.username}`, pStr);
|
localStorage.setItem(`starterPrefs_${loggedInUser?.username}`, pStr);
|
||||||
// update the latest prefs
|
|
||||||
StarterPrefers_private_latest = pStr;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,21 +77,7 @@ export default abstract class AbstractOptionSelectUiHandler extends UiHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected setupOptions() {
|
protected setupOptions() {
|
||||||
const configOptions = this.config?.options ?? [];
|
const options = this.config?.options || [];
|
||||||
|
|
||||||
let options: OptionSelectItem[];
|
|
||||||
|
|
||||||
// for performance reasons, this limits how many options we can see at once. Without this, it would try to make text options for every single options
|
|
||||||
// which makes the performance take a hit. If there's not enough options to do this (set to 10 at the moment) and the ui mode !== Mode.AUTO_COMPLETE,
|
|
||||||
// this is ignored and the original code is untouched, with the options array being all the options from the config
|
|
||||||
if (configOptions.length >= 10 && this.scene.ui.getMode() === Mode.AUTO_COMPLETE) {
|
|
||||||
const optionsScrollTotal = configOptions.length;
|
|
||||||
const optionStartIndex = this.scrollCursor;
|
|
||||||
const optionEndIndex = Math.min(optionsScrollTotal, optionStartIndex + (!optionStartIndex || this.scrollCursor + (this.config?.maxOptions! - 1) >= optionsScrollTotal ? this.config?.maxOptions! - 1 : this.config?.maxOptions! - 2));
|
|
||||||
options = configOptions.slice(optionStartIndex, optionEndIndex + 2);
|
|
||||||
} else {
|
|
||||||
options = configOptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.optionSelectText) {
|
if (this.optionSelectText) {
|
||||||
this.optionSelectText.destroy();
|
this.optionSelectText.destroy();
|
||||||
@ -206,19 +192,6 @@ export default abstract class AbstractOptionSelectUiHandler extends UiHandler {
|
|||||||
} else {
|
} else {
|
||||||
ui.playError();
|
ui.playError();
|
||||||
}
|
}
|
||||||
} else if (button === Button.SUBMIT && ui.getMode() === Mode.AUTO_COMPLETE) {
|
|
||||||
// this is here to differentiate between a Button.SUBMIT vs Button.ACTION within the autocomplete handler
|
|
||||||
// this is here because Button.ACTION is picked up as z on the keyboard, meaning if you're typing and hit z, it'll select the option you've chosen
|
|
||||||
success = true;
|
|
||||||
const option = this.config?.options[this.cursor + (this.scrollCursor - (this.scrollCursor ? 1 : 0))];
|
|
||||||
if (option?.handler()) {
|
|
||||||
if (!option.keepOpen) {
|
|
||||||
this.clear();
|
|
||||||
}
|
|
||||||
playSound = !option.overrideSound;
|
|
||||||
} else {
|
|
||||||
ui.playError();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
switch (button) {
|
switch (button) {
|
||||||
case Button.UP:
|
case Button.UP:
|
||||||
|
@ -64,15 +64,12 @@ export default class AdminUiHandler extends FormModalUiHandler {
|
|||||||
Utils.apiPost("admin/account/discord-link", `username=${encodeURIComponent(this.inputs[0].text)}&discordId=${encodeURIComponent(this.inputs[1].text)}`, "application/x-www-form-urlencoded", true)
|
Utils.apiPost("admin/account/discord-link", `username=${encodeURIComponent(this.inputs[0].text)}&discordId=${encodeURIComponent(this.inputs[1].text)}`, "application/x-www-form-urlencoded", true)
|
||||||
.then(response => {
|
.then(response => {
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
console.error(response);
|
return response.text();
|
||||||
}
|
}
|
||||||
this.inputs[0].setText("");
|
return response.json();
|
||||||
this.inputs[1].setText("");
|
|
||||||
this.scene.ui.revertMode();
|
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.then(response => {
|
||||||
console.error(err);
|
this.scene.ui.setMode(Mode.ADMIN, config);
|
||||||
this.scene.ui.revertMode();
|
|
||||||
});
|
});
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
@ -1,45 +0,0 @@
|
|||||||
import { Button } from "#enums/buttons";
|
|
||||||
import BattleScene from "../battle-scene";
|
|
||||||
import AbstractOptionSelectUiHandler from "./abstact-option-select-ui-handler";
|
|
||||||
import { Mode } from "./ui";
|
|
||||||
|
|
||||||
export default class AutoCompleteUiHandler extends AbstractOptionSelectUiHandler {
|
|
||||||
modalContainer: Phaser.GameObjects.Container;
|
|
||||||
constructor(scene: BattleScene, mode: Mode = Mode.OPTION_SELECT) {
|
|
||||||
super(scene, mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
getWindowWidth(): integer {
|
|
||||||
return 64;
|
|
||||||
}
|
|
||||||
|
|
||||||
show(args: any[]): boolean {
|
|
||||||
if (args[0].modalContainer) {
|
|
||||||
const { modalContainer } = args[0];
|
|
||||||
const show = super.show(args);
|
|
||||||
this.modalContainer = modalContainer;
|
|
||||||
this.setupOptions();
|
|
||||||
|
|
||||||
return show;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected setupOptions() {
|
|
||||||
super.setupOptions();
|
|
||||||
if (this.modalContainer) {
|
|
||||||
this.optionSelectContainer.setSize(this.optionSelectContainer.height, Math.max(this.optionSelectText.displayWidth + 24, this.getWindowWidth()));
|
|
||||||
this.optionSelectContainer.setPositionRelative(this.modalContainer, this.optionSelectBg.width, this.optionSelectBg.height + 50);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
processInput(button: Button): boolean {
|
|
||||||
// the cancel and action button are here because if you're typing, x and z are used for cancel/action. This means you could be typing something and accidentally cancel/select when you don't mean to
|
|
||||||
// the submit button is therefore used to select a choice (the enter button), though this does not work on my local dev testing for phones, as for my phone/keyboard combo, the enter and z key are both
|
|
||||||
// bound to Button.ACTION, which makes this not work on mobile
|
|
||||||
if (button !== Button.CANCEL && button !== Button.ACTION) {
|
|
||||||
return super.processInput(button);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
@ -21,8 +21,6 @@ export default class BattleMessageUiHandler extends MessageUiHandler {
|
|||||||
public movesWindowContainer: Phaser.GameObjects.Container;
|
public movesWindowContainer: Phaser.GameObjects.Container;
|
||||||
public nameBoxContainer: Phaser.GameObjects.Container;
|
public nameBoxContainer: Phaser.GameObjects.Container;
|
||||||
|
|
||||||
public readonly wordWrapWidth: number = 1780;
|
|
||||||
|
|
||||||
constructor(scene: BattleScene) {
|
constructor(scene: BattleScene) {
|
||||||
super(scene, Mode.MESSAGE);
|
super(scene, Mode.MESSAGE);
|
||||||
}
|
}
|
||||||
@ -65,7 +63,7 @@ export default class BattleMessageUiHandler extends MessageUiHandler {
|
|||||||
const message = addTextObject(this.scene, 0, 0, "", TextStyle.MESSAGE, {
|
const message = addTextObject(this.scene, 0, 0, "", TextStyle.MESSAGE, {
|
||||||
maxLines: 2,
|
maxLines: 2,
|
||||||
wordWrap: {
|
wordWrap: {
|
||||||
width: this.wordWrapWidth
|
width: 1780
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
messageContainer.add(message);
|
messageContainer.add(message);
|
||||||
@ -131,7 +129,7 @@ export default class BattleMessageUiHandler extends MessageUiHandler {
|
|||||||
|
|
||||||
this.commandWindow.setVisible(false);
|
this.commandWindow.setVisible(false);
|
||||||
this.movesWindowContainer.setVisible(false);
|
this.movesWindowContainer.setVisible(false);
|
||||||
this.message.setWordWrapWidth(this.wordWrapWidth);
|
this.message.setWordWrapWidth(1780);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -163,9 +161,7 @@ export default class BattleMessageUiHandler extends MessageUiHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
showDialogue(text: string, name?: string, delay?: integer | null, callback?: Function, callbackDelay?: integer, prompt?: boolean, promptDelay?: integer) {
|
showDialogue(text: string, name?: string, delay?: integer | null, callback?: Function, callbackDelay?: integer, prompt?: boolean, promptDelay?: integer) {
|
||||||
if (name) {
|
name && this.showNameText(name);
|
||||||
this.showNameText(name);
|
|
||||||
}
|
|
||||||
super.showDialogue(text, name, delay, callback, callbackDelay, prompt, promptDelay);
|
super.showDialogue(text, name, delay, callback, callbackDelay, prompt, promptDelay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ import BattleScene, { bypassLogin } from "../battle-scene";
|
|||||||
import { TextStyle, addTextObject, getTextStyleOptions } from "./text";
|
import { TextStyle, addTextObject, getTextStyleOptions } from "./text";
|
||||||
import { Mode } from "./ui";
|
import { Mode } from "./ui";
|
||||||
import * as Utils from "../utils";
|
import * as Utils from "../utils";
|
||||||
import { addWindow, WindowVariant } from "./ui-theme";
|
import { addWindow } from "./ui-theme";
|
||||||
import MessageUiHandler from "./message-ui-handler";
|
import MessageUiHandler from "./message-ui-handler";
|
||||||
import { OptionSelectConfig, OptionSelectItem } from "./abstact-option-select-ui-handler";
|
import { OptionSelectConfig, OptionSelectItem } from "./abstact-option-select-ui-handler";
|
||||||
import { Tutorial, handleTutorial } from "../tutorial";
|
import { Tutorial, handleTutorial } from "../tutorial";
|
||||||
@ -11,7 +11,6 @@ import i18next from "i18next";
|
|||||||
import { Button } from "#enums/buttons";
|
import { Button } from "#enums/buttons";
|
||||||
import { GameDataType } from "#enums/game-data-type";
|
import { GameDataType } from "#enums/game-data-type";
|
||||||
import BgmBar from "#app/ui/bgm-bar";
|
import BgmBar from "#app/ui/bgm-bar";
|
||||||
import AwaitableUiHandler from "./awaitable-ui-handler";
|
|
||||||
|
|
||||||
enum MenuOptions {
|
enum MenuOptions {
|
||||||
GAME_SETTINGS,
|
GAME_SETTINGS,
|
||||||
@ -32,10 +31,6 @@ const githubUrl = "https://github.com/pagefaultgames/pokerogue";
|
|||||||
const redditUrl = "https://www.reddit.com/r/pokerogue";
|
const redditUrl = "https://www.reddit.com/r/pokerogue";
|
||||||
|
|
||||||
export default class MenuUiHandler extends MessageUiHandler {
|
export default class MenuUiHandler extends MessageUiHandler {
|
||||||
private readonly textPadding = 8;
|
|
||||||
private readonly defaultMessageBoxWidth = 220;
|
|
||||||
private readonly defaultWordWrapWidth = 1224;
|
|
||||||
|
|
||||||
private menuContainer: Phaser.GameObjects.Container;
|
private menuContainer: Phaser.GameObjects.Container;
|
||||||
private menuMessageBoxContainer: Phaser.GameObjects.Container;
|
private menuMessageBoxContainer: Phaser.GameObjects.Container;
|
||||||
private menuOverlay: Phaser.GameObjects.Rectangle;
|
private menuOverlay: Phaser.GameObjects.Rectangle;
|
||||||
@ -51,20 +46,17 @@ export default class MenuUiHandler extends MessageUiHandler {
|
|||||||
protected manageDataConfig: OptionSelectConfig;
|
protected manageDataConfig: OptionSelectConfig;
|
||||||
protected communityConfig: OptionSelectConfig;
|
protected communityConfig: OptionSelectConfig;
|
||||||
|
|
||||||
// Windows for the default message box and the message box for testing dialogue
|
|
||||||
private menuMessageBox: Phaser.GameObjects.NineSlice;
|
|
||||||
private dialogueMessageBox: Phaser.GameObjects.NineSlice;
|
|
||||||
|
|
||||||
protected scale: number = 0.1666666667;
|
protected scale: number = 0.1666666667;
|
||||||
|
|
||||||
public bgmBar: BgmBar;
|
public bgmBar: BgmBar;
|
||||||
|
|
||||||
|
|
||||||
constructor(scene: BattleScene, mode: Mode | null = null) {
|
constructor(scene: BattleScene, mode: Mode | null = null) {
|
||||||
super(scene, mode);
|
super(scene, mode);
|
||||||
|
|
||||||
this.excludedMenus = () => [
|
this.excludedMenus = () => [
|
||||||
{ condition: [Mode.COMMAND, Mode.TITLE].includes(mode ?? Mode.TITLE), options: [MenuOptions.EGG_GACHA, MenuOptions.EGG_LIST] },
|
{ condition: [Mode.COMMAND, Mode.TITLE].includes(mode ?? Mode.TITLE), options: [ MenuOptions.EGG_GACHA, MenuOptions.EGG_LIST] },
|
||||||
{ condition: bypassLogin, options: [MenuOptions.LOG_OUT] }
|
{ condition: bypassLogin, options: [ MenuOptions.LOG_OUT ] }
|
||||||
];
|
];
|
||||||
|
|
||||||
this.menuOptions = Utils.getEnumKeys(MenuOptions)
|
this.menuOptions = Utils.getEnumKeys(MenuOptions)
|
||||||
@ -106,8 +98,8 @@ export default class MenuUiHandler extends MessageUiHandler {
|
|||||||
render() {
|
render() {
|
||||||
const ui = this.getUi();
|
const ui = this.getUi();
|
||||||
this.excludedMenus = () => [
|
this.excludedMenus = () => [
|
||||||
{ condition: ![Mode.COMMAND, Mode.TITLE].includes(ui.getModeChain()[0]), options: [MenuOptions.EGG_GACHA, MenuOptions.EGG_LIST] },
|
{ condition: ![Mode.COMMAND, Mode.TITLE].includes(ui.getModeChain()[0]), options: [ MenuOptions.EGG_GACHA, MenuOptions.EGG_LIST] },
|
||||||
{ condition: bypassLogin, options: [MenuOptions.LOG_OUT] }
|
{ condition: bypassLogin, options: [ MenuOptions.LOG_OUT ] }
|
||||||
];
|
];
|
||||||
|
|
||||||
this.menuOptions = Utils.getEnumKeys(MenuOptions)
|
this.menuOptions = Utils.getEnumKeys(MenuOptions)
|
||||||
@ -123,12 +115,12 @@ export default class MenuUiHandler extends MessageUiHandler {
|
|||||||
this.menuBg = addWindow(this.scene,
|
this.menuBg = addWindow(this.scene,
|
||||||
(this.scene.game.canvas.width / 6) - (this.optionSelectText.displayWidth + 25),
|
(this.scene.game.canvas.width / 6) - (this.optionSelectText.displayWidth + 25),
|
||||||
0,
|
0,
|
||||||
this.optionSelectText.displayWidth + 19 + 24 * this.scale,
|
this.optionSelectText.displayWidth + 19+24*this.scale,
|
||||||
(this.scene.game.canvas.height / 6) - 2
|
(this.scene.game.canvas.height / 6) - 2
|
||||||
);
|
);
|
||||||
this.menuBg.setOrigin(0, 0);
|
this.menuBg.setOrigin(0, 0);
|
||||||
|
|
||||||
this.optionSelectText.setPositionRelative(this.menuBg, 10 + 24 * this.scale, 6);
|
this.optionSelectText.setPositionRelative(this.menuBg, 10+24*this.scale, 6);
|
||||||
|
|
||||||
this.menuContainer.add(this.menuBg);
|
this.menuContainer.add(this.menuBg);
|
||||||
|
|
||||||
@ -139,27 +131,20 @@ export default class MenuUiHandler extends MessageUiHandler {
|
|||||||
this.menuMessageBoxContainer = this.scene.add.container(0, 130);
|
this.menuMessageBoxContainer = this.scene.add.container(0, 130);
|
||||||
this.menuMessageBoxContainer.setName("menu-message-box");
|
this.menuMessageBoxContainer.setName("menu-message-box");
|
||||||
this.menuMessageBoxContainer.setVisible(false);
|
this.menuMessageBoxContainer.setVisible(false);
|
||||||
|
this.menuContainer.add(this.menuMessageBoxContainer);
|
||||||
|
|
||||||
// Window for general messages
|
const menuMessageBox = addWindow(this.scene, 0, -0, 220, 48);
|
||||||
this.menuMessageBox = addWindow(this.scene, 0, 0, this.defaultMessageBoxWidth, 48);
|
menuMessageBox.setOrigin(0, 0);
|
||||||
this.menuMessageBox.setOrigin(0, 0);
|
this.menuMessageBoxContainer.add(menuMessageBox);
|
||||||
this.menuMessageBoxContainer.add(this.menuMessageBox);
|
|
||||||
|
|
||||||
// Full-width window used for testing dialog messages in debug mode
|
const menuMessageText = addTextObject(this.scene, 8, 8, "", TextStyle.WINDOW, { maxLines: 2 });
|
||||||
this.dialogueMessageBox = addWindow(this.scene, -this.textPadding, 0, this.scene.game.canvas.width / 6 + this.textPadding * 2, 49, false, false, 0, 0, WindowVariant.THIN);
|
|
||||||
this.dialogueMessageBox.setOrigin(0, 0);
|
|
||||||
this.menuMessageBoxContainer.add(this.dialogueMessageBox);
|
|
||||||
|
|
||||||
const menuMessageText = addTextObject(this.scene, this.textPadding, this.textPadding, "", TextStyle.WINDOW, { maxLines: 2 });
|
|
||||||
menuMessageText.setName("menu-message");
|
menuMessageText.setName("menu-message");
|
||||||
|
menuMessageText.setWordWrapWidth(1224);
|
||||||
menuMessageText.setOrigin(0, 0);
|
menuMessageText.setOrigin(0, 0);
|
||||||
this.menuMessageBoxContainer.add(menuMessageText);
|
this.menuMessageBoxContainer.add(menuMessageText);
|
||||||
|
|
||||||
this.message = menuMessageText;
|
this.message = menuMessageText;
|
||||||
|
|
||||||
// By default we use the general purpose message window
|
|
||||||
this.setDialogTestMode(false);
|
|
||||||
|
|
||||||
this.menuContainer.add(this.menuMessageBoxContainer);
|
this.menuContainer.add(this.menuMessageBoxContainer);
|
||||||
|
|
||||||
const manageDataOptions: any[] = []; // TODO: proper type
|
const manageDataOptions: any[] = []; // TODO: proper type
|
||||||
@ -170,7 +155,7 @@ export default class MenuUiHandler extends MessageUiHandler {
|
|||||||
const config: OptionSelectConfig = {
|
const config: OptionSelectConfig = {
|
||||||
options: new Array(5).fill(null).map((_, i) => i).filter(slotFilter).map(i => {
|
options: new Array(5).fill(null).map((_, i) => i).filter(slotFilter).map(i => {
|
||||||
return {
|
return {
|
||||||
label: i18next.t("menuUiHandler:slot", { slotNumber: i + 1 }),
|
label: i18next.t("menuUiHandler:slot", {slotNumber: i+1}),
|
||||||
handler: () => {
|
handler: () => {
|
||||||
callback(i);
|
callback(i);
|
||||||
ui.revertMode();
|
ui.revertMode();
|
||||||
@ -272,55 +257,8 @@ export default class MenuUiHandler extends MessageUiHandler {
|
|||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
keepOpen: true
|
keepOpen: true
|
||||||
});
|
},
|
||||||
if (Utils.isLocal || Utils.isBeta) { // this should make sure we don't have this option in live
|
{
|
||||||
manageDataOptions.push({
|
|
||||||
label: "Test Dialogue",
|
|
||||||
handler: () => {
|
|
||||||
ui.playSelect();
|
|
||||||
const prefilledText = "";
|
|
||||||
const buttonAction: any = {};
|
|
||||||
buttonAction["buttonActions"] = [
|
|
||||||
(sanitizedName: string) => {
|
|
||||||
ui.revertMode();
|
|
||||||
ui.playSelect();
|
|
||||||
const dialogueTestName = sanitizedName;
|
|
||||||
const dialogueName = decodeURIComponent(escape(atob(dialogueTestName)));
|
|
||||||
const handler = ui.getHandler() as AwaitableUiHandler;
|
|
||||||
handler.tutorialActive = true;
|
|
||||||
const interpolatorOptions: any = {};
|
|
||||||
const splitArr = dialogueName.split(" "); // this splits our inputted text into words to cycle through later
|
|
||||||
const translatedString = splitArr[0]; // this is our outputted i18 string
|
|
||||||
const regex = RegExp("\\{\\{(\\w*)\\}\\}", "g"); // this is a regex expression to find all the text between {{ }} in the i18 output
|
|
||||||
const matches = i18next.t(translatedString).match(regex) ?? [];
|
|
||||||
if (matches.length > 0) {
|
|
||||||
for (let match = 0; match < matches.length; match++) {
|
|
||||||
// we add 1 here because splitArr[0] is our first value for the translatedString, and after that is where the variables are
|
|
||||||
// the regex here in the replace (/\W/g) is to remove the {{ and }} and just give us all alphanumeric characters
|
|
||||||
if (typeof splitArr[match + 1] !== "undefined") {
|
|
||||||
interpolatorOptions[matches[match].replace(/\W/g, "")] = i18next.t(splitArr[match + 1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Switch to the dialog test window
|
|
||||||
this.setDialogTestMode(true);
|
|
||||||
ui.showText(String(i18next.t(translatedString, interpolatorOptions)), null, () => this.scene.ui.showText("", 0, () => {
|
|
||||||
handler.tutorialActive = false;
|
|
||||||
// Go back to the default message window
|
|
||||||
this.setDialogTestMode(false);
|
|
||||||
}), null, true);
|
|
||||||
},
|
|
||||||
() => {
|
|
||||||
ui.revertMode();
|
|
||||||
}
|
|
||||||
];
|
|
||||||
ui.setMode(Mode.TEST_DIALOGUE, buttonAction, prefilledText);
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
keepOpen: true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
manageDataOptions.push({
|
|
||||||
label: i18next.t("menuUiHandler:cancel"),
|
label: i18next.t("menuUiHandler:cancel"),
|
||||||
handler: () => {
|
handler: () => {
|
||||||
this.scene.ui.revertMode();
|
this.scene.ui.revertMode();
|
||||||
@ -483,7 +421,7 @@ export default class MenuUiHandler extends MessageUiHandler {
|
|||||||
break;
|
break;
|
||||||
case MenuOptions.MANAGE_DATA:
|
case MenuOptions.MANAGE_DATA:
|
||||||
if (!bypassLogin && !this.manageDataConfig.options.some(o => o.label === i18next.t("menuUiHandler:linkDiscord") || o.label === i18next.t("menuUiHandler:unlinkDiscord"))) {
|
if (!bypassLogin && !this.manageDataConfig.options.some(o => o.label === i18next.t("menuUiHandler:linkDiscord") || o.label === i18next.t("menuUiHandler:unlinkDiscord"))) {
|
||||||
this.manageDataConfig.options.splice(this.manageDataConfig.options.length - 1, 0,
|
this.manageDataConfig.options.splice(this.manageDataConfig.options.length-1, 0,
|
||||||
{
|
{
|
||||||
label: loggedInUser?.discordId === "" ? i18next.t("menuUiHandler:linkDiscord") : i18next.t("menuUiHandler:unlinkDiscord"),
|
label: loggedInUser?.discordId === "" ? i18next.t("menuUiHandler:linkDiscord") : i18next.t("menuUiHandler:unlinkDiscord"),
|
||||||
handler: () => {
|
handler: () => {
|
||||||
@ -609,21 +547,6 @@ export default class MenuUiHandler extends MessageUiHandler {
|
|||||||
return success || error;
|
return success || error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Switch the message window style and size when we are replaying dialog for debug purposes
|
|
||||||
* In "dialog test mode", the window takes the whole width of the screen and the text
|
|
||||||
* is set up to wrap around the same way as the dialogue during the game
|
|
||||||
* @param isDialogMode whether to use the dialog test
|
|
||||||
*/
|
|
||||||
setDialogTestMode(isDialogMode: boolean) {
|
|
||||||
this.menuMessageBox.setVisible(!isDialogMode);
|
|
||||||
this.dialogueMessageBox.setVisible(isDialogMode);
|
|
||||||
// If we're testing dialog, we use the same word wrapping as the battle message handler
|
|
||||||
this.message.setWordWrapWidth(isDialogMode ? this.scene.ui.getMessageHandler().wordWrapWidth : this.defaultWordWrapWidth);
|
|
||||||
this.message.setX(isDialogMode ? this.textPadding + 1 : this.textPadding);
|
|
||||||
this.message.setY(isDialogMode ? this.textPadding + 0.4 : this.textPadding);
|
|
||||||
}
|
|
||||||
|
|
||||||
showText(text: string, delay?: number, callback?: Function, callbackDelay?: number, prompt?: boolean, promptDelay?: number): void {
|
showText(text: string, delay?: number, callback?: Function, callbackDelay?: number, prompt?: boolean, promptDelay?: number): void {
|
||||||
this.menuMessageBoxContainer.setVisible(!!text);
|
this.menuMessageBoxContainer.setVisible(!!text);
|
||||||
|
|
||||||
|
@ -915,9 +915,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
this.allSpecies.forEach((species, s) => {
|
this.allSpecies.forEach((species, s) => {
|
||||||
const icon = this.starterContainers[s].icon;
|
const icon = this.starterContainers[s].icon;
|
||||||
const dexEntry = this.scene.gameData.dexData[species.speciesId];
|
const dexEntry = this.scene.gameData.dexData[species.speciesId];
|
||||||
|
this.starterPreferences[species.speciesId] = this.starterPreferences[species.speciesId] ?? {};
|
||||||
// Initialize the StarterAttributes for this species
|
|
||||||
this.starterPreferences[species.speciesId] = this.initStarterPrefs(species);
|
|
||||||
|
|
||||||
if (dexEntry.caughtAttr) {
|
if (dexEntry.caughtAttr) {
|
||||||
icon.clearTint();
|
icon.clearTint();
|
||||||
@ -944,93 +942,6 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the starter attributes for the given PokemonSpecies, after sanitizing them.
|
|
||||||
* If somehow a preference is set for a form, variant, gender, ability or nature
|
|
||||||
* that wasn't actually unlocked or is invalid it will be cleared here
|
|
||||||
*
|
|
||||||
* @param species The species to get Starter Preferences for
|
|
||||||
* @returns StarterAttributes for the species
|
|
||||||
*/
|
|
||||||
initStarterPrefs(species: PokemonSpecies): StarterAttributes {
|
|
||||||
const starterAttributes = this.starterPreferences[species.speciesId];
|
|
||||||
const dexEntry = this.scene.gameData.dexData[species.speciesId];
|
|
||||||
const starterData = this.scene.gameData.starterData[species.speciesId];
|
|
||||||
|
|
||||||
// no preferences or Pokemon wasn't caught, return empty attribute
|
|
||||||
if (!starterAttributes || !dexEntry.caughtAttr) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
const caughtAttr = dexEntry.caughtAttr;
|
|
||||||
|
|
||||||
const hasShiny = caughtAttr & DexAttr.SHINY;
|
|
||||||
const hasNonShiny = caughtAttr & DexAttr.NON_SHINY;
|
|
||||||
if (starterAttributes.shiny && !hasShiny) {
|
|
||||||
// shiny form wasn't unlocked, purging shiny and variant setting
|
|
||||||
delete starterAttributes.shiny;
|
|
||||||
delete starterAttributes.variant;
|
|
||||||
} else if (starterAttributes.shiny === false && !hasNonShiny) {
|
|
||||||
// non shiny form wasn't unlocked, purging shiny setting
|
|
||||||
delete starterAttributes.shiny;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (starterAttributes.variant !== undefined && !isNaN(starterAttributes.variant)) {
|
|
||||||
const unlockedVariants = [
|
|
||||||
hasNonShiny,
|
|
||||||
hasShiny && caughtAttr & DexAttr.DEFAULT_VARIANT,
|
|
||||||
hasShiny && caughtAttr & DexAttr.VARIANT_2,
|
|
||||||
hasShiny && caughtAttr & DexAttr.VARIANT_3
|
|
||||||
];
|
|
||||||
if (!unlockedVariants[starterAttributes.variant + 1]) { // add 1 as -1 = non-shiny
|
|
||||||
// requested variant wasn't unlocked, purging setting
|
|
||||||
delete starterAttributes.variant;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (starterAttributes.female !== undefined) {
|
|
||||||
if (!(starterAttributes.female ? caughtAttr & DexAttr.FEMALE : caughtAttr & DexAttr.MALE)) {
|
|
||||||
// requested gender wasn't unlocked, purging setting
|
|
||||||
delete starterAttributes.female;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (starterAttributes.ability !== undefined) {
|
|
||||||
const speciesHasSingleAbility = species.ability2 === species.ability1;
|
|
||||||
const abilityAttr = starterData.abilityAttr;
|
|
||||||
const hasAbility1 = abilityAttr & AbilityAttr.ABILITY_1;
|
|
||||||
const hasAbility2 = abilityAttr & AbilityAttr.ABILITY_2;
|
|
||||||
const hasHiddenAbility = abilityAttr & AbilityAttr.ABILITY_HIDDEN;
|
|
||||||
// Due to a past bug it is possible that some Pokemon with a single ability have the ability2 flag
|
|
||||||
// In this case, we only count ability2 as valid if ability1 was not unlocked, otherwise we ignore it
|
|
||||||
const unlockedAbilities = [
|
|
||||||
hasAbility1,
|
|
||||||
speciesHasSingleAbility ? hasAbility2 && !hasAbility1 : hasAbility2,
|
|
||||||
hasHiddenAbility
|
|
||||||
];
|
|
||||||
if (!unlockedAbilities[starterAttributes.ability]) {
|
|
||||||
// requested ability wasn't unlocked, purging setting
|
|
||||||
delete starterAttributes.ability;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const selectedForm = starterAttributes.form;
|
|
||||||
if (selectedForm !== undefined && (!species.forms[selectedForm]?.isStarterSelectable || !(caughtAttr & this.scene.gameData.getFormAttr(selectedForm)))) {
|
|
||||||
// requested form wasn't unlocked/isn't a starter form, purging setting
|
|
||||||
delete starterAttributes.form;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (starterAttributes.nature !== undefined) {
|
|
||||||
const unlockedNatures = this.scene.gameData.getNaturesForAttr(dexEntry.natureAttr);
|
|
||||||
if (unlockedNatures.indexOf(starterAttributes.nature as unknown as Nature) < 0) {
|
|
||||||
// requested nature wasn't unlocked, purging setting
|
|
||||||
delete starterAttributes.nature;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return starterAttributes;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the selections for all filters to their default starting value
|
* Set the selections for all filters to their default starting value
|
||||||
*/
|
*/
|
||||||
@ -1838,9 +1749,9 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
switch (button) {
|
switch (button) {
|
||||||
case Button.CYCLE_SHINY:
|
case Button.CYCLE_SHINY:
|
||||||
if (this.canCycleShiny) {
|
if (this.canCycleShiny) {
|
||||||
const newVariant = starterAttributes.variant ? starterAttributes.variant as Variant : props.variant;
|
const newVariant = props.variant;
|
||||||
starterAttributes.shiny = starterAttributes.shiny ? !starterAttributes.shiny : true;
|
starterAttributes.shiny = starterAttributes.shiny ? !starterAttributes.shiny : true;
|
||||||
this.setSpeciesDetails(this.lastSpecies, !props.shiny, undefined, undefined, props.shiny ? 0 : newVariant, undefined, undefined);
|
this.setSpeciesDetails(this.lastSpecies, !props.shiny, undefined, undefined, props.shiny ? 0 : undefined, undefined, undefined);
|
||||||
if (starterAttributes.shiny) {
|
if (starterAttributes.shiny) {
|
||||||
this.scene.playSound("se/sparkle");
|
this.scene.playSound("se/sparkle");
|
||||||
// Set the variant label to the shiny tint
|
// Set the variant label to the shiny tint
|
||||||
@ -1849,6 +1760,10 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
this.pokemonShinyIcon.setTint(tint);
|
this.pokemonShinyIcon.setTint(tint);
|
||||||
this.pokemonShinyIcon.setVisible(true);
|
this.pokemonShinyIcon.setVisible(true);
|
||||||
} else {
|
} else {
|
||||||
|
// starterAttributes.variant = 0;
|
||||||
|
if (starterAttributes?.variant) {
|
||||||
|
delete starterAttributes.variant;
|
||||||
|
}
|
||||||
this.pokemonShinyIcon.setVisible(false);
|
this.pokemonShinyIcon.setVisible(false);
|
||||||
success = true;
|
success = true;
|
||||||
}
|
}
|
||||||
@ -2361,39 +2276,43 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
container.cost = this.scene.gameData.getSpeciesStarterValue(container.species.speciesId);
|
container.cost = this.scene.gameData.getSpeciesStarterValue(container.species.speciesId);
|
||||||
|
|
||||||
// First, ensure you have the caught attributes for the species else default to bigint 0
|
// First, ensure you have the caught attributes for the species else default to bigint 0
|
||||||
const caughtAttr = this.scene.gameData.dexData[container.species.speciesId]?.caughtAttr || BigInt(0);
|
const isCaught = this.scene.gameData.dexData[container.species.speciesId]?.caughtAttr || BigInt(0);
|
||||||
const starterData = this.scene.gameData.starterData[container.species.speciesId];
|
|
||||||
|
// Define the variables based on whether their respective variants have been caught
|
||||||
|
const isVariant3Caught = !!(isCaught & DexAttr.VARIANT_3);
|
||||||
|
const isVariant2Caught = !!(isCaught & DexAttr.VARIANT_2);
|
||||||
|
const isVariantCaught = !!(isCaught & DexAttr.SHINY);
|
||||||
|
const isUncaught = !isCaught && !isVariantCaught && !isVariant2Caught && !isVariant3Caught;
|
||||||
|
const isPassiveUnlocked = this.scene.gameData.starterData[container.species.speciesId].passiveAttr > 0;
|
||||||
|
const isPassiveUnlockable = this.isPassiveAvailable(container.species.speciesId) && !isPassiveUnlocked;
|
||||||
|
const isCostReduced = this.scene.gameData.starterData[container.species.speciesId].valueReduction > 0;
|
||||||
|
const isCostReductionUnlockable = this.isValueReductionAvailable(container.species.speciesId);
|
||||||
|
const isFavorite = this.starterPreferences[container.species.speciesId]?.favorite ?? false;
|
||||||
|
|
||||||
|
const isWin = this.scene.gameData.starterData[container.species.speciesId].classicWinCount > 0;
|
||||||
|
const isNotWin = this.scene.gameData.starterData[container.species.speciesId].classicWinCount === 0;
|
||||||
|
const isUndefined = this.scene.gameData.starterData[container.species.speciesId].classicWinCount === undefined;
|
||||||
|
const isHA = this.scene.gameData.starterData[container.species.speciesId].abilityAttr & AbilityAttr.ABILITY_HIDDEN;
|
||||||
|
const isEggPurchasable = this.isSameSpeciesEggAvailable(container.species.speciesId);
|
||||||
|
|
||||||
// Gen filter
|
|
||||||
const fitsGen = this.filterBar.getVals(DropDownColumn.GEN).includes(container.species.generation);
|
const fitsGen = this.filterBar.getVals(DropDownColumn.GEN).includes(container.species.generation);
|
||||||
|
|
||||||
// Type filter
|
|
||||||
const fitsType = this.filterBar.getVals(DropDownColumn.TYPES).some(type => container.species.isOfType((type as number) - 1));
|
const fitsType = this.filterBar.getVals(DropDownColumn.TYPES).some(type => container.species.isOfType((type as number) - 1));
|
||||||
|
|
||||||
// Caught / Shiny filter
|
|
||||||
const isNonShinyCaught = !!(caughtAttr & DexAttr.NON_SHINY);
|
|
||||||
const isShinyCaught = !!(caughtAttr & DexAttr.SHINY);
|
|
||||||
const isVariant1Caught = isShinyCaught && !!(caughtAttr & DexAttr.DEFAULT_VARIANT);
|
|
||||||
const isVariant2Caught = isShinyCaught && !!(caughtAttr & DexAttr.VARIANT_2);
|
|
||||||
const isVariant3Caught = isShinyCaught && !!(caughtAttr & DexAttr.VARIANT_3);
|
|
||||||
const isUncaught = !isNonShinyCaught && !isVariant1Caught && !isVariant2Caught && !isVariant3Caught;
|
|
||||||
const fitsCaught = this.filterBar.getVals(DropDownColumn.CAUGHT).some(caught => {
|
const fitsCaught = this.filterBar.getVals(DropDownColumn.CAUGHT).some(caught => {
|
||||||
if (caught === "SHINY3") {
|
if (caught === "SHINY3") {
|
||||||
return isVariant3Caught;
|
return isVariant3Caught;
|
||||||
} else if (caught === "SHINY2") {
|
} else if (caught === "SHINY2") {
|
||||||
return isVariant2Caught && !isVariant3Caught;
|
return isVariant2Caught && !isVariant3Caught;
|
||||||
} else if (caught === "SHINY") {
|
} else if (caught === "SHINY") {
|
||||||
return isVariant1Caught && !isVariant2Caught && !isVariant3Caught;
|
return isVariantCaught && !isVariant2Caught && !isVariant3Caught;
|
||||||
} else if (caught === "NORMAL") {
|
} else if (caught === "NORMAL") {
|
||||||
return isNonShinyCaught && !isVariant1Caught && !isVariant2Caught && !isVariant3Caught;
|
return isCaught && !isVariantCaught && !isVariant2Caught && !isVariant3Caught;
|
||||||
} else if (caught === "UNCAUGHT") {
|
} else if (caught === "UNCAUGHT") {
|
||||||
return isUncaught;
|
return isUncaught;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Passive Filter
|
|
||||||
const isPassiveUnlocked = starterData.passiveAttr > 0;
|
|
||||||
const isPassiveUnlockable = this.isPassiveAvailable(container.species.speciesId) && !isPassiveUnlocked;
|
|
||||||
const fitsPassive = this.filterBar.getVals(DropDownColumn.UNLOCKS).some(unlocks => {
|
const fitsPassive = this.filterBar.getVals(DropDownColumn.UNLOCKS).some(unlocks => {
|
||||||
if (unlocks.val === "PASSIVE" && unlocks.state === DropDownState.ON) {
|
if (unlocks.val === "PASSIVE" && unlocks.state === DropDownState.ON) {
|
||||||
return isPassiveUnlocked;
|
return isPassiveUnlocked;
|
||||||
@ -2406,9 +2325,6 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Cost Reduction Filter
|
|
||||||
const isCostReduced = starterData.valueReduction > 0;
|
|
||||||
const isCostReductionUnlockable = this.isValueReductionAvailable(container.species.speciesId);
|
|
||||||
const fitsCostReduction = this.filterBar.getVals(DropDownColumn.UNLOCKS).some(unlocks => {
|
const fitsCostReduction = this.filterBar.getVals(DropDownColumn.UNLOCKS).some(unlocks => {
|
||||||
if (unlocks.val === "COST_REDUCTION" && unlocks.state === DropDownState.ON) {
|
if (unlocks.val === "COST_REDUCTION" && unlocks.state === DropDownState.ON) {
|
||||||
return isCostReduced;
|
return isCostReduced;
|
||||||
@ -2421,8 +2337,6 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Favorite Filter
|
|
||||||
const isFavorite = this.starterPreferences[container.species.speciesId]?.favorite ?? false;
|
|
||||||
const fitsFavorite = this.filterBar.getVals(DropDownColumn.MISC).some(misc => {
|
const fitsFavorite = this.filterBar.getVals(DropDownColumn.MISC).some(misc => {
|
||||||
if (misc.val === "FAVORITE" && misc.state === DropDownState.ON) {
|
if (misc.val === "FAVORITE" && misc.state === DropDownState.ON) {
|
||||||
return isFavorite;
|
return isFavorite;
|
||||||
@ -2435,34 +2349,28 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Ribbon / Classic Win Filter
|
|
||||||
const hasWon = starterData.classicWinCount > 0;
|
|
||||||
const hasNotWon = starterData.classicWinCount === 0;
|
|
||||||
const isUndefined = starterData.classicWinCount === undefined;
|
|
||||||
const fitsWin = this.filterBar.getVals(DropDownColumn.MISC).some(misc => {
|
const fitsWin = this.filterBar.getVals(DropDownColumn.MISC).some(misc => {
|
||||||
|
if (container.species.speciesId < 10) {
|
||||||
|
}
|
||||||
if (misc.val === "WIN" && misc.state === DropDownState.ON) {
|
if (misc.val === "WIN" && misc.state === DropDownState.ON) {
|
||||||
return hasWon;
|
return isWin;
|
||||||
} else if (misc.val === "WIN" && misc.state === DropDownState.EXCLUDE) {
|
} else if (misc.val === "WIN" && misc.state === DropDownState.EXCLUDE) {
|
||||||
return hasNotWon || isUndefined;
|
return isNotWin || isUndefined;
|
||||||
} else if (misc.val === "WIN" && misc.state === DropDownState.OFF) {
|
} else if (misc.val === "WIN" && misc.state === DropDownState.OFF) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// HA Filter
|
|
||||||
const hasHA = starterData.abilityAttr & AbilityAttr.ABILITY_HIDDEN;
|
|
||||||
const fitsHA = this.filterBar.getVals(DropDownColumn.MISC).some(misc => {
|
const fitsHA = this.filterBar.getVals(DropDownColumn.MISC).some(misc => {
|
||||||
if (misc.val === "HIDDEN_ABILITY" && misc.state === DropDownState.ON) {
|
if (misc.val === "HIDDEN_ABILITY" && misc.state === DropDownState.ON) {
|
||||||
return hasHA;
|
return isHA;
|
||||||
} else if (misc.val === "HIDDEN_ABILITY" && misc.state === DropDownState.EXCLUDE) {
|
} else if (misc.val === "HIDDEN_ABILITY" && misc.state === DropDownState.EXCLUDE) {
|
||||||
return !hasHA;
|
return !isHA;
|
||||||
} else if (misc.val === "HIDDEN_ABILITY" && misc.state === DropDownState.OFF) {
|
} else if (misc.val === "HIDDEN_ABILITY" && misc.state === DropDownState.OFF) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Egg Purchasable Filter
|
|
||||||
const isEggPurchasable = this.isSameSpeciesEggAvailable(container.species.speciesId);
|
|
||||||
const fitsEgg = this.filterBar.getVals(DropDownColumn.MISC).some(misc => {
|
const fitsEgg = this.filterBar.getVals(DropDownColumn.MISC).some(misc => {
|
||||||
if (misc.val === "EGG" && misc.state === DropDownState.ON) {
|
if (misc.val === "EGG" && misc.state === DropDownState.ON) {
|
||||||
return isEggPurchasable;
|
return isEggPurchasable;
|
||||||
@ -2473,7 +2381,6 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Pokerus Filter
|
|
||||||
const fitsPokerus = this.filterBar.getVals(DropDownColumn.MISC).some(misc => {
|
const fitsPokerus = this.filterBar.getVals(DropDownColumn.MISC).some(misc => {
|
||||||
if (misc.val === "POKERUS" && misc.state === DropDownState.ON) {
|
if (misc.val === "POKERUS" && misc.state === DropDownState.ON) {
|
||||||
return this.pokerusSpecies.includes(container.species);
|
return this.pokerusSpecies.includes(container.species);
|
||||||
@ -2672,13 +2579,56 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
this.natureCursor = species ? this.scene.gameData.getSpeciesDefaultNature(species) : 0;
|
this.natureCursor = species ? this.scene.gameData.getSpeciesDefaultNature(species) : 0;
|
||||||
|
|
||||||
const starterAttributes : StarterAttributes | null = species ? {...this.starterPreferences[species.speciesId]} : null;
|
const starterAttributes : StarterAttributes | null = species ? {...this.starterPreferences[species.speciesId]} : null;
|
||||||
|
// validate starterAttributes
|
||||||
|
if (starterAttributes) {
|
||||||
|
// this may cause changes so we created a copy of the attributes before
|
||||||
|
if (starterAttributes.variant && !isNaN(starterAttributes.variant)) {
|
||||||
|
if (![
|
||||||
|
this.speciesStarterDexEntry!.caughtAttr & DexAttr.NON_SHINY, // TODO: is that bang correct?
|
||||||
|
this.speciesStarterDexEntry!.caughtAttr & DexAttr.DEFAULT_VARIANT, // TODO: is that bang correct?
|
||||||
|
this.speciesStarterDexEntry!.caughtAttr & DexAttr.VARIANT_2, // TODO: is that bang correct?
|
||||||
|
this.speciesStarterDexEntry!.caughtAttr & DexAttr.VARIANT_3 // TODO: is that bang correct?
|
||||||
|
][starterAttributes.variant+1]) { // add 1 as -1 = non-shiny
|
||||||
|
// requested variant wasn't unlocked, purging setting
|
||||||
|
delete starterAttributes.variant;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof starterAttributes.female !== "boolean" || !(starterAttributes.female ?
|
||||||
|
this.speciesStarterDexEntry!.caughtAttr & DexAttr.FEMALE : // TODO: is this bang correct?
|
||||||
|
this.speciesStarterDexEntry!.caughtAttr & DexAttr.MALE // TODO: is this bang correct?
|
||||||
|
)) {
|
||||||
|
// requested gender wasn't unlocked, purging setting
|
||||||
|
delete starterAttributes.female;
|
||||||
|
}
|
||||||
|
|
||||||
|
const abilityAttr = this.scene.gameData.starterData[species!.speciesId].abilityAttr; // TODO: is this bang correct?
|
||||||
|
if (![
|
||||||
|
abilityAttr & AbilityAttr.ABILITY_1,
|
||||||
|
species!.ability2 ? (abilityAttr & AbilityAttr.ABILITY_2) : abilityAttr & AbilityAttr.ABILITY_HIDDEN, // TODO: is this bang correct?
|
||||||
|
species!.ability2 && abilityAttr & AbilityAttr.ABILITY_HIDDEN // TODO: is this bang correct?
|
||||||
|
][starterAttributes.ability!]) { // TODO: is this bang correct?
|
||||||
|
// requested ability wasn't unlocked, purging setting
|
||||||
|
delete starterAttributes.ability;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(species?.forms[starterAttributes.form!]?.isStarterSelectable && this.speciesStarterDexEntry!.caughtAttr & this.scene.gameData.getFormAttr(starterAttributes.form!))) { // TODO: are those bangs correct?
|
||||||
|
// requested form wasn't unlocked/isn't a starter form, purging setting
|
||||||
|
delete starterAttributes.form;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.scene.gameData.getNaturesForAttr(this.speciesStarterDexEntry?.natureAttr).indexOf(starterAttributes.nature as unknown as Nature) < 0) {
|
||||||
|
// requested nature wasn't unlocked, purging setting
|
||||||
|
delete starterAttributes.nature;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (starterAttributes?.nature) {
|
if (starterAttributes?.nature) {
|
||||||
// load default nature from stater save data, if set
|
// load default nature from stater save data, if set
|
||||||
this.natureCursor = starterAttributes.nature;
|
this.natureCursor = starterAttributes.nature;
|
||||||
}
|
}
|
||||||
if (starterAttributes?.ability && !isNaN(starterAttributes.ability)) {
|
if (starterAttributes?.ability && !isNaN(starterAttributes.ability)) {
|
||||||
// load default ability from stater save data, if set
|
// load default nature from stater save data, if set
|
||||||
this.abilityCursor = starterAttributes.ability;
|
this.abilityCursor = starterAttributes.ability;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2725,6 +2675,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
this.pokemonLuckText.setText(luck.toString());
|
this.pokemonLuckText.setText(luck.toString());
|
||||||
this.pokemonLuckText.setTint(getVariantTint(Math.min(luck - 1, 2) as Variant));
|
this.pokemonLuckText.setTint(getVariantTint(Math.min(luck - 1, 2) as Variant));
|
||||||
this.pokemonLuckLabelText.setVisible(this.pokemonLuckText.visible);
|
this.pokemonLuckLabelText.setVisible(this.pokemonLuckText.visible);
|
||||||
|
this.pokemonShinyIcon.setVisible(this.starterPreferences[species.speciesId]?.shiny ?? false);
|
||||||
|
|
||||||
//Growth translate
|
//Growth translate
|
||||||
let growthReadable = Utils.toReadableString(GrowthRate[species.growthRate]);
|
let growthReadable = Utils.toReadableString(GrowthRate[species.growthRate]);
|
||||||
@ -2748,14 +2699,12 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
this.pokemonHatchedIcon.setFrame(getEggTierForSpecies(species));
|
this.pokemonHatchedIcon.setFrame(getEggTierForSpecies(species));
|
||||||
}
|
}
|
||||||
this.pokemonHatchedCountText.setText(`${this.speciesStarterDexEntry.hatchedCount}`);
|
this.pokemonHatchedCountText.setText(`${this.speciesStarterDexEntry.hatchedCount}`);
|
||||||
|
|
||||||
const defaultDexAttr = this.getCurrentDexProps(species.speciesId);
|
const defaultDexAttr = this.getCurrentDexProps(species.speciesId);
|
||||||
const defaultProps = this.scene.gameData.getSpeciesDexAttrProps(species, defaultDexAttr);
|
const defaultProps = this.scene.gameData.getSpeciesDexAttrProps(species, defaultDexAttr);
|
||||||
const variant = defaultProps.variant;
|
const variant = defaultProps.variant;
|
||||||
const tint = getVariantTint(variant);
|
const tint = getVariantTint(variant);
|
||||||
this.pokemonShinyIcon.setFrame(getVariantIcon(variant));
|
this.pokemonShinyIcon.setFrame(getVariantIcon(variant));
|
||||||
this.pokemonShinyIcon.setTint(tint);
|
this.pokemonShinyIcon.setTint(tint);
|
||||||
this.pokemonShinyIcon.setVisible(defaultProps.shiny);
|
|
||||||
this.pokemonCaughtHatchedContainer.setVisible(true);
|
this.pokemonCaughtHatchedContainer.setVisible(true);
|
||||||
if (pokemonPrevolutions.hasOwnProperty(species.speciesId)) {
|
if (pokemonPrevolutions.hasOwnProperty(species.speciesId)) {
|
||||||
this.pokemonCaughtHatchedContainer.setY(16);
|
this.pokemonCaughtHatchedContainer.setY(16);
|
||||||
@ -2945,13 +2894,21 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
const dexEntry = this.scene.gameData.dexData[species.speciesId];
|
const dexEntry = this.scene.gameData.dexData[species.speciesId];
|
||||||
const abilityAttr = this.scene.gameData.starterData[species.speciesId].abilityAttr;
|
const abilityAttr = this.scene.gameData.starterData[species.speciesId].abilityAttr;
|
||||||
|
|
||||||
const caughtAttr = this.scene.gameData.dexData[species.speciesId]?.caughtAttr || BigInt(0);
|
const isCaught = this.scene.gameData.dexData[species.speciesId]?.caughtAttr || BigInt(0);
|
||||||
|
const isVariant3Caught = !!(isCaught & DexAttr.VARIANT_3);
|
||||||
|
const isVariant2Caught = !!(isCaught & DexAttr.VARIANT_2);
|
||||||
|
const isDefaultVariantCaught = !!(isCaught & DexAttr.DEFAULT_VARIANT);
|
||||||
|
const isVariantCaught = !!(isCaught & DexAttr.SHINY);
|
||||||
|
const isMaleCaught = !!(isCaught & DexAttr.MALE);
|
||||||
|
const isFemaleCaught = !!(isCaught & DexAttr.FEMALE);
|
||||||
|
|
||||||
|
const starterAttributes = this.starterPreferences[species.speciesId];
|
||||||
|
|
||||||
|
const props = this.scene.gameData.getSpeciesDexAttrProps(species, this.getCurrentDexProps(species.speciesId));
|
||||||
|
const defaultAbilityIndex = this.scene.gameData.getStarterSpeciesDefaultAbilityIndex(species);
|
||||||
|
const defaultNature = this.scene.gameData.getSpeciesDefaultNature(species);
|
||||||
|
|
||||||
if (!dexEntry.caughtAttr) {
|
if (!dexEntry.caughtAttr) {
|
||||||
const props = this.scene.gameData.getSpeciesDexAttrProps(species, this.getCurrentDexProps(species.speciesId));
|
|
||||||
const defaultAbilityIndex = this.scene.gameData.getStarterSpeciesDefaultAbilityIndex(species);
|
|
||||||
const defaultNature = this.scene.gameData.getSpeciesDefaultNature(species);
|
|
||||||
|
|
||||||
if (shiny === undefined || shiny !== props.shiny) {
|
if (shiny === undefined || shiny !== props.shiny) {
|
||||||
shiny = props.shiny;
|
shiny = props.shiny;
|
||||||
}
|
}
|
||||||
@ -2970,6 +2927,83 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
if (natureIndex === undefined || natureIndex !== defaultNature) {
|
if (natureIndex === undefined || natureIndex !== defaultNature) {
|
||||||
natureIndex = defaultNature;
|
natureIndex = defaultNature;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// compare current shiny, formIndex, female, variant, abilityIndex, natureIndex with the caught ones
|
||||||
|
// if the current ones are not caught, we need to find the next caught ones
|
||||||
|
if (shiny) {
|
||||||
|
if (!(isVariantCaught || isVariant2Caught || isVariant3Caught)) {
|
||||||
|
shiny = false;
|
||||||
|
starterAttributes.shiny = false;
|
||||||
|
variant = 0;
|
||||||
|
starterAttributes.variant = 0;
|
||||||
|
} else {
|
||||||
|
shiny = true;
|
||||||
|
starterAttributes.shiny = true;
|
||||||
|
if (variant === 0 && !isDefaultVariantCaught) {
|
||||||
|
if (isVariant2Caught) {
|
||||||
|
variant = 1;
|
||||||
|
starterAttributes.variant = 1;
|
||||||
|
} else if (isVariant3Caught) {
|
||||||
|
variant = 2;
|
||||||
|
starterAttributes.variant = 2;
|
||||||
|
} else {
|
||||||
|
variant = 0;
|
||||||
|
starterAttributes.variant = 0;
|
||||||
|
}
|
||||||
|
} else if (variant === 1 && !isVariant2Caught) {
|
||||||
|
if (isVariantCaught) {
|
||||||
|
variant = 0;
|
||||||
|
starterAttributes.variant = 0;
|
||||||
|
} else if (isVariant3Caught) {
|
||||||
|
variant = 2;
|
||||||
|
starterAttributes.variant = 2;
|
||||||
|
} else {
|
||||||
|
variant = 0;
|
||||||
|
starterAttributes.variant = 0;
|
||||||
|
}
|
||||||
|
} else if (variant === 2 && !isVariant3Caught) {
|
||||||
|
if (isVariantCaught) {
|
||||||
|
variant = 0;
|
||||||
|
starterAttributes.variant = 0;
|
||||||
|
} else if (isVariant2Caught) {
|
||||||
|
variant = 1;
|
||||||
|
starterAttributes.variant = 1;
|
||||||
|
} else {
|
||||||
|
variant = 0;
|
||||||
|
starterAttributes.variant = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (female) {
|
||||||
|
if (!isFemaleCaught) {
|
||||||
|
female = false;
|
||||||
|
starterAttributes.female = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!isMaleCaught) {
|
||||||
|
female = true;
|
||||||
|
starterAttributes.female = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (species.forms) {
|
||||||
|
const formCount = species.forms.length;
|
||||||
|
let newFormIndex = formIndex??0;
|
||||||
|
if (species.forms[newFormIndex]) {
|
||||||
|
const isValidForm = species.forms[newFormIndex].isStarterSelectable && dexEntry.caughtAttr & this.scene.gameData.getFormAttr(newFormIndex);
|
||||||
|
if (!isValidForm) {
|
||||||
|
do {
|
||||||
|
newFormIndex = (newFormIndex + 1) % formCount;
|
||||||
|
if (species.forms[newFormIndex].isStarterSelectable && dexEntry.caughtAttr & this.scene.gameData.getFormAttr(newFormIndex)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (newFormIndex !== props.formIndex);
|
||||||
|
formIndex = newFormIndex;
|
||||||
|
starterAttributes.form = formIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.shinyOverlay.setVisible(shiny ?? false); // TODO: is false the correct default?
|
this.shinyOverlay.setVisible(shiny ?? false); // TODO: is false the correct default?
|
||||||
@ -3011,19 +3045,8 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
currentFilteredContainer.checkIconId(female, formIndex, shiny, variant);
|
currentFilteredContainer.checkIconId(female, formIndex, shiny, variant);
|
||||||
}
|
}
|
||||||
|
|
||||||
const isNonShinyCaught = !!(caughtAttr & DexAttr.NON_SHINY);
|
this.canCycleShiny = isVariantCaught || isVariant2Caught || isVariant3Caught;
|
||||||
const isShinyCaught = !!(caughtAttr & DexAttr.SHINY);
|
|
||||||
const isVariant1Caught = isShinyCaught && !!(caughtAttr & DexAttr.DEFAULT_VARIANT);
|
|
||||||
const isVariant2Caught = isShinyCaught && !!(caughtAttr & DexAttr.VARIANT_2);
|
|
||||||
const isVariant3Caught = isShinyCaught && !!(caughtAttr & DexAttr.VARIANT_3);
|
|
||||||
|
|
||||||
this.canCycleShiny = isNonShinyCaught && isShinyCaught;
|
|
||||||
this.canCycleVariant = !!shiny && [ isVariant1Caught, isVariant2Caught, isVariant3Caught].filter(v => v).length > 1;
|
|
||||||
|
|
||||||
const isMaleCaught = !!(caughtAttr & DexAttr.MALE);
|
|
||||||
const isFemaleCaught = !!(caughtAttr & DexAttr.FEMALE);
|
|
||||||
this.canCycleGender = isMaleCaught && isFemaleCaught;
|
this.canCycleGender = isMaleCaught && isFemaleCaught;
|
||||||
|
|
||||||
const hasAbility1 = abilityAttr & AbilityAttr.ABILITY_1;
|
const hasAbility1 = abilityAttr & AbilityAttr.ABILITY_1;
|
||||||
let hasAbility2 = abilityAttr & AbilityAttr.ABILITY_2;
|
let hasAbility2 = abilityAttr & AbilityAttr.ABILITY_2;
|
||||||
const hasHiddenAbility = abilityAttr & AbilityAttr.ABILITY_HIDDEN;
|
const hasHiddenAbility = abilityAttr & AbilityAttr.ABILITY_HIDDEN;
|
||||||
@ -3038,11 +3061,10 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.canCycleAbility = [ hasAbility1, hasAbility2, hasHiddenAbility ].filter(a => a).length > 1;
|
this.canCycleAbility = [ hasAbility1, hasAbility2, hasHiddenAbility ].filter(a => a).length > 1;
|
||||||
|
|
||||||
this.canCycleForm = species.forms.filter(f => f.isStarterSelectable || !pokemonFormChanges[species.speciesId]?.find(fc => fc.formKey))
|
this.canCycleForm = species.forms.filter(f => f.isStarterSelectable || !pokemonFormChanges[species.speciesId]?.find(fc => fc.formKey))
|
||||||
.map((_, f) => dexEntry.caughtAttr & this.scene.gameData.getFormAttr(f)).filter(f => f).length > 1;
|
.map((_, f) => dexEntry.caughtAttr & this.scene.gameData.getFormAttr(f)).filter(f => f).length > 1;
|
||||||
this.canCycleNature = this.scene.gameData.getNaturesForAttr(dexEntry.natureAttr).length > 1;
|
this.canCycleNature = this.scene.gameData.getNaturesForAttr(dexEntry.natureAttr).length > 1;
|
||||||
|
this.canCycleVariant = !!shiny && [ dexEntry.caughtAttr & DexAttr.DEFAULT_VARIANT, dexEntry.caughtAttr & DexAttr.VARIANT_2, dexEntry.caughtAttr & DexAttr.VARIANT_3].filter(v => v).length > 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dexEntry.caughtAttr && species.malePercent !== null) {
|
if (dexEntry.caughtAttr && species.malePercent !== null) {
|
||||||
@ -3420,55 +3442,39 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
return canStart;
|
return canStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/* this creates a temporary dex attr props that we use to check whether a pokemon is valid for a challenge.
|
||||||
* Creates a temporary dex attr props that will be used to check whether a pokemon is valid for a challenge
|
* when checking for certain challenges (i.e. mono type), we need to check for form changes AND evolutions
|
||||||
* and to display the correct shiny, variant, and form based on the StarterPreferences
|
* However, since some pokemon can evolve based on their intial gender/form, we need a way to look for that
|
||||||
*
|
* This temporary dex attr will therefore ONLY look at gender and form, since there's no cases of shinies/variants
|
||||||
* @param speciesId the id of the species to get props for
|
* having different evolutions to their non shiny/variant part, and so those can be ignored
|
||||||
* @returns the dex props
|
* Since the current form and gender is stored in the starter preferences, this is where we get the values from
|
||||||
*/
|
*/
|
||||||
getCurrentDexProps(speciesId: number): bigint {
|
getCurrentDexProps(speciesId: number): bigint {
|
||||||
let props = 0n;
|
let props = 0n;
|
||||||
const caughtAttr = this.scene.gameData.dexData[speciesId].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
|
if (this.starterPreferences[speciesId]?.female) { // this checks the gender of the pokemon
|
||||||
* 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.starterPreferences[speciesId]?.female || ((caughtAttr & DexAttr.FEMALE) > 0n && (caughtAttr & DexAttr.MALE) === 0n)) {
|
|
||||||
props += DexAttr.FEMALE;
|
props += DexAttr.FEMALE;
|
||||||
} else {
|
} else {
|
||||||
props += DexAttr.MALE;
|
props += DexAttr.MALE;
|
||||||
}
|
}
|
||||||
/* This part is very similar to above, but instead of for gender, it checks for shiny within starter preferences.
|
if (this.starterPreferences[speciesId]?.shiny) {
|
||||||
* If they're not there, it checks the caughtAttr for shiny only (i.e. SHINY === true && NON_SHINY === false)
|
|
||||||
*/
|
|
||||||
if (this.starterPreferences[speciesId]?.shiny || ((caughtAttr & DexAttr.SHINY) > 0n && (caughtAttr & DexAttr.NON_SHINY) === 0n)) {
|
|
||||||
props += DexAttr.SHINY;
|
props += DexAttr.SHINY;
|
||||||
if (this.starterPreferences[speciesId]?.variant) {
|
if (this.starterPreferences[speciesId]?.variant) {
|
||||||
props += BigInt(Math.pow(2, this.starterPreferences[speciesId]?.variant)) * DexAttr.DEFAULT_VARIANT;
|
props += BigInt(Math.pow(2, this.starterPreferences[speciesId]?.variant)) * DexAttr.DEFAULT_VARIANT;
|
||||||
} else {
|
} else {
|
||||||
/* This calculates the correct variant if there's no starter preferences for it.
|
props += DexAttr.DEFAULT_VARIANT;
|
||||||
* This gets the lowest tier variant that you've caught (in line with other mechanics) and adds it to the temp props
|
|
||||||
*/
|
|
||||||
if ((caughtAttr & DexAttr.DEFAULT_VARIANT) > 0) {
|
|
||||||
props += DexAttr.DEFAULT_VARIANT;
|
|
||||||
}
|
|
||||||
if ((caughtAttr & DexAttr.VARIANT_2) > 0) {
|
|
||||||
props += DexAttr.VARIANT_2;
|
|
||||||
} else if ((caughtAttr & DexAttr.VARIANT_3) > 0) {
|
|
||||||
props += DexAttr.VARIANT_3;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
props += DexAttr.NON_SHINY;
|
props += DexAttr.NON_SHINY;
|
||||||
|
if (this.starterPreferences[speciesId]?.variant) {
|
||||||
|
delete this.starterPreferences[speciesId].variant;
|
||||||
|
}
|
||||||
props += DexAttr.DEFAULT_VARIANT; // we add the default variant here because non shiny versions are listed as default variant
|
props += DexAttr.DEFAULT_VARIANT; // we add the default variant here because non shiny versions are listed as default variant
|
||||||
}
|
}
|
||||||
if (this.starterPreferences[speciesId]?.form) { // this checks for the form of the pokemon
|
if (this.starterPreferences[speciesId]?.form) { // 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]?.form)) * DexAttr.DEFAULT_FORM;
|
||||||
} else {
|
} else {
|
||||||
// Get the first unlocked form
|
props += DexAttr.DEFAULT_FORM;
|
||||||
props += this.scene.gameData.getFormAttr(this.scene.gameData.getFormIndex(caughtAttr));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return props;
|
return props;
|
||||||
|
@ -1,147 +0,0 @@
|
|||||||
import { FormModalUiHandler } from "./form-modal-ui-handler";
|
|
||||||
import { ModalConfig } from "./modal-ui-handler";
|
|
||||||
import i18next from "i18next";
|
|
||||||
import { PlayerPokemon } from "#app/field/pokemon";
|
|
||||||
import { OptionSelectItem } from "./abstact-option-select-ui-handler";
|
|
||||||
import { isNullOrUndefined } from "#app/utils";
|
|
||||||
import { Mode } from "./ui";
|
|
||||||
|
|
||||||
export default class TestDialogueUiHandler extends FormModalUiHandler {
|
|
||||||
|
|
||||||
keys: string[];
|
|
||||||
|
|
||||||
constructor(scene, mode) {
|
|
||||||
super(scene, mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
setup() {
|
|
||||||
super.setup();
|
|
||||||
|
|
||||||
const flattenKeys = (object, topKey?: string, midleKey?: string[]): Array<any> => {
|
|
||||||
return Object.keys(object).map((t, i) => {
|
|
||||||
const value = Object.values(object)[i];
|
|
||||||
|
|
||||||
if (typeof value === "object" && !isNullOrUndefined(value)) { // we check for not null or undefined here because if the language json file has a null key, the typeof will still be an object, but that object will be null, causing issues
|
|
||||||
// If the value is an object, execute the same process
|
|
||||||
// si el valor es un objeto ejecuta el mismo proceso
|
|
||||||
|
|
||||||
return flattenKeys(value, topKey ?? t, topKey ? midleKey ? [...midleKey, t] : [t] : undefined).filter((t) => t.length > 0);
|
|
||||||
} else if (typeof value === "string" || isNullOrUndefined(value)) { // we check for null or undefined here as per above - the typeof is still an object but the value is null so we need to exit out of this and pass the null key
|
|
||||||
|
|
||||||
// Return in the format expected by i18next
|
|
||||||
return midleKey ? `${topKey}:${midleKey.map((m) => m).join(".")}.${t}` : `${topKey}:${t}`;
|
|
||||||
}
|
|
||||||
}).filter((t) => t);
|
|
||||||
};
|
|
||||||
|
|
||||||
const keysInArrays = flattenKeys(i18next.getDataByLanguage(String(i18next.resolvedLanguage))).filter((t) => t.length > 0); // Array of arrays
|
|
||||||
const keys = keysInArrays.flat(Infinity).map(String); // One array of string
|
|
||||||
this.keys = keys;
|
|
||||||
}
|
|
||||||
|
|
||||||
getModalTitle(config?: ModalConfig): string {
|
|
||||||
return "Test Dialogue";
|
|
||||||
}
|
|
||||||
|
|
||||||
getFields(config?: ModalConfig): string[] {
|
|
||||||
return [ "Dialogue" ];
|
|
||||||
}
|
|
||||||
|
|
||||||
getWidth(config?: ModalConfig): number {
|
|
||||||
return 300;
|
|
||||||
}
|
|
||||||
|
|
||||||
getMargin(config?: ModalConfig): [number, number, number, number] {
|
|
||||||
return [ 0, 0, 48, 0 ];
|
|
||||||
}
|
|
||||||
|
|
||||||
getButtonLabels(config?: ModalConfig): string[] {
|
|
||||||
return [ "Check", "Cancel" ];
|
|
||||||
}
|
|
||||||
|
|
||||||
getReadableErrorMessage(error: string): string {
|
|
||||||
const colonIndex = error?.indexOf(":");
|
|
||||||
if (colonIndex > 0) {
|
|
||||||
error = error.slice(0, colonIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.getReadableErrorMessage(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
show(args: any[]): boolean {
|
|
||||||
const ui = this.getUi();
|
|
||||||
const input = this.inputs[0];
|
|
||||||
input.setMaxLength(255);
|
|
||||||
|
|
||||||
input.on("keydown", (inputObject, evt: KeyboardEvent) => {
|
|
||||||
if (["escape", "space"].some((v) => v === evt.key.toLowerCase() || v === evt.code.toLowerCase()) && ui.getMode() === Mode.AUTO_COMPLETE) {
|
|
||||||
// Delete autocomplete list and recovery focus.
|
|
||||||
inputObject.on("blur", () => inputObject.node.focus(), { once: true });
|
|
||||||
ui.revertMode();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
input.on("textchange", (inputObject, evt: InputEvent) => {
|
|
||||||
// Delete autocomplete.
|
|
||||||
if (ui.getMode() === Mode.AUTO_COMPLETE) {
|
|
||||||
ui.revertMode();
|
|
||||||
}
|
|
||||||
|
|
||||||
let options: OptionSelectItem[] = [];
|
|
||||||
const splitArr = inputObject.text.split(" ");
|
|
||||||
const filteredKeys = this.keys.filter((command) => command.toLowerCase().includes(splitArr[splitArr.length - 1].toLowerCase()));
|
|
||||||
if (inputObject.text !== "" && filteredKeys.length > 0) {
|
|
||||||
// if performance is required, you could reduce the number of total results by changing the slice below to not have all ~8000 inputs going
|
|
||||||
options = filteredKeys.slice(0).map((value) => {
|
|
||||||
return {
|
|
||||||
label: value,
|
|
||||||
handler: () => {
|
|
||||||
// this is here to make sure that if you try to backspace then enter, the last known evt.data (backspace) is picked up
|
|
||||||
// this is because evt.data is null for backspace, so without this, the autocomplete windows just closes
|
|
||||||
if (!isNullOrUndefined(evt.data) || evt.inputType?.toLowerCase() === "deletecontentbackward") {
|
|
||||||
const separatedArray = inputObject.text.split(" ");
|
|
||||||
separatedArray[separatedArray.length - 1] = value;
|
|
||||||
inputObject.setText(separatedArray.join(" "));
|
|
||||||
}
|
|
||||||
ui.revertMode();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.length > 0) {
|
|
||||||
const modalOpts = {
|
|
||||||
options: options,
|
|
||||||
maxOptions: 5,
|
|
||||||
modalContainer: this.modalContainer
|
|
||||||
};
|
|
||||||
ui.setOverlayMode(Mode.AUTO_COMPLETE, modalOpts);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
if (super.show(args)) {
|
|
||||||
const config = args[0] as ModalConfig;
|
|
||||||
this.inputs[0].resize(1150, 116);
|
|
||||||
this.inputContainers[0].list[0].width = 200;
|
|
||||||
if (args[1] && typeof (args[1] as PlayerPokemon).getNameToRender === "function") {
|
|
||||||
this.inputs[0].text = (args[1] as PlayerPokemon).getNameToRender();
|
|
||||||
} else {
|
|
||||||
this.inputs[0].text = args[1];
|
|
||||||
}
|
|
||||||
this.submitAction = (_) => {
|
|
||||||
if (ui.getMode() === Mode.TEST_DIALOGUE) {
|
|
||||||
this.sanitizeInputs();
|
|
||||||
const sanitizedName = btoa(unescape(encodeURIComponent(this.inputs[0].text)));
|
|
||||||
config.buttonActions[0](sanitizedName);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
@ -49,8 +49,6 @@ import RenameFormUiHandler from "./rename-form-ui-handler";
|
|||||||
import AdminUiHandler from "./admin-ui-handler";
|
import AdminUiHandler from "./admin-ui-handler";
|
||||||
import RunHistoryUiHandler from "./run-history-ui-handler";
|
import RunHistoryUiHandler from "./run-history-ui-handler";
|
||||||
import RunInfoUiHandler from "./run-info-ui-handler";
|
import RunInfoUiHandler from "./run-info-ui-handler";
|
||||||
import TestDialogueUiHandler from "#app/ui/test-dialogue-ui-handler";
|
|
||||||
import AutoCompleteUiHandler from "./autocomplete-ui-handler";
|
|
||||||
|
|
||||||
export enum Mode {
|
export enum Mode {
|
||||||
MESSAGE,
|
MESSAGE,
|
||||||
@ -91,8 +89,6 @@ export enum Mode {
|
|||||||
RENAME_POKEMON,
|
RENAME_POKEMON,
|
||||||
RUN_HISTORY,
|
RUN_HISTORY,
|
||||||
RUN_INFO,
|
RUN_INFO,
|
||||||
TEST_DIALOGUE,
|
|
||||||
AUTO_COMPLETE,
|
|
||||||
ADMIN,
|
ADMIN,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,8 +127,6 @@ const noTransitionModes = [
|
|||||||
Mode.UNAVAILABLE,
|
Mode.UNAVAILABLE,
|
||||||
Mode.OUTDATED,
|
Mode.OUTDATED,
|
||||||
Mode.RENAME_POKEMON,
|
Mode.RENAME_POKEMON,
|
||||||
Mode.TEST_DIALOGUE,
|
|
||||||
Mode.AUTO_COMPLETE,
|
|
||||||
Mode.ADMIN,
|
Mode.ADMIN,
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -197,8 +191,6 @@ export default class UI extends Phaser.GameObjects.Container {
|
|||||||
new RenameFormUiHandler(scene),
|
new RenameFormUiHandler(scene),
|
||||||
new RunHistoryUiHandler(scene),
|
new RunHistoryUiHandler(scene),
|
||||||
new RunInfoUiHandler(scene),
|
new RunInfoUiHandler(scene),
|
||||||
new TestDialogueUiHandler(scene, Mode.TEST_DIALOGUE),
|
|
||||||
new AutoCompleteUiHandler(scene),
|
|
||||||
new AdminUiHandler(scene),
|
new AdminUiHandler(scene),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user