stash current changes

This commit is contained in:
ImperialSympathizer 2024-09-23 16:11:38 -04:00
parent 8449bfc60d
commit ec0aaaf4ca
9 changed files with 517 additions and 318 deletions

View File

@ -6,7 +6,7 @@ import { Constructor, isNullOrUndefined } from "#app/utils";
import * as Utils from "./utils";
import { ConsumableModifier, ConsumablePokemonModifier, DoubleBattleChanceBoosterModifier, ExpBalanceModifier, ExpShareModifier, FusePokemonModifier, HealingBoosterModifier, Modifier, ModifierBar, ModifierPredicate, MultipleParticipantExpBonusModifier, overrideHeldItems, overrideModifiers, PersistentModifier, PokemonExpBoosterModifier, PokemonFormChangeItemModifier, PokemonHeldItemModifier, PokemonHpRestoreModifier, PokemonIncrementingStatModifier, TerastallizeModifier, TurnHeldItemTransferModifier } from "./modifier/modifier";
import { PokeballType } from "./data/pokeball";
import { initCommonAnims, initMoveAnim, loadCommonAnimAssets, loadMoveAnimAssets, populateAnims } from "./data/battle-anims";
import { getAnimAssetKeys, getCommonAnimConfigs, getMoveAnimConfigs, initCommonAnims, initMoveAnim, loadCommonAnimAssets, loadMoveAnimAssets, populateAnims } from "./data/battle-anims";
import { Phase } from "./phase";
import { initGameSpeed } from "./system/game-speed";
import { Arena, ArenaBase } from "./field/arena";
@ -336,7 +336,7 @@ export default class BattleScene extends SceneBase {
if (variant) {
atlasPath = atlasPath.replace("variant/", "");
}
this.load.atlas(key, `images/pokemon/${variant ? "variant/" : ""}${experimental ? "exp/" : ""}${atlasPath}.png`, `images/pokemon/${variant ? "variant/" : ""}${experimental ? "exp/" : ""}${atlasPath}.json`);
this.load.atlas(key, this.getCachedUrl(`images/pokemon/${variant ? "variant/" : ""}${experimental ? "exp/" : ""}${atlasPath}.png`), this.getCachedUrl(`images/pokemon/${variant ? "variant/" : ""}${experimental ? "exp/" : ""}${atlasPath}.json`));
}
async preload() {
@ -2207,6 +2207,49 @@ export default class BattleScene extends SceneBase {
return 0;
}
clearUnusedAssets() {
// Get manifest of assets that are used by the player's party Pokemon or general-use
// These should not be unloaded
const backgrounds = new Set<string>();
const sounds = new Set<string>();
const graphics = new Set<string>();
// Player Pokemon assets and Enemy Pokemon assets for upcoming battle
const allPokemon: Pokemon[] = [...this.getParty(), ...this.getEnemyParty()];
for (const p of allPokemon) {
// Move assets
const animConfigs = getMoveAnimConfigs(p.getMoveset().filter(m => !!m).map(m => m.getMove().id));
getAnimAssetKeys(animConfigs, sounds, backgrounds, graphics);
// Cry
sounds.add(`cry/${p.getSpeciesForm().getCryKey(p.formIndex)}`);
// Sprite assets
let spriteKey = p.getSpeciesForm().getSpriteKey(p.getGender() === Gender.FEMALE, p.formIndex, p.shiny, p.variant);
graphics.add(spriteKey);
let spriteBackKey = spriteKey.replace("pkmn__", "pkmn__back__");
graphics.add(spriteBackKey);
if (p.getFusionSpeciesForm()) {
spriteKey = p.getFusionSpeciesForm().getSpriteKey(p.getGender() === Gender.FEMALE, p.formIndex, p.shiny, p.variant);
graphics.add(spriteKey);
spriteBackKey = spriteKey.replace("pkmn__", "pkmn__back__");
graphics.add(spriteBackKey);
}
}
// Common Move assets
getAnimAssetKeys(getCommonAnimConfigs(), sounds, backgrounds, graphics);
// Current Biome BGM
sounds.add(this.arena.bgm);
// Rival sprites
graphics.add("rival_m");
graphics.add("rival_f");
this.clearAssets(sounds, backgrounds, graphics);
}
toggleInvert(invert: boolean): void {
if (invert) {
this.cameras.main.setPostPipeline(InvertPostFX);

View File

@ -620,10 +620,15 @@ function populateMoveChargeAnim(chargeAnim: ChargeAnim, animSource: any) {
export function loadCommonAnimAssets(scene: BattleScene, startLoad?: boolean): Promise<void> {
return new Promise(resolve => {
loadAnimAssets(scene, Array.from(commonAnims.values()), startLoad).then(() => resolve());
const animConfigs = getCommonAnimConfigs();
loadAnimAssets(scene, animConfigs, startLoad).then(() => resolve());
});
}
export function getCommonAnimConfigs() {
return Array.from(commonAnims.values());
}
/**
* Loads encounter animation assets to scene
* MUST be called after {@linkcode initEncounterAnims()} to load all required animations properly
@ -634,51 +639,46 @@ export async function loadEncounterAnimAssets(scene: BattleScene, startLoad?: bo
await loadAnimAssets(scene, Array.from(encounterAnims.values()), startLoad);
}
export function loadMoveAnimAssets(scene: BattleScene, moveIds: Moves[], startLoad?: boolean): Promise<void> {
return new Promise(resolve => {
const moveAnimations = moveIds.map(m => moveAnims.get(m) as AnimConfig).flat();
for (const moveId of moveIds) {
const chargeAttr = allMoves[moveId].getAttrs(ChargeAttr)[0]
|| allMoves[moveId].getAttrs(DelayedAttackAttr)[0]
|| allMoves[moveId].getAttrs(BeakBlastHeaderAttr)[0];
if (chargeAttr) {
const moveChargeAnims = chargeAnims.get(chargeAttr.chargeAnim);
moveAnimations.push(moveChargeAnims instanceof AnimConfig ? moveChargeAnims : moveChargeAnims![0]); // TODO: is the bang correct?
if (Array.isArray(moveChargeAnims)) {
moveAnimations.push(moveChargeAnims[1]);
}
export async function loadMoveAnimAssets(scene: BattleScene, moveIds: Moves[], startLoad?: boolean): Promise<void> {
const moveAnimations = getMoveAnimConfigs(moveIds);
await loadAnimAssets(scene, moveAnimations, startLoad);
}
export function getMoveAnimConfigs(moveIds: Moves[]): AnimConfig[] {
const moveAnimations: AnimConfig[] = moveIds.map(m => moveAnims.get(m) as AnimConfig).flat();
for (const moveId of moveIds) {
const chargeAttr = allMoves[moveId].getAttrs(ChargeAttr)[0]
|| allMoves[moveId].getAttrs(DelayedAttackAttr)[0]
|| allMoves[moveId].getAttrs(BeakBlastHeaderAttr)[0];
if (chargeAttr) {
const moveChargeAnims = chargeAnims.get(chargeAttr.chargeAnim);
moveAnimations.push(moveChargeAnims instanceof AnimConfig ? moveChargeAnims : moveChargeAnims![0]); // TODO: is the bang correct?
if (Array.isArray(moveChargeAnims)) {
moveAnimations.push(moveChargeAnims[1]);
}
}
loadAnimAssets(scene, moveAnimations, startLoad).then(() => resolve());
});
}
return moveAnimations;
}
function loadAnimAssets(scene: BattleScene, anims: AnimConfig[], startLoad?: boolean): Promise<void> {
return new Promise(resolve => {
const backgrounds = new Set<string>();
const sounds = new Set<string>();
for (const a of anims) {
if (!a.frames?.length) {
continue;
}
const animSounds = a.getSoundResourceNames();
for (const ms of animSounds) {
sounds.add(ms);
}
const animBackgrounds = a.getBackgroundResourceNames();
for (const abg of animBackgrounds) {
backgrounds.add(abg);
}
if (a.graphic) {
scene.loadSpritesheet(a.graphic, "battle_anims", 96);
}
}
const graphics = new Set<string>();
getAnimAssetKeys(anims, sounds, backgrounds, graphics);
for (const bg of backgrounds) {
scene.loadImage(bg, "battle_anims");
}
for (const s of sounds) {
scene.loadSe(s, "battle_anims", s);
}
for (const g of graphics) {
scene.loadSpritesheet(g, "battle_anims", 96);
}
if (startLoad) {
scene.load.once(Phaser.Loader.Events.COMPLETE, () => resolve());
if (!scene.load.isLoading()) {
@ -690,6 +690,33 @@ function loadAnimAssets(scene: BattleScene, anims: AnimConfig[], startLoad?: boo
});
}
/**
* Gets the asset keys for the specified {@linkcode AnimConfig}s.
* Passes the keys by reference via `backgrounds` and `sounds`.
* @param anims
* @param backgrounds Returns Set of image keys passed by reference
* @param sounds Returns Set of sound effect keys passed by reference
* @param graphics Returns Set of graphics keys passed by reference
*/
export function getAnimAssetKeys(anims: AnimConfig[], sounds: Set<string>, backgrounds: Set<string>, graphics: Set<string>): void {
for (const a of anims) {
if (!a || !a.frames?.length) {
continue;
}
const animSounds = a.getSoundResourceNames();
for (const ms of animSounds) {
sounds.add(ms);
}
const animBackgrounds = a.getBackgroundResourceNames();
for (const abg of animBackgrounds) {
backgrounds.add(abg);
}
if (a.graphic) {
graphics.add(a.graphic);
}
}
}
interface GraphicFrameData {
x: number,
y: number,

View File

@ -59,3 +59,160 @@ export const allDefaultSeAssets: Map<string, string | undefined> = new Map<strin
["PRSFX- Transform", "battle_anims"]
]);
export const allDefaultImageAssets: Map<string, string | string[]> = new Map<string, string | string[]>([
["loading_bg", "arenas"],
["logo", ""],
["candy", "ui"],
["candy_overlay", "ui"],
["cursor", "ui"],
["cursor_reverse", "ui"],
["pbinfo_player", "ui"],
["pbinfo_player_stats", "ui"],
["pbinfo_player_mini", "ui"],
["pbinfo_player_mini_stats", "ui"],
["pbinfo_enemy_mini", "ui"],
["pbinfo_enemy_mini_stats", "ui"],
["pbinfo_enemy_boss", "ui"],
["pbinfo_enemy_boss_stats", "ui"],
["overlay_lv", "ui"],
["overlay_exp", "ui"],
["icon_owned", "ui"],
["icon_egg_move", "ui"],
["ability_bar_left", "ui"],
["bgm_bar", "ui"],
["party_exp_bar", "ui"],
["achv_bar", "ui"],
["achv_bar_2", "ui"],
["achv_bar_3", "ui"],
["achv_bar_4", "ui"],
["achv_bar_5", "ui"],
["shiny_star", ["ui", "shiny.png"]],
["shiny_star_1", ["ui", "shiny_1.png"]],
["shiny_star_2", ["ui", "shiny_2.png"]],
["shiny_star_small", ["ui", "shiny_small.png"]],
["shiny_star_small_1", ["ui", "shiny_small_1.png"]],
["shiny_star_small_2", ["ui", "shiny_small_2.png"]],
["favorite", ["ui", "favorite.png"]],
["passive_bg", ["ui", "passive_bg.png"]],
["ha_capsule", ["ui", "ha_capsule.png"]],
["champion_ribbon", ["ui", "champion_ribbon.png"]],
["icon_spliced", "ui"],
["icon_lock", ["ui", "icon_lock.png"]],
["icon_stop", ["ui", "icon_stop.png"]],
["icon_tera", "ui"],
["type_tera", "ui"],
["dawn_icon_fg", "ui"],
["dawn_icon_mg", "ui"],
["dawn_icon_bg", "ui"],
["day_icon_fg", "ui"],
["day_icon_mg", "ui"],
["day_icon_bg", "ui"],
["dusk_icon_fg", "ui"],
["dusk_icon_mg", "ui"],
["dusk_icon_bg", "ui"],
["night_icon_fg", "ui"],
["night_icon_mg", "ui"],
["night_icon_bg", "ui"],
["pb_tray_overlay_player", "ui"],
["pb_tray_overlay_enemy", "ui"],
["party_bg", "ui"],
["party_bg_double", "ui"],
["party_slot_overlay_lv", "ui"],
["party_slot_hp_bar", "ui"],
["summary_bg", "ui"],
["summary_overlay_shiny", "ui"],
["summary_profile", "ui"],
["summary_profile_prompt_z", "ui"], // The pixel Z button prompt
["summary_profile_prompt_a", "ui"], // The pixel A button prompt
["summary_profile_ability", "ui"], // Pixel text 'ABILITY'
["summary_profile_passive", "ui"], // Pixel text 'PASSIVE'
["summary_status", "ui"],
["summary_stats", "ui"],
["summary_stats_overlay_exp", "ui"],
["summary_moves", "ui"],
["summary_moves_effect", "ui"],
["summary_moves_overlay_row", "ui"],
["summary_moves_overlay_pp", "ui"],
["scroll_bar", "ui"],
["scroll_bar_handle", "ui"],
["starter_container_bg", "ui"],
["starter_select_bg", "ui"],
["select_cursor", "ui"],
["select_cursor_highlight", "ui"],
["select_cursor_highlight_thick", "ui"],
["select_cursor_pokerus", "ui"],
["select_gen_cursor", "ui"],
["select_gen_cursor_highlight", "ui"],
["saving_icon", "ui"],
["discord", "ui"],
["google", "ui"],
["settings_icon", "ui"],
["default_bg", "arenas"],
["pkmn__back__sub", ["pokemon/back", "sub.png"]],
["pkmn__sub", ["pokemon", "sub.png"]],
["tera", "effects"],
["evo_sparkle", "effects"],
["gacha_glass", "egg"],
["gacha_eggs", "egg"],
["gacha_knob", "egg"],
["egg_list_bg", "ui"],
["egg_summary_bg", "ui"],
["end_m", "cg"],
["end_f", "cg"],
["encounter_radar", "mystery-encounters"],
]);
export const allDefaultAtlasAssets: Map<string, string | string[]> = new Map<string, string | string[]>([
["bg", "ui"],
["prompt", "ui"],
["namebox", "ui"],
["pbinfo_player_type", "ui"],
["pbinfo_player_type1", "ui"],
["pbinfo_player_type2", "ui"],
["pbinfo_enemy_type", "ui"],
["pbinfo_enemy_type1", "ui"],
["pbinfo_enemy_type2", "ui"],
["pbinfo_stat", "ui"],
["pbinfo_stat_numbers", "ui"],
["numbers", "ui"],
["numbers_red", "ui"],
["overlay_hp", "ui"],
["overlay_hp_boss", "ui"],
["shiny_icons", "ui"],
["type_bgs", "ui"],
["pb_tray_ball", "ui"],
["party_slot_main", "ui"],
["party_slot", "ui"],
["party_slot_hp_overlay", "ui"],
["party_pb", "ui"],
["party_cancel", "ui"],
["summary_moves_cursor", "ui"],
// Load character sprites
["trainer_m_back", "trainer"],
["trainer_m_back_pb", "trainer"],
["trainer_f_back", "trainer"],
["trainer_f_back_pb", "trainer"],
["c_rival_m", ["character", "rival_m"]],
["c_rival_f", ["character", "rival_f"]],
// Load pokemon-related images
["battle_stats", "effects"],
["shiny", "effects"],
["shiny_2", "effects"],
["shiny_3", "effects"],
["pb_particles", "effects"],
["tera_sparkle", "effects"],
["pb", ""],
["items", ""],
["types", ""],
["statuses", ""],
["categories", ""],
["egg", "egg"],
["egg_crack", "egg"],
["egg_icons", "egg"],
["egg_shard", "egg"],
["egg_lightrays", "egg"],
["gacha_hatch", "egg"],
["dualshock", "inputs"],
["xbox", "inputs"],
["keyboard", "inputs"],
]);

View File

@ -1,36 +1,35 @@
import Phaser from "phaser";
import BattleScene, { AnySound } from "../battle-scene";
import { Variant, VariantSet, variantColorCache } from "#app/data/variant";
import { variantData } from "#app/data/variant";
import BattleInfo, { PlayerBattleInfo, EnemyBattleInfo } from "../ui/battle-info";
import Move, { HighCritAttr, HitsTagAttr, applyMoveAttrs, FixedDamageAttr, VariableAtkAttr, allMoves, MoveCategory, TypelessAttr, CritOnlyAttr, getMoveTargets, OneHitKOAttr, VariableMoveTypeAttr, VariableDefAttr, AttackMove, ModifiedDamageAttr, VariableMoveTypeMultiplierAttr, IgnoreOpponentStatStagesAttr, SacrificialAttr, VariableMoveCategoryAttr, CounterDamageAttr, StatStageChangeAttr, RechargeAttr, ChargeAttr, IgnoreWeatherTypeDebuffAttr, BypassBurnDamageReductionAttr, SacrificialAttrOnHit, OneHitKOAccuracyAttr, RespectAttackTypeImmunityAttr, MoveTarget } from "../data/move";
import { default as PokemonSpecies, PokemonSpeciesForm, SpeciesFormKey, getFusedSpeciesName, getPokemonSpecies, getPokemonSpeciesForm, getStarterValueFriendshipCap, speciesStarters, starterPassiveAbilities } from "../data/pokemon-species";
import { Variant, variantColorCache, variantData, VariantSet } from "#app/data/variant";
import BattleInfo, { EnemyBattleInfo, PlayerBattleInfo } from "../ui/battle-info";
import Move, { allMoves, applyMoveAttrs, AttackMove, BypassBurnDamageReductionAttr, ChargeAttr, CounterDamageAttr, CritOnlyAttr, FixedDamageAttr, getMoveTargets, HighCritAttr, HitsTagAttr, IgnoreOpponentStatStagesAttr, IgnoreWeatherTypeDebuffAttr, ModifiedDamageAttr, MoveCategory, MoveTarget, OneHitKOAccuracyAttr, OneHitKOAttr, RechargeAttr, RespectAttackTypeImmunityAttr, SacrificialAttr, SacrificialAttrOnHit, StatStageChangeAttr, TypelessAttr, VariableAtkAttr, VariableDefAttr, VariableMoveCategoryAttr, VariableMoveTypeAttr, VariableMoveTypeMultiplierAttr } from "../data/move";
import { default as PokemonSpecies, getFusedSpeciesName, getPokemonSpecies, getPokemonSpeciesForm, getStarterValueFriendshipCap, PokemonSpeciesForm, SpeciesFormKey, speciesStarters, starterPassiveAbilities } from "../data/pokemon-species";
import { Constructor, isNullOrUndefined, randSeedInt } from "#app/utils";
import * as Utils from "../utils";
import { Type, TypeDamageMultiplier, getTypeDamageMultiplier, getTypeRgb } from "../data/type";
import { getTypeDamageMultiplier, getTypeRgb, Type, TypeDamageMultiplier } from "../data/type";
import { getLevelTotalExp } from "../data/exp";
import { Stat, type PermanentStat, type BattleStat, type EffectiveStat, PERMANENT_STATS, BATTLE_STATS, EFFECTIVE_STATS } from "#enums/stat";
import { DamageMoneyRewardModifier, EnemyDamageBoosterModifier, EnemyDamageReducerModifier, EnemyEndureChanceModifier, EnemyFusionChanceModifier, HiddenAbilityRateBoosterModifier, BaseStatModifier, PokemonFriendshipBoosterModifier, PokemonHeldItemModifier, PokemonNatureWeightModifier, ShinyRateBoosterModifier, SurviveDamageModifier, TempStatStageBoosterModifier, TempCritBoosterModifier, StatBoosterModifier, CritBoosterModifier, TerastallizeModifier, PokemonBaseStatFlatModifier, PokemonBaseStatTotalModifier, PokemonIncrementingStatModifier, EvoTrackerModifier } from "../modifier/modifier";
import { BATTLE_STATS, type BattleStat, EFFECTIVE_STATS, type EffectiveStat, PERMANENT_STATS, type PermanentStat, Stat } from "#enums/stat";
import { BaseStatModifier, CritBoosterModifier, DamageMoneyRewardModifier, EnemyDamageBoosterModifier, EnemyDamageReducerModifier, EnemyEndureChanceModifier, EnemyFusionChanceModifier, EvoTrackerModifier, HiddenAbilityRateBoosterModifier, PokemonBaseStatFlatModifier, PokemonBaseStatTotalModifier, PokemonFriendshipBoosterModifier, PokemonHeldItemModifier, PokemonIncrementingStatModifier, PokemonNatureWeightModifier, ShinyRateBoosterModifier, StatBoosterModifier, SurviveDamageModifier, TempCritBoosterModifier, TempStatStageBoosterModifier, TerastallizeModifier } from "../modifier/modifier";
import { PokeballType } from "../data/pokeball";
import { Gender } from "../data/gender";
import { initMoveAnim, loadMoveAnimAssets } from "../data/battle-anims";
import { Status, StatusEffect, getRandomStatus } from "../data/status-effect";
import { pokemonEvolutions, pokemonPrevolutions, SpeciesFormEvolution, SpeciesEvolutionCondition, FusionSpeciesFormEvolution } from "../data/pokemon-evolutions";
import { reverseCompatibleTms, tmSpecies, tmPoolTiers } from "../data/tms";
import { BattlerTag, BattlerTagLapseType, EncoreTag, GroundedTag, HighestStatBoostTag, SubstituteTag, TypeImmuneTag, getBattlerTag, SemiInvulnerableTag, TypeBoostTag, MoveRestrictionBattlerTag, ExposedTag, DragonCheerTag, CritBoostTag, TrappedTag, TarShotTag } from "../data/battler-tags";
import { getRandomStatus, Status, StatusEffect } from "../data/status-effect";
import { FusionSpeciesFormEvolution, pokemonEvolutions, pokemonPrevolutions, SpeciesEvolutionCondition, SpeciesFormEvolution } from "../data/pokemon-evolutions";
import { reverseCompatibleTms, tmPoolTiers, tmSpecies } from "../data/tms";
import { BattlerTag, BattlerTagLapseType, CritBoostTag, DragonCheerTag, EncoreTag, ExposedTag, getBattlerTag, GroundedTag, HighestStatBoostTag, MoveRestrictionBattlerTag, SemiInvulnerableTag, SubstituteTag, TarShotTag, TrappedTag, TypeBoostTag, TypeImmuneTag } from "../data/battler-tags";
import { WeatherType } from "../data/weather";
import { ArenaTagSide, NoCritTag, WeakenMoveScreenTag } from "../data/arena-tag";
import { Ability, AbAttr, StatMultiplierAbAttr, BlockCritAbAttr, BonusCritAbAttr, BypassBurnDamageReductionAbAttr, FieldPriorityMoveImmunityAbAttr, IgnoreOpponentStatStagesAbAttr, MoveImmunityAbAttr, PreDefendFullHpEndureAbAttr, ReceivedMoveDamageMultiplierAbAttr, ReduceStatusEffectDurationAbAttr, StabBoostAbAttr, StatusEffectImmunityAbAttr, TypeImmunityAbAttr, WeightMultiplierAbAttr, allAbilities, applyAbAttrs, applyStatMultiplierAbAttrs, applyPreApplyBattlerTagAbAttrs, applyPreAttackAbAttrs, applyPreDefendAbAttrs, applyPreSetStatusAbAttrs, UnsuppressableAbilityAbAttr, SuppressFieldAbilitiesAbAttr, NoFusionAbilityAbAttr, MultCritAbAttr, IgnoreTypeImmunityAbAttr, DamageBoostAbAttr, IgnoreTypeStatusEffectImmunityAbAttr, ConditionalCritAbAttr, applyFieldStatMultiplierAbAttrs, FieldMultiplyStatAbAttr, AddSecondStrikeAbAttr, UserFieldStatusEffectImmunityAbAttr, UserFieldBattlerTagImmunityAbAttr, BattlerTagImmunityAbAttr, MoveTypeChangeAbAttr, FullHpResistTypeAbAttr, applyCheckTrappedAbAttrs, CheckTrappedAbAttr } from "../data/ability";
import { AbAttr, Ability, AddSecondStrikeAbAttr, allAbilities, applyAbAttrs, applyCheckTrappedAbAttrs, applyFieldStatMultiplierAbAttrs, applyPreApplyBattlerTagAbAttrs, applyPreAttackAbAttrs, applyPreDefendAbAttrs, applyPreSetStatusAbAttrs, applyStatMultiplierAbAttrs, BattlerTagImmunityAbAttr, BlockCritAbAttr, BonusCritAbAttr, BypassBurnDamageReductionAbAttr, CheckTrappedAbAttr, ConditionalCritAbAttr, DamageBoostAbAttr, FieldMultiplyStatAbAttr, FieldPriorityMoveImmunityAbAttr, FullHpResistTypeAbAttr, IgnoreOpponentStatStagesAbAttr, IgnoreTypeImmunityAbAttr, IgnoreTypeStatusEffectImmunityAbAttr, MoveImmunityAbAttr, MoveTypeChangeAbAttr, MultCritAbAttr, NoFusionAbilityAbAttr, PreDefendFullHpEndureAbAttr, ReceivedMoveDamageMultiplierAbAttr, ReduceStatusEffectDurationAbAttr, StabBoostAbAttr, StatMultiplierAbAttr, StatusEffectImmunityAbAttr, SuppressFieldAbilitiesAbAttr, TypeImmunityAbAttr, UnsuppressableAbilityAbAttr, UserFieldBattlerTagImmunityAbAttr, UserFieldStatusEffectImmunityAbAttr, WeightMultiplierAbAttr } from "../data/ability";
import PokemonData from "../system/pokemon-data";
import { BattlerIndex } from "../battle";
import { Mode } from "../ui/ui";
import PartyUiHandler, { PartyOption, PartyUiMode } from "../ui/party-ui-handler";
import SoundFade from "phaser3-rex-plugins/plugins/soundfade";
import { LevelMoves } from "../data/pokemon-level-moves";
import { DamageAchv, achvs } from "../system/achv";
import { achvs, DamageAchv } from "../system/achv";
import { DexAttr, StarterDataEntry, StarterMoveset } from "../system/game-data";
import { QuantizerCelebi, argbFromRgba, rgbaFromArgb } from "@material/material-color-utilities";
import { Nature, getNatureStatMultiplier } from "../data/nature";
import { argbFromRgba, QuantizerCelebi, rgbaFromArgb } from "@material/material-color-utilities";
import { getNatureStatMultiplier, Nature } from "../data/nature";
import { SpeciesFormChange, SpeciesFormChangeActiveTrigger, SpeciesFormChangeMoveLearnedTrigger, SpeciesFormChangePostMoveTrigger, SpeciesFormChangeStatusEffectTrigger } from "../data/pokemon-forms";
import { TerrainType } from "../data/terrain";
import { TrainerSlot } from "../data/trainer-config";

View File

@ -1,5 +1,4 @@
import { GachaType } from "./enums/gacha-types";
import { trainerConfigs } from "./data/trainer-config";
import { getBiomeHasProps } from "./field/arena";
import CacheBustedLoaderPlugin from "./plugins/cache-busted-loader-plugin";
import { SceneBase } from "./scene-base";
@ -21,9 +20,8 @@ import i18next from "i18next";
import { initStatsKeys } from "./ui/game-stats-ui-handler";
import { initVouchers } from "./system/voucher";
import { Biome } from "#enums/biome";
import { TrainerType } from "#enums/trainer-type";
import {initMysteryEncounters} from "#app/data/mystery-encounters/mystery-encounters";
import { allDefaultBgmAssets, allDefaultSeAssets } from "#app/default-assets";
import { allDefaultAtlasAssets, allDefaultBgmAssets, allDefaultImageAssets, allDefaultSeAssets } from "#app/default-assets";
export class LoadingScene extends SceneBase {
public static readonly KEY = "loading";
@ -38,266 +36,10 @@ export class LoadingScene extends SceneBase {
}
preload() {
this.logPartitionedStorageSize();
Utils.localPing();
this.load["manifest"] = this.game["manifest"];
this.loadImage("loading_bg", "arenas");
this.loadImage("logo", "");
// Load menu images
this.loadAtlas("bg", "ui");
this.loadAtlas("prompt", "ui");
this.loadImage("candy", "ui");
this.loadImage("candy_overlay", "ui");
this.loadImage("cursor", "ui");
this.loadImage("cursor_reverse", "ui");
for (const wv of Utils.getEnumValues(WindowVariant)) {
for (let w = 1; w <= 5; w++) {
this.loadImage(`window_${w}${getWindowVariantSuffix(wv)}`, "ui/windows");
}
}
this.loadAtlas("namebox", "ui");
this.loadImage("pbinfo_player", "ui");
this.loadImage("pbinfo_player_stats", "ui");
this.loadImage("pbinfo_player_mini", "ui");
this.loadImage("pbinfo_player_mini_stats", "ui");
this.loadAtlas("pbinfo_player_type", "ui");
this.loadAtlas("pbinfo_player_type1", "ui");
this.loadAtlas("pbinfo_player_type2", "ui");
this.loadImage("pbinfo_enemy_mini", "ui");
this.loadImage("pbinfo_enemy_mini_stats", "ui");
this.loadImage("pbinfo_enemy_boss", "ui");
this.loadImage("pbinfo_enemy_boss_stats", "ui");
this.loadAtlas("pbinfo_enemy_type", "ui");
this.loadAtlas("pbinfo_enemy_type1", "ui");
this.loadAtlas("pbinfo_enemy_type2", "ui");
this.loadAtlas("pbinfo_stat", "ui");
this.loadAtlas("pbinfo_stat_numbers", "ui");
this.loadImage("overlay_lv", "ui");
this.loadAtlas("numbers", "ui");
this.loadAtlas("numbers_red", "ui");
this.loadAtlas("overlay_hp", "ui");
this.loadAtlas("overlay_hp_boss", "ui");
this.loadImage("overlay_exp", "ui");
this.loadImage("icon_owned", "ui");
this.loadImage("icon_egg_move", "ui");
this.loadImage("ability_bar_left", "ui");
this.loadImage("bgm_bar", "ui");
this.loadImage("party_exp_bar", "ui");
this.loadImage("achv_bar", "ui");
this.loadImage("achv_bar_2", "ui");
this.loadImage("achv_bar_3", "ui");
this.loadImage("achv_bar_4", "ui");
this.loadImage("achv_bar_5", "ui");
this.loadImage("shiny_star", "ui", "shiny.png");
this.loadImage("shiny_star_1", "ui", "shiny_1.png");
this.loadImage("shiny_star_2", "ui", "shiny_2.png");
this.loadImage("shiny_star_small", "ui", "shiny_small.png");
this.loadImage("shiny_star_small_1", "ui", "shiny_small_1.png");
this.loadImage("shiny_star_small_2", "ui", "shiny_small_2.png");
this.loadImage("favorite", "ui", "favorite.png");
this.loadImage("passive_bg", "ui", "passive_bg.png");
this.loadAtlas("shiny_icons", "ui");
this.loadImage("ha_capsule", "ui", "ha_capsule.png");
this.loadImage("champion_ribbon", "ui", "champion_ribbon.png");
this.loadImage("icon_spliced", "ui");
this.loadImage("icon_lock", "ui", "icon_lock.png");
this.loadImage("icon_stop", "ui", "icon_stop.png");
this.loadImage("icon_tera", "ui");
this.loadImage("type_tera", "ui");
this.loadAtlas("type_bgs", "ui");
this.loadImage("dawn_icon_fg", "ui");
this.loadImage("dawn_icon_mg", "ui");
this.loadImage("dawn_icon_bg", "ui");
this.loadImage("day_icon_fg", "ui");
this.loadImage("day_icon_mg", "ui");
this.loadImage("day_icon_bg", "ui");
this.loadImage("dusk_icon_fg", "ui");
this.loadImage("dusk_icon_mg", "ui");
this.loadImage("dusk_icon_bg", "ui");
this.loadImage("night_icon_fg", "ui");
this.loadImage("night_icon_mg", "ui");
this.loadImage("night_icon_bg", "ui");
this.loadImage("pb_tray_overlay_player", "ui");
this.loadImage("pb_tray_overlay_enemy", "ui");
this.loadAtlas("pb_tray_ball", "ui");
this.loadImage("party_bg", "ui");
this.loadImage("party_bg_double", "ui");
this.loadAtlas("party_slot_main", "ui");
this.loadAtlas("party_slot", "ui");
this.loadImage("party_slot_overlay_lv", "ui");
this.loadImage("party_slot_hp_bar", "ui");
this.loadAtlas("party_slot_hp_overlay", "ui");
this.loadAtlas("party_pb", "ui");
this.loadAtlas("party_cancel", "ui");
this.loadImage("summary_bg", "ui");
this.loadImage("summary_overlay_shiny", "ui");
this.loadImage("summary_profile", "ui");
this.loadImage("summary_profile_prompt_z", "ui"); // The pixel Z button prompt
this.loadImage("summary_profile_prompt_a", "ui"); // The pixel A button prompt
this.loadImage("summary_profile_ability", "ui"); // Pixel text 'ABILITY'
this.loadImage("summary_profile_passive", "ui"); // Pixel text 'PASSIVE'
this.loadImage("summary_status", "ui");
this.loadImage("summary_stats", "ui");
this.loadImage("summary_stats_overlay_exp", "ui");
this.loadImage("summary_moves", "ui");
this.loadImage("summary_moves_effect", "ui");
this.loadImage("summary_moves_overlay_row", "ui");
this.loadImage("summary_moves_overlay_pp", "ui");
this.loadAtlas("summary_moves_cursor", "ui");
for (let t = 1; t <= 3; t++) {
this.loadImage(`summary_tabs_${t}`, "ui");
}
this.loadImage("scroll_bar", "ui");
this.loadImage("scroll_bar_handle", "ui");
this.loadImage("starter_container_bg", "ui");
this.loadImage("starter_select_bg", "ui");
this.loadImage("select_cursor", "ui");
this.loadImage("select_cursor_highlight", "ui");
this.loadImage("select_cursor_highlight_thick", "ui");
this.loadImage("select_cursor_pokerus", "ui");
this.loadImage("select_gen_cursor", "ui");
this.loadImage("select_gen_cursor_highlight", "ui");
this.loadImage("saving_icon", "ui");
this.loadImage("discord", "ui");
this.loadImage("google", "ui");
this.loadImage("settings_icon", "ui");
this.loadImage("default_bg", "arenas");
// Load arena images
Utils.getEnumValues(Biome).map(bt => {
const btKey = Biome[bt].toLowerCase();
const isBaseAnimated = btKey === "end";
const baseAKey = `${btKey}_a`;
const baseBKey = `${btKey}_b`;
this.loadImage(`${btKey}_bg`, "arenas");
if (!isBaseAnimated) {
this.loadImage(baseAKey, "arenas");
} else {
this.loadAtlas(baseAKey, "arenas");
}
if (!isBaseAnimated) {
this.loadImage(baseBKey, "arenas");
} else {
this.loadAtlas(baseBKey, "arenas");
}
if (getBiomeHasProps(bt)) {
for (let p = 1; p <= 3; p++) {
const isPropAnimated = p === 3 && [ "power_plant", "end" ].find(b => b === btKey);
const propKey = `${btKey}_b_${p}`;
if (!isPropAnimated) {
this.loadImage(propKey, "arenas");
} else {
this.loadAtlas(propKey, "arenas");
}
}
}
});
// Load bitmap fonts
this.load.bitmapFont("item-count", "fonts/item-count.png", "fonts/item-count.xml");
// Load trainer images
this.loadAtlas("trainer_m_back", "trainer");
this.loadAtlas("trainer_m_back_pb", "trainer");
this.loadAtlas("trainer_f_back", "trainer");
this.loadAtlas("trainer_f_back_pb", "trainer");
Utils.getEnumValues(TrainerType).map(tt => {
const config = trainerConfigs[tt];
this.loadAtlas(config.getSpriteKey(), "trainer");
if (config.doubleOnly || config.hasDouble) {
this.loadAtlas(config.getSpriteKey(true), "trainer");
}
});
// Load character sprites
this.loadAtlas("c_rival_m", "character", "rival_m");
this.loadAtlas("c_rival_f", "character", "rival_f");
// Load pokemon-related images
this.loadImage("pkmn__back__sub", "pokemon/back", "sub.png");
this.loadImage("pkmn__sub", "pokemon", "sub.png");
this.loadAtlas("battle_stats", "effects");
this.loadAtlas("shiny", "effects");
this.loadAtlas("shiny_2", "effects");
this.loadAtlas("shiny_3", "effects");
this.loadImage("tera", "effects");
this.loadAtlas("pb_particles", "effects");
this.loadImage("evo_sparkle", "effects");
this.loadAtlas("tera_sparkle", "effects");
this.load.video("evo_bg", "images/effects/evo_bg.mp4", true);
this.loadAtlas("pb", "");
this.loadAtlas("items", "");
this.loadAtlas("types", "");
// Get current lang and load the types atlas for it. English will only load types while all other languages will load types and types_<lang>
const lang = i18next.resolvedLanguage;
if (lang !== "en") {
if (Utils.verifyLang(lang)) {
this.loadAtlas(`statuses_${lang}`, "");
this.loadAtlas(`types_${lang}`, "");
} else {
// Fallback to English
this.loadAtlas("statuses", "");
this.loadAtlas("types", "");
}
} else {
this.loadAtlas("statuses", "");
this.loadAtlas("types", "");
}
const availableLangs = ["en", "de", "it", "fr", "ja", "ko", "es", "pt-BR", "zh-CN"];
if (lang && availableLangs.includes(lang)) {
this.loadImage("egg-update_"+lang, "events");
} else {
this.loadImage("egg-update_en", "events");
}
this.loadAtlas("statuses", "");
this.loadAtlas("categories", "");
this.loadAtlas("egg", "egg");
this.loadAtlas("egg_crack", "egg");
this.loadAtlas("egg_icons", "egg");
this.loadAtlas("egg_shard", "egg");
this.loadAtlas("egg_lightrays", "egg");
Utils.getEnumKeys(GachaType).forEach(gt => {
const key = gt.toLowerCase();
this.loadImage(`gacha_${key}`, "egg");
this.loadAtlas(`gacha_underlay_${key}`, "egg");
});
this.loadImage("gacha_glass", "egg");
this.loadImage("gacha_eggs", "egg");
this.loadAtlas("gacha_hatch", "egg");
this.loadImage("gacha_knob", "egg");
this.loadImage("egg_list_bg", "ui");
this.loadImage("egg_summary_bg", "ui");
this.loadImage("end_m", "cg");
this.loadImage("end_f", "cg");
for (let i = 0; i < 10; i++) {
this.loadAtlas(`pokemon_icons_${i}`, "");
if (i) {
this.loadAtlas(`pokemon_icons_${i}v`, "");
}
}
// Load Mystery Encounter dex progress icon
this.loadImage("encounter_radar", "mystery-encounters");
this.loadAtlas("dualshock", "inputs");
this.loadAtlas("xbox", "inputs");
this.loadAtlas("keyboard", "inputs");
for (const key of allDefaultSeAssets.keys()) {
this.loadSe(key, allDefaultSeAssets.get(key));
}
@ -306,6 +48,132 @@ export class LoadingScene extends SceneBase {
this.loadBgm(key, allDefaultBgmAssets.get(key));
}
for (const key of allDefaultImageAssets.keys()) {
const val = allDefaultImageAssets.get(key);
if (val instanceof Array) {
this.loadImage(key, val[0], val[1]);
} else if (val !== undefined) {
this.loadImage(key, val);
}
}
for (const key of allDefaultAtlasAssets.keys()) {
const val = allDefaultAtlasAssets.get(key);
if (val instanceof Array) {
this.loadAtlas(key, val[0], val[1]);
} else if (val !== undefined) {
this.loadAtlas(key, val);
}
}
// UI windows
for (const wv of Utils.getEnumValues(WindowVariant)) {
for (let w = 1; w <= 5; w++) {
const key = `window_${w}${getWindowVariantSuffix(wv)}`;
allDefaultImageAssets.set(key, "ui/windows");
this.loadImage(key, "ui/windows");
}
}
// Summary screen tabs
for (let t = 1; t <= 3; t++) {
const key = `summary_tabs_${t}`;
allDefaultImageAssets.set(key, "ui");
this.loadImage(key, "ui");
}
// Load arena images
Utils.getEnumValues(Biome).map(bt => {
const btKey = Biome[bt].toLowerCase();
const isBaseAnimated = btKey === "end";
const baseAKey = `${btKey}_a`;
const baseBKey = `${btKey}_b`;
allDefaultImageAssets.set(`${btKey}_bg`, "arenas");
this.loadImage(`${btKey}_bg`, "arenas");
if (!isBaseAnimated) {
allDefaultImageAssets.set(baseAKey, "arenas");
this.loadImage(baseAKey, "arenas");
} else {
allDefaultAtlasAssets.set(baseAKey, "arenas");
this.loadAtlas(baseAKey, "arenas");
}
if (!isBaseAnimated) {
allDefaultImageAssets.set(baseBKey, "arenas");
this.loadImage(baseBKey, "arenas");
} else {
allDefaultAtlasAssets.set(baseBKey, "arenas");
this.loadAtlas(baseBKey, "arenas");
}
if (getBiomeHasProps(bt)) {
for (let p = 1; p <= 3; p++) {
const isPropAnimated = p === 3 && [ "power_plant", "end" ].find(b => b === btKey);
const propKey = `${btKey}_b_${p}`;
if (!isPropAnimated) {
allDefaultImageAssets.set(propKey, "arenas");
this.loadImage(propKey, "arenas");
} else {
allDefaultAtlasAssets.set(propKey, "arenas");
this.loadAtlas(propKey, "arenas");
}
}
}
});
// Load bitmap fonts
allDefaultAtlasAssets.set("item-count", "");
this.load.bitmapFont("item-count", "fonts/item-count.png", "fonts/item-count.xml");
this.load.video("evo_bg", "images/effects/evo_bg.mp4", true);
// Get current lang and load the types atlas for it. English will only load types while all other languages will load types and types_<lang>
const lang = i18next.resolvedLanguage;
if (lang !== "en") {
if (Utils.verifyLang(lang)) {
allDefaultAtlasAssets.set(`statuses_${lang}`, "");
allDefaultAtlasAssets.set(`types_${lang}`, "");
this.loadAtlas(`statuses_${lang}`, "");
this.loadAtlas(`types_${lang}`, "");
} else {
// Fallback to English
allDefaultAtlasAssets.set("statuses", "");
allDefaultAtlasAssets.set("types", "");
this.loadAtlas("statuses", "");
this.loadAtlas("types", "");
}
} else {
allDefaultAtlasAssets.set("statuses", "");
allDefaultAtlasAssets.set("types", "");
this.loadAtlas("statuses", "");
this.loadAtlas("types", "");
}
const availableLangs = ["en", "de", "it", "fr", "ja", "ko", "es", "pt-BR", "zh-CN"];
if (lang && availableLangs.includes(lang)) {
const key = "egg-update_"+lang;
allDefaultImageAssets.set(key, "events");
this.loadImage(key, "events");
} else {
allDefaultImageAssets.set("egg-update_en", "events");
this.loadImage("egg-update_en", "events");
}
// Gacha UI
Utils.getEnumKeys(GachaType).forEach(gt => {
const key = gt.toLowerCase();
allDefaultImageAssets.set(`gacha_${key}`, "egg");
allDefaultAtlasAssets.set(`gacha_underlay_${key}`, "egg");
this.loadImage(`gacha_${key}`, "egg");
this.loadAtlas(`gacha_underlay_${key}`, "egg");
});
for (let i = 0; i < 10; i++) {
allDefaultAtlasAssets.set(`pokemon_icons_${i}`, "");
this.loadAtlas(`pokemon_icons_${i}`, "");
if (i) {
allDefaultAtlasAssets.set(`pokemon_icons_${i}v`, "");
this.loadAtlas(`pokemon_icons_${i}v`, "");
}
}
this.load.plugin("rextexteditplugin", "https://raw.githubusercontent.com/rexrainbow/phaser3-rex-notes/master/dist/rextexteditplugin.min.js", true);
this.loadLoadingScreen();
@ -323,6 +191,9 @@ export class LoadingScene extends SceneBase {
initAbilities();
initChallenges();
initMysteryEncounters();
this.logLocalStorageSize();
this.logSessionStorageSize();
}
loadLoadingScreen() {

View File

@ -33,6 +33,8 @@ const config: Phaser.Types.Core.GameConfig = {
height: 1080,
mode: Phaser.Scale.FIT
},
/** Unnecessary since there is full-screen background art {@link https://newdocs.phaser.io/docs/3.85.1/focus/Phaser.Core.Config-clearBeforeRender} */
clearBeforeRender: false,
plugins: {
global: [{
key: "rexInputTextPlugin",
@ -67,6 +69,7 @@ const config: Phaser.Types.Core.GameConfig = {
},
pixelArt: true,
pipeline: [ InvertPostFX ] as unknown as Phaser.Types.Core.PipelineConfig,
powerPreference: "high-performance",
scene: [ LoadingScene, BattleScene ],
version: version
};

View File

@ -11,7 +11,7 @@ export class NewBiomeEncounterPhase extends NextEncounterPhase {
start() {
super.start();
this.scene.clearAllAudio();
// this.scene.clearAllAudio();
}
doEncounter(): void {

View File

@ -8,6 +8,8 @@ export class NextEncounterPhase extends EncounterPhase {
start() {
super.start();
this.scene.clearUnusedAssets();
}
doEncounter(): void {

View File

@ -1,4 +1,5 @@
import { allDefaultBgmAssets, allDefaultSeAssets } from "#app/default-assets";
import { allDefaultAtlasAssets, allDefaultBgmAssets, allDefaultImageAssets, allDefaultSeAssets } from "#app/default-assets";
import CanvasTexture = Phaser.Textures.CanvasTexture;
export const legacyCompatibleImages: string[] = [];
@ -94,7 +95,57 @@ export class SceneBase extends Phaser.Scene {
this.load.audio(key, this.getCachedUrl(`audio/bgm/${filename}`));
}
clearAllAudio() {
logLocalStorageSize() {
let _lsTotal = 0;
let _xLen, _x;
for (_x in localStorage) {
if (!localStorage.hasOwnProperty(_x)) {
continue;
}
_xLen = ((localStorage[_x].length + _x.length) * 2);
_lsTotal += _xLen;
// console.log(_x.substr(0, 50) + " = " + (_xLen / 1024).toFixed(2) + " KB");
}
console.log("Estimated localStorage: " + (_lsTotal / 1024).toFixed(2) + " KB");
}
logSessionStorageSize() {
let _lsTotal = 0;
let _xLen, _x;
for (_x in sessionStorage) {
if (!sessionStorage.hasOwnProperty(_x)) {
continue;
}
_xLen = ((sessionStorage[_x].length + _x.length) * 2);
_lsTotal += _xLen;
// console.log(_x.substr(0, 50) + " = " + (_xLen / 1024).toFixed(2) + " KB");
}
console.log("Estimated sessionStorage: " + (_lsTotal / 1024).toFixed(2) + " KB");
}
async logPartitionedStorageSize() {
const storageEstimate = await navigator.storage.estimate();
const storagePercent = ((storageEstimate.usage ?? 0) / (storageEstimate.quota ?? 1) * 100).toFixed(2);
const storageUse = ((storageEstimate.usage ?? 0) / 1024 ).toFixed(2) + "kB";
const storageMax = ((storageEstimate.quota ?? 0) / 1024 / 1024).toFixed(2) + "MB";
console.log(`Estimated partitioned storage usage: ${storageUse} (${storagePercent}%) of ${storageMax}`);
}
protected async clearAssets(excludedAudioKeys: Set<string>, excludedImageKeys: Set<string>, excludedGraphicsKeys: Set<string>) {
const storageEstimate = await navigator.storage.estimate();
console.log("Estimated cache usage: " + JSON.stringify(storageEstimate));
this.logLocalStorageSize();
await this.clearAllAudio(excludedAudioKeys);
await this.clearAllImages(new Set([...excludedImageKeys, ... excludedGraphicsKeys]));
const newStorageEstimate = await navigator.storage.estimate();
console.log("Estimated cache usage: " + JSON.stringify(newStorageEstimate));
this.logLocalStorageSize();
}
private async clearAllAudio(excludedAudioKeys: Set<string>) {
let removedAssets = "";
for (const key of this.cache.audio.entries.keys()) {
const audioKey = key as string;
@ -104,11 +155,10 @@ export class SceneBase extends Phaser.Scene {
continue;
}
// TODO: filter for player's Pokemon assets and do not unload
// if (audioKey.includes("PRSFX - ")) {
// // Asset in use by one of the player's party Pokemon, don't unload
// continue;
// }
if (excludedAudioKeys.has(audioKey) || (keyWithoutFolder && excludedAudioKeys.has(keyWithoutFolder))) {
// Asset in use by one of the player's party Pokemon, don't unload
continue;
}
if (this.cache.audio.has(audioKey)) {
removedAssets += `${audioKey}\n`;
@ -118,4 +168,51 @@ export class SceneBase extends Phaser.Scene {
console.log(`Audio keys removed from cache:\n${removedAssets}`);
}
private async clearAllImages(excludedImageKeys: Set<string>) {
let removedAssets = "";
for (const textureProperty of Object.keys(this.textures.list)) {
const texture = this.textures.get(textureProperty);
if (!texture || texture instanceof CanvasTexture || ["__NORMAL", "__DEFAULT", "__MISSING", "__WHITE"].includes(texture.key)) {
continue;
}
const imageKey = texture.key;
// const keyWithoutFolder = imageKey.split("/").pop();
if (allDefaultImageAssets.has(imageKey) || allDefaultAtlasAssets.has(imageKey)) {
// Default image/atlas asset, don't unload
continue;
}
if (excludedImageKeys.has(imageKey)) {
// Asset in use by one of the player's party Pokemon, don't unload
continue;
}
if (texture.source.some(s => (s.source as any)?.currentSrc.includes(".mp4"))) {
// Cached image from a video, skip
continue;
}
const removeLegacySuffix = imageKey.replace("_legacy", "");
if (legacyCompatibleImages.includes(imageKey) || legacyCompatibleImages.includes(removeLegacySuffix)) {
// UI image, skip
continue;
}
if (imageKey.includes("pkmn__")) {
// TODO: figure out why Pokemon assets being reloaded into TextureManager breaks
// Skip all Pokemon asset removal
continue;
}
if (this.textures.exists(imageKey)) {
removedAssets += `${imageKey}\n`;
this.textures.remove(imageKey);
}
}
console.log(`Image keys removed from cache:\n${removedAssets}`);
}
}