2023-04-11 05:24:55 +01:00
|
|
|
import BattleScene, { Button } from "../battle-scene";
|
2023-04-21 19:05:16 +01:00
|
|
|
import { ModifierTier, ModifierTypeOption } from "../modifier/modifier-type";
|
2023-04-20 20:46:05 +01:00
|
|
|
import { getPokeballAtlasKey, PokeballType } from "../data/pokeball";
|
|
|
|
import { addTextObject, TextStyle } from "./text";
|
2023-03-28 19:54:52 +01:00
|
|
|
import AwaitableUiHandler from "./awaitable-ui-handler";
|
|
|
|
import { Mode } from "./ui";
|
2023-04-21 19:05:16 +01:00
|
|
|
import { PokemonHeldItemModifier } from "../modifier/modifier";
|
2023-03-28 19:54:52 +01:00
|
|
|
|
|
|
|
export default class ModifierSelectUiHandler extends AwaitableUiHandler {
|
|
|
|
private overlayBg: Phaser.GameObjects.Rectangle;
|
|
|
|
private modifierContainer: Phaser.GameObjects.Container;
|
2023-04-21 19:05:16 +01:00
|
|
|
private transferButtonContainer: Phaser.GameObjects.Container;
|
|
|
|
|
|
|
|
private lastCursor: integer = 0;
|
|
|
|
|
2023-03-29 05:31:25 +01:00
|
|
|
public options: ModifierOption[];
|
2023-03-28 19:54:52 +01:00
|
|
|
|
|
|
|
private cursorObj: Phaser.GameObjects.Image;
|
|
|
|
|
|
|
|
constructor(scene: BattleScene) {
|
2023-04-07 03:24:13 +01:00
|
|
|
super(scene, Mode.CONFIRM);
|
2023-03-28 19:54:52 +01:00
|
|
|
|
|
|
|
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);
|
2023-04-21 19:05:16 +01:00
|
|
|
|
|
|
|
this.transferButtonContainer = this.scene.add.container((this.scene.game.canvas.width / 6) - 1, -64);
|
|
|
|
this.transferButtonContainer.setVisible(false);
|
|
|
|
ui.add(this.transferButtonContainer);
|
|
|
|
|
|
|
|
const transferButtonText = addTextObject(this.scene, -4, -2, 'Transfer', TextStyle.PARTY);
|
|
|
|
transferButtonText.setOrigin(1, 0);
|
|
|
|
this.transferButtonContainer.add(transferButtonText);
|
2023-03-28 19:54:52 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
show(args: any[]) {
|
2023-04-10 00:15:21 +01:00
|
|
|
if (this.active) {
|
|
|
|
if (args.length === 2) {
|
|
|
|
this.awaitingActionInput = true;
|
|
|
|
this.onActionInput = args[1];
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (args.length !== 2 || !(args[0] instanceof Array) || !args[0].length || !(args[1] instanceof Function))
|
2023-03-28 19:54:52 +01:00
|
|
|
return;
|
|
|
|
|
|
|
|
super.show(args);
|
|
|
|
|
|
|
|
this.getUi().clearText();
|
|
|
|
|
2023-06-01 00:54:57 +01:00
|
|
|
const partyHasHeldItem = !!this.scene.findModifiers(m => m instanceof PokemonHeldItemModifier && (m as PokemonHeldItemModifier).getTransferrable(true)).length;
|
2023-04-21 19:05:16 +01:00
|
|
|
|
|
|
|
this.transferButtonContainer.setVisible(false);
|
|
|
|
this.transferButtonContainer.setAlpha(0);
|
|
|
|
|
2023-04-12 17:48:02 +01:00
|
|
|
const typeOptions = args[0] as ModifierTypeOption[];
|
|
|
|
for (let m = 0; m < typeOptions.length; m++) {
|
|
|
|
const sliceWidth = (this.scene.game.canvas.width / 6) / (typeOptions.length + 2);
|
|
|
|
const option = new ModifierOption(this.scene, sliceWidth * (m + 1) + (sliceWidth * 0.5), -this.scene.game.canvas.height / 12 - 24, typeOptions[m]);
|
2023-03-28 19:54:52 +01:00
|
|
|
option.setScale(0.5);
|
|
|
|
this.scene.add.existing(option);
|
|
|
|
this.modifierContainer.add(option);
|
|
|
|
this.options.push(option);
|
|
|
|
}
|
|
|
|
|
2023-04-12 17:48:02 +01:00
|
|
|
const hasUpgrade = typeOptions.filter(to => to.upgraded).length;
|
|
|
|
|
2023-03-28 19:54:52 +01:00
|
|
|
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();
|
2023-04-12 17:48:02 +01:00
|
|
|
const index = Math.floor(value * typeOptions.length);
|
|
|
|
if (index > i && index <= typeOptions.length) {
|
2023-03-29 05:31:25 +01:00
|
|
|
const option = this.options[i++];
|
2023-04-12 17:48:02 +01:00
|
|
|
option?.show(Math.floor((1 - value) * 1250) * 0.325 + (hasUpgrade ? 2000 : 0));
|
2023-03-29 05:31:25 +01:00
|
|
|
}
|
2023-03-28 19:54:52 +01:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2023-04-12 17:48:02 +01:00
|
|
|
this.scene.time.delayedCall(4000 + (hasUpgrade ? 2000 : 0), () => {
|
2023-04-21 19:05:16 +01:00
|
|
|
if (partyHasHeldItem) {
|
|
|
|
this.transferButtonContainer.setAlpha(0);
|
|
|
|
this.transferButtonContainer.setVisible(true);
|
|
|
|
this.scene.tweens.add({
|
|
|
|
targets: this.transferButtonContainer,
|
|
|
|
alpha: 1,
|
|
|
|
duration: 250
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2023-03-28 19:54:52 +01:00
|
|
|
this.setCursor(0);
|
|
|
|
this.awaitingActionInput = true;
|
|
|
|
this.onActionInput = args[1];
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2023-04-11 05:24:55 +01:00
|
|
|
processInput(button: Button) {
|
2023-03-28 19:54:52 +01:00
|
|
|
const ui = this.getUi();
|
|
|
|
|
|
|
|
if (!this.awaitingActionInput)
|
|
|
|
return;
|
|
|
|
|
|
|
|
let success = false;
|
|
|
|
|
2023-04-11 05:24:55 +01:00
|
|
|
if (button === Button.ACTION) {
|
2023-03-28 19:54:52 +01:00
|
|
|
success = true;
|
2023-04-09 05:22:14 +01:00
|
|
|
if (this.onActionInput) {
|
|
|
|
const originalOnActionInput = this.onActionInput;
|
2023-04-10 00:15:21 +01:00
|
|
|
this.awaitingActionInput = false;
|
2023-04-09 05:22:14 +01:00
|
|
|
this.onActionInput = null;
|
|
|
|
originalOnActionInput(this.cursor);
|
|
|
|
}
|
2023-04-11 05:24:55 +01:00
|
|
|
} else if (button === Button.CANCEL) {
|
2023-03-28 19:54:52 +01:00
|
|
|
success = true;
|
2023-04-09 05:22:14 +01:00
|
|
|
if (this.onActionInput) {
|
|
|
|
const originalOnActionInput = this.onActionInput;
|
2023-04-10 00:15:21 +01:00
|
|
|
this.awaitingActionInput = false;
|
2023-04-09 05:22:14 +01:00
|
|
|
this.onActionInput = null;
|
|
|
|
originalOnActionInput(-1);
|
|
|
|
}
|
2023-03-28 19:54:52 +01:00
|
|
|
} else {
|
2023-04-11 05:24:55 +01:00
|
|
|
switch (button) {
|
2023-04-21 19:05:16 +01:00
|
|
|
case Button.UP:
|
|
|
|
if (this.cursor === this.options.length)
|
|
|
|
success = this.setCursor(this.lastCursor);
|
|
|
|
break;
|
|
|
|
case Button.DOWN:
|
|
|
|
if (this.cursor < this.options.length && this.transferButtonContainer.visible)
|
|
|
|
success = this.setCursor(this.options.length);
|
|
|
|
break;
|
2023-04-11 05:24:55 +01:00
|
|
|
case Button.LEFT:
|
2023-03-28 19:54:52 +01:00
|
|
|
if (this.cursor)
|
|
|
|
success = this.setCursor(this.cursor - 1);
|
|
|
|
break;
|
2023-04-11 05:24:55 +01:00
|
|
|
case Button.RIGHT:
|
2023-04-21 19:05:16 +01:00
|
|
|
if (this.cursor < this.options.length - (this.transferButtonContainer.visible ? 0 : 1))
|
2023-03-28 19:54:52 +01:00
|
|
|
success = this.setCursor(this.cursor + 1);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (success)
|
|
|
|
ui.playSelect();
|
|
|
|
}
|
|
|
|
|
|
|
|
setCursor(cursor: integer): boolean {
|
2023-04-21 19:05:16 +01:00
|
|
|
const lastCursor = this.cursor;
|
|
|
|
|
2023-03-28 19:54:52 +01:00
|
|
|
const ui = this.getUi();
|
|
|
|
const ret = super.setCursor(cursor);
|
|
|
|
|
2023-04-21 19:05:16 +01:00
|
|
|
if (ret)
|
|
|
|
this.lastCursor = lastCursor;
|
|
|
|
|
2023-03-28 19:54:52 +01:00
|
|
|
if (!this.cursorObj) {
|
|
|
|
this.cursorObj = this.scene.add.image(0, 0, 'cursor');
|
|
|
|
this.modifierContainer.add(this.cursorObj);
|
|
|
|
}
|
|
|
|
|
2023-04-21 19:05:16 +01:00
|
|
|
this.cursorObj.setScale(cursor < this.options.length ? 2 : 1);
|
|
|
|
|
|
|
|
if (cursor < this.options.length) {
|
|
|
|
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].modifierTypeOption.type.description);
|
|
|
|
} else {
|
|
|
|
this.cursorObj.setPosition((this.scene.game.canvas.width / 6) - 50, -60);
|
2023-10-18 23:01:15 +01:00
|
|
|
ui.showText('Transfer a held item from one Pokémon to another instead of selecting an item');
|
2023-04-21 19:05:16 +01:00
|
|
|
}
|
2023-03-28 19:54:52 +01:00
|
|
|
|
|
|
|
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,
|
2023-04-22 16:46:52 +01:00
|
|
|
ease: 'Cubic.easeIn',
|
2023-03-28 19:54:52 +01:00
|
|
|
onComplete: () => {
|
|
|
|
this.options.forEach(o => o.destroy());
|
|
|
|
this.options.splice(0, this.options.length);
|
|
|
|
}
|
|
|
|
});
|
2023-04-21 19:05:16 +01:00
|
|
|
if (this.transferButtonContainer.visible) {
|
|
|
|
this.scene.tweens.add({
|
|
|
|
targets: this.transferButtonContainer,
|
|
|
|
alpha: 0,
|
|
|
|
duration: 250,
|
|
|
|
ease: 'Cubic.easeIn',
|
|
|
|
onComplete: () => this.transferButtonContainer.setVisible(false)
|
|
|
|
})
|
|
|
|
}
|
2023-03-28 19:54:52 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
eraseCursor() {
|
|
|
|
if (this.cursorObj)
|
|
|
|
this.cursorObj.destroy();
|
|
|
|
this.cursorObj = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class ModifierOption extends Phaser.GameObjects.Container {
|
2023-04-12 17:48:02 +01:00
|
|
|
public modifierTypeOption: ModifierTypeOption;
|
2023-03-28 19:54:52 +01:00
|
|
|
private pb: Phaser.GameObjects.Sprite;
|
2023-04-12 17:48:02 +01:00
|
|
|
private pbTint: Phaser.GameObjects.Sprite;
|
2023-03-28 19:54:52 +01:00
|
|
|
private itemContainer: Phaser.GameObjects.Container;
|
|
|
|
private item: Phaser.GameObjects.Sprite;
|
|
|
|
private itemTint: Phaser.GameObjects.Sprite;
|
|
|
|
private itemText: Phaser.GameObjects.Text;
|
|
|
|
|
2023-04-12 17:48:02 +01:00
|
|
|
constructor(scene: BattleScene, x: number, y: number, modifierTypeOption: ModifierTypeOption) {
|
2023-03-28 19:54:52 +01:00
|
|
|
super(scene, x, y);
|
|
|
|
|
2023-04-12 17:48:02 +01:00
|
|
|
this.modifierTypeOption = modifierTypeOption;
|
2023-03-28 19:54:52 +01:00
|
|
|
|
|
|
|
this.setup();
|
|
|
|
}
|
|
|
|
|
|
|
|
setup() {
|
2023-04-12 17:48:02 +01:00
|
|
|
const getPb = (): Phaser.GameObjects.Sprite => {
|
|
|
|
const pb = this.scene.add.sprite(0, -150, 'pb', this.getPbAtlasKey(true));
|
|
|
|
pb.setScale(2);
|
|
|
|
return pb;
|
|
|
|
};
|
|
|
|
|
|
|
|
this.pb = getPb();
|
2023-03-28 19:54:52 +01:00
|
|
|
this.add(this.pb);
|
|
|
|
|
2023-04-12 17:48:02 +01:00
|
|
|
this.pbTint = getPb();
|
|
|
|
this.pbTint.setVisible(false);
|
|
|
|
this.add(this.pbTint);
|
|
|
|
|
2023-03-28 19:54:52 +01:00
|
|
|
this.itemContainer = this.scene.add.container(0, 0);
|
|
|
|
this.itemContainer.setScale(0.5);
|
|
|
|
this.itemContainer.setAlpha(0);
|
|
|
|
this.add(this.itemContainer);
|
|
|
|
|
|
|
|
const getItem = () => {
|
2023-04-12 17:48:02 +01:00
|
|
|
const item = this.scene.add.sprite(0, 0, 'items', this.modifierTypeOption.type.iconImage);
|
2023-03-28 19:54:52 +01:00
|
|
|
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);
|
|
|
|
|
2023-04-12 17:48:02 +01:00
|
|
|
this.itemText = addTextObject(this.scene, 0, 35, this.modifierTypeOption.type.name, TextStyle.PARTY, { align: 'center' });
|
2023-03-28 19:54:52 +01:00
|
|
|
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 => {
|
2023-03-29 05:31:25 +01:00
|
|
|
if (!this.scene)
|
|
|
|
return;
|
2023-03-28 19:54:52 +01:00
|
|
|
const value = t.getValue();
|
|
|
|
if (!bounce && value > lastValue) {
|
2023-10-21 13:58:39 +01:00
|
|
|
(this.scene as BattleScene).playSound('pb_bounce_1', { volume: 1 / ++bounceCount });
|
2023-03-28 19:54:52 +01:00
|
|
|
bounce = true;
|
|
|
|
} else if (bounce && value < lastValue)
|
|
|
|
bounce = false;
|
|
|
|
lastValue = value;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2023-04-12 17:48:02 +01:00
|
|
|
if (this.modifierTypeOption.upgraded) {
|
|
|
|
this.scene.time.delayedCall(remainingDuration, () => {
|
2023-10-21 13:58:39 +01:00
|
|
|
(this.scene as BattleScene).playSound('upgrade');
|
2023-04-12 17:48:02 +01:00
|
|
|
this.pbTint.setPosition(this.pb.x, this.pb.y);
|
|
|
|
this.pbTint.setTintFill(0xFFFFFF);
|
|
|
|
this.pbTint.setAlpha(0);
|
|
|
|
this.pbTint.setVisible(true);
|
|
|
|
this.scene.tweens.add({
|
|
|
|
targets: this.pbTint,
|
|
|
|
alpha: 1,
|
|
|
|
duration: 1000,
|
|
|
|
ease: 'Sine.easeIn',
|
|
|
|
onComplete: () => {
|
|
|
|
this.pb.setTexture('pb', this.getPbAtlasKey(false));
|
|
|
|
this.scene.tweens.add({
|
|
|
|
targets: this.pbTint,
|
|
|
|
alpha: 0,
|
|
|
|
duration: 1000,
|
|
|
|
ease: 'Sine.easeOut',
|
|
|
|
onComplete: () => {
|
|
|
|
this.pbTint.setVisible(false);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2023-03-28 19:54:52 +01:00
|
|
|
this.scene.time.delayedCall(remainingDuration + 2000, () => {
|
2023-03-29 05:31:25 +01:00
|
|
|
if (!this.scene)
|
|
|
|
return;
|
|
|
|
|
2023-04-12 17:48:02 +01:00
|
|
|
this.pb.setTexture('pb', `${this.getPbAtlasKey(false)}_open`);
|
2023-10-21 13:58:39 +01:00
|
|
|
(this.scene as BattleScene).playSound('pb_rel');
|
2023-03-28 19:54:52 +01:00
|
|
|
|
|
|
|
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'
|
|
|
|
});
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2023-04-12 17:48:02 +01:00
|
|
|
getPbAtlasKey(beforeUpgrade: boolean) {
|
|
|
|
return getPokeballAtlasKey((this.modifierTypeOption.type.tier - (beforeUpgrade && this.modifierTypeOption.upgraded ? 1 : 0)) as integer as PokeballType);
|
2023-03-28 19:54:52 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
getTextTint(): integer {
|
2023-04-12 17:48:02 +01:00
|
|
|
switch (this.modifierTypeOption.type.tier) {
|
2023-03-28 19:54:52 +01:00
|
|
|
case ModifierTier.COMMON:
|
|
|
|
return 0xffffff
|
|
|
|
case ModifierTier.GREAT:
|
|
|
|
return 0x3890f8;
|
|
|
|
case ModifierTier.ULTRA:
|
|
|
|
return 0xf8d038
|
|
|
|
case ModifierTier.MASTER:
|
|
|
|
return 0xe020c0;
|
2023-03-30 05:13:56 +01:00
|
|
|
case ModifierTier.LUXURY:
|
|
|
|
return 0xe64a18;
|
2023-03-28 19:54:52 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|