pokerogue/src/ui/modifier-select-ui-handler.ts
2023-03-28 14:54:52 -04:00

290 lines
7.9 KiB
TypeScript

import { SwitchPhase, SwitchSummonPhase } from "../battle-phase";
import BattleScene from "../battle-scene";
import { ModifierTier, ModifierType } from "../modifier";
import { getPokeballAtlasKey, PokeballType } from "../pokeball";
import { addTextObject, TextStyle } from "../text";
import AwaitableUiHandler from "./awaitable-ui-handler";
import { Mode } from "./ui";
export default class ModifierSelectUiHandler extends AwaitableUiHandler {
private overlayBg: Phaser.GameObjects.Rectangle;
private modifierContainer: Phaser.GameObjects.Container;
private options: ModifierOption[];
private cursorObj: Phaser.GameObjects.Image;
constructor(scene: BattleScene) {
super(scene, Mode.SWITCH_CHECK);
this.options = [];
}
setup() {
const ui = this.getUi();
const overlayWidth = this.scene.game.canvas.width / 6;
const overlayHeight = (this.scene.game.canvas.height / 6) - 48;
this.overlayBg = this.scene.add.rectangle(0, overlayHeight * -1 - 48, overlayWidth, overlayHeight, 0x424242);
this.overlayBg.setOrigin(0, 0);
this.overlayBg.setAlpha(0);
ui.add(this.overlayBg);
this.modifierContainer = this.scene.add.container(0, 0);
ui.add(this.modifierContainer);
}
show(args: any[]) {
if (this.active || args.length !== 2 || !(args[0] instanceof Array) || !args[0].length || !(args[1] instanceof Function))
return;
super.show(args);
this.getUi().clearText();
const types = args[0] as ModifierType[];
for (let m = 0; m < types.length; m++) {
const sliceWidth = (this.scene.game.canvas.width / 6) / (types.length + 2);
const option = new ModifierOption(this.scene, sliceWidth * (m + 1) + (sliceWidth * 0.5), -this.scene.game.canvas.height / 12 - 24, types[m]);
option.setScale(0.5);
this.scene.add.existing(option);
this.modifierContainer.add(option);
this.options.push(option);
}
this.scene.tweens.add({
targets: this.overlayBg,
alpha: 0.5,
ease: 'Sine.easeOut',
duration: 750
});
let i = 0;
this.scene.tweens.addCounter({
ease: 'Sine.easeIn',
duration: 1250,
onUpdate: t => {
const value = t.getValue();
const index = Math.floor(value * types.length);
if (index > i && index <= types.length)
this.options[i++].show(Math.floor((1 - value) * 1250) * 0.325);
}
});
this.scene.time.delayedCall(4000, () => {
this.setCursor(0);
this.awaitingActionInput = true;
this.onActionInput = args[1];
});
}
processInput(keyCode: integer) {
const keyCodes = Phaser.Input.Keyboard.KeyCodes;
const ui = this.getUi();
if (!this.awaitingActionInput)
return;
let success = false;
if (keyCode === keyCodes.Z) {
success = true;
if (this.onActionInput)
this.onActionInput(this.cursor);
} else if (keyCode === keyCodes.X) {
success = true;
if (this.onActionInput)
this.onActionInput(-1);
} else {
switch (keyCode) {
case keyCodes.LEFT:
if (this.cursor)
success = this.setCursor(this.cursor - 1);
break;
case keyCodes.RIGHT:
if (this.cursor < this.options.length - 1)
success = this.setCursor(this.cursor + 1);
break;
}
}
if (success)
ui.playSelect();
}
setCursor(cursor: integer): boolean {
const ui = this.getUi();
const ret = super.setCursor(cursor);
if (!this.cursorObj) {
this.cursorObj = this.scene.add.image(0, 0, 'cursor');
this.cursorObj.setScale(2);
this.modifierContainer.add(this.cursorObj);
}
const sliceWidth = (this.scene.game.canvas.width / 6) / (this.options.length + 2);
this.cursorObj.setPosition(sliceWidth * (cursor + 1) + (sliceWidth * 0.5) - 20, -this.scene.game.canvas.height / 12 - 20);
ui.showText(this.options[this.cursor].modifierType.description);
return ret;
}
clear() {
super.clear();
this.awaitingActionInput = false;
this.onActionInput = null;
this.getUi().clearText();
this.eraseCursor();
this.scene.tweens.add({
targets: this.overlayBg,
alpha: 0,
duration: 250,
ease: 'Cubic.easeIn'
});
this.scene.tweens.add({
targets: this.options,
scale: 0.01,
duration: 250,
east: 'Elastic.easeIn',
onComplete: () => {
this.options.forEach(o => o.destroy());
this.options.splice(0, this.options.length);
}
});
}
eraseCursor() {
if (this.cursorObj)
this.cursorObj.destroy();
this.cursorObj = null;
}
}
class ModifierOption extends Phaser.GameObjects.Container {
public modifierType: ModifierType;
private pb: Phaser.GameObjects.Sprite;
private itemContainer: Phaser.GameObjects.Container;
private item: Phaser.GameObjects.Sprite;
private itemTint: Phaser.GameObjects.Sprite;
private itemText: Phaser.GameObjects.Text;
constructor(scene: BattleScene, x: number, y: number, modifierType: ModifierType) {
super(scene, x, y);
this.modifierType = modifierType;
this.setup();
}
setup() {
this.pb = this.scene.add.sprite(0, -150, 'pb', this.getPbAtlasKey());
this.pb.setScale(2);
this.add(this.pb);
this.itemContainer = this.scene.add.container(0, 0);
this.itemContainer.setScale(0.5);
this.itemContainer.setAlpha(0);
this.add(this.itemContainer);
const getItem = () => {
const item = this.scene.add.sprite(0, 0, 'items', this.modifierType.iconImage);
return item;
};
this.item = getItem();
this.itemContainer.add(this.item);
this.itemTint = getItem();
this.itemTint.setTintFill(Phaser.Display.Color.GetColor(255, 192, 255));
this.itemContainer.add(this.itemTint);
this.itemText = addTextObject(this.scene, 0, 35, this.modifierType.name, TextStyle.PARTY, { align: 'center' });
this.itemText.setOrigin(0.5, 0);
this.itemText.setAlpha(0);
this.itemText.setTint(this.getTextTint());
this.add(this.itemText);
}
show(remainingDuration: integer) {
this.scene.tweens.add({
targets: this.pb,
y: 0,
duration: 1250,
ease: 'Bounce.Out'
});
let lastValue = 1;
let bounceCount = 0;
let bounce = false;
this.scene.tweens.addCounter({
from: 1,
to: 0,
duration: 1250,
ease: 'Bounce.Out',
onUpdate: t => {
const value = t.getValue();
if (!bounce && value > lastValue) {
this.scene.sound.play('pb_bounce_1', { volume: 1 / ++bounceCount });
bounce = true;
} else if (bounce && value < lastValue)
bounce = false;
lastValue = value;
}
});
this.scene.time.delayedCall(remainingDuration + 2000, () => {
this.pb.setTexture('pb', `${this.getPbAtlasKey()}_open`);
this.scene.sound.play('pb_rel');
this.scene.tweens.add({
targets: this.pb,
duration: 500,
delay: 250,
ease: 'Sine.easeIn',
alpha: 0,
onComplete: () => this.pb.destroy()
})
this.scene.tweens.add({
targets: this.itemContainer,
duration: 500,
ease: 'Elastic.Out',
scale: 2,
alpha: 1
});
this.scene.tweens.add({
targets: this.itemTint,
alpha: 0,
duration: 500,
ease: 'Sine.easeIn',
onComplete: () => this.itemTint.destroy()
});
this.scene.tweens.add({
targets: this.itemText,
duration: 500,
alpha: 1,
y: 25,
ease: 'Cubic.easeInOut'
});
})
}
getPbAtlasKey() {
return getPokeballAtlasKey(this.modifierType.tier as unknown as PokeballType);
}
getTextTint(): integer {
switch (this.modifierType.tier) {
case ModifierTier.COMMON:
return 0xffffff
case ModifierTier.GREAT:
return 0x3890f8;
case ModifierTier.ULTRA:
return 0xf8d038
case ModifierTier.MASTER:
return 0xe020c0;
}
}
}