Move Random Battles files to a separate folder (#10285)

* Move Random Battles files to a new folder

* Fix bdsp test

* Move SSB back and move rands files into folders

* fix BF tests

* fix test

* fix bug

* fix SSB teamgen
This commit is contained in:
livid washed 2024-05-10 10:52:33 +10:00 committed by GitHub
parent cf08ea102c
commit 64c5951970
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
48 changed files with 67 additions and 436 deletions

View File

@ -1,5 +0,0 @@
import RandomGen7Teams from '../gen7/random-teams';
export class RandomGen7PokebilitiesTeams extends RandomGen7Teams {}
export default RandomGen7PokebilitiesTeams;

View File

@ -1,4 +1,4 @@
import RandomTeams from '../../random-teams';
import RandomTeams from '../../random-battles/gen9/teams';
export interface SSBSet {
species: string;

View File

@ -1,154 +0,0 @@
import {RandomTeams} from './../../random-teams';
import {toID} from '../../../sim/dex';
const mnmItems = [
'blueorb', 'redorb', 'rustedshield', 'rustedsword',
];
export class RandomMnMTeams extends RandomTeams {
randomCCTeam(): RandomTeamsTypes.RandomSet[] {
this.enforceNoDirectCustomBanlistChanges();
const dex = this.dex;
const team = [];
const natures = this.dex.natures.all();
const items = this.dex.items.all().filter(item => item.megaStone || mnmItems.includes(item.id));
const randomN = this.randomNPokemon(this.maxTeamSize, this.forceMonotype, undefined, undefined, true);
for (let forme of randomN) {
let species = dex.species.get(forme);
if (species.isNonstandard) species = dex.species.get(species.baseSpecies);
// Random legal item
let item = '';
let isIllegalItem;
if (this.gen >= 2) {
do {
item = this.sample(items).name;
isIllegalItem = this.dex.items.get(item).gen > this.gen || this.dex.items.get(item).isNonstandard;
} while (isIllegalItem);
}
// Make sure forme is legal
if (species.battleOnly) {
if (typeof species.battleOnly === 'string') {
species = dex.species.get(species.battleOnly);
} else {
species = dex.species.get(this.sample(species.battleOnly));
}
forme = species.name;
} else if (species.requiredItems && !species.requiredItems.some(req => toID(req) === item)) {
if (!species.changesFrom) throw new Error(`${species.name} needs a changesFrom value`);
species = dex.species.get(species.changesFrom);
forme = species.name;
}
// Random legal ability
const abilities = Object.values(species.abilities).filter(a => this.dex.abilities.get(a).gen <= this.gen);
const ability: string = this.gen <= 2 ? 'No Ability' : this.sample(abilities);
// Four random unique moves from the movepool
let pool = ['struggle'];
if (forme === 'Smeargle') {
pool = this.dex.moves.all()
.filter(move => !(move.isNonstandard || move.isZ || move.isMax || move.realMove))
.map(m => m.id);
} else {
pool = [...this.dex.species.getMovePool(species.id)];
}
const moves = this.multipleSamplesNoReplace(pool, this.maxMoveCount);
// Random EVs
const evs: StatsTable = {hp: 0, atk: 0, def: 0, spa: 0, spd: 0, spe: 0};
const s: StatID[] = ["hp", "atk", "def", "spa", "spd", "spe"];
let evpool = 510;
do {
const x = this.sample(s);
const y = this.random(Math.min(256 - evs[x], evpool + 1));
evs[x] += y;
evpool -= y;
} while (evpool > 0);
// Random IVs
const ivs = {
hp: this.random(32),
atk: this.random(32),
def: this.random(32),
spa: this.random(32),
spd: this.random(32),
spe: this.random(32),
};
// Random nature
const nature = this.sample(natures).name;
// Level balance--calculate directly from stats rather than using some silly lookup table
const mbstmin = 1307; // Sunkern has the lowest modified base stat total, and that total is 807
let stats = species.baseStats;
// If Wishiwashi, use the school-forme's much higher stats
if (species.baseSpecies === 'Wishiwashi') stats = Dex.species.get('wishiwashischool').baseStats;
// Modified base stat total assumes 31 IVs, 85 EVs in every stat
let mbst = (stats["hp"] * 2 + 31 + 21 + 100) + 10;
mbst += (stats["atk"] * 2 + 31 + 21 + 100) + 5;
mbst += (stats["def"] * 2 + 31 + 21 + 100) + 5;
mbst += (stats["spa"] * 2 + 31 + 21 + 100) + 5;
mbst += (stats["spd"] * 2 + 31 + 21 + 100) + 5;
mbst += (stats["spe"] * 2 + 31 + 21 + 100) + 5;
let level;
if (this.adjustLevel) {
level = this.adjustLevel;
} else {
level = Math.floor(100 * mbstmin / mbst); // Initial level guess will underestimate
while (level < 100) {
mbst = Math.floor((stats["hp"] * 2 + 31 + 21 + 100) * level / 100 + 10);
// Since damage is roughly proportional to level
mbst += Math.floor(((stats["atk"] * 2 + 31 + 21 + 100) * level / 100 + 5) * level / 100);
mbst += Math.floor((stats["def"] * 2 + 31 + 21 + 100) * level / 100 + 5);
mbst += Math.floor(((stats["spa"] * 2 + 31 + 21 + 100) * level / 100 + 5) * level / 100);
mbst += Math.floor((stats["spd"] * 2 + 31 + 21 + 100) * level / 100 + 5);
mbst += Math.floor((stats["spe"] * 2 + 31 + 21 + 100) * level / 100 + 5);
if (mbst >= mbstmin) break;
level++;
}
}
// Random happiness
const happiness = this.random(256);
// Random shininess
const shiny = this.randomChance(1, 1024);
const set: RandomTeamsTypes.RandomSet = {
name: species.baseSpecies,
species: species.name,
gender: species.gender,
item,
ability,
moves,
evs,
ivs,
nature,
level,
happiness,
shiny,
};
if (this.gen === 9) {
// Tera type
set.teraType = this.sample(this.dex.types.all()).name;
}
team.push(set);
}
return team;
}
}
export default RandomMnMTeams;

View File

@ -1,5 +0,0 @@
import RandomTeams from '../../random-teams';
export class RandomPartnersInCrimeTeams extends RandomTeams {}
export default RandomPartnersInCrimeTeams;

View File

@ -1,206 +0,0 @@
import {RandomTeams} from './../../random-teams';
const potdPokemon = [
"hoopa", "groudon", "dachsbun", "squawkabilly", "cacturne", "typhlosion", "jolteon", "masquerain", "falinks",
"wyrdeer", "gardevoir", "decidueye", "hawlucha", "azelf", "gothitelle", "donphan", "pikachu", "zaciancrowned",
"quagsire", "uxie", "dondozo", "orthworm", "klawf", "dunsparce", "avalugg", "pawmot", "qwilfish", "lilliganthisui",
];
export class RandomPOTDTeams extends RandomTeams {
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 isDoubles = this.format.gameType !== 'singles';
const typePool = this.dex.types.names();
const type = this.forceMonotype || this.sample(typePool);
// PotD stuff
const day = new Date().getDate();
const potd = this.dex.species.get(potdPokemon[day > 28 ? 27 : day - 1]);
const baseFormes: {[k: string]: number} = {};
const tierCount: {[k: string]: number} = {};
const typeCount: {[k: string]: number} = {};
const typeComboCount: {[k: string]: number} = {};
const typeWeaknesses: {[k: string]: number} = {};
const teamDetails: RandomTeamsTypes.TeamDetails = {};
const pokemonList = isDoubles ? Object.keys(this.randomDoublesSets) : Object.keys(this.randomSets);
const [pokemonPool, baseSpeciesPool] = this.getPokemonPool(
type, pokemon, isMonotype, pokemonList.filter(m => this.dex.species.get(m).baseSpecies !== potd.baseSpecies)
);
// Add PotD to type counts
for (const typeName of potd.types) {
typeCount[typeName] = 1;
}
typeComboCount[potd.types.slice().sort().join()] = 1;
// Increment weakness counter
for (const typeName of this.dex.types.names()) {
// it's weak to the type
if (this.dex.getEffectiveness(typeName, potd) > 0) {
typeWeaknesses[typeName] = 1;
}
}
while (baseSpeciesPool.length && pokemon.length < this.maxTeamSize) {
const baseSpecies = this.sampleNoReplace(baseSpeciesPool);
let species = this.dex.species.get(this.sample(pokemonPool[baseSpecies]));
if (!species.exists) continue;
// Limit to one of each species (Species Clause)
if (baseFormes[species.baseSpecies]) continue;
// Illusion shouldn't be on the last slot
if (species.baseSpecies === 'Zoroark' && pokemon.length >= (this.maxTeamSize - 1)) continue;
// If Zoroark is in the team, the sixth slot should not be a Pokemon with extremely low level
if (
pokemon.some(pkmn => pkmn.name === 'Zoroark') &&
pokemon.length >= (this.maxTeamSize - 1) &&
this.getLevel(species, isDoubles) < 72 &&
!this.adjustLevel
) {
continue;
}
// Pokemon with Last Respects, Intrepid Sword, and Dauntless Shield shouldn't be leading
if (['Basculegion', 'Houndstone', 'Zacian', 'Zamazenta'].includes(species.baseSpecies) && !pokemon.length) continue;
const tier = species.tier;
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 Pokemon per tier, two for Monotype
// Disable this for now, since it is still a new gen
// Unless you want to have a lot of Ubers!
// if (
// (tierCount[tier] >= (this.forceMonotype || isMonotype ? 2 : 1) * limitFactor) &&
// !this.randomChance(1, Math.pow(5, tierCount[tier]))
// ) {
// continue;
// }
if (!isMonotype && !this.forceMonotype) {
let skip = false;
// Limit two of any type
for (const typeName of types) {
if (typeCount[typeName] >= 2 * limitFactor) {
skip = true;
break;
}
}
if (skip) continue;
// Limit three weak to any type
for (const typeName of this.dex.types.names()) {
// it's weak to the type
if (this.dex.getEffectiveness(typeName, species) > 0) {
if (!typeWeaknesses[typeName]) typeWeaknesses[typeName] = 0;
if (typeWeaknesses[typeName] >= 3 * limitFactor) {
skip = true;
break;
}
}
}
if (skip) continue;
}
// Limit one of any type combination, two in Monotype
if (!this.forceMonotype && typeComboCount[typeCombo] >= (isMonotype ? 2 : 1) * limitFactor) continue;
// The Pokemon of the Day
if (potd?.exists && (pokemon.length === 1 || this.maxTeamSize === 1)) species = potd;
const set = this.randomSet(species, teamDetails, pokemon.length === 0, isDoubles);
// Okay, the set passes, add it to our team
pokemon.push(set);
if (pokemon.length === this.maxTeamSize) {
// Set Zoroark's level to be the same as the last Pokemon
const illusion = teamDetails.illusion;
if (illusion) pokemon[illusion - 1].level = pokemon[this.maxTeamSize - 1].level;
// Don't bother tracking details for the last Pokemon
break;
}
// Now that our Pokemon has passed all checks, we can increment our counters
baseFormes[species.baseSpecies] = 1;
// Increment tier counter
if (tierCount[tier]) {
tierCount[tier]++;
} else {
tierCount[tier] = 1;
}
// Don't increment type/weakness counters for POTD, since they were added at the beginning
if (pokemon.length !== 1 && this.maxTeamSize !== 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;
}
// Increment weakness counter
for (const typeName of this.dex.types.names()) {
// it's weak to the type
if (this.dex.getEffectiveness(typeName, species) > 0) {
typeWeaknesses[typeName]++;
}
}
}
// 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' || set.moves.includes('snowscape') || set.moves.includes('chillyreception')) {
teamDetails.snow = 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('stoneaxe')) teamDetails.stealthRock = 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('mortalspin')) teamDetails.rapidSpin = 1;
if (set.moves.includes('tidyup')) teamDetails.rapidSpin = 1;
if (set.moves.includes('auroraveil') || (set.moves.includes('reflect') && set.moves.includes('lightscreen'))) {
teamDetails.screens = 1;
}
if (set.role === 'Tera Blast user') teamDetails.teraBlast = 1;
// For setting Zoroark's level
if (set.ability === 'Illusion') teamDetails.illusion = pokemon.length;
}
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 RandomPOTDTeams;

