Rework option select and add game stats
This commit is contained in:
1 parent
13aa20630d
commit
fcf1c4f574
14 files changed
+585
-169
No files matched your search
@@ -4,13 +4,25 @@ import { Mode } from "./ui";
|
||||
import UiHandler from "./ui-handler";
|
||||
import { addWindow } from "./window";
|
||||
|
||||
export default abstract class AbstractOptionSelectUiHandler extends UiHandler {
|
||||
protected handlers: Function[];
|
||||
export interface OptionSelectConfig {
|
||||
xOffset?: number;
|
||||
options: OptionSelectItem[];
|
||||
}
|
||||
|
||||
export interface OptionSelectItem {
|
||||
label: string;
|
||||
handler: Function;
|
||||
keepOpen?: boolean;
|
||||
overrideSound?: boolean;
|
||||
}
|
||||
|
||||
export default abstract class AbstractOptionSelectUiHandler extends UiHandler {
|
||||
protected optionSelectContainer: Phaser.GameObjects.Container;
|
||||
protected optionSelectBg: Phaser.GameObjects.NineSlice;
|
||||
protected optionSelectText: Phaser.GameObjects.Text;
|
||||
|
||||
protected config: OptionSelectConfig;
|
||||
|
||||
private cursorObj: Phaser.GameObjects.Image;
|
||||
|
||||
constructor(scene: BattleScene, mode?: Mode) {
|
||||
@@ -19,9 +31,9 @@ export default abstract class AbstractOptionSelectUiHandler extends UiHandler {
|
||||
|
||||
abstract getWindowWidth(): integer;
|
||||
|
||||
abstract getWindowHeight(): integer;
|
||||
|
||||
abstract getOptions(): string[];
|
||||
getWindowHeight(): integer {
|
||||
return ((this.config?.options || []).length + 1) * 16;
|
||||
}
|
||||
|
||||
setup() {
|
||||
const ui = this.getUi();
|
||||
@@ -34,19 +46,19 @@ export default abstract class AbstractOptionSelectUiHandler extends UiHandler {
|
||||
this.optionSelectBg.setOrigin(1, 1);
|
||||
this.optionSelectContainer.add(this.optionSelectBg);
|
||||
|
||||
this.setupOptions();
|
||||
this.setCursor(0);
|
||||
}
|
||||
|
||||
protected setupOptions() {
|
||||
const options = this.getOptions();
|
||||
const options = this.config?.options || [];
|
||||
|
||||
if (this.optionSelectText)
|
||||
this.optionSelectText.destroy();
|
||||
|
||||
this.optionSelectText = addTextObject(this.scene, 0, 0, options.join('\n'), TextStyle.WINDOW, { maxLines: options.length });
|
||||
this.optionSelectText = addTextObject(this.scene, 0, 0, options.map(o => o.label).join('\n'), TextStyle.WINDOW, { maxLines: options.length });
|
||||
this.optionSelectText.setLineSpacing(12);
|
||||
this.optionSelectContainer.add(this.optionSelectText);
|
||||
this.optionSelectContainer.x = (this.scene.game.canvas.width / 6) - 1 - (this.config?.xOffset || 0);
|
||||
|
||||
this.optionSelectBg.width = Math.max(this.optionSelectText.displayWidth + 24, this.getWindowWidth());
|
||||
this.optionSelectBg.height = this.getWindowHeight();
|
||||
@@ -55,20 +67,20 @@ export default abstract class AbstractOptionSelectUiHandler extends UiHandler {
|
||||
}
|
||||
|
||||
show(args: any[]): boolean {
|
||||
const options = this.getOptions();
|
||||
if (!args.length || !args[0].hasOwnProperty('options') || !args[0].options.length)
|
||||
return false;
|
||||
|
||||
if (args.length >= options.length && args.slice(0, options.length).filter(a => a instanceof Function).length === options.length) {
|
||||
super.show(args);
|
||||
|
||||
this.handlers = args.slice(0, options.length) as Function[];
|
||||
super.show(args);
|
||||
|
||||
this.optionSelectContainer.setVisible(true);
|
||||
this.setCursor(0);
|
||||
this.config = args[0] as OptionSelectConfig;
|
||||
this.setupOptions();
|
||||
|
||||
return true;
|
||||
}
|
||||
this.scene.ui.bringToTop(this.optionSelectContainer);
|
||||
|
||||
return false;
|
||||
this.optionSelectContainer.setVisible(true);
|
||||
this.setCursor(0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
processInput(button: Button): boolean {
|
||||
@@ -76,15 +88,19 @@ export default abstract class AbstractOptionSelectUiHandler extends UiHandler {
|
||||
|
||||
let success = false;
|
||||
|
||||
const options = this.getOptions();
|
||||
const options = this.config?.options || [];
|
||||
|
||||
let playSound = true;
|
||||
|
||||
if (button === Button.ACTION || button === Button.CANCEL) {
|
||||
success = true;
|
||||
if (button === Button.CANCEL)
|
||||
this.setCursor(options.length - 1);
|
||||
const handler = this.handlers[this.cursor];
|
||||
handler();
|
||||
this.clear();
|
||||
const option = options[this.cursor];
|
||||
option.handler();
|
||||
if (!option.keepOpen)
|
||||
this.clear();
|
||||
playSound = !option.overrideSound;
|
||||
} else {
|
||||
switch (button) {
|
||||
case Button.UP:
|
||||
@@ -98,7 +114,7 @@ export default abstract class AbstractOptionSelectUiHandler extends UiHandler {
|
||||
}
|
||||
}
|
||||
|
||||
if (success)
|
||||
if (success && playSound)
|
||||
ui.playSelect();
|
||||
|
||||
return success;
|
||||
@@ -119,8 +135,7 @@ export default abstract class AbstractOptionSelectUiHandler extends UiHandler {
|
||||
|
||||
clear() {
|
||||
super.clear();
|
||||
for (let h = 0; h < this.handlers.length; h++)
|
||||
this.handlers[h] = null;
|
||||
this.config = null;
|
||||
this.optionSelectContainer.setVisible(false);
|
||||
this.eraseCursor();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import BattleScene from "../battle-scene";
|
||||
import AbstractOptionSelectUiHandler from "./abstact-option-select-ui-handler";
|
||||
import AbstractOptionSelectUiHandler, { OptionSelectConfig } from "./abstact-option-select-ui-handler";
|
||||
import { Mode } from "./ui";
|
||||
|
||||
export default class ConfirmUiHandler extends AbstractOptionSelectUiHandler {
|
||||
@@ -14,17 +14,22 @@ export default class ConfirmUiHandler extends AbstractOptionSelectUiHandler {
|
||||
return 48;
|
||||
}
|
||||
|
||||
getWindowHeight(): integer {
|
||||
return 48;
|
||||
}
|
||||
|
||||
getOptions(): string[] {
|
||||
return [ 'Yes', 'No' ];
|
||||
}
|
||||
|
||||
show(args: any[]): boolean {
|
||||
if (args.length >= 2 && args[0] instanceof Function && args[1] instanceof Function) {
|
||||
super.show(args);
|
||||
const config: OptionSelectConfig = {
|
||||
options: [
|
||||
{
|
||||
label: 'Yes',
|
||||
handler: args[0]
|
||||
},
|
||||
{
|
||||
label: 'No',
|
||||
handler: args[1]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
super.show([ config ]);
|
||||
|
||||
this.switchCheck = args.length >= 3 && args[2] as boolean;
|
||||
|
||||
|
||||
@@ -346,10 +346,25 @@ export default class EggGachaUiHandler extends MessageUiHandler {
|
||||
|
||||
for (let tier of tiers) {
|
||||
const egg = new Egg(Utils.randInt(EGG_SEED, EGG_SEED * tier), this.gachaCursor, getEggTierDefaultHatchWaves(tier), timestamp);
|
||||
if (egg.isManaphyEgg())
|
||||
if (egg.isManaphyEgg()) {
|
||||
this.scene.gameData.gameStats.manaphyEggsPulled++;
|
||||
egg.hatchWaves = getEggTierDefaultHatchWaves(ModifierTier.ULTRA);
|
||||
} else {
|
||||
switch (tier) {
|
||||
case ModifierTier.GREAT:
|
||||
this.scene.gameData.gameStats.rareEggsPulled++;
|
||||
break;
|
||||
case ModifierTier.ULTRA:
|
||||
this.scene.gameData.gameStats.epicEggsPulled++;
|
||||
break;
|
||||
case ModifierTier.MASTER:
|
||||
this.scene.gameData.gameStats.legendaryEggsPulled++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
eggs.push(egg);
|
||||
this.scene.gameData.eggs.push(egg);
|
||||
this.scene.gameData.gameStats.eggsPulled++;
|
||||
}
|
||||
|
||||
this.scene.gameData.saveSystem().then(success => {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import BattleScene, { Button } from "../battle-scene";
|
||||
import BattleScene from "../battle-scene";
|
||||
import { GameMode, gameModeNames } from "../game-mode";
|
||||
import { Unlockables } from "../system/unlockables";
|
||||
import AbstractOptionSelectUiHandler from "./abstact-option-select-ui-handler";
|
||||
import AbstractOptionSelectUiHandler, { OptionSelectConfig, OptionSelectItem } from "./abstact-option-select-ui-handler";
|
||||
import { Mode } from "./ui";
|
||||
|
||||
export default class GameModeSelectUiHandler extends AbstractOptionSelectUiHandler {
|
||||
@@ -14,28 +14,38 @@ export default class GameModeSelectUiHandler extends AbstractOptionSelectUiHandl
|
||||
return 104;
|
||||
}
|
||||
|
||||
getWindowHeight(): number {
|
||||
return (this.getOptions().length + 1) * 16;
|
||||
}
|
||||
|
||||
getOptions(): string[] {
|
||||
const ret = [ gameModeNames[GameMode.CLASSIC] ];
|
||||
if (this.scene.gameData.unlocks[Unlockables.ENDLESS_MODE]) {
|
||||
ret.push(gameModeNames[GameMode.ENDLESS]);
|
||||
if (this.scene.gameData.unlocks[Unlockables.SPLICED_ENDLESS_MODE])
|
||||
ret.push(gameModeNames[GameMode.SPLICED_ENDLESS]);
|
||||
}
|
||||
ret.push('Cancel');
|
||||
return ret;
|
||||
}
|
||||
|
||||
show(args: any[]): boolean {
|
||||
if (args.length === 2 && args[0] instanceof Function && args[1] instanceof Function) {
|
||||
this.setupOptions();
|
||||
const options: OptionSelectItem[] = [
|
||||
{
|
||||
label: gameModeNames[GameMode.CLASSIC],
|
||||
handler: () => args[0](GameMode.CLASSIC)
|
||||
}
|
||||
];
|
||||
|
||||
if (this.scene.gameData.unlocks[Unlockables.ENDLESS_MODE]) {
|
||||
options.push({
|
||||
label: gameModeNames[GameMode.ENDLESS],
|
||||
handler: () => args[0](GameMode.ENDLESS)
|
||||
});
|
||||
if (this.scene.gameData.unlocks[Unlockables.SPLICED_ENDLESS_MODE]) {
|
||||
options.push({
|
||||
label: gameModeNames[GameMode.SPLICED_ENDLESS],
|
||||
handler: () => args[0](GameMode.SPLICED_ENDLESS)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
options.push({
|
||||
label: 'Cancel',
|
||||
handler: args[1]
|
||||
})
|
||||
|
||||
const config: OptionSelectConfig = {
|
||||
options: options
|
||||
};
|
||||
|
||||
super.show(args);
|
||||
|
||||
this.handlers = args as Function[];
|
||||
super.show([ config ]);
|
||||
|
||||
this.optionSelectContainer.setVisible(true);
|
||||
this.setCursor(0);
|
||||
@@ -45,25 +55,4 @@ export default class GameModeSelectUiHandler extends AbstractOptionSelectUiHandl
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
processInput(button: Button): boolean {
|
||||
const ui = this.getUi();
|
||||
|
||||
const options = this.getOptions();
|
||||
|
||||
if (button === Button.ACTION || button === Button.CANCEL) {
|
||||
if (button === Button.CANCEL)
|
||||
this.setCursor(options.length - 1);
|
||||
if (this.cursor < options.length - 1) {
|
||||
const gameMode = Object.values(gameModeNames).indexOf(options[this.cursor]) as GameMode;
|
||||
this.handlers[0](gameMode);
|
||||
} else
|
||||
this.handlers[1]();
|
||||
this.clear();
|
||||
ui.playSelect();
|
||||
} else
|
||||
return super.processInput(button);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,241 @@
|
||||
import BattleScene, { Button } from "../battle-scene";
|
||||
import { GameStats } from "../system/game-stats";
|
||||
import { TextStyle, addTextObject, getTextColor } from "./text";
|
||||
import { Mode } from "./ui";
|
||||
import UiHandler from "./ui-handler";
|
||||
import { addWindow } from "./window";
|
||||
import * as Utils from "../utils";
|
||||
import { GameData } from "../system/game-data";
|
||||
import { speciesStarters } from "../data/pokemon-species";
|
||||
|
||||
interface DisplayStat {
|
||||
label?: string;
|
||||
sourceFunc?: (gameData: GameData) => string;
|
||||
hidden?: boolean;
|
||||
}
|
||||
|
||||
interface DisplayStats {
|
||||
[key: string]: DisplayStat | string
|
||||
}
|
||||
|
||||
const secondsInHour = 3600;
|
||||
|
||||
const displayStats: DisplayStats = {
|
||||
playTime: {
|
||||
sourceFunc: gameData => {
|
||||
const totalSeconds = gameData.gameStats.playTime;
|
||||
|
||||
const days = `${Math.floor(totalSeconds / (secondsInHour * 24))}`;
|
||||
const hours = `${Math.floor(totalSeconds % (secondsInHour * 24) / secondsInHour)}`;
|
||||
const minutes = `${Math.floor(totalSeconds % secondsInHour / 60)}`;
|
||||
const seconds = `${Math.floor(totalSeconds % 60)}`;
|
||||
|
||||
return `${days.padStart(2, '0')}:${hours.padStart(2, '0')}:${minutes.padStart(2, '0')}:${seconds.padStart(2, '0')}`;
|
||||
}
|
||||
},
|
||||
battles: 'Total Battles',
|
||||
startersUnlocked: {
|
||||
label: 'Starters',
|
||||
sourceFunc: gameData => {
|
||||
const starterKeys = Object.keys(speciesStarters);
|
||||
let starterCount = 0;
|
||||
for (let s of starterKeys) {
|
||||
if (gameData.dexData[s].caughtAttr)
|
||||
starterCount++;
|
||||
}
|
||||
return `${starterCount} (${Math.floor((starterCount / starterKeys.length) * 1000) / 10}%)`;
|
||||
}
|
||||
},
|
||||
classicSessionsPlayed: 'Runs (Classic)',
|
||||
sessionsWon: 'Runs (Classic)',
|
||||
endlessSessionsPlayed: 'Runs (Endless)?',
|
||||
highestEndlessWave: 'Highest Wave (Endless)?',
|
||||
highestMoney: 'Highest Money',
|
||||
pokemonSeen: 'Pokémon Encountered',
|
||||
pokemonDefeated: 'Pokémon Defeated',
|
||||
pokemonCaught: 'Pokémon Caught',
|
||||
pokemonHatched: 'Eggs Hatched',
|
||||
legendaryPokemonSeen: 'Legendary Encounters?',
|
||||
legendaryPokemonCaught: 'Legendaries Caught?',
|
||||
legendaryPokemonHatched: 'Legendaries Hatched?',
|
||||
mythicalPokemonSeen: 'Mythical Encounters?',
|
||||
mythicalPokemonCaught: 'Mythicals Caught?',
|
||||
mythicalPokemonHatched: 'Mythicals Hatched?',
|
||||
shinyPokemonSeen: 'Shiny Encounters?',
|
||||
shinyPokemonCaught: 'Shinies Caught?',
|
||||
shinyPokemonHatched: 'Shinies Hatched?',
|
||||
pokemonFused: 'Pokémon Fused?',
|
||||
trainersDefeated: 'Trainers Defeated',
|
||||
eggsPulled: 'Eggs Pulled',
|
||||
rareEggsPulled: 'Rare Eggs Pulled?',
|
||||
epicEggsPulled: 'Epic Eggs Pulled?',
|
||||
legendaryEggsPulled: 'Legendary Eggs Pulled?',
|
||||
manaphyEggsPulled: 'Manaphy Eggs Pulled?'
|
||||
};
|
||||
|
||||
export default class GameStatsUiHandler extends UiHandler {
|
||||
private gameStatsContainer: Phaser.GameObjects.Container;
|
||||
private statsContainer: Phaser.GameObjects.Container;
|
||||
|
||||
private statLabels: Phaser.GameObjects.Text[];
|
||||
private statValues: Phaser.GameObjects.Text[];
|
||||
|
||||
constructor(scene: BattleScene, mode?: Mode) {
|
||||
super(scene, mode);
|
||||
|
||||
this.statLabels = [];
|
||||
this.statValues = [];
|
||||
}
|
||||
|
||||
setup() {
|
||||
const ui = this.getUi();
|
||||
|
||||
this.gameStatsContainer = this.scene.add.container(1, -(this.scene.game.canvas.height / 6) + 1);
|
||||
|
||||
this.gameStatsContainer.setInteractive(new Phaser.Geom.Rectangle(0, 0, this.scene.game.canvas.width / 6, this.scene.game.canvas.height / 6), Phaser.Geom.Rectangle.Contains);
|
||||
|
||||
const headerBg = addWindow(this.scene, 0, 0, (this.scene.game.canvas.width / 6) - 2, 24);
|
||||
headerBg.setOrigin(0, 0);
|
||||
|
||||
const headerText = addTextObject(this.scene, 0, 0, 'Stats', TextStyle.SETTINGS_LABEL);
|
||||
headerText.setOrigin(0, 0);
|
||||
headerText.setPositionRelative(headerBg, 8, 4);
|
||||
|
||||
const statsBgWidth = ((this.scene.game.canvas.width / 6) - 2) / 2;
|
||||
const [ statsBgLeft, statsBgRight ] = new Array(2).fill(null).map((_, i) => {
|
||||
let width = statsBgWidth;
|
||||
if (!i)
|
||||
width += 5;
|
||||
const statsBg = addWindow(this.scene, statsBgWidth * i, headerBg.height, width, (this.scene.game.canvas.height / 6) - headerBg.height - 2, false, !!i, 2);
|
||||
statsBg.setOrigin(0, 0);
|
||||
return statsBg;
|
||||
});
|
||||
|
||||
this.statsContainer = this.scene.add.container(0, 0);
|
||||
|
||||
new Array(18).fill(null).map((_, s) => {
|
||||
const statLabel = addTextObject(this.scene, 8 + (s % 2 === 1 ? statsBgWidth : 0), 28 + Math.floor(s / 2) * 16, '', TextStyle.SETTINGS_LABEL);
|
||||
statLabel.setOrigin(0, 0);
|
||||
this.statsContainer.add(statLabel);
|
||||
this.statLabels.push(statLabel);
|
||||
|
||||
const statValue = addTextObject(this.scene, (statsBgWidth * ((s % 2) + 1)) - 8, statLabel.y, '', TextStyle.WINDOW);
|
||||
statValue.setOrigin(1, 0);
|
||||
this.statsContainer.add(statValue);
|
||||
this.statValues.push(statValue);
|
||||
});
|
||||
|
||||
this.gameStatsContainer.add(headerBg);
|
||||
this.gameStatsContainer.add(headerText);
|
||||
this.gameStatsContainer.add(statsBgLeft);
|
||||
this.gameStatsContainer.add(statsBgRight);
|
||||
this.gameStatsContainer.add(this.statsContainer);
|
||||
|
||||
ui.add(this.gameStatsContainer);
|
||||
|
||||
this.setCursor(0);
|
||||
|
||||
this.gameStatsContainer.setVisible(false);
|
||||
}
|
||||
|
||||
show(args: any[]): boolean {
|
||||
super.show(args);
|
||||
|
||||
this.setCursor(0);
|
||||
|
||||
this.updateStats();
|
||||
|
||||
this.gameStatsContainer.setVisible(true);
|
||||
|
||||
this.getUi().moveTo(this.gameStatsContainer, this.getUi().length - 1);
|
||||
|
||||
this.getUi().hideTooltip();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
updateStats(): void {
|
||||
const statKeys = Object.keys(displayStats).slice(this.cursor * 2, this.cursor * 2 + 18);
|
||||
statKeys.forEach((key, s) => {
|
||||
const stat = displayStats[key] as DisplayStat;
|
||||
const value = stat.sourceFunc(this.scene.gameData);
|
||||
this.statLabels[s].setText(!stat.hidden || isNaN(parseInt(value)) || parseInt(value) ? stat.label : '???');
|
||||
this.statValues[s].setText(value);
|
||||
});
|
||||
if (statKeys.length < 18) {
|
||||
for (let s = statKeys.length; s < 18; s++) {
|
||||
this.statLabels[s].setText('');
|
||||
this.statValues[s].setText('');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
processInput(button: Button): boolean {
|
||||
const ui = this.getUi();
|
||||
|
||||
let success = false;
|
||||
|
||||
if (button === Button.CANCEL) {
|
||||
success = true;
|
||||
this.scene.ui.revertMode();
|
||||
} else {
|
||||
switch (button) {
|
||||
case Button.UP:
|
||||
if (this.cursor)
|
||||
success = this.setCursor(this.cursor - 1);
|
||||
break;
|
||||
case Button.DOWN:
|
||||
if (this.cursor < Math.ceil((Object.keys(displayStats).length - 18) / 2))
|
||||
success = this.setCursor(this.cursor + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (success)
|
||||
ui.playSelect();
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
setCursor(cursor: integer): boolean {
|
||||
const ret = super.setCursor(cursor);
|
||||
|
||||
if (ret)
|
||||
this.updateStats();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
clear() {
|
||||
super.clear();
|
||||
this.gameStatsContainer.setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
(function () {
|
||||
const statKeys = Object.keys(displayStats);
|
||||
|
||||
for (let key of statKeys) {
|
||||
if (typeof displayStats[key] === 'string') {
|
||||
let label = displayStats[key] as string;
|
||||
let hidden = false;
|
||||
if (label.endsWith('?')) {
|
||||
label = label.slice(0, -1);
|
||||
hidden = true;
|
||||
}
|
||||
displayStats[key] = {
|
||||
label: label,
|
||||
sourceFunc: gameData => gameData.gameStats[key].toString(),
|
||||
hidden: hidden
|
||||
};
|
||||
} else if (displayStats[key] === null) {
|
||||
displayStats[key] = {
|
||||
sourceFunc: gameData => gameData.gameStats[key].toString()
|
||||
};
|
||||
}
|
||||
if (!(displayStats[key] as DisplayStat).label) {
|
||||
const splittableKey = key.replace(/([a-z]{2,})([A-Z]{1}(?:[^A-Z]|$))/g, '$1_$2');
|
||||
(displayStats[key] as DisplayStat).label = Utils.toReadableString(`${splittableKey[0].toUpperCase()}${splittableKey.slice(1)}`);
|
||||
}
|
||||
}
|
||||
})();
|
||||
+64
-27
@@ -5,17 +5,16 @@ import * as Utils from "../utils";
|
||||
import { addWindow } from "./window";
|
||||
import MessageUiHandler from "./message-ui-handler";
|
||||
import { GameDataType } from "../system/game-data";
|
||||
import { OptionSelectConfig } from "./abstact-option-select-ui-handler";
|
||||
|
||||
export enum MenuOptions {
|
||||
GAME_SETTINGS,
|
||||
ACHIEVEMENTS,
|
||||
STATS,
|
||||
VOUCHERS,
|
||||
EGG_LIST,
|
||||
EGG_GACHA,
|
||||
IMPORT_SESSION,
|
||||
EXPORT_SESSION,
|
||||
IMPORT_DATA,
|
||||
EXPORT_DATA,
|
||||
MANAGE_DATA,
|
||||
LOG_OUT
|
||||
}
|
||||
|
||||
@@ -31,12 +30,14 @@ export default class MenuUiHandler extends MessageUiHandler {
|
||||
protected ignoredMenuOptions: MenuOptions[];
|
||||
protected menuOptions: MenuOptions[];
|
||||
|
||||
protected manageDataConfig: OptionSelectConfig;
|
||||
|
||||
constructor(scene: BattleScene, mode?: Mode) {
|
||||
super(scene, mode);
|
||||
|
||||
this.ignoredMenuOptions = /*!bypassLogin */ false
|
||||
? [ MenuOptions.IMPORT_SESSION, MenuOptions.IMPORT_DATA ]
|
||||
: [];
|
||||
this.ignoredMenuOptions = !bypassLogin
|
||||
? [ ]
|
||||
: [ MenuOptions.LOG_OUT ];
|
||||
this.menuOptions = Utils.getEnumKeys(MenuOptions).map(m => parseInt(MenuOptions[m]) as MenuOptions).filter(m => this.ignoredMenuOptions.indexOf(m) === -1);
|
||||
}
|
||||
|
||||
@@ -76,6 +77,44 @@ export default class MenuUiHandler extends MessageUiHandler {
|
||||
|
||||
this.menuContainer.add(this.menuMessageBoxContainer);
|
||||
|
||||
const manageDataOptions = [];
|
||||
|
||||
if (bypassLogin) {
|
||||
manageDataOptions.push({
|
||||
label: 'Import Session',
|
||||
handler: () => this.scene.gameData.importData(GameDataType.SESSION),
|
||||
keepOpen: true
|
||||
});
|
||||
}
|
||||
manageDataOptions.push({
|
||||
label: 'Export Session',
|
||||
handler: () => this.scene.gameData.exportData(GameDataType.SESSION),
|
||||
keepOpen: true
|
||||
});
|
||||
if (bypassLogin) {
|
||||
manageDataOptions.push({
|
||||
label: 'Import Data',
|
||||
handler: () => this.scene.gameData.importData(GameDataType.SYSTEM),
|
||||
keepOpen: true
|
||||
});
|
||||
}
|
||||
manageDataOptions.push(
|
||||
{
|
||||
label: 'Export Data',
|
||||
handler: () => this.scene.gameData.exportData(GameDataType.SYSTEM),
|
||||
keepOpen: true
|
||||
},
|
||||
{
|
||||
label: 'Cancel',
|
||||
handler: () => this.scene.ui.revertMode()
|
||||
}
|
||||
);
|
||||
|
||||
this.manageDataConfig = {
|
||||
xOffset: 98,
|
||||
options: manageDataOptions
|
||||
};
|
||||
|
||||
this.setCursor(0);
|
||||
|
||||
this.menuContainer.setVisible(false);
|
||||
@@ -112,38 +151,36 @@ export default class MenuUiHandler extends MessageUiHandler {
|
||||
}
|
||||
switch (adjustedCursor) {
|
||||
case MenuOptions.GAME_SETTINGS:
|
||||
this.scene.ui.setOverlayMode(Mode.SETTINGS);
|
||||
ui.setOverlayMode(Mode.SETTINGS);
|
||||
success = true;
|
||||
break;
|
||||
case MenuOptions.ACHIEVEMENTS:
|
||||
this.scene.ui.setOverlayMode(Mode.ACHIEVEMENTS);
|
||||
ui.setOverlayMode(Mode.ACHIEVEMENTS);
|
||||
success = true;
|
||||
break;
|
||||
case MenuOptions.STATS:
|
||||
ui.setOverlayMode(Mode.GAME_STATS);
|
||||
success = true;
|
||||
break;
|
||||
case MenuOptions.VOUCHERS:
|
||||
this.scene.ui.setOverlayMode(Mode.VOUCHERS);
|
||||
ui.setOverlayMode(Mode.VOUCHERS);
|
||||
success = true;
|
||||
break;
|
||||
case MenuOptions.EGG_LIST:
|
||||
if (this.scene.gameData.eggs.length) {
|
||||
this.scene.ui.revertMode();
|
||||
this.scene.ui.setOverlayMode(Mode.EGG_LIST);
|
||||
ui.revertMode();
|
||||
ui.setOverlayMode(Mode.EGG_LIST);
|
||||
success = true;
|
||||
} else
|
||||
error = true;
|
||||
break;
|
||||
case MenuOptions.EGG_GACHA:
|
||||
this.scene.ui.revertMode();
|
||||
this.scene.ui.setOverlayMode(Mode.EGG_GACHA);
|
||||
ui.revertMode();
|
||||
ui.setOverlayMode(Mode.EGG_GACHA);
|
||||
success = true;
|
||||
break;
|
||||
case MenuOptions.IMPORT_SESSION:
|
||||
case MenuOptions.IMPORT_DATA:
|
||||
this.scene.gameData.importData(this.cursor === MenuOptions.IMPORT_DATA ? GameDataType.SYSTEM : GameDataType.SESSION);
|
||||
success = true;
|
||||
break;
|
||||
case MenuOptions.EXPORT_SESSION:
|
||||
case MenuOptions.EXPORT_DATA:
|
||||
this.scene.gameData.exportData(this.cursor === MenuOptions.EXPORT_DATA ? GameDataType.SYSTEM : GameDataType.SESSION);
|
||||
case MenuOptions.MANAGE_DATA:
|
||||
ui.setOverlayMode(Mode.OPTION_SELECT, this.manageDataConfig);
|
||||
success = true;
|
||||
break;
|
||||
case MenuOptions.LOG_OUT:
|
||||
@@ -157,10 +194,10 @@ export default class MenuUiHandler extends MessageUiHandler {
|
||||
});
|
||||
};
|
||||
if (this.scene.currentBattle) {
|
||||
this.scene.ui.showText('You will lose any progress since the beginning of the battle. Proceed?', null, () => {
|
||||
this.scene.ui.setOverlayMode(Mode.CONFIRM, doLogout, () => {
|
||||
this.scene.ui.revertMode();
|
||||
this.scene.ui.showText(null, 0);
|
||||
ui.showText('You will lose any progress since the beginning of the battle. Proceed?', null, () => {
|
||||
ui.setOverlayMode(Mode.CONFIRM, doLogout, () => {
|
||||
ui.revertMode();
|
||||
ui.showText(null, 0);
|
||||
}, false, 98);
|
||||
});
|
||||
} else
|
||||
@@ -169,7 +206,7 @@ export default class MenuUiHandler extends MessageUiHandler {
|
||||
}
|
||||
} else if (button === Button.CANCEL) {
|
||||
success = true;
|
||||
if (!this.scene.ui.revertMode())
|
||||
if (!ui.revertMode())
|
||||
ui.setMode(Mode.MESSAGE);
|
||||
} else {
|
||||
switch (button) {
|
||||
|
||||
@@ -3,8 +3,6 @@ import AbstractOptionSelectUiHandler from "./abstact-option-select-ui-handler";
|
||||
import { Mode } from "./ui";
|
||||
|
||||
export default class OptionSelectUiHandler extends AbstractOptionSelectUiHandler {
|
||||
private options: string[] = [];
|
||||
|
||||
constructor(scene: BattleScene) {
|
||||
super(scene, Mode.OPTION_SELECT);
|
||||
}
|
||||
@@ -12,28 +10,4 @@ export default class OptionSelectUiHandler extends AbstractOptionSelectUiHandler
|
||||
getWindowWidth(): integer {
|
||||
return 64;
|
||||
}
|
||||
|
||||
getWindowHeight(): integer {
|
||||
return (this.getOptions().length + 1) * 16;
|
||||
}
|
||||
|
||||
getOptions(): string[] {
|
||||
return this.options;
|
||||
}
|
||||
|
||||
show(args: any[]): boolean {
|
||||
if (args.length < 2 || args.length % 2 === 1)
|
||||
return false;
|
||||
|
||||
const optionNames: string[] = [];
|
||||
const optionFuncs: Function[] = [];
|
||||
|
||||
args.map((arg, i) => (i % 2 ? optionFuncs : optionNames).push(arg));
|
||||
|
||||
this.options = optionNames;
|
||||
|
||||
this.setupOptions();
|
||||
|
||||
return super.show(optionFuncs);
|
||||
}
|
||||
}
|
||||
@@ -419,38 +419,50 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
||||
if (!this.speciesStarterDexEntry?.caughtAttr)
|
||||
error = true;
|
||||
else if (this.starterCursors.length < 6) {
|
||||
ui.setModeWithoutClear(Mode.OPTION_SELECT, 'Add to Party', () => {
|
||||
ui.setMode(Mode.STARTER_SELECT);
|
||||
let isDupe = false;
|
||||
for (let s = 0; s < this.starterCursors.length; s++) {
|
||||
if (this.starterGens[s] === this.getGenCursorWithScroll() && this.starterCursors[s] === this.cursor) {
|
||||
isDupe = true;
|
||||
break;
|
||||
ui.setModeWithoutClear(Mode.OPTION_SELECT, {
|
||||
options: [
|
||||
{
|
||||
label: 'Add to Party',
|
||||
handler: () => {
|
||||
ui.setMode(Mode.STARTER_SELECT);
|
||||
let isDupe = false;
|
||||
for (let s = 0; s < this.starterCursors.length; s++) {
|
||||
if (this.starterGens[s] === this.getGenCursorWithScroll() && this.starterCursors[s] === this.cursor) {
|
||||
isDupe = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
const species = this.genSpecies[this.getGenCursorWithScroll()][this.cursor];
|
||||
if (!isDupe && this.tryUpdateValue(speciesStarterValues[species.speciesId])) {
|
||||
const cursorObj = this.starterCursorObjs[this.starterCursors.length];
|
||||
cursorObj.setVisible(true);
|
||||
cursorObj.setPosition(this.cursorObj.x, this.cursorObj.y);
|
||||
const props = this.scene.gameData.getSpeciesDexAttrProps(species, this.dexAttrCursor);
|
||||
this.starterIcons[this.starterCursors.length].setTexture(species.getIconAtlasKey(props.formIndex));
|
||||
this.starterIcons[this.starterCursors.length].setFrame(species.getIconId(props.female, props.formIndex, props.shiny));
|
||||
this.starterGens.push(this.getGenCursorWithScroll());
|
||||
this.starterCursors.push(this.cursor);
|
||||
this.starterAttr.push(this.dexAttrCursor);
|
||||
this.starterNatures.push(this.natureCursor as unknown as Nature);
|
||||
if (this.speciesLoaded.get(species.speciesId))
|
||||
species.cry(this.scene);
|
||||
if (this.starterCursors.length === 6 || this.value === 10)
|
||||
this.tryStart();
|
||||
this.updateInstructions();
|
||||
ui.playSelect();
|
||||
} else
|
||||
ui.playError();
|
||||
},
|
||||
overrideSound: true
|
||||
},
|
||||
{
|
||||
label: 'Toggle IVs',
|
||||
handler: () => {
|
||||
this.toggleStatsMode();
|
||||
ui.setMode(Mode.STARTER_SELECT);
|
||||
}
|
||||
}
|
||||
}
|
||||
const species = this.genSpecies[this.getGenCursorWithScroll()][this.cursor];
|
||||
if (!isDupe && this.tryUpdateValue(speciesStarterValues[species.speciesId])) {
|
||||
const cursorObj = this.starterCursorObjs[this.starterCursors.length];
|
||||
cursorObj.setVisible(true);
|
||||
cursorObj.setPosition(this.cursorObj.x, this.cursorObj.y);
|
||||
const props = this.scene.gameData.getSpeciesDexAttrProps(species, this.dexAttrCursor);
|
||||
this.starterIcons[this.starterCursors.length].setTexture(species.getIconAtlasKey(props.formIndex));
|
||||
this.starterIcons[this.starterCursors.length].setFrame(species.getIconId(props.female, props.formIndex, props.shiny));
|
||||
this.starterGens.push(this.getGenCursorWithScroll());
|
||||
this.starterCursors.push(this.cursor);
|
||||
this.starterAttr.push(this.dexAttrCursor);
|
||||
this.starterNatures.push(this.natureCursor as unknown as Nature);
|
||||
if (this.speciesLoaded.get(species.speciesId))
|
||||
species.cry(this.scene);
|
||||
if (this.starterCursors.length === 6 || this.value === 10)
|
||||
this.tryStart();
|
||||
this.updateInstructions();
|
||||
ui.playSelect();
|
||||
} else
|
||||
ui.playError();
|
||||
}, 'Toggle IVs', () => {
|
||||
this.toggleStatsMode();
|
||||
ui.setMode(Mode.STARTER_SELECT);
|
||||
]
|
||||
});
|
||||
success = true;
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import LoginFormUiHandler from './login-form-ui-handler';
|
||||
import RegistrationFormUiHandler from './registration-form-ui-handler';
|
||||
import LoadingModalUiHandler from './loading-modal-ui-handler';
|
||||
import * as Utils from "../utils";
|
||||
import GameStatsUiHandler from './game-stats-ui-handler';
|
||||
|
||||
export enum Mode {
|
||||
MESSAGE,
|
||||
@@ -49,6 +50,7 @@ export enum Mode {
|
||||
MENU,
|
||||
SETTINGS,
|
||||
ACHIEVEMENTS,
|
||||
GAME_STATS,
|
||||
VOUCHERS,
|
||||
EGG_LIST,
|
||||
EGG_GACHA,
|
||||
@@ -74,6 +76,7 @@ const noTransitionModes = [
|
||||
Mode.MENU,
|
||||
Mode.SETTINGS,
|
||||
Mode.ACHIEVEMENTS,
|
||||
Mode.GAME_STATS,
|
||||
Mode.VOUCHERS,
|
||||
Mode.LOGIN_FORM,
|
||||
Mode.REGISTRATION_FORM,
|
||||
@@ -118,6 +121,7 @@ export default class UI extends Phaser.GameObjects.Container {
|
||||
new MenuUiHandler(scene),
|
||||
new SettingsUiHandler(scene),
|
||||
new AchvsUiHandler(scene),
|
||||
new GameStatsUiHandler(scene),
|
||||
new VouchersUiHandler(scene),
|
||||
new EggListUiHandler(scene),
|
||||
new EggGachaUiHandler(scene),
|
||||
|
||||
Reference in new issue
Block a user