pokerogue/src/ui/title-ui-handler.ts
flx-sta 48430c8feb
[Feature] Seasonal splash messages logic + scaffolding (#4318)
* add: seasonsl splash messages logic + scaffolding

* refactor: settin up and displaying splash messages.

They are now stored with their i18next keys and only get translated as soon as they are displayed. This also allows for better display of the `battlesWon` parameter which now supports better number formatting and the count is an interpolation

* fix: updateTitleStats not checking the namespace of battlesWon

* add tests for splash_messages

* test: always use UTC time

* fix: time-pattern to MM-DD

* fix splash_messages test

* add: const to control usage of seasonal splash messages

* fix tests (splashj)

* Update src/locales/ja/splash-messages.json

Co-authored-by: Chapybara-jp <charlie.beer@hotmail.com>

* Update src/locales/es/splash-messages.json

Add missing `number` format for battlesWon message

---------

Co-authored-by: Chapybara-jp <charlie.beer@hotmail.com>
2024-09-19 15:59:37 -07:00

135 lines
4.3 KiB
TypeScript

import BattleScene from "../battle-scene";
import OptionSelectUiHandler from "./settings/option-select-ui-handler";
import { Mode } from "./ui";
import * as Utils from "../utils";
import { TextStyle, addTextObject, getTextStyleOptions } from "./text";
import { getSplashMessages } from "../data/splash-messages";
import i18next from "i18next";
import { TimedEventDisplay } from "#app/timed-event-manager";
export default class TitleUiHandler extends OptionSelectUiHandler {
/** If the stats can not be retrieved, use this fallback value */
private static readonly BATTLES_WON_FALLBACK: number = -99999999;
private titleContainer: Phaser.GameObjects.Container;
private playerCountLabel: Phaser.GameObjects.Text;
private splashMessage: string;
private splashMessageText: Phaser.GameObjects.Text;
private eventDisplay: TimedEventDisplay;
private titleStatsTimer: NodeJS.Timeout | null;
constructor(scene: BattleScene, mode: Mode = Mode.TITLE) {
super(scene, mode);
}
setup() {
super.setup();
const ui = this.getUi();
this.titleContainer = this.scene.add.container(0, -(this.scene.game.canvas.height / 6));
this.titleContainer.setName("title");
this.titleContainer.setAlpha(0);
ui.add(this.titleContainer);
const logo = this.scene.add.image((this.scene.game.canvas.width / 6) / 2, 8, "logo");
logo.setOrigin(0.5, 0);
this.titleContainer.add(logo);
if (this.scene.eventManager.isEventActive()) {
this.eventDisplay = new TimedEventDisplay(this.scene, 0, 0, this.scene.eventManager.activeEvent());
this.eventDisplay.setup();
this.titleContainer.add(this.eventDisplay);
}
this.playerCountLabel = addTextObject(
this.scene,
(this.scene.game.canvas.width / 6) - 2,
(this.scene.game.canvas.height / 6) - 13 - 576 * getTextStyleOptions(TextStyle.WINDOW, this.scene.uiTheme).scale,
`? ${i18next.t("menu:playersOnline")}`,
TextStyle.MESSAGE,
{ fontSize: "54px" }
);
this.playerCountLabel.setOrigin(1, 0);
this.titleContainer.add(this.playerCountLabel);
this.splashMessageText = addTextObject(this.scene, logo.x + 64, logo.y + logo.displayHeight - 8, "", TextStyle.MONEY, { fontSize: "54px" });
this.splashMessageText.setOrigin(0.5, 0.5);
this.splashMessageText.setAngle(-20);
this.titleContainer.add(this.splashMessageText);
const originalSplashMessageScale = this.splashMessageText.scale;
this.scene.tweens.add({
targets: this.splashMessageText,
duration: Utils.fixedInt(350),
scale: originalSplashMessageScale * 1.25,
loop: -1,
yoyo: true,
});
}
updateTitleStats(): void {
Utils.apiFetch("game/titlestats")
.then(request => request.json())
.then(stats => {
this.playerCountLabel.setText(`${stats.playerCount} ${i18next.t("menu:playersOnline")}`);
if (this.splashMessage === "splashMessages:battlesWon") {
this.splashMessageText.setText(i18next.t(this.splashMessage, { count: stats.battlesWon }));
}
})
.catch(err => {
console.error("Failed to fetch title stats:\n", err);
});
}
show(args: any[]): boolean {
const ret = super.show(args);
if (ret) {
this.splashMessage = Utils.randItem(getSplashMessages());
this.splashMessageText.setText(i18next.t(this.splashMessage, { count: TitleUiHandler.BATTLES_WON_FALLBACK }));
const ui = this.getUi();
if (this.scene.eventManager.isEventActive()) {
this.eventDisplay.show();
}
this.updateTitleStats();
this.titleStatsTimer = setInterval(() => {
this.updateTitleStats();
}, 60000);
this.scene.tweens.add({
targets: [ this.titleContainer, ui.getMessageHandler().bg ],
duration: Utils.fixedInt(325),
alpha: (target: any) => target === this.titleContainer ? 1 : 0,
ease: "Sine.easeInOut"
});
}
return ret;
}
clear(): void {
super.clear();
const ui = this.getUi();
this.eventDisplay?.clear();
this.titleStatsTimer && clearInterval(this.titleStatsTimer);
this.titleStatsTimer = null;
this.scene.tweens.add({
targets: [ this.titleContainer, ui.getMessageHandler().bg ],
duration: Utils.fixedInt(325),
alpha: (target: any) => target === this.titleContainer ? 0 : 1,
ease: "Sine.easeInOut"
});
}
}