import {PRNG, PRNGSeed} from '../../../sim/prng'; import RandomTeams from '../../random-teams'; export class RandomRoulettemonsTeams extends RandomTeams { constructor(format: Format | string, prng: PRNG | PRNGSeed | null) { super(format, prng); this.noStab = [...this.noStab, 'gigaimpact']; } getPokemonPool( type: string, pokemonToExclude: RandomTeamsTypes.RandomSet[] = [], isMonotype = false, ) { const pokemonPool = []; for (let species of this.dex.species.all()) { if (species.heightm) continue; if (isMonotype) { if (!species.types.includes(type)) continue; if (typeof species.battleOnly === 'string') { species = this.dex.species.get(species.battleOnly); if (!species.types.includes(type)) continue; } } pokemonPool.push(species.id); } return pokemonPool; } randomTeam() { this.enforceNoDirectCustomBanlistChanges(); const seed = this.prng.seed; const ruleTable = this.dex.formats.getRuleTable(this.format); const pokemon: RandomTeamsTypes.RandomSet[] = []; // For Monotype const isMonotype = !!this.forceMonotype || ruleTable.has('sametypeclause'); const typePool = this.dex.types.names(); const type = this.forceMonotype || this.sample(typePool); const baseFormes: {[k: string]: number} = {}; const typeCount: {[k: string]: number} = {}; const typeComboCount: {[k: string]: number} = {}; const teamDetails: RandomTeamsTypes.TeamDetails = {}; const pokemonPool = this.getPokemonPool(type, pokemon, isMonotype); while (pokemonPool.length && pokemon.length < this.maxTeamSize) { const species = this.dex.species.get(this.sampleNoReplace(pokemonPool)); if (!species.exists) continue; // Check if the forme has moves for random battle if (this.format.gameType === 'singles') { if (!species.randomBattleMoves?.length) continue; } else { if (!species.randomDoubleBattleMoves?.length) continue; } // Limit to one of each species (Species Clause) if (baseFormes[species.baseSpecies]) continue; // Adjust rate for species with multiple sets // TODO: investigate automating this by searching for Pokémon with multiple sets const types = species.types; const typeCombo = types.slice().sort().join(); // Dynamically scale limits for different team sizes. The default and minimum value is 1. const limitFactor = Math.round(this.maxTeamSize / 6) || 1; // Limit one of any type combination, two in Monotype if (!this.forceMonotype && typeComboCount[typeCombo] >= (isMonotype ? 2 : 1) * limitFactor) continue; const set = this.randomSet(species, teamDetails, pokemon.length === 0, this.format.gameType !== 'singles', this.dex.formats.getRuleTable(this.format).has('dynamaxclause')); // Okay, the set passes, add it to our team pokemon.push(set); // Now that our Pokemon has passed all checks, we can increment our counters baseFormes[species.baseSpecies] = 1; // Increment type counters for (const typeName of types) { if (typeName in typeCount) { typeCount[typeName]++; } else { typeCount[typeName] = 1; } } if (typeCombo in typeComboCount) { typeComboCount[typeCombo]++; } else { typeComboCount[typeCombo] = 1; } // Track what the team has if (set.ability === 'Drizzle' || set.moves.includes('raindance')) teamDetails.rain = 1; if (set.ability === 'Drought' || set.moves.includes('sunnyday')) teamDetails.sun = 1; if (set.ability === 'Sand Stream') teamDetails.sand = 1; if (set.ability === 'Snow Warning') teamDetails.hail = 1; if (set.moves.includes('spikes')) teamDetails.spikes = (teamDetails.spikes || 0) + 1; if (set.moves.includes('stealthrock')) teamDetails.stealthRock = 1; if (set.moves.includes('stickyweb')) teamDetails.stickyWeb = 1; if (set.moves.includes('toxicspikes')) teamDetails.toxicSpikes = 1; if (set.moves.includes('defog')) teamDetails.defog = 1; if (set.moves.includes('rapidspin')) teamDetails.rapidSpin = 1; if (set.moves.includes('auroraveil') || (set.moves.includes('reflect') && set.moves.includes('lightscreen'))) { teamDetails.screens = 1; } } if (pokemon.length < this.maxTeamSize && pokemon.length < 12) { // large teams sometimes cannot be built throw new Error(`Could not build a random team for ${this.format} (seed=${seed})`); } return pokemon; } } export default RandomRoulettemonsTeams;