pokerogue/src/ui/ui.ts

536 lines
17 KiB
TypeScript
Raw Normal View History

import {default as BattleScene} from "../battle-scene";
import UiHandler from "./ui-handler";
import BattleMessageUiHandler from "./battle-message-ui-handler";
import CommandUiHandler from "./command-ui-handler";
import PartyUiHandler from "./party-ui-handler";
import FightUiHandler from "./fight-ui-handler";
import MessageUiHandler from "./message-ui-handler";
import ConfirmUiHandler from "./confirm-ui-handler";
import ModifierSelectUiHandler from "./modifier-select-ui-handler";
import BallUiHandler from "./ball-ui-handler";
import SummaryUiHandler from "./summary-ui-handler";
import StarterSelectUiHandler from "./starter-select-ui-handler";
import EvolutionSceneHandler from "./evolution-scene-handler";
import TargetSelectUiHandler from "./target-select-ui-handler";
import SettingsUiHandler from "./settings/settings-ui-handler";
import SettingsGamepadUiHandler from "./settings/settings-gamepad-ui-handler";
Add Challenges (#1459) * Initial challenge framework * Add type localisation * Change how challenges are tracked Also fixes the difficulty total text * MVP Renames challenge types, temporarily hides difficulty, and implements challenge saving. * Attempt to fix one legal pokemon in a double battle * Make monotype ignore type changing effects * Make isOfType correctly detect normal types * Try to fix double battles again * Make challenge function more like classic * Add helper function for fainted or not allowed * Add framework for fresh start challenge and improve comments * Try to fix evolution issues * Make form changing items only usable from rewards screen * Update localisation * Additional localisation change * Add achievements for completing challenges * Fix initialisation bug with challenge achievements * Add support for gamemode specific fixed battles Also make monogen challenges face the e4 of their generation * Add better support for mobile in challenges * Localise illegal evolution/form change message * Update achievement names * Make alternate forms count for monogen * Update monotype achievement icons * Add more comments * Improve comments * Fix mid battle form changes * Reorder mode list * Remove currently unused localisation entry * Add type overrides for monotype challenges Meloetta always counts for psychic and castform always counts for normal * Change how form changes are handled Now attempts a switch at the start of each turn instead of immediately * Add start button to challenge select screen * Make starter select back out to challenge screen if using challenges * Fix daily runs * Update tests to new game mode logic
2024-06-08 06:07:23 +01:00
import GameChallengesUiHandler from "./challenges-select-ui-handler";
import { TextStyle, addTextObject } from "./text";
import AchvBar from "./achv-bar";
import MenuUiHandler from "./menu-ui-handler";
import AchvsUiHandler from "./achvs-ui-handler";
import OptionSelectUiHandler from "./settings/option-select-ui-handler";
import EggHatchSceneHandler from "./egg-hatch-scene-handler";
import EggListUiHandler from "./egg-list-ui-handler";
import EggGachaUiHandler from "./egg-gacha-ui-handler";
import VouchersUiHandler from "./vouchers-ui-handler";
import {addWindow} from "./ui-theme";
import LoginFormUiHandler from "./login-form-ui-handler";
import RegistrationFormUiHandler from "./registration-form-ui-handler";
import LoadingModalUiHandler from "./loading-modal-ui-handler";
2023-12-30 23:41:25 +00:00
import * as Utils from "../utils";
import GameStatsUiHandler from "./game-stats-ui-handler";
import AwaitableUiHandler from "./awaitable-ui-handler";
import SaveSlotSelectUiHandler from "./save-slot-select-ui-handler";
import TitleUiHandler from "./title-ui-handler";
import SavingIconHandler from "./saving-icon-handler";
import UnavailableModalUiHandler from "./unavailable-modal-ui-handler";
import OutdatedModalUiHandler from "./outdated-modal-ui-handler";
import SessionReloadModalUiHandler from "./session-reload-modal-ui-handler";
import {Button} from "#enums/buttons";
import i18next, {ParseKeys} from "i18next";
import GamepadBindingUiHandler from "./settings/gamepad-binding-ui-handler";
import SettingsKeyboardUiHandler from "#app/ui/settings/settings-keyboard-ui-handler";
import KeyboardBindingUiHandler from "#app/ui/settings/keyboard-binding-ui-handler";
import SettingsDisplayUiHandler from "./settings/settings-display-ui-handler";
import SettingsAudioUiHandler from "./settings/settings-audio-ui-handler";
import { PlayerGender } from "#enums/player-gender";
[Enhancement] Added a bgmBar to show the name of the track once music is played (#2457) * Added a bgmBar to show the name of the track once music is played * Even more close to ability bar * It now shows. And also shows already for a couple of them a readable name * Now the queue actually works * Create locales for bgmName (bgm-bar ui) + Most of the music has only Japanese and English names But there are a number of tracks with official translations following OST commercialization * Add i18n and use it to retrieve OST names (avoids a giga switch case) + A fallback key is implemented in the case of adding tracks not referenced in the translation files, its value being just the name of the bgm itself * FormatText is now in Utils and not arena-flyout BGM Names for non-localized music will be formatted to have capitalized letters and no _ * It is now a setting. It can be even changed mid fight * Update src/ui/ability-bar.ts * Apply suggestions from code review Co-authored-by: Lugiad' <adrien.grivel@hotmail.fr> * Update src/locales/de/bgm-name.ts * Apply suggestions from code review Co-authored-by: sodam <66295123+sodaMelon@users.noreply.github.com> * Added the rest of the music names * Changed PMD EoS to PMD ETH in german (Pokemon Mystery Dungeon Erkundungsteam Himmel) * Due to feedback it is now "PMD ET-Himmel" * Corrected the encounter theme names (and some missed trainer class names) * Background is now a nicneslice. And it is at the top of the screen and above everything else * The bar now scales with the text. * Revert override * Update src/locales/fr/bgm-name.ts Co-authored-by: Lugiad' <adrien.grivel@hotmail.fr> * It now only appears when V is pressed (in all but starter select) * Cleared the cod eup * Update src/locales/zh_CN/bgm-name.ts Co-authored-by: Yonmaru40 <47717431+40chyan@users.noreply.github.com> * Update src/locales/zh_CN/settings.ts Co-authored-by: Yonmaru40 <47717431+40chyan@users.noreply.github.com> * Update src/locales/ko/bgm-name.ts Co-authored-by: sodam <66295123+sodaMelon@users.noreply.github.com> * The bgmBar now appears in the pause menu instead. * Should react better on settings change * To be safe this required a reload now * Update src/locales/fr/bgm-name.ts Co-authored-by: Lugiad' <adrien.grivel@hotmail.fr> * Update src/locales/fr/bgm-name.ts Co-authored-by: Lugiad' <adrien.grivel@hotmail.fr> * Write out pokemon mystery dungeon names in german * Update src/locales/es/bgm-name.ts Co-authored-by: GoldTra <162721984+GoldTra@users.noreply.github.com> * Update src/locales/zh_CN/bgm-name.ts Co-authored-by: Yonmaru40 <47717431+40chyan@users.noreply.github.com> * Update src/battle-scene.ts --------- Co-authored-by: Dakurei <maxime.palanchini@gmail.com> Co-authored-by: Lugiad' <adrien.grivel@hotmail.fr> Co-authored-by: sodam <66295123+sodaMelon@users.noreply.github.com> Co-authored-by: Yonmaru40 <47717431+40chyan@users.noreply.github.com> Co-authored-by: GoldTra <162721984+GoldTra@users.noreply.github.com>
2024-06-24 16:31:38 +01:00
import BgmBar from "#app/ui/bgm-bar";
2023-03-28 19:54:52 +01:00
export enum Mode {
MESSAGE,
2024-03-21 17:12:05 +00:00
TITLE,
2023-03-28 19:54:52 +01:00
COMMAND,
FIGHT,
2023-04-02 03:59:07 +01:00
BALL,
TARGET_SELECT,
2023-03-28 19:54:52 +01:00
MODIFIER_SELECT,
SAVE_SLOT,
PARTY,
2023-04-10 00:15:21 +01:00
SUMMARY,
2023-04-10 18:54:06 +01:00
STARTER_SELECT,
2023-04-13 00:09:15 +01:00
EVOLUTION_SCENE,
EGG_HATCH_SCENE,
CONFIRM,
2023-11-14 03:29:03 +00:00
OPTION_SELECT,
MENU,
MENU_OPTION_SELECT,
SETTINGS,
SETTINGS_DISPLAY,
SETTINGS_AUDIO,
SETTINGS_GAMEPAD,
GAMEPAD_BINDING,
SETTINGS_KEYBOARD,
KEYBOARD_BINDING,
ACHIEVEMENTS,
GAME_STATS,
VOUCHERS,
EGG_LIST,
2023-12-30 23:41:25 +00:00
EGG_GACHA,
LOGIN_FORM,
REGISTRATION_FORM,
2024-04-10 06:32:49 +01:00
LOADING,
SESSION_RELOAD,
2024-04-15 15:09:51 +01:00
UNAVAILABLE,
Add Challenges (#1459) * Initial challenge framework * Add type localisation * Change how challenges are tracked Also fixes the difficulty total text * MVP Renames challenge types, temporarily hides difficulty, and implements challenge saving. * Attempt to fix one legal pokemon in a double battle * Make monotype ignore type changing effects * Make isOfType correctly detect normal types * Try to fix double battles again * Make challenge function more like classic * Add helper function for fainted or not allowed * Add framework for fresh start challenge and improve comments * Try to fix evolution issues * Make form changing items only usable from rewards screen * Update localisation * Additional localisation change * Add achievements for completing challenges * Fix initialisation bug with challenge achievements * Add support for gamemode specific fixed battles Also make monogen challenges face the e4 of their generation * Add better support for mobile in challenges * Localise illegal evolution/form change message * Update achievement names * Make alternate forms count for monogen * Update monotype achievement icons * Add more comments * Improve comments * Fix mid battle form changes * Reorder mode list * Remove currently unused localisation entry * Add type overrides for monotype challenges Meloetta always counts for psychic and castform always counts for normal * Change how form changes are handled Now attempts a switch at the start of each turn instead of immediately * Add start button to challenge select screen * Make starter select back out to challenge screen if using challenges * Fix daily runs * Update tests to new game mode logic
2024-06-08 06:07:23 +01:00
OUTDATED,
CHALLENGE_SELECT
}
2023-03-28 19:54:52 +01:00
const transitionModes = [
Mode.SAVE_SLOT,
Mode.PARTY,
2023-04-10 00:15:21 +01:00
Mode.SUMMARY,
Mode.STARTER_SELECT,
Mode.EVOLUTION_SCENE,
Mode.EGG_HATCH_SCENE,
Mode.EGG_LIST,
Add Challenges (#1459) * Initial challenge framework * Add type localisation * Change how challenges are tracked Also fixes the difficulty total text * MVP Renames challenge types, temporarily hides difficulty, and implements challenge saving. * Attempt to fix one legal pokemon in a double battle * Make monotype ignore type changing effects * Make isOfType correctly detect normal types * Try to fix double battles again * Make challenge function more like classic * Add helper function for fainted or not allowed * Add framework for fresh start challenge and improve comments * Try to fix evolution issues * Make form changing items only usable from rewards screen * Update localisation * Additional localisation change * Add achievements for completing challenges * Fix initialisation bug with challenge achievements * Add support for gamemode specific fixed battles Also make monogen challenges face the e4 of their generation * Add better support for mobile in challenges * Localise illegal evolution/form change message * Update achievement names * Make alternate forms count for monogen * Update monotype achievement icons * Add more comments * Improve comments * Fix mid battle form changes * Reorder mode list * Remove currently unused localisation entry * Add type overrides for monotype challenges Meloetta always counts for psychic and castform always counts for normal * Change how form changes are handled Now attempts a switch at the start of each turn instead of immediately * Add start button to challenge select screen * Make starter select back out to challenge screen if using challenges * Fix daily runs * Update tests to new game mode logic
2024-06-08 06:07:23 +01:00
Mode.EGG_GACHA,
Mode.CHALLENGE_SELECT
2023-04-10 18:54:06 +01:00
];
const noTransitionModes = [
2024-03-21 17:12:05 +00:00
Mode.TITLE,
Mode.CONFIRM,
2023-11-14 03:29:03 +00:00
Mode.OPTION_SELECT,
Mode.MENU,
Mode.MENU_OPTION_SELECT,
Mode.GAMEPAD_BINDING,
Mode.KEYBOARD_BINDING,
Mode.SETTINGS,
Mode.SETTINGS_AUDIO,
Mode.SETTINGS_DISPLAY,
Mode.SETTINGS_GAMEPAD,
Mode.SETTINGS_KEYBOARD,
Mode.ACHIEVEMENTS,
Mode.GAME_STATS,
2023-12-30 23:41:25 +00:00
Mode.VOUCHERS,
Mode.LOGIN_FORM,
Mode.REGISTRATION_FORM,
2024-04-10 06:32:49 +01:00
Mode.LOADING,
Mode.SESSION_RELOAD,
2024-04-15 15:09:51 +01:00
Mode.UNAVAILABLE,
Mode.OUTDATED
];
2023-03-28 19:54:52 +01:00
export default class UI extends Phaser.GameObjects.Container {
private mode: Mode;
private modeChain: Mode[];
public handlers: UiHandler[];
private overlay: Phaser.GameObjects.Rectangle;
public achvBar: AchvBar;
[Enhancement] Added a bgmBar to show the name of the track once music is played (#2457) * Added a bgmBar to show the name of the track once music is played * Even more close to ability bar * It now shows. And also shows already for a couple of them a readable name * Now the queue actually works * Create locales for bgmName (bgm-bar ui) + Most of the music has only Japanese and English names But there are a number of tracks with official translations following OST commercialization * Add i18n and use it to retrieve OST names (avoids a giga switch case) + A fallback key is implemented in the case of adding tracks not referenced in the translation files, its value being just the name of the bgm itself * FormatText is now in Utils and not arena-flyout BGM Names for non-localized music will be formatted to have capitalized letters and no _ * It is now a setting. It can be even changed mid fight * Update src/ui/ability-bar.ts * Apply suggestions from code review Co-authored-by: Lugiad' <adrien.grivel@hotmail.fr> * Update src/locales/de/bgm-name.ts * Apply suggestions from code review Co-authored-by: sodam <66295123+sodaMelon@users.noreply.github.com> * Added the rest of the music names * Changed PMD EoS to PMD ETH in german (Pokemon Mystery Dungeon Erkundungsteam Himmel) * Due to feedback it is now "PMD ET-Himmel" * Corrected the encounter theme names (and some missed trainer class names) * Background is now a nicneslice. And it is at the top of the screen and above everything else * The bar now scales with the text. * Revert override * Update src/locales/fr/bgm-name.ts Co-authored-by: Lugiad' <adrien.grivel@hotmail.fr> * It now only appears when V is pressed (in all but starter select) * Cleared the cod eup * Update src/locales/zh_CN/bgm-name.ts Co-authored-by: Yonmaru40 <47717431+40chyan@users.noreply.github.com> * Update src/locales/zh_CN/settings.ts Co-authored-by: Yonmaru40 <47717431+40chyan@users.noreply.github.com> * Update src/locales/ko/bgm-name.ts Co-authored-by: sodam <66295123+sodaMelon@users.noreply.github.com> * The bgmBar now appears in the pause menu instead. * Should react better on settings change * To be safe this required a reload now * Update src/locales/fr/bgm-name.ts Co-authored-by: Lugiad' <adrien.grivel@hotmail.fr> * Update src/locales/fr/bgm-name.ts Co-authored-by: Lugiad' <adrien.grivel@hotmail.fr> * Write out pokemon mystery dungeon names in german * Update src/locales/es/bgm-name.ts Co-authored-by: GoldTra <162721984+GoldTra@users.noreply.github.com> * Update src/locales/zh_CN/bgm-name.ts Co-authored-by: Yonmaru40 <47717431+40chyan@users.noreply.github.com> * Update src/battle-scene.ts --------- Co-authored-by: Dakurei <maxime.palanchini@gmail.com> Co-authored-by: Lugiad' <adrien.grivel@hotmail.fr> Co-authored-by: sodam <66295123+sodaMelon@users.noreply.github.com> Co-authored-by: Yonmaru40 <47717431+40chyan@users.noreply.github.com> Co-authored-by: GoldTra <162721984+GoldTra@users.noreply.github.com>
2024-06-24 16:31:38 +01:00
public bgmBar: BgmBar;
2024-04-04 15:16:29 +01:00
public savingIcon: SavingIconHandler;
2023-11-02 04:55:20 +00:00
private tooltipContainer: Phaser.GameObjects.Container;
private tooltipBg: Phaser.GameObjects.NineSlice;
private tooltipTitle: Phaser.GameObjects.Text;
private tooltipContent: Phaser.GameObjects.Text;
2024-05-24 00:45:04 +01:00
private overlayActive: boolean;
2023-03-28 19:54:52 +01:00
constructor(scene: BattleScene) {
super(scene, 0, scene.game.canvas.height / 6);
this.mode = Mode.MESSAGE;
this.modeChain = [];
2023-03-28 19:54:52 +01:00
this.handlers = [
new BattleMessageUiHandler(scene),
2024-03-21 17:12:05 +00:00
new TitleUiHandler(scene),
2023-03-28 19:54:52 +01:00
new CommandUiHandler(scene),
new FightUiHandler(scene),
2023-04-02 03:59:07 +01:00
new BallUiHandler(scene),
new TargetSelectUiHandler(scene),
2023-03-28 19:54:52 +01:00
new ModifierSelectUiHandler(scene),
new SaveSlotSelectUiHandler(scene),
new PartyUiHandler(scene),
2023-04-10 00:15:21 +01:00
new SummaryUiHandler(scene),
2023-04-10 18:54:06 +01:00
new StarterSelectUiHandler(scene),
2023-04-13 00:09:15 +01:00
new EvolutionSceneHandler(scene),
new EggHatchSceneHandler(scene),
new ConfirmUiHandler(scene),
2023-11-14 03:29:03 +00:00
new OptionSelectUiHandler(scene),
new MenuUiHandler(scene),
new OptionSelectUiHandler(scene, Mode.MENU_OPTION_SELECT),
// settings
new SettingsUiHandler(scene),
new SettingsDisplayUiHandler(scene),
new SettingsAudioUiHandler(scene),
new SettingsGamepadUiHandler(scene),
new GamepadBindingUiHandler(scene),
new SettingsKeyboardUiHandler(scene),
new KeyboardBindingUiHandler(scene),
new AchvsUiHandler(scene),
new GameStatsUiHandler(scene),
new VouchersUiHandler(scene),
new EggListUiHandler(scene),
2023-12-30 23:41:25 +00:00
new EggGachaUiHandler(scene),
new LoginFormUiHandler(scene),
new RegistrationFormUiHandler(scene),
2024-04-10 06:32:49 +01:00
new LoadingModalUiHandler(scene),
new SessionReloadModalUiHandler(scene),
2024-04-15 15:09:51 +01:00
new UnavailableModalUiHandler(scene),
Add Challenges (#1459) * Initial challenge framework * Add type localisation * Change how challenges are tracked Also fixes the difficulty total text * MVP Renames challenge types, temporarily hides difficulty, and implements challenge saving. * Attempt to fix one legal pokemon in a double battle * Make monotype ignore type changing effects * Make isOfType correctly detect normal types * Try to fix double battles again * Make challenge function more like classic * Add helper function for fainted or not allowed * Add framework for fresh start challenge and improve comments * Try to fix evolution issues * Make form changing items only usable from rewards screen * Update localisation * Additional localisation change * Add achievements for completing challenges * Fix initialisation bug with challenge achievements * Add support for gamemode specific fixed battles Also make monogen challenges face the e4 of their generation * Add better support for mobile in challenges * Localise illegal evolution/form change message * Update achievement names * Make alternate forms count for monogen * Update monotype achievement icons * Add more comments * Improve comments * Fix mid battle form changes * Reorder mode list * Remove currently unused localisation entry * Add type overrides for monotype challenges Meloetta always counts for psychic and castform always counts for normal * Change how form changes are handled Now attempts a switch at the start of each turn instead of immediately * Add start button to challenge select screen * Make starter select back out to challenge screen if using challenges * Fix daily runs * Update tests to new game mode logic
2024-06-08 06:07:23 +01:00
new OutdatedModalUiHandler(scene),
new GameChallengesUiHandler(scene)
2023-03-28 19:54:52 +01:00
];
}
2023-04-07 05:17:55 +01:00
setup(): void {
this.setName(`ui-${Mode[this.mode]}`);
for (const handler of this.handlers) {
2023-03-28 19:54:52 +01:00
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);
2023-11-02 04:55:20 +00:00
this.setupTooltip();
this.achvBar = new AchvBar(this.scene as BattleScene);
this.achvBar.setup();
2024-05-24 00:45:04 +01:00
(this.scene as BattleScene).uiContainer.add(this.achvBar);
2024-04-04 15:16:29 +01:00
this.savingIcon = new SavingIconHandler(this.scene as BattleScene);
this.savingIcon.setup();
(this.scene as BattleScene).uiContainer.add(this.savingIcon);
2023-11-02 04:55:20 +00:00
}
private setupTooltip() {
this.tooltipContainer = this.scene.add.container(0, 0);
this.tooltipContainer.setName("tooltip");
2023-11-02 04:55:20 +00:00
this.tooltipContainer.setVisible(false);
2023-12-30 23:41:25 +00:00
this.tooltipBg = addWindow(this.scene as BattleScene, 0, 0, 128, 31);
this.tooltipBg.setName("window-tooltip-bg");
2023-11-02 04:55:20 +00:00
this.tooltipBg.setOrigin(0, 0);
this.tooltipTitle = addTextObject(this.scene, 64, 4, "", TextStyle.TOOLTIP_TITLE);
this.tooltipTitle.setName("text-tooltip-title");
2023-11-02 04:55:20 +00:00
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);
2023-11-02 04:55:20 +00:00
this.tooltipContainer.add(this.tooltipBg);
this.tooltipContainer.add(this.tooltipTitle);
this.tooltipContainer.add(this.tooltipContent);
(this.scene as BattleScene).uiContainer.add(this.tooltipContainer);
2023-03-28 19:54:52 +01:00
}
2023-04-07 05:17:55 +01:00
getHandler(): UiHandler {
2023-03-28 19:54:52 +01:00
return this.handlers[this.mode];
}
2023-04-07 05:17:55 +01:00
getMessageHandler(): BattleMessageUiHandler {
2023-03-28 19:54:52 +01:00
return this.handlers[Mode.MESSAGE] as BattleMessageUiHandler;
}
processInfoButton(pressed: boolean) {
if (this.overlayActive) {
return false;
}
const battleScene = this.scene as BattleScene;
if ([Mode.CONFIRM, Mode.COMMAND, Mode.FIGHT, Mode.MESSAGE].includes(this.mode)) {
battleScene?.processInfoButton(pressed);
return true;
}
battleScene?.processInfoButton(false);
return true;
}
processInput(button: Button): boolean {
if (this.overlayActive) {
return false;
}
2023-04-07 05:17:55 +01:00
2024-02-14 15:44:55 +00:00
const handler = this.getHandler();
if (handler instanceof AwaitableUiHandler && handler.tutorialActive) {
2024-02-14 15:44:55 +00:00
return handler.processTutorialInput(button);
}
2024-02-14 15:44:55 +00:00
return handler.processInput(button);
2023-03-28 19:54:52 +01:00
}
2023-04-10 18:54:06 +01:00
showText(text: string, delay?: integer, callback?: Function, callbackDelay?: integer, prompt?: boolean, promptDelay?: integer): void {
if (prompt && text.indexOf("$") > -1) {
2024-02-13 23:42:11 +00:00
const messagePages = text.split(/\$/g).map(m => m.trim());
let showMessageAndCallback = () => callback();
for (let p = messagePages.length - 1; p >= 0; p--) {
const originalFunc = showMessageAndCallback;
showMessageAndCallback = () => this.showText(messagePages[p], null, originalFunc, null, true);
}
showMessageAndCallback();
} else {
const handler = this.getHandler();
if (handler instanceof MessageUiHandler) {
2024-02-13 23:42:11 +00:00
(handler as MessageUiHandler).showText(text, delay, callback, callbackDelay, prompt, promptDelay);
} else {
2024-02-13 23:42:11 +00:00
this.getMessageHandler().showText(text, delay, callback, callbackDelay, prompt, promptDelay);
}
2024-02-13 23:42:11 +00:00
}
2023-03-28 19:54:52 +01:00
}
2024-02-13 23:42:11 +00:00
showDialogue(text: string, name: string, delay: integer = 0, callback: Function, callbackDelay?: integer, promptDelay?: integer): void {
// First get the gender of the player (default male) (also used if UNSET)
let playerGenderPrefix = "PGM";
if ((this.scene as BattleScene).gameData.gender === PlayerGender.FEMALE) {
playerGenderPrefix = "PGF";
}
// Add the prefix to the text
const localizationKey = playerGenderPrefix + text;
// Get localized dialogue (if available)
let hasi18n = false;
if (i18next.exists(localizationKey as ParseKeys) ) {
text = i18next.t(localizationKey as ParseKeys);
hasi18n = true;
// Skip dialogue if the player has enabled the option and the dialogue has been already seen
if ((this.scene as BattleScene).skipSeenDialogues && (this.scene as BattleScene).gameData.getSeenDialogues()[localizationKey] === true) {
console.log(`Dialogue ${localizationKey} skipped`);
callback();
return;
}
}
let showMessageAndCallback = () => {
hasi18n && (this.scene as BattleScene).gameData.saveSeenDialogue(localizationKey);
callback();
};
if (text.indexOf("$") > -1) {
const messagePages = text.split(/\$/g).map(m => m.trim());
for (let p = messagePages.length - 1; p >= 0; p--) {
const originalFunc = showMessageAndCallback;
2024-02-13 23:42:11 +00:00
showMessageAndCallback = () => this.showDialogue(messagePages[p], name, null, originalFunc);
}
showMessageAndCallback();
} else {
const handler = this.getHandler();
if (handler instanceof MessageUiHandler) {
(handler as MessageUiHandler).showDialogue(text, name, delay, showMessageAndCallback, callbackDelay, true, promptDelay);
} else {
this.getMessageHandler().showDialogue(text, name, delay, showMessageAndCallback, callbackDelay, true, promptDelay);
}
}
}
shouldSkipDialogue(text): boolean {
let playerGenderPrefix = "PGM";
if ((this.scene as BattleScene).gameData.gender === PlayerGender.FEMALE) {
playerGenderPrefix = "PGF";
}
const key = playerGenderPrefix + text;
if (i18next.exists(key as ParseKeys) ) {
if ((this.scene as BattleScene).skipSeenDialogues && (this.scene as BattleScene).gameData.getSeenDialogues()[key] === true) {
return true;
}
}
return false;
}
2023-11-02 04:55:20 +00:00
showTooltip(title: string, content: string, overlap?: boolean): void {
this.tooltipContainer.setVisible(true);
this.tooltipTitle.setText(title || "");
2023-11-02 04:55:20 +00:00
const wrappedContent = this.tooltipContent.runWordWrap(content);
this.tooltipContent.setText(wrappedContent);
this.tooltipContent.y = title ? 16 : 4;
this.tooltipBg.width = Math.min(Math.max(this.tooltipTitle.displayWidth, this.tooltipContent.displayWidth) + 12, 684);
this.tooltipBg.height = (title ? 31 : 19) + 10.5 * (wrappedContent.split("\n").length - 1);
if (overlap) {
(this.scene as BattleScene).uiContainer.moveAbove(this.tooltipContainer, this);
} else {
(this.scene as BattleScene).uiContainer.moveBelow(this.tooltipContainer, this);
}
2023-11-02 04:55:20 +00:00
}
hideTooltip(): void {
this.tooltipContainer.setVisible(false);
this.tooltipTitle.clearTint();
}
update(): void {
if (this.tooltipContainer.visible) {
const reverse = this.scene.game.input.mousePointer.x >= this.scene.game.canvas.width - this.tooltipBg.width * 6 - 12;
this.tooltipContainer.setPosition(!reverse ? this.scene.game.input.mousePointer.x / 6 + 2 : this.scene.game.input.mousePointer.x / 6 - this.tooltipBg.width - 2, this.scene.game.input.mousePointer.y / 6 + 2);
}
}
2023-04-07 05:17:55 +01:00
clearText(): void {
2023-03-28 19:54:52 +01:00
const handler = this.getHandler();
if (handler instanceof MessageUiHandler) {
2023-03-28 19:54:52 +01:00
(handler as MessageUiHandler).clearText();
} else {
2023-03-28 19:54:52 +01:00
this.getMessageHandler().clearText();
}
2023-03-28 19:54:52 +01:00
}
setCursor(cursor: integer): boolean {
const changed = this.getHandler().setCursor(cursor);
if (changed) {
2023-03-28 19:54:52 +01:00
this.playSelect();
}
2023-03-28 19:54:52 +01:00
return changed;
}
2023-04-07 05:17:55 +01:00
playSelect(): void {
(this.scene as BattleScene).playSound("select");
2023-03-28 19:54:52 +01:00
}
2023-04-07 05:17:55 +01:00
playError(): void {
(this.scene as BattleScene).playSound("error");
2023-03-28 19:54:52 +01:00
}
fadeOut(duration: integer): Promise<void> {
return new Promise(resolve => {
if (this.overlayActive) {
return resolve();
}
this.overlayActive = true;
this.overlay.setAlpha(0);
this.overlay.setVisible(true);
this.scene.tweens.add({
targets: this.overlay,
alpha: 1,
duration: duration,
ease: "Sine.easeOut",
onComplete: () => resolve()
});
});
}
fadeIn(duration: integer): Promise<void> {
return new Promise(resolve => {
if (!this.overlayActive) {
return resolve();
}
this.scene.tweens.add({
targets: this.overlay,
alpha: 0,
duration: duration,
ease: "Sine.easeIn",
onComplete: () => {
this.overlay.setVisible(false);
resolve();
}
});
this.overlayActive = false;
});
}
private setModeInternal(mode: Mode, clear: boolean, forceTransition: boolean, chainMode: boolean, args: any[]): Promise<void> {
return new Promise(resolve => {
2023-04-10 18:54:06 +01:00
if (this.mode === mode && !forceTransition) {
resolve();
return;
}
const doSetMode = () => {
2023-04-10 18:54:06 +01:00
if (this.mode !== mode) {
if (clear) {
2023-04-10 18:54:06 +01:00
this.getHandler().clear();
}
if (chainMode && this.mode && !clear) {
this.modeChain.push(this.mode);
}
2023-04-10 18:54:06 +01:00
this.mode = mode;
const touchControls = document.getElementById("touchControls");
if (touchControls) {
2023-12-25 20:03:50 +00:00
touchControls.dataset.uiMode = Mode[mode];
}
2023-04-10 18:54:06 +01:00
this.getHandler().show(args);
}
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))) {
this.fadeOut(250).then(() => {
this.scene.time.delayedCall(100, () => {
doSetMode();
this.fadeIn(250);
});
});
} else {
doSetMode();
}
});
}
2023-10-26 21:33:59 +01:00
getMode(): Mode {
return this.mode;
}
setMode(mode: Mode, ...args: any[]): Promise<void> {
return this.setModeInternal(mode, true, false, false, args);
2023-04-10 18:54:06 +01:00
}
setModeForceTransition(mode: Mode, ...args: any[]): Promise<void> {
return this.setModeInternal(mode, true, true, false, args);
2023-03-28 19:54:52 +01:00
}
setModeWithoutClear(mode: Mode, ...args: any[]): Promise<void> {
return this.setModeInternal(mode, false, false, false, args);
}
setOverlayMode(mode: Mode, ...args: any[]): Promise<void> {
return this.setModeInternal(mode, false, false, true, args);
2023-03-28 19:54:52 +01:00
}
2023-10-26 21:33:59 +01:00
revertMode(): Promise<boolean> {
return new Promise<boolean>(resolve => {
if (!this?.modeChain?.length) {
return resolve(false);
}
const lastMode = this.mode;
const doRevertMode = () => {
this.getHandler().clear();
this.mode = this.modeChain.pop();
const touchControls = document.getElementById("touchControls");
if (touchControls) {
touchControls.dataset.uiMode = Mode[this.mode];
}
2024-01-10 04:34:43 +00:00
resolve(true);
};
if (noTransitionModes.indexOf(lastMode) === -1) {
this.fadeOut(250).then(() => {
this.scene.time.delayedCall(100, () => {
doRevertMode();
this.fadeIn(250);
});
});
} else {
doRevertMode();
}
});
2023-10-26 21:33:59 +01:00
}
2023-12-30 23:41:25 +00:00
revertModes(): Promise<void> {
return new Promise<void>(resolve => {
if (!this?.modeChain?.length) {
2023-12-30 23:41:25 +00:00
return resolve();
}
2023-12-30 23:41:25 +00:00
this.revertMode().then(success => Utils.executeIf(success, this.revertModes).then(() => resolve()));
});
}
}