View File

@ -1,4 +1,4 @@
import RandomGen2Teams from '../gen2/random-teams';
import RandomGen2Teams from '../gen2/teams';
import {Utils} from '../../../lib';
interface HackmonsCupEntry {
@ -15,7 +15,7 @@ interface Gen1RandomBattleSpecies {
}
export class RandomGen1Teams extends RandomGen2Teams {
randomData: {[species: string]: Gen1RandomBattleSpecies} = require('./random-data.json');
randomData: {[species: string]: Gen1RandomBattleSpecies} = require('./data.json');
// Challenge Cup or CC teams are basically fully random teams.
randomCCTeam() {

View File

@ -1,6 +1,6 @@
import RandomGen3Teams from '../gen3/random-teams';
import RandomGen3Teams from '../gen3/teams';
import {PRNG, PRNGSeed} from '../../../sim/prng';
import type {MoveCounter} from '../gen8/random-teams';
import type {MoveCounter} from '../gen8/teams';
// Moves that restore HP:
const RECOVERY_MOVES = [
@ -26,7 +26,7 @@ const MOVE_PAIRS = [
];
export class RandomGen2Teams extends RandomGen3Teams {
randomSets: {[species: string]: RandomTeamsTypes.RandomSpeciesData} = require('./random-sets.json');
randomSets: {[species: string]: RandomTeamsTypes.RandomSpeciesData} = require('./sets.json');
constructor(format: string | Format, prng: PRNG | PRNGSeed | null) {
super(format, prng);

View File

@ -1,7 +1,7 @@
import RandomGen4Teams from '../gen4/random-teams';
import RandomGen4Teams from '../gen4/teams';
import {Utils} from '../../../lib';
import {PRNG, PRNGSeed} from '../../../sim/prng';
import type {MoveCounter} from '../gen8/random-teams';
import type {MoveCounter} from '../gen8/teams';
// Moves that restore HP:
const RECOVERY_MOVES = [
@ -31,7 +31,7 @@ export class RandomGen3Teams extends RandomGen4Teams {
battleHasDitto: boolean;
battleHasWobbuffet: boolean;
randomSets: {[species: string]: RandomTeamsTypes.RandomSpeciesData} = require('./random-sets.json');
randomSets: {[species: string]: RandomTeamsTypes.RandomSpeciesData} = require('./sets.json');
constructor(format: string | Format, prng: PRNG | PRNGSeed | null) {
super(format, prng);

View File

@ -1,7 +1,7 @@
import RandomGen5Teams from '../gen5/random-teams';
import RandomGen5Teams from '../gen5/teams';
import {Utils} from '../../../lib';
import {PRNG} from '../../../sim';
import type {MoveCounter} from '../gen8/random-teams';
import type {MoveCounter} from '../gen8/teams';
// Moves that restore HP:
const RECOVERY_MOVES = [
@ -43,7 +43,7 @@ const PRIORITY_POKEMON = [
];
export class RandomGen4Teams extends RandomGen5Teams {
randomSets: {[species: string]: RandomTeamsTypes.RandomSpeciesData} = require('./random-sets.json');
randomSets: {[species: string]: RandomTeamsTypes.RandomSpeciesData} = require('./sets.json');
constructor(format: string | Format, prng: PRNG | PRNGSeed | null) {
super(format, prng);

View File

@ -1,8 +1,8 @@
import RandomGen6Teams from '../gen6/random-teams';
import RandomGen6Teams from '../gen6/teams';
import {Utils} from '../../../lib';
import {toID} from '../../../sim/dex';
import {PRNG} from '../../../sim';
import {MoveCounter} from '../gen8/random-teams';
import {MoveCounter} from '../gen8/teams';
// Moves that restore HP:
const RECOVERY_MOVES = [
@ -52,7 +52,7 @@ const PRIORITY_POKEMON = [
];
export class RandomGen5Teams extends RandomGen6Teams {
randomSets: {[species: string]: RandomTeamsTypes.RandomSpeciesData} = require('./random-sets.json');
randomSets: {[species: string]: RandomTeamsTypes.RandomSpeciesData} = require('./sets.json');
constructor(format: string | Format, prng: PRNG | PRNGSeed | null) {
super(format, prng);

View File

@ -1,5 +1,5 @@
import {MoveCounter, TeamData} from '../gen8/random-teams';
import RandomGen7Teams, {BattleFactorySpecies, ZeroAttackHPIVs} from '../gen7/random-teams';
import {MoveCounter, TeamData} from '../gen8/teams';
import RandomGen7Teams, {BattleFactorySpecies, ZeroAttackHPIVs} from '../gen7/teams';
import {PRNG, PRNGSeed} from '../../../sim/prng';
import {Utils} from '../../../lib';
import {toID} from '../../../sim/dex';
@ -63,7 +63,7 @@ const PRIORITY_POKEMON = [
];
export class RandomGen6Teams extends RandomGen7Teams {
randomSets: {[species: string]: RandomTeamsTypes.RandomSpeciesData} = require('./random-sets.json');
randomSets: {[species: string]: RandomTeamsTypes.RandomSpeciesData} = require('./sets.json');
constructor(format: Format | string, prng: PRNG | PRNGSeed | null) {
super(format, prng);

View File

@ -1,4 +1,4 @@
import {MoveCounter, TeamData, RandomGen8Teams} from '../gen8/random-teams';
import {MoveCounter, TeamData, RandomGen8Teams} from '../gen8/teams';
import {PRNG, PRNGSeed} from '../../../sim/prng';
import {Utils} from '../../../lib';
import {toID} from '../../../sim/dex';
@ -99,7 +99,7 @@ function sereneGraceBenefits(move: Move) {
}
export class RandomGen7Teams extends RandomGen8Teams {
randomSets: {[species: string]: RandomTeamsTypes.RandomSpeciesData} = require('./random-sets.json');
randomSets: {[species: string]: RandomTeamsTypes.RandomSpeciesData} = require('./sets.json');
constructor(format: Format | string, prng: PRNG | PRNGSeed | null) {
super(format, prng);

View File

@ -1,8 +1,8 @@
import type {PRNG} from '../../../sim';
import {MoveCounter, RandomGen8Teams, OldRandomBattleSpecies} from '../gen8/random-teams';
import {MoveCounter, RandomGen8Teams, OldRandomBattleSpecies} from '../gen8/teams';
export class RandomLetsGoTeams extends RandomGen8Teams {
randomData: {[species: string]: OldRandomBattleSpecies} = require('./random-data.json');
randomData: {[species: string]: OldRandomBattleSpecies} = require('./data.json');
constructor(format: Format | string, prng: PRNG | PRNGSeed | null) {
super(format, prng);

View File

@ -111,7 +111,7 @@ export class RandomGen8Teams {
readonly maxMoveCount: number;
readonly forceMonotype: string | undefined;
randomData: {[species: string]: OldRandomBattleSpecies} = require('./random-data.json');
randomData: {[species: string]: OldRandomBattleSpecies} = require('./data.json');
/**
* Checkers for move enforcement based on a Pokémon's types or other factors

View File

@ -1,10 +1,10 @@
// BDSP team generation logic is currently largely shared with Swsh
import {PRNG, PRNGSeed} from '../../../sim/prng';
import {MoveCounter, RandomGen8Teams, OldRandomBattleSpecies} from '../gen8/random-teams';
import {MoveCounter, RandomGen8Teams, OldRandomBattleSpecies} from '../gen8/teams';
export class RandomBDSPTeams extends RandomGen8Teams {
randomData: {[species: string]: OldRandomBattleSpecies} = require('./random-data.json');
randomData: {[species: string]: OldRandomBattleSpecies} = require('./data.json');
constructor(format: Format | string, prng: PRNG | PRNGSeed | null) {
super(format, prng);

View File

@ -1,8 +1,8 @@
import {Dex, toID} from '../sim/dex';
import {Utils} from '../lib';
import {PRNG, PRNGSeed} from '../sim/prng';
import {RuleTable} from '../sim/dex-formats';
import {Tags} from './tags';
import {Dex, toID} from '../../../sim/dex';
import {Utils} from '../../../lib';
import {PRNG, PRNGSeed} from '../../../sim/prng';
import {RuleTable} from '../../../sim/dex-formats';
import {Tags} from './../../tags';
export interface TeamData {
typeCount: {[k: string]: number};
@ -1755,8 +1755,8 @@ export class RandomTeams {
return [pokemonPool, baseSpeciesPool];
}
randomSets: {[species: string]: RandomTeamsTypes.RandomSpeciesData} = require('./random-sets.json');
randomDoublesSets: {[species: string]: RandomTeamsTypes.RandomSpeciesData} = require('./random-doubles-sets.json');
randomSets: {[species: string]: RandomTeamsTypes.RandomSpeciesData} = require('./sets.json');
randomDoublesSets: {[species: string]: RandomTeamsTypes.RandomSpeciesData} = require('./doubles-sets.json');
randomTeam() {
this.enforceNoDirectCustomBanlistChanges();

View File

@ -1,4 +1,4 @@
import RandomTeams from '../../random-teams';
import RandomTeams from '../gen9/teams';
export class RandomRandomRouletteTeams extends RandomTeams {}

View File

@ -1,4 +1,4 @@
import RandomTeams from '../../random-teams';
import RandomTeams from '../gen9/teams';
export class RandomSharedPowerTeams extends RandomTeams {}

View File

@ -156,7 +156,7 @@ function getSets(species: string | Species, format: string | Format = 'gen9rando
species = dex.species.get(species);
const isDoubles = format.gameType === 'doubles';
const setsFile = JSON.parse(
FS(`data/${dex.isBase ? '' : `mods/${dex.currentMod}/`}random-${isDoubles ? `doubles-` : ``}sets.json`)
FS(`data/random-battles/${format.mod}/${isDoubles ? `doubles-` : ``}sets.json`)
.readIfExistsSync() || '{}'
);
const data = setsFile[species.id];
@ -172,7 +172,7 @@ function getData(species: string | Species, format: string | Format): any | null
format = Dex.formats.get(format);
species = dex.species.get(species);
const dataFile = JSON.parse(
FS(`data/mods/${dex.currentMod}/random-data.json`).readIfExistsSync() || '{}'
FS(`data/random-battles/${format.mod}/data.json`).readIfExistsSync() || '{}'
);
const data = dataFile[species.id];
if (!data) return null;
@ -203,7 +203,6 @@ function getLevel(species: string | Species, format: string | Format): number {
Uber: 61,
};
return levelScale[species.tier] || 80;
// TODO: Gen 7 Doubles (currently uses BST-based scaling that accounts for the set's ability/item)
}
return 0;
}
@ -260,7 +259,7 @@ function battleFactorySets(species: string | Species, tier: string | null, gen =
const genNum = parseInt(gen[3]);
if (isNaN(genNum) || genNum < 6 || (isBSS && genNum < 7)) return null;
const statsFile = JSON.parse(
FS(`data${gen === 'gen9' ? '/' : `/mods/${gen}`}/${isBSS ? `bss-` : ``}factory-sets.json`).readIfExistsSync() ||
FS(`data/random-battles/gen${genNum}/${isBSS ? `bss-` : ``}factory-sets.json`).readIfExistsSync() ||
"{}"
);
if (!Object.keys(statsFile).length) return null;
@ -360,7 +359,7 @@ function battleFactorySets(species: string | Species, tier: string | null, gen =
function CAP1v1Sets(species: string | Species) {
species = Dex.species.get(species);
const statsFile = JSON.parse(
FS(`data/mods/gen8/cap-1v1-sets.json`).readIfExistsSync() ||
FS(`data/random-battles/gen8/cap-1v1-sets.json`).readIfExistsSync() ||
"{}"
);
if (!Object.keys(statsFile).length) return null;

View File

@ -617,12 +617,13 @@ export const Teams = new class Teams {
getGenerator(format: Format | string, seed: PRNG | PRNGSeed | null = null) {
let TeamGenerator;
format = Dex.formats.get(format);
if (toID(format).includes('gen9computergeneratedteams')) {
TeamGenerator = require(Dex.forFormat(format).dataDir + '/cg-teams').default;
} else if (toID(format).includes('gen7randomdoublesbattle')) {
TeamGenerator = require(Dex.forFormat(format).dataDir + '/random-doubles-teams').default;
} else if (toID(format).includes('gen9superstaffbrosultimate')) {
TeamGenerator = require(`../data/mods/gen9ssb/random-teams`).default;
} else {
TeamGenerator = require(Dex.forFormat(format).dataDir + '/random-teams').default;
TeamGenerator = require(`../data/random-battles/${format.mod}/teams`).default;
}
return new TeamGenerator(format, seed);

View File

@ -34,7 +34,7 @@ describe('value rule support (slow)', () => {
// Due to frontloading of moveset generation, formats with the new set format do not support
// Max Move Counts less than 4
if (count < 4) continue;
const setsJSON = require(`../../dist/data/${gen === 9 ? '' : `mods/gen${gen}/`}random-sets.json`);
const setsJSON = require(`../../dist/data/random-battles/gen${gen}/sets.json`);
it(`${format.name} should support Max Move Count = ${count}`, () => {
testTeam({format, rounds: 50}, team => {
@ -66,7 +66,7 @@ describe('value rule support (slow)', () => {
});
});
} else {
const dataJSON = require(`../../dist/data/mods/gen${gen}/random-data.json`);
const dataJSON = require(`../../dist/data/random-battles/gen${gen}/data.json`);
it(`${format.name} should support Max Move Count = ${count}`, () => {
testTeam({format, rounds: 50}, team => {
@ -114,12 +114,12 @@ describe('value rule support (slow)', () => {
});
describe("New set format", () => {
const files = ['../../data/random-sets.json', '../../data/random-doubles-sets.json'];
const files = ['../../data/random-battles/gen9/sets.json', '../../data/random-battles/gen9/doubles-sets.json'];
for (const filename of files) {
it(`${filename} should have valid set data`, () => {
const setsJSON = require(filename);
let validRoles = [];
if (filename === '../../data/random-sets.json') {
if (filename === '../../data/random-battles/gen9/sets.json') {
validRoles = ["Fast Attacker", "Setup Sweeper", "Wallbreaker", "Tera Blast user",
"Bulky Attacker", "Bulky Setup", "Fast Bulky Setup", "Bulky Support", "Fast Support", "AV Pivot"];
} else {
@ -178,16 +178,16 @@ describe('randomly generated teams should be valid (slow)', () => {
});
describe('Battle Factory and BSS Factory data should be valid (slow)', () => {
for (const filename of ['mods/gen8/bss-factory-sets', 'mods/gen7/bss-factory-sets', 'mods/gen7/factory-sets', 'mods/gen6/factory-sets']) {
for (const filename of ['gen8/bss-factory-sets', 'gen7/bss-factory-sets', 'gen7/factory-sets', 'gen6/factory-sets']) {
it(`${filename}.json should contain valid sets`, function () {
this.timeout(0);
const setsJSON = require(`../../dist/data/${filename}.json`);
const mod = filename.split('/')[1] || 'gen' + Dex.gen;
const setsJSON = require(`../../dist/data/random-battles/${filename}.json`);
const mod = filename.split('/')[0] || 'gen' + Dex.gen;
const genNum = isNaN(mod[3]) ? Dex.gen : mod[3];
for (const type in setsJSON) {
const typeTable = filename.includes('bss-factory-sets') ? setsJSON : setsJSON[type];
const vType = filename === 'bss-factory-sets' ? `battle${genNum === 8 ? 'stadium' : 'spot'}singles` :
const vType = filename.includes('bss-factory-sets') ? `battle${genNum === 8 ? 'stadium' : 'spot'}singles` :
type === 'Mono' ? 'monotype' : type.toLowerCase();
for (const species in typeTable) {
const speciesData = typeTable[species];

View File

@ -8,11 +8,11 @@ const {testTeam, validateLearnset} = require('./tools');
describe('[Gen 2] Random Battle (slow)', () => {
const options = {format: 'gen2randombattle'};
const setsJSON = require(`../../dist/data/mods/gen2/random-sets.json`);
const setsJSON = require(`../../dist/data/random-battles/gen2/sets.json`);
const dex = Dex.forFormat(options.format);
describe("New set format", () => {
const filename = '../../data/mods/gen2/random-sets.json';
const filename = '../../data/random-battles/gen2/sets.json';
it(`${filename} should have valid set data`, () => {
const setsJSON = require(filename);
const validRoles = [

View File

@ -8,11 +8,11 @@ const {testTeam, validateLearnset} = require('./tools');
describe('[Gen 3] Random Battle (slow)', () => {
const options = {format: 'gen3randombattle'};
const setsJSON = require(`../../dist/data/mods/gen3/random-sets.json`);
const setsJSON = require(`../../dist/data/random-battles/gen3/sets.json`);
const dex = Dex.forFormat(options.format);
describe("New set format", () => {
const filename = '../../data/mods/gen3/random-sets.json';
const filename = '../../data/random-battles/gen3/sets.json';
it(`${filename} should have valid set data`, () => {
const setsJSON = require(filename);
const validRoles = [

View File

@ -8,11 +8,11 @@ const {testTeam, testSet, testHiddenPower, validateLearnset} = require('./tools'
describe('[Gen 4] Random Battle (slow)', () => {
const options = {format: 'gen4randombattle'};
const setsJSON = require(`../../dist/data/mods/gen4/random-sets.json`);
const setsJSON = require(`../../dist/data/random-battles/gen4/sets.json`);
const dex = Dex.forFormat(options.format);
describe("New set format", () => {
const filename = '../../data/mods/gen4/random-sets.json';
const filename = '../../data/random-battles/gen4/sets.json';
it(`${filename} should have valid set data`, () => {
const setsJSON = require(filename);
const validRoles = [

View File

@ -8,11 +8,11 @@ const {testTeam, testSet, testHiddenPower, testAlwaysHasMove, validateLearnset}
describe('[Gen 5] Random Battle (slow)', () => {
const options = {format: 'gen5randombattle'};
const setsJSON = require(`../../dist/data/mods/gen5/random-sets.json`);
const setsJSON = require(`../../dist/data/random-battles/gen5/sets.json`);
const dex = Dex.forFormat(options.format);
describe("New set format", () => {
const filename = '../../data/mods/gen5/random-sets.json';
const filename = '../../data/random-battles/gen5/sets.json';
it(`${filename} should have valid set data`, () => {
const setsJSON = require(filename);
const validRoles = [

View File

@ -8,11 +8,11 @@ const {testTeam, testNotBothMoves, testSet, testHiddenPower, testAlwaysHasMove,
describe('[Gen 6] Random Battle (slow)', () => {
const options = {format: 'gen6randombattle'};
const setsJSON = require(`../../dist/data/mods/gen6/random-sets.json`);
const setsJSON = require(`../../dist/data/random-battles/gen6/sets.json`);
const dex = Dex.forFormat(options.format);
describe("New set format", () => {
const filename = '../../data/mods/gen6/random-sets.json';
const filename = '../../data/random-battles/gen6/sets.json';
it(`${filename} should have valid set data`, () => {
const setsJSON = require(filename);
const validRoles = [

View File

@ -8,11 +8,11 @@ const {testTeam, testNotBothMoves, testSet, testHiddenPower, testAlwaysHasMove,
describe('[Gen 7] Random Battle (slow)', () => {
const options = {format: 'gen7randombattle'};
const setsJSON = require(`../../dist/data/mods/gen7/random-sets.json`);
const setsJSON = require(`../../dist/data/random-battles/gen7/sets.json`);
const dex = Dex.forFormat(options.format);
describe("New set format", () => {
const filename = '../../data/mods/gen7/random-sets.json';
const filename = '../../data/random-battles/gen7/sets.json';
it(`${filename} should have valid set data`, () => {
const setsJSON = require(filename);
const validRoles = [

View File

@ -8,7 +8,7 @@ const assert = require('../assert');
describe('[Gen 8] Random Battle (slow)', () => {
const options = {format: 'gen8randombattle'};
const dataJSON = require(`../../dist/data/mods/gen8/random-data.json`);
const dataJSON = require(`../../dist/data/random-battles/gen8/data.json`);
const dex = Dex.forFormat(options.format);
const generator = Teams.getGenerator(options.format);
@ -258,7 +258,7 @@ describe('[Gen 8] Free-for-All Random Battle (slow)', () => {
describe('[Gen 8 BDSP] Random Battle (slow)', () => {
const options = {format: 'gen8bdsprandombattle'};
const dataJSON = require(`../../dist/data/mods/gen8bdsp/random-data.json`);
const dataJSON = require(`../../dist/data/random-battles/gen8bdsp/data.json`);
const dex = Dex.forFormat(options.format);
const okToHaveChoiceMoves = ['switcheroo', 'trick', 'healingwish'];

View File

@ -10,7 +10,7 @@ const Dex = require('./../../dist/sim/dex').Dex;
describe('[Gen 9] Random Battle (slow)', () => {
const options = {format: 'gen9randombattle'};
const setsJSON = require(`../../dist/data/random-sets.json`);
const setsJSON = require(`../../dist/data/random-battles/gen9/sets.json`);
const dex = Dex.forFormat(options.format);
it('all Pokemon should have 4 moves, except for Ditto', function () {
@ -78,7 +78,7 @@ describe('[Gen 9] Monotype Random Battle (slow)', () => {
describe('[Gen 9] Random Doubles Battle (slow)', () => {
const options = {format: 'gen9randomdoublesbattle'};
const setsJSON = require(`../../dist/data/random-doubles-sets.json`);
const setsJSON = require(`../../dist/data/random-battles/gen9/doubles-sets.json`);
const dex = Dex.forFormat(options.format);
it('all Pokemon should have 4 moves, except for Ditto', function () {

View File

@ -27,6 +27,7 @@
"./config/*.ts",
"./data/*",
"./data/text/*",
"./data/random-battles/**/*",
"./data/mods/*/*",
"./dev-tools/*.ts",
"./lib/*.ts",