diff --git a/src/battle-scene.ts b/src/battle-scene.ts index 001c4cf9a..29041e695 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -966,10 +966,7 @@ export default class BattleScene extends Phaser.Scene { } return s; }))] : allSpecies.filter(s => s.isCatchable()); - let ret = filteredSpecies[Utils.randSeedInt(filteredSpecies.length)]; - if (!filterAllEvolutions) - ret = getPokemonSpecies(ret.getSpeciesForLevel(level, true)); - return ret; + return filteredSpecies[Utils.randSeedInt(filteredSpecies.length)]; } checkInput(): boolean { diff --git a/src/data/pokemon-evolutions.ts b/src/data/pokemon-evolutions.ts index 71861b5ef..d60d618dc 100644 --- a/src/data/pokemon-evolutions.ts +++ b/src/data/pokemon-evolutions.ts @@ -19,8 +19,7 @@ export enum SpeciesWildEvolutionDelay { MEDIUM, LONG, VERY_LONG, - MEGA, - NEVER + MEGA } export enum EvolutionItem { @@ -259,7 +258,7 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.ELECTRODE, 30, null, null) ], [Species.CUBONE]: [ - new SpeciesEvolution(Species.ALOLA_MAROWAK, 28, null, new SpeciesEvolutionCondition((p: Pokemon) => p.scene.arena.biomeType === Biome.ISLAND), SpeciesWildEvolutionDelay.NEVER), + new SpeciesEvolution(Species.ALOLA_MAROWAK, 28, null, new SpeciesEvolutionCondition((p: Pokemon) => p.scene.arena.biomeType === Biome.ISLAND), SpeciesWildEvolutionDelay.MEDIUM), new SpeciesEvolution(Species.MAROWAK, 28, null, null) ], [Species.TYROGUE]: [ @@ -268,7 +267,7 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.HITMONTOP, 20, null, new SpeciesEvolutionCondition((p: Pokemon) => p.stats[Stat.ATK] === p.stats[Stat.DEF])) ], [Species.KOFFING]: [ - new SpeciesEvolution(Species.GALAR_WEEZING, 35, null, new SpeciesEvolutionCondition((p: Pokemon) => p.scene.arena.biomeType === Biome.METROPOLIS), SpeciesWildEvolutionDelay.NEVER), + new SpeciesEvolution(Species.GALAR_WEEZING, 35, null, new SpeciesEvolutionCondition((p: Pokemon) => p.scene.arena.biomeType === Biome.METROPOLIS), SpeciesWildEvolutionDelay.MEDIUM), new SpeciesEvolution(Species.WEEZING, 35, null, null) ], [Species.RHYHORN]: [ @@ -314,7 +313,7 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.QUILAVA, 14, null, null) ], [Species.QUILAVA]: [ - new SpeciesEvolution(Species.HISUI_TYPHLOSION, 36, null, new SpeciesEvolutionCondition((p: Pokemon) => p.scene.arena.biomeType === Biome.RUINS), SpeciesWildEvolutionDelay.NEVER), + new SpeciesEvolution(Species.HISUI_TYPHLOSION, 36, null, new SpeciesEvolutionCondition((p: Pokemon) => p.scene.arena.biomeType === Biome.RUINS), SpeciesWildEvolutionDelay.VERY_LONG), new SpeciesEvolution(Species.TYPHLOSION, 36, null, null) ], [Species.TOTODILE]: [ @@ -663,7 +662,7 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.DEWOTT, 17, null, null) ], [Species.DEWOTT]: [ - new SpeciesEvolution(Species.HISUI_SAMUROTT, 36, null, new SpeciesEvolutionCondition((p: Pokemon) => p.scene.arena.biomeType === Biome.RUINS), SpeciesWildEvolutionDelay.NEVER), + new SpeciesEvolution(Species.HISUI_SAMUROTT, 36, null, new SpeciesEvolutionCondition((p: Pokemon) => p.scene.arena.biomeType === Biome.RUINS), SpeciesWildEvolutionDelay.VERY_LONG), new SpeciesEvolution(Species.SAMUROTT, 36, null, null) ], [Species.PATRAT]: [ @@ -814,7 +813,7 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.KINGAMBIT, 64, null, null) ], [Species.RUFFLET]: [ - new SpeciesEvolution(Species.HISUI_BRAVIARY, 54, null, new SpeciesEvolutionCondition((p: Pokemon) => p.scene.arena.biomeType === Biome.RUINS), SpeciesWildEvolutionDelay.NEVER), + new SpeciesEvolution(Species.HISUI_BRAVIARY, 54, null, new SpeciesEvolutionCondition((p: Pokemon) => p.scene.arena.biomeType === Biome.RUINS), SpeciesWildEvolutionDelay.VERY_LONG), new SpeciesEvolution(Species.BRAVIARY, 54, null, null) ], [Species.VULLABY]: [ @@ -900,15 +899,15 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.AURORUS, 39, null, new SpeciesEvolutionCondition((p: Pokemon) => p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.MEDIUM) ], [Species.GOOMY]: [ - new SpeciesEvolution(Species.HISUI_SLIGGOO, 40, null, new SpeciesEvolutionCondition((p: Pokemon) => p.scene.arena.biomeType === Biome.RUINS), SpeciesWildEvolutionDelay.NEVER), + new SpeciesEvolution(Species.HISUI_SLIGGOO, 40, null, new SpeciesEvolutionCondition((p: Pokemon) => p.scene.arena.biomeType === Biome.RUINS), SpeciesWildEvolutionDelay.VERY_LONG), new SpeciesEvolution(Species.SLIGGOO, 40, null, null) ], [Species.SLIGGOO]: [ - new SpeciesEvolution(Species.HISUI_GOODRA, 54, null, new SpeciesEvolutionCondition((p: Pokemon) => [ WeatherType.RAIN, WeatherType.HEAVY_RAIN ].indexOf(p.scene.arena.weather?.weatherType || WeatherType.NONE) > -1 && p.scene.arena.biomeType === Biome.RUINS), SpeciesWildEvolutionDelay.NEVER), + new SpeciesEvolution(Species.HISUI_GOODRA, 54, null, new SpeciesEvolutionCondition((p: Pokemon) => [ WeatherType.RAIN, WeatherType.HEAVY_RAIN ].indexOf(p.scene.arena.weather?.weatherType || WeatherType.NONE) > -1 && p.scene.arena.biomeType === Biome.RUINS), SpeciesWildEvolutionDelay.VERY_LONG), new SpeciesEvolution(Species.GOODRA, 50, null, new SpeciesEvolutionCondition((p: Pokemon) => [ WeatherType.RAIN, WeatherType.HEAVY_RAIN ].indexOf(p.scene.arena.weather?.weatherType || WeatherType.NONE) > -1), SpeciesWildEvolutionDelay.LONG) ], [Species.BERGMITE]: [ - new SpeciesEvolution(Species.HISUI_AVALUGG, 37, null, new SpeciesEvolutionCondition((p: Pokemon) => p.scene.arena.biomeType === Biome.RUINS), SpeciesWildEvolutionDelay.NEVER), + new SpeciesEvolution(Species.HISUI_AVALUGG, 37, null, new SpeciesEvolutionCondition((p: Pokemon) => p.scene.arena.biomeType === Biome.RUINS), SpeciesWildEvolutionDelay.VERY_LONG), new SpeciesEvolution(Species.AVALUGG, 37, null, null) ], [Species.NOIBAT]: [ @@ -918,7 +917,7 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.DARTRIX, 17, null, null) ], [Species.DARTRIX]: [ - new SpeciesEvolution(Species.HISUI_DECIDUEYE, 36, null, new SpeciesEvolutionCondition((p: Pokemon) => p.scene.arena.biomeType === Biome.RUINS), SpeciesWildEvolutionDelay.NEVER), + new SpeciesEvolution(Species.HISUI_DECIDUEYE, 36, null, new SpeciesEvolutionCondition((p: Pokemon) => p.scene.arena.biomeType === Biome.RUINS), SpeciesWildEvolutionDelay.VERY_LONG), new SpeciesEvolution(Species.DECIDUEYE, 36, null, null) ], [Species.LITTEN]: [ @@ -1228,7 +1227,7 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.CLODSIRE, 20, null, null) ], [Species.PIKACHU]: [ - new SpeciesEvolution(Species.ALOLA_RAICHU, 1, EvolutionItem.THUNDER_STONE, new SpeciesEvolutionCondition((p: Pokemon) => p.scene.arena.biomeType === Biome.ISLAND), SpeciesWildEvolutionDelay.NEVER), + new SpeciesEvolution(Species.ALOLA_RAICHU, 1, EvolutionItem.THUNDER_STONE, new SpeciesEvolutionCondition((p: Pokemon) => p.scene.arena.biomeType === Biome.ISLAND), SpeciesWildEvolutionDelay.MEDIUM), new SpeciesEvolution(Species.RAICHU, 1, EvolutionItem.THUNDER_STONE, null, SpeciesWildEvolutionDelay.LONG) ], [Species.NIDORINA]: [ @@ -1267,7 +1266,7 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.CLOYSTER, 1, EvolutionItem.WATER_STONE, null, SpeciesWildEvolutionDelay.MEDIUM) ], [Species.EXEGGCUTE]: [ - new SpeciesEvolution(Species.ALOLA_EXEGGUTOR, 1, EvolutionItem.LEAF_STONE, new SpeciesEvolutionCondition((p: Pokemon) => p.scene.arena.biomeType === Biome.ISLAND), SpeciesWildEvolutionDelay.NEVER), + new SpeciesEvolution(Species.ALOLA_EXEGGUTOR, 1, EvolutionItem.LEAF_STONE, new SpeciesEvolutionCondition((p: Pokemon) => p.scene.arena.biomeType === Biome.ISLAND), SpeciesWildEvolutionDelay.MEDIUM), new SpeciesEvolution(Species.EXEGGUTOR, 1, EvolutionItem.LEAF_STONE, null, SpeciesWildEvolutionDelay.LONG) ], [Species.TANGELA]: [ @@ -1353,7 +1352,7 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.SUDOWOODO, 1, null, new SpeciesEvolutionCondition((p: Pokemon) => p.moveset.filter(m => m.moveId === Moves.MIMIC).length > 0), SpeciesWildEvolutionDelay.MEDIUM) ], [Species.MIME_JR]: [ - new SpeciesEvolution(Species.GALAR_MR_MIME, 1, null, new SpeciesEvolutionCondition((p: Pokemon) => p.moveset.filter(m => m.moveId === Moves.MIMIC).length > 0 && p.scene.arena.biomeType === Biome.RUINS), SpeciesWildEvolutionDelay.NEVER), + new SpeciesEvolution(Species.GALAR_MR_MIME, 1, null, new SpeciesEvolutionCondition((p: Pokemon) => p.moveset.filter(m => m.moveId === Moves.MIMIC).length > 0 && p.scene.arena.biomeType === Biome.RUINS), SpeciesWildEvolutionDelay.MEDIUM), new SpeciesEvolution(Species.MR_MIME, 1, null, new SpeciesEvolutionCondition((p: Pokemon) => p.moveset.filter(m => m.moveId === Moves.MIMIC).length > 0), SpeciesWildEvolutionDelay.MEDIUM) ], [Species.MANTYKE]: [ @@ -1375,7 +1374,7 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.WHIMSICOTT, 1, EvolutionItem.SUN_STONE, null, SpeciesWildEvolutionDelay.MEDIUM) ], [Species.PETILIL]: [ - new SpeciesEvolution(Species.HISUI_LILLIGANT, 1, EvolutionItem.SUN_STONE, new SpeciesEvolutionCondition((p: Pokemon) => p.scene.arena.biomeType === Biome.RUINS), SpeciesWildEvolutionDelay.NEVER), + new SpeciesEvolution(Species.HISUI_LILLIGANT, 1, EvolutionItem.SUN_STONE, new SpeciesEvolutionCondition((p: Pokemon) => p.scene.arena.biomeType === Biome.RUINS), SpeciesWildEvolutionDelay.VERY_LONG), new SpeciesEvolution(Species.LILLIGANT, 1, EvolutionItem.SUN_STONE, null, SpeciesWildEvolutionDelay.MEDIUM) ], [Species.BASCULIN]: [ diff --git a/src/data/pokemon-species.ts b/src/data/pokemon-species.ts index c70a28c77..41c2758c8 100644 --- a/src/data/pokemon-species.ts +++ b/src/data/pokemon-species.ts @@ -6,6 +6,15 @@ import { Species } from './species'; import { Type } from './type'; import { LevelMoves, pokemonFormLevelMoves as pokemonSpeciesFormLevelMoves, pokemonSpeciesLevelMoves } from './pokemon-level-moves'; import { uncatchableSpecies } from './biome'; +import * as Utils from '../utils'; + +export enum Region { + NORMAL, + ALOLA, + GALAR, + HISUI, + PALDEA +} export function getPokemonSpecies(species: Species): PokemonSpecies { if (species >= 2000) @@ -106,14 +115,31 @@ export abstract class PokemonSpeciesForm { return pokemonSpeciesLevelMoves[this.speciesId].slice(0); } - isObtainable() { + getRegion(): Region { + return Math.floor(this.speciesId / 2000) as Region; + } + + isObtainable(): boolean { return (this.generation <= 8 || pokemonPrevolutions.hasOwnProperty(this.speciesId)); } - isCatchable() { + isCatchable(): boolean { return this.isObtainable() && uncatchableSpecies.indexOf(this.speciesId) === -1; } + isRegional(): boolean { + return this.getRegion() > Region.NORMAL; + } + + isRareRegional(): boolean { + switch (this.getRegion()) { + case Region.HISUI: + return true; + } + + return false; + } + getSpriteAtlasPath(female: boolean, formIndex?: integer, shiny?: boolean): string { return this.getSpriteId(female, formIndex, shiny).replace(/\_{2}/g, '/'); } @@ -318,7 +344,7 @@ export default class PokemonSpecies extends PokemonSpeciesForm { return this.name; } - getSpeciesForLevel(level: integer, allowEvolving?: boolean): Species { + getSpeciesForLevel(level: integer, allowEvolving?: boolean, forTrainer?: boolean): Species { const prevolutionLevels = this.getPrevolutionLevels(); if (prevolutionLevels.length) { @@ -342,14 +368,19 @@ export default class PokemonSpecies extends PokemonSpeciesForm { let noEvolutionChance = 1; for (let ev of evolutions) { - if (ev.level > level || ev.wildDelay === SpeciesWildEvolutionDelay.NEVER) + if (ev.level > level) continue; let evolutionChance: number; - if (ev.wildDelay === SpeciesWildEvolutionDelay.NONE) + const evolutionSpecies = getPokemonSpecies(ev.speciesId); + const isRegional = evolutionSpecies.isRegional(); + + if (!forTrainer && isRegional) + evolutionChance = 0; + else if (ev.wildDelay === SpeciesWildEvolutionDelay.NONE) { evolutionChance = Math.min(0.5 + easeInFunc(Math.min(level - ev.level, 40) / 40) / 2, 1); - else { + } else { let preferredMinLevel = (ev.level - 1) + ev.wildDelay * 10; let evolutionLevel = ev.level > 1 ? ev.level : Math.floor(preferredMinLevel / 2); @@ -363,6 +394,9 @@ export default class PokemonSpecies extends PokemonSpeciesForm { } if (evolutionChance > 0) { + if (isRegional) + evolutionChance /= (evolutionSpecies.isRareRegional() ? 16 : 4); + totalWeight += evolutionChance; evolutionPool.set(totalWeight, ev.speciesId); @@ -372,10 +406,10 @@ export default class PokemonSpecies extends PokemonSpeciesForm { } } - if (noEvolutionChance === 1 || Math.random() < noEvolutionChance) + if (noEvolutionChance === 1 || Phaser.Math.RND.realInRange(0, 1) < noEvolutionChance) return this.speciesId; - const randValue = evolutionPool.size === 1 ? 0 : Math.random() * totalWeight; + const randValue = evolutionPool.size === 1 ? 0 : Utils.randSeedInt(totalWeight); for (let weight of evolutionPool.keys()) { if (randValue < weight) diff --git a/src/data/trainer-type.ts b/src/data/trainer-type.ts index 54f55d230..f7ea4fe83 100644 --- a/src/data/trainer-type.ts +++ b/src/data/trainer-type.ts @@ -300,6 +300,7 @@ export class TrainerConfig { public partyMemberFuncs: PartyMemberFuncs = {}; public speciesPools: TrainerTierPools; public speciesFilter: PokemonSpeciesFilter; + public specialtyTypes: Type[] = []; public encounterMessages: string[] = []; public victoryMessages: string[] = []; @@ -419,6 +420,11 @@ export class TrainerConfig { return this; } + setSpecialtyTypes(...specialtyTypes: Type[]): TrainerConfig { + this.specialtyTypes = specialtyTypes; + return this; + } + setEncounterMessages(messages: string[], femaleMessages?: string[]): TrainerConfig { this.encounterMessages = messages; this.femaleEncounterMessages = femaleMessages; @@ -452,6 +458,7 @@ export class TrainerConfig { this.setPartyMemberFunc(-1, getRandomPartyMemberFunc([ signatureSpecies ])); if (specialtyType !== undefined) this.setSpeciesFilter(p => p.isOfType(specialtyType)); + this.setSpecialtyTypes(specialtyType); this.setMoneyMultiplier(2.5); this.setBoss(); this.setStaticParty(); @@ -463,9 +470,10 @@ export class TrainerConfig { initForEliteFour(signatureSpecies: Species, specialtyType?: Type): TrainerConfig { this.setPartyTemplates(trainerPartyTemplates.ELITE_FOUR); this.setPartyMemberFunc(-1, getRandomPartyMemberFunc([ signatureSpecies ])); - if (specialtyType !== undefined) + if (specialtyType !== undefined) { this.setSpeciesFilter(p => p.isOfType(specialtyType) && p.baseTotal >= 450); - else + this.setSpecialtyTypes(specialtyType); + } else this.setSpeciesFilter(p => p.baseTotal >= 450); this.setMoneyMultiplier(3.25); this.setBoss(); @@ -541,7 +549,7 @@ function getGymLeaderPartyTemplate(scene: BattleScene) { function getRandomPartyMemberFunc(speciesPool: Species[], postProcess?: (enemyPokemon: EnemyPokemon) => void): PartyMemberFunc { return (scene: BattleScene, level: integer) => { - const species = getPokemonSpecies(Phaser.Math.RND.pick(speciesPool)).getSpeciesForLevel(level, true); + const species = getPokemonSpecies(Phaser.Math.RND.pick(speciesPool)).getSpeciesForLevel(level, true, true); const ret = new EnemyPokemon(scene, getPokemonSpecies(species), level, true); if (postProcess) postProcess(ret); @@ -553,7 +561,7 @@ function getSpeciesFilterRandomPartyMemberFunc(speciesFilter: PokemonSpeciesFilt const originalSpeciesFilter = speciesFilter; speciesFilter = (species: PokemonSpecies) => allowLegendaries || (!species.legendary && !species.pseudoLegendary && !species.mythical) && originalSpeciesFilter(species); return (scene: BattleScene, level: integer) => { - const ret = new EnemyPokemon(scene, scene.randomSpecies(scene.currentBattle.waveIndex, level, false, speciesFilter), level, true); + const ret = new EnemyPokemon(scene, getPokemonSpecies(scene.randomSpecies(scene.currentBattle.waveIndex, level, false, speciesFilter).getSpeciesForLevel(level, true, true)), level, true); if (postProcess) postProcess(ret); return ret; @@ -578,7 +586,7 @@ export const trainerConfigs: TrainerConfigs = { [TrainerType.BAKER]: new TrainerConfig(++t).setEncounterBgm(TrainerType.CLERK).setMoneyMultiplier(1.35).setSpeciesFilter(s => s.isOfType(Type.GRASS) || s.isOfType(Type.FIRE)), [TrainerType.BEAUTY]: new TrainerConfig(++t).setMoneyMultiplier(1.55).setEncounterBgm(TrainerType.PARASOL_LADY), [TrainerType.BIKER]: new TrainerConfig(++t).setMoneyMultiplier(1.4).setEncounterBgm(TrainerType.ROUGHNECK).setSpeciesFilter(s => s.isOfType(Type.POISON)), - [TrainerType.BLACK_BELT]: new TrainerConfig(++t).setHasGenders('Battle Girl', TrainerType.PSYCHIC).setEncounterBgm(TrainerType.ROUGHNECK).setSpeciesFilter(s => s.isOfType(Type.FIGHTING)) + [TrainerType.BLACK_BELT]: new TrainerConfig(++t).setHasGenders('Battle Girl', TrainerType.PSYCHIC).setEncounterBgm(TrainerType.ROUGHNECK).setSpecialtyTypes(Type.FIGHTING) .setPartyTemplates(trainerPartyTemplates.TWO_WEAK_ONE_AVG, trainerPartyTemplates.TWO_WEAK_ONE_AVG, trainerPartyTemplates.TWO_AVG, trainerPartyTemplates.TWO_AVG, trainerPartyTemplates.TWO_WEAK_ONE_STRONG, trainerPartyTemplates.THREE_AVG, trainerPartyTemplates.TWO_AVG_ONE_STRONG) .setSpeciesPools({ [TrainerPoolTier.COMMON]: [ Species.NIDORAN_F, Species.NIDORAN_M, Species.MACHOP, Species.MAKUHITA, Species.MEDITITE, Species.CROAGUNK, Species.TIMBURR ], @@ -596,7 +604,7 @@ export const trainerConfigs: TrainerConfigs = { [TrainerPoolTier.UNCOMMON]: [ Species.JIGGLYPUFF, Species.MAGNEMITE, Species.MARILL, Species.COTTONEE, Species.SKIDDO ], [TrainerPoolTier.RARE]: [ Species.BUIZEL, Species.SNEASEL, Species.KLEFKI, Species.INDEEDEE ] }), - [TrainerType.CYCLIST]: new TrainerConfig(++t).setMoneyMultiplier(1.3).setHasGenders().setEncounterBgm(TrainerType.CYCLIST).setSpeciesFilter(s => !!s.getLevelMoves().find(plm => plm[1] === Moves.QUICK_ATTACK)) + [TrainerType.CYCLIST]: new TrainerConfig(++t).setMoneyMultiplier(1.3).setHasGenders().setEncounterBgm(TrainerType.CYCLIST) .setPartyTemplates(trainerPartyTemplates.TWO_WEAK, trainerPartyTemplates.ONE_AVG) .setSpeciesPools({ [TrainerPoolTier.COMMON]: [ Species.PICHU, Species.STARLY, Species.TAILLOW, Species.BOLTUND ], @@ -614,7 +622,7 @@ export const trainerConfigs: TrainerConfigs = { }), [TrainerType.DEPOT_AGENT]: new TrainerConfig(++t).setMoneyMultiplier(1.45).setEncounterBgm(TrainerType.CLERK), [TrainerType.DOCTOR]: new TrainerConfig(++t).setMoneyMultiplier(3).setEncounterBgm(TrainerType.CLERK), - [TrainerType.FISHERMAN]: new TrainerConfig(++t).setMoneyMultiplier(1.25).setEncounterBgm(TrainerType.BACKPACKER) + [TrainerType.FISHERMAN]: new TrainerConfig(++t).setMoneyMultiplier(1.25).setEncounterBgm(TrainerType.BACKPACKER).setSpecialtyTypes(Type.WATER) .setPartyTemplates(trainerPartyTemplates.TWO_WEAK_SAME_ONE_AVG, trainerPartyTemplates.ONE_AVG, trainerPartyTemplates.THREE_WEAK_SAME, trainerPartyTemplates.ONE_STRONG, trainerPartyTemplates.SIX_WEAKER) .setSpeciesPools({ [TrainerPoolTier.COMMON]: [ Species.TENTACOOL, Species.MAGIKARP, Species.GOLDEEN, Species.STARYU, Species.REMORAID, Species.SKRELP, Species.CLAUNCHER, Species.ARROKUDA ], @@ -622,9 +630,9 @@ export const trainerConfigs: TrainerConfigs = { [TrainerPoolTier.RARE]: [ Species.CHINCHOU, Species.CORSOLA, Species.WAILMER, Species.BARBOACH, Species.CLAMPERL, Species.LUVDISC, Species.MANTYKE, Species.ALOMOMOLA, /* Species.TATSUGIRI */ /* Species.VELUZA */ ], [TrainerPoolTier.SUPER_RARE]: [ Species.LAPRAS, Species.FEEBAS, Species.RELICANTH, /* Species.DONDOZO */ ] }), - [TrainerType.GUITARIST]: new TrainerConfig(++t).setMoneyMultiplier(1.2).setEncounterBgm(TrainerType.ROUGHNECK).setSpeciesFilter(s => s.isOfType(Type.ELECTRIC)), + [TrainerType.GUITARIST]: new TrainerConfig(++t).setMoneyMultiplier(1.2).setEncounterBgm(TrainerType.ROUGHNECK).setSpecialtyTypes(Type.ELECTRIC).setSpeciesFilter(s => s.isOfType(Type.ELECTRIC)), [TrainerType.HARLEQUIN]: new TrainerConfig(++t).setEncounterBgm(TrainerType.PSYCHIC).setSpeciesFilter(s => tmSpecies[Moves.TRICK_ROOM].indexOf(s.speciesId) > -1), - [TrainerType.HIKER]: new TrainerConfig(++t).setEncounterBgm(TrainerType.BACKPACKER).setSpeciesFilter(s => s.isOfType(Type.GROUND) || s.isOfType(Type.ROCK)) + [TrainerType.HIKER]: new TrainerConfig(++t).setEncounterBgm(TrainerType.BACKPACKER) .setPartyTemplates(trainerPartyTemplates.TWO_AVG_SAME_ONE_AVG, trainerPartyTemplates.TWO_AVG_SAME_ONE_STRONG, trainerPartyTemplates.TWO_AVG, trainerPartyTemplates.FOUR_WEAK, trainerPartyTemplates.ONE_STRONG) .setSpeciesPools({ [TrainerPoolTier.COMMON]: [ Species.SANDSHREW, Species.DIGLETT, Species.GEODUDE, Species.MACHOP, Species.ARON, Species.ROGGENROLA, Species.DRILBUR, /* Species.NACLI */ ], @@ -692,7 +700,7 @@ export const trainerConfigs: TrainerConfigs = { [TrainerType.SNOW_WORKER]: new TrainerConfig(++t).setName('Worker').setMoneyMultiplier(1.7).setEncounterBgm(TrainerType.CLERK).setSpeciesFilter(s => s.isOfType(Type.ICE) || s.isOfType(Type.STEEL)), [TrainerType.STRIKER]: new TrainerConfig(++t).setMoneyMultiplier(1.2).setEncounterBgm(TrainerType.CYCLIST), [TrainerType.STUDENT]: new TrainerConfig(++t).setHasGenders(), - [TrainerType.SWIMMER]: new TrainerConfig(++t).setMoneyMultiplier(1.3).setEncounterBgm(TrainerType.PARASOL_LADY).setHasGenders().setSpeciesFilter(s => s.isOfType(Type.WATER)), + [TrainerType.SWIMMER]: new TrainerConfig(++t).setMoneyMultiplier(1.3).setEncounterBgm(TrainerType.PARASOL_LADY).setHasGenders().setSpecialtyTypes(Type.WATER).setSpeciesFilter(s => s.isOfType(Type.WATER)), [TrainerType.TWINS]: new TrainerConfig(++t).setDouble().setMoneyMultiplier(0.65).setUseSameSeedForAllMembers() .setPartyTemplateFunc(scene => getWavePartyTemplate(scene, trainerPartyTemplates.TWO_WEAK, trainerPartyTemplates.TWO_AVG, trainerPartyTemplates.TWO_STRONG)) .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.PLUSLE, Species.VOLBEAT, Species.PACHIRISU, Species.SILCOON, Species.METAPOD, Species.IGGLYBUFF, Species.PETILIL, Species.EEVEE ])) diff --git a/src/trainer.ts b/src/trainer.ts index 22fe140fd..0daddda59 100644 --- a/src/trainer.ts +++ b/src/trainer.ts @@ -136,7 +136,7 @@ export default class Trainer extends Phaser.GameObjects.Container { } const species = template.isSameSpecies(index) && index > offset - ? getPokemonSpecies(battle.enemyParty[offset].species.getSpeciesForLevel(level)) + ? getPokemonSpecies(battle.enemyParty[offset].species.getSpeciesForLevel(level, false, true)) : this.genNewPartyMemberSpecies(level); ret = new EnemyPokemon(this.scene, species, level, true); @@ -163,7 +163,7 @@ export default class Trainer extends Phaser.GameObjects.Container { } else species = this.scene.randomSpecies(battle.waveIndex, level, false, this.config.speciesFilter); - let ret = getPokemonSpecies(species.getSpeciesForLevel(level, true)); + let ret = getPokemonSpecies(species.getSpeciesForLevel(level, true, true)); let retry = false; console.log(ret.getName()); @@ -176,6 +176,18 @@ export default class Trainer extends Phaser.GameObjects.Container { retry = true; } + if (!retry && this.config.specialtyTypes.length && !this.config.specialtyTypes.find(t => ret.isOfType(t))) { + retry = true; + console.log('Attempting reroll of species evolution to fit specialty type...'); + let evoAttempt = 0; + while (retry && evoAttempt++ < 10) { + ret = getPokemonSpecies(species.getSpeciesForLevel(level, true, true)); + console.log(ret.name); + if (this.config.specialtyTypes.find(t => ret.isOfType(t))) + retry = false; + } + } + if (retry && (attempt || 0) < 10) { console.log('Rerolling party member...') ret = this.genNewPartyMemberSpecies(level, (attempt || 0) + 1);