mirror of
https://github.com/smogon/pokemon-showdown.git
synced 2026-03-21 17:25:10 -05:00
Add November 2025 rotational ladders (#11554)
Some checks are pending
Node.js CI / build (18.x) (push) Waiting to run
Some checks are pending
Node.js CI / build (18.x) (push) Waiting to run
This commit is contained in:
parent
0005dd6a40
commit
97c7a70bfd
|
|
@ -506,89 +506,203 @@ export const Formats: import('../sim/dex-formats').FormatList = [
|
|||
column: 2,
|
||||
},
|
||||
{
|
||||
name: "[Gen 9] Pokebilities",
|
||||
desc: `Pokémon have all of their released abilities simultaneously.`,
|
||||
mod: 'pokebilities',
|
||||
name: "[Gen 9] Fortemons",
|
||||
desc: `Put an attacking move in the item slot to have all of a Pokémon's attacks inherit its properties.`,
|
||||
mod: 'gen9',
|
||||
// searchShow: false,
|
||||
ruleset: ['Standard OMs', 'Sleep Moves Clause'],
|
||||
ruleset: ['Standard OMs', 'Sleep Moves Clause', 'Terastal Clause'],
|
||||
banlist: [
|
||||
// Pokemon
|
||||
'Arceus', 'Annihilape', 'Archaludon', 'Basculegion', 'Basculegion-F', 'Baxcalibur', 'Braviary-Hisui', 'Calyrex-Ice', 'Calyrex-Shadow', 'Chi-Yu', 'Chien-Pao', 'Conkeldurr',
|
||||
'Deoxys-Normal', 'Deoxys-Attack', 'Dialga', 'Dialga-Origin', 'Espathra', 'Eternatus', 'Excadrill', 'Flutter Mane', 'Giratina', 'Giratina-Origin', 'Gouging Fire', 'Groudon',
|
||||
'Ho-Oh', 'Iron Bundle', 'Koraidon', 'Kyogre', 'Kyurem-Black', 'Kyurem-White', 'Landorus-Incarnate', 'Lugia', 'Lunala', 'Magearna', 'Miraidon', 'Mewtwo', 'Necrozma-Dusk-Mane',
|
||||
'Necrozma-Dawn-Wings', 'Ogerpon-Hearthflame', 'Palafin', 'Palkia', 'Palkia-Origin', 'Porygon-Z', 'Rayquaza', 'Regieleki', 'Reshiram', 'Roaring Moon', 'Shaymin-Sky', 'Sneasler',
|
||||
'Solgaleo', 'Spectrier', 'Terapagos', 'Ursaluna-Bloodmoon', 'Urshifu-Single-Strike', 'Urshifu-Rapid-Strike', 'Volcarona', 'Zacian', 'Zacian-Crowned', 'Zamazenta-Crowned',
|
||||
'Zekrom', 'Arena Trap', 'Moody', 'Shadow Tag', 'Bright Powder', 'Damp Rock', 'Icy Rock', 'King\'s Rock', 'Razor Fang', 'Smooth Rock', 'Baton Pass', 'Shed Tail', 'Last Respects',
|
||||
'Annihilape', 'Arceus', 'Archaludon', 'Azumarill', 'Calyrex-Ice', 'Calyrex-Shadow', 'Chi-Yu', 'Chien-Pao', 'Cloyster', 'Comfey', 'Deoxys-Normal', 'Deoxys-Attack',
|
||||
'Dialga-Base', 'Espathra', 'Eternatus', 'Flutter Mane', 'Giratina-Altered', 'Great Tusk', 'Groudon', 'Ho-Oh', 'Iron Bundle', 'Iron Treads', 'Koraidon', 'Kyogre',
|
||||
'Kyurem-Black', 'Kyurem-White', 'Lugia', 'Lunala', 'Magearna', 'Meowscarada', 'Mewtwo', 'Miraidon', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane', 'Palafin',
|
||||
'Palkia', 'Palkia-Origin', 'Rayquaza', 'Reshiram', 'Samurott-Hisui', 'Shaymin-Sky', 'Skeledirge', 'Smeargle', 'Solgaleo', 'Spectrier', 'Sneasler', 'Terapagos',
|
||||
'Urshifu', 'Urshifu-Rapid-Strike', 'Zacian', 'Zacian-Crowned', 'Zamazenta', 'Zamazenta-Crowned', 'Zekrom', 'Arena Trap', 'Moody', 'Serene Grace', 'Shadow Tag',
|
||||
'Damp Rock', 'Heat Rock', 'Light Clay', 'Baton Pass', 'Beat Up', 'Fake Out', 'Last Respects', 'Shed Tail',
|
||||
],
|
||||
onValidateSet(set) {
|
||||
const species = this.dex.species.get(set.species);
|
||||
const unSeenAbilities = Object.keys(species.abilities)
|
||||
.filter(key => key !== 'S' && (key !== 'H' || !species.unreleasedHidden))
|
||||
.map(key => species.abilities[key as "0" | "1" | "H" | "S"])
|
||||
.filter(ability => ability !== set.ability);
|
||||
if (unSeenAbilities.length && this.toID(set.ability) !== this.toID(species.abilities['S'])) {
|
||||
for (const abilityName of unSeenAbilities) {
|
||||
const banReason = this.ruleTable.check('ability:' + this.toID(abilityName));
|
||||
if (banReason) {
|
||||
return [`${set.name}'s ability ${abilityName} is ${banReason}.`];
|
||||
restricted: [
|
||||
'Doom Desire', 'Dynamic Punch', 'Electro Ball', 'Explosion', 'Gyro Ball', 'Final Gambit', 'Flail', 'Flip Turn', 'Fury Cutter', 'Future Sight', 'Grass Knot',
|
||||
'Grassy Glide', 'Hard Press', 'Heavy Slam', 'Heat Crash', 'Inferno', 'Low Kick', 'Misty Explosion', 'Nuzzle', 'Power Trip', 'Reversal', 'Self-Destruct',
|
||||
'Spit Up', 'Stored Power', 'Tera Blast', 'U-turn', 'Weather Ball', 'Zap Cannon',
|
||||
],
|
||||
onValidateTeam(team) {
|
||||
const itemTable = new Set<string>();
|
||||
for (const set of team) {
|
||||
const forte = this.toID(set.item);
|
||||
if (!forte) continue;
|
||||
const move = this.dex.moves.get(forte);
|
||||
if (move.exists && move.id !== 'metronome') {
|
||||
if (itemTable.has(forte)) {
|
||||
return [
|
||||
`You are limited to one of each move in the item slot per team.`,
|
||||
`(You have more than one ${move.name}.)`,
|
||||
];
|
||||
}
|
||||
itemTable.add(forte);
|
||||
}
|
||||
}
|
||||
},
|
||||
validateSet(set, teamHas) {
|
||||
const item = set.item;
|
||||
const species = this.dex.species.get(set.species);
|
||||
const move = this.dex.moves.get(item);
|
||||
if (!move.exists || move.id === 'metronome' || move.category === 'Status') {
|
||||
return this.validateSet(set, teamHas);
|
||||
}
|
||||
set.item = '';
|
||||
const problems = this.validateSet(set, teamHas) || [];
|
||||
set.item = item;
|
||||
if (this.checkCanLearn(move, species, this.allSources(species), set)) {
|
||||
problems.push(`${species.name} can't learn ${move.name}.`);
|
||||
}
|
||||
if (set.moves.map(this.toID).includes(move.id)) {
|
||||
problems.push(`Moves in the item slot can't be in the moveslots as well.`);
|
||||
}
|
||||
if (this.ruleTable.has(`-move:${move.id}`)) {
|
||||
problems.push(`The move ${move.name} is fully banned.`);
|
||||
}
|
||||
const accuracyLoweringMove =
|
||||
move.secondaries?.some(secondary => secondary.boosts?.accuracy && secondary.boosts?.accuracy < 0);
|
||||
const flinchMove = move.secondaries?.some(secondary => secondary.volatileStatus === 'flinch');
|
||||
const freezeMove = move.secondaries?.some(secondary => secondary.status === 'frz') || move.id === 'triattack';
|
||||
if (
|
||||
this.ruleTable.isRestricted(`move:${move.id}`) ||
|
||||
((accuracyLoweringMove || move.ohko || move.multihit || move.id === 'beatup' || move.flags['charge'] ||
|
||||
move.priority > 0 || move.damageCallback || flinchMove || freezeMove) &&
|
||||
!this.ruleTable.has(`+move:${move.id}`))
|
||||
) {
|
||||
problems.push(`The move ${move.name} can't be used as an item.`);
|
||||
}
|
||||
return problems.length ? problems : null;
|
||||
},
|
||||
onBegin() {
|
||||
for (const pokemon of this.getAllPokemon()) {
|
||||
if (pokemon.ability === this.toID(pokemon.species.abilities['S'])) {
|
||||
continue;
|
||||
}
|
||||
pokemon.m.innates = Object.keys(pokemon.species.abilities)
|
||||
.filter(key => key !== 'S' && (key !== 'H' || !pokemon.species.unreleasedHidden))
|
||||
.map(key => this.toID(pokemon.species.abilities[key as "0" | "1" | "H" | "S"]))
|
||||
.filter(ability => ability !== pokemon.ability);
|
||||
}
|
||||
},
|
||||
onBeforeSwitchIn(pokemon) {
|
||||
if (pokemon.m.innates) {
|
||||
for (const innate of pokemon.m.innates) {
|
||||
if (pokemon.hasAbility(innate)) continue;
|
||||
const effect = 'ability:' + this.toID(innate);
|
||||
pokemon.volatiles[effect] = this.initEffectState({ id: effect, target: pokemon });
|
||||
const move = this.dex.getActiveMove(pokemon.set.item);
|
||||
if (move.exists && move.category !== 'Status') {
|
||||
pokemon.m.forte = move;
|
||||
pokemon.item = 'mail' as ID;
|
||||
}
|
||||
}
|
||||
},
|
||||
onSwitchOut(pokemon) {
|
||||
for (const innate of Object.keys(pokemon.volatiles).filter(i => i.startsWith('ability:'))) {
|
||||
pokemon.removeVolatile(innate);
|
||||
onModifyMovePriority: 1,
|
||||
onModifyMove(move, pokemon, target) {
|
||||
const forte: ActiveMove = pokemon.m.forte;
|
||||
if (move.category !== 'Status' && forte) {
|
||||
move.flags = { ...move.flags, ...forte.flags };
|
||||
if (forte.self) {
|
||||
if (forte.self.onHit && move.self?.onHit) {
|
||||
for (const i in forte.self) {
|
||||
if (i.startsWith('onHit')) continue;
|
||||
(move.self as any)[i] = (forte.self as any)[i];
|
||||
}
|
||||
} else {
|
||||
move.self = { ...move.self, ...forte.self };
|
||||
}
|
||||
}
|
||||
if (forte.selfBoost?.boosts) {
|
||||
if (!move.selfBoost?.boosts) move.selfBoost = { boosts: {} };
|
||||
let boostid: BoostID;
|
||||
for (boostid in forte.selfBoost.boosts) {
|
||||
if (!move.selfBoost.boosts![boostid]) move.selfBoost.boosts![boostid] = 0;
|
||||
move.selfBoost.boosts![boostid]! += forte.selfBoost.boosts[boostid]!;
|
||||
}
|
||||
}
|
||||
if (forte.secondaries) {
|
||||
move.secondaries = [...(move.secondaries || []), ...forte.secondaries];
|
||||
}
|
||||
move.critRatio = (move.critRatio || 1) + (forte.critRatio || 1) - 1;
|
||||
const VALID_PROPERTIES = [
|
||||
'alwaysHit', 'basePowerCallback', 'breaksProtect', 'drain', 'forceSTAB', 'forceSwitch', 'hasCrashDamage', 'hasSheerForce',
|
||||
'ignoreAbility', 'ignoreAccuracy', 'ignoreDefensive', 'ignoreEvasion', 'ignoreImmunity', 'mindBlownRecoil', 'noDamageVariance',
|
||||
'ohko', 'overrideDefensivePokemon', 'overrideDefensiveStat', 'overrideOffensivePokemon', 'overrideOffensiveStat', 'pseudoWeather',
|
||||
'recoil', 'selfdestruct', 'selfSwitch', 'sleepUsable', 'smartTarget', 'stealsBoosts', 'thawsTarget', 'volatileStatus', 'willCrit',
|
||||
] as const;
|
||||
for (const property of VALID_PROPERTIES) {
|
||||
if (forte[property]) {
|
||||
move[property] = forte[property] as any;
|
||||
}
|
||||
}
|
||||
// Added here because onEffectiveness doesn't have an easy way to reference the source
|
||||
if (forte.onEffectiveness) {
|
||||
move.onEffectiveness = function (typeMod, t, type, m) {
|
||||
return forte.onEffectiveness!.call(this, typeMod, t, type, m);
|
||||
};
|
||||
}
|
||||
forte.onModifyMove?.call(this, move, pokemon, target);
|
||||
}
|
||||
},
|
||||
onFaint(pokemon) {
|
||||
for (const innate of Object.keys(pokemon.volatiles).filter(i => i.startsWith('ability:'))) {
|
||||
const innateEffect = this.dex.conditions.get(innate) as Effect;
|
||||
this.singleEvent('End', innateEffect, null, pokemon);
|
||||
onModifyPriority(priority, source, target, move) {
|
||||
const forte = source?.m.forte;
|
||||
if (move.category !== 'Status' && forte) {
|
||||
if (source.hasAbility('Triage') && forte.flags['heal']) {
|
||||
return priority + (move.flags['heal'] ? 0 : 3);
|
||||
}
|
||||
return priority + forte.priority;
|
||||
}
|
||||
},
|
||||
onAfterMega(pokemon) {
|
||||
for (const innate of Object.keys(pokemon.volatiles).filter(i => i.startsWith('ability:'))) {
|
||||
pokemon.removeVolatile(innate);
|
||||
onModifyTypePriority: 1,
|
||||
onModifyType(move, pokemon, target) {
|
||||
const forte = pokemon.m.forte;
|
||||
if (move.category !== 'Status' && forte) {
|
||||
this.singleEvent('ModifyType', forte, null, pokemon, target, move, move);
|
||||
}
|
||||
pokemon.m.innates = undefined;
|
||||
},
|
||||
onHitPriority: 1,
|
||||
onHit(target, source, move) {
|
||||
const forte = source.m.forte;
|
||||
if (move?.category !== 'Status' && forte) {
|
||||
this.singleEvent('Hit', forte, {}, target, source, move);
|
||||
if (forte.self) this.singleEvent('Hit', forte.self, {}, source, source, move);
|
||||
this.singleEvent('AfterHit', forte, {}, target, source, move);
|
||||
}
|
||||
},
|
||||
onAfterSubDamage(damage, target, source, move) {
|
||||
const forte = source.m.forte;
|
||||
if (move?.category !== 'Status' && forte) {
|
||||
this.singleEvent('AfterSubDamage', forte, null, target, source, move, damage);
|
||||
}
|
||||
},
|
||||
onModifySecondaries(secondaries, target, source, move) {
|
||||
if (secondaries.some(s => !!s.self)) move.selfDropped = false;
|
||||
},
|
||||
onAfterMoveSecondaryPriority: 1,
|
||||
onAfterMoveSecondarySelf(source, target, move) {
|
||||
const forte = source.m.forte;
|
||||
if (move?.category !== 'Status' && forte) {
|
||||
this.singleEvent('AfterMoveSecondarySelf', forte, null, source, target, move);
|
||||
}
|
||||
},
|
||||
onBasePowerPriority: 1,
|
||||
onBasePower(basePower, source, target, move) {
|
||||
const forte = source.m.forte;
|
||||
if (move.category !== 'Status' && forte?.onBasePower) {
|
||||
forte.onBasePower.call(this, basePower, source, target, move);
|
||||
}
|
||||
},
|
||||
pokemon: {
|
||||
getItem() {
|
||||
const move = this.battle.dex.moves.get(this.m.forte);
|
||||
if (!move.exists) return Object.getPrototypeOf(this).getItem.call(this);
|
||||
return {
|
||||
...this.battle.dex.items.get('mail'),
|
||||
name: move.name, id: move.id, ignoreKlutz: true, onTakeItem: false,
|
||||
};
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "[Gen 9] Tera Override",
|
||||
desc: `Any moves/items/abilities with mechanics relating to a specific type get that type replaced with the user's Tera type.`,
|
||||
mod: 'teraoverride',
|
||||
ruleset: ['Standard OMs', 'Evasion Abilities Clause', 'Evasion Items Clause', 'Tera Type Preview'],
|
||||
name: "[Gen 9] Camomons",
|
||||
desc: `Pokémon have their types set to match their first two moves.`,
|
||||
mod: 'gen9',
|
||||
// searchShow: false,
|
||||
ruleset: ['Standard OMs', 'Sleep Clause Mod', 'Evasion Items Clause', 'Evasion Abilities Clause', 'Terastal Clause', 'Camomons Mod'],
|
||||
banlist: [
|
||||
'Annihilape', 'Arceus', 'Archaludon', 'Baxcalibur', 'Calyrex-Ice', 'Calyrex-Shadow', 'Chi-Yu', 'Chien-Pao', 'Deoxys-Attack', 'Deoxys-Normal', 'Dialga', 'Dialga-Origin', 'Espathra',
|
||||
'Eternatus', 'Flutter Mane', 'Giratina', 'Giratina-Origin', 'Groudon', 'Hawlucha', 'Ho-Oh', 'Iron Bundle', 'Koraidon', 'Kyogre', 'Kyurem-Black', 'Kyurem-White', 'Landorus-Incarnate',
|
||||
'Lugia', 'Lunala', 'Magearna', 'Mewtwo', 'Miraidon', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane', 'Ninetales-Alola', 'Ogerpon-Hearthflame', 'Palafin', 'Palkia', 'Palkia-Origin',
|
||||
'Rayquaza', 'Regieleki', 'Reshiram', 'Roaring Moon', 'Shaymin-Sky', 'Sneasler', 'Solgaleo', 'Spectrier', 'Terapagos', 'Ursaluna-Bloodmoon', 'Urshifu', 'Urshifu-Rapid-Strike',
|
||||
'Volcarona', 'Zacian', 'Zacian-Crowned', 'Zamazenta-Crowned', 'Zekrom', 'Arena Trap', 'Magnet Pull', 'Moody', 'Shadow Tag', 'Focus Band', 'King\'s Rock', 'Razor Fang', 'Quick Claw',
|
||||
'Baton Pass', 'Last Respects', 'Shed Tail', 'Weather Ball',
|
||||
'Arceus', 'Baxcalibur', 'Calyrex-Ice', 'Calyrex-Shadow', 'Chi-Yu', 'Chien-Pao', 'Darkrai', 'Deoxys-Normal', 'Deoxys-Attack', 'Dialga', 'Dialga-Origin', 'Dragonite', 'Drednaw',
|
||||
'Enamorus-Incarnate', 'Espathra', 'Eternatus', 'Flutter Mane', 'Giratina', 'Giratina-Origin', 'Gouging Fire', 'Groudon', 'Ho-Oh', 'Iron Bundle', 'Kommo-o', 'Koraidon', 'Kyogre',
|
||||
'Kyurem', 'Kyurem-Black', 'Kyurem-White', 'Landorus-Incarnate', 'Lugia', 'Lunala', 'Magearna', 'Manaphy', 'Mewtwo', 'Miraidon', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane',
|
||||
'Palafin', 'Palkia', 'Palkia-Origin', 'Rayquaza', 'Reshiram', 'Roaring Moon', 'Shaymin-Sky', 'Sneasler', 'Solgaleo', 'Spectrier', 'Tornadus-Therian', 'Ursaluna-Bloodmoon',
|
||||
'Volcarona', 'Zacian', 'Zacian-Crowned', 'Zamazenta-Crowned', 'Zekrom', 'Arena Trap', 'Moody', 'Shadow Tag', 'Booster Energy', 'King\'s Rock', 'Light Clay', 'Razor Fang',
|
||||
'Baton Pass', 'Last Respects', 'Shed Tail',
|
||||
],
|
||||
onSwitchIn(pokemon) {
|
||||
this.add('-start', pokemon, pokemon.teraType, '[silent]');
|
||||
},
|
||||
},
|
||||
|
||||
// Other Metagames
|
||||
|
|
@ -909,21 +1023,6 @@ export const Formats: import('../sim/dex-formats').FormatList = [
|
|||
side.sideConditions[sideCondition.id].duration = 0;
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "[Gen 9] Camomons",
|
||||
desc: `Pokémon have their types set to match their first two moves.`,
|
||||
mod: 'gen9',
|
||||
searchShow: false,
|
||||
ruleset: ['Standard OMs', 'Sleep Clause Mod', 'Evasion Items Clause', 'Evasion Abilities Clause', 'Terastal Clause', 'Camomons Mod'],
|
||||
banlist: [
|
||||
'Arceus', 'Baxcalibur', 'Calyrex-Ice', 'Calyrex-Shadow', 'Chi-Yu', 'Chien-Pao', 'Darkrai', 'Deoxys-Normal', 'Deoxys-Attack', 'Dialga', 'Dialga-Origin', 'Dragonite', 'Drednaw',
|
||||
'Enamorus-Incarnate', 'Espathra', 'Eternatus', 'Flutter Mane', 'Giratina', 'Giratina-Origin', 'Gouging Fire', 'Groudon', 'Ho-Oh', 'Iron Bundle', 'Kommo-o', 'Koraidon', 'Kyogre',
|
||||
'Kyurem', 'Kyurem-Black', 'Kyurem-White', 'Landorus-Incarnate', 'Lugia', 'Lunala', 'Magearna', 'Manaphy', 'Mewtwo', 'Miraidon', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane',
|
||||
'Palafin', 'Palkia', 'Palkia-Origin', 'Rayquaza', 'Reshiram', 'Roaring Moon', 'Shaymin-Sky', 'Sneasler', 'Solgaleo', 'Spectrier', 'Tornadus-Therian', 'Ursaluna-Bloodmoon',
|
||||
'Volcarona', 'Zacian', 'Zacian-Crowned', 'Zamazenta-Crowned', 'Zekrom', 'Arena Trap', 'Moody', 'Shadow Tag', 'Booster Energy', 'King\'s Rock', 'Light Clay', 'Razor Fang',
|
||||
'Baton Pass', 'Last Respects', 'Shed Tail',
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "[Gen 9] Category Swap",
|
||||
desc: `All Special moves become Physical, and all Physical moves become Special.`,
|
||||
|
|
@ -1164,190 +1263,6 @@ export const Formats: import('../sim/dex-formats').FormatList = [
|
|||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "[Gen 9] Fortemons",
|
||||
desc: `Put an attacking move in the item slot to have all of a Pokémon's attacks inherit its properties.`,
|
||||
mod: 'gen9',
|
||||
searchShow: false,
|
||||
ruleset: ['Standard OMs', 'Sleep Moves Clause', 'Terastal Clause'],
|
||||
banlist: [
|
||||
'Annihilape', 'Arceus', 'Archaludon', 'Azumarill', 'Calyrex-Ice', 'Calyrex-Shadow', 'Chi-Yu', 'Chien-Pao', 'Cloyster', 'Comfey', 'Deoxys-Normal', 'Deoxys-Attack',
|
||||
'Dialga-Base', 'Espathra', 'Eternatus', 'Flutter Mane', 'Giratina-Altered', 'Great Tusk', 'Groudon', 'Ho-Oh', 'Iron Bundle', 'Iron Treads', 'Koraidon', 'Kyogre',
|
||||
'Kyurem-Black', 'Kyurem-White', 'Lugia', 'Lunala', 'Magearna', 'Meowscarada', 'Mewtwo', 'Miraidon', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane', 'Palafin',
|
||||
'Palkia', 'Palkia-Origin', 'Rayquaza', 'Reshiram', 'Samurott-Hisui', 'Shaymin-Sky', 'Skeledirge', 'Smeargle', 'Solgaleo', 'Spectrier', 'Sneasler', 'Terapagos',
|
||||
'Urshifu', 'Urshifu-Rapid-Strike', 'Zacian', 'Zacian-Crowned', 'Zamazenta', 'Zamazenta-Crowned', 'Zekrom', 'Arena Trap', 'Moody', 'Serene Grace', 'Shadow Tag',
|
||||
'Damp Rock', 'Heat Rock', 'Light Clay', 'Baton Pass', 'Beat Up', 'Fake Out', 'Last Respects', 'Shed Tail',
|
||||
],
|
||||
restricted: [
|
||||
'Doom Desire', 'Dynamic Punch', 'Electro Ball', 'Explosion', 'Gyro Ball', 'Final Gambit', 'Flail', 'Flip Turn', 'Fury Cutter', 'Future Sight', 'Grass Knot',
|
||||
'Grassy Glide', 'Hard Press', 'Heavy Slam', 'Heat Crash', 'Inferno', 'Low Kick', 'Misty Explosion', 'Nuzzle', 'Power Trip', 'Reversal', 'Self-Destruct',
|
||||
'Spit Up', 'Stored Power', 'Tera Blast', 'U-turn', 'Weather Ball', 'Zap Cannon',
|
||||
],
|
||||
onValidateTeam(team) {
|
||||
const itemTable = new Set<string>();
|
||||
for (const set of team) {
|
||||
const forte = this.toID(set.item);
|
||||
if (!forte) continue;
|
||||
const move = this.dex.moves.get(forte);
|
||||
if (move.exists && move.id !== 'metronome') {
|
||||
if (itemTable.has(forte)) {
|
||||
return [
|
||||
`You are limited to one of each move in the item slot per team.`,
|
||||
`(You have more than one ${move.name}.)`,
|
||||
];
|
||||
}
|
||||
itemTable.add(forte);
|
||||
}
|
||||
}
|
||||
},
|
||||
validateSet(set, teamHas) {
|
||||
const item = set.item;
|
||||
const species = this.dex.species.get(set.species);
|
||||
const move = this.dex.moves.get(item);
|
||||
if (!move.exists || move.id === 'metronome' || move.category === 'Status') {
|
||||
return this.validateSet(set, teamHas);
|
||||
}
|
||||
set.item = '';
|
||||
const problems = this.validateSet(set, teamHas) || [];
|
||||
set.item = item;
|
||||
if (this.checkCanLearn(move, species, this.allSources(species), set)) {
|
||||
problems.push(`${species.name} can't learn ${move.name}.`);
|
||||
}
|
||||
if (set.moves.map(this.toID).includes(move.id)) {
|
||||
problems.push(`Moves in the item slot can't be in the moveslots as well.`);
|
||||
}
|
||||
if (this.ruleTable.has(`-move:${move.id}`)) {
|
||||
problems.push(`The move ${move.name} is fully banned.`);
|
||||
}
|
||||
const accuracyLoweringMove =
|
||||
move.secondaries?.some(secondary => secondary.boosts?.accuracy && secondary.boosts?.accuracy < 0);
|
||||
const flinchMove = move.secondaries?.some(secondary => secondary.volatileStatus === 'flinch');
|
||||
const freezeMove = move.secondaries?.some(secondary => secondary.status === 'frz') || move.id === 'triattack';
|
||||
if (
|
||||
this.ruleTable.isRestricted(`move:${move.id}`) ||
|
||||
((accuracyLoweringMove || move.ohko || move.multihit || move.id === 'beatup' || move.flags['charge'] ||
|
||||
move.priority > 0 || move.damageCallback || flinchMove || freezeMove) &&
|
||||
!this.ruleTable.has(`+move:${move.id}`))
|
||||
) {
|
||||
problems.push(`The move ${move.name} can't be used as an item.`);
|
||||
}
|
||||
return problems.length ? problems : null;
|
||||
},
|
||||
onBegin() {
|
||||
for (const pokemon of this.getAllPokemon()) {
|
||||
const move = this.dex.getActiveMove(pokemon.set.item);
|
||||
if (move.exists && move.category !== 'Status') {
|
||||
pokemon.m.forte = move;
|
||||
pokemon.item = 'mail' as ID;
|
||||
}
|
||||
}
|
||||
},
|
||||
onModifyMovePriority: 1,
|
||||
onModifyMove(move, pokemon, target) {
|
||||
const forte: ActiveMove = pokemon.m.forte;
|
||||
if (move.category !== 'Status' && forte) {
|
||||
move.flags = { ...move.flags, ...forte.flags };
|
||||
if (forte.self) {
|
||||
if (forte.self.onHit && move.self?.onHit) {
|
||||
for (const i in forte.self) {
|
||||
if (i.startsWith('onHit')) continue;
|
||||
(move.self as any)[i] = (forte.self as any)[i];
|
||||
}
|
||||
} else {
|
||||
move.self = { ...move.self, ...forte.self };
|
||||
}
|
||||
}
|
||||
if (forte.selfBoost?.boosts) {
|
||||
if (!move.selfBoost?.boosts) move.selfBoost = { boosts: {} };
|
||||
let boostid: BoostID;
|
||||
for (boostid in forte.selfBoost.boosts) {
|
||||
if (!move.selfBoost.boosts![boostid]) move.selfBoost.boosts![boostid] = 0;
|
||||
move.selfBoost.boosts![boostid]! += forte.selfBoost.boosts[boostid]!;
|
||||
}
|
||||
}
|
||||
if (forte.secondaries) {
|
||||
move.secondaries = [...(move.secondaries || []), ...forte.secondaries];
|
||||
}
|
||||
move.critRatio = (move.critRatio || 1) + (forte.critRatio || 1) - 1;
|
||||
const VALID_PROPERTIES = [
|
||||
'alwaysHit', 'basePowerCallback', 'breaksProtect', 'drain', 'forceSTAB', 'forceSwitch', 'hasCrashDamage', 'hasSheerForce',
|
||||
'ignoreAbility', 'ignoreAccuracy', 'ignoreDefensive', 'ignoreEvasion', 'ignoreImmunity', 'mindBlownRecoil', 'noDamageVariance',
|
||||
'ohko', 'overrideDefensivePokemon', 'overrideDefensiveStat', 'overrideOffensivePokemon', 'overrideOffensiveStat', 'pseudoWeather',
|
||||
'recoil', 'selfdestruct', 'selfSwitch', 'sleepUsable', 'smartTarget', 'stealsBoosts', 'thawsTarget', 'volatileStatus', 'willCrit',
|
||||
] as const;
|
||||
for (const property of VALID_PROPERTIES) {
|
||||
if (forte[property]) {
|
||||
move[property] = forte[property] as any;
|
||||
}
|
||||
}
|
||||
// Added here because onEffectiveness doesn't have an easy way to reference the source
|
||||
if (forte.onEffectiveness) {
|
||||
move.onEffectiveness = function (typeMod, t, type, m) {
|
||||
return forte.onEffectiveness!.call(this, typeMod, t, type, m);
|
||||
};
|
||||
}
|
||||
forte.onModifyMove?.call(this, move, pokemon, target);
|
||||
}
|
||||
},
|
||||
onModifyPriority(priority, source, target, move) {
|
||||
const forte = source?.m.forte;
|
||||
if (move.category !== 'Status' && forte) {
|
||||
if (source.hasAbility('Triage') && forte.flags['heal']) {
|
||||
return priority + (move.flags['heal'] ? 0 : 3);
|
||||
}
|
||||
return priority + forte.priority;
|
||||
}
|
||||
},
|
||||
onModifyTypePriority: 1,
|
||||
onModifyType(move, pokemon, target) {
|
||||
const forte = pokemon.m.forte;
|
||||
if (move.category !== 'Status' && forte) {
|
||||
this.singleEvent('ModifyType', forte, null, pokemon, target, move, move);
|
||||
}
|
||||
},
|
||||
onHitPriority: 1,
|
||||
onHit(target, source, move) {
|
||||
const forte = source.m.forte;
|
||||
if (move?.category !== 'Status' && forte) {
|
||||
this.singleEvent('Hit', forte, {}, target, source, move);
|
||||
if (forte.self) this.singleEvent('Hit', forte.self, {}, source, source, move);
|
||||
this.singleEvent('AfterHit', forte, {}, target, source, move);
|
||||
}
|
||||
},
|
||||
onAfterSubDamage(damage, target, source, move) {
|
||||
const forte = source.m.forte;
|
||||
if (move?.category !== 'Status' && forte) {
|
||||
this.singleEvent('AfterSubDamage', forte, null, target, source, move, damage);
|
||||
}
|
||||
},
|
||||
onModifySecondaries(secondaries, target, source, move) {
|
||||
if (secondaries.some(s => !!s.self)) move.selfDropped = false;
|
||||
},
|
||||
onAfterMoveSecondaryPriority: 1,
|
||||
onAfterMoveSecondarySelf(source, target, move) {
|
||||
const forte = source.m.forte;
|
||||
if (move?.category !== 'Status' && forte) {
|
||||
this.singleEvent('AfterMoveSecondarySelf', forte, null, source, target, move);
|
||||
}
|
||||
},
|
||||
onBasePowerPriority: 1,
|
||||
onBasePower(basePower, source, target, move) {
|
||||
const forte = source.m.forte;
|
||||
if (move.category !== 'Status' && forte?.onBasePower) {
|
||||
forte.onBasePower.call(this, basePower, source, target, move);
|
||||
}
|
||||
},
|
||||
pokemon: {
|
||||
getItem() {
|
||||
const move = this.battle.dex.moves.get(this.m.forte);
|
||||
if (!move.exists) return Object.getPrototypeOf(this).getItem.call(this);
|
||||
return {
|
||||
...this.battle.dex.items.get('mail'),
|
||||
name: move.name, id: move.id, ignoreKlutz: true, onTakeItem: false,
|
||||
};
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "[Gen 9] Frantic Fusions",
|
||||
desc: `Pokémon nicknamed after another Pokémon get their stats buffed by 1/4 of that Pokémon's stats, barring HP, and access to one of their abilities.`,
|
||||
|
|
@ -1716,6 +1631,73 @@ export const Formats: import('../sim/dex-formats').FormatList = [
|
|||
'Speed Boost', 'Heat Rock', 'King\'s Rock', 'Razor Fang', 'Quick Claw', 'Baton Pass', 'Last Respects', 'Shed Tail',
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "[Gen 9] Pokebilities",
|
||||
desc: `Pokémon have all of their released abilities simultaneously.`,
|
||||
mod: 'pokebilities',
|
||||
searchShow: false,
|
||||
ruleset: ['Standard OMs', 'Sleep Moves Clause'],
|
||||
banlist: [
|
||||
'Arceus', 'Annihilape', 'Archaludon', 'Basculegion', 'Basculegion-F', 'Baxcalibur', 'Braviary-Hisui', 'Calyrex-Ice', 'Calyrex-Shadow', 'Chi-Yu', 'Chien-Pao', 'Conkeldurr',
|
||||
'Deoxys-Normal', 'Deoxys-Attack', 'Dialga', 'Dialga-Origin', 'Espathra', 'Eternatus', 'Excadrill', 'Flutter Mane', 'Giratina', 'Giratina-Origin', 'Gouging Fire', 'Groudon',
|
||||
'Ho-Oh', 'Iron Bundle', 'Koraidon', 'Kyogre', 'Kyurem-Black', 'Kyurem-White', 'Landorus-Incarnate', 'Lugia', 'Lunala', 'Magearna', 'Miraidon', 'Mewtwo', 'Necrozma-Dusk-Mane',
|
||||
'Necrozma-Dawn-Wings', 'Ogerpon-Hearthflame', 'Palafin', 'Palkia', 'Palkia-Origin', 'Porygon-Z', 'Rayquaza', 'Regieleki', 'Reshiram', 'Roaring Moon', 'Shaymin-Sky', 'Sneasler',
|
||||
'Solgaleo', 'Spectrier', 'Terapagos', 'Ursaluna-Bloodmoon', 'Urshifu-Single-Strike', 'Urshifu-Rapid-Strike', 'Volcarona', 'Zacian', 'Zacian-Crowned', 'Zamazenta-Crowned',
|
||||
'Zekrom', 'Arena Trap', 'Moody', 'Shadow Tag', 'Bright Powder', 'Damp Rock', 'Icy Rock', 'King\'s Rock', 'Razor Fang', 'Smooth Rock', 'Baton Pass', 'Shed Tail', 'Last Respects',
|
||||
],
|
||||
onValidateSet(set) {
|
||||
const species = this.dex.species.get(set.species);
|
||||
const unSeenAbilities = Object.keys(species.abilities)
|
||||
.filter(key => key !== 'S' && (key !== 'H' || !species.unreleasedHidden))
|
||||
.map(key => species.abilities[key as "0" | "1" | "H" | "S"])
|
||||
.filter(ability => ability !== set.ability);
|
||||
if (unSeenAbilities.length && this.toID(set.ability) !== this.toID(species.abilities['S'])) {
|
||||
for (const abilityName of unSeenAbilities) {
|
||||
const banReason = this.ruleTable.check('ability:' + this.toID(abilityName));
|
||||
if (banReason) {
|
||||
return [`${set.name}'s ability ${abilityName} is ${banReason}.`];
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
onBegin() {
|
||||
for (const pokemon of this.getAllPokemon()) {
|
||||
if (pokemon.ability === this.toID(pokemon.species.abilities['S'])) {
|
||||
continue;
|
||||
}
|
||||
pokemon.m.innates = Object.keys(pokemon.species.abilities)
|
||||
.filter(key => key !== 'S' && (key !== 'H' || !pokemon.species.unreleasedHidden))
|
||||
.map(key => this.toID(pokemon.species.abilities[key as "0" | "1" | "H" | "S"]))
|
||||
.filter(ability => ability !== pokemon.ability);
|
||||
}
|
||||
},
|
||||
onBeforeSwitchIn(pokemon) {
|
||||
if (pokemon.m.innates) {
|
||||
for (const innate of pokemon.m.innates) {
|
||||
if (pokemon.hasAbility(innate)) continue;
|
||||
const effect = 'ability:' + this.toID(innate);
|
||||
pokemon.volatiles[effect] = this.initEffectState({ id: effect, target: pokemon });
|
||||
}
|
||||
}
|
||||
},
|
||||
onSwitchOut(pokemon) {
|
||||
for (const innate of Object.keys(pokemon.volatiles).filter(i => i.startsWith('ability:'))) {
|
||||
pokemon.removeVolatile(innate);
|
||||
}
|
||||
},
|
||||
onFaint(pokemon) {
|
||||
for (const innate of Object.keys(pokemon.volatiles).filter(i => i.startsWith('ability:'))) {
|
||||
const innateEffect = this.dex.conditions.get(innate) as Effect;
|
||||
this.singleEvent('End', innateEffect, null, pokemon);
|
||||
}
|
||||
},
|
||||
onAfterMega(pokemon) {
|
||||
for (const innate of Object.keys(pokemon.volatiles).filter(i => i.startsWith('ability:'))) {
|
||||
pokemon.removeVolatile(innate);
|
||||
}
|
||||
pokemon.m.innates = undefined;
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "[Gen 9] Pokemoves",
|
||||
desc: `Put a Pokémon's name in a moveslot to turn them into a move. The move has 8 PP, 100% accuracy, and a category and Base Power matching their highest attacking stat. Use /pokemove for more info.`,
|
||||
|
|
@ -2232,6 +2214,24 @@ export const Formats: import('../sim/dex-formats').FormatList = [
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "[Gen 9] Tera Override",
|
||||
desc: `Any moves/items/abilities with mechanics relating to a specific type get that type replaced with the user's Tera type.`,
|
||||
mod: 'teraoverride',
|
||||
searchShow: false,
|
||||
ruleset: ['Standard OMs', 'Evasion Abilities Clause', 'Evasion Items Clause', 'Tera Type Preview'],
|
||||
banlist: [
|
||||
'Annihilape', 'Arceus', 'Archaludon', 'Baxcalibur', 'Calyrex-Ice', 'Calyrex-Shadow', 'Chi-Yu', 'Chien-Pao', 'Deoxys-Attack', 'Deoxys-Normal', 'Dialga', 'Dialga-Origin', 'Espathra',
|
||||
'Eternatus', 'Flutter Mane', 'Giratina', 'Giratina-Origin', 'Groudon', 'Hawlucha', 'Ho-Oh', 'Iron Bundle', 'Koraidon', 'Kyogre', 'Kyurem-Black', 'Kyurem-White', 'Landorus-Incarnate',
|
||||
'Lugia', 'Lunala', 'Magearna', 'Mewtwo', 'Miraidon', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane', 'Ninetales-Alola', 'Ogerpon-Hearthflame', 'Palafin', 'Palkia', 'Palkia-Origin',
|
||||
'Rayquaza', 'Regieleki', 'Reshiram', 'Roaring Moon', 'Shaymin-Sky', 'Sneasler', 'Solgaleo', 'Spectrier', 'Terapagos', 'Ursaluna-Bloodmoon', 'Urshifu', 'Urshifu-Rapid-Strike',
|
||||
'Volcarona', 'Zacian', 'Zacian-Crowned', 'Zamazenta-Crowned', 'Zekrom', 'Arena Trap', 'Magnet Pull', 'Moody', 'Shadow Tag', 'Focus Band', 'King\'s Rock', 'Razor Fang', 'Quick Claw',
|
||||
'Baton Pass', 'Last Respects', 'Shed Tail', 'Weather Ball',
|
||||
],
|
||||
onSwitchIn(pokemon) {
|
||||
this.add('-start', pokemon, pokemon.teraType, '[silent]');
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "[Gen 9] The Card Game",
|
||||
desc: `The type chart is simplified based off of the Pokémon Trading Card Game.`,
|
||||
|
|
@ -2607,7 +2607,7 @@ export const Formats: import('../sim/dex-formats').FormatList = [
|
|||
name: "[Gen 9] National Dex 35 Pokes",
|
||||
desc: `Only 35 Pokémon are legal.`,
|
||||
mod: 'gen9',
|
||||
// searchShow: false,
|
||||
searchShow: false,
|
||||
ruleset: [
|
||||
'Standard NatDex',
|
||||
'!Species Clause', 'Forme Clause', 'Terastal Clause', 'DryPass Clause', 'Z-Move Clause', 'Mega Rayquaza Clause',
|
||||
|
|
@ -2813,7 +2813,7 @@ export const Formats: import('../sim/dex-formats').FormatList = [
|
|||
{
|
||||
name: "[Gen 9] National Dex STABmons",
|
||||
mod: 'gen9',
|
||||
searchShow: false,
|
||||
// searchShow: false,
|
||||
ruleset: ['Standard NatDex', 'STABmons Move Legality', '!Sleep Clause Mod', 'Sleep Moves Clause', 'Terastal Clause'],
|
||||
banlist: [
|
||||
'Araquanid', 'Arceus', 'Azumarill', 'Baxcalibur', 'Blastoise-Mega', 'Blaziken-Mega', 'Basculegion', 'Basculegion-F', 'Calyrex-Ice', 'Calyrex-Shadow', 'Chi-Yu', 'Chien-Pao',
|
||||
|
|
@ -3681,28 +3681,27 @@ export const Formats: import('../sim/dex-formats').FormatList = [
|
|||
column: 4,
|
||||
},
|
||||
{
|
||||
name: "[Gen 7] UU",
|
||||
mod: 'gen7',
|
||||
name: "[Gen 8] UU",
|
||||
mod: 'gen8',
|
||||
// searchShow: false,
|
||||
ruleset: ['[Gen 7] OU'],
|
||||
banlist: ['OU', 'UUBL', 'Drizzle', 'Drought', 'Kommonium Z', 'Mewnium Z'],
|
||||
ruleset: ['[Gen 8] OU'],
|
||||
banlist: ['OU', 'UUBL', 'Light Clay'],
|
||||
},
|
||||
{
|
||||
name: "[Gen 5] VGC 2013",
|
||||
mod: 'gen5',
|
||||
name: "[Gen 8] CAP",
|
||||
desc: "The Create-A-Pokémon project is a community dedicated to exploring and understanding the competitive Pokémon metagame by designing, creating, and playtesting new Pokémon concepts.",
|
||||
mod: 'gen8',
|
||||
// searchShow: false,
|
||||
ruleset: ['[Gen 8] OU', '+CAP'],
|
||||
banlist: ['Crucibellite'],
|
||||
},
|
||||
{
|
||||
name: "[Gen 6] VGC 2014",
|
||||
mod: 'gen6xy',
|
||||
gameType: 'doubles',
|
||||
// searchShow: false,
|
||||
bestOfDefault: true,
|
||||
ruleset: ['Flat Rules'],
|
||||
banlist: ['Chatot', 'Dark Void', 'Sky Drop', 'Soul Dew'],
|
||||
},
|
||||
{
|
||||
name: "[Gen 8] ZU",
|
||||
desc: `The unofficial usage-based tier below PU.`,
|
||||
mod: 'gen8',
|
||||
// searchShow: false,
|
||||
ruleset: ['[Gen 8] PU'],
|
||||
banlist: ['PU', 'ZUBL', 'Damp Rock', 'Grassy Seed'],
|
||||
ruleset: ['Flat Rules', 'Kalos Pokedex', 'Min Source Gen = 6'],
|
||||
},
|
||||
|
||||
// Past Gens OU
|
||||
|
|
@ -3830,13 +3829,6 @@ export const Formats: import('../sim/dex-formats').FormatList = [
|
|||
ruleset: ['Standard', 'Dynamax Clause'],
|
||||
banlist: ['AG', 'Shadow Tag', 'Baton Pass'],
|
||||
},
|
||||
{
|
||||
name: "[Gen 8] UU",
|
||||
mod: 'gen8',
|
||||
searchShow: false,
|
||||
ruleset: ['[Gen 8] OU'],
|
||||
banlist: ['OU', 'UUBL', 'Light Clay'],
|
||||
},
|
||||
{
|
||||
name: "[Gen 8] RU",
|
||||
mod: 'gen8',
|
||||
|
|
@ -3906,12 +3898,12 @@ export const Formats: import('../sim/dex-formats').FormatList = [
|
|||
ruleset: ['Obtainable', 'Team Preview', 'HP Percentage Mod', 'Cancel Mod', 'Endless Battle Clause'],
|
||||
},
|
||||
{
|
||||
name: "[Gen 8] CAP",
|
||||
desc: "The Create-A-Pokémon project is a community dedicated to exploring and understanding the competitive Pokémon metagame by designing, creating, and playtesting new Pokémon concepts.",
|
||||
name: "[Gen 8] ZU",
|
||||
desc: `The unofficial usage-based tier below PU.`,
|
||||
mod: 'gen8',
|
||||
searchShow: false,
|
||||
ruleset: ['[Gen 8] OU', '+CAP'],
|
||||
banlist: ['Crucibellite'],
|
||||
ruleset: ['[Gen 8] PU'],
|
||||
banlist: ['PU', 'ZUBL', 'Damp Rock', 'Grassy Seed'],
|
||||
},
|
||||
{
|
||||
name: "[Gen 8] Battle Stadium Singles",
|
||||
|
|
@ -4032,6 +4024,13 @@ export const Formats: import('../sim/dex-formats').FormatList = [
|
|||
ruleset: ['Standard', 'Mega Rayquaza Clause'],
|
||||
banlist: ['Baton Pass'],
|
||||
},
|
||||
{
|
||||
name: "[Gen 7] UU",
|
||||
mod: 'gen7',
|
||||
searchShow: false,
|
||||
ruleset: ['[Gen 7] OU'],
|
||||
banlist: ['OU', 'UUBL', 'Drizzle', 'Drought', 'Kommonium Z', 'Mewnium Z'],
|
||||
},
|
||||
{
|
||||
name: "[Gen 7] RU",
|
||||
mod: 'gen7',
|
||||
|
|
@ -4362,14 +4361,6 @@ export const Formats: import('../sim/dex-formats').FormatList = [
|
|||
ruleset: ['Flat Rules', 'Min Source Gen = 6'],
|
||||
banlist: ['Soul Dew', 'Articuno + Snow Cloak', 'Zapdos + Static', 'Moltres + Flame Body', 'Dragonite + Barrier'],
|
||||
},
|
||||
{
|
||||
name: "[Gen 6] VGC 2014",
|
||||
mod: 'gen6xy',
|
||||
gameType: 'doubles',
|
||||
searchShow: false,
|
||||
bestOfDefault: true,
|
||||
ruleset: ['Flat Rules', 'Kalos Pokedex', 'Min Source Gen = 6'],
|
||||
},
|
||||
{
|
||||
name: "[Gen 6] Battle Spot Doubles",
|
||||
mod: 'gen6',
|
||||
|
|
@ -4542,6 +4533,15 @@ export const Formats: import('../sim/dex-formats').FormatList = [
|
|||
section: "B2/W2 Doubles",
|
||||
column: 4,
|
||||
},
|
||||
{
|
||||
name: "[Gen 5] VGC 2013",
|
||||
mod: 'gen5',
|
||||
gameType: 'doubles',
|
||||
searchShow: false,
|
||||
bestOfDefault: true,
|
||||
ruleset: ['Flat Rules'],
|
||||
banlist: ['Chatot', 'Dark Void', 'Sky Drop', 'Soul Dew'],
|
||||
},
|
||||
{
|
||||
name: "[Gen 5] VGC 2012",
|
||||
mod: 'gen5bw1',
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user