@pkmn/sim 0.5.18 → 0.5.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/config/formats.js +487 -432
- package/build/config/formats.js.map +1 -1
- package/build/data/aliases.js +2 -2
- package/build/data/aliases.js.map +1 -1
- package/build/data/formats-data.js +17 -13
- package/build/data/formats-data.js.map +1 -1
- package/build/data/learnsets.js +77 -9
- package/build/data/learnsets.js.map +1 -1
- package/build/data/mods/gen1/conditions.js +4 -0
- package/build/data/mods/gen1/conditions.js.map +1 -1
- package/build/data/mods/gen1/formats-data.js +3 -3
- package/build/data/mods/gen1/formats-data.js.map +1 -1
- package/build/data/mods/gen1/moves.js +2 -10
- package/build/data/mods/gen1/moves.js.map +1 -1
- package/build/data/mods/gen2/learnsets.js +2 -2
- package/build/data/mods/gen2/learnsets.js.map +1 -1
- package/build/data/mods/gen2/scripts.js +16 -0
- package/build/data/mods/gen2/scripts.js.map +1 -1
- package/build/data/mods/gen4/formats-data.js +1 -1
- package/build/data/mods/gen4/formats-data.js.map +1 -1
- package/build/data/mods/gen6/formats-data.js +1 -1
- package/build/data/mods/gen6/formats-data.js.map +1 -1
- package/build/data/mods/gen6/learnsets.js +0 -75
- package/build/data/mods/gen6/learnsets.js.map +1 -1
- package/build/data/mods/gen7/formats-data.js +1 -1
- package/build/data/mods/gen7/formats-data.js.map +1 -1
- package/build/data/moves.js +2 -4
- package/build/data/moves.js.map +1 -1
- package/build/data/pokedex.js +20 -1
- package/build/data/pokedex.js.map +1 -1
- package/build/data/rulesets.js +29 -0
- package/build/data/rulesets.js.map +1 -1
- package/build/data/tags.js +2 -2
- package/build/data/tags.js.map +1 -1
- package/build/sim/battle.js +1 -7
- package/build/sim/battle.js.map +1 -1
- package/build/sim/state.d.ts +1 -1
- package/build/sim/state.js +6 -6
- package/build/sim/state.js.map +1 -1
- package/build/sim/teams.d.ts +2 -2
- package/config/formats.ts +352 -302
- package/data/aliases.ts +2 -2
- package/data/formats-data.ts +17 -13
- package/data/learnsets.ts +77 -9
- package/data/mods/gen1/conditions.ts +4 -0
- package/data/mods/gen1/formats-data.ts +3 -3
- package/data/mods/gen1/moves.ts +2 -9
- package/data/mods/gen2/learnsets.ts +2 -2
- package/data/mods/gen2/scripts.ts +16 -0
- package/data/mods/gen4/formats-data.ts +1 -1
- package/data/mods/gen6/formats-data.ts +1 -1
- package/data/mods/gen6/learnsets.ts +0 -75
- package/data/mods/gen7/formats-data.ts +1 -1
- package/data/moves.ts +2 -4
- package/data/pokedex.ts +20 -1
- package/data/rulesets.ts +28 -0
- package/data/tags.ts +2 -2
- package/package.json +1 -1
- package/sim/battle.ts +1 -7
package/build/config/formats.js
CHANGED
|
@@ -154,7 +154,7 @@ exports.Formats = [
|
|
|
154
154
|
mod: 'gen8',
|
|
155
155
|
ruleset: ['Little Cup', 'Standard', 'Dynamax Clause'],
|
|
156
156
|
banlist: [
|
|
157
|
-
'Corsola-Galar', 'Cutiefly', 'Drifloon', 'Gastly', 'Gothita', 'Rufflet', 'Scraggy', 'Scyther', 'Sneasel', 'Swirlix', 'Tangela', '
|
|
157
|
+
'Corsola-Galar', 'Cutiefly', 'Drifloon', 'Gastly', 'Gothita', 'Rufflet', 'Scraggy', 'Scyther', 'Sneasel', 'Swirlix', 'Tangela', 'Vulpix-Alola', 'Woobat', 'Zigzagoon-Base',
|
|
158
158
|
'Chlorophyll', 'Moody', 'Baton Pass', 'Sticky Web',
|
|
159
159
|
],
|
|
160
160
|
},
|
|
@@ -163,7 +163,7 @@ exports.Formats = [
|
|
|
163
163
|
desc: `All the Pokémon on a team must share a type.`,
|
|
164
164
|
threads: [
|
|
165
165
|
`• <a href="https://www.smogon.com/forums/threads/3672167/">Monotype Metagame Discussion</a>`,
|
|
166
|
-
`• <a href="https://www.smogon.com/forums/threads/
|
|
166
|
+
`• <a href="https://www.smogon.com/forums/threads/3702647/">Monotype Sample Teams</a>`,
|
|
167
167
|
`• <a href="https://www.smogon.com/forums/threads/3673165">Monotype Viability Rankings</a>`,
|
|
168
168
|
],
|
|
169
169
|
mod: 'gen8',
|
|
@@ -218,8 +218,8 @@ exports.Formats = [
|
|
|
218
218
|
mod: 'gen8',
|
|
219
219
|
ruleset: ['[Gen 8] PU'],
|
|
220
220
|
banlist: [
|
|
221
|
-
'PU', 'Arctovish', 'Aurorus', 'Basculin', 'Centiskorch', 'Drampa', 'Exeggutor-Alola', 'Gallade', 'Haunter', 'Magmortar', 'Magneton', '
|
|
222
|
-
'Rotom-Frost', 'Turtonator', 'Vanilluxe', 'Vikavolt', 'Silvally-Dragon', 'Silvally-Ground', 'Sneasel', 'Damp Rock', 'Grassy Seed',
|
|
221
|
+
'PU', 'Arctovish', 'Aurorus', 'Basculin', 'Centiskorch', 'Drampa', 'Exeggutor-Alola', 'Gallade', 'Haunter', 'Magmortar', 'Magneton', 'Malamar',
|
|
222
|
+
'Omastar', 'Rotom-Frost', 'Turtonator', 'Vanilluxe', 'Vikavolt', 'Silvally-Dragon', 'Silvally-Ground', 'Sneasel', 'Damp Rock', 'Grassy Seed',
|
|
223
223
|
],
|
|
224
224
|
},
|
|
225
225
|
{
|
|
@@ -233,8 +233,8 @@ exports.Formats = [
|
|
|
233
233
|
banlist: [
|
|
234
234
|
// LC OU
|
|
235
235
|
'Abra', 'Carvanha', 'Diglett-Base', 'Dwebble', 'Ferroseed', 'Foongus', 'Frillish', 'Grookey', 'Koffing',
|
|
236
|
-
'Larvesta', 'Magby', 'Magnemite', 'Mareanie', 'Mienfoo', 'Mudbray', '
|
|
237
|
-
'Ponyta
|
|
236
|
+
'Larvesta', 'Magby', 'Magnemite', 'Mareanie', 'Mienfoo', 'Mudbray', 'Natu', 'Onix', 'Pawniard',
|
|
237
|
+
'Ponyta-Base', 'Porygon', 'Slowpoke-Base', 'Staryu', 'Timburr', 'Trapinch', 'Tyrunt', 'Vullaby',
|
|
238
238
|
// LC UUBL
|
|
239
239
|
'Archen', 'Farfetch\u2019d-Galar', 'Scorbunny', 'Shellder', 'Wingull',
|
|
240
240
|
],
|
|
@@ -268,6 +268,14 @@ exports.Formats = [
|
|
|
268
268
|
ruleset: ['Flat Rules', '!! Adjust Level = 50', 'Min Source Gen = 8', 'Limit Two Restricted'],
|
|
269
269
|
restricted: ['Restricted Legendary'],
|
|
270
270
|
},
|
|
271
|
+
{
|
|
272
|
+
name: "[Gen 8] Single Battle Cup",
|
|
273
|
+
threads: [
|
|
274
|
+
`• <a href="https://www.pokemon.com/us/pokemon-news/register-now-for-the-single-battle-cup-competition/">Single Battle Cup</a>`,
|
|
275
|
+
],
|
|
276
|
+
mod: 'gen8',
|
|
277
|
+
ruleset: ['Flat Rules', '!! Adjust Level = 50', 'Min Source Gen = 8'],
|
|
278
|
+
},
|
|
271
279
|
{
|
|
272
280
|
name: "[Gen 8] Custom Game",
|
|
273
281
|
mod: 'gen8',
|
|
@@ -371,10 +379,10 @@ exports.Formats = [
|
|
|
371
379
|
'Standard Doubles', 'Accuracy Moves Clause', 'Dynamax Clause', 'Sleep Clause Mod',
|
|
372
380
|
],
|
|
373
381
|
banlist: [
|
|
374
|
-
'Calyrex-Ice', 'Calyrex-Shadow', 'Dialga', 'Eternatus', 'Giratina', 'Giratina-Origin', 'Groudon', 'Ho-Oh', 'Jirachi', 'Kyogre',
|
|
375
|
-
'Lugia', 'Lunala', 'Magearna', 'Marshadow', 'Melmetal', 'Mewtwo', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane', 'Palkia', 'Rayquaza',
|
|
376
|
-
'Solgaleo', 'Tornadus-Base', 'Urshifu-Base', 'Urshifu-Rapid-Strike', 'Whimsicott', 'Xerneas', 'Yveltal', 'Zacian', 'Zacian-Crowned',
|
|
377
|
-
'Zamazenta-Crowned', 'Zekrom', 'Moody', 'Power Construct', 'Focus Sash', 'Ally Switch', 'Final Gambit', 'Perish Song', 'Swagger',
|
|
382
|
+
'Calyrex-Ice', 'Calyrex-Shadow', 'Cottonee', 'Dialga', 'Eternatus', 'Giratina', 'Giratina-Origin', 'Groudon', 'Ho-Oh', 'Jirachi', 'Kyogre',
|
|
383
|
+
'Kyurem-White', 'Lugia', 'Lunala', 'Magearna', 'Marshadow', 'Melmetal', 'Mewtwo', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane', 'Palkia', 'Rayquaza',
|
|
384
|
+
'Reshiram', 'Solgaleo', 'Tornadus-Base', 'Urshifu-Base', 'Urshifu-Rapid-Strike', 'Whimsicott', 'Xerneas', 'Yveltal', 'Zacian', 'Zacian-Crowned',
|
|
385
|
+
'Zamazenta', 'Zamazenta-Crowned', 'Zekrom', 'Moody', 'Power Construct', 'Focus Sash', 'Ally Switch', 'Final Gambit', 'Perish Song', 'Swagger',
|
|
378
386
|
],
|
|
379
387
|
},
|
|
380
388
|
{
|
|
@@ -570,45 +578,271 @@ exports.Formats = [
|
|
|
570
578
|
column: 2,
|
|
571
579
|
},
|
|
572
580
|
{
|
|
573
|
-
name: "[Gen 8]
|
|
574
|
-
desc: `Pokémon
|
|
581
|
+
name: "[Gen 8] Broken Record",
|
|
582
|
+
desc: `Pokémon can hold a TR to use that move in battle.`,
|
|
575
583
|
threads: [
|
|
576
|
-
`• <a href="https://www.smogon.com/forums/threads/
|
|
584
|
+
`• <a href="https://www.smogon.com/forums/threads/3701270/">Broken Record</a>`,
|
|
577
585
|
],
|
|
578
586
|
mod: 'gen8',
|
|
579
|
-
ruleset: ['Standard', '
|
|
587
|
+
ruleset: ['Standard', '!Sleep Clause Mod', 'Sleep Moves Clause', 'Dynamax Clause'],
|
|
580
588
|
banlist: [
|
|
581
|
-
'Calyrex-Ice', 'Calyrex-Shadow', 'Cinderace', 'Darmanitan-Galar', 'Dialga', 'Dracovish', 'Eternatus', 'Genesect', 'Giratina',
|
|
582
|
-
'
|
|
583
|
-
'
|
|
584
|
-
'
|
|
585
|
-
'
|
|
586
|
-
'King\'s Rock', 'Lax Incense', 'Baton Pass', 'Explosion', 'Final Gambit', 'Healing Wish', 'Lunar Dance', 'Memento',
|
|
587
|
-
'Misty Explosion', 'Self-Destruct',
|
|
589
|
+
'Calyrex-Ice', 'Calyrex-Shadow', 'Cinderace', 'Darmanitan-Galar', 'Dialga', 'Dracovish', 'Eternatus', 'Genesect', 'Giratina', 'Giratina-Origin',
|
|
590
|
+
'Groudon', 'Ho-Oh', 'Kartana', 'Kyogre', 'Kyurem', 'Kyurem-Black', 'Kyurem-White', 'Landorus-Base', 'Lugia', 'Lunala', 'Magearna', 'Marshadow',
|
|
591
|
+
'Mewtwo', 'Naganadel', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane', 'Palkia', 'Pheromosa', 'Rayquaza', 'Regieleki', 'Reshiram', 'Solgaleo',
|
|
592
|
+
'Spectrier', 'Urshifu-Base', 'Xerneas', 'Yveltal', 'Zacian', 'Zacian-Crowned', 'Zamazenta', 'Zamazenta-Crowned', 'Zekrom', 'Zygarde-Base',
|
|
593
|
+
'Arena Trap', 'Magnet Pull', 'Moody', 'Power Construct', 'Shadow Tag', 'TR29 (Baton Pass)', 'TR82 (Stored Power)', 'Baton Pass',
|
|
588
594
|
],
|
|
595
|
+
onValidateSet(set) {
|
|
596
|
+
if (!set.item)
|
|
597
|
+
return;
|
|
598
|
+
const item = this.dex.items.get(set.item);
|
|
599
|
+
if (!/^tr\d\d/i.test(item.name))
|
|
600
|
+
return;
|
|
601
|
+
const moveName = item.desc.split('move ')[1].split('.')[0];
|
|
602
|
+
if (set.moves.map(this.toID).includes(this.toID(moveName))) {
|
|
603
|
+
return [
|
|
604
|
+
`${set.species} can't run ${item.name} (${moveName}) as its item because it already has that move in its moveset.`,
|
|
605
|
+
];
|
|
606
|
+
}
|
|
607
|
+
},
|
|
608
|
+
onValidateTeam(team) {
|
|
609
|
+
const trs = new Set();
|
|
610
|
+
for (const set of team) {
|
|
611
|
+
if (!set.item)
|
|
612
|
+
continue;
|
|
613
|
+
const item = this.dex.items.get(set.item).name;
|
|
614
|
+
if (!/^tr\d\d/i.test(item))
|
|
615
|
+
continue;
|
|
616
|
+
if (trs.has(item)) {
|
|
617
|
+
return [`Your team already has a Pok\u00e9mon with ${item}.`];
|
|
618
|
+
}
|
|
619
|
+
trs.add(item);
|
|
620
|
+
}
|
|
621
|
+
},
|
|
622
|
+
onTakeItem(item) {
|
|
623
|
+
return !/^tr\d\d/i.test(item.name);
|
|
624
|
+
},
|
|
625
|
+
onModifyMove(move) {
|
|
626
|
+
if (move.id === 'knockoff') {
|
|
627
|
+
move.onBasePower = function (basePower, source, target, m) {
|
|
628
|
+
const item = target.getItem();
|
|
629
|
+
if (!this.singleEvent('TakeItem', item, target.itemState, target, target, m, item))
|
|
630
|
+
return;
|
|
631
|
+
// Very hardcode but I'd prefer to not make a mod for one damage calculation change
|
|
632
|
+
if (item.id && !/^tr\d\d/i.test(item.id)) {
|
|
633
|
+
return this.chainModify(1.5);
|
|
634
|
+
}
|
|
635
|
+
};
|
|
636
|
+
}
|
|
637
|
+
},
|
|
638
|
+
onBegin() {
|
|
639
|
+
for (const pokemon of this.getAllPokemon()) {
|
|
640
|
+
const item = pokemon.getItem();
|
|
641
|
+
if (/^tr\d\d/i.test(item.name)) {
|
|
642
|
+
const move = this.dex.moves.get(item.desc.split('move ')[1].split('.')[0]);
|
|
643
|
+
pokemon.moveSlots = pokemon.baseMoveSlots = [
|
|
644
|
+
...pokemon.baseMoveSlots, {
|
|
645
|
+
id: move.id,
|
|
646
|
+
move: move.name,
|
|
647
|
+
pp: move.pp * 8 / 5,
|
|
648
|
+
maxpp: move.pp * 8 / 5,
|
|
649
|
+
target: move.target,
|
|
650
|
+
disabled: false,
|
|
651
|
+
disabledSource: '',
|
|
652
|
+
used: false,
|
|
653
|
+
},
|
|
654
|
+
];
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
},
|
|
589
658
|
},
|
|
590
659
|
{
|
|
591
|
-
name: "[Gen 8]
|
|
592
|
-
desc: `Pokémon
|
|
660
|
+
name: "[Gen 8] Inheritance",
|
|
661
|
+
desc: `Pokémon may use the ability and moves of another, as long as they forfeit their own learnset.`,
|
|
593
662
|
threads: [
|
|
594
|
-
`• <a href="https://www.smogon.com/forums/
|
|
663
|
+
`• <a href="https://www.smogon.com/forums/threads/3656811/">Inheritance</a>`,
|
|
595
664
|
],
|
|
596
|
-
mod: '
|
|
597
|
-
|
|
665
|
+
mod: 'gen8',
|
|
666
|
+
// searchShow: false,
|
|
667
|
+
ruleset: ['Standard', '!Sleep Clause Mod', 'Sleep Moves Clause', '2 Ability Clause', 'Dynamax Clause'],
|
|
598
668
|
banlist: [
|
|
599
|
-
'
|
|
600
|
-
'
|
|
601
|
-
'
|
|
602
|
-
'
|
|
603
|
-
'
|
|
604
|
-
'
|
|
605
|
-
|
|
606
|
-
restricted: [
|
|
607
|
-
'Comatose', 'Contrary', 'Fluffy', 'Fur Coat', 'Gorilla Tactics', 'Huge Power', 'Ice Scales', 'Illusion', 'Imposter', 'Innards Out',
|
|
608
|
-
'Intrepid Sword', 'Libero', 'Magnet Pull', 'Neutralizing Gas', 'Parental Bond', 'Poison Heal', 'Prankster', 'Protean', 'Pure Power',
|
|
609
|
-
'Quick Draw', 'Sand Veil', 'Serene Grace', 'Simple', 'Snow Cloak', 'Speed Boost', 'Stakeout', 'Stench', 'Tinted Lens', 'Triage',
|
|
610
|
-
'Unburden', 'Water Bubble',
|
|
669
|
+
'Blacephalon', 'Blaziken', 'Butterfree', 'Calyrex-Ice', 'Calyrex-Shadow', 'Chansey', 'Combusken', 'Cresselia', 'Darmanitan-Galar', 'Dialga', 'Dracovish',
|
|
670
|
+
'Eternatus', 'Giratina', 'Giratina-Origin', 'Groudon', 'Ho-Oh', 'Kartana', 'Kyogre', 'Kyurem-Black', 'Kyurem-White', 'Landorus-Base', 'Lugia', 'Lunala',
|
|
671
|
+
'Magearna', 'Marshadow', 'Melmetal', 'Mewtwo', 'Natu', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane', 'Palkia', 'Pheromosa', 'Rayquaza', 'Regieleki',
|
|
672
|
+
'Regigigas', 'Reshiram', 'Sableye', 'Shedinja', 'Solgaleo', 'Spectrier', 'Tapu Koko', 'Toxtricity', 'Torkoal', 'Urshifu-Base', 'Xatu', 'Xerneas', 'Yveltal',
|
|
673
|
+
'Zacian', 'Zacian-Crowned', 'Zamazenta', 'Zamazenta-Crowned', 'Zeraora', 'Zekrom', 'Arena Trap', 'Contrary', 'Drizzle', 'Huge Power', 'Imposter', 'Innards Out',
|
|
674
|
+
'Libero', 'Moody', 'Power Construct', 'Pure Power', 'Quick Draw', 'Shadow Tag', 'Sheer Force', 'Simple', 'Unaware', 'Unburden', 'Water Bubble', 'King\'s Rock',
|
|
675
|
+
'Quick Claw', 'Baton Pass', 'Bolt Beak', 'Fishious Rend', 'Shell Smash', 'Thousand Arrows',
|
|
611
676
|
],
|
|
677
|
+
getEvoFamily(speciesid) {
|
|
678
|
+
let species = Dex.species.get(speciesid);
|
|
679
|
+
while (species.prevo) {
|
|
680
|
+
species = Dex.species.get(species.prevo);
|
|
681
|
+
}
|
|
682
|
+
return species.id;
|
|
683
|
+
},
|
|
684
|
+
validateSet(set, teamHas) {
|
|
685
|
+
const unreleased = (pokemon) => pokemon.tier === "Unreleased" && pokemon.isNonstandard === "Unobtainable";
|
|
686
|
+
if (!teamHas.abilityMap) {
|
|
687
|
+
teamHas.abilityMap = Object.create(null);
|
|
688
|
+
for (const pokemon of Dex.species.all()) {
|
|
689
|
+
if (pokemon.isNonstandard || unreleased(pokemon))
|
|
690
|
+
continue;
|
|
691
|
+
if (pokemon.requiredAbility || pokemon.requiredItem || pokemon.requiredMove)
|
|
692
|
+
continue;
|
|
693
|
+
if (this.ruleTable.isBannedSpecies(pokemon))
|
|
694
|
+
continue;
|
|
695
|
+
for (const key of Object.values(pokemon.abilities)) {
|
|
696
|
+
const abilityId = this.dex.toID(key);
|
|
697
|
+
if (abilityId in teamHas.abilityMap) {
|
|
698
|
+
teamHas.abilityMap[abilityId][pokemon.evos ? 'push' : 'unshift'](pokemon.id);
|
|
699
|
+
}
|
|
700
|
+
else {
|
|
701
|
+
teamHas.abilityMap[abilityId] = [pokemon.id];
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
const problem = this.validateForme(set);
|
|
707
|
+
if (problem.length)
|
|
708
|
+
return problem;
|
|
709
|
+
const species = this.dex.species.get(set.species);
|
|
710
|
+
if (!species.exists || species.num < 1)
|
|
711
|
+
return [`The Pok\u00e9mon "${set.species}" does not exist.`];
|
|
712
|
+
if (species.isNonstandard || unreleased(species)) {
|
|
713
|
+
return [`${species.name} is not obtainable in Generation ${this.dex.gen}.`];
|
|
714
|
+
}
|
|
715
|
+
const name = set.name;
|
|
716
|
+
if (this.ruleTable.isBannedSpecies(species)) {
|
|
717
|
+
return this.validateSet(set, teamHas);
|
|
718
|
+
}
|
|
719
|
+
const ability = this.dex.abilities.get(set.ability);
|
|
720
|
+
if (!ability.exists || ability.isNonstandard)
|
|
721
|
+
return [`${name} needs to have a valid ability.`];
|
|
722
|
+
const pokemonWithAbility = teamHas.abilityMap[ability.id];
|
|
723
|
+
if (!pokemonWithAbility)
|
|
724
|
+
return [`${ability.name} is not available on a legal Pok\u00e9mon.`];
|
|
725
|
+
this.format.debug = true;
|
|
726
|
+
if (!teamHas.abilitySources)
|
|
727
|
+
teamHas.abilitySources = Object.create(null);
|
|
728
|
+
const validSources = teamHas.abilitySources[this.dex.toID(set.species)] = []; // Evolution families
|
|
729
|
+
let canonicalSource = ''; // Specific for the basic implementation of Donor Clause (see onValidateTeam).
|
|
730
|
+
for (const donor of pokemonWithAbility) {
|
|
731
|
+
const donorSpecies = this.dex.species.get(donor);
|
|
732
|
+
let format = this.format;
|
|
733
|
+
if (!format.getEvoFamily)
|
|
734
|
+
format = this.dex.formats.get('gen8inheritance');
|
|
735
|
+
const evoFamily = format.getEvoFamily(donorSpecies.id);
|
|
736
|
+
if (validSources.includes(evoFamily))
|
|
737
|
+
continue;
|
|
738
|
+
set.species = donorSpecies.name;
|
|
739
|
+
set.name = donorSpecies.baseSpecies;
|
|
740
|
+
const problems = this.validateSet(set, teamHas) || [];
|
|
741
|
+
if (!problems.length) {
|
|
742
|
+
validSources.push(evoFamily);
|
|
743
|
+
canonicalSource = donorSpecies.name;
|
|
744
|
+
}
|
|
745
|
+
// Specific for the basic implementation of Donor Clause (see onValidateTeam).
|
|
746
|
+
if (validSources.length > 1)
|
|
747
|
+
break;
|
|
748
|
+
}
|
|
749
|
+
this.format.debug = false;
|
|
750
|
+
set.name = name;
|
|
751
|
+
set.species = species.name;
|
|
752
|
+
if (!validSources.length) {
|
|
753
|
+
if (pokemonWithAbility.length > 1)
|
|
754
|
+
return [`${name}'s set is illegal.`];
|
|
755
|
+
return [`${name} has an illegal set with an ability from ${this.dex.species.get(pokemonWithAbility[0]).name}.`];
|
|
756
|
+
}
|
|
757
|
+
// Protocol: Include the data of the donor species in the `ability` data slot.
|
|
758
|
+
// Afterwards, we are going to reset the name to what the user intended.
|
|
759
|
+
set.ability = `${set.ability}0${canonicalSource}`;
|
|
760
|
+
return null;
|
|
761
|
+
},
|
|
762
|
+
onValidateTeam(team, f, teamHas) {
|
|
763
|
+
if (this.ruleTable.has('2abilityclause')) {
|
|
764
|
+
const abilityTable = new Map();
|
|
765
|
+
const base = {
|
|
766
|
+
airlock: 'cloudnine',
|
|
767
|
+
battlearmor: 'shellarmor',
|
|
768
|
+
clearbody: 'whitesmoke',
|
|
769
|
+
dazzling: 'queenlymajesty',
|
|
770
|
+
emergencyexit: 'wimpout',
|
|
771
|
+
filter: 'solidrock',
|
|
772
|
+
gooey: 'tanglinghair',
|
|
773
|
+
insomnia: 'vitalspirit',
|
|
774
|
+
ironbarbs: 'roughskin',
|
|
775
|
+
libero: 'protean',
|
|
776
|
+
minus: 'plus',
|
|
777
|
+
moxie: 'chillingneigh',
|
|
778
|
+
powerofalchemy: 'receiver',
|
|
779
|
+
propellertail: 'stalwart',
|
|
780
|
+
teravolt: 'moldbreaker',
|
|
781
|
+
turboblaze: 'moldbreaker',
|
|
782
|
+
};
|
|
783
|
+
for (const set of team) {
|
|
784
|
+
let ability = this.toID(set.ability.split('0')[0]);
|
|
785
|
+
if (!ability)
|
|
786
|
+
continue;
|
|
787
|
+
if (ability in base)
|
|
788
|
+
ability = base[ability];
|
|
789
|
+
if ((abilityTable.get(ability) || 0) >= 2) {
|
|
790
|
+
return [
|
|
791
|
+
`You are limited to two of each ability by 2 Ability Clause.`,
|
|
792
|
+
`(You have more than two ${this.dex.abilities.get(ability).name} variants)`,
|
|
793
|
+
];
|
|
794
|
+
}
|
|
795
|
+
abilityTable.set(ability, (abilityTable.get(ability) || 0) + 1);
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
// Donor Clause
|
|
799
|
+
const evoFamilyLists = [];
|
|
800
|
+
for (const set of team) {
|
|
801
|
+
const abilitySources = teamHas.abilitySources?.[this.dex.toID(set.species)];
|
|
802
|
+
if (!abilitySources)
|
|
803
|
+
continue;
|
|
804
|
+
let format = this.format;
|
|
805
|
+
if (!format.getEvoFamily)
|
|
806
|
+
format = this.dex.formats.get('gen8inheritance');
|
|
807
|
+
evoFamilyLists.push(abilitySources.map(format.getEvoFamily));
|
|
808
|
+
}
|
|
809
|
+
// Checking actual full incompatibility would require expensive algebra.
|
|
810
|
+
// Instead, we only check the trivial case of multiple Pokémon only legal for exactly one family. FIXME?
|
|
811
|
+
const requiredFamilies = Object.create(null);
|
|
812
|
+
for (const evoFamilies of evoFamilyLists) {
|
|
813
|
+
if (evoFamilies.length !== 1)
|
|
814
|
+
continue;
|
|
815
|
+
const [familyId] = evoFamilies;
|
|
816
|
+
if (!(familyId in requiredFamilies))
|
|
817
|
+
requiredFamilies[familyId] = 1;
|
|
818
|
+
requiredFamilies[familyId]++;
|
|
819
|
+
if (requiredFamilies[familyId] > 2) {
|
|
820
|
+
return [
|
|
821
|
+
`You are limited to up to two inheritances from each evolution family by the Donor Clause.`,
|
|
822
|
+
`(You inherit more than twice from ${this.dex.species.get(familyId).name}).`,
|
|
823
|
+
];
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
},
|
|
827
|
+
onBegin() {
|
|
828
|
+
for (const pokemon of this.getAllPokemon()) {
|
|
829
|
+
if (pokemon.baseAbility.includes('0')) {
|
|
830
|
+
const donor = pokemon.baseAbility.split('0')[1];
|
|
831
|
+
pokemon.m.donor = this.toID(donor);
|
|
832
|
+
pokemon.baseAbility = this.toID(pokemon.baseAbility.split('0')[0]);
|
|
833
|
+
pokemon.ability = pokemon.baseAbility;
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
},
|
|
837
|
+
onSwitchIn(pokemon) {
|
|
838
|
+
if (!pokemon.m.donor)
|
|
839
|
+
return;
|
|
840
|
+
const donorTemplate = this.dex.species.get(pokemon.m.donor);
|
|
841
|
+
if (!donorTemplate.exists)
|
|
842
|
+
return;
|
|
843
|
+
// Place volatiles on the Pokémon to show the donor details.
|
|
844
|
+
this.add('-start', pokemon, donorTemplate.name, '[silent]');
|
|
845
|
+
},
|
|
612
846
|
},
|
|
613
847
|
// Other Metagames
|
|
614
848
|
///////////////////////////////////////////////////////////////////
|
|
@@ -629,8 +863,8 @@ exports.Formats = [
|
|
|
629
863
|
'Calyrex-Shadow', 'Cramorant-Gorging', 'Darmanitan-Galar-Zen', 'Eternatus-Eternamax', 'Shedinja', 'Zacian-Crowned',
|
|
630
864
|
'Arena Trap', 'Contrary', 'Gorilla Tactics', 'Huge Power', 'Illusion', 'Innards Out', 'Intrepid Sword', 'Libero',
|
|
631
865
|
'Magnet Pull', 'Moody', 'Neutralizing Gas', 'Parental Bond', 'Protean', 'Pure Power', 'Shadow Tag', 'Stakeout',
|
|
632
|
-
'Water Bubble', 'Wonder Guard', 'Comatose + Sleep Talk', 'Rusted Sword', '
|
|
633
|
-
'Octolock', 'Shell Smash',
|
|
866
|
+
'Water Bubble', 'Wonder Guard', 'Comatose + Sleep Talk', 'Rusted Sword', 'Belly Drum', 'Bolt Beak', 'Court Change',
|
|
867
|
+
'Double Iron Bash', 'Octolock', 'Shell Smash',
|
|
634
868
|
],
|
|
635
869
|
},
|
|
636
870
|
{
|
|
@@ -643,8 +877,8 @@ exports.Formats = [
|
|
|
643
877
|
mod: 'gen8',
|
|
644
878
|
ruleset: ['Standard', '!Obtainable Abilities', '2 Ability Clause', 'Dynamax Clause', 'Sleep Moves Clause', '!Sleep Clause Mod'],
|
|
645
879
|
banlist: [
|
|
646
|
-
'Archeops', 'Blacephalon', 'Buzzwole', 'Calyrex-Ice', 'Calyrex-Shadow', 'Dialga', 'Dracovish', 'Dragapult', 'Dragonite', 'Eternatus',
|
|
647
|
-
'
|
|
880
|
+
'Archeops', 'Blacephalon', 'Buzzwole', 'Calyrex-Ice', 'Calyrex-Shadow', 'Dialga', 'Dracovish', 'Dragapult', 'Dragonite', 'Eternatus', 'Gengar',
|
|
881
|
+
'Giratina', 'Giratina-Origin', 'Groudon', 'Ho-Oh', 'Kartana', 'Keldeo', 'Kommo-o', 'Kyogre', 'Kyurem', 'Kyurem-Black', 'Kyurem-White',
|
|
648
882
|
'Lugia', 'Lunala', 'Magearna', 'Marshadow', 'Melmetal', 'Mewtwo', 'Naganadel', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane', 'Noivern',
|
|
649
883
|
'Palkia', 'Pheromosa', 'Rayquaza', 'Regigigas', 'Reshiram', 'Shedinja', 'Solgaleo', 'Spectrier', 'Urshifu', 'Urshifu-Rapid-Strike',
|
|
650
884
|
'Victini', 'Weavile', 'Xerneas', 'Yveltal', 'Zacian', 'Zacian-Crowned', 'Zamazenta-Base', 'Zekrom', 'Zeraora', 'Zygarde-Base',
|
|
@@ -741,9 +975,9 @@ exports.Formats = [
|
|
|
741
975
|
'Arena Trap', 'Magnet Pull', 'Moody', 'Power Construct', 'Shadow Tag', 'King\'s Rock', 'Baton Pass',
|
|
742
976
|
],
|
|
743
977
|
restricted: [
|
|
744
|
-
'Acupressure', 'Astral Barrage', 'Belly Drum', 'Bolt Beak', 'Clangorous Soul', 'Double Iron Bash', 'Electrify', 'Extreme Speed', '
|
|
745
|
-
'Geomancy', 'Glacial Lance', 'Oblivion Wing', 'Precipice Blades', 'Shell Smash', 'Shift Gear', 'Thousand Arrows', 'Thunderous Kick',
|
|
746
|
-
'Wicked Blow',
|
|
978
|
+
'Acupressure', 'Astral Barrage', 'Belly Drum', 'Bolt Beak', 'Clangorous Soul', 'Double Iron Bash', 'Electrify', 'Extreme Speed', 'Final Gambit',
|
|
979
|
+
'Fishious Rend', 'Geomancy', 'Glacial Lance', 'Oblivion Wing', 'Precipice Blades', 'Shell Smash', 'Shift Gear', 'Thousand Arrows', 'Thunderous Kick',
|
|
980
|
+
'V-create', 'Wicked Blow',
|
|
747
981
|
],
|
|
748
982
|
},
|
|
749
983
|
{
|
|
@@ -930,7 +1164,7 @@ exports.Formats = [
|
|
|
930
1164
|
],
|
|
931
1165
|
mod: 'gen8bdsp',
|
|
932
1166
|
ruleset: ['Little Cup', 'Standard'],
|
|
933
|
-
banlist: ['Gligar', 'Meditite', 'Misdreavus', 'Murkrow', 'Scyther', 'Sneasel', 'Tangela', 'Vulpix', 'Yanma', 'Moody', 'Baton Pass', 'Sticky Web'],
|
|
1167
|
+
banlist: ['Gligar', 'Meditite', 'Misdreavus', 'Munchlax', 'Murkrow', 'Scyther', 'Sneasel', 'Tangela', 'Vulpix', 'Yanma', 'Moody', 'Baton Pass', 'Sticky Web'],
|
|
934
1168
|
},
|
|
935
1169
|
{
|
|
936
1170
|
name: "[Gen 8 BDSP] Monotype",
|
|
@@ -1018,332 +1252,144 @@ exports.Formats = [
|
|
|
1018
1252
|
searchShow: false,
|
|
1019
1253
|
ruleset: ['Standard', 'Overflow Stat Mod', 'Dynamax Clause', '2 Ability Clause'],
|
|
1020
1254
|
banlist: ['Corsola-Galar', 'Sneasel', 'Type: Null', 'Arena Trap', 'Ice Scales', 'Moody', 'King\'s Rock', 'Baton Pass'],
|
|
1021
|
-
restricted: ['Chansey', 'Lunala', 'Shedinja', 'Solgaleo', 'Gorilla Tactics', 'Huge Power', 'Pure Power', 'Shadow Tag'],
|
|
1022
|
-
onValidateTeam(team) {
|
|
1023
|
-
const names = new Set();
|
|
1024
|
-
for (const set of team) {
|
|
1025
|
-
const name = set.name;
|
|
1026
|
-
if (names.has(this.dex.toID(name))) {
|
|
1027
|
-
return [
|
|
1028
|
-
`Your Pok\u00e9mon must have different nicknames.`,
|
|
1029
|
-
`(You have more than one Pok\u00e9mon named '${name}')`,
|
|
1030
|
-
];
|
|
1031
|
-
}
|
|
1032
|
-
names.add(this.dex.toID(name));
|
|
1033
|
-
}
|
|
1034
|
-
if (!names.size) {
|
|
1035
|
-
return [
|
|
1036
|
-
`${this.format.name} works using nicknames; your team has 0 nicknamed Pok\u00e9mon.`,
|
|
1037
|
-
`(If this was intentional, add a nickname to one Pok\u00e9mon that isn't the name of a Pok\u00e9mon species.)`,
|
|
1038
|
-
];
|
|
1039
|
-
}
|
|
1040
|
-
},
|
|
1041
|
-
checkCanLearn(move, species, lsetData, set) {
|
|
1042
|
-
// @ts-ignore
|
|
1043
|
-
if (!set.sp?.exists || !set.crossSpecies?.exists) {
|
|
1044
|
-
return this.checkCanLearn(move, species, lsetData, set);
|
|
1045
|
-
}
|
|
1046
|
-
// @ts-ignore
|
|
1047
|
-
const problem = this.checkCanLearn(move, set.sp);
|
|
1048
|
-
if (!problem)
|
|
1049
|
-
return null;
|
|
1050
|
-
// @ts-ignore
|
|
1051
|
-
if (!set.crossMovesLeft)
|
|
1052
|
-
return problem;
|
|
1053
|
-
// @ts-ignore
|
|
1054
|
-
if (this.checkCanLearn(move, set.crossSpecies))
|
|
1055
|
-
return problem;
|
|
1056
|
-
// @ts-ignore
|
|
1057
|
-
set.crossMovesLeft--;
|
|
1058
|
-
return null;
|
|
1059
|
-
},
|
|
1060
|
-
validateSet(set, teamHas) {
|
|
1061
|
-
const crossSpecies = this.dex.species.get(set.name);
|
|
1062
|
-
let problems = this.dex.formats.get('Pokemon').onChangeSet?.call(this, set, this.format) || null;
|
|
1063
|
-
if (Array.isArray(problems) && problems.length)
|
|
1064
|
-
return problems;
|
|
1065
|
-
const crossNonstandard = (!this.ruleTable.has('standardnatdex') && crossSpecies.isNonstandard === 'Past') ||
|
|
1066
|
-
crossSpecies.isNonstandard === 'Future';
|
|
1067
|
-
const crossIsCap = !this.ruleTable.has('+pokemontag:cap') && crossSpecies.isNonstandard === 'CAP';
|
|
1068
|
-
if (!crossSpecies.exists || crossNonstandard || crossIsCap)
|
|
1069
|
-
return this.validateSet(set, teamHas);
|
|
1070
|
-
const species = this.dex.species.get(set.species);
|
|
1071
|
-
const check = this.checkSpecies(set, species, species, {});
|
|
1072
|
-
if (check)
|
|
1073
|
-
return [check];
|
|
1074
|
-
const nonstandard = !this.ruleTable.has('standardnatdex') && species.isNonstandard === 'Past';
|
|
1075
|
-
const isCap = !this.ruleTable.has('+pokemontag:cap') && species.isNonstandard === 'CAP';
|
|
1076
|
-
if (!species.exists || nonstandard || isCap || species === crossSpecies)
|
|
1077
|
-
return this.validateSet(set, teamHas);
|
|
1078
|
-
if (!species.nfe)
|
|
1079
|
-
return [`${species.name} cannot cross evolve because it doesn't evolve.`];
|
|
1080
|
-
const crossIsUnreleased = (crossSpecies.tier === "Unreleased" && crossSpecies.isNonstandard === "Unobtainable");
|
|
1081
|
-
if (crossSpecies.battleOnly || crossIsUnreleased || !crossSpecies.prevo) {
|
|
1082
|
-
return [`${species.name} cannot cross evolve into ${crossSpecies.name} because it isn't an evolution.`];
|
|
1083
|
-
}
|
|
1084
|
-
if (this.ruleTable.isRestrictedSpecies(crossSpecies)) {
|
|
1085
|
-
return [`${species.name} cannot cross evolve into ${crossSpecies.name} because it is banned.`];
|
|
1086
|
-
}
|
|
1087
|
-
const crossPrevoSpecies = this.dex.species.get(crossSpecies.prevo);
|
|
1088
|
-
if (!crossPrevoSpecies.prevo !== !species.prevo) {
|
|
1089
|
-
return [
|
|
1090
|
-
`${species.name} cannot cross evolve into ${crossSpecies.name} because they are not consecutive evolution stages.`,
|
|
1091
|
-
];
|
|
1092
|
-
}
|
|
1093
|
-
const item = this.dex.items.get(set.item);
|
|
1094
|
-
if (item.itemUser?.length) {
|
|
1095
|
-
if (!item.itemUser.includes(crossSpecies.name) || crossSpecies.name !== species.name) {
|
|
1096
|
-
return [`${species.name} cannot use ${item.name} because it is cross evolved into ${crossSpecies.name}.`];
|
|
1097
|
-
}
|
|
1098
|
-
}
|
|
1099
|
-
const ability = this.dex.abilities.get(set.ability);
|
|
1100
|
-
if (!this.ruleTable.isRestricted(`ability:${ability.id}`) || Object.values(species.abilities).includes(ability.name)) {
|
|
1101
|
-
set.species = crossSpecies.name;
|
|
1102
|
-
}
|
|
1103
|
-
// @ts-ignore
|
|
1104
|
-
set.sp = species;
|
|
1105
|
-
// @ts-ignore
|
|
1106
|
-
set.crossSpecies = crossSpecies;
|
|
1107
|
-
// @ts-ignore
|
|
1108
|
-
set.crossMovesLeft = 2;
|
|
1109
|
-
problems = this.validateSet(set, teamHas);
|
|
1110
|
-
set.name = crossSpecies.name;
|
|
1111
|
-
set.species = species.name;
|
|
1112
|
-
return problems;
|
|
1113
|
-
},
|
|
1114
|
-
onModifySpecies(species, target, source, effect) {
|
|
1115
|
-
if (!target)
|
|
1116
|
-
return; // chat
|
|
1117
|
-
if (effect && ['imposter', 'transform'].includes(effect.id))
|
|
1118
|
-
return;
|
|
1119
|
-
if (target.set.name === target.set.species)
|
|
1120
|
-
return;
|
|
1121
|
-
const crossSpecies = this.dex.species.get(target.set.name);
|
|
1122
|
-
if (!crossSpecies.exists)
|
|
1123
|
-
return;
|
|
1124
|
-
if (species.battleOnly || !species.nfe)
|
|
1125
|
-
return;
|
|
1126
|
-
const crossIsUnreleased = (crossSpecies.tier === "Unreleased" && crossSpecies.isNonstandard === "Unobtainable");
|
|
1127
|
-
if (crossSpecies.battleOnly || crossIsUnreleased || !crossSpecies.prevo)
|
|
1128
|
-
return;
|
|
1129
|
-
const crossPrevoSpecies = this.dex.species.get(crossSpecies.prevo);
|
|
1130
|
-
if (!crossPrevoSpecies.prevo !== !species.prevo)
|
|
1131
|
-
return;
|
|
1132
|
-
const mixedSpecies = this.dex.deepClone(species);
|
|
1133
|
-
mixedSpecies.weightkg =
|
|
1134
|
-
Math.max(0.1, +(species.weightkg + crossSpecies.weightkg - crossPrevoSpecies.weightkg)).toFixed(1);
|
|
1135
|
-
mixedSpecies.nfe = false;
|
|
1136
|
-
mixedSpecies.evos = [];
|
|
1137
|
-
mixedSpecies.eggGroups = crossSpecies.eggGroups;
|
|
1138
|
-
mixedSpecies.abilities = crossSpecies.abilities;
|
|
1139
|
-
mixedSpecies.bst = 0;
|
|
1140
|
-
let i;
|
|
1141
|
-
for (i in species.baseStats) {
|
|
1142
|
-
const statChange = crossSpecies.baseStats[i] - crossPrevoSpecies.baseStats[i];
|
|
1143
|
-
mixedSpecies.baseStats[i] = this.clampIntRange(species.baseStats[i] + statChange, 1, 255);
|
|
1144
|
-
mixedSpecies.bst += mixedSpecies.baseStats[i];
|
|
1145
|
-
}
|
|
1146
|
-
if (crossSpecies.types[0] !== crossPrevoSpecies.types[0])
|
|
1147
|
-
mixedSpecies.types[0] = crossSpecies.types[0];
|
|
1148
|
-
if (crossSpecies.types[1] !== crossPrevoSpecies.types[1]) {
|
|
1149
|
-
mixedSpecies.types[1] = crossSpecies.types[1] || crossSpecies.types[0];
|
|
1150
|
-
}
|
|
1151
|
-
if (mixedSpecies.types[0] === mixedSpecies.types[1])
|
|
1152
|
-
mixedSpecies.types = [mixedSpecies.types[0]];
|
|
1153
|
-
return mixedSpecies;
|
|
1154
|
-
},
|
|
1155
|
-
onBegin() {
|
|
1156
|
-
for (const pokemon of this.getAllPokemon()) {
|
|
1157
|
-
pokemon.baseSpecies = pokemon.species;
|
|
1158
|
-
}
|
|
1159
|
-
},
|
|
1160
|
-
},
|
|
1161
|
-
{
|
|
1162
|
-
name: "[Gen 8] Inheritance",
|
|
1163
|
-
desc: `Pokémon may use the ability and moves of another, as long as they forfeit their own learnset.`,
|
|
1164
|
-
threads: [
|
|
1165
|
-
`• <a href="https://www.smogon.com/forums/threads/3656811/">Inheritance</a>`,
|
|
1166
|
-
],
|
|
1167
|
-
mod: 'gen8',
|
|
1168
|
-
searchShow: false,
|
|
1169
|
-
ruleset: ['Standard', '2 Ability Clause', 'Dynamax Clause'],
|
|
1170
|
-
banlist: [
|
|
1171
|
-
'Blacephalon', 'Blaziken', 'Butterfree', 'Calyrex-Ice', 'Calyrex-Shadow', 'Chansey', 'Combusken', 'Cresselia', 'Darmanitan-Galar', 'Dialga', 'Dracovish',
|
|
1172
|
-
'Eternatus', 'Giratina', 'Giratina-Origin', 'Groudon', 'Ho-Oh', 'Kartana', 'Kyogre', 'Kyurem-Black', 'Kyurem-White', 'Landorus-Base', 'Lugia', 'Lunala',
|
|
1173
|
-
'Magearna', 'Marshadow', 'Melmetal', 'Mewtwo', 'Natu', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane', 'Palkia', 'Pheromosa', 'Rayquaza', 'Regieleki',
|
|
1174
|
-
'Regigigas', 'Reshiram', 'Sableye', 'Shedinja', 'Solgaleo', 'Spectrier', 'Tapu Koko', 'Toxtricity', 'Torkoal', 'Urshifu-Base', 'Xatu', 'Xerneas', 'Yveltal',
|
|
1175
|
-
'Zacian', 'Zacian-Crowned', 'Zamazenta', 'Zamazenta-Crowned', 'Zeraora', 'Zekrom', 'Arena Trap', 'Contrary', 'Drizzle', 'Huge Power', 'Imposter', 'Innards Out',
|
|
1176
|
-
'Libero', 'Moody', 'Power Construct', 'Pure Power', 'Quick Draw', 'Shadow Tag', 'Sheer Force', 'Simple', 'Unaware', 'Unburden', 'Water Bubble', 'King\'s Rock',
|
|
1177
|
-
'Quick Claw', 'Baton Pass', 'Bolt Beak', 'Fishious Rend', 'Shell Smash', 'Thousand Arrows',
|
|
1178
|
-
],
|
|
1179
|
-
getEvoFamily(speciesid) {
|
|
1180
|
-
let species = Dex.species.get(speciesid);
|
|
1181
|
-
while (species.prevo) {
|
|
1182
|
-
species = Dex.species.get(species.prevo);
|
|
1183
|
-
}
|
|
1184
|
-
return species.id;
|
|
1185
|
-
},
|
|
1186
|
-
validateSet(set, teamHas) {
|
|
1187
|
-
const unreleased = (pokemon) => pokemon.tier === "Unreleased" && pokemon.isNonstandard === "Unobtainable";
|
|
1188
|
-
if (!teamHas.abilityMap) {
|
|
1189
|
-
teamHas.abilityMap = Object.create(null);
|
|
1190
|
-
for (const pokemon of Dex.species.all()) {
|
|
1191
|
-
if (pokemon.isNonstandard || unreleased(pokemon))
|
|
1192
|
-
continue;
|
|
1193
|
-
if (pokemon.requiredAbility || pokemon.requiredItem || pokemon.requiredMove)
|
|
1194
|
-
continue;
|
|
1195
|
-
if (this.ruleTable.isBannedSpecies(pokemon))
|
|
1196
|
-
continue;
|
|
1197
|
-
for (const key of Object.values(pokemon.abilities)) {
|
|
1198
|
-
const abilityId = this.dex.toID(key);
|
|
1199
|
-
if (abilityId in teamHas.abilityMap) {
|
|
1200
|
-
teamHas.abilityMap[abilityId][pokemon.evos ? 'push' : 'unshift'](pokemon.id);
|
|
1201
|
-
}
|
|
1202
|
-
else {
|
|
1203
|
-
teamHas.abilityMap[abilityId] = [pokemon.id];
|
|
1204
|
-
}
|
|
1205
|
-
}
|
|
1206
|
-
}
|
|
1207
|
-
}
|
|
1208
|
-
const problem = this.validateForme(set);
|
|
1209
|
-
if (problem.length)
|
|
1210
|
-
return problem;
|
|
1211
|
-
const species = this.dex.species.get(set.species);
|
|
1212
|
-
if (!species.exists || species.num < 1)
|
|
1213
|
-
return [`The Pok\u00e9mon "${set.species}" does not exist.`];
|
|
1214
|
-
if (species.isNonstandard || unreleased(species)) {
|
|
1215
|
-
return [`${species.name} is not obtainable in Generation ${this.dex.gen}.`];
|
|
1216
|
-
}
|
|
1217
|
-
const name = set.name;
|
|
1218
|
-
if (this.ruleTable.isBannedSpecies(species)) {
|
|
1219
|
-
return this.validateSet(set, teamHas);
|
|
1220
|
-
}
|
|
1221
|
-
const ability = this.dex.abilities.get(set.ability);
|
|
1222
|
-
if (!ability.exists || ability.isNonstandard)
|
|
1223
|
-
return [`${name} needs to have a valid ability.`];
|
|
1224
|
-
const pokemonWithAbility = teamHas.abilityMap[ability.id];
|
|
1225
|
-
if (!pokemonWithAbility)
|
|
1226
|
-
return [`${ability.name} is not available on a legal Pok\u00e9mon.`];
|
|
1227
|
-
this.format.debug = true;
|
|
1228
|
-
if (!teamHas.abilitySources)
|
|
1229
|
-
teamHas.abilitySources = Object.create(null);
|
|
1230
|
-
const validSources = teamHas.abilitySources[this.dex.toID(set.species)] = []; // Evolution families
|
|
1231
|
-
let canonicalSource = ''; // Specific for the basic implementation of Donor Clause (see onValidateTeam).
|
|
1232
|
-
for (const donor of pokemonWithAbility) {
|
|
1233
|
-
const donorSpecies = this.dex.species.get(donor);
|
|
1234
|
-
let format = this.format;
|
|
1235
|
-
if (!format.getEvoFamily)
|
|
1236
|
-
format = this.dex.formats.get('gen8inheritance');
|
|
1237
|
-
const evoFamily = format.getEvoFamily(donorSpecies.id);
|
|
1238
|
-
if (validSources.includes(evoFamily))
|
|
1239
|
-
continue;
|
|
1240
|
-
set.species = donorSpecies.name;
|
|
1241
|
-
set.name = donorSpecies.baseSpecies;
|
|
1242
|
-
const problems = this.validateSet(set, teamHas) || [];
|
|
1243
|
-
if (!problems.length) {
|
|
1244
|
-
validSources.push(evoFamily);
|
|
1245
|
-
canonicalSource = donorSpecies.name;
|
|
1246
|
-
}
|
|
1247
|
-
// Specific for the basic implementation of Donor Clause (see onValidateTeam).
|
|
1248
|
-
if (validSources.length > 1)
|
|
1249
|
-
break;
|
|
1250
|
-
}
|
|
1251
|
-
this.format.debug = false;
|
|
1252
|
-
set.name = name;
|
|
1253
|
-
set.species = species.name;
|
|
1254
|
-
if (!validSources.length) {
|
|
1255
|
-
if (pokemonWithAbility.length > 1)
|
|
1256
|
-
return [`${name}'s set is illegal.`];
|
|
1257
|
-
return [`${name} has an illegal set with an ability from ${this.dex.species.get(pokemonWithAbility[0]).name}.`];
|
|
1258
|
-
}
|
|
1259
|
-
// Protocol: Include the data of the donor species in the `ability` data slot.
|
|
1260
|
-
// Afterwards, we are going to reset the name to what the user intended.
|
|
1261
|
-
set.ability = `${set.ability}0${canonicalSource}`;
|
|
1262
|
-
return null;
|
|
1263
|
-
},
|
|
1264
|
-
onValidateTeam(team, f, teamHas) {
|
|
1265
|
-
if (this.ruleTable.has('2abilityclause')) {
|
|
1266
|
-
const abilityTable = new Map();
|
|
1267
|
-
const base = {
|
|
1268
|
-
airlock: 'cloudnine',
|
|
1269
|
-
battlearmor: 'shellarmor',
|
|
1270
|
-
clearbody: 'whitesmoke',
|
|
1271
|
-
dazzling: 'queenlymajesty',
|
|
1272
|
-
emergencyexit: 'wimpout',
|
|
1273
|
-
filter: 'solidrock',
|
|
1274
|
-
gooey: 'tanglinghair',
|
|
1275
|
-
insomnia: 'vitalspirit',
|
|
1276
|
-
ironbarbs: 'roughskin',
|
|
1277
|
-
libero: 'protean',
|
|
1278
|
-
minus: 'plus',
|
|
1279
|
-
moxie: 'chillingneigh',
|
|
1280
|
-
powerofalchemy: 'receiver',
|
|
1281
|
-
propellertail: 'stalwart',
|
|
1282
|
-
teravolt: 'moldbreaker',
|
|
1283
|
-
turboblaze: 'moldbreaker',
|
|
1284
|
-
};
|
|
1285
|
-
for (const set of team) {
|
|
1286
|
-
let ability = this.toID(set.ability.split('0')[0]);
|
|
1287
|
-
if (!ability)
|
|
1288
|
-
continue;
|
|
1289
|
-
if (ability in base)
|
|
1290
|
-
ability = base[ability];
|
|
1291
|
-
if ((abilityTable.get(ability) || 0) >= 2) {
|
|
1292
|
-
return [
|
|
1293
|
-
`You are limited to two of each ability by 2 Ability Clause.`,
|
|
1294
|
-
`(You have more than two ${this.dex.abilities.get(ability).name} variants)`,
|
|
1295
|
-
];
|
|
1296
|
-
}
|
|
1297
|
-
abilityTable.set(ability, (abilityTable.get(ability) || 0) + 1);
|
|
1298
|
-
}
|
|
1299
|
-
}
|
|
1300
|
-
// Donor Clause
|
|
1301
|
-
const evoFamilyLists = [];
|
|
1302
|
-
for (const set of team) {
|
|
1303
|
-
const abilitySources = teamHas.abilitySources?.[this.dex.toID(set.species)];
|
|
1304
|
-
if (!abilitySources)
|
|
1305
|
-
continue;
|
|
1306
|
-
let format = this.format;
|
|
1307
|
-
if (!format.getEvoFamily)
|
|
1308
|
-
format = this.dex.formats.get('gen8inheritance');
|
|
1309
|
-
evoFamilyLists.push(abilitySources.map(format.getEvoFamily));
|
|
1310
|
-
}
|
|
1311
|
-
// Checking actual full incompatibility would require expensive algebra.
|
|
1312
|
-
// Instead, we only check the trivial case of multiple Pokémon only legal for exactly one family. FIXME?
|
|
1313
|
-
const requiredFamilies = Object.create(null);
|
|
1314
|
-
for (const evoFamilies of evoFamilyLists) {
|
|
1315
|
-
if (evoFamilies.length !== 1)
|
|
1316
|
-
continue;
|
|
1317
|
-
const [familyId] = evoFamilies;
|
|
1318
|
-
if (!(familyId in requiredFamilies))
|
|
1319
|
-
requiredFamilies[familyId] = 1;
|
|
1320
|
-
requiredFamilies[familyId]++;
|
|
1321
|
-
if (requiredFamilies[familyId] > 2) {
|
|
1255
|
+
restricted: ['Chansey', 'Lunala', 'Shedinja', 'Solgaleo', 'Gorilla Tactics', 'Huge Power', 'Pure Power', 'Shadow Tag'],
|
|
1256
|
+
onValidateTeam(team) {
|
|
1257
|
+
const names = new Set();
|
|
1258
|
+
for (const set of team) {
|
|
1259
|
+
const name = set.name;
|
|
1260
|
+
if (names.has(this.dex.toID(name))) {
|
|
1322
1261
|
return [
|
|
1323
|
-
`
|
|
1324
|
-
`(You
|
|
1262
|
+
`Your Pok\u00e9mon must have different nicknames.`,
|
|
1263
|
+
`(You have more than one Pok\u00e9mon named '${name}')`,
|
|
1325
1264
|
];
|
|
1326
1265
|
}
|
|
1266
|
+
names.add(this.dex.toID(name));
|
|
1267
|
+
}
|
|
1268
|
+
if (!names.size) {
|
|
1269
|
+
return [
|
|
1270
|
+
`${this.format.name} works using nicknames; your team has 0 nicknamed Pok\u00e9mon.`,
|
|
1271
|
+
`(If this was intentional, add a nickname to one Pok\u00e9mon that isn't the name of a Pok\u00e9mon species.)`,
|
|
1272
|
+
];
|
|
1327
1273
|
}
|
|
1328
1274
|
},
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1275
|
+
checkCanLearn(move, species, lsetData, set) {
|
|
1276
|
+
// @ts-ignore
|
|
1277
|
+
if (!set.sp?.exists || !set.crossSpecies?.exists) {
|
|
1278
|
+
return this.checkCanLearn(move, species, lsetData, set);
|
|
1279
|
+
}
|
|
1280
|
+
// @ts-ignore
|
|
1281
|
+
const problem = this.checkCanLearn(move, set.sp);
|
|
1282
|
+
if (!problem)
|
|
1283
|
+
return null;
|
|
1284
|
+
// @ts-ignore
|
|
1285
|
+
if (!set.crossMovesLeft)
|
|
1286
|
+
return problem;
|
|
1287
|
+
// @ts-ignore
|
|
1288
|
+
if (this.checkCanLearn(move, set.crossSpecies))
|
|
1289
|
+
return problem;
|
|
1290
|
+
// @ts-ignore
|
|
1291
|
+
set.crossMovesLeft--;
|
|
1292
|
+
return null;
|
|
1293
|
+
},
|
|
1294
|
+
validateSet(set, teamHas) {
|
|
1295
|
+
const crossSpecies = this.dex.species.get(set.name);
|
|
1296
|
+
let problems = this.dex.formats.get('Pokemon').onChangeSet?.call(this, set, this.format) || null;
|
|
1297
|
+
if (Array.isArray(problems) && problems.length)
|
|
1298
|
+
return problems;
|
|
1299
|
+
const crossNonstandard = (!this.ruleTable.has('standardnatdex') && crossSpecies.isNonstandard === 'Past') ||
|
|
1300
|
+
crossSpecies.isNonstandard === 'Future';
|
|
1301
|
+
const crossIsCap = !this.ruleTable.has('+pokemontag:cap') && crossSpecies.isNonstandard === 'CAP';
|
|
1302
|
+
if (!crossSpecies.exists || crossNonstandard || crossIsCap)
|
|
1303
|
+
return this.validateSet(set, teamHas);
|
|
1304
|
+
const species = this.dex.species.get(set.species);
|
|
1305
|
+
const check = this.checkSpecies(set, species, species, {});
|
|
1306
|
+
if (check)
|
|
1307
|
+
return [check];
|
|
1308
|
+
const nonstandard = !this.ruleTable.has('standardnatdex') && species.isNonstandard === 'Past';
|
|
1309
|
+
const isCap = !this.ruleTable.has('+pokemontag:cap') && species.isNonstandard === 'CAP';
|
|
1310
|
+
if (!species.exists || nonstandard || isCap || species === crossSpecies)
|
|
1311
|
+
return this.validateSet(set, teamHas);
|
|
1312
|
+
if (!species.nfe)
|
|
1313
|
+
return [`${species.name} cannot cross evolve because it doesn't evolve.`];
|
|
1314
|
+
const crossIsUnreleased = (crossSpecies.tier === "Unreleased" && crossSpecies.isNonstandard === "Unobtainable");
|
|
1315
|
+
if (crossSpecies.battleOnly || crossIsUnreleased || !crossSpecies.prevo) {
|
|
1316
|
+
return [`${species.name} cannot cross evolve into ${crossSpecies.name} because it isn't an evolution.`];
|
|
1317
|
+
}
|
|
1318
|
+
if (this.ruleTable.isRestrictedSpecies(crossSpecies)) {
|
|
1319
|
+
return [`${species.name} cannot cross evolve into ${crossSpecies.name} because it is banned.`];
|
|
1320
|
+
}
|
|
1321
|
+
const crossPrevoSpecies = this.dex.species.get(crossSpecies.prevo);
|
|
1322
|
+
if (!crossPrevoSpecies.prevo !== !species.prevo) {
|
|
1323
|
+
return [
|
|
1324
|
+
`${species.name} cannot cross evolve into ${crossSpecies.name} because they are not consecutive evolution stages.`,
|
|
1325
|
+
];
|
|
1326
|
+
}
|
|
1327
|
+
const item = this.dex.items.get(set.item);
|
|
1328
|
+
if (item.itemUser?.length) {
|
|
1329
|
+
if (!item.itemUser.includes(crossSpecies.name) || crossSpecies.name !== species.name) {
|
|
1330
|
+
return [`${species.name} cannot use ${item.name} because it is cross evolved into ${crossSpecies.name}.`];
|
|
1336
1331
|
}
|
|
1337
1332
|
}
|
|
1333
|
+
const ability = this.dex.abilities.get(set.ability);
|
|
1334
|
+
if (!this.ruleTable.isRestricted(`ability:${ability.id}`) || Object.values(species.abilities).includes(ability.name)) {
|
|
1335
|
+
set.species = crossSpecies.name;
|
|
1336
|
+
}
|
|
1337
|
+
// @ts-ignore
|
|
1338
|
+
set.sp = species;
|
|
1339
|
+
// @ts-ignore
|
|
1340
|
+
set.crossSpecies = crossSpecies;
|
|
1341
|
+
// @ts-ignore
|
|
1342
|
+
set.crossMovesLeft = 2;
|
|
1343
|
+
problems = this.validateSet(set, teamHas);
|
|
1344
|
+
set.name = crossSpecies.name;
|
|
1345
|
+
set.species = species.name;
|
|
1346
|
+
return problems;
|
|
1338
1347
|
},
|
|
1339
|
-
|
|
1340
|
-
if (!
|
|
1348
|
+
onModifySpecies(species, target, source, effect) {
|
|
1349
|
+
if (!target)
|
|
1350
|
+
return; // chat
|
|
1351
|
+
if (effect && ['imposter', 'transform'].includes(effect.id))
|
|
1341
1352
|
return;
|
|
1342
|
-
|
|
1343
|
-
if (!donorTemplate.exists)
|
|
1353
|
+
if (target.set.name === target.set.species)
|
|
1344
1354
|
return;
|
|
1345
|
-
|
|
1346
|
-
|
|
1355
|
+
const crossSpecies = this.dex.species.get(target.set.name);
|
|
1356
|
+
if (!crossSpecies.exists)
|
|
1357
|
+
return;
|
|
1358
|
+
if (species.battleOnly || !species.nfe)
|
|
1359
|
+
return;
|
|
1360
|
+
const crossIsUnreleased = (crossSpecies.tier === "Unreleased" && crossSpecies.isNonstandard === "Unobtainable");
|
|
1361
|
+
if (crossSpecies.battleOnly || crossIsUnreleased || !crossSpecies.prevo)
|
|
1362
|
+
return;
|
|
1363
|
+
const crossPrevoSpecies = this.dex.species.get(crossSpecies.prevo);
|
|
1364
|
+
if (!crossPrevoSpecies.prevo !== !species.prevo)
|
|
1365
|
+
return;
|
|
1366
|
+
const mixedSpecies = this.dex.deepClone(species);
|
|
1367
|
+
mixedSpecies.weightkg =
|
|
1368
|
+
Math.max(0.1, +(species.weightkg + crossSpecies.weightkg - crossPrevoSpecies.weightkg)).toFixed(1);
|
|
1369
|
+
mixedSpecies.nfe = false;
|
|
1370
|
+
mixedSpecies.evos = [];
|
|
1371
|
+
mixedSpecies.eggGroups = crossSpecies.eggGroups;
|
|
1372
|
+
mixedSpecies.abilities = crossSpecies.abilities;
|
|
1373
|
+
mixedSpecies.bst = 0;
|
|
1374
|
+
let i;
|
|
1375
|
+
for (i in species.baseStats) {
|
|
1376
|
+
const statChange = crossSpecies.baseStats[i] - crossPrevoSpecies.baseStats[i];
|
|
1377
|
+
mixedSpecies.baseStats[i] = this.clampIntRange(species.baseStats[i] + statChange, 1, 255);
|
|
1378
|
+
mixedSpecies.bst += mixedSpecies.baseStats[i];
|
|
1379
|
+
}
|
|
1380
|
+
if (crossSpecies.types[0] !== crossPrevoSpecies.types[0])
|
|
1381
|
+
mixedSpecies.types[0] = crossSpecies.types[0];
|
|
1382
|
+
if (crossSpecies.types[1] !== crossPrevoSpecies.types[1]) {
|
|
1383
|
+
mixedSpecies.types[1] = crossSpecies.types[1] || crossSpecies.types[0];
|
|
1384
|
+
}
|
|
1385
|
+
if (mixedSpecies.types[0] === mixedSpecies.types[1])
|
|
1386
|
+
mixedSpecies.types = [mixedSpecies.types[0]];
|
|
1387
|
+
return mixedSpecies;
|
|
1388
|
+
},
|
|
1389
|
+
onBegin() {
|
|
1390
|
+
for (const pokemon of this.getAllPokemon()) {
|
|
1391
|
+
pokemon.baseSpecies = pokemon.species;
|
|
1392
|
+
}
|
|
1347
1393
|
},
|
|
1348
1394
|
},
|
|
1349
1395
|
{
|
|
@@ -2080,6 +2126,17 @@ exports.Formats = [
|
|
|
2080
2126
|
team: 'randomStaffBros',
|
|
2081
2127
|
ruleset: ['Dynamax Clause', 'HP Percentage Mod', 'Cancel Mod', 'Sleep Clause Mod'],
|
|
2082
2128
|
onBegin() {
|
|
2129
|
+
if (!this.ruleTable.has('dynamaxclause')) {
|
|
2130
|
+
// Old joke format we're bringing back
|
|
2131
|
+
for (const side of this.sides) {
|
|
2132
|
+
side.dynamaxUsed = true;
|
|
2133
|
+
}
|
|
2134
|
+
this.add('message', 'Delphox only');
|
|
2135
|
+
this.add('message', 'No items');
|
|
2136
|
+
this.add('message', 'Final Destination');
|
|
2137
|
+
return;
|
|
2138
|
+
}
|
|
2139
|
+
// TODO look into making an event to put this right after turn|1
|
|
2083
2140
|
// https://discordapp.com/channels/630837856075513856/630845310033330206/716126469528485909
|
|
2084
2141
|
// Requires client change
|
|
2085
2142
|
this.add(`raw|<div class='broadcast-green'><b>Wondering what all these custom moves, abilities, and items do?<br />Check out the <a href="https://www.smogon.com/articles/super-staff-bros-4" target="_blank">Super Staff Bros 4 Guide</a> or use /ssb to find out!</b></div>`);
|
|
@@ -2184,7 +2241,7 @@ exports.Formats = [
|
|
|
2184
2241
|
],
|
|
2185
2242
|
mod: 'gen7',
|
|
2186
2243
|
team: 'random',
|
|
2187
|
-
ruleset: ['Obtainable', 'Sleep Clause Mod', 'HP Percentage Mod', 'Cancel Mod'],
|
|
2244
|
+
ruleset: ['Obtainable', 'Sleep Clause Mod', 'HP Percentage Mod', 'Cancel Mod', 'Mega Rayquaza Clause'],
|
|
2188
2245
|
},
|
|
2189
2246
|
{
|
|
2190
2247
|
name: "[Gen 7] Random Doubles Battle",
|
|
@@ -2240,7 +2297,7 @@ exports.Formats = [
|
|
|
2240
2297
|
name: "[Gen 6] Random Battle",
|
|
2241
2298
|
mod: 'gen6',
|
|
2242
2299
|
team: 'random',
|
|
2243
|
-
ruleset: ['Obtainable', 'Sleep Clause Mod', 'HP Percentage Mod', 'Cancel Mod'],
|
|
2300
|
+
ruleset: ['Obtainable', 'Sleep Clause Mod', 'HP Percentage Mod', 'Cancel Mod', 'Mega Rayquaza Clause'],
|
|
2244
2301
|
},
|
|
2245
2302
|
{
|
|
2246
2303
|
name: "[Gen 6] Battle Factory",
|
|
@@ -2316,33 +2373,41 @@ exports.Formats = [
|
|
|
2316
2373
|
column: 3,
|
|
2317
2374
|
},
|
|
2318
2375
|
{
|
|
2319
|
-
name: "[Gen
|
|
2376
|
+
name: "[Gen 2] Ubers",
|
|
2320
2377
|
threads: [
|
|
2321
|
-
`• <a href="https://www.smogon.com/
|
|
2322
|
-
`• <a href="https://www.smogon.com/forums/threads/3598164/">ORAS UU Viability Rankings</a>`,
|
|
2378
|
+
`• <a href="https://www.smogon.com/forums/posts/8286282/">GSC Ubers</a>`,
|
|
2323
2379
|
],
|
|
2324
|
-
mod: '
|
|
2380
|
+
mod: 'gen2',
|
|
2325
2381
|
// searchShow: false,
|
|
2326
|
-
ruleset: ['
|
|
2327
|
-
banlist: ['OU', 'UUBL', 'Drizzle', 'Drought'],
|
|
2382
|
+
ruleset: ['Standard'],
|
|
2328
2383
|
},
|
|
2329
2384
|
{
|
|
2330
|
-
name: "[Gen
|
|
2331
|
-
|
|
2385
|
+
name: "[Gen 3] 1v1",
|
|
2386
|
+
desc: `Bring three Pokémon to Team Preview and choose one to battle.`,
|
|
2387
|
+
threads: [
|
|
2388
|
+
`• <a href="https://www.smogon.com/forums/posts/8031456/">ADV 1v1</a>`,
|
|
2389
|
+
],
|
|
2390
|
+
mod: 'gen3',
|
|
2332
2391
|
// searchShow: false,
|
|
2333
|
-
ruleset: [
|
|
2392
|
+
ruleset: [
|
|
2393
|
+
'Picked Team Size = 1', 'Max Team Size = 3',
|
|
2394
|
+
'[Gen 3] OU', 'Accuracy Moves Clause', 'Sleep Moves Clause', 'Team Preview', '!Freeze Clause Mod',
|
|
2395
|
+
],
|
|
2396
|
+
banlist: ['Clefable', 'Slaking', 'Snorlax', 'Suicune', 'Destiny Bond', 'Explosion', 'Ingrain', 'Perish Song', 'Self-Destruct', 'Bright Powder', 'Focus Band', 'King\'s Rock', 'Lax Incense', 'Quick Claw'],
|
|
2397
|
+
unbanlist: ['Mr. Mime', 'Wobbuffet', 'Wynaut', 'Sand Veil'],
|
|
2334
2398
|
},
|
|
2335
2399
|
{
|
|
2336
|
-
name: "[Gen
|
|
2400
|
+
name: "[Gen 1] Stadium OU",
|
|
2337
2401
|
threads: [
|
|
2338
|
-
`• <a href="https://www.smogon.com/forums/threads/
|
|
2339
|
-
`• <a href="https://www.smogon.com/forums/threads/3645873/">USM RU Viability Rankings</a>`,
|
|
2402
|
+
`• <a href="https://www.smogon.com/forums/threads/3685877/">Stadium OU Viability Rankings</a>`,
|
|
2340
2403
|
],
|
|
2341
|
-
mod: '
|
|
2404
|
+
mod: 'gen1stadium',
|
|
2342
2405
|
// searchShow: false,
|
|
2343
|
-
ruleset: ['
|
|
2344
|
-
banlist: ['
|
|
2345
|
-
|
|
2406
|
+
ruleset: ['Standard', 'Team Preview'],
|
|
2407
|
+
banlist: ['Uber',
|
|
2408
|
+
'Nidoking + Fury Attack + Thrash', 'Exeggutor + Poison Powder + Stomp', 'Exeggutor + Sleep Powder + Stomp',
|
|
2409
|
+
'Exeggutor + Stun Spore + Stomp', 'Jolteon + Focus Energy + Thunder Shock', 'Flareon + Focus Energy + Ember',
|
|
2410
|
+
],
|
|
2346
2411
|
},
|
|
2347
2412
|
// Past Gens OU
|
|
2348
2413
|
///////////////////////////////////////////////////////////////////
|
|
@@ -2390,7 +2455,7 @@ exports.Formats = [
|
|
|
2390
2455
|
`• <a href="https://www.smogon.com/forums/threads/3683332/">DPP OU Viability Rankings</a>`,
|
|
2391
2456
|
],
|
|
2392
2457
|
mod: 'gen4',
|
|
2393
|
-
ruleset: ['Standard'],
|
|
2458
|
+
ruleset: ['Standard', 'Freeze Clause Mod'],
|
|
2394
2459
|
banlist: ['AG', 'Uber', 'Arena Trap', 'Sand Veil', 'Swinub + Snow Cloak', 'Piloswine + Snow Cloak', 'Mamoswine + Snow Cloak', 'Soul Dew', 'Baton Pass', 'Swagger'],
|
|
2395
2460
|
},
|
|
2396
2461
|
{
|
|
@@ -2400,7 +2465,7 @@ exports.Formats = [
|
|
|
2400
2465
|
`• <a href="https://www.smogon.com/forums/threads/3503019/">ADV OU Viability Rankings</a>`,
|
|
2401
2466
|
],
|
|
2402
2467
|
mod: 'gen3',
|
|
2403
|
-
ruleset: ['Standard', 'One Boost Passer Clause'],
|
|
2468
|
+
ruleset: ['Standard', 'One Boost Passer Clause', 'Freeze Clause Mod'],
|
|
2404
2469
|
banlist: ['Uber', 'Sand Veil', 'Soundproof', 'Assist', 'Baton Pass + Block', 'Baton Pass + Mean Look', 'Baton Pass + Spider Web', 'Smeargle + Ingrain'],
|
|
2405
2470
|
},
|
|
2406
2471
|
{
|
|
@@ -2572,6 +2637,18 @@ exports.Formats = [
|
|
|
2572
2637
|
ruleset: ['[Gen 7] OU'],
|
|
2573
2638
|
banlist: ['OU', 'UUBL', 'Drizzle', 'Drought', 'Kommonium Z', 'Mewnium Z'],
|
|
2574
2639
|
},
|
|
2640
|
+
{
|
|
2641
|
+
name: "[Gen 7] RU",
|
|
2642
|
+
threads: [
|
|
2643
|
+
`• <a href="https://www.smogon.com/forums/threads/3645338/">USM RU Sample Teams</a>`,
|
|
2644
|
+
`• <a href="https://www.smogon.com/forums/threads/3645873/">USM RU Viability Rankings</a>`,
|
|
2645
|
+
],
|
|
2646
|
+
mod: 'gen7',
|
|
2647
|
+
searchShow: false,
|
|
2648
|
+
ruleset: ['[Gen 7] UU'],
|
|
2649
|
+
banlist: ['UU', 'RUBL', 'Mimikyu', 'Aurora Veil'],
|
|
2650
|
+
unbanlist: ['Drought'],
|
|
2651
|
+
},
|
|
2575
2652
|
{
|
|
2576
2653
|
name: "[Gen 7] NU",
|
|
2577
2654
|
threads: [
|
|
@@ -2841,6 +2918,17 @@ exports.Formats = [
|
|
|
2841
2918
|
searchShow: false,
|
|
2842
2919
|
ruleset: ['Standard', 'Swagger Clause', 'Mega Rayquaza Clause'],
|
|
2843
2920
|
},
|
|
2921
|
+
{
|
|
2922
|
+
name: "[Gen 6] UU",
|
|
2923
|
+
threads: [
|
|
2924
|
+
`• <a href="https://www.smogon.com/dex/xy/formats/uu/">ORAS UU Banlist</a>`,
|
|
2925
|
+
`• <a href="https://www.smogon.com/forums/threads/3598164/">ORAS UU Viability Rankings</a>`,
|
|
2926
|
+
],
|
|
2927
|
+
mod: 'gen6',
|
|
2928
|
+
searchShow: false,
|
|
2929
|
+
ruleset: ['[Gen 6] OU'],
|
|
2930
|
+
banlist: ['OU', 'UUBL', 'Drizzle', 'Drought'],
|
|
2931
|
+
},
|
|
2844
2932
|
{
|
|
2845
2933
|
name: "[Gen 6] RU",
|
|
2846
2934
|
threads: [
|
|
@@ -2957,7 +3045,7 @@ exports.Formats = [
|
|
|
2957
3045
|
mod: 'gen6',
|
|
2958
3046
|
searchShow: false,
|
|
2959
3047
|
ruleset: ['[Gen 6] OU', '+CAP'],
|
|
2960
|
-
banlist: ['Aurumoth', 'Cawmodore'
|
|
3048
|
+
banlist: ['Aurumoth', 'Cawmodore'],
|
|
2961
3049
|
},
|
|
2962
3050
|
{
|
|
2963
3051
|
name: "[Gen 6] Battle Spot Singles",
|
|
@@ -3135,7 +3223,7 @@ exports.Formats = [
|
|
|
3135
3223
|
mod: 'gen5',
|
|
3136
3224
|
searchShow: false,
|
|
3137
3225
|
ruleset: ['[Gen 5] NU', 'Sleep Moves Clause'],
|
|
3138
|
-
banlist: ['NU', 'PUBL'],
|
|
3226
|
+
banlist: ['NU', 'PUBL', 'Damp Rock'],
|
|
3139
3227
|
},
|
|
3140
3228
|
{
|
|
3141
3229
|
name: "[Gen 5] LC",
|
|
@@ -3171,7 +3259,7 @@ exports.Formats = [
|
|
|
3171
3259
|
searchShow: false,
|
|
3172
3260
|
ruleset: [
|
|
3173
3261
|
'Picked Team Size = 1', 'Max Team Size = 3',
|
|
3174
|
-
'Standard', 'Baton Pass Clause', 'Swagger Clause', 'Accuracy Moves Clause',
|
|
3262
|
+
'Standard', 'Baton Pass Clause', 'Swagger Clause', 'Accuracy Moves Clause', 'Sleep Moves Clause',
|
|
3175
3263
|
],
|
|
3176
3264
|
banlist: ['Uber', 'Cottonee', 'Dragonite', 'Jirachi', 'Kyurem-Black', 'Mew', 'Togekiss', 'Whimsicott', 'Victini', 'Bright Powder', 'Focus Band', 'Focus Sash', 'Lax Incense', 'Quick Claw', 'Soul Dew', 'Perish Song'],
|
|
3177
3265
|
unbanlist: ['Genesect', 'Landorus', 'Manaphy', 'Thundurus', 'Tornadus-Therian'],
|
|
@@ -3289,7 +3377,7 @@ exports.Formats = [
|
|
|
3289
3377
|
],
|
|
3290
3378
|
mod: 'gen4',
|
|
3291
3379
|
searchShow: false,
|
|
3292
|
-
ruleset: ['[Gen 4] OU'],
|
|
3380
|
+
ruleset: ['[Gen 4] OU', '!Freeze Clause Mod'],
|
|
3293
3381
|
banlist: ['OU', 'UUBL'],
|
|
3294
3382
|
unbanlist: ['Arena Trap', 'Swagger'],
|
|
3295
3383
|
},
|
|
@@ -3335,6 +3423,12 @@ exports.Formats = [
|
|
|
3335
3423
|
'Berry Juice', 'Deep Sea Tooth', 'Dragon Rage', 'Sonic Boom', 'Swagger',
|
|
3336
3424
|
],
|
|
3337
3425
|
},
|
|
3426
|
+
{
|
|
3427
|
+
name: "[Gen 4] Anything Goes",
|
|
3428
|
+
mod: 'gen4',
|
|
3429
|
+
searchShow: false,
|
|
3430
|
+
ruleset: ['Obtainable', 'Arceus EV Limit', 'Endless Battle Clause', 'HP Percentage Mod', 'Cancel Mod'],
|
|
3431
|
+
},
|
|
3338
3432
|
{
|
|
3339
3433
|
name: "[Gen 4] 1v1",
|
|
3340
3434
|
desc: `Bring three Pokémon to Team Preview and choose one to battle.`,
|
|
@@ -3345,7 +3439,7 @@ exports.Formats = [
|
|
|
3345
3439
|
searchShow: false,
|
|
3346
3440
|
ruleset: [
|
|
3347
3441
|
'Picked Team Size = 1', 'Max Team Size = 3',
|
|
3348
|
-
'[Gen 4] OU', 'Accuracy Moves Clause', 'Sleep Moves Clause', 'Team Preview',
|
|
3442
|
+
'[Gen 4] OU', 'Accuracy Moves Clause', 'Sleep Moves Clause', 'Team Preview', '!Freeze Clause Mod',
|
|
3349
3443
|
],
|
|
3350
3444
|
banlist: ['Latias', 'Machamp', 'Porygon-Z', 'Shaymin', 'Snorlax', 'Togekiss', 'Focus Sash', 'Destiny Bond', 'Explosion', 'Perish Song', 'Self-Destruct'],
|
|
3351
3445
|
unbanlist: ['Wobbuffet', 'Wynaut', 'Sand Veil', 'Swagger'],
|
|
@@ -3387,7 +3481,7 @@ exports.Formats = [
|
|
|
3387
3481
|
mod: 'gen4',
|
|
3388
3482
|
gameType: 'doubles',
|
|
3389
3483
|
searchShow: false,
|
|
3390
|
-
ruleset: ['[Gen 4] OU'],
|
|
3484
|
+
ruleset: ['[Gen 4] OU', '!Freeze Clause Mod'],
|
|
3391
3485
|
banlist: ['Explosion'],
|
|
3392
3486
|
unbanlist: ['Garchomp', 'Latias', 'Latios', 'Manaphy', 'Mew', 'Salamence', 'Wobbuffet', 'Wynaut', 'Swagger'],
|
|
3393
3487
|
},
|
|
@@ -3442,9 +3536,8 @@ exports.Formats = [
|
|
|
3442
3536
|
],
|
|
3443
3537
|
mod: 'gen3',
|
|
3444
3538
|
searchShow: false,
|
|
3445
|
-
ruleset: ['Standard'
|
|
3446
|
-
banlist: ['Uber', 'OU', 'UUBL', 'Smeargle + Ingrain', 'Baton Pass'],
|
|
3447
|
-
unbanlist: ['Scyther'],
|
|
3539
|
+
ruleset: ['Standard'],
|
|
3540
|
+
banlist: ['Uber', 'OU', 'UUBL', 'Smeargle + Ingrain', 'Arena Trap', 'Bright Powder', 'Lax Incense', 'Baton Pass', 'Swagger'],
|
|
3448
3541
|
},
|
|
3449
3542
|
{
|
|
3450
3543
|
name: "[Gen 3] NU",
|
|
@@ -3453,9 +3546,8 @@ exports.Formats = [
|
|
|
3453
3546
|
],
|
|
3454
3547
|
mod: 'gen3',
|
|
3455
3548
|
searchShow: false,
|
|
3456
|
-
ruleset: ['
|
|
3457
|
-
banlist: ['UU'],
|
|
3458
|
-
unbanlist: ['Baton Pass'],
|
|
3549
|
+
ruleset: ['Standard'],
|
|
3550
|
+
banlist: ['Uber', 'OU', 'UUBL', 'UU', 'Smeargle + Ingrain'],
|
|
3459
3551
|
},
|
|
3460
3552
|
{
|
|
3461
3553
|
name: "[Gen 3] Doubles OU",
|
|
@@ -3469,21 +3561,6 @@ exports.Formats = [
|
|
|
3469
3561
|
banlist: ['Uber'],
|
|
3470
3562
|
unbanlist: ['Deoxys-Speed', 'Wobbuffet', 'Wynaut'],
|
|
3471
3563
|
},
|
|
3472
|
-
{
|
|
3473
|
-
name: "[Gen 3] 1v1",
|
|
3474
|
-
desc: `Bring three Pokémon to Team Preview and choose one to battle.`,
|
|
3475
|
-
threads: [
|
|
3476
|
-
`• <a href="https://www.smogon.com/forums/posts/8031456/">ADV 1v1</a>`,
|
|
3477
|
-
],
|
|
3478
|
-
mod: 'gen3',
|
|
3479
|
-
searchShow: false,
|
|
3480
|
-
ruleset: [
|
|
3481
|
-
'Picked Team Size = 1', 'Max Team Size = 3',
|
|
3482
|
-
'[Gen 3] OU', 'Accuracy Moves Clause', 'Sleep Moves Clause', 'Team Preview',
|
|
3483
|
-
],
|
|
3484
|
-
banlist: ['Clefable', 'Slaking', 'Snorlax', 'Suicune', 'Destiny Bond', 'Explosion', 'Ingrain', 'Perish Song', 'Self-Destruct', 'Bright Powder', 'Focus Band', 'King\'s Rock', 'Lax Incense', 'Quick Claw'],
|
|
3485
|
-
unbanlist: ['Mr. Mime', 'Wobbuffet', 'Wynaut', 'Sand Veil'],
|
|
3486
|
-
},
|
|
3487
3564
|
{
|
|
3488
3565
|
name: "[Gen 3] Custom Game",
|
|
3489
3566
|
mod: 'gen3',
|
|
@@ -3500,15 +3577,6 @@ exports.Formats = [
|
|
|
3500
3577
|
debug: true,
|
|
3501
3578
|
ruleset: ['HP Percentage Mod', 'Cancel Mod', 'Max Team Size = 24', 'Max Move Count = 24', 'Max Level = 9999', 'Default Level = 100'],
|
|
3502
3579
|
},
|
|
3503
|
-
{
|
|
3504
|
-
name: "[Gen 2] Ubers",
|
|
3505
|
-
threads: [
|
|
3506
|
-
`• <a href="https://www.smogon.com/forums/posts/8286282/">GSC Ubers</a>`,
|
|
3507
|
-
],
|
|
3508
|
-
mod: 'gen2',
|
|
3509
|
-
searchShow: false,
|
|
3510
|
-
ruleset: ['Standard'],
|
|
3511
|
-
},
|
|
3512
3580
|
{
|
|
3513
3581
|
name: "[Gen 2] UU",
|
|
3514
3582
|
threads: [`• <a href="https://www.smogon.com/forums/threads/3576710/">GSC UU</a>`],
|
|
@@ -3588,7 +3656,7 @@ exports.Formats = [
|
|
|
3588
3656
|
],
|
|
3589
3657
|
mod: 'gen1',
|
|
3590
3658
|
searchShow: false,
|
|
3591
|
-
ruleset: ['[Gen 1] OU'],
|
|
3659
|
+
ruleset: ['[Gen 1] OU', 'APT Clause'],
|
|
3592
3660
|
banlist: ['OU', 'UUBL'],
|
|
3593
3661
|
},
|
|
3594
3662
|
{
|
|
@@ -3622,19 +3690,6 @@ exports.Formats = [
|
|
|
3622
3690
|
],
|
|
3623
3691
|
banlist: ['Uber'],
|
|
3624
3692
|
},
|
|
3625
|
-
{
|
|
3626
|
-
name: "[Gen 1] Stadium OU",
|
|
3627
|
-
threads: [
|
|
3628
|
-
`• <a href="https://www.smogon.com/forums/threads/3685877/">Stadium OU Viability Rankings</a>`,
|
|
3629
|
-
],
|
|
3630
|
-
mod: 'gen1stadium',
|
|
3631
|
-
searchShow: false,
|
|
3632
|
-
ruleset: ['Standard', 'Team Preview'],
|
|
3633
|
-
banlist: ['Uber',
|
|
3634
|
-
'Nidoking + Fury Attack + Thrash', 'Exeggutor + Poison Powder + Stomp', 'Exeggutor + Sleep Powder + Stomp',
|
|
3635
|
-
'Exeggutor + Stun Spore + Stomp', 'Jolteon + Focus Energy + Thunder Shock', 'Flareon + Focus Energy + Ember',
|
|
3636
|
-
],
|
|
3637
|
-
},
|
|
3638
3693
|
{
|
|
3639
3694
|
name: "[Gen 1] Tradebacks OU",
|
|
3640
3695
|
desc: `RBY OU with movepool additions from the Time Capsule.`,
|