pokerogue/src/modifier/modifier-bar.ts
2025-05-31 00:30:36 +02:00

106 lines
3.7 KiB
TypeScript

import { globalScene } from "#app/global-scene";
import { type Modifier, type PersistentModifier, PokemonHeldItemModifier } from "./modifier";
const iconOverflowIndex = 24;
export const modifierSortFunc = (a: Modifier, b: Modifier): number => {
const itemNameMatch = a.type.name.localeCompare(b.type.name);
const typeNameMatch = a.constructor.name.localeCompare(b.constructor.name);
const aId = a instanceof PokemonHeldItemModifier && a.pokemonId ? a.pokemonId : 4294967295;
const bId = b instanceof PokemonHeldItemModifier && b.pokemonId ? b.pokemonId : 4294967295;
//First sort by pokemonID
if (aId < bId) {
return 1;
}
if (aId > bId) {
return -1;
}
if (aId === bId) {
//Then sort by item type
if (typeNameMatch === 0) {
return itemNameMatch;
//Finally sort by item name
}
return typeNameMatch;
}
return 0;
};
export class ModifierBar extends Phaser.GameObjects.Container {
private player: boolean;
private modifierCache: PersistentModifier[];
constructor(enemy?: boolean) {
super(globalScene, 1 + (enemy ? 302 : 0), 2);
this.player = !enemy;
this.setScale(0.5);
}
/**
* Method to update content displayed in {@linkcode ModifierBar}
* @param {PersistentModifier[]} modifiers - The list of modifiers to be displayed in the {@linkcode ModifierBar}
* @param {boolean} hideHeldItems - If set to "true", only modifiers not assigned to a Pokémon are displayed
*/
updateModifiers(modifiers: PersistentModifier[], hideHeldItems = false) {
this.removeAll(true);
const visibleIconModifiers = modifiers.filter(m => m.isIconVisible());
const nonPokemonSpecificModifiers = visibleIconModifiers
.filter(m => !(m as PokemonHeldItemModifier).pokemonId)
.sort(modifierSortFunc);
const pokemonSpecificModifiers = visibleIconModifiers
.filter(m => (m as PokemonHeldItemModifier).pokemonId)
.sort(modifierSortFunc);
const sortedVisibleIconModifiers = hideHeldItems
? nonPokemonSpecificModifiers
: nonPokemonSpecificModifiers.concat(pokemonSpecificModifiers);
sortedVisibleIconModifiers.forEach((modifier: PersistentModifier, i: number) => {
const icon = modifier.getIcon();
if (i >= iconOverflowIndex) {
icon.setVisible(false);
}
this.add(icon);
this.setModifierIconPosition(icon, sortedVisibleIconModifiers.length);
icon.setInteractive(new Phaser.Geom.Rectangle(0, 0, 32, 24), Phaser.Geom.Rectangle.Contains);
icon.on("pointerover", () => {
globalScene.ui.showTooltip(modifier.type.name, modifier.type.getDescription());
if (this.modifierCache && this.modifierCache.length > iconOverflowIndex) {
this.updateModifierOverflowVisibility(true);
}
});
icon.on("pointerout", () => {
globalScene.ui.hideTooltip();
if (this.modifierCache && this.modifierCache.length > iconOverflowIndex) {
this.updateModifierOverflowVisibility(false);
}
});
});
for (const icon of this.getAll()) {
this.sendToBack(icon);
}
this.modifierCache = modifiers;
}
updateModifierOverflowVisibility(ignoreLimit: boolean) {
const modifierIcons = this.getAll().reverse();
for (const modifier of modifierIcons.map(m => m as Phaser.GameObjects.Container).slice(iconOverflowIndex)) {
modifier.setVisible(ignoreLimit);
}
}
setModifierIconPosition(icon: Phaser.GameObjects.Container, modifierCount: number) {
const rowIcons: number = 12 + 6 * Math.max(Math.ceil(Math.min(modifierCount, 24) / 12) - 2, 0);
const x = ((this.getIndex(icon) % rowIcons) * 26) / (rowIcons / 12);
const y = Math.floor(this.getIndex(icon) / rowIcons) * 20;
icon.setPosition(this.player ? x : -x, y);
}
}