pokerogue/src/ui/ui.ts

352 lines
11 KiB
TypeScript
Raw Normal View History

import { Button, default as BattleScene } from '../battle-scene';
import UiHandler from './ui-handler';
2023-03-28 19:54:52 +01:00
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';
2023-03-28 19:54:52 +01:00
import ModifierSelectUiHandler from './modifier-select-ui-handler';
2023-04-02 03:59:07 +01:00
import BallUiHandler from './ball-ui-handler';
import SummaryUiHandler from './summary-ui-handler';
2023-04-10 00:15:21 +01:00
import StarterSelectUiHandler from './starter-select-ui-handler';
2023-04-10 18:54:06 +01:00
import EvolutionSceneHandler from './evolution-scene-handler';
2023-04-12 05:37:56 +01:00
import BiomeSelectUiHandler from './biome-select-ui-handler';
import TargetSelectUiHandler from './target-select-ui-handler';
import GameModeSelectUiHandler from './game-mode-select-ui-handler';
2023-10-26 21:33:59 +01:00
import SettingsUiHandler from './settings-ui-handler';
import { TextStyle, addTextObject } from './text';
import AchvBar from './achv-bar';
import MenuUiHandler from './menu-ui-handler';
import AchvsUiHandler from './achvs-ui-handler';
2023-11-14 03:29:03 +00:00
import OptionSelectUiHandler from './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 VoucherBar from './voucher-bar';
import { addWindow } from './window';
2023-03-28 19:54:52 +01:00
export enum Mode {
MESSAGE,
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,
PARTY,
2023-04-10 00:15:21 +01:00
SUMMARY,
2023-04-12 05:37:56 +01:00
BIOME_SELECT,
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,
2023-10-26 21:33:59 +01:00
GAME_MODE_SELECT,
MENU,
SETTINGS,
ACHIEVEMENTS,
VOUCHERS,
EGG_LIST,
EGG_GACHA
2023-03-28 19:54:52 +01:00
};
const transitionModes = [
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,
Mode.EGG_GACHA
2023-04-10 18:54:06 +01:00
];
const noTransitionModes = [
Mode.CONFIRM,
2023-11-14 03:29:03 +00:00
Mode.OPTION_SELECT,
2023-10-26 21:33:59 +01:00
Mode.GAME_MODE_SELECT,
Mode.MENU,
Mode.SETTINGS,
Mode.ACHIEVEMENTS,
Mode.VOUCHERS
];
2023-03-28 19:54:52 +01:00
export default class UI extends Phaser.GameObjects.Container {
private mode: Mode;
private modeChain: Mode[];
2023-03-28 19:54:52 +01:00
private handlers: UiHandler[];
private overlay: Phaser.GameObjects.Rectangle;
public achvBar: AchvBar;
public voucherBar: VoucherBar;
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;
2023-04-07 05:17:55 +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),
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 PartyUiHandler(scene),
2023-04-10 00:15:21 +01:00
new SummaryUiHandler(scene),
2023-04-12 05:37:56 +01:00
new BiomeSelectUiHandler(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),
2023-10-26 21:33:59 +01:00
new GameModeSelectUiHandler(scene),
new MenuUiHandler(scene),
new SettingsUiHandler(scene),
new AchvsUiHandler(scene),
new VouchersUiHandler(scene),
new EggListUiHandler(scene),
new EggGachaUiHandler(scene)
2023-03-28 19:54:52 +01:00
];
}
2023-04-07 05:17:55 +01:00
setup(): void {
2023-11-02 04:55:20 +00:00
for (let 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.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();
(this.scene as BattleScene).uiContainer.add(this.achvBar);
2023-11-02 04:55:20 +00:00
}
private setupTooltip() {
this.tooltipContainer = this.scene.add.container(0, 0);
this.tooltipContainer.setVisible(false);
this.tooltipBg = addWindow(this.scene, 0, 0, 128, 31);
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.setOrigin(0.5, 0);
this.tooltipContent = addTextObject(this.scene, 6, 16, '', TextStyle.TOOLTIP_CONTENT);
this.tooltipContent.setWordWrapWidth(696)
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;
}
processInput(button: Button): boolean {
if (this.overlayActive)
return false;
2023-04-07 05:17:55 +01:00
return this.getHandler().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 {
2023-03-28 19:54:52 +01:00
const handler = this.getHandler();
if (handler instanceof MessageUiHandler)
2023-04-10 18:54:06 +01:00
(handler as MessageUiHandler).showText(text, delay, callback, callbackDelay, prompt, promptDelay);
2023-03-28 19:54:52 +01:00
else
2023-04-10 18:54:06 +01:00
this.getMessageHandler().showText(text, delay, callback, callbackDelay, prompt, promptDelay);
2023-03-28 19:54:52 +01:00
}
showDialogue(text: string, name: string, delay?: integer, callback?: Function, callbackDelay?: integer, prompt?: boolean, promptDelay?: integer): void {
const handler = this.getHandler();
if (handler instanceof MessageUiHandler)
(handler as MessageUiHandler).showDialogue(text, name, delay, callback, callbackDelay, prompt, promptDelay);
else
this.getMessageHandler().showDialogue(text, name, delay, callback, callbackDelay, prompt, promptDelay);
}
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);
2023-11-02 04:55:20 +00:00
if (overlap)
(this.scene as BattleScene).uiContainer.moveAbove(this.tooltipContainer, this);
else
(this.scene as BattleScene).uiContainer.moveBelow(this.tooltipContainer, this);
}
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)
(handler as MessageUiHandler).clearText();
else
this.getMessageHandler().clearText();
}
setCursor(cursor: integer): boolean {
const changed = this.getHandler().setCursor(cursor);
if (changed)
this.playSelect();
return changed;
}
2023-04-07 05:17:55 +01:00
playSelect(): void {
2023-10-21 13:58:39 +01:00
(this.scene as BattleScene).playSound('select');
2023-03-28 19:54:52 +01:00
}
2023-04-07 05:17:55 +01:00
playError(): void {
2023-10-21 13:58:39 +01:00
(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) {
resolve();
return;
}
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 => {
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)
this.getHandler().clear();
if (chainMode && this.mode && !clear)
this.modeChain.push(this.mode);
2023-04-10 18:54:06 +01:00
this.mode = mode;
2023-12-25 20:03:50 +00:00
const touchControls = document.getElementById('touchControls');
if (touchControls)
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.scene as BattleScene).auto) {
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];
};
if (noTransitionModes.indexOf(lastMode) === -1) {
this.fadeOut(250).then(() => {
this.scene.time.delayedCall(100, () => {
doRevertMode();
this.fadeIn(250);
});
});
} else
doRevertMode();
resolve(true);
});
2023-10-26 21:33:59 +01:00
}
2023-03-28 19:54:52 +01:00
}