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 { SpeciesFormKey } from "#app/enums/species-form-key";
|
||||
import { Abilities } from "#app/enums/abilities";
|
||||
import BaseStatsOverlay from "./base-stats-overlay";
|
||||
|
||||
|
||||
interface LanguageSetting {
|
||||
@ -184,6 +185,7 @@ export default class PokedexPageUiHandler extends MessageUiHandler {
|
||||
private statsContainer: StatsContainer;
|
||||
private moveInfoOverlay: MoveInfoOverlay;
|
||||
private infoOverlay: PokedexInfoOverlay;
|
||||
private baseStatsOverlay: BaseStatsOverlay;
|
||||
|
||||
private statsMode: boolean;
|
||||
|
||||
@ -230,6 +232,7 @@ export default class PokedexPageUiHandler extends MessageUiHandler {
|
||||
private starterAttributes: StarterAttributes;
|
||||
|
||||
protected blockInput: boolean = false;
|
||||
protected blockInputOverlay: boolean = false;
|
||||
|
||||
// Menu
|
||||
private menuContainer: Phaser.GameObjects.Container;
|
||||
@ -239,7 +242,6 @@ export default class PokedexPageUiHandler extends MessageUiHandler {
|
||||
private menuOptions: MenuOptions[];
|
||||
protected scale: number = 0.1666666667;
|
||||
|
||||
|
||||
constructor(scene: BattleScene) {
|
||||
super(scene, Mode.POKEDEX_PAGE);
|
||||
}
|
||||
@ -477,14 +479,10 @@ export default class PokedexPageUiHandler extends MessageUiHandler {
|
||||
|
||||
this.bgmBar = new BgmBar(this.scene);
|
||||
this.bgmBar.setup();
|
||||
|
||||
ui.bgmBar = this.bgmBar;
|
||||
|
||||
this.menuContainer.add(this.bgmBar);
|
||||
|
||||
this.menuContainer.setVisible(false);
|
||||
|
||||
|
||||
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 });
|
||||
@ -510,6 +508,11 @@ export default class PokedexPageUiHandler extends MessageUiHandler {
|
||||
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
|
||||
const overlayScale = 1;
|
||||
this.moveInfoOverlay = new MoveInfoOverlay(this.scene, {
|
||||
@ -929,6 +932,21 @@ export default class PokedexPageUiHandler extends MessageUiHandler {
|
||||
let success = 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) {
|
||||
success = true;
|
||||
} else if (button === Button.CANCEL) {
|
||||
@ -956,43 +974,13 @@ export default class PokedexPageUiHandler extends MessageUiHandler {
|
||||
|
||||
ui.setMode(Mode.POKEDEX_PAGE, "refresh").then(() => {
|
||||
ui.showText(i18next.t("pokedexUiHandler:baseStats"), null, () => {
|
||||
const options: any[] = [];
|
||||
const shortStats = [ "HP", "ATK", "DEF", "SPATK", "SPDEF", "SPD" ];
|
||||
|
||||
this.baseStats.map((bst, index) => {
|
||||
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.baseStatsOverlay.show(this.baseStats, this.baseTotal);
|
||||
|
||||
this.blockInput = false;
|
||||
this.blockInputOverlay = true;
|
||||
|
||||
return true;
|
||||
});
|
||||
});
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user