diff --git a/public/images/pokemon/678ms.json b/public/images/pokemon/678ms.json deleted file mode 100644 index 0fac19c59c4..00000000000 --- a/public/images/pokemon/678ms.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "textures": [ - { - "image": "678ms.png", - "format": "RGBA8888", - "size": { - "w": 56, - "h": 56 - }, - "scale": 1, - "frames": [ - { - "filename": "0001.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 45, - "h": 56 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 45, - "h": 56 - }, - "frame": { - "x": 0, - "y": 0, - "w": 45, - "h": 56 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:935ddcd2ff1f413e94967151e2f4cc6d:bdb048fb547d7ebb9a83d391e8f1c9ba:81f219fee9493a3658266d8c5e858b9e$" - } -} diff --git a/public/images/pokemon/678ms.png b/public/images/pokemon/678ms.png deleted file mode 100644 index d2b6f348a0b..00000000000 Binary files a/public/images/pokemon/678ms.png and /dev/null differ diff --git a/public/images/pokemon/678msb.json b/public/images/pokemon/678msb.json deleted file mode 100644 index 78125f1c5ee..00000000000 --- a/public/images/pokemon/678msb.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "textures": [ - { - "image": "678msb.png", - "format": "RGBA8888", - "size": { - "w": 55, - "h": 55 - }, - "scale": 1, - "frames": [ - { - "filename": "0001.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 46, - "h": 55 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 46, - "h": 55 - }, - "frame": { - "x": 0, - "y": 0, - "w": 46, - "h": 55 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:979291307687f1a4af47bc4d29542ccf:f61247ececc23f282bb95c5bfe49e179:bbcc2663448733722c64bc1ebafbf9c6$" - } -} diff --git a/public/images/pokemon/678msb.png b/public/images/pokemon/678msb.png deleted file mode 100644 index c32e3064451..00000000000 Binary files a/public/images/pokemon/678msb.png and /dev/null differ diff --git a/public/images/ui/command_fight_labels.png b/public/images/ui/command_fight_labels.png deleted file mode 100644 index c9d6d60c47f..00000000000 Binary files a/public/images/ui/command_fight_labels.png and /dev/null differ diff --git a/public/images/ui/legacy/command_fight_labels.png b/public/images/ui/legacy/command_fight_labels.png deleted file mode 100644 index 257d0e5d93f..00000000000 Binary files a/public/images/ui/legacy/command_fight_labels.png and /dev/null differ diff --git a/src/@types/i18next.d.ts b/src/@types/i18next.d.ts index c4a867b9d73..f3a63d6f4ec 100644 --- a/src/@types/i18next.d.ts +++ b/src/@types/i18next.d.ts @@ -1,55 +1,9 @@ -import { AbilityTranslationEntries, SimpleTranslationEntries, AchievementTranslationEntries, BerryTranslationEntries, DialogueTranslationEntries, ModifierTypeTranslationEntries, MoveTranslationEntries, PokemonInfoTranslationEntries, TranslationEntries } from "#app/interfaces/locales"; +import { enConfig } from "#app/locales/en/config.js"; // Module declared to make referencing keys in the localization files type-safe. declare module "i18next" { interface CustomTypeOptions { defaultNS: "menu", // needed here as well for typedoc - resources: { - ability: AbilityTranslationEntries; - abilityTriggers: SimpleTranslationEntries; - achv: AchievementTranslationEntries; - battle: SimpleTranslationEntries; - battleMessageUiHandler: SimpleTranslationEntries; - berry: BerryTranslationEntries; - biome: SimpleTranslationEntries; - challenges: SimpleTranslationEntries; - commandUiHandler: SimpleTranslationEntries; - common: TranslationEntries; - PGMachv: AchievementTranslationEntries; - PGFachv: AchievementTranslationEntries; - PGMdialogue: DialogueTranslationEntries; - PGFdialogue: DialogueTranslationEntries; - PGMbattleSpecDialogue: SimpleTranslationEntries; - PGFbattleSpecDialogue: SimpleTranslationEntries; - PGMmiscDialogue: SimpleTranslationEntries; - PGFmiscDialogue: SimpleTranslationEntries; - PGMdoubleBattleDialogue: DialogueTranslationEntries; - PGFdoubleBattleDialogue: DialogueTranslationEntries; - egg: SimpleTranslationEntries; - fightUiHandler: SimpleTranslationEntries; - gameMode: SimpleTranslationEntries; - gameStatsUiHandler: SimpleTranslationEntries; - growth: SimpleTranslationEntries; - menu: SimpleTranslationEntries; - menuUiHandler: SimpleTranslationEntries; - modifierType: ModifierTypeTranslationEntries; - move: MoveTranslationEntries; - nature: SimpleTranslationEntries; - partyUiHandler: SimpleTranslationEntries; - pokeball: SimpleTranslationEntries; - pokemon: SimpleTranslationEntries; - pokemonInfo: PokemonInfoTranslationEntries; - pokemonInfoContainer: SimpleTranslationEntries; - saveSlotSelectUiHandler: SimpleTranslationEntries; - settings: SimpleTranslationEntries; - splashMessages: SimpleTranslationEntries; - starterSelectUiHandler: SimpleTranslationEntries; - titles: SimpleTranslationEntries; - trainerClasses: SimpleTranslationEntries; - trainerNames: SimpleTranslationEntries; - tutorial: SimpleTranslationEntries; - voucher: SimpleTranslationEntries; - weather: SimpleTranslationEntries; - }; + resources: typeof enConfig } } diff --git a/src/battle-scene.ts b/src/battle-scene.ts index 0e82ce97880..2049348ed94 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -333,7 +333,9 @@ export default class BattleScene extends SceneBase { launchBattle() { this.arenaBg = this.add.sprite(0, 0, "plains_bg"); + this.arenaBg.setName("sprite-arena-bg"); this.arenaBgTransition = this.add.sprite(0, 0, "plains_bg"); + this.arenaBgTransition.setName("sprite-arena-bg-transition"); [ this.arenaBgTransition, this.arenaBg ].forEach(a => { a.setPipeline(this.fieldSpritePipeline); @@ -343,13 +345,13 @@ export default class BattleScene extends SceneBase { }); const field = this.add.container(0, 0); + field.setName("field"); field.setScale(6); - field.setName("container-field"); this.field = field; const fieldUI = this.add.container(0, this.game.canvas.height); - fieldUI.setName("container-field-ui"); + fieldUI.setName("field-ui"); fieldUI.setDepth(1); fieldUI.setScale(6); @@ -373,7 +375,7 @@ export default class BattleScene extends SceneBase { this.add.existing(transition); const uiContainer = this.add.container(0, 0); - uiContainer.setName("container-ui"); + uiContainer.setName("ui"); uiContainer.setDepth(2); uiContainer.setScale(6); @@ -397,12 +399,12 @@ export default class BattleScene extends SceneBase { this.enemyModifiers = []; this.modifierBar = new ModifierBar(this); - this.modifierBar.setName("container-modifier-bar"); + this.modifierBar.setName("modifier-bar"); this.add.existing(this.modifierBar); uiContainer.add(this.modifierBar); this.enemyModifierBar = new ModifierBar(this, true); - this.enemyModifierBar.setName("container-enemy-modifier-bar"); + this.enemyModifierBar.setName("enemy-modifier-bar"); this.add.existing(this.enemyModifierBar); uiContainer.add(this.enemyModifierBar); @@ -413,28 +415,28 @@ export default class BattleScene extends SceneBase { this.fieldUI.add(this.charSprite); this.pbTray = new PokeballTray(this, true); - this.pbTray.setName("container-pb-tray"); + this.pbTray.setName("pb-tray"); this.pbTray.setup(); this.pbTrayEnemy = new PokeballTray(this, false); - this.pbTrayEnemy.setName("container-enemy-pb-tray"); + this.pbTrayEnemy.setName("enemy-pb-tray"); this.pbTrayEnemy.setup(); this.fieldUI.add(this.pbTray); this.fieldUI.add(this.pbTrayEnemy); this.abilityBar = new AbilityBar(this); - this.abilityBar.setName("container-ability-bar"); + this.abilityBar.setName("ability-bar"); this.abilityBar.setup(); this.fieldUI.add(this.abilityBar); this.partyExpBar = new PartyExpBar(this); - this.partyExpBar.setName("container-party-exp-bar"); + this.partyExpBar.setName("party-exp-bar"); this.partyExpBar.setup(); this.fieldUI.add(this.partyExpBar); this.candyBar = new CandyBar(this); - this.candyBar.setName("container-candy-bar"); + this.candyBar.setName("candy-bar"); this.candyBar.setup(); this.fieldUI.add(this.candyBar); @@ -486,13 +488,13 @@ export default class BattleScene extends SceneBase { const loadPokemonAssets = []; this.arenaPlayer = new ArenaBase(this, true); - this.arenaPlayer.setName("container-arena-player"); + this.arenaPlayer.setName("arena-player"); this.arenaPlayerTransition = new ArenaBase(this, true); - this.arenaPlayerTransition.setName("container-arena-player-transition"); + this.arenaPlayerTransition.setName("arena-player-transition"); this.arenaEnemy = new ArenaBase(this, false); - this.arenaEnemy.setName("container-arena-enemy"); + this.arenaEnemy.setName("arena-enemy"); this.arenaNextEnemy = new ArenaBase(this, false); - this.arenaNextEnemy.setName("container-arena-next-enemy"); + this.arenaNextEnemy.setName("arena-next-enemy"); this.arenaBgTransition.setVisible(false); this.arenaPlayerTransition.setVisible(false); @@ -813,8 +815,10 @@ export default class BattleScene extends SceneBase { addPokemonIcon(pokemon: Pokemon, x: number, y: number, originX: number = 0.5, originY: number = 0.5, ignoreOverride: boolean = false): Phaser.GameObjects.Container { const container = this.add.container(x, y); + container.setName(`${pokemon.name}-icon`); const icon = this.add.sprite(0, 0, pokemon.getIconAtlasKey(ignoreOverride)); + icon.setName(`sprite-${pokemon.name}-icon`); icon.setFrame(pokemon.getIconId(true)); // Temporary fix to show pokemon's default icon if variant icon doesn't exist if (icon.frame.name !== pokemon.getIconId(true)) { @@ -831,6 +835,7 @@ export default class BattleScene extends SceneBase { if (pokemon.isFusion()) { const fusionIcon = this.add.sprite(0, 0, pokemon.getFusionIconAtlasKey(ignoreOverride)); + fusionIcon.setName("sprite-fusion-icon"); fusionIcon.setOrigin(0.5, 0); fusionIcon.setFrame(pokemon.getFusionIconId(true)); diff --git a/src/field/damage-number-handler.ts b/src/field/damage-number-handler.ts index cebde7c3ae9..4af219a60b9 100644 --- a/src/field/damage-number-handler.ts +++ b/src/field/damage-number-handler.ts @@ -20,6 +20,7 @@ export default class DamageNumberHandler { const battlerIndex = target.getBattlerIndex(); const baseScale = target.getSpriteScale() / 6; const damageNumber = addTextObject(scene, target.x, -(scene.game.canvas.height / 6) + target.y - target.getSprite().height / 2, Utils.formatStat(amount, true), TextStyle.SUMMARY); + damageNumber.setName("text-damage-number"); damageNumber.setOrigin(0.5, 1); damageNumber.setScale(baseScale); diff --git a/src/field/pokemon-sprite-sparkle-handler.ts b/src/field/pokemon-sprite-sparkle-handler.ts index 9b55133bb50..5312dd18727 100644 --- a/src/field/pokemon-sprite-sparkle-handler.ts +++ b/src/field/pokemon-sprite-sparkle-handler.ts @@ -39,6 +39,7 @@ export default class PokemonSpriteSparkleHandler { const [ xOffset, yOffset ] = [ -s.originX * s.width, -s.originY * s.height]; const sparkle = (s.scene as BattleScene).addFieldSprite(((pokemon?.x || 0) + s.x + pixelX * ratioX + xOffset), ((pokemon?.y || 0) + s.y + pixelY * ratioY + yOffset), "tera_sparkle"); sparkle.pipelineData["ignoreTimeTint"] = s.pipelineData["ignoreTimeTint"]; + sparkle.setName("sprite-tera-sparkle"); sparkle.play("tera_sparkle"); parent.add(sparkle); s.scene.time.delayedCall(Utils.fixedInt(Math.floor((1000 / 12) * 13)), () => sparkle.destroy()); diff --git a/src/loading-scene.ts b/src/loading-scene.ts index 424a52aaa2f..fa2ba9af507 100644 --- a/src/loading-scene.ts +++ b/src/loading-scene.ts @@ -43,7 +43,6 @@ export class LoadingScene extends SceneBase { // Load menu images this.loadAtlas("bg", "ui"); - this.loadImage("command_fight_labels", "ui"); this.loadAtlas("prompt", "ui"); this.loadImage("candy", "ui"); this.loadImage("candy_overlay", "ui"); diff --git a/src/locales/en/menu.ts b/src/locales/en/menu.ts index c7bade07a47..9be87724ea8 100644 --- a/src/locales/en/menu.ts +++ b/src/locales/en/menu.ts @@ -53,4 +53,5 @@ export const menu: SimpleTranslationEntries = { "no":"No", "disclaimer": "DISCLAIMER", "disclaimerDescription": "This game is an unfinished product; it might have playability issues (including the potential loss of save data),\n change without notice, and may or may not be updated further or completed.", + "choosePokemon": "Choose a Pokémon.", } as const; diff --git a/src/test/utils/gameWrapper.ts b/src/test/utils/gameWrapper.ts index da54471a7e3..b1b00c8e15d 100644 --- a/src/test/utils/gameWrapper.ts +++ b/src/test/utils/gameWrapper.ts @@ -24,6 +24,7 @@ import BattleScene from "#app/battle-scene.js"; import {MoveAnim} from "#app/data/battle-anims"; import Pokemon from "#app/field/pokemon"; import * as battleScene from "#app/battle-scene"; +import MockImage from "#app/test/utils/mocks/mocksContainer/mockImage.js"; Object.defineProperty(window, "localStorage", { value: mockLocalStorage(), @@ -35,6 +36,7 @@ Object.defineProperty(window, "console", { InputText.prototype.setElement = () => null; InputText.prototype.resize = () => null; +Phaser.GameObjects.Image = MockImage; window.URL.createObjectURL = (blob: Blob) => { blobToString(blob).then((data: string) => { localStorage.setItem("toExport", data); diff --git a/src/timed-event-manager.ts b/src/timed-event-manager.ts index 518c983b2ac..dac67bd7b4e 100644 --- a/src/timed-event-manager.ts +++ b/src/timed-event-manager.ts @@ -1,3 +1,5 @@ +import BattleScene from "#app/battle-scene.js"; +import { TextStyle, addTextObject } from "#app/ui/text.js"; export enum EventType { SHINY @@ -60,3 +62,89 @@ export class TimedEventManager { return timedEvents.find((te: TimedEvent) => this.isActive(te)).bannerFilename ?? null; } } + +export class TimedEventDisplay extends Phaser.GameObjects.Container { + private event: TimedEvent; + private eventTimerText: Phaser.GameObjects.Text; + private banner: Phaser.GameObjects.Image; + private bannerShadow: Phaser.GameObjects.Rectangle; + private eventTimer: NodeJS.Timeout; + + constructor(scene: BattleScene, x: number, y: number, event: TimedEvent) { + super(scene, x, y); + this.event = event; + this.setVisible(false); + } + + setup() { + this.banner = new Phaser.GameObjects.Image(this.scene, 29, 64, this.event.bannerFilename); + this.banner.setName("img-event-banner"); + this.banner.setOrigin(0, 0); + this.banner.setScale(0.07); + this.bannerShadow = new Phaser.GameObjects.Rectangle( + this.scene, + this.banner.x - 2, + this.banner.y + 2, + this.banner.width, + this.banner.height, + 0x484848 + ); + this.bannerShadow.setName("rect-event-banner-shadow"); + this.bannerShadow.setScale(0.07); + this.bannerShadow.setAlpha(0.5); + this.bannerShadow.setOrigin(0,0); + this.eventTimerText = addTextObject( + this.scene, + this.banner.x + 8, + this.banner.y + 100, + this.timeToGo(this.event.endDate), + TextStyle.WINDOW + ); + this.eventTimerText.setName("text-event-timer"); + this.eventTimerText.setScale(0.15); + this.eventTimerText.setOrigin(0,0); + + this.add([this.eventTimerText, this.bannerShadow, this.banner]); + } + + show() { + this.setVisible(true); + this.updateCountdown(); + + this.eventTimer = setInterval(() => { + this.updateCountdown(); + }, 1000); + } + + clear() { + this.setVisible(false); + clearInterval(this.eventTimer); + this.eventTimer = null; + } + + private timeToGo(date: Date) { + + // Utility to add leading zero + function z(n) { + return (n < 10? "0" : "") + n; + } + const now = new Date(); + let diff = Math.abs(date.getTime() - now.getTime()); + + // Allow for previous times + diff = Math.abs(diff); + + // Get time components + const days = diff/8.64e7 | 0; + const hours = diff%8.64e7 / 3.6e6 | 0; + const mins = diff%3.6e6 / 6e4 | 0; + const secs = Math.round(diff%6e4 / 1e3); + + // Return formatted string + return "Event Ends in : " + z(days) + "d " + z(hours) + "h " + z(mins) + "m " + z(secs)+ "s"; + } + + updateCountdown() { + this.eventTimerText.setText(this.timeToGo(this.event.endDate)); + } +} diff --git a/src/ui/abstact-option-select-ui-handler.ts b/src/ui/abstact-option-select-ui-handler.ts index c4877cfca59..2069f034e89 100644 --- a/src/ui/abstact-option-select-ui-handler.ts +++ b/src/ui/abstact-option-select-ui-handler.ts @@ -58,10 +58,12 @@ export default abstract class AbstractOptionSelectUiHandler extends UiHandler { const ui = this.getUi(); this.optionSelectContainer = this.scene.add.container((this.scene.game.canvas.width / 6) - 1, -48); + this.optionSelectContainer.setName(`option-select-${Mode[this.mode]}`); this.optionSelectContainer.setVisible(false); ui.add(this.optionSelectContainer); this.optionSelectBg = addWindow(this.scene, 0, 0, this.getWindowWidth(), this.getWindowHeight()); + this.optionSelectBg.setName("option-select-bg"); this.optionSelectBg.setOrigin(1, 1); this.optionSelectContainer.add(this.optionSelectBg); @@ -82,6 +84,7 @@ export default abstract class AbstractOptionSelectUiHandler extends UiHandler { } this.optionSelectText = addTextObject(this.scene, 0, 0, options.map(o => o.item ? ` ${o.label}` : o.label).join("\n"), TextStyle.WINDOW, { maxLines: options.length }); + this.optionSelectText.setName("text-option-select"); this.optionSelectText.setLineSpacing(12); this.optionSelectContainer.add(this.optionSelectText); this.optionSelectContainer.setPosition((this.scene.game.canvas.width / 6) - 1 - (this.config?.xOffset || 0), -48 + (this.config?.yOffset || 0)); diff --git a/src/ui/arena-flyout.ts b/src/ui/arena-flyout.ts index c7a0267273b..4d934c5fcf4 100644 --- a/src/ui/arena-flyout.ts +++ b/src/ui/arena-flyout.ts @@ -89,6 +89,7 @@ export default class ArenaFlyout extends Phaser.GameObjects.Container { constructor(scene: Phaser.Scene) { super(scene, 0, 0); + this.setName("arena-flyout"); this.battleScene = this.scene as BattleScene; this.translationX = this.flyoutWidth; diff --git a/src/ui/battle-message-ui-handler.ts b/src/ui/battle-message-ui-handler.ts index 49482d5c575..f2da553c6da 100644 --- a/src/ui/battle-message-ui-handler.ts +++ b/src/ui/battle-message-ui-handler.ts @@ -16,7 +16,7 @@ export default class BattleMessageUiHandler extends MessageUiHandler { private nameBox: Phaser.GameObjects.NineSlice; private nameText: Phaser.GameObjects.Text; - public bg: Phaser.GameObjects.Image; + public bg: Phaser.GameObjects.Sprite; public commandWindow: Phaser.GameObjects.NineSlice; public movesWindowContainer: Phaser.GameObjects.Container; public nameBoxContainer: Phaser.GameObjects.Container; @@ -31,33 +31,30 @@ export default class BattleMessageUiHandler extends MessageUiHandler { this.textTimer = null; this.textCallbackTimer = null; - const bg = this.scene.add.sprite(0, 0, "bg", this.scene.windowType); - bg.setOrigin(0, 1); - ui.add(bg); + this.bg = this.scene.add.sprite(0, 0, "bg", this.scene.windowType); + this.bg.setName("sprite-battle-msg-bg"); + this.bg.setOrigin(0, 1); + ui.add(this.bg); - this.bg = bg; - - this.commandWindow = addWindow(this.scene, 201, -1, 118, 46); + this.commandWindow = addWindow(this.scene, 202, 0, 118, 48); + this.commandWindow.setName("window-command"); this.commandWindow.setOrigin(0, 1); this.commandWindow.setVisible(false); ui.add(this.commandWindow); - this.movesWindowContainer = this.scene.add.container(1, -1); + this.movesWindowContainer = this.scene.add.container(0, 0); + this.movesWindowContainer.setName("moves-bg"); this.movesWindowContainer.setVisible(false); - const movesWindow = addWindow(this.scene, 0, 0, 243, 46); + const movesWindow = addWindow(this.scene, 0, 0, 243, 48); + movesWindow.setName("moves-window"); movesWindow.setOrigin(0, 1); - this.movesWindowContainer.add(movesWindow); - const moveDetailsWindow = addWindow(this.scene, 238, 0, 80, 46, false, true, 2, 133); + const moveDetailsWindow = addWindow(this.scene, 240, 0, 80, 48, false, false, -1, 132); + moveDetailsWindow.setName("move-details-window"); moveDetailsWindow.setOrigin(0, 1); - this.movesWindowContainer.add(moveDetailsWindow); - - // TODO: Maybe remove this asset definitively if it's no longer needed? - // const commandFightLabels = this.scene.add.image(246, -10, 'command_fight_labels'); - // commandFightLabels.setOrigin(0, 1); - // this.movesWindowContainer.add(commandFightLabels); + this.movesWindowContainer.add([movesWindow, moveDetailsWindow]); ui.add(this.movesWindowContainer); const messageContainer = this.scene.add.container(12, -39); diff --git a/src/ui/challenges-select-ui-handler.ts b/src/ui/challenges-select-ui-handler.ts index 67703b63aee..dce04276a4d 100644 --- a/src/ui/challenges-select-ui-handler.ts +++ b/src/ui/challenges-select-ui-handler.ts @@ -41,7 +41,7 @@ export default class GameChallengesUiHandler extends UiHandler { const ui = this.getUi(); this.challengesContainer = this.scene.add.container(1, -(this.scene.game.canvas.height / 6) + 1); - this.challengesContainer.setName("container-challenges"); + this.challengesContainer.setName("challenges"); this.challengesContainer.setInteractive(new Phaser.Geom.Rectangle(0, 0, this.scene.game.canvas.width / 6, this.scene.game.canvas.height / 6), Phaser.Geom.Rectangle.Contains); @@ -82,7 +82,7 @@ export default class GameChallengesUiHandler extends UiHandler { descriptionBg.setPositionRelative(this.optionsBg, this.optionsBg.width, 0); this.descriptionText = new BBCodeText(this.scene, descriptionBg.x + 6, descriptionBg.y + 4, "", { - fontFamily: "emerald, unifont", + fontFamily: "emerald", fontSize: 96, color: Color.ORANGE, padding: { @@ -116,7 +116,7 @@ export default class GameChallengesUiHandler extends UiHandler { this.startCursor.setVisible(false); this.valuesContainer = this.scene.add.container(0, 0); - this.valuesContainer.setName("container-values"); + this.valuesContainer.setName("values"); this.challengeLabels = []; diff --git a/src/ui/command-ui-handler.ts b/src/ui/command-ui-handler.ts index 852b1f855b6..8ccd05675c8 100644 --- a/src/ui/command-ui-handler.ts +++ b/src/ui/command-ui-handler.ts @@ -34,12 +34,14 @@ export default class CommandUiHandler extends UiHandler { i18next.t("commandUiHandler:run") ]; - this.commandsContainer = this.scene.add.container(216, -38.7); + this.commandsContainer = this.scene.add.container(217, -38.7); + this.commandsContainer.setName("commands"); this.commandsContainer.setVisible(false); ui.add(this.commandsContainer); for (let c = 0; c < commands.length; c++) { const commandText = addTextObject(this.scene, c % 2 === 0 ? 0 : 55.8, c < 2 ? 0 : 16, commands[c], TextStyle.WINDOW); + commandText.setName(commands[c]); this.commandsContainer.add(commandText); } } @@ -60,6 +62,7 @@ export default class CommandUiHandler extends UiHandler { } const messageHandler = this.getUi().getMessageHandler(); + messageHandler.bg.setVisible(true); messageHandler.commandWindow.setVisible(true); messageHandler.movesWindowContainer.setVisible(false); messageHandler.message.setWordWrapWidth(1110); diff --git a/src/ui/fight-ui-handler.ts b/src/ui/fight-ui-handler.ts index 0ee5b511b31..75108101ad9 100644 --- a/src/ui/fight-ui-handler.ts +++ b/src/ui/fight-ui-handler.ts @@ -13,6 +13,7 @@ import Pokemon, { PokemonMove } from "#app/field/pokemon.js"; export default class FightUiHandler extends UiHandler { private movesContainer: Phaser.GameObjects.Container; + private moveInfoContainer: Phaser.GameObjects.Container; private typeIcon: Phaser.GameObjects.Sprite; private ppLabel: Phaser.GameObjects.Text; private ppText: Phaser.GameObjects.Text; @@ -34,48 +35,53 @@ export default class FightUiHandler extends UiHandler { const ui = this.getUi(); this.movesContainer = this.scene.add.container(18, -38.7); + this.movesContainer.setName("moves"); ui.add(this.movesContainer); - this.typeIcon = this.scene.add.sprite((this.scene.game.canvas.width / 6) - 57, -36,`types${Utils.verifyLang(i18next.resolvedLanguage) ? `_${i18next.resolvedLanguage}` : ""}` , "unknown"); + this.moveInfoContainer = this.scene.add.container(1, 0); + this.moveInfoContainer.setName("move-info"); + ui.add(this.moveInfoContainer); + + this.typeIcon = this.scene.add.sprite(this.scene.scaledCanvas.width - 57, -36,`types${Utils.verifyLang(i18next.resolvedLanguage) ? `_${i18next.resolvedLanguage}` : ""}` , "unknown"); this.typeIcon.setVisible(false); - ui.add(this.typeIcon); + this.moveInfoContainer.add(this.typeIcon); - this.moveCategoryIcon = this.scene.add.sprite((this.scene.game.canvas.width / 6) - 25, -36, "categories", "physical"); + this.moveCategoryIcon = this.scene.add.sprite(this.scene.scaledCanvas.width - 25, -36, "categories", "physical"); this.moveCategoryIcon.setVisible(false); - ui.add(this.moveCategoryIcon); + this.moveInfoContainer.add(this.moveCategoryIcon); - this.ppLabel = addTextObject(this.scene, (this.scene.game.canvas.width / 6) - 70, -26, "PP", TextStyle.MOVE_INFO_CONTENT); + this.ppLabel = addTextObject(this.scene, this.scene.scaledCanvas.width - 70, -26, "PP", TextStyle.MOVE_INFO_CONTENT); this.ppLabel.setOrigin(0.0, 0.5); this.ppLabel.setVisible(false); this.ppLabel.setText(i18next.t("fightUiHandler:pp")); - ui.add(this.ppLabel); + this.moveInfoContainer.add(this.ppLabel); - this.ppText = addTextObject(this.scene, (this.scene.game.canvas.width / 6) - 12, -26, "--/--", TextStyle.MOVE_INFO_CONTENT); + this.ppText = addTextObject(this.scene, this.scene.scaledCanvas.width - 12, -26, "--/--", TextStyle.MOVE_INFO_CONTENT); this.ppText.setOrigin(1, 0.5); this.ppText.setVisible(false); - ui.add(this.ppText); + this.moveInfoContainer.add(this.ppText); - this.powerLabel = addTextObject(this.scene, (this.scene.game.canvas.width / 6) - 70, -18, "POWER", TextStyle.MOVE_INFO_CONTENT); + this.powerLabel = addTextObject(this.scene, this.scene.scaledCanvas.width - 70, -18, "POWER", TextStyle.MOVE_INFO_CONTENT); this.powerLabel.setOrigin(0.0, 0.5); this.powerLabel.setVisible(false); this.powerLabel.setText(i18next.t("fightUiHandler:power")); - ui.add(this.powerLabel); + this.moveInfoContainer.add(this.powerLabel); - this.powerText = addTextObject(this.scene, (this.scene.game.canvas.width / 6) - 12, -18, "---", TextStyle.MOVE_INFO_CONTENT); + this.powerText = addTextObject(this.scene, this.scene.scaledCanvas.width - 12, -18, "---", TextStyle.MOVE_INFO_CONTENT); this.powerText.setOrigin(1, 0.5); this.powerText.setVisible(false); - ui.add(this.powerText); + this.moveInfoContainer.add(this.powerText); - this.accuracyLabel = addTextObject(this.scene, (this.scene.game.canvas.width / 6) - 70, -10, "ACC", TextStyle.MOVE_INFO_CONTENT); + this.accuracyLabel = addTextObject(this.scene, this.scene.scaledCanvas.width - 70, -10, "ACC", TextStyle.MOVE_INFO_CONTENT); this.accuracyLabel.setOrigin(0.0, 0.5); this.accuracyLabel.setVisible(false); this.accuracyLabel.setText(i18next.t("fightUiHandler:accuracy")); - ui.add(this.accuracyLabel); + this.moveInfoContainer.add(this.accuracyLabel); - this.accuracyText = addTextObject(this.scene, (this.scene.game.canvas.width / 6) - 12, -10, "---", TextStyle.MOVE_INFO_CONTENT); + this.accuracyText = addTextObject(this.scene, this.scene.scaledCanvas.width - 12, -10, "---", TextStyle.MOVE_INFO_CONTENT); this.accuracyText.setOrigin(1, 0.5); this.accuracyText.setVisible(false); - ui.add(this.accuracyText); + this.moveInfoContainer.add(this.accuracyText); } show(args: any[]): boolean { @@ -84,6 +90,7 @@ export default class FightUiHandler extends UiHandler { this.fieldIndex = args.length ? args[0] as integer : 0; const messageHandler = this.getUi().getMessageHandler(); + messageHandler.bg.setVisible(false); messageHandler.commandWindow.setVisible(false); messageHandler.movesWindowContainer.setVisible(true); this.setCursor(this.getCursor()); @@ -236,10 +243,12 @@ export default class FightUiHandler extends UiHandler { for (let moveIndex = 0; moveIndex < 4; moveIndex++) { const moveText = addTextObject(this.scene, moveIndex % 2 === 0 ? 0 : 100, moveIndex < 2 ? 0 : 16, "-", TextStyle.WINDOW); + moveText.setName("text-empty-move"); if (moveIndex < moveset.length) { const pokemonMove = moveset[moveIndex]; moveText.setText(pokemonMove.getName()); + moveText.setName(pokemonMove.getName()); moveText.setColor(this.getMoveColor(pokemon, pokemonMove) ?? moveText.style.color); } diff --git a/src/ui/menu-ui-handler.ts b/src/ui/menu-ui-handler.ts index c7c06227d48..0b5082d215e 100644 --- a/src/ui/menu-ui-handler.ts +++ b/src/ui/menu-ui-handler.ts @@ -11,7 +11,7 @@ import i18next from "i18next"; import {Button} from "#enums/buttons"; import { GameDataType } from "#enums/game-data-type"; -export enum MenuOptions { +enum MenuOptions { GAME_SETTINGS, ACHIEVEMENTS, STATS, @@ -32,6 +32,7 @@ const redditUrl = "https://www.reddit.com/r/pokerogue"; export default class MenuUiHandler extends MessageUiHandler { private menuContainer: Phaser.GameObjects.Container; private menuMessageBoxContainer: Phaser.GameObjects.Container; + private menuOverlay: Phaser.GameObjects.Rectangle; private menuBg: Phaser.GameObjects.NineSlice; protected optionSelectText: Phaser.GameObjects.Text; @@ -62,10 +63,16 @@ export default class MenuUiHandler extends MessageUiHandler { } this.menuContainer = this.scene.add.container(1, -(this.scene.game.canvas.height / 6) + 1); - + this.menuContainer.setName("menu"); this.menuContainer.setInteractive(new Phaser.Geom.Rectangle(0, 0, this.scene.game.canvas.width / 6, this.scene.game.canvas.height / 6), Phaser.Geom.Rectangle.Contains); + this.menuOverlay = new Phaser.GameObjects.Rectangle(this.scene, -1, -1, this.scene.scaledCanvas.width, this.scene.scaledCanvas.height, 0xffffff, 0.3); + this.menuOverlay.setName("menu-overlay"); + this.menuOverlay.setOrigin(0,0); + this.menuContainer.add(this.menuOverlay); + const menuMessageText = addTextObject(this.scene, 8, 8, "", TextStyle.WINDOW, { maxLines: 2 }); + menuMessageText.setName("menu-message"); menuMessageText.setWordWrapWidth(1224); menuMessageText.setOrigin(0, 0); @@ -84,6 +91,7 @@ export default class MenuUiHandler extends MessageUiHandler { ui.add(this.menuContainer); this.menuMessageBoxContainer = this.scene.add.container(0, 130); + this.menuMessageBoxContainer.setName("menu-message-box"); this.menuMessageBoxContainer.setVisible(false); this.menuContainer.add(this.menuMessageBoxContainer); diff --git a/src/ui/modifier-select-ui-handler.ts b/src/ui/modifier-select-ui-handler.ts index 5792e170ac7..c403dc28abb 100644 --- a/src/ui/modifier-select-ui-handler.ts +++ b/src/ui/modifier-select-ui-handler.ts @@ -47,7 +47,7 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler { ui.add(this.modifierContainer); this.transferButtonContainer = this.scene.add.container((this.scene.game.canvas.width / 6) - 71, -64); - this.transferButtonContainer.setName("container-transfer-btn"); + this.transferButtonContainer.setName("transfer-btn"); this.transferButtonContainer.setVisible(false); ui.add(this.transferButtonContainer); @@ -57,7 +57,7 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler { this.transferButtonContainer.add(transferButtonText); this.checkButtonContainer = this.scene.add.container((this.scene.game.canvas.width / 6) - 1, -64); - this.checkButtonContainer.setName("container-use-btn"); + this.checkButtonContainer.setName("use-btn"); this.checkButtonContainer.setVisible(false); ui.add(this.checkButtonContainer); @@ -67,7 +67,7 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler { this.checkButtonContainer.add(checkButtonText); this.rerollButtonContainer = this.scene.add.container(16, -64); - this.rerollButtonContainer.setName("container-reroll-brn"); + this.rerollButtonContainer.setName("reroll-brn"); this.rerollButtonContainer.setVisible(false); ui.add(this.rerollButtonContainer); diff --git a/src/ui/party-ui-handler.ts b/src/ui/party-ui-handler.ts index 9c628acd74f..93dc052b09d 100644 --- a/src/ui/party-ui-handler.ts +++ b/src/ui/party-ui-handler.ts @@ -21,7 +21,7 @@ import MoveInfoOverlay from "./move-info-overlay"; import i18next from "i18next"; import { Moves } from "#enums/moves"; -const defaultMessage = "Choose a Pokémon."; +const defaultMessage = i18next.t("menu:choosePokemon"); export enum PartyUiMode { SWITCH, @@ -161,31 +161,37 @@ export default class PartyUiHandler extends MessageUiHandler { const ui = this.getUi(); const partyContainer = this.scene.add.container(0, 0); + partyContainer.setName("party"); partyContainer.setVisible(false); ui.add(partyContainer); this.partyContainer = partyContainer; this.partyBg = this.scene.add.image(0, 0, "party_bg"); + this.partyBg.setName("img-party-bg"); partyContainer.add(this.partyBg); this.partyBg.setOrigin(0, 1); const partySlotsContainer = this.scene.add.container(0, 0); + partySlotsContainer.setName("party-slots"); partyContainer.add(partySlotsContainer); this.partySlotsContainer = partySlotsContainer; const partyMessageBoxContainer = this.scene.add.container(0, -32); + partyMessageBoxContainer.setName("party-msg-box"); partyContainer.add(partyMessageBoxContainer); const partyMessageBox = addWindow(this.scene, 1, 31, 262, 30); + partyMessageBox.setName("window-party-msg-box"); partyMessageBox.setOrigin(0, 1); partyMessageBoxContainer.add(partyMessageBox); this.partyMessageBox = partyMessageBox; - const partyMessageText = addTextObject(this.scene, 8, 10, defaultMessage, TextStyle.WINDOW, { maxLines: 2 }); + const partyMessageText = addTextObject(this.scene, 10, 8, defaultMessage, TextStyle.WINDOW, { maxLines: 2 }); + partyMessageText.setName("text-party-msg"); partyMessageText.setOrigin(0, 0); partyMessageBoxContainer.add(partyMessageText); @@ -1224,7 +1230,7 @@ class PartyCancelButton extends Phaser.GameObjects.Container { this.partyCancelPb = partyCancelPb; - const partyCancelText = addTextObject(this.scene, -7, -6, "Cancel", TextStyle.PARTY); + const partyCancelText = addTextObject(this.scene, -8, -7, "Cancel", TextStyle.PARTY); this.add(partyCancelText); } diff --git a/src/ui/pokemon-info-container.ts b/src/ui/pokemon-info-container.ts index 482aeec6871..9ab3028b564 100644 --- a/src/ui/pokemon-info-container.ts +++ b/src/ui/pokemon-info-container.ts @@ -79,7 +79,7 @@ export default class PokemonInfoContainer extends Phaser.GameObjects.Container { } setup(): void { - this.setName("container-pkmn-info"); + this.setName("pkmn-info"); const currentLanguage = i18next.resolvedLanguage; const langSettingKey = Object.keys(languageSettings).find(lang => currentLanguage.includes(lang)); const textSettings = languageSettings[langSettingKey]; @@ -88,7 +88,7 @@ export default class PokemonInfoContainer extends Phaser.GameObjects.Container { infoBg.setName("window-info-bg"); this.pokemonMovesContainer = this.scene.add.container(6, 14); - this.pokemonMovesContainer.setName("container-pkmn-moves"); + this.pokemonMovesContainer.setName("pkmn-moves"); this.movesContainerInitialX = this.pokemonMovesContainer.x; @@ -109,7 +109,7 @@ export default class PokemonInfoContainer extends Phaser.GameObjects.Container { for (let m = 0; m < 4; m++) { const moveContainer = this.scene.add.container(-6, 18 + 7 * m); moveContainer.setScale(0.5); - moveContainer.setName("container-move"); + moveContainer.setName("move"); const moveBg = this.scene.add.nineslice(0, 0, "type_bgs", "unknown", 92, 14, 2, 2, 2, 2); moveBg.setOrigin(1, 0); diff --git a/src/ui/settings/abstract-control-settings-ui-handler.ts b/src/ui/settings/abstract-control-settings-ui-handler.ts index 2ec4c437b3c..9bf0cb40975 100644 --- a/src/ui/settings/abstract-control-settings-ui-handler.ts +++ b/src/ui/settings/abstract-control-settings-ui-handler.ts @@ -98,6 +98,7 @@ export default abstract class AbstractControlSettingsUiHandler extends UiHandler this.navigationIcons = {}; this.settingsContainer = this.scene.add.container(1, -(this.scene.game.canvas.height / 6) + 1); + this.settingsContainer.setName(`settings-${this.titleSelected}`); this.settingsContainer.setInteractive(new Phaser.Geom.Rectangle(0, 0, this.scene.game.canvas.width / 6, this.scene.game.canvas.height / 6), Phaser.Geom.Rectangle.Contains); diff --git a/src/ui/settings/abstract-settings-ui-handler.ts b/src/ui/settings/abstract-settings-ui-handler.ts index 1834d5f09dd..6763c8d3d85 100644 --- a/src/ui/settings/abstract-settings-ui-handler.ts +++ b/src/ui/settings/abstract-settings-ui-handler.ts @@ -54,7 +54,7 @@ export default class AbstractSettingsUiHandler extends UiHandler { const ui = this.getUi(); this.settingsContainer = this.scene.add.container(1, -(this.scene.game.canvas.height / 6) + 1); - + this.settingsContainer.setName(`settings-${this.title}`); this.settingsContainer.setInteractive(new Phaser.Geom.Rectangle(0, 0, this.scene.game.canvas.width / 6, this.scene.game.canvas.height / 6 - 20), Phaser.Geom.Rectangle.Contains); this.navigationIcons = {}; @@ -62,6 +62,7 @@ export default class AbstractSettingsUiHandler extends UiHandler { this.navigationContainer = new NavigationMenu(this.scene, 0, 0); this.optionsBg = addWindow(this.scene, 0, this.navigationContainer.height, (this.scene.game.canvas.width / 6) - 2, (this.scene.game.canvas.height / 6) - 16 - this.navigationContainer.height - 2); + this.optionsBg.setName("window-options-bg"); this.optionsBg.setOrigin(0, 0); const actionsBg = addWindow(this.scene, 0, (this.scene.game.canvas.height / 6) - this.navigationContainer.height, (this.scene.game.canvas.width / 6) - 2, 22); diff --git a/src/ui/starter-select-ui-handler.ts b/src/ui/starter-select-ui-handler.ts index 3ed1c6bc9e5..f32ea13deda 100644 --- a/src/ui/starter-select-ui-handler.ts +++ b/src/ui/starter-select-ui-handler.ts @@ -687,35 +687,48 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.starterSelectContainer.add(this.instructionsContainer); // instruction rows that will be pushed into the container dynamically based on need - this.shinyIconElement = this.scene.add.sprite(this.instructionRowX, this.instructionRowY, "keyboard", "R.png"); + // creating new sprites since they will be added to the scene later + this.shinyIconElement = new Phaser.GameObjects.Sprite(this.scene, this.instructionRowX, this.instructionRowY, "keyboard", "R.png"); + this.shinyIconElement.setName("sprite-shiny-icon-element"); this.shinyIconElement.setScale(0.675); this.shinyIconElement.setOrigin(0.0, 0.0); this.shinyLabel = addTextObject(this.scene, this.instructionRowX + this.instructionRowTextOffset, this.instructionRowY, i18next.t("starterSelectUiHandler:cycleShiny"), TextStyle.PARTY, { fontSize: instructionTextSize }); + this.shinyLabel.setName("text-shiny-label"); - this.formIconElement = this.scene.add.sprite(this.instructionRowX, this.instructionRowY, "keyboard", "F.png"); + this.formIconElement = new Phaser.GameObjects.Sprite(this.scene, this.instructionRowX, this.instructionRowY, "keyboard", "F.png"); + this.formIconElement.setName("sprite-form-icon-element"); this.formIconElement.setScale(0.675); this.formIconElement.setOrigin(0.0, 0.0); this.formLabel = addTextObject(this.scene, this.instructionRowX + this.instructionRowTextOffset, this.instructionRowY, i18next.t("starterSelectUiHandler:cycleForm"), TextStyle.PARTY, { fontSize: instructionTextSize }); + this.formLabel.setName("text-form-label"); - this.genderIconElement = this.scene.add.sprite(this.instructionRowX, this.instructionRowY, "keyboard", "G.png"); + this.genderIconElement = new Phaser.GameObjects.Sprite(this.scene, this.instructionRowX, this.instructionRowY, "keyboard", "G.png"); + this.genderIconElement.setName("sprite-gender-icon-element"); this.genderIconElement.setScale(0.675); this.genderIconElement.setOrigin(0.0, 0.0); this.genderLabel = addTextObject(this.scene, this.instructionRowX + this.instructionRowTextOffset, this.instructionRowY, i18next.t("starterSelectUiHandler:cycleGender"), TextStyle.PARTY, { fontSize: instructionTextSize }); + this.genderLabel.setName("text-gender-label"); - this.abilityIconElement = this.scene.add.sprite(this.instructionRowX, this.instructionRowY, "keyboard", "E.png"); + this.abilityIconElement = new Phaser.GameObjects.Sprite(this.scene, this.instructionRowX, this.instructionRowY, "keyboard", "E.png"); + this.abilityIconElement.setName("sprite-ability-icon-element"); this.abilityIconElement.setScale(0.675); this.abilityIconElement.setOrigin(0.0, 0.0); this.abilityLabel = addTextObject(this.scene, this.instructionRowX + this.instructionRowTextOffset, this.instructionRowY, i18next.t("starterSelectUiHandler:cycleAbility"), TextStyle.PARTY, { fontSize: instructionTextSize }); + this.abilityLabel.setName("text-ability-label"); - this.natureIconElement = this.scene.add.sprite(this.instructionRowX, this.instructionRowY, "keyboard", "N.png"); + this.natureIconElement = new Phaser.GameObjects.Sprite(this.scene, this.instructionRowX, this.instructionRowY, "keyboard", "N.png"); + this.natureIconElement.setName("sprite-nature-icon-element"); this.natureIconElement.setScale(0.675); this.natureIconElement.setOrigin(0.0, 0.0); this.natureLabel = addTextObject(this.scene, this.instructionRowX + this.instructionRowTextOffset, this.instructionRowY, i18next.t("starterSelectUiHandler:cycleNature"), TextStyle.PARTY, { fontSize: instructionTextSize }); + this.natureLabel.setName("text-nature-label"); - this.variantIconElement = this.scene.add.sprite(this.instructionRowX, this.instructionRowY, "keyboard", "V.png"); + this.variantIconElement = new Phaser.GameObjects.Sprite(this.scene, this.instructionRowX, this.instructionRowY, "keyboard", "V.png"); + this.variantIconElement.setName("sprite-variant-icon-element"); this.variantIconElement.setScale(0.675); this.variantIconElement.setOrigin(0.0, 0.0); this.variantLabel = addTextObject(this.scene, this.instructionRowX + this.instructionRowTextOffset, this.instructionRowY, i18next.t("starterSelectUiHandler:cycleVariant"), TextStyle.PARTY, { fontSize: instructionTextSize }); + this.variantLabel.setName("text-variant-label"); this.hideInstructions(); diff --git a/src/ui/stats-container.ts b/src/ui/stats-container.ts index 11154bd700b..b4e799bafc0 100644 --- a/src/ui/stats-container.ts +++ b/src/ui/stats-container.ts @@ -26,7 +26,7 @@ export class StatsContainer extends Phaser.GameObjects.Container { } setup() { - this.setName("container-stats"); + this.setName("stats"); const ivChartBgData = new Array(6).fill(null).map((_, i: integer) => [ ivChartSize * ivChartStatCoordMultipliers[ivChartStatIndexes[i]][0], ivChartSize * ivChartStatCoordMultipliers[ivChartStatIndexes[i]][1] ] ).flat(); const ivChartBg = this.scene.add.polygon(48, 44, ivChartBgData, 0xd8e0f0, 0.625); diff --git a/src/ui/title-ui-handler.ts b/src/ui/title-ui-handler.ts index 54c478a7ad7..4036e0b9922 100644 --- a/src/ui/title-ui-handler.ts +++ b/src/ui/title-ui-handler.ts @@ -1,22 +1,20 @@ import BattleScene from "../battle-scene"; -import { DailyRunScoreboard } from "./daily-run-scoreboard"; import OptionSelectUiHandler from "./settings/option-select-ui-handler"; import { Mode } from "./ui"; import * as Utils from "../utils"; import { TextStyle, addTextObject } from "./text"; import { getBattleCountSplashMessage, getSplashMessages } from "../data/splash-messages"; import i18next from "i18next"; +import { TimedEventDisplay } from "#app/timed-event-manager.js"; export default class TitleUiHandler extends OptionSelectUiHandler { private titleContainer: Phaser.GameObjects.Container; - private dailyRunScoreboard: DailyRunScoreboard; private playerCountLabel: Phaser.GameObjects.Text; private splashMessage: string; private splashMessageText: Phaser.GameObjects.Text; - private eventTimerText: Phaser.GameObjects.Text; + private eventDisplay: TimedEventDisplay; private titleStatsTimer: NodeJS.Timeout; - private eventTimer: NodeJS.Timeout; constructor(scene: BattleScene, mode: Mode = Mode.TITLE) { super(scene, mode); @@ -28,7 +26,7 @@ export default class TitleUiHandler extends OptionSelectUiHandler { const ui = this.getUi(); this.titleContainer = this.scene.add.container(0, -(this.scene.game.canvas.height / 6)); - this.titleContainer.setName("container-title"); + this.titleContainer.setName("title"); this.titleContainer.setAlpha(0); ui.add(this.titleContainer); @@ -37,36 +35,9 @@ export default class TitleUiHandler extends OptionSelectUiHandler { this.titleContainer.add(logo); if (this.scene.eventManager.isEventActive()) { - const event = this.scene.eventManager.activeEvent(); - const banner = this.scene.add.image(29, 64, event.bannerFilename); - banner.setName("img-event-banner"); - banner.setOrigin(0, 0); - banner.setScale(0.07); - const bannerShadow = this.scene.add.rectangle( - banner.x - 2, - banner.y + 2, - banner.width, - banner.height, - 0x484848 - ); - bannerShadow.setName("rect-event-banner-shadow"); - bannerShadow.setScale(0.07); - bannerShadow.setAlpha(0.5); - bannerShadow.setOrigin(0,0); - this.eventTimerText = addTextObject( - this.scene, - banner.x + 8, - banner.y + 100, - this.timeToGo(event.endDate), - TextStyle.WINDOW - ); - this.eventTimerText.setName("text-event-timer"); - this.eventTimerText.setScale(0.15); - this.eventTimerText.setOrigin(0,0); - - this.titleContainer.add(bannerShadow); - this.titleContainer.add(banner); - this.titleContainer.add(this.eventTimerText); + 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) - 109, `? ${i18next.t("menu:playersOnline")}`, TextStyle.MESSAGE, { fontSize: "54px" }); @@ -89,33 +60,6 @@ export default class TitleUiHandler extends OptionSelectUiHandler { }); } - timeToGo(date: Date) { - - // Utility to add leading zero - function z(n) { - return (n < 10? "0" : "") + n; - } - const now = new Date(); - let diff = Math.abs(date.getTime() - now.getTime()); - - // Allow for previous times - diff = Math.abs(diff); - - // Get time components - const days = diff/8.64e7 | 0; - const hours = diff%8.64e7 / 3.6e6 | 0; - const mins = diff%3.6e6 / 6e4 | 0; - const secs = Math.round(diff%6e4 / 1e3); - - // Return formatted string - return "Event Ends in : " + z(days) + "d " + z(hours) + "h " + z(mins) + "m " + z(secs)+ "s"; - } - - updateCountdown() { - const event = this.scene.eventManager.activeEvent(); - this.eventTimerText.setText(this.timeToGo(event.endDate)); - } - updateTitleStats(): void { Utils.apiFetch("game/titlestats") .then(request => request.json()) @@ -139,14 +83,8 @@ export default class TitleUiHandler extends OptionSelectUiHandler { const ui = this.getUi(); - // this.dailyRunScoreboard.update(); - if (this.scene.eventManager.isEventActive()) { - this.updateCountdown(); - - this.eventTimer = setInterval(() => { - this.updateCountdown(); - }, 1000); + this.eventDisplay.show(); } this.updateTitleStats(); @@ -171,8 +109,7 @@ export default class TitleUiHandler extends OptionSelectUiHandler { const ui = this.getUi(); - clearInterval(this.eventTimer); - this.eventTimer = null; + this.eventDisplay?.clear(); clearInterval(this.titleStatsTimer); this.titleStatsTimer = null; diff --git a/src/ui/ui-theme.ts b/src/ui/ui-theme.ts index b2992d049cb..58490e1c618 100644 --- a/src/ui/ui-theme.ts +++ b/src/ui/ui-theme.ts @@ -46,13 +46,25 @@ export function addWindow(scene: BattleScene, x: number, y: number, width: numbe const window = scene.add.nineslice(x, y, `window_${scene.windowType}${getWindowVariantSuffix(windowVariant)}`, null, width, height, borderSize, borderSize, borderSize, borderSize); window.setOrigin(0, 0); - if (mergeMaskTop || mergeMaskLeft) { - const maskRect = scene.make.graphics({}); + if (mergeMaskLeft || mergeMaskTop || maskOffsetX || maskOffsetY) { + /** + * x: left + * y: top + * width: right + * height: bottom + */ + const maskRect = new Phaser.GameObjects.Rectangle( + scene, + 6*(x - (mergeMaskLeft ? 2 : 0) - (maskOffsetX || 0)), + 6*(y + (mergeMaskTop ? 2 : 0) + (maskOffsetY || 0)), + width - (mergeMaskLeft ? 2 : 0), + height - (mergeMaskTop ? 2 : 0), + 0xffffff + ); + maskRect.setOrigin(0); maskRect.setScale(6); - maskRect.fillStyle(0xFFFFFF); - maskRect.beginPath(); - maskRect.fillRect(window.x + (mergeMaskLeft ? 2 : 0) + (maskOffsetX || 0), window.y + (mergeMaskTop ? 2 : 0) + (maskOffsetY || 0), window.width - (mergeMaskLeft ? 2 : 0), window.height - (mergeMaskTop ? 2 : 0)); - window.setMask(maskRect.createGeometryMask()); + const mask = maskRect.createGeometryMask(); + window.setMask(mask); } return window; diff --git a/src/ui/ui.ts b/src/ui/ui.ts index 75ccfc40f59..6b9de255590 100644 --- a/src/ui/ui.ts +++ b/src/ui/ui.ts @@ -159,6 +159,7 @@ export default class UI extends Phaser.GameObjects.Container { new OptionSelectUiHandler(scene), new MenuUiHandler(scene), new OptionSelectUiHandler(scene, Mode.MENU_OPTION_SELECT), + // settings new SettingsUiHandler(scene), new SettingsDisplayUiHandler(scene), new SettingsAudioUiHandler(scene), @@ -182,11 +183,12 @@ export default class UI extends Phaser.GameObjects.Container { } setup(): void { - this.setName(`container-ui-${Mode[this.mode]}`); + this.setName(`ui-${Mode[this.mode]}`); for (const handler of this.handlers) { handler.setup(); } this.overlay = this.scene.add.rectangle(0, 0, this.scene.game.canvas.width / 6, this.scene.game.canvas.height / 6, 0); + this.overlay.setName("rect-ui-overlay"); this.overlay.setOrigin(0, 0); (this.scene as BattleScene).uiContainer.add(this.overlay); this.overlay.setVisible(false); @@ -205,15 +207,19 @@ export default class UI extends Phaser.GameObjects.Container { private setupTooltip() { this.tooltipContainer = this.scene.add.container(0, 0); + this.tooltipContainer.setName("tooltip"); this.tooltipContainer.setVisible(false); this.tooltipBg = addWindow(this.scene as BattleScene, 0, 0, 128, 31); + this.tooltipBg.setName("window-tooltip-bg"); this.tooltipBg.setOrigin(0, 0); this.tooltipTitle = addTextObject(this.scene, 64, 4, "", TextStyle.TOOLTIP_TITLE); + this.tooltipTitle.setName("text-tooltip-title"); this.tooltipTitle.setOrigin(0.5, 0); this.tooltipContent = addTextObject(this.scene, 6, 16, "", TextStyle.TOOLTIP_CONTENT); + this.tooltipContent.setName("text-tooltip-content"); this.tooltipContent.setWordWrapWidth(696); this.tooltipContainer.add(this.tooltipBg);