Add achievement system and UI
Add achievement system and UI; fix counting invalid inputs in UI handlers for input delay
This commit is contained in:
1 parent
ff93e6233f
commit
cbbb8e972b
49 files changed
+4920
-3764
No files matched your search
@@ -0,0 +1,96 @@
|
||||
import BattleScene from "../battle-scene";
|
||||
import { Achv } from "../system/achv";
|
||||
import { TextStyle, addTextObject } from "./text";
|
||||
|
||||
export default class AchvBar extends Phaser.GameObjects.Container {
|
||||
private bg: Phaser.GameObjects.NineSlice;
|
||||
private icon: Phaser.GameObjects.Sprite;
|
||||
private titleText: Phaser.GameObjects.Text;
|
||||
private scoreText: Phaser.GameObjects.Text;
|
||||
private descriptionText: Phaser.GameObjects.Text;
|
||||
|
||||
private queue: Achv[] = [];
|
||||
|
||||
public shown: boolean;
|
||||
|
||||
constructor(scene: BattleScene) {
|
||||
super(scene, scene.game.canvas.width / 6, 0);
|
||||
}
|
||||
|
||||
setup(): void {
|
||||
this.bg = this.scene.add.nineslice(0, 0, 'achv_bar', null, 160, 40, 41, 6, 16, 4);
|
||||
this.bg.setOrigin(0, 0);
|
||||
|
||||
this.add(this.bg);
|
||||
|
||||
this.icon = this.scene.add.sprite(4, 4, 'items');
|
||||
this.icon.setOrigin(0, 0);
|
||||
this.add(this.icon);
|
||||
|
||||
this.titleText = addTextObject(this.scene, 40, 3, '', TextStyle.MESSAGE, { fontSize: '72px' });
|
||||
this.titleText.setOrigin(0, 0);
|
||||
this.add(this.titleText);
|
||||
|
||||
this.scoreText = addTextObject(this.scene, 150, 3, '', TextStyle.MESSAGE, { fontSize: '72px' });
|
||||
this.scoreText.setOrigin(1, 0);
|
||||
this.add(this.scoreText);
|
||||
|
||||
this.descriptionText = addTextObject(this.scene, 43, 16, '', TextStyle.WINDOW, { fontSize: '72px' });
|
||||
this.descriptionText.setOrigin(0, 0);
|
||||
this.add(this.descriptionText);
|
||||
|
||||
this.descriptionText.setWordWrapWidth(664);
|
||||
this.descriptionText.setLineSpacing(-5);
|
||||
|
||||
this.setScale(0.5);
|
||||
|
||||
this.shown = false;
|
||||
}
|
||||
|
||||
showAchv(achv: Achv): void {
|
||||
if (this.shown) {
|
||||
this.queue.push(achv);
|
||||
return;
|
||||
}
|
||||
|
||||
const tier = achv.getTier();
|
||||
|
||||
this.bg.setTexture(`achv_bar${tier ? `_${tier + 1}` : ''}`);
|
||||
this.icon.setFrame(achv.iconImage);
|
||||
this.titleText.setText(achv.name);
|
||||
this.descriptionText.setText(achv.description);
|
||||
this.scoreText.setText(`+${achv.score}pt`);
|
||||
|
||||
(this.scene as BattleScene).playSound('achv');
|
||||
|
||||
this.scene.tweens.add({
|
||||
targets: this,
|
||||
x: (this.scene.game.canvas.width / 6) - 76,
|
||||
duration: 500,
|
||||
ease: 'Sine.easeOut'
|
||||
});
|
||||
|
||||
this.scene.time.delayedCall(10000, () => this.hide());
|
||||
|
||||
this.setVisible(true);
|
||||
this.shown = true;
|
||||
}
|
||||
|
||||
protected hide(): void {
|
||||
if (!this.shown)
|
||||
return;
|
||||
|
||||
this.scene.tweens.add({
|
||||
targets: this,
|
||||
x: (this.scene.game.canvas.width / 6),
|
||||
duration: 500,
|
||||
ease: 'Sine.easeIn',
|
||||
onComplete: () => {
|
||||
this.shown = false;
|
||||
this.setVisible(false);
|
||||
if (this.queue.length)
|
||||
this.showAchv(this.queue.shift());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,210 @@
|
||||
import BattleScene, { Button } from "../battle-scene";
|
||||
import { Achv, achvs } from "../system/achv";
|
||||
import MessageUiHandler from "./message-ui-handler";
|
||||
import { TextStyle, addTextObject } from "./text";
|
||||
import { Mode } from "./ui";
|
||||
|
||||
export default class AchvsUiHandler extends MessageUiHandler {
|
||||
private achvsContainer: Phaser.GameObjects.Container;
|
||||
private achvIconsContainer: Phaser.GameObjects.Container;
|
||||
|
||||
private achvIconsBg: Phaser.GameObjects.NineSlice;
|
||||
private achvIcons: Phaser.GameObjects.Sprite[];
|
||||
private titleText: Phaser.GameObjects.Text;
|
||||
private scoreText: Phaser.GameObjects.Text;
|
||||
private unlockText: Phaser.GameObjects.Text;
|
||||
|
||||
private cursorObj: Phaser.GameObjects.NineSlice;
|
||||
|
||||
constructor(scene: BattleScene, mode?: Mode) {
|
||||
super(scene, mode);
|
||||
}
|
||||
|
||||
setup() {
|
||||
const ui = this.getUi();
|
||||
|
||||
this.achvsContainer = this.scene.add.container(1, -(this.scene.game.canvas.height / 6) + 1);
|
||||
|
||||
this.achvsContainer.setInteractive(new Phaser.Geom.Rectangle(0, 0, this.scene.game.canvas.width / 6, this.scene.game.canvas.height / 6), Phaser.Geom.Rectangle.Contains);
|
||||
|
||||
const headerBg = this.scene.add.nineslice(0, 0, 'window', null, (this.scene.game.canvas.width / 6) - 2, 24, 6, 6, 6, 6);
|
||||
headerBg.setOrigin(0, 0);
|
||||
|
||||
const headerText = addTextObject(this.scene, 0, 0, 'Achievements', TextStyle.SETTINGS_LABEL);
|
||||
headerText.setOrigin(0, 0);
|
||||
headerText.setPositionRelative(headerBg, 8, 4);
|
||||
|
||||
this.achvIconsBg = this.scene.add.nineslice(0, headerBg.height, 'window', null, (this.scene.game.canvas.width / 6) - 2, (this.scene.game.canvas.height / 6) - headerBg.height - 68, 6, 6, 6, 6);
|
||||
this.achvIconsBg.setOrigin(0, 0);
|
||||
|
||||
this.achvIconsContainer = this.scene.add.container(6, headerBg.height + 6);
|
||||
|
||||
this.achvIcons = [];
|
||||
|
||||
for (let a = 0; a < Object.keys(achvs).length; a++) {
|
||||
const x = (a % 17) * 18;
|
||||
const y = Math.floor(a / 17) * 18;
|
||||
|
||||
const icon = this.scene.add.sprite(x, y, 'items', 'unknown');
|
||||
icon.setOrigin(0, 0);
|
||||
icon.setScale(0.5);
|
||||
|
||||
this.achvIcons.push(icon);
|
||||
this.achvIconsContainer.add(icon);
|
||||
}
|
||||
|
||||
const titleBg = this.scene.add.nineslice(0, headerBg.height + this.achvIconsBg.height, 'window', null, 174, 24, 6, 6, 6, 6);
|
||||
titleBg.setOrigin(0, 0);
|
||||
|
||||
this.titleText = addTextObject(this.scene, 0, 0, '', TextStyle.WINDOW);
|
||||
this.titleText.setOrigin(0, 0);
|
||||
this.titleText.setPositionRelative(titleBg, 8, 4);
|
||||
|
||||
const scoreBg = this.scene.add.nineslice(titleBg.x + titleBg.width, titleBg.y, 'window', null, 46, 24, 6, 6, 6, 6);
|
||||
scoreBg.setOrigin(0, 0);
|
||||
|
||||
this.scoreText = addTextObject(this.scene, 0, 0, '', TextStyle.WINDOW);
|
||||
this.scoreText.setOrigin(0, 0);
|
||||
this.scoreText.setPositionRelative(scoreBg, 8, 4);
|
||||
|
||||
const unlockBg = this.scene.add.nineslice(scoreBg.x + scoreBg.width, scoreBg.y, 'window', null, 98, 24, 6, 6, 6, 6);
|
||||
unlockBg.setOrigin(0, 0);
|
||||
|
||||
this.unlockText = addTextObject(this.scene, 0, 0, '', TextStyle.WINDOW);
|
||||
this.unlockText.setOrigin(0, 0);
|
||||
this.unlockText.setPositionRelative(unlockBg, 8, 4);
|
||||
|
||||
const descriptionBg = this.scene.add.nineslice(0, titleBg.y + titleBg.height, 'window', null, (this.scene.game.canvas.width / 6) - 2, 42, 6, 6, 6, 6);
|
||||
descriptionBg.setOrigin(0, 0);
|
||||
|
||||
const descriptionText = addTextObject(this.scene, 0, 0, '', TextStyle.WINDOW, { maxLines: 2 });
|
||||
descriptionText.setWordWrapWidth(1870);
|
||||
descriptionText.setOrigin(0, 0);
|
||||
descriptionText.setPositionRelative(descriptionBg, 8, 4);
|
||||
|
||||
this.message = descriptionText;
|
||||
|
||||
this.achvsContainer.add(headerBg);
|
||||
this.achvsContainer.add(headerText);
|
||||
this.achvsContainer.add(this.achvIconsBg);
|
||||
this.achvsContainer.add(this.achvIconsContainer);
|
||||
this.achvsContainer.add(titleBg);
|
||||
this.achvsContainer.add(this.titleText);
|
||||
this.achvsContainer.add(scoreBg);
|
||||
this.achvsContainer.add(this.scoreText);
|
||||
this.achvsContainer.add(unlockBg);
|
||||
this.achvsContainer.add(this.unlockText);
|
||||
this.achvsContainer.add(descriptionBg);
|
||||
this.achvsContainer.add(descriptionText);
|
||||
|
||||
ui.add(this.achvsContainer);
|
||||
|
||||
this.setCursor(0);
|
||||
|
||||
this.achvsContainer.setVisible(false);
|
||||
}
|
||||
|
||||
show(args: any[]) {
|
||||
super.show(args);
|
||||
|
||||
const achvUnlocks = this.scene.gameData.achvUnlocks;
|
||||
|
||||
Object.values(achvs).forEach((achv: Achv, i: integer) => {
|
||||
const icon = this.achvIcons[i];
|
||||
const unlocked = achvUnlocks.hasOwnProperty(achv.id);
|
||||
const hidden = achv.secret && (!achv.parentId || !achvUnlocks.hasOwnProperty(achv.parentId));
|
||||
const tinted = !hidden && !unlocked;
|
||||
|
||||
icon.setFrame(!hidden ? achv.iconImage : 'unknown');
|
||||
if (tinted)
|
||||
icon.setTintFill(0);
|
||||
else
|
||||
icon.clearTint();
|
||||
});
|
||||
|
||||
this.achvsContainer.setVisible(true);
|
||||
this.setCursor(0);
|
||||
|
||||
this.getUi().moveTo(this.achvsContainer, this.getUi().length - 1);
|
||||
|
||||
this.getUi().hideTooltip();
|
||||
}
|
||||
|
||||
protected showAchv(achv: Achv) {
|
||||
const achvUnlocks = this.scene.gameData.achvUnlocks;
|
||||
const unlocked = achvUnlocks.hasOwnProperty(achv.id);
|
||||
const hidden = achv.secret && (!achv.parentId || !achvUnlocks.hasOwnProperty(achv.parentId));
|
||||
|
||||
this.titleText.setText(unlocked ? achv.name : '???');
|
||||
this.showText(!hidden ? achv.description : '');
|
||||
this.scoreText.setText(`${achv.score}pt`);
|
||||
this.unlockText.setText(unlocked ? new Date(achvUnlocks[achv.id]).toLocaleDateString() : 'Locked');
|
||||
}
|
||||
|
||||
processInput(button: Button): boolean {
|
||||
const ui = this.getUi();
|
||||
|
||||
let success = false;
|
||||
|
||||
if (button === Button.CANCEL) {
|
||||
success = true;
|
||||
this.scene.ui.revertMode();
|
||||
} else {
|
||||
switch (button) {
|
||||
case Button.UP:
|
||||
if (this.cursor >= 17)
|
||||
success = this.setCursor(this.cursor - 17);
|
||||
break;
|
||||
case Button.DOWN:
|
||||
if (this.cursor + 17 < Object.keys(achvs).length)
|
||||
success = this.setCursor(this.cursor + 17);
|
||||
break;
|
||||
case Button.LEFT:
|
||||
if (this.cursor % 17)
|
||||
success = this.setCursor(this.cursor - 1);
|
||||
break;
|
||||
case Button.RIGHT:
|
||||
if (this.cursor % 17 < 16 && this.cursor < Object.keys(achvs).length - 1)
|
||||
success = this.setCursor(this.cursor + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (success)
|
||||
ui.playSelect();
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
setCursor(cursor: integer): boolean {
|
||||
let ret = super.setCursor(cursor);
|
||||
|
||||
let updateAchv = ret;
|
||||
|
||||
if (!this.cursorObj) {
|
||||
this.cursorObj = this.scene.add.nineslice(0, 0, 'starter_select_cursor_highlight', null, 16, 16, 1, 1, 1, 1);
|
||||
this.cursorObj.setOrigin(0, 0);
|
||||
this.achvIconsContainer.add(this.cursorObj);
|
||||
updateAchv = true;
|
||||
}
|
||||
|
||||
this.cursorObj.setPositionRelative(this.achvIcons[this.cursor], 0, 0);
|
||||
|
||||
if (updateAchv)
|
||||
this.showAchv(achvs[Object.keys(achvs)[cursor]]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
clear() {
|
||||
super.clear();
|
||||
this.achvsContainer.setVisible(false);
|
||||
this.eraseCursor();
|
||||
}
|
||||
|
||||
eraseCursor() {
|
||||
if (this.cursorObj)
|
||||
this.cursorObj.destroy();
|
||||
this.cursorObj = null;
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,7 @@ export default class BallUiHandler extends UiHandler {
|
||||
this.setCursor(this.cursor);
|
||||
}
|
||||
|
||||
processInput(button: Button) {
|
||||
processInput(button: Button): boolean {
|
||||
const ui = this.getUi();
|
||||
|
||||
let success = false;
|
||||
@@ -91,6 +91,8 @@ export default class BallUiHandler extends UiHandler {
|
||||
|
||||
if (success)
|
||||
ui.playSelect();
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
updateCounts() {
|
||||
|
||||
@@ -102,7 +102,7 @@ export default class BattleMessageUiHandler extends MessageUiHandler {
|
||||
this.message.setWordWrapWidth(1780);
|
||||
}
|
||||
|
||||
processInput(button: Button): void {
|
||||
processInput(button: Button): boolean {
|
||||
const ui = this.getUi();
|
||||
if (this.awaitingActionInput) {
|
||||
if (button === Button.CANCEL || button === Button.ACTION) {
|
||||
@@ -111,6 +111,7 @@ export default class BattleMessageUiHandler extends MessageUiHandler {
|
||||
const originalOnActionInput = this.onActionInput;
|
||||
this.onActionInput = null;
|
||||
originalOnActionInput();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ export default class BiomeSelectUiHandler extends UiHandler {
|
||||
}
|
||||
}
|
||||
|
||||
processInput(button: Button) {
|
||||
processInput(button: Button): boolean {
|
||||
const ui = this.getUi();
|
||||
|
||||
let success = false;
|
||||
@@ -78,6 +78,8 @@ export default class BiomeSelectUiHandler extends UiHandler {
|
||||
|
||||
if (success)
|
||||
ui.playSelect();
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
setCursor(cursor: integer): boolean {
|
||||
|
||||
@@ -51,7 +51,7 @@ export default class CommandUiHandler extends UiHandler {
|
||||
this.setCursor(this.getCursor());
|
||||
}
|
||||
|
||||
processInput(button: Button) {
|
||||
processInput(button: Button): boolean {
|
||||
const ui = this.getUi();
|
||||
|
||||
let success = false;
|
||||
@@ -104,6 +104,8 @@ export default class CommandUiHandler extends UiHandler {
|
||||
|
||||
if (success)
|
||||
ui.playSelect();
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
getCursor(): integer {
|
||||
|
||||
@@ -20,8 +20,8 @@ export default class EvolutionSceneHandler extends UiHandler {
|
||||
this.scene.fieldUI.bringToTop(this.evolutionContainer);
|
||||
}
|
||||
|
||||
processInput(button: Button) {
|
||||
this.scene.ui.getMessageHandler().processInput(button);
|
||||
processInput(button: Button): boolean {
|
||||
return this.scene.ui.getMessageHandler().processInput(button);
|
||||
}
|
||||
|
||||
setCursor(_cursor: integer): boolean {
|
||||
|
||||
@@ -47,7 +47,7 @@ export default class FightUiHandler extends UiHandler {
|
||||
this.displayMoves();
|
||||
}
|
||||
|
||||
processInput(button: Button) {
|
||||
processInput(button: Button): boolean {
|
||||
const ui = this.getUi();
|
||||
|
||||
let success = false;
|
||||
@@ -87,6 +87,8 @@ export default class FightUiHandler extends UiHandler {
|
||||
|
||||
if (success)
|
||||
ui.playSelect();
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
getCursor(): integer {
|
||||
|
||||
@@ -42,7 +42,7 @@ export default class GameModeSelectUiHandler extends OptionSelectUiHandler {
|
||||
}
|
||||
}
|
||||
|
||||
processInput(button: Button) {
|
||||
processInput(button: Button): boolean {
|
||||
const ui = this.getUi();
|
||||
|
||||
const options = this.getOptions();
|
||||
@@ -59,5 +59,7 @@ export default class GameModeSelectUiHandler extends OptionSelectUiHandler {
|
||||
ui.playSelect();
|
||||
} else
|
||||
return super.processInput(button);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
import BattleScene, { Button } from "../battle-scene";
|
||||
import { TextStyle, addTextObject } from "./text";
|
||||
import { Mode } from "./ui";
|
||||
import UiHandler from "./uiHandler";
|
||||
import * as Utils from "../utils";
|
||||
|
||||
export enum MenuOptions {
|
||||
SETTINGS,
|
||||
ACHIEVEMENTS
|
||||
}
|
||||
|
||||
export default class MenuUiHandler extends UiHandler {
|
||||
private menuContainer: Phaser.GameObjects.Container;
|
||||
|
||||
private menuBg: Phaser.GameObjects.NineSlice;
|
||||
protected optionSelectText: Phaser.GameObjects.Text;
|
||||
|
||||
private cursorObj: Phaser.GameObjects.Image;
|
||||
|
||||
constructor(scene: BattleScene, mode?: Mode) {
|
||||
super(scene, mode);
|
||||
}
|
||||
|
||||
setup() {
|
||||
const ui = this.getUi();
|
||||
|
||||
this.menuContainer = this.scene.add.container(1, -(this.scene.game.canvas.height / 6) + 1);
|
||||
|
||||
this.menuContainer.setInteractive(new Phaser.Geom.Rectangle(0, 0, this.scene.game.canvas.width / 6, this.scene.game.canvas.height / 6), Phaser.Geom.Rectangle.Contains);
|
||||
|
||||
this.menuBg = this.scene.add.nineslice((this.scene.game.canvas.width / 6) - 92, 0, 'window', null, 90, (this.scene.game.canvas.height / 6) - 2, 6, 6, 6, 6);
|
||||
this.menuBg.setOrigin(0, 0);
|
||||
|
||||
this.menuContainer.add(this.menuBg);
|
||||
|
||||
this.optionSelectText = addTextObject(this.scene, 0, 0, Utils.getEnumKeys(MenuOptions).map(o => Utils.toReadableString(o)).join('\n'), TextStyle.WINDOW, { maxLines: Utils.getEnumKeys(MenuOptions).length });
|
||||
this.optionSelectText.setPositionRelative(this.menuBg, 14, 6);
|
||||
this.optionSelectText.setLineSpacing(12);
|
||||
this.menuContainer.add(this.optionSelectText);
|
||||
|
||||
ui.add(this.menuContainer);
|
||||
|
||||
this.setCursor(0);
|
||||
|
||||
this.menuContainer.setVisible(false);
|
||||
}
|
||||
|
||||
show(args: any[]) {
|
||||
super.show(args);
|
||||
|
||||
this.menuContainer.setVisible(true);
|
||||
this.setCursor(0);
|
||||
|
||||
this.getUi().moveTo(this.menuContainer, this.getUi().length - 1);
|
||||
|
||||
this.getUi().hideTooltip();
|
||||
|
||||
this.scene.playSound('menu_open');
|
||||
}
|
||||
|
||||
processInput(button: Button): boolean {
|
||||
const ui = this.getUi();
|
||||
|
||||
let success = false;
|
||||
|
||||
if (button === Button.ACTION) {
|
||||
switch (this.cursor as MenuOptions) {
|
||||
case MenuOptions.SETTINGS:
|
||||
this.scene.ui.setOverlayMode(Mode.SETTINGS);
|
||||
success = true;
|
||||
break;
|
||||
case MenuOptions.ACHIEVEMENTS:
|
||||
this.scene.ui.setOverlayMode(Mode.ACHIEVEMENTS);
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
} else if (button === Button.CANCEL) {
|
||||
success = true;
|
||||
this.scene.ui.revertMode();
|
||||
} else {
|
||||
switch (button) {
|
||||
case Button.UP:
|
||||
if (this.cursor)
|
||||
success = this.setCursor(this.cursor - 1);
|
||||
break;
|
||||
case Button.DOWN:
|
||||
if (this.cursor < Utils.getEnumKeys(MenuOptions).length)
|
||||
success = this.setCursor(this.cursor + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (success)
|
||||
ui.playSelect();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
setCursor(cursor: integer): boolean {
|
||||
const ret = super.setCursor(cursor);
|
||||
|
||||
if (!this.cursorObj) {
|
||||
this.cursorObj = this.scene.add.image(0, 0, 'cursor');
|
||||
this.cursorObj.setOrigin(0, 0);
|
||||
this.menuContainer.add(this.cursorObj);
|
||||
}
|
||||
|
||||
this.cursorObj.setPositionRelative(this.menuBg, 7, 9 + this.cursor * 16);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
clear() {
|
||||
super.clear();
|
||||
this.menuContainer.setVisible(false);
|
||||
this.eraseCursor();
|
||||
}
|
||||
|
||||
eraseCursor() {
|
||||
if (this.cursorObj)
|
||||
this.cursorObj.destroy();
|
||||
this.cursorObj = null;
|
||||
}
|
||||
}
|
||||
@@ -137,11 +137,11 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler {
|
||||
});
|
||||
}
|
||||
|
||||
processInput(button: Button) {
|
||||
processInput(button: Button): boolean {
|
||||
const ui = this.getUi();
|
||||
|
||||
if (!this.awaitingActionInput)
|
||||
return;
|
||||
return false;
|
||||
|
||||
let success = false;
|
||||
|
||||
@@ -193,6 +193,8 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler {
|
||||
|
||||
if (success)
|
||||
ui.playSelect();
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
setCursor(cursor: integer): boolean {
|
||||
|
||||
@@ -65,7 +65,7 @@ export default abstract class OptionSelectUiHandler extends UiHandler {
|
||||
}
|
||||
}
|
||||
|
||||
processInput(button: Button) {
|
||||
processInput(button: Button): boolean {
|
||||
const ui = this.getUi();
|
||||
|
||||
let success = false;
|
||||
@@ -94,6 +94,8 @@ export default abstract class OptionSelectUiHandler extends UiHandler {
|
||||
|
||||
if (success)
|
||||
ui.playSelect();
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
setCursor(cursor: integer): boolean {
|
||||
|
||||
+23
-16
@@ -177,23 +177,22 @@ export default class PartyUiHandler extends MessageUiHandler {
|
||||
this.setCursor(this.cursor < 6 ? this.cursor : 0);
|
||||
}
|
||||
|
||||
processInput(button: Button) {
|
||||
processInput(button: Button): boolean {
|
||||
const ui = this.getUi();
|
||||
|
||||
if (this.pendingPrompt)
|
||||
return;
|
||||
return false;
|
||||
|
||||
if (this.awaitingActionInput) {
|
||||
if (button === Button.ACTION || button === Button.CANCEL) {
|
||||
if (this.onActionInput) {
|
||||
ui.playSelect();
|
||||
const originalOnActionInput = this.onActionInput;
|
||||
this.onActionInput = null;
|
||||
originalOnActionInput();
|
||||
this.awaitingActionInput = false;
|
||||
}
|
||||
if ((button === Button.ACTION || button === Button.CANCEL) && this.onActionInput) {
|
||||
ui.playSelect();
|
||||
const originalOnActionInput = this.onActionInput;
|
||||
this.onActionInput = null;
|
||||
originalOnActionInput();
|
||||
this.awaitingActionInput = false;
|
||||
return true;
|
||||
}
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
let success = false;
|
||||
@@ -206,6 +205,7 @@ export default class PartyUiHandler extends MessageUiHandler {
|
||||
this.startTransfer();
|
||||
this.clearOptions();
|
||||
ui.playSelect();
|
||||
return true;
|
||||
} else if (this.partyUiMode === PartyUiMode.REMEMBER_MOVE_MODIFIER && option !== PartyOption.CANCEL) {
|
||||
let filterResult = (this.selectFilter as PokemonSelectFilter)(pokemon);
|
||||
if (filterResult === null) {
|
||||
@@ -216,6 +216,7 @@ export default class PartyUiHandler extends MessageUiHandler {
|
||||
this.showText(filterResult as string, null, () => this.showText(null, 0), null, true);
|
||||
}
|
||||
ui.playSelect();
|
||||
return true;
|
||||
} else if ((option !== PartyOption.SUMMARY && option !== PartyOption.RELEASE && option !== PartyOption.CANCEL)
|
||||
|| (option === PartyOption.RELEASE && this.partyUiMode === PartyUiMode.RELEASE)) {
|
||||
let filterResult: string;
|
||||
@@ -254,7 +255,7 @@ export default class PartyUiHandler extends MessageUiHandler {
|
||||
(this.scene.getCurrentPhase() as CommandPhase).handleCommand(Command.POKEMON, this.cursor, option === PartyOption.PASS_BATON);
|
||||
if (this.partyUiMode !== PartyUiMode.MODIFIER && this.partyUiMode !== PartyUiMode.TM_MODIFIER && this.partyUiMode !== PartyUiMode.MOVE_MODIFIER)
|
||||
ui.playSelect();
|
||||
return;
|
||||
return true;
|
||||
} else {
|
||||
this.clearOptions();
|
||||
this.showText(filterResult as string, null, () => this.showText(null, 0), null, true);
|
||||
@@ -262,6 +263,7 @@ export default class PartyUiHandler extends MessageUiHandler {
|
||||
} else if (option === PartyOption.SUMMARY) {
|
||||
ui.playSelect();
|
||||
ui.setModeWithoutClear(Mode.SUMMARY, pokemon).then(() => this.clearOptions());
|
||||
return true;
|
||||
} else if (option === PartyOption.RELEASE) {
|
||||
this.clearOptions();
|
||||
ui.playSelect();
|
||||
@@ -277,11 +279,13 @@ export default class PartyUiHandler extends MessageUiHandler {
|
||||
});
|
||||
} else
|
||||
this.showText('You can\'t release a Pokémon that\'s in battle!', null, () => this.showText(null, 0), null, true);
|
||||
return true;
|
||||
} else if (option === PartyOption.CANCEL)
|
||||
this.processInput(Button.CANCEL);
|
||||
return this.processInput(Button.CANCEL);
|
||||
} else if (button === Button.CANCEL) {
|
||||
this.clearOptions();
|
||||
ui.playSelect();
|
||||
return true;
|
||||
} else {
|
||||
switch (button) {
|
||||
case Button.UP:
|
||||
@@ -300,8 +304,8 @@ export default class PartyUiHandler extends MessageUiHandler {
|
||||
} else if (this.partyUiMode === PartyUiMode.FAINT_SWITCH)
|
||||
ui.playError();
|
||||
else
|
||||
this.processInput(Button.CANCEL);
|
||||
return;
|
||||
return this.processInput(Button.CANCEL);
|
||||
return true;
|
||||
} else if (button === Button.CANCEL) {
|
||||
if ((this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER || this.partyUiMode === PartyUiMode.SPLICE) && this.transferMode) {
|
||||
this.clearTransfer();
|
||||
@@ -317,7 +321,8 @@ export default class PartyUiHandler extends MessageUiHandler {
|
||||
ui.playSelect();
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const slotCount = this.partySlots.length;
|
||||
@@ -343,6 +348,8 @@ export default class PartyUiHandler extends MessageUiHandler {
|
||||
|
||||
if (success)
|
||||
ui.playSelect();
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
populatePartySlots() {
|
||||
|
||||
@@ -91,9 +91,7 @@ export default class SettingsUiHandler extends UiHandler {
|
||||
|
||||
const settings: object = localStorage.hasOwnProperty('settings') ? JSON.parse(localStorage.getItem('settings')) : {};
|
||||
|
||||
Object.keys(settingDefaults).forEach((setting, s) => {
|
||||
this.setOptionCursor(s, settings.hasOwnProperty(setting) ? settings[setting] : settingDefaults[setting]);
|
||||
});
|
||||
Object.keys(settingDefaults).forEach((setting, s) => this.setOptionCursor(s, settings.hasOwnProperty(setting) ? settings[setting] : settingDefaults[setting]));
|
||||
|
||||
this.settingsContainer.setVisible(true);
|
||||
this.setCursor(0);
|
||||
@@ -103,7 +101,7 @@ export default class SettingsUiHandler extends UiHandler {
|
||||
this.getUi().hideTooltip();
|
||||
}
|
||||
|
||||
processInput(button: Button) {
|
||||
processInput(button: Button): boolean {
|
||||
const ui = this.getUi();
|
||||
|
||||
let success = false;
|
||||
@@ -134,6 +132,8 @@ export default class SettingsUiHandler extends UiHandler {
|
||||
|
||||
if (success)
|
||||
ui.playSelect();
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
setCursor(cursor: integer): boolean {
|
||||
|
||||
@@ -301,10 +301,11 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
||||
this.starterSelectMessageBoxContainer.setVisible(true);
|
||||
}
|
||||
|
||||
processInput(button: Button): void {
|
||||
processInput(button: Button): boolean {
|
||||
const ui = this.getUi();
|
||||
|
||||
let success = false;
|
||||
let error = false;
|
||||
|
||||
if (this.genMode) {
|
||||
switch (button) {
|
||||
@@ -323,7 +324,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
||||
} else {
|
||||
if (button === Button.ACTION) {
|
||||
if (!this.speciesStarterDexEntry)
|
||||
ui.playError();
|
||||
error = true;
|
||||
else if (this.starterCursors.length < 3) {
|
||||
let isDupe = false;
|
||||
for (let s = 0; s < this.starterCursors.length; s++) {
|
||||
@@ -380,7 +381,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
||||
success = true;
|
||||
this.updateInstructions();
|
||||
} else
|
||||
ui.playError();
|
||||
error = true;
|
||||
}
|
||||
} else if (button === Button.CANCEL) {
|
||||
if (this.starterCursors.length) {
|
||||
@@ -388,7 +389,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
||||
success = true;
|
||||
this.updateInstructions();
|
||||
} else
|
||||
ui.playError();
|
||||
error = true;
|
||||
} else {
|
||||
const genStarters = this.starterSelectGenIconContainers[this.genCursor].getAll().length;
|
||||
const rows = Math.ceil(genStarters / 9);
|
||||
@@ -446,6 +447,10 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
||||
|
||||
if (success)
|
||||
ui.playSelect();
|
||||
else if (error)
|
||||
ui.playError();
|
||||
|
||||
return success || error;
|
||||
}
|
||||
|
||||
updateInstructions(): void {
|
||||
|
||||
@@ -241,13 +241,14 @@ export default class SummaryUiHandler extends UiHandler {
|
||||
this.hideStatus(!fromSummary);
|
||||
}
|
||||
|
||||
processInput(button: Button) {
|
||||
processInput(button: Button): boolean {
|
||||
if (this.transitioning)
|
||||
return;
|
||||
return false;
|
||||
|
||||
const ui = this.getUi();
|
||||
|
||||
let success = false;
|
||||
let error = false;
|
||||
|
||||
if (this.moveSelect) {
|
||||
if (button === Button.ACTION) {
|
||||
@@ -283,9 +284,9 @@ export default class SummaryUiHandler extends UiHandler {
|
||||
}
|
||||
success = true;
|
||||
} else if (this.moveCursor === 4)
|
||||
this.processInput(Button.CANCEL);
|
||||
return this.processInput(Button.CANCEL);
|
||||
else
|
||||
ui.playError();
|
||||
error = true;
|
||||
} else if (button === Button.CANCEL) {
|
||||
this.hideMoveSelect();
|
||||
success = true;
|
||||
@@ -336,6 +337,10 @@ export default class SummaryUiHandler extends UiHandler {
|
||||
|
||||
if (success)
|
||||
ui.playSelect();
|
||||
else if (error)
|
||||
ui.playError();
|
||||
|
||||
return success || error;
|
||||
}
|
||||
|
||||
setCursor(cursor: integer): boolean {
|
||||
|
||||
@@ -41,7 +41,7 @@ export default class TargetSelectUiHandler extends UiHandler {
|
||||
this.setCursor(this.targets.indexOf(this.cursor) > -1 ? this.cursor : this.targets[0]);
|
||||
}
|
||||
|
||||
processInput(button: Button) {
|
||||
processInput(button: Button): boolean {
|
||||
const ui = this.getUi();
|
||||
|
||||
let success = false;
|
||||
@@ -72,6 +72,8 @@ export default class TargetSelectUiHandler extends UiHandler {
|
||||
|
||||
if (success)
|
||||
ui.playSelect();
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
setCursor(cursor: integer): boolean {
|
||||
|
||||
+1
-1
@@ -107,7 +107,7 @@ export function getModifierTierTextTint(tier: integer): integer {
|
||||
case 1: // ModifierTier.GREAT:
|
||||
return 0x3890f8;
|
||||
case 2: // ModifierTier.ULTRA:
|
||||
return 0xf8d038
|
||||
return 0xf8d038;
|
||||
case 3: // ModifierTier.MASTER:
|
||||
return 0xe020c0;
|
||||
case 4: // ModifierTier.LUXURY:
|
||||
|
||||
+38
-16
@@ -15,8 +15,10 @@ import BiomeSelectUiHandler from './biome-select-ui-handler';
|
||||
import TargetSelectUiHandler from './target-select-ui-handler';
|
||||
import GameModeSelectUiHandler from './game-mode-select-ui-handler';
|
||||
import SettingsUiHandler from './settings-ui-handler';
|
||||
import { TextStyle, addTextObject, getTextColor } from './text';
|
||||
import { getPokeballTintColor } from '../data/pokeball';
|
||||
import { TextStyle, addTextObject } from './text';
|
||||
import AchvBar from './achv-bar';
|
||||
import MenuUiHandler from './menu-ui-handler';
|
||||
import AchvsUiHandler from './achvs-ui-handler';
|
||||
|
||||
export enum Mode {
|
||||
MESSAGE,
|
||||
@@ -32,7 +34,9 @@ export enum Mode {
|
||||
EVOLUTION_SCENE,
|
||||
CONFIRM,
|
||||
GAME_MODE_SELECT,
|
||||
SETTINGS
|
||||
MENU,
|
||||
SETTINGS,
|
||||
ACHIEVEMENTS
|
||||
};
|
||||
|
||||
const transitionModes = [
|
||||
@@ -45,14 +49,21 @@ const transitionModes = [
|
||||
const noTransitionModes = [
|
||||
Mode.CONFIRM,
|
||||
Mode.GAME_MODE_SELECT,
|
||||
Mode.MENU,
|
||||
Mode.SETTINGS
|
||||
];
|
||||
|
||||
const menuModes = [
|
||||
Mode.MENU,
|
||||
Mode.SETTINGS
|
||||
];
|
||||
|
||||
export default class UI extends Phaser.GameObjects.Container {
|
||||
private mode: Mode;
|
||||
private lastMode: Mode;
|
||||
private modeChain: Mode[];
|
||||
private handlers: UiHandler[];
|
||||
private overlay: Phaser.GameObjects.Rectangle;
|
||||
public achvBar: AchvBar;
|
||||
|
||||
private tooltipContainer: Phaser.GameObjects.Container;
|
||||
private tooltipBg: Phaser.GameObjects.NineSlice;
|
||||
@@ -65,6 +76,7 @@ export default class UI extends Phaser.GameObjects.Container {
|
||||
super(scene, 0, scene.game.canvas.height / 6);
|
||||
|
||||
this.mode = Mode.MESSAGE;
|
||||
this.modeChain = [];
|
||||
this.handlers = [
|
||||
new BattleMessageUiHandler(scene),
|
||||
new CommandUiHandler(scene),
|
||||
@@ -79,7 +91,9 @@ export default class UI extends Phaser.GameObjects.Container {
|
||||
new EvolutionSceneHandler(scene),
|
||||
new ConfirmUiHandler(scene),
|
||||
new GameModeSelectUiHandler(scene),
|
||||
new SettingsUiHandler(scene)
|
||||
new MenuUiHandler(scene),
|
||||
new SettingsUiHandler(scene),
|
||||
new AchvsUiHandler(scene)
|
||||
];
|
||||
}
|
||||
|
||||
@@ -91,6 +105,10 @@ export default class UI extends Phaser.GameObjects.Container {
|
||||
(this.scene as BattleScene).uiContainer.add(this.overlay);
|
||||
this.overlay.setVisible(false);
|
||||
this.setupTooltip();
|
||||
|
||||
this.achvBar = new AchvBar(this.scene as BattleScene);
|
||||
this.achvBar.setup();
|
||||
(this.scene as BattleScene).uiContainer.add(this.achvBar);
|
||||
}
|
||||
|
||||
private setupTooltip() {
|
||||
@@ -121,11 +139,11 @@ export default class UI extends Phaser.GameObjects.Container {
|
||||
return this.handlers[Mode.MESSAGE] as BattleMessageUiHandler;
|
||||
}
|
||||
|
||||
processInput(button: Button): void {
|
||||
processInput(button: Button): boolean {
|
||||
if (this.overlayActive)
|
||||
return;
|
||||
return false;
|
||||
|
||||
this.getHandler().processInput(button);
|
||||
return this.getHandler().processInput(button);
|
||||
}
|
||||
|
||||
showText(text: string, delay?: integer, callback?: Function, callbackDelay?: integer, prompt?: boolean, promptDelay?: integer): void {
|
||||
@@ -229,7 +247,7 @@ export default class UI extends Phaser.GameObjects.Container {
|
||||
});
|
||||
}
|
||||
|
||||
private setModeInternal(mode: Mode, clear: boolean, forceTransition: boolean, args: any[]): Promise<void> {
|
||||
private setModeInternal(mode: Mode, clear: boolean, forceTransition: boolean, chainMode: boolean, args: any[]): Promise<void> {
|
||||
return new Promise(resolve => {
|
||||
if (this.mode === mode && !forceTransition) {
|
||||
resolve();
|
||||
@@ -239,7 +257,8 @@ export default class UI extends Phaser.GameObjects.Container {
|
||||
if (this.mode !== mode) {
|
||||
if (clear)
|
||||
this.getHandler().clear();
|
||||
this.lastMode = this.mode && !clear ? this.mode : undefined;
|
||||
if (chainMode && this.mode && !clear)
|
||||
this.modeChain.push(this.mode);
|
||||
this.mode = mode;
|
||||
this.getHandler().show(args);
|
||||
}
|
||||
@@ -263,23 +282,26 @@ export default class UI extends Phaser.GameObjects.Container {
|
||||
}
|
||||
|
||||
setMode(mode: Mode, ...args: any[]): Promise<void> {
|
||||
return this.setModeInternal(mode, true, false, args);
|
||||
return this.setModeInternal(mode, true, false, false, args);
|
||||
}
|
||||
|
||||
setModeForceTransition(mode: Mode, ...args: any[]): Promise<void> {
|
||||
return this.setModeInternal(mode, true, true, args);
|
||||
return this.setModeInternal(mode, true, true, false, args);
|
||||
}
|
||||
|
||||
setModeWithoutClear(mode: Mode, ...args: any[]): Promise<void> {
|
||||
return this.setModeInternal(mode, false, false, args);
|
||||
return this.setModeInternal(mode, false, false, false, args);
|
||||
}
|
||||
|
||||
setOverlayMode(mode: Mode, ...args: any[]): Promise<void> {
|
||||
return this.setModeInternal(mode, false, false, true, args);
|
||||
}
|
||||
|
||||
revertMode(): void {
|
||||
if (!this.lastMode)
|
||||
if (!this.modeChain.length)
|
||||
return;
|
||||
|
||||
this.getHandler().clear();
|
||||
this.mode = this.lastMode;
|
||||
this.lastMode = undefined;
|
||||
this.mode = this.modeChain.pop();
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -18,7 +18,7 @@ export default abstract class UiHandler {
|
||||
this.active = true;
|
||||
}
|
||||
|
||||
abstract processInput(button: Button): void;
|
||||
abstract processInput(button: Button): boolean;
|
||||
|
||||
getUi() {
|
||||
return this.scene.ui;
|
||||
|
||||
Reference in new issue
Block a user