Update modifier bar display to avoid clutter and improve performance

This commit is contained in:
Flashfyre 2023-10-31 21:43:22 -04:00
parent c3734112b3
commit 74f6e9a8f2
5 changed files with 60 additions and 22 deletions

View File

@ -304,7 +304,8 @@ export class EncounterPhase extends BattlePhase {
if (startingWave > 10) { if (startingWave > 10) {
for (let m = 0; m < Math.min(Math.floor(startingWave / 10), 99); m++) 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); this.scene.arena.trySetWeather(getRandomWeatherType(this.scene.arena.biomeType), false);
@ -638,8 +639,8 @@ export class SummonPhase extends PartyMemberPokemonPhase {
if (playerPokemon?.visible) if (playerPokemon?.visible)
this.scene.field.moveBelow(pokemon, playerPokemon); this.scene.field.moveBelow(pokemon, playerPokemon);
this.scene.currentBattle.seenEnemyPartyMemberIds.add(pokemon.id); this.scene.currentBattle.seenEnemyPartyMemberIds.add(pokemon.id);
this.scene.updateModifiers(false);
} }
this.scene.updateModifiers(this.player);
pokemon.showInfo(); pokemon.showInfo();
pokemon.playAnim(); pokemon.playAnim();
pokemon.setVisible(true); pokemon.setVisible(true);
@ -2739,7 +2740,8 @@ export class AttemptCapturePhase extends PokemonPhase {
const addToParty = () => { const addToParty = () => {
const newPokemon = pokemon.addToParty(); const newPokemon = pokemon.addToParty();
const modifiers = this.scene.findModifiers(m => m instanceof PokemonHeldItemModifier, false); 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(); removePokemon();
if (newPokemon) if (newPokemon)
newPokemon.loadAssets().then(end); newPokemon.loadAssets().then(end);
@ -2893,7 +2895,7 @@ export class SelectModifierPhase extends BattlePhase {
: modifierType.newModifier(party[slotIndex], option - PartyOption.MOVE_1); : modifierType.newModifier(party[slotIndex], option - PartyOption.MOVE_1);
this.scene.ui.clearText(); this.scene.ui.clearText();
this.scene.ui.setMode(Mode.MESSAGE); this.scene.ui.setMode(Mode.MESSAGE);
this.scene.addModifier(modifier, true).then(() => super.end()); this.scene.addModifier(modifier, false, true).then(() => super.end());
}); });
} else } else
this.scene.ui.setMode(Mode.MODIFIER_SELECT, this.isPlayer(), typeOptions, modifierSelectCallback, ); this.scene.ui.setMode(Mode.MODIFIER_SELECT, this.isPlayer(), typeOptions, modifierSelectCallback, );
@ -2924,7 +2926,7 @@ export class SelectModifierPhase extends BattlePhase {
} }
addModifier(modifier: Modifier): Promise<void> { addModifier(modifier: Modifier): Promise<void> {
return this.scene.addModifier(modifier, true); return this.scene.addModifier(modifier, false, true);
} }
} }

View File

