From ca778e07d5d9123351cddfc6eeafa5c6aba235f2 Mon Sep 17 00:00:00 2001 From: Flashfyre Date: Wed, 10 Apr 2024 10:57:06 -0400 Subject: [PATCH] Implement Pokemon fusion icons --- src/battle-scene.ts | 58 +++++++++++++++++++++++++++ src/field/pokemon.ts | 8 ++++ src/modifier/modifier.ts | 6 +-- src/ui/party-exp-bar.ts | 15 ++++--- src/ui/party-ui-handler.ts | 5 +-- src/ui/pokemon-icon-anim-handler.ts | 6 +-- src/ui/save-slot-select-ui-handler.ts | 3 +- 7 files changed, 80 insertions(+), 21 deletions(-) diff --git a/src/battle-scene.ts b/src/battle-scene.ts index fd1ba7fee..2fc0d562c 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -580,6 +580,64 @@ export default class BattleScene extends SceneBase { return pokemon; } + addPokemonIcon(pokemon: Pokemon, x: number, y: number, originX: number = 0.5, originY: number = 0.5, ignoreOverride: boolean = false): Phaser.GameObjects.Container { + const container = this.add.container(x, y); + + const icon = this.add.sprite(0, 0, pokemon.getIconAtlasKey(ignoreOverride)); + icon.setFrame(pokemon.getIconId(true)); + icon.setOrigin(0.5, 0); + + container.add(icon); + + if (pokemon.isFusion()) { + const fusionIcon = this.add.sprite(0, 0, pokemon.getFusionIconAtlasKey(ignoreOverride)); + fusionIcon.setOrigin(0.5, 0) + fusionIcon.setFrame(pokemon.getFusionIconId(true)); + + const originalWidth = icon.width; + const originalHeight = icon.height; + const originalFrame = icon.frame; + + const iconHeight = (icon.frame.cutHeight <= fusionIcon.frame.cutHeight ? Math.ceil : Math.floor)((icon.frame.cutHeight + fusionIcon.frame.cutHeight) / 4); + + const iconFrameId = `${icon.frame.name}h${iconHeight}`; + + if (!icon.frame.texture.has(iconFrameId)) + icon.frame.texture.add(iconFrameId, icon.frame.sourceIndex, icon.frame.cutX, icon.frame.cutY, icon.frame.cutWidth, iconHeight); + + icon.setFrame(iconFrameId); + + fusionIcon.y = icon.frame.cutHeight; + + const originalFusionFrame = fusionIcon.frame; + + const fusionIconY = fusionIcon.frame.cutY + icon.frame.cutHeight; + const fusionIconHeight = fusionIcon.frame.cutHeight - icon.frame.cutHeight; + const fusionIconFrameId = `${fusionIcon.frame.name}y${fusionIconY}`; + + if (!fusionIcon.frame.texture.has(fusionIconFrameId)) + fusionIcon.frame.texture.add(fusionIconFrameId, fusionIcon.frame.sourceIndex, fusionIcon.frame.cutX, fusionIconY, fusionIcon.frame.cutWidth, fusionIconHeight); + fusionIcon.setFrame(fusionIconFrameId); + + const frameY = (originalFrame.y + originalFusionFrame.y) / 2; + icon.frame.y = fusionIcon.frame.y = frameY; + + container.add(fusionIcon); + + if (originX !== 0.5) + container.x -= originalWidth * (originX - 0.5); + if (originY !== 0) + container.y -= (originalHeight) * originY; + } else { + if (originX !== 0.5) + container.x -= icon.width * (originX - 0.5); + if (originY !== 0) + container.y -= icon.height * originY; + } + + return container; + } + setSeed(seed: string): void { this.seed = seed; this.rngCounter = 0; diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 7b0e9e6d5..ddb05ff62 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -357,10 +357,18 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { return this.getSpeciesForm(ignoreOverride).getIconAtlasKey(this.formIndex); } + getFusionIconAtlasKey(ignoreOverride?: boolean): string { + return this.getFusionSpeciesForm(ignoreOverride).getIconAtlasKey(this.fusionFormIndex); + } + getIconId(ignoreOverride?: boolean): string { return this.getSpeciesForm(ignoreOverride).getIconId(this.getGender(ignoreOverride) === Gender.FEMALE, this.formIndex, this.isShiny()); } + getFusionIconId(ignoreOverride?: boolean): string { + return this.getFusionSpeciesForm(ignoreOverride).getIconId(this.getFusionGender(ignoreOverride) === Gender.FEMALE, this.fusionFormIndex, this.isShiny()); + } + getSpeciesForm(ignoreOverride?: boolean): PokemonSpeciesForm { if (!ignoreOverride && this.summonData?.speciesForm) return this.summonData.speciesForm; diff --git a/src/modifier/modifier.ts b/src/modifier/modifier.ts index c829d5a44..10a88d950 100644 --- a/src/modifier/modifier.ts +++ b/src/modifier/modifier.ts @@ -455,11 +455,7 @@ export abstract class PokemonHeldItemModifier extends PersistentModifier { if (!forSummary) { const pokemon = this.getPokemon(scene); - const isIconShown = pokemon instanceof PlayerPokemon || scene.currentBattle.seenEnemyPartyMemberIds.has(pokemon.id); - const iconAtlasKey = isIconShown ? pokemon.getIconAtlasKey() : 'pokemon_icons_0'; - const pokemonIcon = scene.add.sprite(-2, 10, iconAtlasKey); - pokemonIcon.setFrame(pokemon.getIconId()); - pokemonIcon.setOrigin(0, 0.5); + const pokemonIcon = scene.addPokemonIcon(pokemon, -2, 10, 0, 0.5); container.add(pokemonIcon); diff --git a/src/ui/party-exp-bar.ts b/src/ui/party-exp-bar.ts index 1d4734c3b..a582c7e85 100644 --- a/src/ui/party-exp-bar.ts +++ b/src/ui/party-exp-bar.ts @@ -4,7 +4,7 @@ import { TextStyle, addTextObject } from "./text"; export default class PartyExpBar extends Phaser.GameObjects.Container { private bg: Phaser.GameObjects.NineSlice; - private pokemonIcon: Phaser.GameObjects.Sprite; + private pokemonIcon: Phaser.GameObjects.Container; private expText: Phaser.GameObjects.Text; private tween: Phaser.Tweens.Tween; @@ -21,11 +21,6 @@ export default class PartyExpBar extends Phaser.GameObjects.Container { this.add(this.bg); - this.pokemonIcon = this.scene.add.sprite(1, 9, 'pokemon_icons_0'); - this.pokemonIcon.setOrigin(0, 0.5); - this.pokemonIcon.setScale(0.5); - this.add(this.pokemonIcon); - this.expText = addTextObject(this.scene, 22, 4, '', TextStyle.BATTLE_INFO); this.expText.setOrigin(0, 0); this.add(this.expText); @@ -39,8 +34,11 @@ export default class PartyExpBar extends Phaser.GameObjects.Container { if (this.shown) return resolve(); - this.pokemonIcon.setTexture(pokemon.getIconAtlasKey()); - this.pokemonIcon.setFrame(pokemon.getIconId()); + this.pokemonIcon = (this.scene as BattleScene).addPokemonIcon(pokemon, -8, 15, 0, 0.5); + this.pokemonIcon.setScale(0.5); + + this.add(this.pokemonIcon); + this.expText.setText(`+${expValue.toString()}`); this.bg.width = this.expText.displayWidth + 28; @@ -83,6 +81,7 @@ export default class PartyExpBar extends Phaser.GameObjects.Container { this.tween = null; this.shown = false; this.setVisible(false); + this.pokemonIcon?.destroy(); resolve(); } }); diff --git a/src/ui/party-ui-handler.ts b/src/ui/party-ui-handler.ts index 839245021..834b994a0 100644 --- a/src/ui/party-ui-handler.ts +++ b/src/ui/party-ui-handler.ts @@ -795,7 +795,7 @@ class PartySlot extends Phaser.GameObjects.Container { private slotBg: Phaser.GameObjects.Image; private slotPb: Phaser.GameObjects.Sprite; - private pokemonIcon: Phaser.GameObjects.Sprite; + private pokemonIcon: Phaser.GameObjects.Container; private iconAnimHandler: PokemonIconAnimHandler; constructor(scene: BattleScene, slotIndex: integer, pokemon: PlayerPokemon, iconAnimHandler: PokemonIconAnimHandler, partyUiMode: PartyUiMode, tmMoveId: Moves) { @@ -825,8 +825,7 @@ class PartySlot extends Phaser.GameObjects.Container { this.add(slotPb); - this.pokemonIcon = this.scene.add.sprite(slotPb.x, slotPb.y, this.pokemon.getIconAtlasKey(true)); - this.pokemonIcon.setFrame(this.pokemon.getIconId(true)); + this.pokemonIcon = (this.scene as BattleScene).addPokemonIcon(this.pokemon, slotPb.x, slotPb.y, 0.5, 0.5, true); this.add(this.pokemonIcon); diff --git a/src/ui/pokemon-icon-anim-handler.ts b/src/ui/pokemon-icon-anim-handler.ts index efa16f296..f1afa4353 100644 --- a/src/ui/pokemon-icon-anim-handler.ts +++ b/src/ui/pokemon-icon-anim-handler.ts @@ -8,7 +8,7 @@ export enum PokemonIconAnimMode { } export default class PokemonIconAnimHandler { - private icons: Map; + private icons: Map; private toggled: boolean; setup(scene: BattleScene): void { @@ -43,7 +43,7 @@ export default class PokemonIconAnimHandler { } } - addOrUpdate(icons: Phaser.GameObjects.Sprite | Phaser.GameObjects.Sprite[], mode: PokemonIconAnimMode): void { + addOrUpdate(icons: Phaser.GameObjects.Container | Phaser.GameObjects.Container[], mode: PokemonIconAnimMode): void { if (!Array.isArray(icons)) icons = [ icons ]; for (let i of icons) { @@ -60,7 +60,7 @@ export default class PokemonIconAnimHandler { } } - remove(icons: Phaser.GameObjects.Sprite | Phaser.GameObjects.Sprite[]): void { + remove(icons: Phaser.GameObjects.Container | Phaser.GameObjects.Container[]): void { if (!Array.isArray(icons)) icons = [ icons ]; for (let i of icons) { diff --git a/src/ui/save-slot-select-ui-handler.ts b/src/ui/save-slot-select-ui-handler.ts index aca844c39..054bb1ab9 100644 --- a/src/ui/save-slot-select-ui-handler.ts +++ b/src/ui/save-slot-select-ui-handler.ts @@ -242,8 +242,7 @@ class SessionSlot extends Phaser.GameObjects.Container { iconContainer.setScale(0.75); const pokemon = p.toPokemon(this.scene); - const icon = this.scene.add.sprite(0, 0, pokemon.getIconAtlasKey(), pokemon.getIconId()); - icon.setOrigin(0, 0); + const icon = this.scene.addPokemonIcon(pokemon, 0, 0, 0, 0); const text = addTextObject(this.scene, 32, 20, `Lv${Utils.formatLargeNumber(pokemon.level, 1000)}`, TextStyle.PARTY, { fontSize: '54px', color: '#f8f8f8' }); text.setShadow(0, 0, null);