Add egg gacha system and various minor changes

Add egg gacha system; remove certain mythical Pokemon from the wild pool as egg exclusive; add egg vouchers with UI; rework Shiny Charm odds; fix trainer Pokemon shiny odds not properly ignoring Shiny Charm modifier
This commit is contained in:
Flashfyre committed 2023-12-19 23:51:48 -05:00
1 parent 50d4858caa
commit aa94e044ab
71 files changed
+4303 -2241

No files matched your search

+8 -5
View File
@@ -1,5 +1,6 @@
import BattleScene from "../battle-scene";
import { Achv } from "../system/achv";
import { Voucher } from "../system/voucher";
import { TextStyle, addTextObject } from "./text";
export default class AchvBar extends Phaser.GameObjects.Container {
@@ -9,7 +10,7 @@ export default class AchvBar extends Phaser.GameObjects.Container {
private scoreText: Phaser.GameObjects.Text;
private descriptionText: Phaser.GameObjects.Text;
private queue: Achv[] = [];
private queue: (Achv | Voucher)[] = [];
public shown: boolean;
@@ -47,7 +48,7 @@ export default class AchvBar extends Phaser.GameObjects.Container {
this.shown = false;
}
showAchv(achv: Achv): void {
showAchv(achv: Achv | Voucher): void {
if (this.shown) {
this.queue.push(achv);
return;
@@ -56,10 +57,12 @@ export default class AchvBar extends Phaser.GameObjects.Container {
const tier = achv.getTier();
this.bg.setTexture(`achv_bar${tier ? `_${tier + 1}` : ''}`);
this.icon.setFrame(achv.iconImage);
this.titleText.setText(achv.name);
this.icon.setFrame(achv.getIconImage());
this.titleText.setText(achv.getName());
this.descriptionText.setText(achv.description);
this.scoreText.setText(`+${achv.score}pt`);
if (achv instanceof Achv)
this.scoreText.setText(`+${(achv as Achv).score}pt`);
(this.scene as BattleScene).playSound('achv');
+2 -2
View File
@@ -127,10 +127,10 @@ export default class CommandUiHandler extends UiHandler {
if (!this.cursorObj) {
this.cursorObj = this.scene.add.image(0, 0, 'cursor');
ui.add(this.cursorObj);
this.commandsContainer.add(this.cursorObj);
}
this.cursorObj.setPosition(211 + (cursor % 2 === 1 ? 56 : 0), -31 + (cursor >= 2 ? 16 : 0));
this.cursorObj.setPosition(-5 + (cursor % 2 === 1 ? 56 : 0), 8 + (cursor >= 2 ? 16 : 0));
return changed;
}
+600
View File
@@ -0,0 +1,600 @@
import BattleScene, { Button } from "../battle-scene";
import { Mode } from "./ui";
import { TextStyle, addTextObject, getModifierTierTextTint } from "./text";
import MessageUiHandler from "./message-ui-handler";
import * as Utils from "../utils";
import { ModifierTier } from "../modifier/modifier-type";
import { EGG_SEED, Egg, GachaType, getEggTierDefaultHatchWaves, getEggDescriptor, getLegendaryGachaSpeciesForTimestamp, getTypeGachaTypeForTimestamp } from "../data/egg";
import { VoucherType, getVoucherTypeIcon } from "../system/voucher";
import { getPokemonSpecies } from "../data/pokemon-species";
import { Type } from "../data/type";
const defaultText = 'Select a machine.';
export default class EggGachaUiHandler extends MessageUiHandler {
private eggGachaContainer: Phaser.GameObjects.Container;
private eggGachaMessageBox: Phaser.GameObjects.NineSlice;
private eggGachaOptionsContainer: Phaser.GameObjects.Container;
private eggGachaOptionSelectBg: Phaser.GameObjects.NineSlice;
private gachaContainers: Phaser.GameObjects.Container[];
private gachaKnobs: Phaser.GameObjects.Sprite[];
private gachaHatches: Phaser.GameObjects.Sprite[];
private gachaInfoContainers: Phaser.GameObjects.Container[];
private eggGachaOverlay: Phaser.GameObjects.Rectangle;
private eggGachaSummaryContainer: Phaser.GameObjects.Container;
private voucherCountLabels: Phaser.GameObjects.Text[];
private gachaCursor: integer;
private cursorObj: Phaser.GameObjects.Image;
private transitioning: boolean;
private transitionCancelled: boolean;
constructor(scene: BattleScene) {
super(scene, Mode.EGG_GACHA);
this.gachaContainers = [];
this.gachaKnobs = [];
this.gachaHatches = [];
this.gachaInfoContainers = [];
this.voucherCountLabels = [];
}
setup() {
this.gachaCursor = 0;
const ui = this.getUi();
this.eggGachaContainer = this.scene.add.container(0, -this.scene.game.canvas.height / 6);
this.eggGachaContainer.setVisible(false);
ui.add(this.eggGachaContainer);
const bg = this.scene.add.nineslice(0, 0, 'default_bg', null, 320, 180, 0, 0, 16, 0);
bg.setOrigin(0, 0);
this.eggGachaContainer.add(bg);
const hatchFrameNames = this.scene.anims.generateFrameNames('gacha_hatch', { suffix: ".png", start: 1, end: 4 });
this.scene.anims.create({
key: 'open',
frames: hatchFrameNames,
frameRate: 12
});
this.scene.anims.create({
key: 'close',
frames: hatchFrameNames.reverse(),
frameRate: 12
});
Utils.getEnumValues(GachaType).forEach((gachaType, g) => {
const gachaTypeKey = GachaType[gachaType].toString().toLowerCase();
const gachaContainer = this.scene.add.container(180 * g, 18);
const gacha = this.scene.add.sprite(0, 0, `gacha_${gachaTypeKey}`);
gacha.setOrigin(0, 0);
const gachaUnderlay = this.scene.add.sprite(115, 80, `gacha_underlay_${gachaTypeKey}`);
gachaUnderlay.setOrigin(0, 0);
const gachaGlass = this.scene.add.sprite(0, 0, 'gacha_glass');
gachaGlass.setOrigin(0, 0);
const gachaInfoContainer = this.scene.add.container(160, 46);
const gachaUpLabel = addTextObject(this.scene, 4, 0, 'UP!', TextStyle.WINDOW);
gachaUpLabel.setOrigin(0, 0);
gachaInfoContainer.add(gachaUpLabel);
switch (gachaType as GachaType) {
case GachaType.LEGENDARY:
const pokemonIcon = this.scene.add.sprite(-20, 6, 'pokemon_icons_0');
pokemonIcon.setScale(0.5);
pokemonIcon.setOrigin(0, 0.5);
gachaInfoContainer.add(pokemonIcon);
break;
case GachaType.TYPE:
const typeIcon = this.scene.add.sprite(-22, 7, 'types', 'unknown');
typeIcon.setScale(0.75);
typeIcon.setOrigin(0, 0.5);
gachaUpLabel.x += 4;
gachaInfoContainer.add(typeIcon);
break;
case GachaType.SHINY:
gachaUpLabel.setText('Shiny UP!');
gachaUpLabel.setX(0);
gachaUpLabel.setOrigin(0.5, 0);
break;
}
const gachaKnob = this.scene.add.sprite(191, 89, 'gacha_knob');
const gachaHatch = this.scene.add.sprite(115, 73, 'gacha_hatch');
gachaHatch.setOrigin(0, 0);
gachaContainer.add(gachaUnderlay);
gachaContainer.add(gacha);
gachaContainer.add(gachaGlass);
gachaContainer.add(gachaKnob);
gachaContainer.add(gachaHatch);
gachaContainer.add(gachaInfoContainer);
gachaGlass.setAlpha(0.5);
gachaHatch.setAlpha(0.9);
gachaHatch.on('animationupdate', (_anim, frame) => gachaUnderlay.setFrame(frame.textureFrame === '4.png' ? 'open_hatch' : 'default'));
this.gachaContainers.push(gachaContainer);
this.gachaKnobs.push(gachaKnob);
this.gachaHatches.push(gachaHatch);
this.gachaInfoContainers.push(gachaInfoContainer);
this.eggGachaContainer.add(gachaContainer);
this.updateGachaInfo(g);
});
this.eggGachaOptionsContainer = this.scene.add.container()
this.eggGachaOptionsContainer = this.scene.add.container((this.scene.game.canvas.width / 6), 148);
this.eggGachaContainer.add(this.eggGachaOptionsContainer);
this.eggGachaOptionSelectBg = this.scene.add.nineslice(0, 0, 'window', null, 96, 96, 6, 6, 6, 6);
this.eggGachaOptionSelectBg.setOrigin(1, 1);
this.eggGachaOptionsContainer.add(this.eggGachaOptionSelectBg);
const optionText = addTextObject(this.scene, 0, 0, ' x1 1 Pull\n x10 10 Pulls\n x1 5 Pulls\n x1 10 Pulls\nCancel', TextStyle.WINDOW, { maxLines: 5 });
optionText.setLineSpacing(12);
this.eggGachaOptionsContainer.add(optionText);
optionText.setPositionRelative(this.eggGachaOptionSelectBg, 16, 9);
new Array(4).fill(null).map((_, i) => {
const voucherType = i < 2 ? VoucherType.REGULAR : i === 2 ? VoucherType.PLUS : VoucherType.PREMIUM;
const icon = this.scene.add.sprite(0, 0, 'items', getVoucherTypeIcon(voucherType));
icon.setScale(0.5);
icon.setPositionRelative(this.eggGachaOptionSelectBg, 20, 17 + i * 16);
this.eggGachaOptionsContainer.add(icon);
});
this.eggGachaContainer.add(this.eggGachaOptionsContainer);
new Array(Utils.getEnumKeys(VoucherType).length).fill(null).map((_, i) => {
const container = this.scene.add.container((this.scene.game.canvas.width / 6) - 56 * i, 0);
const bg = this.scene.add.nineslice(0, 0, 'window', null, 56, 22, 6, 6, 6, 6);
bg.setOrigin(1, 0);
container.add(bg);
const countLabel = addTextObject(this.scene, -48, 3, '0', TextStyle.WINDOW);
countLabel.setOrigin(0, 0);
container.add(countLabel);
this.voucherCountLabels.push(countLabel);
const iconImage = getVoucherTypeIcon(i as VoucherType);
const icon = this.scene.add.sprite(-19, 2, 'items', iconImage);
icon.setOrigin(0, 0);
icon.setScale(0.5);
container.add(icon);
this.eggGachaContainer.add(container);
});
this.eggGachaOverlay = this.scene.add.rectangle(0, 0, bg.displayWidth, bg.displayHeight, 0x000000);
this.eggGachaOverlay.setOrigin(0, 0);
this.eggGachaOverlay.setAlpha(0);
this.eggGachaContainer.add(this.eggGachaOverlay);
this.eggGachaSummaryContainer = this.scene.add.container(0, 0);
this.eggGachaSummaryContainer.setVisible(false);
this.eggGachaContainer.add(this.eggGachaSummaryContainer);
const gachaMessageBoxContainer = this.scene.add.container(0, 148);
this.eggGachaContainer.add(gachaMessageBoxContainer);
const gachaMessageBox = this.scene.add.nineslice(0, 0, 'window', null, 320, 32, 6, 6, 6, 6);
gachaMessageBox.setOrigin(0, 0);
gachaMessageBoxContainer.add(gachaMessageBox);
this.eggGachaMessageBox = gachaMessageBox;
const gachaMessageText = addTextObject(this.scene, 8, 8, '', TextStyle.WINDOW, { maxLines: 2 });
gachaMessageText.setOrigin(0, 0);
gachaMessageBoxContainer.add(gachaMessageText);
this.message = gachaMessageText;
this.eggGachaContainer.add(gachaMessageBoxContainer);
this.setCursor(0);
}
show(args: any[]): void {
super.show(args);
this.getUi().showText(defaultText, 0);
this.setGachaCursor(1);
for (let g = 0; g < this.gachaContainers.length; g++)
this.updateGachaInfo(g);
this.updateVoucherCounts();
this.eggGachaContainer.setVisible(true);
}
getDelayValue(delay: integer) {
if (this.transitioning && this.transitionCancelled)
delay = Math.ceil(delay / 5);
return Utils.fixedInt(delay);
}
pull(pullCount?: integer, count?: integer, eggs?: Egg[]) {
this.eggGachaOptionsContainer.setVisible(false);
this.setTransitioning(true);
if (!pullCount)
pullCount = 1;
if (!count)
count = 0;
if (!eggs) {
eggs = [];
const tiers = new Array(pullCount).fill(null).map(() => {
const tierValue = Utils.randInt(256);
return tierValue >= 52 ? ModifierTier.COMMON : tierValue >= 8 ? ModifierTier.GREAT : tierValue >= 1 ? ModifierTier.ULTRA : ModifierTier.MASTER;
});
/*if (pullCount >= 100 && !tiers.filter(t => t >= ModifierTier.ULTRA).length)
tiers[Utils.randInt(tiers.length)] = ModifierTier.ULTRA;*/
if (pullCount >= 10 && !tiers.filter(t => t >= ModifierTier.GREAT).length)
tiers[Utils.randInt(tiers.length)] = ModifierTier.GREAT;
const timestamp = new Date().getTime();
for (let tier of tiers) {
const egg = new Egg(Utils.randInt(EGG_SEED, EGG_SEED * tier), this.gachaCursor, getEggTierDefaultHatchWaves(tier), timestamp);
if (egg.isManaphyEgg())
egg.hatchWaves = getEggTierDefaultHatchWaves(ModifierTier.ULTRA);
eggs.push(egg);
this.scene.gameData.eggs.push(egg);
}
this.scene.gameData.saveSystem();
}
if (this.transitionCancelled) {
return this.showSummary(eggs);
}
const egg = this.scene.add.sprite(127, 75, 'egg', `egg_${eggs[count].getKey()}`);
egg.setScale(0.5);
this.gachaContainers[this.gachaCursor].add(egg);
this.gachaContainers[this.gachaCursor].moveTo(egg, 1);
const doPullAnim = () => {
this.scene.playSound('gacha_running', { loop: true });
this.scene.time.delayedCall(this.getDelayValue(count ? 500 : 1250), () => {
this.scene.playSound('gacha_dispense');
this.scene.time.delayedCall(this.getDelayValue(750), () => {
this.scene.sound.stopByKey('gacha_running');
this.scene.tweens.add({
targets: egg,
duration: this.getDelayValue(350),
y: 95,
ease: 'Bounce.easeOut',
onComplete: () => {
this.scene.time.delayedCall(this.getDelayValue(125), () => {
this.scene.playSound('pb_catch');
this.gachaHatches[this.gachaCursor].play('open');
this.scene.tweens.add({
targets: egg,
duration: this.getDelayValue(350),
scale: 0.75,
ease: 'Sine.easeIn'
});
this.scene.tweens.add({
targets: egg,
y: 110,
duration: this.getDelayValue(350),
ease: 'Back.easeOut',
onComplete: () => {
this.gachaHatches[this.gachaCursor].play('close');
this.scene.tweens.add({
targets: egg,
y: 200,
duration: this.getDelayValue(350),
ease: 'Cubic.easeIn',
onComplete: () => {
if (++count < pullCount)
this.pull(pullCount, count, eggs);
else
this.showSummary(eggs);
}
});
}
});
});
}
});
});
});
};
if (!count) {
this.scene.playSound('gacha_dial');
this.scene.tweens.add({
targets: this.gachaKnobs[this.gachaCursor],
duration: this.getDelayValue(350),
angle: 90,
ease: 'Cubic.easeInOut',
onComplete: () => {
this.scene.tweens.add({
targets: this.gachaKnobs[this.gachaCursor],
duration: this.getDelayValue(350),
angle: 0,
ease: 'Sine.easeInOut'
});
this.scene.time.delayedCall(this.getDelayValue(350), doPullAnim);
}
});
} else
doPullAnim();
}
showSummary(eggs: Egg[]): void {
this.transitioning = false;
this.eggGachaSummaryContainer.setVisible(true);
this.scene.tweens.add({
targets: this.eggGachaOverlay,
alpha: 0.5,
ease: 'Sine.easeOut',
duration: 750,
onComplete: () => {
const rows = Math.ceil(eggs.length / 5);
const cols = Math.min(eggs.length, 5);
const height = this.eggGachaOverlay.displayHeight - this.eggGachaMessageBox.displayHeight;
const eggContainers = eggs.map((egg, t) => {
const col = t % 5;
const row = Math.floor(t / 5);
const sliceWidth = this.eggGachaOverlay.displayWidth / (cols + 2);
const sliceHeight = height / (rows + 2);
const yOffset = (sliceHeight / 2 * (row / Math.max(rows - 1, 1))) + sliceHeight / 4;
const ret = this.scene.add.container(sliceWidth * (col + 1) + (sliceWidth * 0.5), sliceHeight * (row + 1) + yOffset);
ret.setScale(0.0001);
const eggSprite = this.scene.add.sprite(0, 0, 'egg', `egg_${egg.getKey()}`);
ret.add(eggSprite);
const eggText = addTextObject(this.scene, 0, 14, getEggDescriptor(egg), TextStyle.PARTY, { align: 'center' });
eggText.setOrigin(0.5, 0);
eggText.setTint(getModifierTierTextTint(!egg.isManaphyEgg() ? egg.tier : ModifierTier.ULTRA));
ret.add(eggText);
this.eggGachaSummaryContainer.add(ret);
return ret;
});
eggContainers.forEach((eggContainer, e) => {
this.scene.tweens.add({
targets: eggContainer,
delay: this.getDelayValue(e * 100),
duration: this.getDelayValue(350),
scale: 1,
ease: 'Sine.easeOut'
});
});
}
});
}
hideSummary() {
this.setTransitioning(true);
this.scene.tweens.add({
targets: [ this.eggGachaOverlay, this.eggGachaSummaryContainer ],
alpha: 0,
duration: this.getDelayValue(250),
ease: 'Cubic.easeIn',
onComplete: () => {
this.eggGachaSummaryContainer.setVisible(false);
this.eggGachaSummaryContainer.setAlpha(1);
this.eggGachaSummaryContainer.removeAll(true);
this.setTransitioning(false);
this.eggGachaOptionsContainer.setVisible(true);
}
});
}
updateGachaInfo(gachaType: GachaType): void {
const infoContainer = this.gachaInfoContainers[gachaType];
switch (gachaType as GachaType) {
case GachaType.LEGENDARY:
const species = getPokemonSpecies(getLegendaryGachaSpeciesForTimestamp(this.scene, new Date().getTime()));
const pokemonIcon = infoContainer.getAt(1) as Phaser.GameObjects.Sprite;
pokemonIcon.setTexture(species.getIconAtlasKey(), species.getIconId(false));
break;
case GachaType.TYPE:
const typeIcon = infoContainer.getAt(1) as Phaser.GameObjects.Sprite;
typeIcon.setFrame(Type[getTypeGachaTypeForTimestamp(this.scene, new Date().getTime())].toLowerCase());
break;
}
}
consumeVouchers(voucherType: VoucherType, count: integer): void {
this.scene.gameData.voucherCounts[voucherType] = Math.max(this.scene.gameData.voucherCounts[voucherType] - count, 0);
this.updateVoucherCounts();
}
updateVoucherCounts(): void {
this.voucherCountLabels.forEach((label, type) => {
label.setText(this.scene.gameData.voucherCounts[type].toString());
});
}
showError(text: string): void {
this.showText(text, null, () => this.showText(defaultText), Utils.fixedInt(1500));
}
setTransitioning(transitioning: boolean): void {
if (this.transitioning === transitioning)
return;
this.transitioning = transitioning;
this.transitionCancelled = false;
}
processInput(button: Button): boolean {
const ui = this.getUi();
let success = false;
let error = false;
if (this.transitioning) {
if (!this.transitionCancelled && (button === Button.ACTION || button === Button.CANCEL)) {
this.transitionCancelled = true;
success = true;
} else
return false;
} else {
if (this.eggGachaSummaryContainer.visible) {
if (button === Button.ACTION || button === Button.CANCEL) {
this.hideSummary();
success = true;
}
} else {
switch (button) {
case Button.ACTION:
switch (this.cursor) {
case 0:
if (!this.scene.gameData.voucherCounts[VoucherType.REGULAR]) {
error = true;
this.showError('You don\'t have enough vouchers!');
} else if (this.scene.gameData.eggs.length < 99) {
this.consumeVouchers(VoucherType.REGULAR, 1);
this.pull();
success = true;
} else {
error = true;
this.showError('You have too many eggs!');
}
break;
case 2:
if (!this.scene.gameData.voucherCounts[VoucherType.PLUS]) {
error = true;
this.showError('You don\'t have enough vouchers!');
} else if (this.scene.gameData.eggs.length < 95) {
this.consumeVouchers(VoucherType.PLUS, 1);
this.pull(5);
success = true;
} else {
error = true;
this.showError('You have too many eggs!');
}
break;
case 1:
case 3:
if ((this.cursor === 1 && this.scene.gameData.voucherCounts[VoucherType.REGULAR] < 10)
|| (this.cursor === 3 && !this.scene.gameData.voucherCounts[VoucherType.PREMIUM])) {
error = true;
this.showError('You don\'t have enough vouchers!');
} else if (this.scene.gameData.eggs.length < 90) {
if (this.cursor === 3)
this.consumeVouchers(VoucherType.PREMIUM, 1);
else
this.consumeVouchers(VoucherType.REGULAR, 10);
this.pull(10);
success = true;
} else {
error = true;
this.showError('You have too many eggs!');
}
break;
case 4:
ui.revertMode();
success = true;
break;
}
break;
case Button.CANCEL:
this.getUi().revertMode();
success = true;
break;
case Button.UP:
if (this.cursor)
success = this.setCursor(this.cursor - 1);
break;
case Button.DOWN:
if (this.cursor < 4)
success = this.setCursor(this.cursor + 1);
break;
case Button.LEFT:
if (this.gachaCursor)
success = this.setGachaCursor(this.gachaCursor - 1);
break;
case Button.RIGHT:
if (this.gachaCursor < Utils.getEnumKeys(GachaType).length - 1)
success = this.setGachaCursor(this.gachaCursor + 1);
break;
}
}
}
if (success)
ui.playSelect();
else if (error)
ui.playError();
return success || error;
}
setCursor(cursor: integer): boolean {
const ret = super.setCursor(cursor);
if (!this.cursorObj) {
this.cursorObj = this.scene.add.image(0, 0, 'cursor');
this.eggGachaOptionsContainer.add(this.cursorObj);
}
this.cursorObj.setPositionRelative(this.eggGachaOptionSelectBg, 10, 17 + this.cursor * 16);
return ret;
}
setGachaCursor(cursor: integer): boolean {
let oldCursor = this.gachaCursor;
let changed = oldCursor !== cursor;
if (changed) {
this.gachaCursor = cursor;
this.setTransitioning(true);
this.scene.tweens.add({
targets: this.gachaContainers,
duration: this.eggGachaContainer.visible ? 500 : 0,
x: (_target, _key, _value, index) => 180 * (index - cursor),
ease: 'Cubic.easeInOut',
onComplete: () => this.setTransitioning(false)
});
}
return changed;
}
clear(): void {
super.clear();
this.setGachaCursor(-1);
this.eggGachaContainer.setVisible(false);
}
}
+33 -32
View File
@@ -3,39 +3,40 @@ import { Mode } from "./ui";
import UiHandler from "./uiHandler";
export default class EggHatchSceneHandler extends UiHandler {
public eggHatchContainer: Phaser.GameObjects.Container;
public eggHatchContainer: Phaser.GameObjects.Container;
constructor(scene: BattleScene) {
super(scene, Mode.EGG_HATCH_SCENE);
}
setup() {
this.eggHatchContainer = this.scene.add.container(0, -this.scene.game.canvas.height / 6);
this.scene.fieldUI.add(this.eggHatchContainer);
constructor(scene: BattleScene) {
super(scene, Mode.EGG_HATCH_SCENE);
}
const eggLightraysAnimFrames = this.scene.anims.generateFrameNames('egg_lightrays', { start: 0, end: 3 });
this.scene.anims.create({
key: 'egg_lightrays',
frames: eggLightraysAnimFrames,
frameRate: 32
});
}
setup() {
this.eggHatchContainer = this.scene.add.container(0, -this.scene.game.canvas.height / 6);
this.scene.fieldUI.add(this.eggHatchContainer);
show(_args: any[]): void {
super.show(_args);
this.scene.fieldUI.bringToTop(this.eggHatchContainer);
}
processInput(button: Button): boolean {
return this.scene.ui.getMessageHandler().processInput(button);
}
setCursor(_cursor: integer): boolean {
return false;
}
const eggLightraysAnimFrames = this.scene.anims.generateFrameNames('egg_lightrays', { start: 0, end: 3 });
this.scene.anims.create({
key: 'egg_lightrays',
frames: eggLightraysAnimFrames,
frameRate: 32
});
}
clear() {
this.eggHatchContainer.removeAll(true);
}
}
show(_args: any[]): void {
super.show(_args);
this.getUi().showText(null, 0);
}
processInput(button: Button): boolean {
return this.scene.ui.getMessageHandler().processInput(button);
}
setCursor(_cursor: integer): boolean {
return false;
}
clear() {
super.clear();
this.eggHatchContainer.removeAll(true);
}
}
+201
View File
@@ -0,0 +1,201 @@
import BattleScene, { Button } from "../battle-scene";
import { Mode } from "./ui";
import PokemonIconAnimHandler, { PokemonIconAnimMode } from "./pokemon-icon-anim-handler";
import { TextStyle, addTextObject } from "./text";
import MessageUiHandler from "./message-ui-handler";
import { EGG_SEED, Egg, GachaType, getEggGachaTypeDescriptor, getEggHatchWavesMessage, getEggDescriptor } from "../data/egg";
import * as Utils from "../utils";
export default class EggListUiHandler extends MessageUiHandler {
private eggListContainer: Phaser.GameObjects.Container;
private eggListIconContainer: Phaser.GameObjects.Container;
private eggSprite: Phaser.GameObjects.Sprite;
private eggNameText: Phaser.GameObjects.Text;
private eggDateText: Phaser.GameObjects.Text;
private eggHatchWavesText: Phaser.GameObjects.Text;
private eggGachaInfoText: Phaser.GameObjects.Text;
private eggListMessageBoxContainer: Phaser.GameObjects.Container;
private cursorObj: Phaser.GameObjects.Image;
private iconAnimHandler: PokemonIconAnimHandler;
constructor(scene: BattleScene) {
super(scene, Mode.EGG_LIST);
}
setup() {
const ui = this.getUi();
this.eggListContainer = this.scene.add.container(0, -this.scene.game.canvas.height / 6);
this.eggListContainer.setVisible(false);
ui.add(this.eggListContainer);
const bgColor = this.scene.add.rectangle(0, 0, this.scene.game.canvas.width / 6, this.scene.game.canvas.height / 6, 0x006860);
bgColor.setOrigin(0, 0);
this.eggListContainer.add(bgColor);
const starterSelectBg = this.scene.add.image(1, 1, 'egg_list_bg');
starterSelectBg.setOrigin(0, 0);
this.eggListContainer.add(starterSelectBg);
this.iconAnimHandler = new PokemonIconAnimHandler();
this.iconAnimHandler.setup(this.scene);
this.eggNameText = addTextObject(this.scene, 6, 66, '', TextStyle.SUMMARY);
this.eggNameText.setOrigin(0, 0);
this.eggListContainer.add(this.eggNameText);
this.eggDateText = addTextObject(this.scene, 8, 91, '', TextStyle.TOOLTIP_CONTENT);
this.eggListContainer.add(this.eggDateText);
this.eggHatchWavesText = addTextObject(this.scene, 8, 108, '', TextStyle.TOOLTIP_CONTENT);
this.eggHatchWavesText.setWordWrapWidth(540);
this.eggListContainer.add(this.eggHatchWavesText);
this.eggGachaInfoText = addTextObject(this.scene, 8, 152, '', TextStyle.TOOLTIP_CONTENT);
this.eggGachaInfoText.setWordWrapWidth(540);
this.eggListContainer.add(this.eggGachaInfoText);
this.eggListIconContainer = this.scene.add.container(115, 9);
this.eggListContainer.add(this.eggListIconContainer);
this.cursorObj = this.scene.add.image(0, 0, 'starter_select_cursor');
this.cursorObj.setOrigin(0, 0);
this.eggListContainer.add(this.cursorObj);
this.eggSprite = this.scene.add.sprite(54, 37, `egg`);
this.eggListContainer.add(this.eggSprite);
this.eggListMessageBoxContainer = this.scene.add.container(0, this.scene.game.canvas.height / 6);
this.eggListMessageBoxContainer.setVisible(false);
this.eggListContainer.add(this.eggListMessageBoxContainer);
const starterSelectMessageBox = this.scene.add.image(0, 0, 'starter_select_message');
starterSelectMessageBox.setOrigin(0, 1);
this.eggListMessageBoxContainer.add(starterSelectMessageBox);
this.message = addTextObject(this.scene, 8, -8, '', TextStyle.WINDOW, { maxLines: 1 });
this.message.setOrigin(0, 1);
this.eggListMessageBoxContainer.add(this.message);
this.cursor = -1;
}
show(args: any[]): void {
super.show(args);
this.eggListContainer.setVisible(true);
let e = 0;
/*this.scene.gameData.eggs = [
new Egg(1, 1, 5, new Date().getTime()),
new Egg(1 + EGG_SEED, 1, 15, new Date().getTime()),
new Egg(1 + EGG_SEED * 2, 1, 50, new Date().getTime()),
new Egg(1 + EGG_SEED * 3, GachaType.LEGENDARY, 100, new Date().getTime())
];*/
for (let egg of this.scene.gameData.eggs) {
const x = (e % 11) * 18;
const y = Math.floor(e / 11) * 18;
const icon = this.scene.add.sprite(x - 2, y + 2, 'egg_icons');
icon.setScale(0.5);
icon.setOrigin(0, 0);
icon.setFrame(egg.getKey());
this.eggListIconContainer.add(icon);
this.iconAnimHandler.addOrUpdate(icon, PokemonIconAnimMode.NONE);
e++;
}
this.setCursor(0);
}
showText(text: string, delay?: integer, callback?: Function, callbackDelay?: integer, prompt?: boolean, promptDelay?: integer) {
super.showText(text, delay, callback, callbackDelay, prompt, promptDelay);
}
processInput(button: Button): boolean {
const ui = this.getUi();
let success = false;
let error = false;
if (button === Button.CANCEL) {
ui.revertMode();
success = true;
} else {
const eggCount = this.eggListIconContainer.getAll().length;
const rows = Math.ceil(eggCount / 11);
const row = Math.floor(this.cursor / 11);
switch (button) {
case Button.UP:
if (row)
success = this.setCursor(this.cursor - 11);
break;
case Button.DOWN:
if (row < rows - 2 || (row < rows - 1 && this.cursor % 11 <= (eggCount - 1) % 11))
success = this.setCursor(this.cursor + 11);
break;
case Button.LEFT:
if (this.cursor % 11)
success = this.setCursor(this.cursor - 1);
break;
case Button.RIGHT:
if (this.cursor % 11 < (row < rows - 1 ? 10 : (eggCount - 1) % 11))
success = this.setCursor(this.cursor + 1);
break;
}
}
if (success)
ui.playSelect();
else if (error)
ui.playError();
return success || error;
}
setEggDetails(egg: Egg): void {
this.eggSprite.setFrame(`egg_${egg.getKey()}`);
this.eggNameText.setText(`Egg (${getEggDescriptor(egg)})`);
this.eggDateText.setText(
new Date(egg.timestamp).toLocaleString(undefined, {
weekday: 'short',
year: 'numeric',
month: '2-digit',
day: 'numeric'
})
);
this.eggHatchWavesText.setText(getEggHatchWavesMessage(egg.hatchWaves));
this.eggGachaInfoText.setText(getEggGachaTypeDescriptor(this.scene, egg));
}
setCursor(cursor: integer): boolean {
let changed = false;
let lastCursor = this.cursor;
changed = super.setCursor(cursor);
if (changed) {
this.cursorObj.setPosition(114 + 18 * (cursor % 11), 10 + 18 * Math.floor(cursor / 11));
if (lastCursor > -1)
this.iconAnimHandler.addOrUpdate(this.eggListIconContainer.getAt(lastCursor) as Phaser.GameObjects.Sprite, PokemonIconAnimMode.NONE);
this.iconAnimHandler.addOrUpdate(this.eggListIconContainer.getAt(cursor) as Phaser.GameObjects.Sprite, PokemonIconAnimMode.ACTIVE);
this.setEggDetails(this.scene.gameData.eggs[cursor]);
}
return changed;
}
clear(): void {
super.clear();
this.cursor = -1;
this.eggListContainer.setVisible(false);
this.iconAnimHandler.removeAll();
this.eggListIconContainer.removeAll(true);
}
}
+25 -1
View File
@@ -6,7 +6,10 @@ import * as Utils from "../utils";
export enum MenuOptions {
SETTINGS,
ACHIEVEMENTS
ACHIEVEMENTS,
VOUCHERS,
EGG_LIST,
EGG_GACHA
}
export default class MenuUiHandler extends UiHandler {
@@ -62,6 +65,7 @@ export default class MenuUiHandler extends UiHandler {
const ui = this.getUi();
let success = false;
let error = false;
if (button === Button.ACTION) {
switch (this.cursor as MenuOptions) {
@@ -73,6 +77,24 @@ export default class MenuUiHandler extends UiHandler {
this.scene.ui.setOverlayMode(Mode.ACHIEVEMENTS);
success = true;
break;
case MenuOptions.VOUCHERS:
this.scene.ui.setOverlayMode(Mode.VOUCHERS);
success = true;
break;
case MenuOptions.EGG_LIST:
if (this.scene.gameData.eggs.length) {
this.scene.ui.revertMode();
this.scene.ui.setOverlayMode(Mode.EGG_LIST);
success = true;
} else
error = true;
break;
case MenuOptions.EGG_GACHA:
this.scene.ui.revertMode();
this.scene.ui.setOverlayMode(Mode.EGG_GACHA);
success = true;
break;
}
} else if (button === Button.CANCEL) {
success = true;
@@ -93,6 +115,8 @@ export default class MenuUiHandler extends UiHandler {
if (success)
ui.playSelect();
else if (error)
ui.playError();
return true;
}
+9 -2
View File
@@ -8,7 +8,6 @@ export enum PokemonIconAnimMode {
}
export default class PokemonIconAnimHandler {
private counter: Phaser.Tweens.Tween;
private icons: Map<Phaser.GameObjects.Sprite, PokemonIconAnimMode>;
private toggled: boolean;
@@ -22,7 +21,7 @@ export default class PokemonIconAnimHandler {
for (let i of this.icons.keys())
i.y += this.getModeYDelta(this.icons.get(i)) * (this.toggled ? 1 : -1);
};
this.counter = scene.tweens.addCounter({
scene.tweens.addCounter({
duration: Utils.fixedInt(200),
from: 0,
to: 1,
@@ -70,4 +69,12 @@ export default class PokemonIconAnimHandler {
this.icons.delete(i);
}
}
removeAll(): void {
for (let i of this.icons.keys()) {
if (this.toggled)
i.y -= this.getModeYDelta(this.icons.get(i));
this.icons.delete(i);
}
}
}
File diff suppressed because it is too large. Load diff
+20 -6
View File
@@ -1,19 +1,24 @@
import BBCodeText from "phaser3-rex-plugins/plugins/gameobjects/tagtext/bbcodetext/BBCodeText";
import BattleScene from "../battle-scene";
import { Stat, getStatName } from "../data/pokemon-stat";
import { TextStyle, addTextObject } from "./text";
import { TextStyle, addBBCodeTextObject, addTextObject, getTextColor } from "./text";
import { Gender, getGenderColor } from "../data/gender";
const ivChartSize = 24;
const ivChartStatCoordMultipliers = [ [ 0, 1 ], [ 0.825, 0.5 ], [ 0.825, -0.5 ], [ 0, -1 ], [ -0.825, -0.5 ], [ -0.825, 0.5 ] ];
const defaultIvChartData = new Array(12).fill(null).map(() => 0);
export class StatsContainer extends Phaser.GameObjects.Container {
private showDiff: boolean;
private statsIvsCache: integer[];
private ivChart: Phaser.GameObjects.Polygon;
private ivStatValueTexts: Phaser.GameObjects.Text[];
private ivStatValueTexts: BBCodeText[];
constructor(scene: BattleScene, x: number, y: number) {
constructor(scene: BattleScene, x: number, y: number, showDiff?: boolean) {
super(scene, x, y);
this.showDiff = !!showDiff;
this.setup();
}
@@ -48,7 +53,7 @@ export class StatsContainer extends Phaser.GameObjects.Container {
const statLabel = addTextObject(this.scene, ivChartBg.x + (ivChartSize) * ivChartStatCoordMultipliers[i][0] * 1.325, ivChartBg.y + (ivChartSize) * ivChartStatCoordMultipliers[i][1] * 1.325 - 4, getStatName(i as Stat), TextStyle.TOOLTIP_CONTENT);
statLabel.setOrigin(0.5);
this.ivStatValueTexts[i] = addTextObject(this.scene, statLabel.x, statLabel.y + 8, '0', TextStyle.TOOLTIP_CONTENT);
this.ivStatValueTexts[i] = addBBCodeTextObject(this.scene, statLabel.x, statLabel.y + 8, '0', TextStyle.TOOLTIP_CONTENT);
this.ivStatValueTexts[i].setOrigin(0.5)
this.add(statLabel);
@@ -56,13 +61,22 @@ export class StatsContainer extends Phaser.GameObjects.Container {
});
}
updateIvs(ivs: integer[]): void {
updateIvs(ivs: integer[], originalIvs?: integer[]): void {
if (ivs) {
const ivChartData = new Array(6).fill(null).map((_, i) => [ (ivs[i] / 31) * ivChartSize * ivChartStatCoordMultipliers[i][0], (ivs[i] / 31) * ivChartSize * ivChartStatCoordMultipliers[i][1] ] ).flat();
const lastIvChartData = this.statsIvsCache || defaultIvChartData;
this.statsIvsCache = ivChartData.slice(0);
this.ivStatValueTexts.map((t: Phaser.GameObjects.Text, i: integer) => t.setText(ivs[i].toString()));
this.ivStatValueTexts.map((t: BBCodeText, i: integer) => {
let label = ivs[i].toString();
if (this.showDiff && originalIvs) {
if (originalIvs[i] < ivs[i])
label += ` ([color=${getGenderColor(Gender.MALE)}]+${ivs[i] - originalIvs[i]}[/color])`;
else
label += ' (-)';
}
t.setText(`[shadow]${label}[/shadow]`);
});
this.scene.tweens.addCounter({
from: 0,
+30 -9
View File
@@ -1,3 +1,5 @@
import BBCodeText from "phaser3-rex-plugins/plugins/gameobjects/tagtext/bbcodetext/BBCodeText";
export enum TextStyle {
MESSAGE,
WINDOW,
@@ -14,7 +16,32 @@ export enum TextStyle {
TOOLTIP_CONTENT
};
export function addTextObject(scene: Phaser.Scene, x: number, y: number, content: string, style: TextStyle, extraStyleOptions?: Phaser.Types.GameObjects.Text.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 [ styleOptions, shadowColor, shadowSize ] = getTextStyleOptions(style, extraStyleOptions);
const ret = scene.add.text(x, y, content, styleOptions);
ret.setScale(0.1666666667);
ret.setShadow(shadowSize, shadowSize, shadowColor);
if (!styleOptions.lineSpacing)
ret.setLineSpacing(5);
return ret;
}
export function addBBCodeTextObject(scene: Phaser.Scene, x: number, y: number, content: string, style: TextStyle, extraStyleOptions?: Phaser.Types.GameObjects.Text.TextStyle): BBCodeText {
const [ styleOptions, shadowColor, shadowSize ] = getTextStyleOptions(style, extraStyleOptions);
const ret = new BBCodeText(scene, x, y, content, styleOptions as BBCodeText.TextStyle);
scene.add.existing(ret);
ret.setScale(0.1666666667);
ret.setShadow(shadowSize, shadowSize, shadowColor);
if (!styleOptions.lineSpacing)
ret.setLineSpacing(5);
return ret;
}
function getTextStyleOptions(style: TextStyle, extraStyleOptions?: Phaser.Types.GameObjects.Text.TextStyle): [ Phaser.Types.GameObjects.Text.TextStyle, string, integer ] {
let shadowColor: string;
let shadowSize = 6;
@@ -64,16 +91,10 @@ export function addTextObject(scene: Phaser.Scene, x: number, y: number, content
styleOptions = Object.assign(styleOptions, extraStyleOptions);
}
const ret = scene.add.text(x, y, content, styleOptions);
ret.setScale(0.1666666667);
ret.setShadow(shadowSize, shadowSize, shadowColor);
if (!styleOptions.lineSpacing)
ret.setLineSpacing(5);
return ret;
return [ styleOptions, shadowColor, shadowSize ];
}
export function getTextColor(textStyle: TextStyle, shadow?: boolean) {
export function getTextColor(textStyle: TextStyle, shadow?: boolean): string {
switch (textStyle) {
case TextStyle.MESSAGE:
return !shadow ? '#f8f8f8' : '#6b5a73';
+48 -14
View File
@@ -21,6 +21,10 @@ import MenuUiHandler from './menu-ui-handler';
import AchvsUiHandler from './achvs-ui-handler';
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';
export enum Mode {
MESSAGE,
@@ -40,7 +44,10 @@ export enum Mode {
GAME_MODE_SELECT,
MENU,
SETTINGS,
ACHIEVEMENTS
ACHIEVEMENTS,
VOUCHERS,
EGG_LIST,
EGG_GACHA
};
const transitionModes = [
@@ -48,7 +55,9 @@ const transitionModes = [
Mode.SUMMARY,
Mode.STARTER_SELECT,
Mode.EVOLUTION_SCENE,
Mode.EGG_HATCH_SCENE
Mode.EGG_HATCH_SCENE,
Mode.EGG_LIST,
Mode.EGG_GACHA
];
const noTransitionModes = [
@@ -56,7 +65,9 @@ const noTransitionModes = [
Mode.OPTION_SELECT,
Mode.GAME_MODE_SELECT,
Mode.MENU,
Mode.SETTINGS
Mode.SETTINGS,
Mode.ACHIEVEMENTS,
Mode.VOUCHERS
];
export default class UI extends Phaser.GameObjects.Container {
@@ -65,6 +76,7 @@ export default class UI extends Phaser.GameObjects.Container {
private handlers: UiHandler[];
private overlay: Phaser.GameObjects.Rectangle;
public achvBar: AchvBar;
public voucherBar: VoucherBar;
private tooltipContainer: Phaser.GameObjects.Container;
private tooltipBg: Phaser.GameObjects.NineSlice;
@@ -96,7 +108,10 @@ export default class UI extends Phaser.GameObjects.Container {
new GameModeSelectUiHandler(scene),
new MenuUiHandler(scene),
new SettingsUiHandler(scene),
new AchvsUiHandler(scene)
new AchvsUiHandler(scene),
new VouchersUiHandler(scene),
new EggListUiHandler(scene),
new EggGachaUiHandler(scene)
];
}
@@ -110,7 +125,8 @@ export default class UI extends Phaser.GameObjects.Container {
this.setupTooltip();
this.achvBar = new AchvBar(this.scene as BattleScene);
this.achvBar.setup();
this.achvBar.setup();
(this.scene as BattleScene).uiContainer.add(this.achvBar);
}
@@ -267,8 +283,9 @@ export default class UI extends Phaser.GameObjects.Container {
}
resolve();
};
if ((transitionModes.indexOf(this.mode) > -1 || transitionModes.indexOf(mode) > -1)
&& (noTransitionModes.indexOf(this.mode) === -1 && noTransitionModes.indexOf(mode) === -1) && !(this.scene as BattleScene).auto) {
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();
@@ -300,12 +317,29 @@ export default class UI extends Phaser.GameObjects.Container {
return this.setModeInternal(mode, false, false, true, args);
}
revertMode(): boolean {
if (!this.modeChain.length)
return false;
this.getHandler().clear();
this.mode = this.modeChain.pop();
return true;
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();
};
if (noTransitionModes.indexOf(lastMode) === -1) {
this.fadeOut(250).then(() => {
this.scene.time.delayedCall(100, () => {
doRevertMode();
this.fadeIn(250);
});
});
} else
doRevertMode();
resolve(true);
});
}
}
+196
View File
@@ -0,0 +1,196 @@
import BattleScene, { Button } from "../battle-scene";
import { Voucher, getVoucherTypeIcon, getVoucherTypeName, vouchers } from "../system/voucher";
import MessageUiHandler from "./message-ui-handler";
import { TextStyle, addTextObject } from "./text";
import { Mode } from "./ui";
export default class VouchersUiHandler extends MessageUiHandler {
private vouchersContainer: Phaser.GameObjects.Container;
private voucherIconsContainer: Phaser.GameObjects.Container;
private voucherIconsBg: Phaser.GameObjects.NineSlice;
private voucherIcons: Phaser.GameObjects.Sprite[];
private titleText: 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.vouchersContainer = this.scene.add.container(1, -(this.scene.game.canvas.height / 6) + 1);
this.vouchersContainer.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, 'Vouchers', TextStyle.SETTINGS_LABEL);
headerText.setOrigin(0, 0);
headerText.setPositionRelative(headerBg, 8, 4);
this.voucherIconsBg = 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.voucherIconsBg.setOrigin(0, 0);
this.voucherIconsContainer = this.scene.add.container(6, headerBg.height + 6);
this.voucherIcons = [];
for (let a = 0; a < Object.keys(vouchers).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.voucherIcons.push(icon);
this.voucherIconsContainer.add(icon);
}
const titleBg = this.scene.add.nineslice(0, headerBg.height + this.voucherIconsBg.height, 'window', null, 220, 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 unlockBg = this.scene.add.nineslice(titleBg.x + titleBg.width, titleBg.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.vouchersContainer.add(headerBg);
this.vouchersContainer.add(headerText);
this.vouchersContainer.add(this.voucherIconsBg);
this.vouchersContainer.add(this.voucherIconsContainer);
this.vouchersContainer.add(titleBg);
this.vouchersContainer.add(this.titleText);
this.vouchersContainer.add(unlockBg);
this.vouchersContainer.add(this.unlockText);
this.vouchersContainer.add(descriptionBg);
this.vouchersContainer.add(descriptionText);
ui.add(this.vouchersContainer);
this.setCursor(0);
this.vouchersContainer.setVisible(false);
}
show(args: any[]) {
super.show(args);
const voucherUnlocks = this.scene.gameData.voucherUnlocks;
Object.values(vouchers).forEach((voucher: Voucher, i: integer) => {
const icon = this.voucherIcons[i];
const unlocked = voucherUnlocks.hasOwnProperty(voucher.id);
icon.setFrame(getVoucherTypeIcon(voucher.voucherType));
if (!unlocked)
icon.setTintFill(0);
else
icon.clearTint();
});
this.vouchersContainer.setVisible(true);
this.setCursor(0);
this.getUi().moveTo(this.vouchersContainer, this.getUi().length - 1);
this.getUi().hideTooltip();
}
protected showVoucher(voucher: Voucher) {
const voucherUnlocks = this.scene.gameData.voucherUnlocks;
const unlocked = voucherUnlocks.hasOwnProperty(voucher.id);
this.titleText.setText(getVoucherTypeName(voucher.voucherType));
this.showText(voucher.description);
this.unlockText.setText(unlocked ? new Date(voucherUnlocks[voucher.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(vouchers).length)
success = this.setCursor(this.cursor + 17);
break;
case Button.LEFT:
if (this.cursor)
success = this.setCursor(this.cursor - 1);
break;
case Button.RIGHT:
if (this.cursor < Object.keys(vouchers).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 updateVoucher = 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.voucherIconsContainer.add(this.cursorObj);
updateVoucher = true;
}
this.cursorObj.setPositionRelative(this.voucherIcons[this.cursor], 0, 0);
if (updateVoucher)
this.showVoucher(vouchers[Object.keys(vouchers)[cursor]]);
return ret;
}
clear() {
super.clear();
this.vouchersContainer.setVisible(false);
this.eraseCursor();
}
eraseCursor() {
if (this.cursorObj)
this.cursorObj.destroy();
this.cursorObj = null;
}
}