@ -1117,7 +1117,7 @@ export default class BattleScene extends Phaser.Scene {
this.phaseQueue.push(new TurnInitPhase(this)); this.phaseQueue.push(new TurnInitPhase(this));
} }
addModifier(modifier: Modifier, playSound?: boolean, virtual?: boolean): Promise<void> { addModifier(modifier: Modifier, ignoreUpdate?: boolean, playSound?: boolean, virtual?: boolean): Promise<void> {
return new Promise(resolve => { return new Promise(resolve => {
const soundName = modifier.type.soundName; const soundName = modifier.type.soundName;
if (modifier instanceof PersistentModifier) { if (modifier instanceof PersistentModifier) {
@ -1126,12 +1126,12 @@ export default class BattleScene extends Phaser.Scene {
this.playSound(soundName); this.playSound(soundName);
} else if (!virtual) { } else if (!virtual) {
const defaultModifierType = getDefaultModifierTypeForTier(modifier.type.tier); 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); this.queueMessage(`The stack for this item is full.\n You will receive ${defaultModifierType.name} instead.`, null, true);
return; return;
} }
if (!virtual) if (!ignoreUpdate && !virtual)
this.updateModifiers().then(() => resolve()); this.updateModifiers().then(() => resolve());
} else if (modifier instanceof ConsumableModifier) { } else if (modifier instanceof ConsumableModifier) {
if (playSound && !this.sound.get(soundName)) if (playSound && !this.sound.get(soundName))
@ -1167,10 +1167,13 @@ export default class BattleScene extends Phaser.Scene {
}); });
} }
addEnemyModifier(itemModifier: PersistentModifier): Promise<void> { addEnemyModifier(itemModifier: PersistentModifier, ignoreUpdate?: boolean): Promise<void> {
return new Promise(resolve => { return new Promise(resolve => {
itemModifier.add(this.enemyModifiers, false); 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 = () => { const addModifier = () => {
if (!matchingModifier || this.removeModifier(matchingModifier, !target.isPlayer())) { if (!matchingModifier || this.removeModifier(matchingModifier, !target.isPlayer())) {
if (target.isPlayer()) if (target.isPlayer())
this.addModifier(newItemModifier, playSound).then(() => resolve(true)); this.addModifier(newItemModifier, false, playSound).then(() => resolve(true));
else else
this.addEnemyModifier(newItemModifier).then(() => resolve(true)); this.addEnemyModifier(newItemModifier).then(() => resolve(true));
} else } else

View File

@ -14,20 +14,35 @@ import * as Utils from "../utils";
import { TempBattleStat } from '../data/temp-battle-stat'; import { TempBattleStat } from '../data/temp-battle-stat';
import { BerryType, getBerryEffectFunc, getBerryPredicate } from '../data/berry'; import { BerryType, getBerryEffectFunc, getBerryPredicate } from '../data/berry';
import { Species } from '../data/species'; import { Species } from '../data/species';
import { BattleType } from '../battle';
import { StatusEffect, getStatusEffectDescriptor } from '../data/status-effect'; import { StatusEffect, getStatusEffectDescriptor } from '../data/status-effect';
type ModifierType = ModifierTypes.ModifierType; type ModifierType = ModifierTypes.ModifierType;
export type ModifierPredicate = (modifier: Modifier) => boolean; export type ModifierPredicate = (modifier: Modifier) => boolean;
const iconOverflowIndex = 24;
export class ModifierBar extends Phaser.GameObjects.Container { export class ModifierBar extends Phaser.GameObjects.Container {
private player: boolean; private player: boolean;
private modifierCache: PersistentModifier[];
constructor(scene: BattleScene, enemy?: boolean) { constructor(scene: BattleScene, enemy?: boolean) {
super(scene, 1 + (enemy ? 302 : 0), 2); super(scene, 1 + (enemy ? 302 : 0), 2);
this.player = !enemy; this.player = !enemy;
this.setScale(0.5); 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[]) { 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)); const visibleIconModifiers = modifiers.filter(m => m.isIconVisible(this.scene as BattleScene));
for (let modifier of visibleIconModifiers) { visibleIconModifiers.sort((a: Modifier, b: Modifier) => {
if (!modifier.isIconVisible(this.scene as BattleScene)) const aId = a instanceof PokemonHeldItemModifier ? a.pokemonId : 4294967295;
continue; 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); const icon = modifier.getIcon(this.scene as BattleScene);
if (i >= iconOverflowIndex)
icon.setVisible(false);
this.add(icon); this.add(icon);
this.setModifierIconPosition(icon, visibleIconModifiers.length); 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) { 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 x = (this.getIndex(icon) % rowIcons) * 26 / (rowIcons / 12);
const y = Math.floor(this.getIndex(icon) / rowIcons) * 20; const y = Math.floor(this.getIndex(icon) / rowIcons) * 20;
@ -340,8 +369,7 @@ export abstract class PokemonHeldItemModifier extends PersistentModifier {
} }
isIconVisible(scene: BattleScene): boolean { isIconVisible(scene: BattleScene): boolean {
const pokemon = this.getPokemon(scene); return this.getPokemon(scene).isOnField();
return pokemon instanceof PlayerPokemon || (scene.currentBattle.battleType === BattleType.WILD || this.getPokemon(scene).isOnField());
} }
getIcon(scene: BattleScene, forSummary?: boolean): Phaser.GameObjects.Container { getIcon(scene: BattleScene, forSummary?: boolean): Phaser.GameObjects.Container {

View File

@ -1214,8 +1214,9 @@ export class PlayerPokemon extends Pokemon {
modifiers.forEach(m => { modifiers.forEach(m => {
const clonedModifier = m.clone() as PokemonHeldItemModifier; const clonedModifier = m.clone() as PokemonHeldItemModifier;
clonedModifier.pokemonId = newPokemon.id; clonedModifier.pokemonId = newPokemon.id;
this.scene.addModifier(clonedModifier); this.scene.addModifier(clonedModifier, true);
}); });
this.scene.updateModifiers(true);
} }
} }
} }

View File

@ -270,15 +270,19 @@ export class GameData {
for (let modifierData of sessionData.modifiers) { for (let modifierData of sessionData.modifiers) {
const modifier = modifierData.toModifier(scene, modifiersModule[modifierData.className]); const modifier = modifierData.toModifier(scene, modifiersModule[modifierData.className]);
if (modifier) if (modifier)
scene.addModifier(modifier); scene.addModifier(modifier, true);
} }
scene.updateModifiers(true);
for (let enemyModifierData of sessionData.enemyModifiers) { for (let enemyModifierData of sessionData.enemyModifiers) {
const modifier = enemyModifierData.toModifier(scene, modifiersModule[enemyModifierData.className]); const modifier = enemyModifierData.toModifier(scene, modifiersModule[enemyModifierData.className]);
if (modifier) if (modifier)
scene.addEnemyModifier(modifier); scene.addEnemyModifier(modifier, true);
} }
scene.updateModifiers(false);
Promise.all(loadPokemonAssets).then(() => resolve(true)); Promise.all(loadPokemonAssets).then(() => resolve(true));
} catch (err) { } catch (err) {
reject(err); reject(err);