mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-07-28 11:12:24 +02:00
Displaying base stats as bars in an overlay
This commit is contained in:
parent
717a2c38f7
commit
82bccd4a2d
125
src/ui/base-stats-overlay.ts
Normal file
125
src/ui/base-stats-overlay.ts
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
import BattleScene, { InfoToggle } from "../battle-scene";
|
||||||
|
import { TextStyle, addTextObject } from "./text";
|
||||||
|
import { addWindow } from "./ui-theme";
|
||||||
|
import * as Utils from "../utils";
|
||||||
|
import i18next from "i18next";
|
||||||
|
|
||||||
|
export interface BaseStatsOverlaySettings {
|
||||||
|
scale?:number; // scale the box? A scale of 0.5 is recommended
|
||||||
|
x?: number;
|
||||||
|
y?: number;
|
||||||
|
/** Default is always half the screen, regardless of scale */
|
||||||
|
width?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
const HEIGHT = 120;
|
||||||
|
const BORDER = 8;
|
||||||
|
const GLOBAL_SCALE = 6;
|
||||||
|
const shortStats = [ "HP", "ATK", "DEF", "SPATK", "SPDEF", "SPD" ];
|
||||||
|
|
||||||
|
export default class BaseStatsOverlay extends Phaser.GameObjects.Container implements InfoToggle {
|
||||||
|
|
||||||
|
public active: boolean = false;
|
||||||
|
|
||||||
|
private statsLabels: Phaser.GameObjects.Text[] = [];
|
||||||
|
private statsRectangles: Phaser.GameObjects.Rectangle[] = [];
|
||||||
|
private statsShadows: Phaser.GameObjects.Rectangle[] = [];
|
||||||
|
private statsTotalLabel: Phaser.GameObjects.Text;
|
||||||
|
|
||||||
|
private statsBg: Phaser.GameObjects.NineSlice;
|
||||||
|
|
||||||
|
private options: BaseStatsOverlaySettings;
|
||||||
|
|
||||||
|
public scale: number;
|
||||||
|
public width: number;
|
||||||
|
|
||||||
|
constructor(scene: BattleScene, options?: BaseStatsOverlaySettings) {
|
||||||
|
super(scene, options?.x, options?.y);
|
||||||
|
this.scale = options?.scale || 1; // set up the scale
|
||||||
|
this.setScale(this.scale);
|
||||||
|
this.options = options || {};
|
||||||
|
|
||||||
|
// prepare the description box
|
||||||
|
this.width = (options?.width || BaseStatsOverlay.getWidth(this.scale, scene)) / this.scale; // divide by scale as we always want this to be half a window wide
|
||||||
|
this.statsBg = addWindow(scene, 0, 0, this.width, HEIGHT);
|
||||||
|
this.statsBg.setOrigin(0, 0);
|
||||||
|
this.add(this.statsBg);
|
||||||
|
|
||||||
|
for (let i = 0; i < 6; i++) {
|
||||||
|
const shadow = this.scene.add.rectangle(0, BORDER + 3 + i * 15, 100, 5, 0x006860);
|
||||||
|
shadow.setOrigin(1, 0);
|
||||||
|
shadow.setX(this.width - BORDER + 1);
|
||||||
|
this.statsShadows.push(shadow);
|
||||||
|
this.add(shadow);
|
||||||
|
|
||||||
|
const rectangle = this.scene.add.rectangle(0, BORDER + 2 + i * 15, 100, 5, 0x66aa99);
|
||||||
|
rectangle.setOrigin(1, 0);
|
||||||
|
rectangle.setX(this.width - BORDER);
|
||||||
|
this.statsRectangles.push(rectangle);
|
||||||
|
this.add(rectangle);
|
||||||
|
|
||||||
|
const label = addTextObject(scene, BORDER, BORDER - 2 + i * 15, "A", TextStyle.BATTLE_INFO);
|
||||||
|
this.statsLabels.push(label);
|
||||||
|
this.add(label);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.statsTotalLabel = addTextObject(scene, BORDER, BORDER + 6 * 15, "A", TextStyle.BATTLE_INFO, { color: "#ccbe00" });
|
||||||
|
this.add(this.statsTotalLabel);
|
||||||
|
|
||||||
|
// hide this component for now
|
||||||
|
this.setVisible(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// show this component with infos for the specific move
|
||||||
|
show(values: number[], total: number):boolean {
|
||||||
|
|
||||||
|
for (let i = 0; i < 6; i++) {
|
||||||
|
this.statsLabels[i].setText(i18next.t(`pokemonInfo:Stat.${shortStats[i]}shortened`) + ": " + `${values[i]}`);
|
||||||
|
// This accounts for base stats up to 200, might not be enough.
|
||||||
|
// TODO: change color based on value.
|
||||||
|
this.statsShadows[i].setSize(values[i] / 2, 5);
|
||||||
|
this.statsRectangles[i].setSize(values[i] / 2, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.statsTotalLabel.setText(i18next.t("pokedexUiHandler:baseTotal") + ": " + `${total}`);
|
||||||
|
|
||||||
|
|
||||||
|
this.setVisible(true);
|
||||||
|
this.active = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
clear() {
|
||||||
|
this.setVisible(false);
|
||||||
|
this.active = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleInfo(visible: boolean): void {
|
||||||
|
if (visible) {
|
||||||
|
this.setVisible(true);
|
||||||
|
}
|
||||||
|
this.scene.tweens.add({
|
||||||
|
targets: this.statsLabels,
|
||||||
|
duration: Utils.fixedInt(125),
|
||||||
|
ease: "Sine.easeInOut",
|
||||||
|
alpha: visible ? 1 : 0
|
||||||
|
});
|
||||||
|
if (!visible) {
|
||||||
|
this.setVisible(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
isActive(): boolean {
|
||||||
|
return this.active;
|
||||||
|
}
|
||||||
|
|
||||||
|
// width of this element
|
||||||
|
static getWidth(scale:number, scene: BattleScene):number {
|
||||||
|
return scene.game.canvas.width / GLOBAL_SCALE / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// height of this element
|
||||||
|
static getHeight(scale:number, onSide?: boolean):number {
|
||||||
|
return HEIGHT * scale;
|
||||||
|
}
|
||||||
|
}
|
@ -49,6 +49,7 @@ import { Biome } from "#app/enums/biome";
|
|||||||
import { TimeOfDay } from "#app/enums/time-of-day";
|
import { TimeOfDay } from "#app/enums/time-of-day";
|
||||||
import { SpeciesFormKey } from "#app/enums/species-form-key";
|
import { SpeciesFormKey } from "#app/enums/species-form-key";
|
||||||
import { Abilities } from "#app/enums/abilities";
|
import { Abilities } from "#app/enums/abilities";
|
||||||
|
import BaseStatsOverlay from "./base-stats-overlay";
|
||||||
|
|
||||||
|
|
||||||
interface LanguageSetting {
|
interface LanguageSetting {
|
||||||
@ -182,8 +183,9 @@ export default class PokedexPageUiHandler extends MessageUiHandler {
|
|||||||
private starterSelectMessageBox: Phaser.GameObjects.NineSlice;
|
private starterSelectMessageBox: Phaser.GameObjects.NineSlice;
|
||||||
private starterSelectMessageBoxContainer: Phaser.GameObjects.Container;
|
private starterSelectMessageBoxContainer: Phaser.GameObjects.Container;
|
||||||
private statsContainer: StatsContainer;
|
private statsContainer: StatsContainer;
|
||||||
private moveInfoOverlay : MoveInfoOverlay;
|
private moveInfoOverlay: MoveInfoOverlay;
|
||||||
private infoOverlay : PokedexInfoOverlay;
|
private infoOverlay: PokedexInfoOverlay;
|
||||||
|
private baseStatsOverlay: BaseStatsOverlay;
|
||||||
|
|
||||||
private statsMode: boolean;
|
private statsMode: boolean;
|
||||||
|
|
||||||
@ -230,6 +232,7 @@ export default class PokedexPageUiHandler extends MessageUiHandler {
|
|||||||
private starterAttributes: StarterAttributes;
|
private starterAttributes: StarterAttributes;
|
||||||
|
|
||||||
protected blockInput: boolean = false;
|
protected blockInput: boolean = false;
|
||||||
|
protected blockInputOverlay: boolean = false;
|
||||||
|
|
||||||
// Menu
|
// Menu
|
||||||
private menuContainer: Phaser.GameObjects.Container;
|
private menuContainer: Phaser.GameObjects.Container;
|
||||||
@ -239,7 +242,6 @@ export default class PokedexPageUiHandler extends MessageUiHandler {
|
|||||||
private menuOptions: MenuOptions[];
|
private menuOptions: MenuOptions[];
|
||||||
protected scale: number = 0.1666666667;
|
protected scale: number = 0.1666666667;
|
||||||
|
|
||||||
|
|
||||||
constructor(scene: BattleScene) {
|
constructor(scene: BattleScene) {
|
||||||
super(scene, Mode.POKEDEX_PAGE);
|
super(scene, Mode.POKEDEX_PAGE);
|
||||||
}
|
}
|
||||||
@ -477,14 +479,10 @@ export default class PokedexPageUiHandler extends MessageUiHandler {
|
|||||||
|
|
||||||
this.bgmBar = new BgmBar(this.scene);
|
this.bgmBar = new BgmBar(this.scene);
|
||||||
this.bgmBar.setup();
|
this.bgmBar.setup();
|
||||||
|
|
||||||
ui.bgmBar = this.bgmBar;
|
ui.bgmBar = this.bgmBar;
|
||||||
|
|
||||||
this.menuContainer.add(this.bgmBar);
|
this.menuContainer.add(this.bgmBar);
|
||||||
|
|
||||||
this.menuContainer.setVisible(false);
|
this.menuContainer.setVisible(false);
|
||||||
|
|
||||||
|
|
||||||
this.menuOptions = Utils.getEnumKeys(MenuOptions).map(m => parseInt(MenuOptions[m]) as MenuOptions);
|
this.menuOptions = Utils.getEnumKeys(MenuOptions).map(m => parseInt(MenuOptions[m]) as MenuOptions);
|
||||||
|
|
||||||
this.optionSelectText = addTextObject(this.scene, 0, 0, this.menuOptions.map(o => `${i18next.t(`pokedexUiHandler:${MenuOptions[o]}`)}`).join("\n"), TextStyle.WINDOW, { maxLines: this.menuOptions.length });
|
this.optionSelectText = addTextObject(this.scene, 0, 0, this.menuOptions.map(o => `${i18next.t(`pokedexUiHandler:${MenuOptions[o]}`)}`).join("\n"), TextStyle.WINDOW, { maxLines: this.menuOptions.length });
|
||||||
@ -510,6 +508,11 @@ export default class PokedexPageUiHandler extends MessageUiHandler {
|
|||||||
this.starterSelectContainer.add(this.menuContainer);
|
this.starterSelectContainer.add(this.menuContainer);
|
||||||
|
|
||||||
|
|
||||||
|
// adding base stats
|
||||||
|
this.baseStatsOverlay = new BaseStatsOverlay(this.scene, { x: 317, y: 0, width:133 });
|
||||||
|
this.menuContainer.add(this.baseStatsOverlay);
|
||||||
|
this.menuContainer.bringToTop(this.baseStatsOverlay);
|
||||||
|
|
||||||
// add the info overlay last to be the top most ui element and prevent the IVs from overlaying this
|
// add the info overlay last to be the top most ui element and prevent the IVs from overlaying this
|
||||||
const overlayScale = 1;
|
const overlayScale = 1;
|
||||||
this.moveInfoOverlay = new MoveInfoOverlay(this.scene, {
|
this.moveInfoOverlay = new MoveInfoOverlay(this.scene, {
|
||||||
@ -929,6 +932,21 @@ export default class PokedexPageUiHandler extends MessageUiHandler {
|
|||||||
let success = false;
|
let success = false;
|
||||||
let error = false;
|
let error = false;
|
||||||
|
|
||||||
|
if (this.blockInputOverlay) {
|
||||||
|
if (button === Button.CANCEL || button === Button.ACTION) {
|
||||||
|
this.blockInputOverlay = false;
|
||||||
|
this.baseStatsOverlay.clear();
|
||||||
|
ui.showText("");
|
||||||
|
return true;
|
||||||
|
} else if (button === Button.UP || button === Button.DOWN) {
|
||||||
|
this.blockInputOverlay = false;
|
||||||
|
this.baseStatsOverlay.clear();
|
||||||
|
ui.showText("");
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (button === Button.SUBMIT) {
|
if (button === Button.SUBMIT) {
|
||||||
success = true;
|
success = true;
|
||||||
} else if (button === Button.CANCEL) {
|
} else if (button === Button.CANCEL) {
|
||||||
@ -956,43 +974,13 @@ export default class PokedexPageUiHandler extends MessageUiHandler {
|
|||||||
|
|
||||||
ui.setMode(Mode.POKEDEX_PAGE, "refresh").then(() => {
|
ui.setMode(Mode.POKEDEX_PAGE, "refresh").then(() => {
|
||||||
ui.showText(i18next.t("pokedexUiHandler:baseStats"), null, () => {
|
ui.showText(i18next.t("pokedexUiHandler:baseStats"), null, () => {
|
||||||
const options: any[] = [];
|
|
||||||
const shortStats = [ "HP", "ATK", "DEF", "SPATK", "SPDEF", "SPD" ];
|
|
||||||
|
|
||||||
this.baseStats.map((bst, index) => {
|
this.baseStatsOverlay.show(this.baseStats, this.baseTotal);
|
||||||
options.push({
|
|
||||||
label: i18next.t(`pokemonInfo:Stat.${shortStats[index]}shortened`).padEnd(5, " ") + ": " + `${bst}`,
|
|
||||||
handler: () => {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
options.push({
|
|
||||||
label: i18next.t("pokedexUiHandler:baseTotal") + ": " + `${this.baseTotal}`,
|
|
||||||
color: "#ccbe00",
|
|
||||||
handler: () => {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
options.push({
|
|
||||||
label: i18next.t("menu:cancel"),
|
|
||||||
handler: () => {
|
|
||||||
this.moveInfoOverlay.clear();
|
|
||||||
this.clearText();
|
|
||||||
ui.setMode(Mode.POKEDEX_PAGE, "refresh");
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
onHover: () => this.moveInfoOverlay.clear()
|
|
||||||
});
|
|
||||||
|
|
||||||
ui.setModeWithoutClear(Mode.OPTION_SELECT, {
|
|
||||||
options: options,
|
|
||||||
supportHover: true,
|
|
||||||
maxOptions: 8,
|
|
||||||
yOffset: 19
|
|
||||||
});
|
|
||||||
|
|
||||||
this.blockInput = false;
|
this.blockInput = false;
|
||||||
|
this.blockInputOverlay = true;
|
||||||
|
|
||||||
|
return true;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user