Initialize with config for champs

This commit is contained in:
AJ Fontaine 2025-06-01 17:31:29 -04:00
parent a7dbf12b15
commit 1a62e1ecdc
3 changed files with 62 additions and 27 deletions

View File

@ -712,7 +712,7 @@ export class TrainerConfig {
return this; return this;
} }
initPartyMemberFuncFromConfig(cfgs: PokemonPregenData[], postProcess?: (Pokemon) => void) { getRandomPartyMemberFuncFromConfig(cfgs: PokemonPregenData[], postProcess?: (Pokemon) => void) {
return (level: number, strength: PartyMemberStrength) => { return (level: number, strength: PartyMemberStrength) => {
let cfg: PokemonPregenData = cfgs[0]; let cfg: PokemonPregenData = cfgs[0];
if (cfgs.length > 1) { if (cfgs.length > 1) {
@ -722,7 +722,7 @@ export class TrainerConfig {
if (cfg.teraType) { // Defined tera type: instant tera if (cfg.teraType) { // Defined tera type: instant tera
cfg.instantTera = true; cfg.instantTera = true;
} }
else if (cfg.instantTera) { // Instant tera with undefined type will be specialty type or undefined else if (cfg.instantTera && this.hasSpecialtyType()) { // Instant tera with undefined type will be specialty type
cfg.teraType = this.specialtyType; cfg.teraType = this.specialtyType;
} }
@ -758,7 +758,10 @@ 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);
let teraSlot: number | undefined;
// Set species filter and specialty type, otherwise filter by base total.
this.setSpeciesFilter(p => p.isOfType(specialtyType) && p.baseTotal >= ELITE_FOUR_MINIMUM_BST);
this.setSpecialtyType(specialtyType);
trainerPartyConfigs[this.trainerType].forEach((slot, s) => { trainerPartyConfigs[this.trainerType].forEach((slot, s) => {
const cfg = Array.isArray(slot[1]) ? slot[1] : [slot[1]]; const cfg = Array.isArray(slot[1]) ? slot[1] : [slot[1]];
@ -769,20 +772,14 @@ export class TrainerConfig {
}); });
} }
cfg.forEach(c => { cfg.forEach(c => {
c.gender = c.gender ?? isMale ? Gender.MALE: Gender.FEMALE; c.preferredGender = c.preferredGender ?? isMale ? Gender.MALE: Gender.FEMALE;
c.pokeball = c.pokeball ?? PokeballType.ULTRA_BALL;
}); });
if (cfg.some(c => c.teraType || c.instantTera)) { if (cfg.some(c => c.teraType || c.instantTera)) {
this.setInstantTera(s); this.setInstantTera(s);
teraSlot = s;
} }
this.setPartyMemberFunc(slot[0], this.initPartyMemberFuncFromConfig(cfg)); this.setPartyMemberFunc(slot[0], this.getRandomPartyMemberFuncFromConfig(cfg));
}); });
// Set species filter and specialty type, otherwise filter by base total.
this.setSpeciesFilter(p => p.isOfType(specialtyType) && p.baseTotal >= ELITE_FOUR_MINIMUM_BST);
this.setSpecialtyType(specialtyType);
// Localize the trainer's name by converting it to lowercase and replacing spaces with underscores. // Localize the trainer's name by converting it to lowercase and replacing spaces with underscores.
const nameForCall = this.name.toLowerCase().replace(/\s/g, "_"); const nameForCall = this.name.toLowerCase().replace(/\s/g, "_");
this.name = i18next.t(`trainerNames:${nameForCall}`); this.name = i18next.t(`trainerNames:${nameForCall}`);
@ -800,7 +797,6 @@ export class TrainerConfig {
this.setHasVoucher(true); this.setHasVoucher(true);
this.setBattleBgm("battle_unova_elite"); this.setBattleBgm("battle_unova_elite");
this.setVictoryBgm("victory_gym"); this.setVictoryBgm("victory_gym");
this.setRandomTeraModifiers(() => 1, teraSlot);
return this; return this;
} }
@ -820,6 +816,23 @@ export class TrainerConfig {
// Set the party templates for the Champion. // Set the party templates for the Champion.
this.setPartyTemplates(trainerPartyTemplates.CHAMPION); this.setPartyTemplates(trainerPartyTemplates.CHAMPION);
trainerPartyConfigs[this.trainerType].forEach((slot, s) => {
const cfg = Array.isArray(slot[1]) ? slot[1] : [slot[1]];
if (s === 5) { // Last party member is always a boss with 2 segments
cfg.forEach(c => {
c.boss = true;
c.bossSegments = 2;
});
}
cfg.forEach(c => {
c.preferredGender = c.preferredGender ?? isMale ? Gender.MALE: Gender.FEMALE;
});
if (cfg.some(c => c.teraType || c.instantTera)) {
this.setInstantTera(s);
}
this.setPartyMemberFunc(slot[0], this.getRandomPartyMemberFuncFromConfig(cfg));
});
// Localize the trainer's name by converting it to lowercase and replacing spaces with underscores. // Localize the trainer's name by converting it to lowercase and replacing spaces with underscores.
const nameForCall = this.name.toLowerCase().replace(/\s/g, "_"); const nameForCall = this.name.toLowerCase().replace(/\s/g, "_");
this.name = i18next.t(`trainerNames:${nameForCall}`); this.name = i18next.t(`trainerNames:${nameForCall}`);
@ -1031,6 +1044,7 @@ export function getRandomPartyMemberFunc(
trainerSlot: TrainerSlot = TrainerSlot.TRAINER, trainerSlot: TrainerSlot = TrainerSlot.TRAINER,
ignoreEvolution = false, ignoreEvolution = false,
postProcess?: (enemyPokemon: EnemyPokemon) => void, postProcess?: (enemyPokemon: EnemyPokemon) => void,
pregenData?: PokemonPregenData,
) { ) {
return (level: number, strength: PartyMemberStrength) => { return (level: number, strength: PartyMemberStrength) => {
let species = randSeedItem(speciesPool); let species = randSeedItem(speciesPool);
@ -1050,6 +1064,7 @@ export function getRandomPartyMemberFunc(
false, false,
undefined, undefined,
postProcess, postProcess,
pregenData,
); );
}; };
} }

