mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-02-10 18:25:54 +00:00
387 lines
12 KiB
TypeScript
387 lines
12 KiB
TypeScript
import Phaser from "phaser";
|
|
import BattleScene from "../battle-scene";
|
|
import { TextStyle, addTextObject } from "./text";
|
|
import { Mode } from "./ui";
|
|
import UiHandler from "./ui-handler";
|
|
import { addWindow } from "./ui-theme";
|
|
import * as Utils from "../utils";
|
|
import { DexAttr, GameData } from "../system/game-data";
|
|
import { speciesStarters } from "../data/pokemon-species";
|
|
import {Button} from "#enums/buttons";
|
|
import i18next from "i18next";
|
|
|
|
interface DisplayStat {
|
|
label_key?: string;
|
|
sourceFunc?: (gameData: GameData) => string;
|
|
hidden?: boolean;
|
|
}
|
|
|
|
interface DisplayStats {
|
|
[key: string]: DisplayStat | string
|
|
}
|
|
|
|
const displayStats: DisplayStats = {
|
|
playTime: {
|
|
label_key: "playTime",
|
|
sourceFunc: gameData => Utils.getPlayTimeString(gameData.gameStats.playTime)
|
|
},
|
|
battles: {
|
|
label_key: "totalBattles",
|
|
sourceFunc: gameData => gameData.gameStats.battles.toString(),
|
|
},
|
|
startersUnlocked: {
|
|
label_key: "starters",
|
|
sourceFunc: gameData => {
|
|
const starterCount = gameData.getStarterCount(d => !!d.caughtAttr);
|
|
return `${starterCount} (${Math.floor((starterCount / Object.keys(speciesStarters).length) * 1000) / 10}%)`;
|
|
}
|
|
},
|
|
shinyStartersUnlocked: {
|
|
label_key: "shinyStarters",
|
|
sourceFunc: gameData => {
|
|
const starterCount = gameData.getStarterCount(d => !!(d.caughtAttr & DexAttr.SHINY));
|
|
return `${starterCount} (${Math.floor((starterCount / Object.keys(speciesStarters).length) * 1000) / 10}%)`;
|
|
}
|
|
},
|
|
dexSeen: {
|
|
label_key: "speciesSeen",
|
|
sourceFunc: gameData => {
|
|
const seenCount = gameData.getSpeciesCount(d => !!d.seenAttr);
|
|
return `${seenCount} (${Math.floor((seenCount / Object.keys(gameData.dexData).length) * 1000) / 10}%)`;
|
|
}
|
|
},
|
|
dexCaught: {
|
|
label_key: "speciesCaught",
|
|
sourceFunc: gameData => {
|
|
const caughtCount = gameData.getSpeciesCount(d => !!d.caughtAttr);
|
|
return `${caughtCount} (${Math.floor((caughtCount / Object.keys(gameData.dexData).length) * 1000) / 10}%)`;
|
|
}
|
|
},
|
|
ribbonsOwned: {
|
|
label_key: "ribbonsOwned",
|
|
sourceFunc: gameData => gameData.gameStats.ribbonsOwned.toString(),
|
|
},
|
|
classicSessionsPlayed:{
|
|
label_key: "classicRuns",
|
|
sourceFunc: gameData => gameData.gameStats.classicSessionsPlayed.toString(),
|
|
},
|
|
sessionsWon: {
|
|
label_key: "classicWins",
|
|
sourceFunc: gameData => gameData.gameStats.sessionsWon.toString(),
|
|
},
|
|
dailyRunSessionsPlayed: {
|
|
label_key: "dailyRunAttempts",
|
|
sourceFunc: gameData => gameData.gameStats.dailyRunSessionsPlayed.toString(),
|
|
},
|
|
dailyRunSessionsWon: {
|
|
label_key: "dailyRunWins",
|
|
sourceFunc: gameData => gameData.gameStats.dailyRunSessionsWon.toString(),
|
|
},
|
|
endlessSessionsPlayed: {
|
|
label_key: "endlessRuns",
|
|
sourceFunc: gameData => gameData.gameStats.endlessSessionsPlayed.toString(),
|
|
hidden: true
|
|
},
|
|
highestEndlessWave: {
|
|
label_key: "highestWaveEndless",
|
|
sourceFunc: gameData => gameData.gameStats.highestEndlessWave.toString(),
|
|
hidden: true
|
|
},
|
|
highestMoney: {
|
|
label_key: "highestMoney",
|
|
sourceFunc: gameData => Utils.formatFancyLargeNumber(gameData.gameStats.highestMoney),
|
|
},
|
|
highestDamage: {
|
|
label_key: "highestDamage",
|
|
sourceFunc: gameData => gameData.gameStats.highestDamage.toString(),
|
|
},
|
|
highestHeal: {
|
|
label_key: "highestHPHealed",
|
|
sourceFunc: gameData => gameData.gameStats.highestHeal.toString(),
|
|
},
|
|
pokemonSeen: {
|
|
label_key: "pokemonEncountered",
|
|
sourceFunc: gameData => gameData.gameStats.pokemonSeen.toString(),
|
|
},
|
|
pokemonDefeated: {
|
|
label_key: "pokemonDefeated",
|
|
sourceFunc: gameData => gameData.gameStats.pokemonDefeated.toString(),
|
|
},
|
|
pokemonCaught: {
|
|
label_key: "pokemonCaught",
|
|
sourceFunc: gameData => gameData.gameStats.pokemonCaught.toString(),
|
|
},
|
|
pokemonHatched: {
|
|
label_key: "eggsHatched",
|
|
sourceFunc: gameData => gameData.gameStats.pokemonHatched.toString(),
|
|
},
|
|
subLegendaryPokemonSeen: {
|
|
label_key: "subLegendsSeen",
|
|
sourceFunc: gameData => gameData.gameStats.subLegendaryPokemonSeen.toString(),
|
|
hidden: true
|
|
},
|
|
subLegendaryPokemonCaught: {
|
|
label_key: "subLegendsCaught",
|
|
sourceFunc: gameData => gameData.gameStats.subLegendaryPokemonCaught.toString(),
|
|
hidden: true
|
|
},
|
|
subLegendaryPokemonHatched: {
|
|
label_key: "subLegendsHatched",
|
|
sourceFunc: gameData => gameData.gameStats.subLegendaryPokemonHatched.toString(),
|
|
hidden: true
|
|
},
|
|
legendaryPokemonSeen: {
|
|
label_key: "legendsSeen",
|
|
sourceFunc: gameData => gameData.gameStats.legendaryPokemonSeen.toString(),
|
|
hidden: true
|
|
},
|
|
legendaryPokemonCaught: {
|
|
label_key: "legendsCaught",
|
|
sourceFunc: gameData => gameData.gameStats.legendaryPokemonCaught.toString(),
|
|
hidden: true
|
|
},
|
|
legendaryPokemonHatched: {
|
|
label_key: "legendsHatched",
|
|
sourceFunc: gameData => gameData.gameStats.legendaryPokemonHatched.toString(),
|
|
hidden: true
|
|
},
|
|
mythicalPokemonSeen: {
|
|
label_key: "mythicalsSeen",
|
|
sourceFunc: gameData => gameData.gameStats.mythicalPokemonSeen.toString(),
|
|
hidden: true
|
|
},
|
|
mythicalPokemonCaught: {
|
|
label_key: "mythicalsCaught",
|
|
sourceFunc: gameData => gameData.gameStats.mythicalPokemonCaught.toString(),
|
|
hidden: true
|
|
},
|
|
mythicalPokemonHatched: {
|
|
label_key: "mythicalsHatched",
|
|
sourceFunc: gameData => gameData.gameStats.mythicalPokemonHatched.toString(),
|
|
hidden: true
|
|
},
|
|
shinyPokemonSeen: {
|
|
label_key: "shiniesSeen",
|
|
sourceFunc: gameData => gameData.gameStats.shinyPokemonSeen.toString(),
|
|
hidden: true
|
|
},
|
|
shinyPokemonCaught: {
|
|
label_key: "shiniesCaught",
|
|
sourceFunc: gameData => gameData.gameStats.shinyPokemonCaught.toString(),
|
|
hidden: true
|
|
},
|
|
shinyPokemonHatched: {
|
|
label_key: "shiniesHatched",
|
|
sourceFunc: gameData => gameData.gameStats.shinyPokemonHatched.toString(),
|
|
hidden: true
|
|
},
|
|
pokemonFused: {
|
|
label_key: "pokemonFused",
|
|
sourceFunc: gameData => gameData.gameStats.pokemonFused.toString(),
|
|
hidden: true
|
|
},
|
|
trainersDefeated: {
|
|
label_key: "trainersDefeated",
|
|
sourceFunc: gameData => gameData.gameStats.trainersDefeated.toString(),
|
|
},
|
|
eggsPulled: {
|
|
label_key: "eggsPulled",
|
|
sourceFunc: gameData => gameData.gameStats.eggsPulled.toString(),
|
|
hidden: true
|
|
},
|
|
rareEggsPulled: {
|
|
label_key: "rareEggsPulled",
|
|
sourceFunc: gameData => gameData.gameStats.rareEggsPulled.toString(),
|
|
hidden: true
|
|
},
|
|
epicEggsPulled: {
|
|
label_key: "epicEggsPulled",
|
|
sourceFunc: gameData => gameData.gameStats.epicEggsPulled.toString(),
|
|
hidden: true
|
|
},
|
|
legendaryEggsPulled: {
|
|
label_key: "legendaryEggsPulled",
|
|
sourceFunc: gameData => gameData.gameStats.legendaryEggsPulled.toString(),
|
|
hidden: true
|
|
},
|
|
manaphyEggsPulled: {
|
|
label_key: "manaphyEggsPulled",
|
|
sourceFunc: gameData => gameData.gameStats.manaphyEggsPulled.toString(),
|
|
hidden: true
|
|
},
|
|
};
|
|
|
|
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 | null = null) {
|
|
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, i18next.t("gameStatsUiHandler: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.STATS_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.STATS_VALUE);
|
|
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); // TODO: is this bang correct?
|
|
this.statLabels[s].setText(!stat.hidden || isNaN(parseInt(value)) || parseInt(value) ? i18next.t(`gameStatsUiHandler:${stat.label_key}`) : "???");
|
|
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);
|
|
}
|
|
}
|
|
|
|
export function initStatsKeys() {
|
|
const statKeys = Object.keys(displayStats);
|
|
|
|
for (const 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_key: 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_key) {
|
|
const splittableKey = key.replace(/([a-z]{2,})([A-Z]{1}(?:[^A-Z]|$))/g, "$1_$2");
|
|
(displayStats[key] as DisplayStat).label_key = Utils.toReadableString(`${splittableKey[0].toUpperCase()}${splittableKey.slice(1)}`);
|
|
}
|
|
}
|
|
}
|