2024-09-05 02:59:25 +10:00
|
|
|
import BattleScene from "../battle-scene";
|
|
|
|
import { Mode } from "./ui";
|
|
|
|
import PokemonIconAnimHandler, { PokemonIconAnimMode } from "./pokemon-icon-anim-handler";
|
|
|
|
import MessageUiHandler from "./message-ui-handler";
|
|
|
|
import { getEggTierForSpecies } from "../data/egg";
|
2024-09-26 10:51:49 +02:00
|
|
|
import { Button } from "#enums/buttons";
|
2024-09-05 02:59:25 +10:00
|
|
|
import PokemonHatchInfoContainer from "./pokemon-hatch-info-container";
|
|
|
|
import { EggSummaryPhase } from "#app/phases/egg-summary-phase";
|
|
|
|
import { EggHatchData } from "#app/data/egg-hatch-data";
|
2024-09-26 10:51:49 +02:00
|
|
|
import ScrollableGridUiHandler from "./scrollable-grid-handler";
|
|
|
|
import { HatchedPokemonContainer } from "./hatched-pokemon-container";
|
|
|
|
import { ScrollBar } from "#app/ui/scroll-bar";
|
2024-09-05 02:59:25 +10:00
|
|
|
|
2024-09-26 10:51:49 +02:00
|
|
|
const iconContainerX = 112;
|
2024-09-05 02:59:25 +10:00
|
|
|
const iconContainerY = 9;
|
2024-09-26 10:51:49 +02:00
|
|
|
const numRows = 9;
|
2024-09-05 02:59:25 +10:00
|
|
|
const numCols = 11;
|
|
|
|
const iconSize = 18;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* UI Handler for the egg summary.
|
|
|
|
* Handles navigation and display of each pokemon as a list
|
|
|
|
* Also handles display of the pokemon-hatch-info-container
|
|
|
|
*/
|
|
|
|
export default class EggSummaryUiHandler extends MessageUiHandler {
|
|
|
|
/** holds all elements in the scene */
|
|
|
|
private eggHatchContainer: Phaser.GameObjects.Container;
|
|
|
|
/** holds the icon containers and info container */
|
|
|
|
private summaryContainer: Phaser.GameObjects.Container;
|
2024-09-26 10:51:49 +02:00
|
|
|
/** container for the each pokemon sprites and icons */
|
2024-09-05 02:59:25 +10:00
|
|
|
private pokemonIconsContainer: Phaser.GameObjects.Container;
|
2024-09-26 10:51:49 +02:00
|
|
|
/** list of the containers added to pokemonIconsContainer for easier access */
|
|
|
|
private pokemonContainers: HatchedPokemonContainer[];
|
|
|
|
|
2024-09-05 02:59:25 +10:00
|
|
|
/** hatch info container that displays the current pokemon / hatch (main element on left hand side) */
|
|
|
|
private infoContainer: PokemonHatchInfoContainer;
|
|
|
|
/** handles jumping animations for the pokemon sprite icons */
|
|
|
|
private iconAnimHandler: PokemonIconAnimHandler;
|
|
|
|
private eggHatchBg: Phaser.GameObjects.Image;
|
|
|
|
private eggHatchData: EggHatchData[];
|
|
|
|
|
2024-09-26 10:51:49 +02:00
|
|
|
private scrollGridHandler : ScrollableGridUiHandler;
|
|
|
|
private cursorObj: Phaser.GameObjects.Image;
|
2024-09-05 02:59:25 +10:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Allows subscribers to listen for events
|
|
|
|
*
|
|
|
|
* Current Events:
|
|
|
|
* - {@linkcode EggEventType.EGG_COUNT_CHANGED} {@linkcode EggCountChangedEvent}
|
|
|
|
*/
|
|
|
|
public readonly eventTarget: EventTarget = new EventTarget();
|
|
|
|
|
|
|
|
constructor(scene: BattleScene) {
|
|
|
|
super(scene, Mode.EGG_HATCH_SUMMARY);
|
|
|
|
}
|
|
|
|
|
|
|
|
setup() {
|
|
|
|
const ui = this.getUi();
|
|
|
|
|
|
|
|
this.summaryContainer = this.scene.add.container(0, -this.scene.game.canvas.height / 6);
|
|
|
|
this.summaryContainer.setVisible(false);
|
|
|
|
ui.add(this.summaryContainer);
|
|
|
|
|
|
|
|
this.eggHatchContainer = this.scene.add.container(0, -this.scene.game.canvas.height / 6);
|
|
|
|
this.eggHatchContainer.setVisible(false);
|
|
|
|
ui.add(this.eggHatchContainer);
|
|
|
|
|
|
|
|
this.iconAnimHandler = new PokemonIconAnimHandler();
|
|
|
|
this.iconAnimHandler.setup(this.scene);
|
|
|
|
|
|
|
|
this.eggHatchBg = this.scene.add.image(0, 0, "egg_summary_bg");
|
|
|
|
this.eggHatchBg.setOrigin(0, 0);
|
|
|
|
this.eggHatchContainer.add(this.eggHatchBg);
|
|
|
|
|
|
|
|
this.cursorObj = this.scene.add.image(0, 0, "select_cursor");
|
|
|
|
this.cursorObj.setOrigin(0, 0);
|
|
|
|
this.summaryContainer.add(this.cursorObj);
|
|
|
|
|
2024-09-26 10:51:49 +02:00
|
|
|
this.pokemonContainers = [];
|
2024-09-10 16:12:17 +02:00
|
|
|
this.pokemonIconsContainer = this.scene.add.container(iconContainerX, iconContainerY);
|
|
|
|
this.summaryContainer.add(this.pokemonIconsContainer);
|
|
|
|
|
2024-09-05 02:59:25 +10:00
|
|
|
this.infoContainer = new PokemonHatchInfoContainer(this.scene, this.summaryContainer);
|
|
|
|
this.infoContainer.setup();
|
|
|
|
this.infoContainer.changeToEggSummaryLayout();
|
|
|
|
this.infoContainer.setVisible(true);
|
|
|
|
this.summaryContainer.add(this.infoContainer);
|
|
|
|
|
2024-09-26 10:51:49 +02:00
|
|
|
const scrollBar = new ScrollBar(this.scene, iconContainerX + numCols * iconSize, iconContainerY + 3, 4, this.scene.game.canvas.height / 6 - 20, numRows);
|
|
|
|
this.summaryContainer.add(scrollBar);
|
|
|
|
|
|
|
|
this.scrollGridHandler = new ScrollableGridUiHandler(this, numRows, numCols)
|
|
|
|
.withScrollBar(scrollBar)
|
|
|
|
.withUpdateGridCallBack(() => this.updatePokemonIcons())
|
|
|
|
.withUpdateSingleElementCallback((i: number) => this.infoContainer.showHatchInfo(this.eggHatchData[i]));
|
|
|
|
|
2024-09-05 02:59:25 +10:00
|
|
|
this.cursor = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
clear() {
|
|
|
|
super.clear();
|
2024-09-26 10:51:49 +02:00
|
|
|
this.scrollGridHandler.reset();
|
2024-09-30 03:48:29 +02:00
|
|
|
this.cursor = -1;
|
|
|
|
|
2024-09-05 02:59:25 +10:00
|
|
|
this.summaryContainer.setVisible(false);
|
|
|
|
this.pokemonIconsContainer.removeAll(true);
|
2024-09-26 10:51:49 +02:00
|
|
|
this.pokemonContainers = [];
|
2024-09-05 02:59:25 +10:00
|
|
|
this.eggHatchBg.setVisible(false);
|
|
|
|
this.getUi().hideTooltip();
|
2024-09-10 23:23:13 +10:00
|
|
|
|
2024-09-05 02:59:25 +10:00
|
|
|
// Note: Questions on garbage collection go to @frutescens
|
|
|
|
const activeKeys = this.scene.getActiveKeys();
|
|
|
|
// Removing unnecessary sprites from animation manager
|
|
|
|
const animKeys = Object.keys(this.scene.anims["anims"]["entries"]);
|
|
|
|
animKeys.forEach(key => {
|
|
|
|
if (key.startsWith("pkmn__") && !activeKeys.includes(key)) {
|
|
|
|
this.scene.anims.remove(key);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
// Removing unnecessary cries from audio cache
|
|
|
|
const audioKeys = Object.keys(this.scene.cache.audio.entries.entries);
|
|
|
|
audioKeys.forEach(key => {
|
|
|
|
if (key.startsWith("cry/") && !activeKeys.includes(key)) {
|
|
|
|
delete this.scene.cache.audio.entries.entries[key];
|
|
|
|
}
|
|
|
|
});
|
|
|
|
// Clears eggHatchData in EggSummaryUiHandler
|
|
|
|
this.eggHatchData.length = 0;
|
|
|
|
// Removes Pokemon icons in EggSummaryUiHandler
|
|
|
|
this.iconAnimHandler.removeAll();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param args EggHatchData[][]
|
|
|
|
* args[0]: list of EggHatchData for each egg/pokemon hatched
|
|
|
|
*/
|
|
|
|
show(args: EggHatchData[][]): boolean {
|
|
|
|
super.show(args);
|
|
|
|
if (args.length >= 1) {
|
|
|
|
// sort the egg hatch data by egg tier then by species number (then by order hatched)
|
|
|
|
this.eggHatchData = args[0].sort(function sortHatchData(a: EggHatchData, b: EggHatchData) {
|
|
|
|
const speciesA = a.pokemon.species;
|
|
|
|
const speciesB = b.pokemon.species;
|
|
|
|
if (getEggTierForSpecies(speciesA) < getEggTierForSpecies(speciesB)) {
|
|
|
|
return -1;
|
|
|
|
} else if (getEggTierForSpecies(speciesA) > getEggTierForSpecies(speciesB)) {
|
|
|
|
return 1;
|
|
|
|
} else {
|
|
|
|
if (speciesA.speciesId < speciesB.speciesId) {
|
|
|
|
return -1;
|
|
|
|
} else if (speciesA.speciesId > speciesB.speciesId) {
|
|
|
|
return 1;
|
|
|
|
} else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
2024-09-26 10:51:49 +02:00
|
|
|
});
|
2024-09-05 02:59:25 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
this.getUi().bringToTop(this.summaryContainer);
|
|
|
|
this.summaryContainer.setVisible(true);
|
|
|
|
this.eggHatchContainer.setVisible(true);
|
|
|
|
this.eggHatchBg.setVisible(true);
|
|
|
|
this.infoContainer.hideDisplayPokemon();
|
|
|
|
|
2024-09-26 10:51:49 +02:00
|
|
|
this.scrollGridHandler.setTotalElements(this.eggHatchData.length);
|
|
|
|
this.updatePokemonIcons();
|
2024-09-05 02:59:25 +10:00
|
|
|
this.setCursor(0);
|
2024-09-30 03:48:29 +02:00
|
|
|
|
2024-09-05 02:59:25 +10:00
|
|
|
this.scene.playSoundWithoutBgm("evolution_fanfare");
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2024-09-26 10:51:49 +02:00
|
|
|
/**
|
|
|
|
* Show the grid of Pokemon icons
|
|
|
|
*/
|
|
|
|
private updatePokemonIcons(): void {
|
|
|
|
const itemOffset = this.scrollGridHandler.getItemOffset();
|
|
|
|
const eggsToShow = Math.min(numRows * numCols, this.eggHatchData.length - itemOffset);
|
|
|
|
|
|
|
|
for (let i = 0; i < numRows * numCols; i++) {
|
|
|
|
const hatchData = this.eggHatchData[i + itemOffset];
|
|
|
|
let hatchContainer = this.pokemonContainers[i];
|
|
|
|
|
|
|
|
if (i < eggsToShow) {
|
|
|
|
if (!hatchContainer) {
|
|
|
|
const x = (i % numCols) * iconSize;
|
|
|
|
const y = Math.floor(i / numCols) * iconSize;
|
|
|
|
hatchContainer = new HatchedPokemonContainer(this.scene, x, y, hatchData).setVisible(false);
|
|
|
|
this.pokemonContainers.push(hatchContainer);
|
|
|
|
this.pokemonIconsContainer.add(hatchContainer);
|
|
|
|
}
|
|
|
|
hatchContainer.setVisible(true);
|
|
|
|
hatchContainer.updateAndAnimate(hatchData, this.iconAnimHandler);
|
|
|
|
} else if (hatchContainer) {
|
|
|
|
hatchContainer.setVisible(false);
|
|
|
|
this.iconAnimHandler.addOrUpdate(hatchContainer.icon, PokemonIconAnimMode.NONE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-09-05 02:59:25 +10:00
|
|
|
processInput(button: Button): boolean {
|
|
|
|
const ui = this.getUi();
|
|
|
|
|
|
|
|
let success = false;
|
|
|
|
const error = false;
|
|
|
|
if (button === Button.CANCEL) {
|
|
|
|
const phase = this.scene.getCurrentPhase();
|
|
|
|
if (phase instanceof EggSummaryPhase) {
|
|
|
|
phase.end();
|
|
|
|
}
|
|
|
|
success = true;
|
|
|
|
} else {
|
2024-09-26 10:51:49 +02:00
|
|
|
this.scrollGridHandler.processInput(button);
|
2024-09-05 02:59:25 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
if (success) {
|
|
|
|
ui.playSelect();
|
|
|
|
} else if (error) {
|
|
|
|
ui.playError();
|
|
|
|
}
|
|
|
|
|
|
|
|
return success || error;
|
|
|
|
}
|
|
|
|
|
|
|
|
setCursor(cursor: number): boolean {
|
|
|
|
let changed = false;
|
|
|
|
|
|
|
|
const lastCursor = this.cursor;
|
|
|
|
|
|
|
|
changed = super.setCursor(cursor);
|
|
|
|
|
|
|
|
if (changed) {
|
|
|
|
this.cursorObj.setPosition(iconContainerX - 1 + iconSize * (cursor % numCols), iconContainerY + 1 + iconSize * Math.floor(cursor / numCols));
|
|
|
|
|
|
|
|
if (lastCursor > -1) {
|
2024-09-26 10:51:49 +02:00
|
|
|
this.iconAnimHandler.addOrUpdate(this.pokemonContainers[lastCursor].icon, PokemonIconAnimMode.NONE);
|
2024-09-05 02:59:25 +10:00
|
|
|
}
|
2024-09-26 10:51:49 +02:00
|
|
|
this.iconAnimHandler.addOrUpdate(this.pokemonContainers[cursor].icon, PokemonIconAnimMode.ACTIVE);
|
2024-09-05 02:59:25 +10:00
|
|
|
|
2024-09-26 10:51:49 +02:00
|
|
|
this.infoContainer.showHatchInfo(this.eggHatchData[cursor + this.scrollGridHandler.getItemOffset()]);
|
2024-09-05 02:59:25 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
return changed;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|