View File

@ -481,6 +481,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
} }
if (this.formIndex === undefined) { if (this.formIndex === undefined) {
if (pregenData.randomForms) {
this.formIndex = randSeedItem(pregenData.randomForms);
}
else {
this.formIndex = globalScene.getSpeciesFormIndex( this.formIndex = globalScene.getSpeciesFormIndex(
species, species,
this.gender, this.gender,
@ -488,6 +492,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
this.isPlayer(), this.isPlayer(),
); );
} }
}
if (this.shiny === undefined) { if (this.shiny === undefined) {
this.trySetShiny(); this.trySetShiny();
@ -1757,10 +1762,19 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
return precise ? this.hp / this.getMaxHp() : Math.round((this.hp / this.getMaxHp()) * 100) / 100; return precise ? this.hp / this.getMaxHp() : Math.round((this.hp / this.getMaxHp()) * 100) / 100;
} }
generateGender(): void { generateGender(preferred?: Gender): void {
if (this.species.malePercent === null) { if (this.species.malePercent === null) {
this.gender = Gender.GENDERLESS; this.gender = Gender.GENDERLESS;
} else { }
else if (!isNullOrUndefined(preferred)) {
if (preferred === Gender.MALE) {
this.gender = this.species.malePercent >= 50 ? Gender.MALE : Gender.FEMALE;
}
else {
this.gender = this.species.malePercent <= 50? Gender.FEMALE : Gender.MALE;
}
}
else {
const genderChance = (this.id % 256) * 0.390625; const genderChance = (this.id % 256) * 0.390625;
if (genderChance < this.species.malePercent) { if (genderChance < this.species.malePercent) {
this.gender = Gender.MALE; this.gender = Gender.MALE;
@ -6170,7 +6184,12 @@ export class EnemyPokemon extends Pokemon {
this.formIndex = Overrides.OPP_FORM_OVERRIDES[speciesId]; this.formIndex = Overrides.OPP_FORM_OVERRIDES[speciesId];
} }
if (pregenData && pregenData.presetMoves) { // Push any predefined PokemonMove Objects (including PP info etc) to the moveset first
if (pregenData?.moveset) {
this.moveset.push(...pregenData.moveset);
}
if (pregenData?.presetMoves) {
this.generateAndPopulateMoveset(...pregenData.presetMoves); this.generateAndPopulateMoveset(...pregenData.presetMoves);
} }
else if (!dataSource) { else if (!dataSource) {

View File

@ -18,7 +18,7 @@ export interface PokemonPregenData {
species: Species; species: Species;
player?: boolean; player?: boolean;
nickname?: string; nickname?: string;
formIndex?: number; formIndex?: number; // Specific desired form index
abilityIndex?: number; abilityIndex?: number;
passive?: boolean; passive?: boolean;
shiny?: boolean; shiny?: boolean;
@ -28,15 +28,16 @@ export interface PokemonPregenData {
gender?: Gender; gender?: Gender;
ivs?: number[]; ivs?: number[];
nature?: Nature; nature?: Nature;
moveset?: PokemonMove[]; moveset?: PokemonMove[]; // Fully built PokemonMove objects including PP info
presetMoves?: Moves[]; presetMoves?: Moves[]; // Moves to include first during moveset generation
friendship?: number; friendship?: number;
luck?: number; luck?: number;
pokerus?: boolean; pokerus?: boolean;
teraType?: PokemonType; teraType?: PokemonType;
shinyLock?: boolean; shinyLock?: boolean;
instantTera?: boolean; instantTera?: boolean;
randomForms?: number[]; randomForms?: number[]; // Form indexes to choose from at random
preferredGender?: Gender; // The PREFERRED gender for the mon to have, but can be overridden by the majority gender for mons w/ uneven ratios
fusionSpecies?: Species; fusionSpecies?: Species;
fusionFormIndex?: number; fusionFormIndex?: number;
@ -47,8 +48,8 @@ export interface PokemonPregenData {
fusionLuck?: number; fusionLuck?: number;
fusionTeraType?: PokemonType; fusionTeraType?: PokemonType;
boss?: boolean; boss?: boolean; // Defaults to 2 boss bars
bossSegments?: number; bossSegments?: number; // If this is set, boss will be set to true
customPokemonData?: CustomPokemonData; customPokemonData?: CustomPokemonData;
fusionCustomPokemonData?: CustomPokemonData; fusionCustomPokemonData?: CustomPokemonData;