diff --git a/src/battle-phases.ts b/src/battle-phases.ts index 181423691..0e432ad15 100644 --- a/src/battle-phases.ts +++ b/src/battle-phases.ts @@ -304,7 +304,8 @@ export class EncounterPhase extends BattlePhase { if (startingWave > 10) { for (let m = 0; m < Math.min(Math.floor(startingWave / 10), 99); m++) - this.scene.addModifier(getPlayerModifierTypeOptionsForWave((m + 1) * 10, 1, this.scene.getParty())[0].type.newModifier()); + this.scene.addModifier(getPlayerModifierTypeOptionsForWave((m + 1) * 10, 1, this.scene.getParty())[0].type.newModifier(), true); + this.scene.updateModifiers(true); } this.scene.arena.trySetWeather(getRandomWeatherType(this.scene.arena.biomeType), false); @@ -638,8 +639,8 @@ export class SummonPhase extends PartyMemberPokemonPhase { if (playerPokemon?.visible) this.scene.field.moveBelow(pokemon, playerPokemon); this.scene.currentBattle.seenEnemyPartyMemberIds.add(pokemon.id); - this.scene.updateModifiers(false); } + this.scene.updateModifiers(this.player); pokemon.showInfo(); pokemon.playAnim(); pokemon.setVisible(true); @@ -2739,7 +2740,8 @@ export class AttemptCapturePhase extends PokemonPhase { const addToParty = () => { const newPokemon = pokemon.addToParty(); const modifiers = this.scene.findModifiers(m => m instanceof PokemonHeldItemModifier, false); - Promise.all(modifiers.map(m => this.scene.addModifier(m))).then(() => { + Promise.all(modifiers.map(m => this.scene.addModifier(m, true))).then(() => { + this.scene.updateModifiers(true); removePokemon(); if (newPokemon) newPokemon.loadAssets().then(end); @@ -2893,7 +2895,7 @@ export class SelectModifierPhase extends BattlePhase { : modifierType.newModifier(party[slotIndex], option - PartyOption.MOVE_1); this.scene.ui.clearText(); this.scene.ui.setMode(Mode.MESSAGE); - this.scene.addModifier(modifier, true).then(() => super.end()); + this.scene.addModifier(modifier, false, true).then(() => super.end()); }); } else this.scene.ui.setMode(Mode.MODIFIER_SELECT, this.isPlayer(), typeOptions, modifierSelectCallback, ); @@ -2924,7 +2926,7 @@ export class SelectModifierPhase extends BattlePhase { } addModifier(modifier: Modifier): Promise { - return this.scene.addModifier(modifier, true); + return this.scene.addModifier(modifier, false, true); } } diff --git a/src/battle-scene.ts b/src/battle-scene.ts index 4ab72ab37..e150676d2 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -1117,7 +1117,7 @@ export default class BattleScene extends Phaser.Scene { this.phaseQueue.push(new TurnInitPhase(this)); } - addModifier(modifier: Modifier, playSound?: boolean, virtual?: boolean): Promise { + addModifier(modifier: Modifier, ignoreUpdate?: boolean, playSound?: boolean, virtual?: boolean): Promise { return new Promise(resolve => { const soundName = modifier.type.soundName; if (modifier instanceof PersistentModifier) { @@ -1126,12 +1126,12 @@ export default class BattleScene extends Phaser.Scene { this.playSound(soundName); } else if (!virtual) { const defaultModifierType = getDefaultModifierTypeForTier(modifier.type.tier); - this.addModifier(defaultModifierType.newModifier(), playSound).then(() => resolve()); + this.addModifier(defaultModifierType.newModifier(), ignoreUpdate, playSound).then(() => resolve()); this.queueMessage(`The stack for this item is full.\n You will receive ${defaultModifierType.name} instead.`, null, true); return; } - if (!virtual) + if (!ignoreUpdate && !virtual) this.updateModifiers().then(() => resolve()); } else if (modifier instanceof ConsumableModifier) { if (playSound && !this.sound.get(soundName)) @@ -1167,10 +1167,13 @@ export default class BattleScene extends Phaser.Scene { }); } - addEnemyModifier(itemModifier: PersistentModifier): Promise { + addEnemyModifier(itemModifier: PersistentModifier, ignoreUpdate?: boolean): Promise { return new Promise(resolve => { itemModifier.add(this.enemyModifiers, false); - this.updateModifiers(false).then(() => resolve()); + if (!ignoreUpdate) + this.updateModifiers(false).then(() => resolve()); + else + resolve(); }); } @@ -1206,7 +1209,7 @@ export default class BattleScene extends Phaser.Scene { const addModifier = () => { if (!matchingModifier || this.removeModifier(matchingModifier, !target.isPlayer())) { if (target.isPlayer()) - this.addModifier(newItemModifier, playSound).then(() => resolve(true)); + this.addModifier(newItemModifier, false, playSound).then(() => resolve(true)); else this.addEnemyModifier(newItemModifier).then(() => resolve(true)); } else diff --git a/src/modifier/modifier.ts b/src/modifier/modifier.ts index fff887a1c..49401613b 100644 --- a/src/modifier/modifier.ts +++ b/src/modifier/modifier.ts @@ -14,20 +14,35 @@ import * as Utils from "../utils"; import { TempBattleStat } from '../data/temp-battle-stat'; import { BerryType, getBerryEffectFunc, getBerryPredicate } from '../data/berry'; import { Species } from '../data/species'; -import { BattleType } from '../battle'; import { StatusEffect, getStatusEffectDescriptor } from '../data/status-effect'; type ModifierType = ModifierTypes.ModifierType; export type ModifierPredicate = (modifier: Modifier) => boolean; +const iconOverflowIndex = 24; + export class ModifierBar extends Phaser.GameObjects.Container { private player: boolean; + private modifierCache: PersistentModifier[]; constructor(scene: BattleScene, enemy?: boolean) { super(scene, 1 + (enemy ? 302 : 0), 2); this.player = !enemy; this.setScale(0.5); + + this.setInteractive(new Phaser.Geom.Rectangle(enemy ? -320 : 0, 0, 320, 48), Phaser.Geom.Rectangle.Contains); + + const thisArg = this; + + this.on('pointerover', function () { + if (this.modifierCache && this.modifierCache.length > iconOverflowIndex) + thisArg.updateModifierOverflowVisibility(true); + }); + this.on('pointerout', function () { + if (this.modifierCache && this.modifierCache.length > iconOverflowIndex) + thisArg.updateModifierOverflowVisibility(false); + }); } updateModifiers(modifiers: PersistentModifier[]) { @@ -35,17 +50,31 @@ export class ModifierBar extends Phaser.GameObjects.Container { const visibleIconModifiers = modifiers.filter(m => m.isIconVisible(this.scene as BattleScene)); - for (let modifier of visibleIconModifiers) { - if (!modifier.isIconVisible(this.scene as BattleScene)) - continue; + visibleIconModifiers.sort((a: Modifier, b: Modifier) => { + const aId = a instanceof PokemonHeldItemModifier ? a.pokemonId : 4294967295; + const bId = b instanceof PokemonHeldItemModifier ? b.pokemonId : 4294967295; + + return aId < bId ? 1 : aId > bId ? -1 : 0; + }); + + visibleIconModifiers.forEach((modifier: PersistentModifier, i: integer) => { const icon = modifier.getIcon(this.scene as BattleScene); + if (i >= iconOverflowIndex) + icon.setVisible(false); this.add(icon); this.setModifierIconPosition(icon, visibleIconModifiers.length); - } + }); + + this.modifierCache = modifiers; + } + + updateModifierOverflowVisibility(ignoreLimit: boolean) { + for (let modifier of this.getAll().map(m => m as Phaser.GameObjects.Container).slice(iconOverflowIndex)) + modifier.setVisible(ignoreLimit); } setModifierIconPosition(icon: Phaser.GameObjects.Container, modifierCount: integer) { - let rowIcons: integer = 12 + 6 * Math.max((Math.ceil(modifierCount / 12) - 2), 0); + let rowIcons: integer = 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; @@ -340,8 +369,7 @@ export abstract class PokemonHeldItemModifier extends PersistentModifier { } isIconVisible(scene: BattleScene): boolean { - const pokemon = this.getPokemon(scene); - return pokemon instanceof PlayerPokemon || (scene.currentBattle.battleType === BattleType.WILD || this.getPokemon(scene).isOnField()); + return this.getPokemon(scene).isOnField(); } getIcon(scene: BattleScene, forSummary?: boolean): Phaser.GameObjects.Container { diff --git a/src/pokemon.ts b/src/pokemon.ts index ecdebf3b5..771ab3931 100644 --- a/src/pokemon.ts +++ b/src/pokemon.ts @@ -1214,8 +1214,9 @@ export class PlayerPokemon extends Pokemon { modifiers.forEach(m => { const clonedModifier = m.clone() as PokemonHeldItemModifier; clonedModifier.pokemonId = newPokemon.id; - this.scene.addModifier(clonedModifier); + this.scene.addModifier(clonedModifier, true); }); + this.scene.updateModifiers(true); } } } diff --git a/src/system/game-data.ts b/src/system/game-data.ts index 62d6d675e..fb6e2a57d 100644 --- a/src/system/game-data.ts +++ b/src/system/game-data.ts @@ -270,15 +270,19 @@ export class GameData { for (let modifierData of sessionData.modifiers) { const modifier = modifierData.toModifier(scene, modifiersModule[modifierData.className]); if (modifier) - scene.addModifier(modifier); + scene.addModifier(modifier, true); } + scene.updateModifiers(true); + for (let enemyModifierData of sessionData.enemyModifiers) { const modifier = enemyModifierData.toModifier(scene, modifiersModule[enemyModifierData.className]); if (modifier) - scene.addEnemyModifier(modifier); + scene.addEnemyModifier(modifier, true); } + scene.updateModifiers(false); + Promise.all(loadPokemonAssets).then(() => resolve(true)); } catch (err) { reject(err);