pokemon-showdown/data/mods/roulettemons/random-teams.ts
scoopapa d86b9435a3
Add April 2022 Pet Mod of the Season (#8712)
* Add PMOTS

Adding Restrictions and Roulettemons Random Battles

* Update pokedex.ts

* Update random-teams.ts

* Update config/formats.ts

Co-authored-by: Kris Johnson <11083252+KrisXV@users.noreply.github.com>

* Update config/formats.ts

Co-authored-by: Kris Johnson <11083252+KrisXV@users.noreply.github.com>

* Update config/formats.ts

Co-authored-by: Kris Johnson <11083252+KrisXV@users.noreply.github.com>

Co-authored-by: Kris Johnson <11083252+KrisXV@users.noreply.github.com>
2022-04-28 18:49:52 -06:00

118 lines
4.3 KiB
TypeScript

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;