diff --git a/src/battle-scene.ts b/src/battle-scene.ts index 0f75447a500..c6e66508cd0 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -192,11 +192,6 @@ export default class BattleScene extends SceneBase { constructor() { super('battle'); - - initSpecies(); - initMoves(); - initAbilities(); - this.phaseQueue = []; this.phaseQueuePrepend = []; this.phaseQueuePrependSpliceIndex = -1; diff --git a/src/data/biomes.ts b/src/data/biomes.ts index c4fb750542d..3e8fea92bfc 100644 --- a/src/data/biomes.ts +++ b/src/data/biomes.ts @@ -5,7 +5,7 @@ import beautify from 'json-beautify'; import { TrainerType } from "./enums/trainer-type"; import { TimeOfDay } from "./enums/time-of-day"; import { Biome } from "./enums/biome"; -import { SpeciesFormEvolution } from "./pokemon-evolutions"; +import {initPokemonPrevolutions, pokemonEvolutions, SpeciesFormEvolution} from "./pokemon-evolutions"; export function getBiomeName(biome: Biome | -1) { if (biome === -1) @@ -2011,7 +2011,7 @@ export const biomeTrainerPools: BiomeTrainerPools = { } }; -{ +export function initBiomes() { const pokemonBiomes = [ [ Species.BULBASAUR, Type.GRASS, Type.POISON, [ [ Biome.GRASS, BiomePoolTier.RARE ] @@ -7676,123 +7676,121 @@ export const biomeTrainerPools: BiomeTrainerPools = { traverseBiome(Biome.TOWN, 0); biomeDepths[Biome.END] = [ Object.values(biomeDepths).map(d => d[0]).reduce((max: integer, value: integer) => Math.max(max, value), 0) + 1, 1 ]; - import('./pokemon-evolutions').then(pe => { - const pokemonEvolutions = pe.pokemonEvolutions; - for (let biome of Utils.getEnumValues(Biome)) { - biomePokemonPools[biome] = {}; - biomeTrainerPools[biome] = {}; + for (let biome of Utils.getEnumValues(Biome)) { + biomePokemonPools[biome] = {}; + biomeTrainerPools[biome] = {}; - for (let tier of Utils.getEnumValues(BiomePoolTier)) { - biomePokemonPools[biome][tier] = {}; - biomeTrainerPools[biome][tier] = []; + for (let tier of Utils.getEnumValues(BiomePoolTier)) { + biomePokemonPools[biome][tier] = {}; + biomeTrainerPools[biome][tier] = []; - for (let tod of Utils.getEnumValues(TimeOfDay)) - biomePokemonPools[biome][tier][tod] = []; - } + for (let tod of Utils.getEnumValues(TimeOfDay)) + biomePokemonPools[biome][tier][tod] = []; } + } - for (let pb of pokemonBiomes) { - const speciesId = pb[0] as Species; - const biomeEntries = pb[3] as (Biome | BiomePoolTier)[][]; + for (let pb of pokemonBiomes) { + const speciesId = pb[0] as Species; + const biomeEntries = pb[3] as (Biome | BiomePoolTier)[][]; - const speciesEvolutions: SpeciesFormEvolution[] = pokemonEvolutions.hasOwnProperty(speciesId) - ? pokemonEvolutions[speciesId] - : []; - - if (!biomeEntries.filter(b => b[0] !== Biome.END).length && !speciesEvolutions.filter(es => !!((pokemonBiomes.find(p => p[0] === es.speciesId))[3] as any[]).filter(b => b[0] !== Biome.END).length).length) - uncatchableSpecies.push(speciesId); + if (!pokemonEvolutions) initPokemonPrevolutions(); - for (let b of biomeEntries) { - const biome = b[0]; - const tier = b[1]; - const timesOfDay = b.length > 2 - ? Array.isArray(b[2]) - ? b[2] - : [ b[2] ] - : [ TimeOfDay.ALL ]; + const speciesEvolutions: SpeciesFormEvolution[] = pokemonEvolutions.hasOwnProperty(speciesId) + ? pokemonEvolutions[speciesId] + : []; - for (let tod of timesOfDay) { - if (!biomePokemonPools.hasOwnProperty(biome) || !biomePokemonPools[biome].hasOwnProperty(tier) || !biomePokemonPools[biome][tier].hasOwnProperty(tod)) - continue; + if (!biomeEntries.filter(b => b[0] !== Biome.END).length && !speciesEvolutions.filter(es => !!((pokemonBiomes.find(p => p[0] === es.speciesId))[3] as any[]).filter(b => b[0] !== Biome.END).length).length) + uncatchableSpecies.push(speciesId); - const biomeTierPool = biomePokemonPools[biome][tier][tod]; + for (let b of biomeEntries) { + const biome = b[0]; + const tier = b[1]; + const timesOfDay = b.length > 2 + ? Array.isArray(b[2]) + ? b[2] + : [ b[2] ] + : [ TimeOfDay.ALL ]; - let treeIndex = -1; - let arrayIndex = 0; - - for (let t = 0; t < biomeTierPool.length; t++) { - const existingSpeciesIds = biomeTierPool[t] as unknown as Species[]; - for (let es = 0; es < existingSpeciesIds.length; es++) { - const existingSpeciesId = existingSpeciesIds[es]; - if (pokemonEvolutions.hasOwnProperty(existingSpeciesId) && (pokemonEvolutions[existingSpeciesId] as SpeciesFormEvolution[]).find(ese => ese.speciesId === speciesId)) { - treeIndex = t; - arrayIndex = es + 1; - break; - } else if (speciesEvolutions && speciesEvolutions.find(se => se.speciesId === existingSpeciesId)) { - treeIndex = t; - arrayIndex = es; - break; - } - } - if (treeIndex > -1) - break; - } - - if (treeIndex > -1) - (biomeTierPool[treeIndex] as unknown as Species[]).splice(arrayIndex, 0, speciesId); - else - (biomeTierPool as unknown as Species[][]).push([ speciesId ]); - } - } - } - - for (let b of Object.keys(biomePokemonPools)) { - for (let t of Object.keys(biomePokemonPools[b])) { - const tier = parseInt(t) as BiomePoolTier; - for (let tod of Object.keys(biomePokemonPools[b][t])) { - const biomeTierTimePool = biomePokemonPools[b][t][tod]; - for (let e = 0; e < biomeTierTimePool.length; e++) { - const entry = biomeTierTimePool[e]; - if (entry.length === 1) - biomeTierTimePool[e] = entry[0]; - else { - const newEntry = { - 1: [ entry[0] ] - }; - for (let s = 1; s < entry.length; s++) { - const speciesId = entry[s]; - const prevolution = entry.map(s => pokemonEvolutions[s]).flat().find(e => e && e.speciesId === speciesId); - const level = prevolution.level - (prevolution.level === 1 ? 1 : 0) + (prevolution.wildDelay * 10) - (tier >= BiomePoolTier.BOSS ? 10 : 0); - if (!newEntry.hasOwnProperty(level)) - newEntry[level] = [ speciesId ]; - else - newEntry[level].push(speciesId); - } - biomeTierTimePool[e] = newEntry; - } - } - } - } - } - - for (let tb of trainerBiomes) { - const trainerType = tb[0] as TrainerType; - const biomeEntries = tb[1] as BiomePoolTier[][]; - - for (let b of biomeEntries) { - const biome = b[0]; - const tier = b[1]; - - if (!biomeTrainerPools.hasOwnProperty(biome) || !biomeTrainerPools[biome].hasOwnProperty(tier)) + for (let tod of timesOfDay) { + if (!biomePokemonPools.hasOwnProperty(biome) || !biomePokemonPools[biome].hasOwnProperty(tier) || !biomePokemonPools[biome][tier].hasOwnProperty(tod)) continue; - const biomeTierPool = biomeTrainerPools[biome][tier]; - biomeTierPool.push(trainerType); + const biomeTierPool = biomePokemonPools[biome][tier][tod]; + + let treeIndex = -1; + let arrayIndex = 0; + + for (let t = 0; t < biomeTierPool.length; t++) { + const existingSpeciesIds = biomeTierPool[t] as unknown as Species[]; + for (let es = 0; es < existingSpeciesIds.length; es++) { + const existingSpeciesId = existingSpeciesIds[es]; + if (pokemonEvolutions.hasOwnProperty(existingSpeciesId) && (pokemonEvolutions[existingSpeciesId] as SpeciesFormEvolution[]).find(ese => ese.speciesId === speciesId)) { + treeIndex = t; + arrayIndex = es + 1; + break; + } else if (speciesEvolutions && speciesEvolutions.find(se => se.speciesId === existingSpeciesId)) { + treeIndex = t; + arrayIndex = es; + break; + } + } + if (treeIndex > -1) + break; + } + + if (treeIndex > -1) + (biomeTierPool[treeIndex] as unknown as Species[]).splice(arrayIndex, 0, speciesId); + else + (biomeTierPool as unknown as Species[][]).push([ speciesId ]); } } + } + + for (let b of Object.keys(biomePokemonPools)) { + for (let t of Object.keys(biomePokemonPools[b])) { + const tier = parseInt(t) as BiomePoolTier; + for (let tod of Object.keys(biomePokemonPools[b][t])) { + const biomeTierTimePool = biomePokemonPools[b][t][tod]; + for (let e = 0; e < biomeTierTimePool.length; e++) { + const entry = biomeTierTimePool[e]; + if (entry.length === 1) + biomeTierTimePool[e] = entry[0]; + else { + const newEntry = { + 1: [ entry[0] ] + }; + for (let s = 1; s < entry.length; s++) { + const speciesId = entry[s]; + const prevolution = entry.map(s => pokemonEvolutions[s]).flat().find(e => e && e.speciesId === speciesId); + const level = prevolution.level - (prevolution.level === 1 ? 1 : 0) + (prevolution.wildDelay * 10) - (tier >= BiomePoolTier.BOSS ? 10 : 0); + if (!newEntry.hasOwnProperty(level)) + newEntry[level] = [ speciesId ]; + else + newEntry[level].push(speciesId); + } + biomeTierTimePool[e] = newEntry; + } + } + } + } + } + + for (let tb of trainerBiomes) { + const trainerType = tb[0] as TrainerType; + const biomeEntries = tb[1] as BiomePoolTier[][]; + + for (let b of biomeEntries) { + const biome = b[0]; + const tier = b[1]; + + if (!biomeTrainerPools.hasOwnProperty(biome) || !biomeTrainerPools[biome].hasOwnProperty(tier)) + continue; + + const biomeTierPool = biomeTrainerPools[biome][tier]; + biomeTierPool.push(trainerType); + } + } - //outputPools(); - }); function outputPools() { const pokemonOutput = {}; diff --git a/src/data/egg-moves.ts b/src/data/egg-moves.ts index 61099c72fdf..36e2152a218 100644 --- a/src/data/egg-moves.ts +++ b/src/data/egg-moves.ts @@ -606,9 +606,12 @@ function parseEggMoves(content: string): void { console.log(output); } -const eggMovesStr = ``; -if (eggMovesStr) { - setTimeout(() => { - parseEggMoves(eggMovesStr); - }, 1000); + +export function initEggMoves() { + const eggMovesStr = ``; + if (eggMovesStr) { + setTimeout(() => { + parseEggMoves(eggMovesStr); + }, 1000); + } } \ No newline at end of file diff --git a/src/data/pokemon-evolutions.ts b/src/data/pokemon-evolutions.ts index 7511b0e4162..68f2fe5c21d 100644 --- a/src/data/pokemon-evolutions.ts +++ b/src/data/pokemon-evolutions.ts @@ -1618,15 +1618,15 @@ interface PokemonPrevolutions { export const pokemonPrevolutions: PokemonPrevolutions = {}; -{ - const megaFormKeys = [ SpeciesFormKey.MEGA, '', SpeciesFormKey.MEGA_X, '', SpeciesFormKey.MEGA_Y ].map(sfk => sfk as string); - const prevolutionKeys = Object.keys(pokemonEvolutions); - prevolutionKeys.forEach(pk => { - const evolutions = pokemonEvolutions[pk]; - for (let ev of evolutions) { - if (ev.evoFormKey && megaFormKeys.indexOf(ev.evoFormKey) > -1) - continue; - pokemonPrevolutions[ev.speciesId] = parseInt(pk) as Species; - } - }); +export function initPokemonPrevolutions(): void { + const megaFormKeys = [ SpeciesFormKey.MEGA, '', SpeciesFormKey.MEGA_X, '', SpeciesFormKey.MEGA_Y ].map(sfk => sfk as string); + const prevolutionKeys = Object.keys(pokemonEvolutions); + prevolutionKeys.forEach(pk => { + const evolutions = pokemonEvolutions[pk]; + for (let ev of evolutions) { + if (ev.evoFormKey && megaFormKeys.indexOf(ev.evoFormKey) > -1) + continue; + pokemonPrevolutions[ev.speciesId] = parseInt(pk) as Species; + } + }); } \ No newline at end of file diff --git a/src/data/pokemon-forms.ts b/src/data/pokemon-forms.ts index a8bc07e92df..5959970da65 100644 --- a/src/data/pokemon-forms.ts +++ b/src/data/pokemon-forms.ts @@ -715,7 +715,7 @@ export const pokemonFormChanges: PokemonFormChanges = { ] }; -{ +export function initPokemonForms() { const formChangeKeys = Object.keys(pokemonFormChanges); formChangeKeys.forEach(pk => { const formChanges = pokemonFormChanges[pk]; diff --git a/src/data/pokemon-species.ts b/src/data/pokemon-species.ts index 218423d3232..8ad65fa650f 100644 --- a/src/data/pokemon-species.ts +++ b/src/data/pokemon-species.ts @@ -3751,23 +3751,3 @@ export const starterPassiveAbilities = { [Species.PALDEA_WOOPER]: Abilities.THICK_FAT, [Species.BLOODMOON_URSALUNA]: Abilities.BERSERK }; - -// TODO: Remove -{ - //setTimeout(() => { - /*for (let tc of Object.keys(trainerConfigs)) { - console.log(TrainerType[tc], !trainerConfigs[tc].speciesFilter ? 'all' : [...new Set(allSpecies.filter(s => s.generation <= 9).filter(trainerConfigs[tc].speciesFilter).map(s => { - while (pokemonPrevolutions.hasOwnProperty(s.speciesId)) - s = getPokemonSpecies(pokemonPrevolutions[s.speciesId]); - return s; - }))].map(s => s.name)); - } - - const speciesFilter = (species: PokemonSpecies) => !species.legendary && !species.pseudoLegendary && !species.mythical && species.baseTotal >= 540; - console.log(!speciesFilter ? 'all' : [...new Set(allSpecies.filter(s => s.generation <= 9).filter(speciesFilter).map(s => { - while (pokemonPrevolutions.hasOwnProperty(s.speciesId)) - s = getPokemonSpecies(pokemonPrevolutions[s.speciesId]); - return s; - }))].map(s => s.name));*/ - //}, 1000); -} diff --git a/src/data/trainer-config.ts b/src/data/trainer-config.ts index 3d40ceb2ba7..45c8803801c 100644 --- a/src/data/trainer-config.ts +++ b/src/data/trainer-config.ts @@ -1038,6 +1038,7 @@ export const trainerConfigs: TrainerConfigs = { }), }; -(function () { - initTrainerTypeDialogue(); -})(); + +export function initTrainerTypeDialogue() { + initTrainerTypeDialogue(); +} diff --git a/src/loading-scene.ts b/src/loading-scene.ts index 56d0ab47f13..444382b68b9 100644 --- a/src/loading-scene.ts +++ b/src/loading-scene.ts @@ -9,6 +9,14 @@ import { WindowVariant, getWindowVariantSuffix } from "./ui/ui-theme"; import { isMobile } from "./touch-controls"; import * as Utils from "./utils"; import { initI18n } from "./plugins/i18n"; +import {initStatsKeys} from "#app/ui/game-stats-ui-handler"; +import {initPokemonPrevolutions} from "#app/data/pokemon-evolutions"; +import {initBiomes} from "#app/data/biomes"; +import {initEggMoves} from "#app/data/egg-moves"; +import {initPokemonForms} from "#app/data/pokemon-forms"; +import {initSpecies} from "#app/data/pokemon-species"; +import {initMoves} from "#app/data/move"; +import {initAbilities} from "#app/data/ability"; export class LoadingScene extends SceneBase { constructor() { @@ -276,6 +284,15 @@ export class LoadingScene extends SceneBase { this.load.plugin('rextexteditplugin', 'https://raw.githubusercontent.com/rexrainbow/phaser3-rex-notes/master/dist/rextexteditplugin.min.js', true); this.loadLoadingScreen(); + + initStatsKeys(); + initPokemonPrevolutions(); + initBiomes(); + initEggMoves(); + initPokemonForms(); + initSpecies(); + initMoves(); + initAbilities(); } loadLoadingScreen() { diff --git a/src/test/achievement.test.ts b/src/test/achievement.test.ts new file mode 100644 index 00000000000..e6de07f7724 --- /dev/null +++ b/src/test/achievement.test.ts @@ -0,0 +1,10 @@ +import {beforeAll, describe, expect, it} from "vitest"; +import {initStatsKeys} from "#app/ui/game-stats-ui-handler"; +import {MoneyAchv} from "#app/system/achv"; + +describe("check some Achievement related stuff", () => { + it ('should check Achievement creation', () => { + const ach = new MoneyAchv("Achievement", 1000, null, 100); + expect(ach.name).toBe("Achievement"); + }); +}); \ No newline at end of file diff --git a/src/test/debugImports.test.ts b/src/test/debugImports.test.ts new file mode 100644 index 00000000000..e5a224d821e --- /dev/null +++ b/src/test/debugImports.test.ts @@ -0,0 +1,35 @@ +import { describe, expect, it} from "vitest"; +import {initStatsKeys} from "#app/ui/game-stats-ui-handler"; + +async function importModule() { + try { + initStatsKeys(); + const { PokemonMove } = await import('#app/field/pokemon'); + const { Species } = await import('#app/data/enums/species'); + return { + PokemonMove, + Species, + } + // Dynamically import the module + } catch (error) { + // Log the error stack trace + console.error('Error during import:', error.stack); + // Rethrow the error to ensure the test fails + throw error; + } +} + +describe("tests to debug the import, with trace", () => { + it('import PokemonMove module', async () => { + const module = await importModule(); + // Example assertion + expect(module.PokemonMove).toBeDefined(); + }); + + it('import Species module', async () => { + const module = await importModule(); + // Example assertion + expect(module.Species).toBeDefined(); + }); +}); + diff --git a/src/test/pokemon.test.ts b/src/test/pokemon.test.ts new file mode 100644 index 00000000000..6efce7ecc0a --- /dev/null +++ b/src/test/pokemon.test.ts @@ -0,0 +1,57 @@ +import {describe, expect, it} from "vitest"; +import {getPokemonSpecies, initSpecies} from "#app/data/pokemon-species"; +import {PokemonMove} from "#app/field/pokemon"; +import {Species} from "#app/data/enums/species"; +import {Moves} from "#app/data/enums/moves"; +import PokemonData from "#app/system/pokemon-data"; + +describe("some tests related to PokemonData and Species", () => { + it('should create a species', () => { + const species = getPokemonSpecies(Species.MEW); + expect(species).not.toBeNull(); + }); + + it('should create a pokemon', () => { + const pokemon = new PokemonData({ + species: Species.MEW, + level: 1, + }); + expect(pokemon).not.toBeNull(); + expect(pokemon.level).toEqual(1); + expect(pokemon.species).toEqual(Species.MEW); + }); + + it('should generate a moveset', () => { + const pokemon = new PokemonData({ + species: Species.MEW, + level: 1, + }); + expect(pokemon.moveset[0].moveId).toBe(Moves.TACKLE); + expect(pokemon.moveset[1].moveId).toBe(Moves.GROWL); + }); + + it('should create an ennemypokemon', () => { + const ennemyPokemon = new PokemonData({ + species: Species.MEWTWO, + level: 100, + }); + expect(ennemyPokemon).not.toBeNull(); + expect(ennemyPokemon.level).toEqual(100); + expect(ennemyPokemon.species).toEqual(Species.MEWTWO); + }); + + it('should create an ennemypokemon with specified moveset', () => { + const ennemyPokemon = new PokemonData({ + species: Species.MEWTWO, + level: 100, + moveset: [ + new PokemonMove(Moves.ACID), + new PokemonMove(Moves.ACROBATICS), + new PokemonMove(Moves.FOCUS_ENERGY), + ] + }); + expect(ennemyPokemon.moveset[0].moveId).toBe(Moves.ACID); + expect(ennemyPokemon.moveset[1].moveId).toBe(Moves.ACROBATICS); + expect(ennemyPokemon.moveset[2].moveId).toBe(Moves.FOCUS_ENERGY); + }); +}); \ No newline at end of file diff --git a/src/test/vitest.setup.ts b/src/test/vitest.setup.ts index d0141ca9fc3..7742d8f0451 100644 --- a/src/test/vitest.setup.ts +++ b/src/test/vitest.setup.ts @@ -1,2 +1,19 @@ import "vitest-canvas-mock"; import "#app/test/phaser.setup"; +import {initStatsKeys} from "#app/ui/game-stats-ui-handler"; +import {initPokemonPrevolutions} from "#app/data/pokemon-evolutions"; +import {initBiomes} from "#app/data/biomes"; +import {initEggMoves} from "#app/data/egg-moves"; +import {initPokemonForms} from "#app/data/pokemon-forms"; +import {initSpecies} from "#app/data/pokemon-species"; +import {initMoves} from "#app/data/move"; +import {initAbilities} from "#app/data/ability"; + +initStatsKeys(); +initPokemonPrevolutions(); +initBiomes(); +initEggMoves(); +initPokemonForms(); +initSpecies(); +initMoves(); +initAbilities(); \ No newline at end of file diff --git a/src/ui/game-stats-ui-handler.ts b/src/ui/game-stats-ui-handler.ts index c053d5700ac..ef1700c41e8 100644 --- a/src/ui/game-stats-ui-handler.ts +++ b/src/ui/game-stats-ui-handler.ts @@ -225,7 +225,7 @@ export default class GameStatsUiHandler extends UiHandler { } } -(function () { +export function initStatsKeys() { const statKeys = Object.keys(displayStats); for (let key of statKeys) { @@ -251,4 +251,4 @@ export default class GameStatsUiHandler extends UiHandler { (displayStats[key] as DisplayStat).label = Utils.toReadableString(`${splittableKey[0].toUpperCase()}${splittableKey.slice(1)}`); } } -})(); \ No newline at end of file +} \ No newline at end of file diff --git a/vitest.config.js b/vitest.config.js index 5a7babd4232..c73476431dd 100644 --- a/vitest.config.js +++ b/vitest.config.js @@ -14,6 +14,7 @@ export default defineConfig(({ mode }) => { } }, threads: false, + trace: true, environmentOptions: { jsdom: { resources: 'usable',