mirror of
https://github.com/smogon/pokemon-showdown.git
synced 2026-04-25 15:40:31 -05:00
It turns out not creating a format on-the-fly breaks deserialization. We now just use the same custom-rule system that tournaments use. Some hacks are currently necessary (many tests assume that we're playing in Anything Goes rather than Custom Game) but we'll work them out in time.
110 lines
3.0 KiB
JavaScript
110 lines
3.0 KiB
JavaScript
'use strict';
|
|
|
|
const assert = require('assert');
|
|
const Sim = require('./../.sim-dist');
|
|
const Dex = Sim.Dex;
|
|
|
|
const cache = new Map();
|
|
const formatsCache = new Map();
|
|
|
|
function capitalize(word) {
|
|
return word.charAt(0).toUpperCase() + word.slice(1);
|
|
}
|
|
|
|
/**
|
|
* The default random number generator seed used if one is not given.
|
|
*/
|
|
const DEFAULT_SEED = [0x09917, 0x06924, 0x0e1c8, 0x06af0];
|
|
|
|
class TestTools {
|
|
constructor(mod = 'base') {
|
|
this.currentMod = mod;
|
|
this.dex = Dex.mod(mod);
|
|
|
|
this.modPrefix = this.dex.isBase ? `[gen8] ` : `[${mod}] `;
|
|
}
|
|
|
|
mod(mod) {
|
|
if (cache.has(mod)) return cache.get(mod);
|
|
|
|
if (typeof mod !== 'string') throw new Error("This only supports strings");
|
|
if (!Dex.dexes[mod]) throw new Error(`Mod ${mod} does not exist`);
|
|
|
|
const moddedTestTools = new TestTools(mod);
|
|
cache.set(mod, moddedTestTools);
|
|
return moddedTestTools;
|
|
}
|
|
|
|
gen(genNum) {
|
|
return this.mod('gen' + genNum);
|
|
}
|
|
|
|
getFormat(options) {
|
|
if (options.formatid) return Dex.getFormat(options.formatid);
|
|
|
|
const gameType = Dex.getId(options.gameType || 'singles');
|
|
const customRules = [
|
|
options.pokemon && '-Nonexistent',
|
|
options.legality && 'Obtainable',
|
|
!options.preview && '!Team Preview',
|
|
options.sleepClause && 'Sleep Clause Mod',
|
|
!options.cancel && '!Cancel Mod',
|
|
options.endlessBattleClause && 'Endless Battle Clause',
|
|
options.inverseMod && 'Inverse Mod',
|
|
].filter(Boolean);
|
|
const customRulesID = customRules.length ? `@@@${customRules.join(',')}` : ``;
|
|
|
|
let basicFormat = this.currentMod === 'base' && gameType === 'singles' ? 'Anything Goes' : 'Custom Game';
|
|
const gameTypePrefix = gameType === 'singles' ? '' : capitalize(gameType) + ' ';
|
|
const formatName = `${this.modPrefix}${gameTypePrefix}${basicFormat}${customRulesID}`;
|
|
|
|
let format = formatsCache.get(formatName);
|
|
if (format) return format;
|
|
|
|
format = Dex.getFormat(formatName);
|
|
if (!format.exists) throw new Error(`Unidentified format: ${formatName}`);
|
|
|
|
formatsCache.set(formatName, format);
|
|
return format;
|
|
}
|
|
|
|
/**
|
|
* Creates a new Battle and returns it.
|
|
*
|
|
* @param {Object} [options]
|
|
* @param {Team[]} [teams]
|
|
* @returns {Sim.Battle} A battle.
|
|
*/
|
|
createBattle(options, teams) {
|
|
if (Array.isArray(options)) {
|
|
teams = options;
|
|
options = {};
|
|
}
|
|
if (!options) options = {};
|
|
const format = this.getFormat(options);
|
|
|
|
const battleOptions = {
|
|
format: format,
|
|
// If a seed for the pseudo-random number generator is not provided,
|
|
// a default seed (guaranteed to be the same across test executions)
|
|
// will be used.
|
|
seed: options.seed || DEFAULT_SEED,
|
|
strictChoices: options.strictChoices !== false,
|
|
};
|
|
|
|
if (!teams) return new Sim.Battle(battleOptions);
|
|
|
|
for (let i = 0; i < teams.length; i++) {
|
|
assert(Array.isArray(teams[i]), `Team provided is not an array`);
|
|
const playerSlot = `p${i + 1}`;
|
|
battleOptions[playerSlot] = {team: teams[i]};
|
|
}
|
|
|
|
return new Sim.Battle(battleOptions);
|
|
}
|
|
}
|
|
|
|
const common = exports = module.exports = new TestTools();
|
|
cache.set('base', common);
|
|
cache.set('gen8', common);
|