Pokemon constructors accept pregen args

This commit is contained in:
AJ Fontaine 2025-05-13 18:20:55 -04:00
parent 98b9577153
commit d7c28e2781
4 changed files with 184 additions and 15 deletions

View File

@ -186,6 +186,7 @@ import { hasExpSprite } from "./sprites/sprite-utils";
import { timedEventManager } from "./global-event-manager"; import { timedEventManager } from "./global-event-manager";
import { starterColors } from "./global-vars/starter-colors"; import { starterColors } from "./global-vars/starter-colors";
import { startingWave } from "./starting-wave"; import { startingWave } from "./starting-wave";
import { PokemonPregenData } from "#app/system/pokemon-data";
const DEBUG_RNG = false; const DEBUG_RNG = false;
@ -977,6 +978,7 @@ export default class BattleScene extends SceneBase {
shinyLock = false, shinyLock = false,
dataSource?: PokemonData, dataSource?: PokemonData,
postProcess?: (enemyPokemon: EnemyPokemon) => void, postProcess?: (enemyPokemon: EnemyPokemon) => void,
pregenData?: PokemonPregenData,
): EnemyPokemon { ): EnemyPokemon {
if (Overrides.OPP_LEVEL_OVERRIDE > 0) { if (Overrides.OPP_LEVEL_OVERRIDE > 0) {
level = Overrides.OPP_LEVEL_OVERRIDE; level = Overrides.OPP_LEVEL_OVERRIDE;
@ -987,12 +989,12 @@ export default class BattleScene extends SceneBase {
boss = this.getEncounterBossSegments(this.currentBattle.waveIndex, level, species) > 1; boss = this.getEncounterBossSegments(this.currentBattle.waveIndex, level, species) > 1;
} }
const pokemon = new EnemyPokemon(species, level, trainerSlot, boss, shinyLock, dataSource); const pokemon = new EnemyPokemon(species, level, trainerSlot, boss, shinyLock, dataSource, pregenData);
if (Overrides.OPP_FUSION_OVERRIDE) { if (Overrides.OPP_FUSION_OVERRIDE) {
pokemon.generateFusionSpecies(); pokemon.generateFusionSpecies();
} }
if (boss && !dataSource) { if (boss && !dataSource && !pregenData?.ivs) {
const secondaryIvs = getIvsFromId(randSeedInt(4294967296)); const secondaryIvs = getIvsFromId(randSeedInt(4294967296));
for (let s = 0; s < pokemon.ivs.length; s++) { for (let s = 0; s < pokemon.ivs.length; s++) {

View File

@ -38,7 +38,7 @@ import { timedEventManager } from "#app/global-event-manager";
import type { PokemonSpeciesFilter } from "#app/data/pokemon-species"; import type { PokemonSpeciesFilter } from "#app/data/pokemon-species";
import type PokemonSpecies from "#app/data/pokemon-species"; import type PokemonSpecies from "#app/data/pokemon-species";
import type { ModifierTypeFunc } from "#app/modifier/modifier-type"; import type { ModifierTypeFunc } from "#app/modifier/modifier-type";
import type { EnemyPokemon } from "#app/field/pokemon"; import { EnemyPokemon } from "#app/field/pokemon";
import type { EvilTeam } from "./evil-admin-trainer-pools"; import type { EvilTeam } from "./evil-admin-trainer-pools";
import type { import type {
PartyMemberFunc, PartyMemberFunc,
@ -50,6 +50,9 @@ import type {
PartyMemberFuncs, PartyMemberFuncs,
TrainerPartyConfigs, TrainerPartyConfigs,
} from "./typedefs"; } from "./typedefs";
import PokemonData, { PokemonPregenData } from "#app/system/pokemon-data";
import { Variant } from "#app/sprites/variant";
import { Nature } from "#enums/nature";
export interface TrainerPartyMemberConfig { export interface TrainerPartyMemberConfig {
species: Species, species: Species,
@ -62,6 +65,10 @@ export interface TrainerPartyMemberConfig {
isBoss?: boolean, isBoss?: boolean,
bossBars?: number, bossBars?: number,
ball?: PokeballType, ball?: PokeballType,
shiny?: boolean,
variant?: Variant,
ivs?: number[],
nature?: Nature,
} }
export type TrainerPartySetSlot = [ export type TrainerPartySetSlot = [
@ -724,6 +731,44 @@ export class TrainerConfig {
return this; return this;
} }
initPartyMemberFuncFromConfig(cfgs: TrainerPartyMemberConfig[], postProcess?: (Pokemon) => void) {
return (level: number, strength: PartyMemberStrength) => {
let cfg: TrainerPartyMemberConfig = cfgs[0];
if (cfgs.length > 1) {
cfg = randSeedItem(cfgs);
}
cfg.teraType = cfg.teraType ?? this.specialtyType;
const moveset = cfg.moves?.map(m => new PokemonMove(m));
const monPregenData: PokemonPregenData = {
player: false,
species: cfg.species,
formIndex: cfg.formIndex,
abilityIndex: cfg.abilityIndex,
shiny: cfg.shiny,
variant: cfg.variant,
pokeball: cfg.ball,
boss: cfg.isBoss,
bossSegments: cfg.bossBars,
nature: cfg.nature,
ivs: cfg.ivs,
gender: cfg.gender,
teraType: cfg.teraType,
moveset: moveset,
level: level,
}
return globalScene.addEnemyPokemon(
getPokemonSpecies(cfg.species),
level,
TrainerSlot.TRAINER,
cfg.isBoss,
false,
undefined,
postProcess,
monPregenData
);
}
}
/** /**
* Initializes the trainer configuration for an Elite Four member. * Initializes the trainer configuration for an Elite Four member.
* @param signatureSpecies - The signature species for the Elite Four member. * @param signatureSpecies - The signature species for the Elite Four member.
@ -746,6 +791,20 @@ export class TrainerConfig {
// Set the party templates for the Elite Four. // Set the party templates for the Elite Four.
this.setPartyTemplates(trainerPartyTemplates.ELITE_FOUR); this.setPartyTemplates(trainerPartyTemplates.ELITE_FOUR);
trainerPartyConfigs[this.trainerType].forEach((slot, s) => {
const cfg = Array.isArray(slot[1]) ? slot[1] : [slot[1]];
if (s === 5) {
cfg.forEach(c => {
c.isBoss = true;
c.bossBars = 2;
});
}
if (cfg.some(c => c.teraType || c.instantTera)) {
this.setInstantTera(s);
}
this.setPartyMemberFunc(slot[0], this.initPartyMemberFuncFromConfig(cfg));
});
// Set up party members with their corresponding species. // Set up party members with their corresponding species.
signatureSpecies.forEach((speciesPool, s) => { signatureSpecies.forEach((speciesPool, s) => {
// Ensure speciesPool is an array. // Ensure speciesPool is an array.

View File

@ -260,6 +260,7 @@ import { MoveFlags } from "#enums/MoveFlags";
import { timedEventManager } from "#app/global-event-manager"; import { timedEventManager } from "#app/global-event-manager";
import { loadMoveAnimations } from "#app/sprites/pokemon-asset-loader"; import { loadMoveAnimations } from "#app/sprites/pokemon-asset-loader";
import { ResetStatusPhase } from "#app/phases/reset-status-phase"; import { ResetStatusPhase } from "#app/phases/reset-status-phase";
import { PokemonPregenData } from "#app/system/pokemon-data";
export enum LearnMoveSituation { export enum LearnMoveSituation {
MISC, MISC,
@ -402,6 +403,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
ivs?: number[], ivs?: number[],
nature?: Nature, nature?: Nature,
dataSource?: Pokemon | PokemonData, dataSource?: Pokemon | PokemonData,
pregenData?: PokemonPregenData,
) { ) {
super(globalScene, x, y); super(globalScene, x, y);
@ -409,8 +411,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
throw `Cannot create a player Pokemon for species '${species.getName(formIndex)}'`; throw `Cannot create a player Pokemon for species '${species.getName(formIndex)}'`;
} }
const partialData = dataSource ?? pregenData;
this.species = species; this.species = species;
this.pokeball = dataSource?.pokeball || PokeballType.POKEBALL; this.pokeball = partialData?.pokeball || PokeballType.POKEBALL;
this.level = level; this.level = level;
this.abilityIndex = abilityIndex ?? this.generateAbilityIndex() this.abilityIndex = abilityIndex ?? this.generateAbilityIndex()
@ -428,7 +432,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
this.variant = variant; this.variant = variant;
} }
this.exp = this.exp =
dataSource?.exp || getLevelTotalExp(this.level, species.growthRate); dataSource?.exp || getLevelTotalExp(this.level, species.growthRate);
this.levelExp = dataSource?.levelExp || 0; this.levelExp = dataSource?.levelExp || 0;
if (dataSource) { if (dataSource) {
@ -481,7 +485,67 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
this.teraType = dataSource.teraType; this.teraType = dataSource.teraType;
this.isTerastallized = dataSource.isTerastallized; this.isTerastallized = dataSource.isTerastallized;
this.stellarTypesBoosted = dataSource.stellarTypesBoosted ?? []; this.stellarTypesBoosted = dataSource.stellarTypesBoosted ?? [];
} else { }
else if (pregenData) {
this.id = randSeedInt(4294967296);
this.ivs = pregenData.ivs ?? getIvsFromId(this.id);
if (this.gender === undefined) {
this.generateGender();
}
if (this.formIndex === undefined) {
this.formIndex = globalScene.getSpeciesFormIndex(
species,
this.gender,
this.nature,
this.isPlayer(),
);
}
if (this.shiny === undefined) {
this.trySetShiny();
}
if (this.variant === undefined) {
this.variant = this.shiny ? this.generateShinyVariant() : 0;
}
if (nature !== undefined) {
this.setNature(nature);
} else {
this.generateNature();
}
if (pregenData.fusionSpecies) {
this.fusionSpecies = getPokemonSpecies(pregenData.fusionSpecies);
this.fusionAbilityIndex = pregenData.fusionAbilityIndex ?? 0;
this.fusionFormIndex = pregenData.fusionFormIndex ?? 0;
this.fusionGender = pregenData.fusionGender ?? 0;
this.fusionShiny = !!pregenData.fusionShiny;
this.fusionVariant = pregenData.fusionVariant ?? 0;
}
this.friendship = pregenData.friendship ?? species.baseFriendship;
this.metLevel = level;
this.metBiome = globalScene.currentBattle
? globalScene.arena.biomeType
: -1;
this.metSpecies = species.speciesId;
this.metWave = globalScene.currentBattle
? globalScene.currentBattle.waveIndex
: -1;
this.pokerus = !!pregenData.pokerus;
this.luck = pregenData.luck ??
(this.shiny ? this.variant + 1 : 0) +
(this.fusionShiny ? this.fusionVariant + 1 : 0);
this.fusionLuck = pregenData.fusionLuck ?? this.luck;
this.nickname = pregenData.nickname ?? "";
this.teraType = pregenData.teraType ?? randSeedItem(this.getTypes(false, false, true));
this.isTerastallized = false;
this.stellarTypesBoosted = [];
}
else {
this.id = randSeedInt(4294967296); this.id = randSeedInt(4294967296);
this.ivs = ivs || getIvsFromId(this.id); this.ivs = ivs || getIvsFromId(this.id);
@ -7057,27 +7121,29 @@ export class EnemyPokemon extends Pokemon {
boss: boolean, boss: boolean,
shinyLock = false, shinyLock = false,
dataSource?: PokemonData, dataSource?: PokemonData,
pregenData?: PokemonPregenData,
) { ) {
super( super(
236, 236,
84, 84,
species, species,
level, level,
dataSource?.abilityIndex, dataSource?.abilityIndex ?? pregenData?.abilityIndex,
dataSource?.formIndex, dataSource?.formIndex ?? pregenData?.formIndex,
dataSource?.gender, dataSource?.gender ?? pregenData?.gender,
!shinyLock && dataSource ? dataSource.shiny : false, !shinyLock ? dataSource?.shiny ?? pregenData?.shiny : false,
!shinyLock && dataSource ? dataSource.variant : undefined, !shinyLock ? dataSource?.variant ?? pregenData?.variant : undefined,
undefined, dataSource?.ivs ?? pregenData?.ivs ?? undefined,
dataSource ? dataSource.nature : undefined, dataSource ? dataSource.nature : undefined,
dataSource, dataSource,
pregenData,
); );
this.trainerSlot = trainerSlot; this.trainerSlot = trainerSlot;
this.initialTeamIndex = globalScene.currentBattle?.enemyParty.length ?? 0; this.initialTeamIndex = globalScene.currentBattle?.enemyParty.length ?? 0;
this.isPopulatedFromDataSource = !!dataSource; // if a dataSource is provided, then it was populated from dataSource this.isPopulatedFromDataSource = !!dataSource || !!pregenData; // if a dataSource is provided, then it was populated from dataSource
if (boss) { if (boss) {
this.setBoss(boss, dataSource?.bossSegments); this.setBoss(boss, dataSource?.bossSegments ?? pregenData?.bossSegments);
} }
if (Overrides.OPP_STATUS_OVERRIDE) { if (Overrides.OPP_STATUS_OVERRIDE) {
@ -7098,9 +7164,14 @@ export class EnemyPokemon extends Pokemon {
this.formIndex = Overrides.OPP_FORM_OVERRIDES[speciesId]; this.formIndex = Overrides.OPP_FORM_OVERRIDES[speciesId];
} }
if (!dataSource) { if (pregenData && pregenData.presetMoves) {
this.generateAndPopulateMoveset(...pregenData.presetMoves);
}
else if (!dataSource) {
this.generateAndPopulateMoveset(); this.generateAndPopulateMoveset();
}
if (!dataSource && !pregenData) {
if (shinyLock || Overrides.OPP_SHINY_OVERRIDE === false) { if (shinyLock || Overrides.OPP_SHINY_OVERRIDE === false) {
this.shiny = false; this.shiny = false;
} else { } else {

View File

@ -14,6 +14,43 @@ import type { Species } from "#enums/species";
import { CustomPokemonData } from "#app/data/custom-pokemon-data"; import { CustomPokemonData } from "#app/data/custom-pokemon-data";
import type { PokemonType } from "#enums/pokemon-type"; import type { PokemonType } from "#enums/pokemon-type";
export interface PokemonPregenData {
player: boolean;
species: Species;
nickname?: string;
formIndex?: number;
abilityIndex?: number;
passive?: boolean;
shiny?: boolean;
variant?: Variant;
pokeball?: PokeballType;
level?: number;
gender?: Gender;
ivs?: number[];
nature?: Nature;
moveset?: PokemonMove[];
presetMoves?: Moves[];
friendship?: number;
luck?: number;
pokerus?: boolean;
teraType?: PokemonType;
fusionSpecies?: Species;
fusionFormIndex?: number;
fusionAbilityIndex?: number;
fusionShiny?: boolean;
fusionVariant?: Variant;
fusionGender?: Gender;
fusionLuck?: number;
fusionTeraType?: PokemonType;
boss?: boolean;
bossSegments?: number;
customPokemonData?: CustomPokemonData;
fusionCustomPokemonData?: CustomPokemonData;
}
export default class PokemonData { export default class PokemonData {
public id: number; public id: number;
public player: boolean; public player: boolean;