diff --git a/public/images/ui/discord.png b/public/images/ui/discord.png new file mode 100644 index 00000000000..f43aff65ee4 Binary files /dev/null and b/public/images/ui/discord.png differ diff --git a/public/images/ui/github.png b/public/images/ui/github.png new file mode 100644 index 00000000000..bbf850cda35 Binary files /dev/null and b/public/images/ui/github.png differ diff --git a/public/images/ui/legacy/discord.png b/public/images/ui/legacy/discord.png new file mode 100644 index 00000000000..f43aff65ee4 Binary files /dev/null and b/public/images/ui/legacy/discord.png differ diff --git a/public/images/ui/legacy/github.png b/public/images/ui/legacy/github.png new file mode 100644 index 00000000000..bbf850cda35 Binary files /dev/null and b/public/images/ui/legacy/github.png differ diff --git a/public/images/ui/legacy/reddit.png b/public/images/ui/legacy/reddit.png new file mode 100644 index 00000000000..745d9237b5a Binary files /dev/null and b/public/images/ui/legacy/reddit.png differ diff --git a/public/images/ui/legacy/wiki.png b/public/images/ui/legacy/wiki.png new file mode 100644 index 00000000000..afd34a49194 Binary files /dev/null and b/public/images/ui/legacy/wiki.png differ diff --git a/public/images/ui/reddit.png b/public/images/ui/reddit.png new file mode 100644 index 00000000000..745d9237b5a Binary files /dev/null and b/public/images/ui/reddit.png differ diff --git a/public/images/ui/wiki.png b/public/images/ui/wiki.png new file mode 100644 index 00000000000..afd34a49194 Binary files /dev/null and b/public/images/ui/wiki.png differ diff --git a/src/data/splash-messages.ts b/src/data/splash-messages.ts index bd64456c993..a8416973bfa 100644 --- a/src/data/splash-messages.ts +++ b/src/data/splash-messages.ts @@ -5,8 +5,7 @@ export function getBattleCountSplashMessage(): string { } export function getSplashMessages(): string[] { - const splashMessages = Array(10).fill(getBattleCountSplashMessage()); - splashMessages.push(...[ + return [ i18next.t("splashMessages:joinTheDiscord"), i18next.t("splashMessages:infiniteLevels"), i18next.t("splashMessages:everythingStacks"), @@ -39,7 +38,5 @@ export function getSplashMessages(): string[] { i18next.t("splashMessages:alsoTryRadicalRed"), i18next.t("splashMessages:eeveeExpo"), i18next.t("splashMessages:ynoproject"), - ]); - - return splashMessages; + ]; } diff --git a/src/loading-scene.ts b/src/loading-scene.ts index 0a6648a9c57..cce131f271f 100644 --- a/src/loading-scene.ts +++ b/src/loading-scene.ts @@ -53,6 +53,10 @@ export class LoadingScene extends SceneBase { this.loadImage(`window_${w}${getWindowVariantSuffix(wv)}`, "ui/windows"); } } + this.loadImage("discord", "ui"); + this.loadImage("reddit", "ui"); + this.loadImage("github", "ui"); + this.loadImage("wiki", "ui"); this.loadAtlas("namebox", "ui"); this.loadImage("pbinfo_player", "ui"); this.loadImage("pbinfo_player_stats", "ui"); diff --git a/src/locales/de/menu.ts b/src/locales/de/menu.ts index 5bbd19be851..0523e03cf22 100644 --- a/src/locales/de/menu.ts +++ b/src/locales/de/menu.ts @@ -48,7 +48,7 @@ export const menu: SimpleTranslationEntries = { "wave": "Welle", "loading": "Lade…", "loadingAsset": "Lade Asset: {{assetName}}", - "playersOnline": "Spieler Online", + "playersOnline": "{{count}} Spieler Online", "yes":"Ja", "no":"Nein", "disclaimer": "HAFTUNGSAUSSCHLUSS", diff --git a/src/locales/en/menu.ts b/src/locales/en/menu.ts index 47d19bd56b6..8dfa6cc1d71 100644 --- a/src/locales/en/menu.ts +++ b/src/locales/en/menu.ts @@ -48,7 +48,7 @@ export const menu: SimpleTranslationEntries = { "wave": "Wave", "loading": "Loading…", "loadingAsset": "Loading asset: {{assetName}}", - "playersOnline": "Players Online", + "playersOnline": "{{count}} Players Online", "yes":"Yes", "no":"No", "disclaimer": "DISCLAIMER", diff --git a/src/locales/es/menu.ts b/src/locales/es/menu.ts index 8176af456e1..44075bf3053 100644 --- a/src/locales/es/menu.ts +++ b/src/locales/es/menu.ts @@ -48,7 +48,7 @@ export const menu: SimpleTranslationEntries = { "wave": "Wave", "loading": "Cargando…", "loadingAsset": "Cargando recurso: {{assetName}}", - "playersOnline": "Jugadores en Línea", + "playersOnline": "{{count}} Jugadores en Línea", "yes":"Sí", "no":"No", "disclaimer": "AVISO", diff --git a/src/locales/fr/menu.ts b/src/locales/fr/menu.ts index 0402bd4bfda..76c1a8020b1 100644 --- a/src/locales/fr/menu.ts +++ b/src/locales/fr/menu.ts @@ -43,7 +43,7 @@ export const menu: SimpleTranslationEntries = { "wave": "Vague", "loading": "Chargement…", "loadingAsset": "Chargement de la ressource : {{assetName}}", - "playersOnline": "Joueurs Connectés", + "playersOnline": "{{count}} Joueurs Connectés", "yes":"Oui", "no":"Non", "disclaimer": "AVERTISSEMENT", diff --git a/src/locales/it/menu.ts b/src/locales/it/menu.ts index 3336373a6c3..0bfc962f778 100644 --- a/src/locales/it/menu.ts +++ b/src/locales/it/menu.ts @@ -43,7 +43,7 @@ export const menu: SimpleTranslationEntries = { "wave": "Wave", "loading": "Caricamento…", "loadingAsset": "Caricamento asset: {{assetName}}", - "playersOnline": "Giocatori online", + "playersOnline": "{{count}} Giocatori online", "evolving": "Cosa?\n{{pokemonName}} si sta evolvendo!", "stoppedEvolving": "{{pokemonName}} ha smesso di evolversi.", "pauseEvolutionsQuestion": "Vuoi sospendere le evoluzioni per {{pokemonName}}?\nPossono essere riattivate dalla schermata del party.", diff --git a/src/locales/ko/menu.ts b/src/locales/ko/menu.ts index cf72dab8a37..ba8305b0a88 100644 --- a/src/locales/ko/menu.ts +++ b/src/locales/ko/menu.ts @@ -48,7 +48,7 @@ export const menu: SimpleTranslationEntries = { "wave": "웨이브", "loading": "로딩 중…", "loadingAsset": "Loading asset: {{assetName}}", - "playersOnline": "플레이어 온라인", + "playersOnline": "{{count}} 플레이어 온라인", "yes":"예", "no":"아니오", "disclaimer": "면책 조항", diff --git a/src/locales/pt_BR/menu.ts b/src/locales/pt_BR/menu.ts index a200f2c9abe..0c0eeaa160d 100644 --- a/src/locales/pt_BR/menu.ts +++ b/src/locales/pt_BR/menu.ts @@ -48,7 +48,7 @@ export const menu: SimpleTranslationEntries = { "wave": "Onda", "loading": "Carregando…", "loadingAsset": "Carregando recurso: {{assetName}}", - "playersOnline": "Jogadores Ativos", + "playersOnline": "{{count}} Jogadores Ativos", "yes": "Sim", "no": "Não", "disclaimer": "AVISO", diff --git a/src/locales/zh_CN/menu.ts b/src/locales/zh_CN/menu.ts index c19c41333e8..f58046f3ffc 100644 --- a/src/locales/zh_CN/menu.ts +++ b/src/locales/zh_CN/menu.ts @@ -48,7 +48,7 @@ export const menu: SimpleTranslationEntries = { "wave": "层数", "loading": "加载中...", "loadingAsset": "加载资源: {{assetName}}", - "playersOnline": "在线玩家", + "playersOnline": "{{count}} 在线玩家", "yes": "是", "no": "否", "disclaimer": "免责声明", diff --git a/src/locales/zh_TW/menu.ts b/src/locales/zh_TW/menu.ts index 6d89bc256c6..8b405267f34 100644 --- a/src/locales/zh_TW/menu.ts +++ b/src/locales/zh_TW/menu.ts @@ -48,7 +48,7 @@ export const menu: SimpleTranslationEntries = { "wave": "Wave", "loading": "加載中…", "loadingAsset": "Loading asset: {{assetName}}", - "playersOnline": "在線玩家", + "playersOnline": "{{count}} 在線玩家", "yes":"是", "no":"否", "disclaimer": "DISCLAIMER", diff --git a/src/phases.ts b/src/phases.ts index 6865c030730..ac2e14db939 100644 --- a/src/phases.ts +++ b/src/phases.ts @@ -191,104 +191,34 @@ export class TitlePhase extends Phase { const bgTexture = `${biomeKey}_bg`; this.scene.arenaBg.setTexture(bgTexture); } - this.showOptions(); }).catch(err => { console.error(err); - this.showOptions(); }); + this.scene.ui.setMode(Mode.TITLE, this.showOptions()); } - showOptions(): void { + showOptions(): OptionSelectConfig { const options: OptionSelectItem[] = []; - if (loggedInUser.lastSessionSlot > -1) { - options.push({ - label: i18next.t("continue", null, { ns: "menu"}), - handler: () => { - this.loadSaveSlot(this.lastSessionData ? -1 : loggedInUser.lastSessionSlot); - return true; - } - }); - } + // if (loggedInUser.lastSessionSlot > -1) { + // options.push({ + // label: i18next.t("menu:continue"), + // handler: () => { + // this.loadSaveSlot(this.lastSessionData ? -1 : loggedInUser.lastSessionSlot); + // return true; + // } + // }); + // } options.push({ - label: i18next.t("menu:newGame"), - handler: () => { - const setModeAndEnd = (gameMode: GameModes) => { - this.gameMode = gameMode; - this.scene.ui.setMode(Mode.MESSAGE); - this.scene.ui.clearText(); - this.end(); - }; - if (this.scene.gameData.unlocks[Unlockables.ENDLESS_MODE]) { - const options: OptionSelectItem[] = [ - { - label: GameMode.getModeName(GameModes.CLASSIC), - handler: () => { - setModeAndEnd(GameModes.CLASSIC); - return true; - } - }, - { - label: GameMode.getModeName(GameModes.CHALLENGE), - handler: () => { - setModeAndEnd(GameModes.CHALLENGE); - return true; - } - }, - { - label: GameMode.getModeName(GameModes.ENDLESS), - handler: () => { - setModeAndEnd(GameModes.ENDLESS); - return true; - } - } - ]; - if (this.scene.gameData.unlocks[Unlockables.SPLICED_ENDLESS_MODE]) { - options.push({ - label: GameMode.getModeName(GameModes.SPLICED_ENDLESS), - handler: () => { - setModeAndEnd(GameModes.SPLICED_ENDLESS); - return true; - } - }); - } - options.push({ - label: i18next.t("menu:cancel"), - handler: () => { - this.scene.clearPhaseQueue(); - this.scene.pushPhase(new TitlePhase(this.scene)); - super.end(); - return true; - } - }); - this.scene.ui.showText(i18next.t("menu:selectGameMode"), null, () => this.scene.ui.setOverlayMode(Mode.OPTION_SELECT, { options: options })); - } else { - this.gameMode = GameModes.CLASSIC; - this.scene.ui.setMode(Mode.MESSAGE); - this.scene.ui.clearText(); - this.end(); - } - return true; - } + label: i18next.t("menu:loadGame"), + handler: () => this.loadGameHandler(), }, { - label: i18next.t("menu:loadGame"), - handler: () => { - this.scene.ui.setOverlayMode(Mode.SAVE_SLOT, SaveSlotUiMode.LOAD, - (slotId: integer) => { - if (slotId === -1) { - return this.showOptions(); - } - this.loadSaveSlot(slotId); - }); - return true; - } + label: i18next.t("menu:newGame"), + handler: () => this.newGameHandler(), }, { label: i18next.t("menu:dailyRun"), - handler: () => { - this.initDailyRun(); - return true; - }, + handler: () => this.initDailyRun(), keepOpen: true }, { @@ -299,12 +229,65 @@ export class TitlePhase extends Phase { }, keepOpen: true }); - const config: OptionSelectConfig = { + return { options: options, noCancel: true, - yOffset: 47 + xOffset: 220, + yOffset: 13, + noBg: true, }; - this.scene.ui.setMode(Mode.TITLE, config); + } + + newGameHandler(): boolean { + const setModeAndEnd = (gameMode: GameModes) => { + this.gameMode = gameMode; + this.scene.ui.setMode(Mode.MESSAGE); + this.scene.ui.clearText(); + this.end(); + return true; + }; + const optionLabel = (gameMode: GameModes) => { + return { + label: GameMode.getModeName(gameMode), + handler: () => setModeAndEnd(gameMode) + }; + }; + if (this.scene.gameData.unlocks[Unlockables.ENDLESS_MODE]) { + const availableGameModes = [GameModes.CLASSIC, GameModes.CHALLENGE, GameModes.ENDLESS]; + if (this.scene.gameData.unlocks[Unlockables.SPLICED_ENDLESS_MODE]) { + availableGameModes.push(GameModes.SPLICED_ENDLESS); + } + const options: OptionSelectItem[] = availableGameModes.map((gameMode: GameModes) => optionLabel(gameMode)); + options.push({ + label: i18next.t("menu:cancel"), + handler: () => { + this.scene.clearPhaseQueue(); + this.scene.pushPhase(new TitlePhase(this.scene)); + super.end(); + return true; + } + }); + const messageHandler = this.scene.ui.getMessageHandler(); + messageHandler.bg.setVisible(true); + this.scene.ui.showText(i18next.t("menu:selectGameMode"), null, () => this.scene.ui.setOverlayMode(Mode.OPTION_SELECT, { options: options })); + } else { + this.gameMode = GameModes.CLASSIC; + this.scene.ui.setMode(Mode.MESSAGE); + this.scene.ui.clearText(); + this.end(); + } + return true; + } + + loadGameHandler(): boolean { + this.scene.ui.setOverlayMode(Mode.SAVE_SLOT, SaveSlotUiMode.LOAD, + (slotId: integer) => { + if (slotId === -1) { + return this.scene.ui.setMode(Mode.TITLE, this.showOptions()); + } + this.loadSaveSlot(slotId); + }); + return true; } loadSaveSlot(slotId: integer): void { @@ -323,7 +306,7 @@ export class TitlePhase extends Phase { }); } - initDailyRun(): void { + initDailyRun(): boolean { this.scene.ui.setMode(Mode.SAVE_SLOT, SaveSlotUiMode.SAVE, (slotId: integer) => { this.scene.clearPhaseQueue(); if (slotId === -1) { @@ -390,6 +373,7 @@ export class TitlePhase extends Phase { generateDaily(btoa(new Date().toISOString().substring(0, 10))); } }); + return true; } end(): void { diff --git a/src/scene-base.ts b/src/scene-base.ts index 1d7a2518300..33d21552603 100644 --- a/src/scene-base.ts +++ b/src/scene-base.ts @@ -1,4 +1,5 @@ export const legacyCompatibleImages: string[] = []; +export { GameObjects } from "phaser"; export class SceneBase extends Phaser.Scene { /** diff --git a/src/timed-event-manager.ts b/src/timed-event-manager.ts index dac67bd7b4e..1d02726b0ff 100644 --- a/src/timed-event-manager.ts +++ b/src/timed-event-manager.ts @@ -77,28 +77,27 @@ export class TimedEventDisplay extends Phaser.GameObjects.Container { } setup() { - this.banner = new Phaser.GameObjects.Image(this.scene, 29, 64, this.event.bannerFilename); + this.banner = new Phaser.GameObjects.Image(this.scene, 0, 0, this.event.bannerFilename); this.banner.setName("img-event-banner"); this.banner.setOrigin(0, 0); - this.banner.setScale(0.07); + this.banner.setScale(0.05); this.bannerShadow = new Phaser.GameObjects.Rectangle( this.scene, this.banner.x - 2, this.banner.y + 2, - this.banner.width, - this.banner.height, + this.banner.width * this.banner.scaleX, + this.banner.height * this.banner.scaleY, 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.banner.x + 3, + this.banner.y - 10, this.timeToGo(this.event.endDate), - TextStyle.WINDOW + TextStyle.BATTLE_INFO ); this.eventTimerText.setName("text-event-timer"); this.eventTimerText.setScale(0.15); diff --git a/src/ui/abstact-option-select-ui-handler.ts b/src/ui/abstact-option-select-ui-handler.ts index 2069f034e89..b978d0ba879 100644 --- a/src/ui/abstact-option-select-ui-handler.ts +++ b/src/ui/abstact-option-select-ui-handler.ts @@ -4,7 +4,6 @@ import { Mode } from "./ui"; import UiHandler from "./ui-handler"; import { addWindow } from "./ui-theme"; import * as Utils from "../utils"; -import { argbFromRgba } from "@material/material-color-utilities"; import {Button} from "#enums/buttons"; export interface OptionSelectConfig { @@ -15,6 +14,8 @@ export interface OptionSelectConfig { delay?: integer; noCancel?: boolean; supportHover?: boolean; + noBg?: boolean; + textStyle?: TextStyle; } export interface OptionSelectItem { @@ -33,7 +34,7 @@ const scrollDownLabel = "↓"; export default abstract class AbstractOptionSelectUiHandler extends UiHandler { protected optionSelectContainer: Phaser.GameObjects.Container; protected optionSelectBg: Phaser.GameObjects.NineSlice; - protected optionSelectText: Phaser.GameObjects.Text; + protected optionSelectText: Phaser.GameObjects.Text[]; protected optionSelectIcons: Phaser.GameObjects.Sprite[]; protected config: OptionSelectConfig; @@ -65,6 +66,7 @@ export default abstract class AbstractOptionSelectUiHandler extends UiHandler { this.optionSelectBg = addWindow(this.scene, 0, 0, this.getWindowWidth(), this.getWindowHeight()); this.optionSelectBg.setName("option-select-bg"); this.optionSelectBg.setOrigin(1, 1); + this.optionSelectBg.ignoreDestroy = true; this.optionSelectContainer.add(this.optionSelectBg); this.optionSelectIcons = []; @@ -76,51 +78,57 @@ export default abstract class AbstractOptionSelectUiHandler extends UiHandler { const options = this.config?.options || []; if (this.optionSelectText) { - this.optionSelectText.destroy(); - } - if (this.optionSelectIcons?.length) { - this.optionSelectIcons.map(i => i.destroy()); - this.optionSelectIcons.splice(0, this.optionSelectIcons.length); + Phaser.Actions.Call(this.optionSelectText, (text) => text.destroy(), this); } + const optionText = this.config?.options.length > this.config?.maxOptions ? this.getOptionsWithScroll() : options; + this.optionSelectText = []; + this.optionSelectText = optionText.map(o => { + const ret = addTextObject(this.scene, 0, 0, + o.item ? ` ${o.label}` : o.label, + ( this.config?.textStyle ?? TextStyle.WINDOW), + { maxLines: options.length, lineSpacing: 12 } + ); + ret.setName(`text-${o.label}`); + return ret; + }); - 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); + const displayWidth = Math.max(...this.optionSelectText.map(t => t.displayWidth)); this.optionSelectContainer.add(this.optionSelectText); - this.optionSelectContainer.setPosition((this.scene.game.canvas.width / 6) - 1 - (this.config?.xOffset || 0), -48 + (this.config?.yOffset || 0)); - - this.optionSelectBg.width = Math.max(this.optionSelectText.displayWidth + 24, this.getWindowWidth()); - - if (this.config?.options.length > this.config?.maxOptions) { - this.optionSelectText.setText(this.getOptionsWithScroll().map(o => o.label).join("\n")); - } + this.optionSelectContainer.setPosition(this.scene.scaledCanvas.width - 1 - (this.config?.xOffset || 0), -48 + (this.config?.yOffset || 0)); + this.optionSelectBg.width = Math.max(displayWidth + 24, this.getWindowWidth()); this.optionSelectBg.height = this.getWindowHeight(); - this.optionSelectText.setPositionRelative(this.optionSelectBg, 16, 9); + Phaser.Actions.Call(this.optionSelectText, (t: Phaser.GameObjects.Text) => t.setPositionRelative(this.optionSelectBg, 16, 9), this); + Phaser.Actions.SetY(this.optionSelectText, this.optionSelectText[0].y, 16); + if (this.config?.noBg) { + this.optionSelectBg.setVisible(false); + } + + this.optionSelectIcons.forEach(i => i.destroy()); options.forEach((option: OptionSelectItem, i: integer) => { if (option.item) { - const itemIcon = this.scene.add.sprite(0, 0, "items", option.item); - itemIcon.setScale(0.5); - this.optionSelectIcons.push(itemIcon); - - this.optionSelectContainer.add(itemIcon); - - itemIcon.setPositionRelative(this.optionSelectText, 6, 7 + 16 * i); - + const iconGroup = new Phaser.GameObjects.Group(this.scene, [], { + classType: Phaser.GameObjects.Sprite, + createCallback: (sprite: Phaser.GameObjects.Sprite) => { + sprite.setName(`icon-${option.item}`); + sprite.setScale(0.6); + sprite.setPositionRelative(this.optionSelectText[0], 6, 5 + 16 * i); + } + }); + const itemIcon = new Phaser.GameObjects.Sprite(this.scene, 0, 0, "items", option.item); + iconGroup.add(itemIcon); if (option.item === "candy") { - const itemOverlayIcon = this.scene.add.sprite(0, 0, "items", "candy_overlay"); - itemOverlayIcon.setScale(0.5); - this.optionSelectIcons.push(itemOverlayIcon); + const itemOverlayIcon = new Phaser.GameObjects.Sprite(this.scene, 0, 0, "items", "candy_overlay"); + iconGroup.add(itemOverlayIcon); - this.optionSelectContainer.add(itemOverlayIcon); - - itemOverlayIcon.setPositionRelative(this.optionSelectText, 6, 7 + 16 * i); - - itemIcon.setTint(argbFromRgba(Utils.rgbHexToRgba(option.itemArgs[0]))); - itemOverlayIcon.setTint(argbFromRgba(Utils.rgbHexToRgba(option.itemArgs[1]))); + itemIcon.setTint(Number(`0x${option.itemArgs[0]}`)); + itemOverlayIcon.setTint(Number(`0x${option.itemArgs[1]}`)); } + this.optionSelectIcons.push(...(iconGroup.children.getArray() as Phaser.GameObjects.Sprite[])); + + this.optionSelectContainer.add(this.optionSelectIcons); } }); } @@ -143,7 +151,7 @@ export default abstract class AbstractOptionSelectUiHandler extends UiHandler { if (this.config.delay) { this.blockInput = true; - this.optionSelectText.setAlpha(0.5); + Phaser.Actions.SetAlpha(this.optionSelectText, 0.5); this.scene.time.delayedCall(Utils.fixedInt(this.config.delay), () => this.unblockInput()); } @@ -217,7 +225,7 @@ export default abstract class AbstractOptionSelectUiHandler extends UiHandler { } this.blockInput = false; - this.optionSelectText.setAlpha(1); + Phaser.Actions.SetAlpha(this.optionSelectText, 1); } getOptionsWithScroll(): OptionSelectItem[] { @@ -291,6 +299,7 @@ export default abstract class AbstractOptionSelectUiHandler extends UiHandler { if (!this.cursorObj) { this.cursorObj = this.scene.add.image(0, 0, "cursor"); + this.cursorObj.setName("cursor"); this.optionSelectContainer.add(this.cursorObj); } @@ -303,13 +312,14 @@ export default abstract class AbstractOptionSelectUiHandler extends UiHandler { super.clear(); this.config = null; this.optionSelectContainer.setVisible(false); + this.optionSelectContainer.removeBetween(1); + this.optionSelectIcons.forEach(i => i.destroy()); + this.optionSelectText.forEach(t => t.destroy()); this.eraseCursor(); } eraseCursor() { - if (this.cursorObj) { - this.cursorObj.destroy(); - } + this.cursorObj?.destroy(); this.cursorObj = null; } } diff --git a/src/ui/ball-ui-handler.ts b/src/ui/ball-ui-handler.ts index 70349444647..ab33ad74586 100644 --- a/src/ui/ball-ui-handler.ts +++ b/src/ui/ball-ui-handler.ts @@ -23,6 +23,7 @@ export default class BallUiHandler extends UiHandler { const ui = this.getUi(); this.pokeballSelectContainer = this.scene.add.container((this.scene.game.canvas.width / 6) - 115, -49); + this.pokeballSelectContainer.setName("pokeball-select"); this.pokeballSelectContainer.setVisible(false); ui.add(this.pokeballSelectContainer); @@ -37,12 +38,14 @@ export default class BallUiHandler extends UiHandler { } optionsTextContent += "Cancel"; const optionsText = addTextObject(this.scene, 0, 0, optionsTextContent, TextStyle.WINDOW, { align: "right", maxLines: 6 }); + optionsText.setName("pokeball-options"); optionsText.setOrigin(0, 0); optionsText.setPositionRelative(this.pokeballSelectBg, 42, 9); optionsText.setLineSpacing(12); this.pokeballSelectContainer.add(optionsText); this.countsText = addTextObject(this.scene, 0, 0, "", TextStyle.WINDOW, { maxLines: 5 }); + this.countsText.setName("pokeball-counts"); this.countsText.setPositionRelative(this.pokeballSelectBg, 18, 9); this.countsText.setLineSpacing(12); this.pokeballSelectContainer.add(this.countsText); @@ -111,6 +114,7 @@ export default class BallUiHandler extends UiHandler { if (!this.cursorObj) { this.cursorObj = this.scene.add.image(0, 0, "cursor"); + this.cursorObj.setName("cursor"); this.pokeballSelectContainer.add(this.cursorObj); } diff --git a/src/ui/battle-message-ui-handler.ts b/src/ui/battle-message-ui-handler.ts index f2da553c6da..c6c4ccc1713 100644 --- a/src/ui/battle-message-ui-handler.ts +++ b/src/ui/battle-message-ui-handler.ts @@ -34,6 +34,7 @@ export default class BattleMessageUiHandler extends MessageUiHandler { this.bg = this.scene.add.sprite(0, 0, "bg", this.scene.windowType); this.bg.setName("sprite-battle-msg-bg"); this.bg.setOrigin(0, 1); + this.bg.setVisible(false); ui.add(this.bg); this.commandWindow = addWindow(this.scene, 202, 0, 118, 48); diff --git a/src/ui/candy-bar.ts b/src/ui/candy-bar.ts index 3a9f180dd59..c98030c2254 100644 --- a/src/ui/candy-bar.ts +++ b/src/ui/candy-bar.ts @@ -1,7 +1,5 @@ import BattleScene, { starterColors } from "../battle-scene"; import { TextStyle, addTextObject } from "./text"; -import { argbFromRgba } from "@material/material-color-utilities"; -import * as Utils from "../utils"; import { Species } from "#enums/species"; export default class CandyBar extends Phaser.GameObjects.Container { @@ -58,8 +56,8 @@ export default class CandyBar extends Phaser.GameObjects.Container { const colorScheme = starterColors[starterSpeciesId]; - this.candyIcon.setTint(argbFromRgba(Utils.rgbHexToRgba(colorScheme[0]))); - this.candyOverlayIcon.setTint(argbFromRgba(Utils.rgbHexToRgba(colorScheme[1]))); + this.candyIcon.setTint(Number(`0x${colorScheme[0]}`)); + this.candyOverlayIcon.setTint(Number(`0x${colorScheme[1]}`)); this.countText.setText(`${(this.scene as BattleScene).gameData.starterData[starterSpeciesId].candyCount + count} (+${count.toString()})`); diff --git a/src/ui/fight-ui-handler.ts b/src/ui/fight-ui-handler.ts index ed520512443..eca40738e8a 100644 --- a/src/ui/fight-ui-handler.ts +++ b/src/ui/fight-ui-handler.ts @@ -10,6 +10,7 @@ import { MoveCategory } from "#app/data/move.js"; import i18next from "i18next"; import {Button} from "#enums/buttons"; import Pokemon, { PokemonMove } from "#app/field/pokemon.js"; +import BattleMessageUiHandler from "#app/ui/battle-message-ui-handler.js"; export default class FightUiHandler extends UiHandler { private movesContainer: Phaser.GameObjects.Container; @@ -23,6 +24,7 @@ export default class FightUiHandler extends UiHandler { private accuracyText: Phaser.GameObjects.Text; private cursorObj: Phaser.GameObjects.Image; private moveCategoryIcon: Phaser.GameObjects.Sprite; + private messageHandler: BattleMessageUiHandler; protected fieldIndex: integer = 0; protected cursor2: integer = 0; @@ -82,6 +84,7 @@ export default class FightUiHandler extends UiHandler { this.accuracyText.setOrigin(1, 0.5); this.accuracyText.setVisible(false); this.moveInfoContainer.add(this.accuracyText); + this.messageHandler = this.getUi().getMessageHandler(); } show(args: any[]): boolean { @@ -89,10 +92,10 @@ 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.messageHandler.bg.setVisible(false); + this.messageHandler.commandWindow.setVisible(false); + this.messageHandler.movesWindowContainer.setVisible(true); + this.setCursor(this.getCursor()); this.displayMoves(); @@ -210,14 +213,7 @@ export default class FightUiHandler extends UiHandler { }); } - this.typeIcon.setVisible(hasMove); - this.ppLabel.setVisible(hasMove); - this.ppText.setVisible(hasMove); - this.powerLabel.setVisible(hasMove); - this.powerText.setVisible(hasMove); - this.accuracyLabel.setVisible(hasMove); - this.accuracyText.setVisible(hasMove); - this.moveCategoryIcon.setVisible(hasMove); + this.moveInfoContainer.setVisible(hasMove); this.cursorObj.setPosition(13 + (cursor % 2 === 1 ? 100 : 0), -31 + (cursor >= 2 ? 15 : 0)); @@ -282,17 +278,9 @@ export default class FightUiHandler extends UiHandler { clear() { super.clear(); - const messageHandler = this.getUi().getMessageHandler(); this.clearMoves(); - this.typeIcon.setVisible(false); - this.ppLabel.setVisible(false); - this.ppText.setVisible(false); - this.powerLabel.setVisible(false); - this.powerText.setVisible(false); - this.accuracyLabel.setVisible(false); - this.accuracyText.setVisible(false); - this.moveCategoryIcon.setVisible(false); - messageHandler.bg.setVisible(true); + this.moveInfoContainer.setVisible(false); + this.messageHandler.bg.setVisible(true); this.eraseCursor(); } diff --git a/src/ui/menu-ui-handler.ts b/src/ui/menu-ui-handler.ts index 571a09f3b37..829b74fefe4 100644 --- a/src/ui/menu-ui-handler.ts +++ b/src/ui/menu-ui-handler.ts @@ -4,7 +4,7 @@ import { Mode } from "./ui"; import * as Utils from "../utils"; import { addWindow } from "./ui-theme"; import MessageUiHandler from "./message-ui-handler"; -import { OptionSelectConfig, OptionSelectItem } from "./abstact-option-select-ui-handler"; +import { OptionSelectConfig } from "./abstact-option-select-ui-handler"; import { Tutorial, handleTutorial } from "../tutorial"; import { updateUserInfo } from "../account"; import i18next from "i18next"; @@ -20,16 +20,10 @@ enum MenuOptions { EGG_LIST, EGG_GACHA, MANAGE_DATA, - COMMUNITY, SAVE_AND_QUIT, LOG_OUT } -let wikiUrl = "https://wiki.pokerogue.net/start"; -const discordUrl = "https://discord.gg/uWpTfdKG49"; -const githubUrl = "https://github.com/pagefaultgames/pokerogue"; -const redditUrl = "https://www.reddit.com/r/pokerogue"; - export default class MenuUiHandler extends MessageUiHandler { private menuContainer: Phaser.GameObjects.Container; private menuMessageBoxContainer: Phaser.GameObjects.Container; @@ -44,7 +38,6 @@ export default class MenuUiHandler extends MessageUiHandler { protected menuOptions: MenuOptions[]; protected manageDataConfig: OptionSelectConfig; - protected communityConfig: OptionSelectConfig; public bgmBar: BgmBar; @@ -60,11 +53,6 @@ export default class MenuUiHandler extends MessageUiHandler { setup() { const ui = this.getUi(); - // wiki url directs based on languges available on wiki - const lang = i18next.resolvedLanguage.substring(0,2); - if (["de", "fr", "ko", "zh"].includes(lang)) { - wikiUrl = `https://wiki.pokerogue.net/${lang}:start`; - } this.bgmBar = new BgmBar(this.scene); this.bgmBar.setup(); @@ -211,53 +199,6 @@ export default class MenuUiHandler extends MessageUiHandler { options: manageDataOptions }; - const communityOptions: OptionSelectItem[] = [ - { - label: "Wiki", - handler: () => { - window.open(wikiUrl, "_blank").focus(); - return true; - }, - keepOpen: true - }, - { - label: "Discord", - handler: () => { - window.open(discordUrl, "_blank").focus(); - return true; - }, - keepOpen: true - }, - { - label: "GitHub", - handler: () => { - window.open(githubUrl, "_blank").focus(); - return true; - }, - keepOpen: true - }, - { - label: "Reddit", - handler: () => { - window.open(redditUrl, "_blank").focus(); - return true; - }, - keepOpen: true - }, - { - label: i18next.t("menuUiHandler:cancel"), - handler: () => { - this.scene.ui.revertMode(); - return true; - } - } - ]; - - this.communityConfig = { - xOffset: 98, - options: communityOptions - }; - this.setCursor(0); this.menuContainer.setVisible(false); @@ -335,10 +276,6 @@ export default class MenuUiHandler extends MessageUiHandler { ui.setOverlayMode(Mode.MENU_OPTION_SELECT, this.manageDataConfig); success = true; break; - case MenuOptions.COMMUNITY: - ui.setOverlayMode(Mode.MENU_OPTION_SELECT, this.communityConfig); - success = true; - break; case MenuOptions.SAVE_AND_QUIT: if (this.scene.currentBattle) { success = true; diff --git a/src/ui/starter-select-ui-handler.ts b/src/ui/starter-select-ui-handler.ts index db014432b13..c1020d64fdd 100644 --- a/src/ui/starter-select-ui-handler.ts +++ b/src/ui/starter-select-ui-handler.ts @@ -1,7 +1,6 @@ import { BattleSceneEventType, CandyUpgradeNotificationChangedEvent } from "../events/battle-scene"; import { pokemonPrevolutions } from "#app/data/pokemon-evolutions"; import { Variant, getVariantTint, getVariantIcon } from "#app/data/variant"; -import { argbFromRgba } from "@material/material-color-utilities"; import i18next from "i18next"; import BBCodeText from "phaser3-rex-plugins/plugins/bbcodetext"; import BattleScene, { starterColors } from "../battle-scene"; @@ -293,6 +292,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { const textSettings = languageSettings[langSettingKey]; this.starterSelectContainer = this.scene.add.container(0, -this.scene.game.canvas.height / 6); + this.starterSelectContainer.setName("starter-select"); this.starterSelectContainer.setVisible(false); ui.add(this.starterSelectContainer); @@ -689,6 +689,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { const instructionTextSize = textSettings.instructionTextSize; this.instructionsContainer = this.scene.add.container(4, 156); + this.instructionsContainer.setName("instructions"); this.instructionsContainer.setVisible(true); this.starterSelectContainer.add(this.instructionsContainer); @@ -696,47 +697,51 @@ export default class StarterSelectUiHandler extends MessageUiHandler { // 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 = 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 = 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 = 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 = 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 = 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(); + this.instructionsContainer.add( + [ + this.shinyLabel, this.shinyIconElement, + this.formLabel, this.formIconElement, + this.genderLabel, this.genderIconElement, + this.abilityLabel, this.abilityIconElement, + this.natureLabel, this.natureIconElement, + this.variantLabel, this.variantIconElement, + ] + ); + + this.instructionsContainer.getAll("type", "Sprite").forEach((s: Phaser.GameObjects.Sprite) => { + s.setScale(0.675); + s.setOrigin(0); + }); + + this.instructionsContainer.each(i => i.setVisible(false)); this.starterSelectMessageBoxContainer = this.scene.add.container(0, this.scene.game.canvas.height / 6); this.starterSelectMessageBoxContainer.setVisible(false); @@ -1445,17 +1450,6 @@ export default class StarterSelectUiHandler extends MessageUiHandler { ui.setMode(Mode.STARTER_SELECT); this.scene.playSound("buy"); - // If the notification setting is set to 'On', update the candy upgrade display - // if (this.scene.candyUpgradeNotification === 2) { - // if (this.isUpgradeIconEnabled() ) { - // this.setUpgradeIcon(this.cursor); - // } - // if (this.isUpgradeAnimationEnabled()) { - // const genSpecies = this.genSpecies[this.lastSpecies.generation - 1]; - // this.setUpgradeAnimation(this.starterSelectGenIconContainers[this.lastSpecies.generation - 1].getAt(genSpecies.indexOf(this.lastSpecies)), this.lastSpecies, true); - // } - // } - return true; } return false; @@ -1753,8 +1747,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { updateInstructions(): void { this.instructionRowX = 0; this.instructionRowY = 0; - this.hideInstructions(); - this.instructionsContainer.removeAll(); + this.instructionsContainer.each(i => i.setVisible(false)); let gamepadType; if (this.scene.inputMethod === "gamepad") { gamepadType = this.scene.inputController.getConfig(this.scene.inputController.selectedDevice[Device.GAMEPAD]).padType; @@ -1782,6 +1775,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.updateButtonIcon(SettingKeyboard.Button_Cycle_Variant, gamepadType, this.variantIconElement, this.variantLabel); } } + this.instructionsContainer.setVisible(true); } getValueLimit(): integer { @@ -1865,8 +1859,8 @@ export default class StarterSelectUiHandler extends MessageUiHandler { } // Set the candy colors - this.candyUpgradeIcon[s].setTint(argbFromRgba(Utils.rgbHexToRgba(starterColors[speciesId][0]))); - this.candyUpgradeOverlayIcon[s].setTint(argbFromRgba(Utils.rgbHexToRgba(starterColors[speciesId][1]))); + this.candyUpgradeIcon[s].setTint(Number(`0x${starterColors[speciesId][0]}`)); + this.candyUpgradeOverlayIcon[s].setTint(Number(`0x${starterColors[speciesId][1]}`)); this.setUpgradeIcon(s); } else if (this.scene.candyUpgradeDisplay === 1) { @@ -2083,9 +2077,9 @@ export default class StarterSelectUiHandler extends MessageUiHandler { } else { this.pokemonCaughtHatchedContainer.setY(25); this.pokemonShinyIcon.setY(117); - this.pokemonCandyIcon.setTint(argbFromRgba(Utils.rgbHexToRgba(colorScheme[0]))); + this.pokemonCandyIcon.setTint(Number(`0x${colorScheme[0]}`)); this.pokemonCandyIcon.setVisible(true); - this.pokemonCandyOverlayIcon.setTint(argbFromRgba(Utils.rgbHexToRgba(colorScheme[1]))); + this.pokemonCandyOverlayIcon.setTint(Number(`0x${colorScheme[1]}`)); this.pokemonCandyOverlayIcon.setVisible(true); this.pokemonCandyDarknessOverlay.setVisible(true); this.pokemonCandyCountText.setText(`x${this.scene.gameData.starterData[species.speciesId].candyCount}`); @@ -2640,27 +2634,12 @@ export default class StarterSelectUiHandler extends MessageUiHandler { super.clearText(); } - hideInstructions(): void { - this.shinyIconElement.setVisible(false); - this.shinyLabel.setVisible(false); - this.formIconElement.setVisible(false); - this.formLabel.setVisible(false); - this.genderIconElement.setVisible(false); - this.genderLabel.setVisible(false); - this.abilityIconElement.setVisible(false); - this.abilityLabel.setVisible(false); - this.natureIconElement.setVisible(false); - this.natureLabel.setVisible(false); - this.variantIconElement.setVisible(false); - this.variantLabel.setVisible(false); - } - clear(): void { super.clear(); StarterPrefs.save(this.starterPreferences); this.cursor = -1; - this.hideInstructions(); + this.instructionsContainer.setVisible(false); this.starterSelectContainer.setVisible(false); this.blockInput = false; diff --git a/src/ui/summary-ui-handler.ts b/src/ui/summary-ui-handler.ts index 73edda0ba44..571bb84d58d 100644 --- a/src/ui/summary-ui-handler.ts +++ b/src/ui/summary-ui-handler.ts @@ -4,7 +4,6 @@ import UiHandler from "./ui-handler"; import * as Utils from "../utils"; import { PlayerPokemon } from "../field/pokemon"; import { getStarterValueFriendshipCap, speciesStarters } from "../data/pokemon-species"; -import { argbFromRgba } from "@material/material-color-utilities"; import { Type, getTypeRgb } from "../data/type"; import { TextStyle, addBBCodeTextObject, addTextObject, getBBCodeFrag } from "./text"; import Move, { MoveCategory } from "../data/move"; @@ -280,8 +279,8 @@ export default class SummaryUiHandler extends UiHandler { this.shinyOverlay.setVisible(this.pokemon.isShiny()); const colorScheme = starterColors[this.pokemon.species.getRootSpeciesId()]; - this.candyIcon.setTint(argbFromRgba(Utils.rgbHexToRgba(colorScheme[0]))); - this.candyOverlay.setTint(argbFromRgba(Utils.rgbHexToRgba(colorScheme[1]))); + this.candyIcon.setTint(Number(`0x${colorScheme[0]}`)); + this.candyOverlay.setTint(Number(`0x${colorScheme[1]}`)); this.numberText.setText(Utils.padInt(this.pokemon.species.speciesId, 4)); this.numberText.setColor(this.getTextColor(!this.pokemon.isShiny() ? TextStyle.SUMMARY : TextStyle.SUMMARY_GOLD)); diff --git a/src/ui/text.ts b/src/ui/text.ts index dd1ac57523a..e5a3407395e 100644 --- a/src/ui/text.ts +++ b/src/ui/text.ts @@ -39,7 +39,7 @@ export enum TextStyle { export function addTextObject(scene: Phaser.Scene, x: number, y: number, content: string, style: TextStyle, extraStyleOptions?: Phaser.Types.GameObjects.Text.TextStyle): Phaser.GameObjects.Text { const [ scale, styleOptions, shadowColor, shadowXpos, shadowYpos ] = getTextStyleOptions(style, (scene as BattleScene).uiTheme, extraStyleOptions); - const ret = scene.add.text(x, y, content, styleOptions); + const ret = new Phaser.GameObjects.Text(scene, x, y, content, styleOptions); ret.setScale(scale); ret.setShadow(shadowXpos, shadowYpos, shadowColor); if (!(styleOptions as Phaser.Types.GameObjects.Text.TextStyle).lineSpacing) { diff --git a/src/ui/title-ui-handler.ts b/src/ui/title-ui-handler.ts index 4036e0b9922..e4097da522f 100644 --- a/src/ui/title-ui-handler.ts +++ b/src/ui/title-ui-handler.ts @@ -3,16 +3,18 @@ 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 { 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 logo: Phaser.GameObjects.Image; private playerCountLabel: Phaser.GameObjects.Text; private splashMessage: string; private splashMessageText: Phaser.GameObjects.Text; private eventDisplay: TimedEventDisplay; + private iconContainer: TitleIcons; private titleStatsTimer: NodeJS.Timeout; @@ -30,22 +32,30 @@ export default class TitleUiHandler extends OptionSelectUiHandler { 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); + this.logo = this.scene.add.image((this.scene.scaledCanvas.width / 4) + 3, 8, "logo"); + this.logo.setName("logo"); + this.logo.setOrigin(0.5, 0); + this.titleContainer.add(this.logo); + + this.iconContainer = new TitleIcons(this.scene, 15, this.scene.scaledCanvas.height - 15); + this.iconContainer.setup(); + this.titleContainer.add(this.iconContainer); if (this.scene.eventManager.isEventActive()) { - this.eventDisplay = new TimedEventDisplay(this.scene, 0, 0, this.scene.eventManager.activeEvent()); + this.eventDisplay = new TimedEventDisplay(this.scene, 170, 66, 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" }); - this.playerCountLabel.setOrigin(1, 0); + this.playerCountLabel = addTextObject(this.scene, 8, this.scene.scaledCanvas.height - 132, i18next.t("menu:playersOnline", { count: 0 }), TextStyle.MESSAGE, { fontSize: "54px" }); + console.log(this.playerCountLabel); + this.playerCountLabel.setName("player-count"); + this.playerCountLabel.setOrigin(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 = addTextObject(this.scene, this.logo.x + 64, this.logo.y + this.logo.displayHeight - 8, "", TextStyle.MONEY, { fontSize: "54px" }); + this.splashMessageText.setName("splash-message"); + this.splashMessageText.setOrigin(0.5); this.splashMessageText.setAngle(-20); this.titleContainer.add(this.splashMessageText); @@ -63,11 +73,8 @@ export default class TitleUiHandler extends OptionSelectUiHandler { updateTitleStats(): void { Utils.apiFetch("game/titlestats") .then(request => request.json()) - .then(stats => { - this.playerCountLabel.setText(`${stats.playerCount} ${i18next.t("menu:playersOnline")}`); - if (this.splashMessage === getBattleCountSplashMessage()) { - this.splashMessageText.setText(getBattleCountSplashMessage().replace("{COUNT}", stats.battleCount.toLocaleString("en-US"))); - } + .then((stats: { playerCount: number, battleCount: number }) => { + this.playerCountLabel.setText(i18next.t("menu:playersOnline", { count: stats.playerCount })); }) .catch(err => { console.error("Failed to fetch title stats:\n", err); @@ -87,6 +94,8 @@ export default class TitleUiHandler extends OptionSelectUiHandler { this.eventDisplay.show(); } + this.iconContainer.setVisible(true); + this.updateTitleStats(); this.titleStatsTimer = setInterval(() => { @@ -109,7 +118,8 @@ export default class TitleUiHandler extends OptionSelectUiHandler { const ui = this.getUi(); - this.eventDisplay?.clear(); + this.eventDisplay?.setVisible(false); + this.iconContainer?.setVisible(false); clearInterval(this.titleStatsTimer); this.titleStatsTimer = null; @@ -122,3 +132,73 @@ export default class TitleUiHandler extends OptionSelectUiHandler { }); } } + +class TitleIcons extends Phaser.GameObjects.Container { + private icons: Array = []; + private wiki: Icon; + private discord: Icon; + private github: Icon; + private reddit: Icon; + private readonly ICON_WIDTH = 84; + private readonly ICON_HEIGHT = 84; + + constructor(scene: BattleScene, x: number, y: number) { + super(scene, x, y); + } + + setup() { + // urls + let wikiUrl = "https://wiki.pokerogue.net/start"; + const discordUrl = "https://discord.gg/uWpTfdKG49"; + const githubUrl = "https://github.com/pagefaultgames/pokerogue"; + const redditUrl = "https://www.reddit.com/r/pokerogue"; + + + // wiki url directs based on languges available on wiki + const lang = i18next.resolvedLanguage.substring(0,2); + if (["de", "fr", "ko", "zh"].includes(lang)) { + wikiUrl = `https://wiki.pokerogue.net/${lang}:start`; + } + this.wiki = new Icon(this.scene, 0, 0, "wiki", wikiUrl); + this.icons.push(this.wiki); + + this.discord = new Icon(this.scene, 0, 0, "discord", discordUrl); + this.icons.push(this.discord); + + this.github = new Icon(this.scene, 0, 0, "github", githubUrl); + this.icons.push(this.github); + + this.reddit = new Icon(this.scene, 0, 0, "reddit", redditUrl); + this.icons.push(this.reddit); + + Phaser.Actions.IncX(this.icons, 0, this.ICON_WIDTH + 30); + + this.add(this.icons); + this.setScale(1/6); + } + + clear() { + this.icons.forEach((icon: Icon) => icon.destroy()); + } +} + +class Icon extends Phaser.GameObjects.Sprite { + private readonly DEFAULT_ALPHA = 0.5; + + constructor(scene, x, y, texture, link) { + super(scene, x, y, texture); + this.setName(texture); + this.setInteractive(); + this.setAlpha(this.DEFAULT_ALPHA); + this.on(Phaser.Input.Events.GAMEOBJECT_POINTER_OVER, () => { + this.setAlpha(1); + }); + this.on(Phaser.Input.Events.GAMEOBJECT_POINTER_OUT, () => { + this.setAlpha(this.DEFAULT_ALPHA); + }); + this.on(Phaser.Input.Events.GAMEOBJECT_POINTER_DOWN, () => { + window.open(link, "_blank").focus(); + }); + } + +} diff --git a/src/ui/ui.ts b/src/ui/ui.ts index ce834a83645..e4f0df4b766 100644 --- a/src/ui/ui.ts +++ b/src/ui/ui.ts @@ -136,8 +136,6 @@ export default class UI extends Phaser.GameObjects.Container { private tooltipTitle: Phaser.GameObjects.Text; private tooltipContent: Phaser.GameObjects.Text; - private overlayActive: boolean; - constructor(scene: BattleScene) { super(scene, 0, scene.game.canvas.height / 6); @@ -240,7 +238,7 @@ export default class UI extends Phaser.GameObjects.Container { } processInfoButton(pressed: boolean) { - if (this.overlayActive) { + if (this.overlay.visible) { return false; } @@ -254,7 +252,7 @@ export default class UI extends Phaser.GameObjects.Container { } processInput(button: Button): boolean { - if (this.overlayActive) { + if (this.overlay.visible) { return false; } @@ -400,10 +398,9 @@ export default class UI extends Phaser.GameObjects.Container { fadeOut(duration: integer): Promise { return new Promise(resolve => { - if (this.overlayActive) { + if (this.overlay.visible) { return resolve(); } - this.overlayActive = true; this.overlay.setAlpha(0); this.overlay.setVisible(true); this.scene.tweens.add({ @@ -418,7 +415,7 @@ export default class UI extends Phaser.GameObjects.Container { fadeIn(duration: integer): Promise { return new Promise(resolve => { - if (!this.overlayActive) { + if (!this.overlay.visible) { return resolve(); } this.scene.tweens.add({ @@ -431,7 +428,6 @@ export default class UI extends Phaser.GameObjects.Container { resolve(); } }); - this.overlayActive = false; }); } @@ -458,9 +454,11 @@ export default class UI extends Phaser.GameObjects.Container { } resolve(); }; - if (((!chainMode && ((transitionModes.indexOf(this.mode) > -1 || transitionModes.indexOf(mode) > -1) - && (noTransitionModes.indexOf(this.mode) === -1 && noTransitionModes.indexOf(mode) === -1))) - || (chainMode && noTransitionModes.indexOf(mode) === -1))) { + // isn't chain mode, is a transition mode and isnt a no transition mode + const condition1 = (!chainMode && ((transitionModes.indexOf(this.mode) > -1 || transitionModes.indexOf(mode) > -1) && (noTransitionModes.indexOf(this.mode) === -1 && noTransitionModes.indexOf(mode) === -1))); + // is chain mode and isnt a no transition mode + const condition2 = chainMode && noTransitionModes.indexOf(mode) === -1; + if (condition1 || condition2) { this.fadeOut(250).then(() => { this.scene.time.delayedCall(100, () => { doSetMode(); @@ -477,6 +475,15 @@ export default class UI extends Phaser.GameObjects.Container { return this.mode; } + /** + * Set Mode + * @param mode UI Mode to set + * @param args Configuration for that mode + * Calls `setModeInternal` with the following settings: + * - clear: true + * - forceTransition: false + * - chainMode: false + */ setMode(mode: Mode, ...args: any[]): Promise { return this.setModeInternal(mode, true, false, false, args); }