@pkmn/sim 0.5.5 → 0.5.6

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.
Files changed (38) hide show
  1. package/build/config/formats.js +260 -239
  2. package/build/config/formats.js.map +1 -1
  3. package/build/data/aliases.js +4 -4
  4. package/build/data/aliases.js.map +1 -1
  5. package/build/data/formats-data.js +118 -5
  6. package/build/data/formats-data.js.map +1 -1
  7. package/build/data/mods/gen3/formats-data.js +1 -1
  8. package/build/data/mods/gen3/formats-data.js.map +1 -1
  9. package/build/data/mods/gen5/formats-data.js +1 -1
  10. package/build/data/mods/gen5/formats-data.js.map +1 -1
  11. package/build/data/mods/gen6/formats-data.js +3 -2
  12. package/build/data/mods/gen6/formats-data.js.map +1 -1
  13. package/build/data/mods/gen7/formats-data.js +2 -1
  14. package/build/data/mods/gen7/formats-data.js.map +1 -1
  15. package/build/data/pokedex.js +479 -10
  16. package/build/data/pokedex.js.map +1 -1
  17. package/build/data/rulesets.js +3 -1
  18. package/build/data/rulesets.js.map +1 -1
  19. package/build/sim/battle.js +23 -22
  20. package/build/sim/battle.js.map +1 -1
  21. package/build/sim/dex-species.js +5 -2
  22. package/build/sim/dex-species.js.map +1 -1
  23. package/build/sim/exported-global-types.d.ts +1 -0
  24. package/build/sim/global-types.d.ts +1 -0
  25. package/config/formats.ts +263 -242
  26. package/data/aliases.ts +4 -4
  27. package/data/formats-data.ts +118 -5
  28. package/data/mods/gen3/formats-data.ts +1 -1
  29. package/data/mods/gen5/formats-data.ts +1 -1
  30. package/data/mods/gen6/formats-data.ts +3 -2
  31. package/data/mods/gen7/formats-data.ts +2 -1
  32. package/data/pokedex.ts +479 -10
  33. package/data/rulesets.ts +2 -1
  34. package/package.json +2 -2
  35. package/sim/battle.ts +24 -23
  36. package/sim/dex-species.ts +5 -2
  37. package/sim/exported-global-types.ts +1 -0
  38. package/sim/global-types.ts +1 -0
package/config/formats.ts CHANGED
@@ -285,14 +285,6 @@ export const Formats: FormatList = [
285
285
  name: "[Gen 8] Battle Stadium Singles",
286
286
 
287
287
  mod: 'gen8',
288
- ruleset: ['Flat Rules', '!! Adjust Level = 50', 'Min Source Gen = 8', 'Limit One Restricted'],
289
- restricted: ['Restricted Legendary'],
290
- },
291
- {
292
- name: "[Gen 8] Battle Stadium Singles Series 12",
293
-
294
- mod: 'gen8',
295
- searchShow: false,
296
288
  ruleset: ['Flat Rules', '!! Adjust Level = 50', 'Min Source Gen = 8', 'Limit Two Restricted'],
297
289
  restricted: ['Restricted Legendary'],
298
290
  },
@@ -377,20 +369,7 @@ export const Formats: FormatList = [
377
369
  restricted: ['Restricted Legendary'],
378
370
  },
379
371
  {
380
- name: "[Gen 8] VGC 2021 Series 11",
381
- threads: [
382
- `&bullet; <a href="https://www.smogon.com/forums/threads/3677186/">VGC 2021 Series 11 Metagame Discussion</a>`,
383
- `&bullet; <a href="https://www.smogon.com/forums/threads/3693427/">VGC 2021 Series 11 Sample Teams</a>`,
384
- `&bullet; <a href="https://www.smogon.com/forums/threads/3693284/">VGC 2021 Series 11 Viability Rankings</a>`,
385
- ],
386
-
387
- mod: 'gen8',
388
- gameType: 'doubles',
389
- ruleset: ['Flat Rules', '!! Adjust Level = 50', 'Min Source Gen = 8', 'VGC Timer', 'Limit One Restricted'],
390
- restricted: ['Restricted Legendary'],
391
- },
392
- {
393
- name: "[Gen 8] VGC 2021 Series 9",
372
+ name: "[Gen 8] VGC 2021",
394
373
 
395
374
  mod: 'gen8',
396
375
  gameType: 'doubles',
@@ -501,7 +480,7 @@ export const Formats: FormatList = [
501
480
  'Genesect', 'Gengar-Mega', 'Giratina', 'Giratina-Origin', 'Groudon', 'Ho-Oh', 'Kangaskhan-Mega', 'Kyogre', 'Kyurem-Black',
502
481
  'Kyurem-White', 'Landorus-Base', 'Lucario-Mega', 'Lugia', 'Lunala', 'Magearna', 'Marshadow', 'Metagross-Mega', 'Mewtwo',
503
482
  'Naganadel', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane', 'Necrozma-Ultra', 'Palkia', 'Pheromosa', 'Rayquaza', 'Reshiram',
504
- 'Salamence-Mega', 'Shaymin-Sky', 'Solgaleo', 'Spectrier', 'Tornadus-Therian', 'Urshifu-Base', 'Xerneas', 'Yveltal', 'Zacian',
483
+ 'Salamence-Mega', 'Shaymin-Sky', 'Solgaleo', 'Spectrier', 'Urshifu-Base', 'Xerneas', 'Yveltal', 'Zacian',
505
484
  'Zacian-Crowned', 'Zamazenta', 'Zamazenta-Crowned', 'Zekrom', 'Zygarde-Base', 'Zygarde-Complete', 'Arena Trap', 'Moody',
506
485
  'Power Construct', 'Sand Veil', 'Shadow Tag', 'Snow Cloak', 'Bright Powder', 'King\'s Rock', 'Lax Incense', 'Razor Fang',
507
486
  'Quick Claw', 'Baton Pass',
@@ -527,6 +506,8 @@ export const Formats: FormatList = [
527
506
  'Drizzle', 'Drought',
528
507
  // Slowbronite is banned so it doesn't validate on Galarian Slowbro
529
508
  'Slowbronite',
509
+ // NatDex suspect
510
+ 'Tornadus-Therian',
530
511
  ],
531
512
  // Used to distinguish UU from below UU in the client
532
513
  restricted: [
@@ -654,80 +635,134 @@ export const Formats: FormatList = [
654
635
  column: 2,
655
636
  },
656
637
  {
657
- name: "[Gen 8] Pokebilities",
658
- desc: `Pok&eacute;mon have all of their released abilities simultaneously.`,
638
+ name: "[Gen 8] Trademarked",
639
+ desc: `Sacrifice your Pok&eacute;mon's ability for a status move that activates on switch-in.`,
659
640
  threads: [
660
- `&bullet; <a href="https://www.smogon.com/forums/threads/3679692/">Pok&eacute;bilities</a>`,
641
+ `&bullet; <a href="https://www.smogon.com/forums/threads/3656980/">Trademarked</a>`,
661
642
  ],
662
- mod: 'pokebilities',
643
+
644
+ mod: 'gen8',
645
+ // searchShow: false,
663
646
  ruleset: ['Standard', 'Dynamax Clause'],
664
647
  banlist: [
665
- 'Calyrex-Ice', 'Calyrex-Shadow', 'Cinderace', 'Conkeldurr', 'Darmanitan-Galar', 'Dialga', 'Dracovish', 'Dracozolt',
666
- 'Eternatus', 'Excadrill', 'Genesect', 'Giratina', 'Giratina-Origin', 'Groudon', 'Ho-Oh', 'Kyogre', 'Kyurem-Black',
667
- 'Kyurem-White', 'Landorus-Base', 'Lugia', 'Lunala', 'Magearna', 'Marshadow', 'Mewtwo', 'Naganadel', 'Necrozma-Dawn-Wings',
668
- 'Necrozma-Dusk-Mane', 'Palkia', 'Pheromosa', 'Porygon-Z', 'Rayquaza', 'Reshiram', 'Solgaleo', 'Spectrier', 'Urshifu-Base',
669
- 'Xerneas', 'Yveltal', 'Zacian', 'Zacian-Crowned', 'Zamazenta-Base', 'Zekrom', 'Zygarde-Base', 'Power Construct',
670
- 'Baton Pass', 'King\'s Rock',
671
- // Moody users
672
- 'Glalie', 'Octillery', 'Remoraid', 'Snorunt',
673
- // Shadow Tag/Arena Trap
674
- 'Diglett-Base', 'Dugtrio-Base', 'Gothita', 'Gothitelle', 'Gothorita', 'Trapinch', 'Wobbuffet', 'Wynaut',
648
+ 'Calyrex-Ice', 'Calyrex-Shadow', 'Darmanitan-Galar', 'Dialga', 'Dracovish', 'Dragapult', 'Eternatus', 'Kyurem-Black', 'Kyurem-White',
649
+ 'Giratina', 'Giratina-Origin', 'Genesect', 'Groudon', 'Ho-Oh', 'Kartana', 'Kyogre', 'Lugia', 'Lunala', 'Magearna', 'Marowak-Alola',
650
+ 'Marshadow', 'Melmetal', 'Mewtwo', 'Naganadel', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane', 'Palkia', 'Pheromosa', 'Rayquaza',
651
+ 'Reshiram', 'Solgaleo', 'Urshifu-Base', 'Xerneas', 'Yveltal', 'Zacian', 'Zacian-Crowned', 'Zamazenta', 'Zamazenta-Crowned', 'Zekrom',
652
+ 'Zygarde-Base', 'Arena Trap', 'Moody', 'Power Construct', 'Shadow Tag', 'Baton Pass',
675
653
  ],
676
- onBegin() {
677
- for (const pokemon of this.getAllPokemon()) {
678
- if (pokemon.ability === this.toID(pokemon.species.abilities['S'])) {
679
- continue;
654
+ restricted: [
655
+ 'Baneful Bunker', 'Block', 'Copycat', 'Corrosive Gas', 'Detect', 'Destiny Bond', 'Disable', 'Encore', 'Fairy Lock', 'Hypnosis', 'Ingrain',
656
+ 'Instruct', 'Lovely Kiss', 'King\'s Shield', 'Mat Block', 'Mean Look', 'Memento', 'move:Metronome', 'Obstruct', 'Octolock', 'Nature Power',
657
+ 'Parting Shot', 'Psycho Shift', 'Protect', 'Roar', 'Sing', 'Skill Swap', 'Sleep Powder', 'Sleep Talk', 'Spiky Shield', 'Spore', 'Substitute',
658
+ 'Teleport', 'Whirlwind', 'Wish', 'Yawn',
659
+ ],
660
+ onValidateTeam(team, format, teamHas) {
661
+ const problems = [];
662
+ for (const trademark in teamHas.trademarks) {
663
+ if (teamHas.trademarks[trademark] > 1) {
664
+ problems.push(`You are limited to 1 of each Trademark.`, `(You have ${teamHas.trademarks[trademark]} Pok\u00e9mon with ${trademark} as a Trademark.)`);
680
665
  }
681
- pokemon.m.innates = Object.keys(pokemon.species.abilities)
682
- .filter(key => key !== 'S' && (key !== 'H' || !pokemon.species.unreleasedHidden))
683
- .map(key => this.toID(pokemon.species.abilities[key as "0" | "1" | "H" | "S"]))
684
- .filter(ability => ability !== pokemon.ability);
685
666
  }
667
+ return problems;
686
668
  },
687
- onSwitchInPriority: 2,
688
- onSwitchIn(pokemon) {
689
- if (pokemon.m.innates) {
690
- for (const innate of pokemon.m.innates) {
691
- pokemon.addVolatile("ability:" + innate, pokemon);
692
- }
669
+ validateSet(set, teamHas) {
670
+ const dex = this.dex;
671
+ const ability = dex.moves.get(set.ability);
672
+ if (!ability.exists) { // Not even a real move
673
+ return this.validateSet(set, teamHas);
693
674
  }
694
- },
695
- onAfterMega(pokemon) {
696
- for (const innate of Object.keys(pokemon.volatiles).filter(i => i.startsWith('ability:'))) {
697
- pokemon.removeVolatile(innate);
675
+ // Absolute trademark bans
676
+ if (ability.category !== 'Status') {
677
+ return [`${ability.name} is not a status move, and cannot be used as a trademark.`];
698
678
  }
699
- pokemon.m.innates = undefined;
679
+ if (ability.forceSwitch || ability.selfSwitch) {
680
+ return [
681
+ `Force-switching and self-switching moves are banned from being used as trademarks.`,
682
+ `(${ability.name} is a ${ability.forceSwitch ? 'force' : 'self'}-switching move.)`,
683
+ ];
684
+ }
685
+ const irrevokablyRestricted = [
686
+ 'Assist', 'Copycat', 'Metronome', 'Mirror Move', 'Sleep Talk', // Could call another unsafe trademark
687
+ 'Skill Swap', // Self-propagates indefinitely
688
+ ];
689
+ if (irrevokablyRestricted.includes(ability.name)) {
690
+ return [`${ability.name} cannot safely function as a trademark.`];
691
+ }
692
+ // Contingent trademark bans
693
+ if (this.ruleTable.isRestricted(`move:${ability.id}`)) {
694
+ return [`${ability.name} is restricted from being used as a trademark.`];
695
+ }
696
+ if (set.moves.map(this.toID).includes(ability.id)) {
697
+ return [`${set.name} may not use ${ability.name} as both a trademark and one of its moves simultaneously.`];
698
+ }
699
+ const customRules = this.format.customRules || [];
700
+ if (!customRules.includes('!obtainableabilities')) customRules.push('!obtainableabilities');
701
+
702
+ const TeamValidator: typeof import('../sim/team-validator').TeamValidator =
703
+ require('../sim/team-validator').TeamValidator;
704
+
705
+ const validator = new TeamValidator(dex.formats.get(`${this.format.id}@@@${customRules.join(',')}`));
706
+ const moves = set.moves;
707
+ set.moves = [ability.id];
708
+ set.ability = dex.species.get(set.species).abilities['0'];
709
+ let problems = validator.validateSet(set, {}) || [];
710
+ if (problems.length) return problems;
711
+ set.moves = moves;
712
+ set.ability = dex.species.get(set.species).abilities['0'];
713
+ problems = problems.concat(validator.validateSet(set, teamHas) || []);
714
+ set.ability = ability.id;
715
+ if (!teamHas.trademarks) teamHas.trademarks = {};
716
+ teamHas.trademarks[ability.name] = (teamHas.trademarks[ability.name] || 0) + 1;
717
+ return problems.length ? problems : null;
718
+ },
719
+ pokemon: {
720
+ getAbility() {
721
+ const move = this.battle.dex.moves.get(this.battle.toID(this.ability));
722
+ if (!move.exists) return Object.getPrototypeOf(this).getAbility.call(this);
723
+ return {
724
+ id: move.id,
725
+ name: move.name,
726
+ onStart(this: Battle, pokemon: Pokemon) {
727
+ this.add('-activate', pokemon, 'ability: ' + move.name);
728
+ this.actions.useMove(move, pokemon);
729
+ },
730
+ toString() {
731
+ return "";
732
+ },
733
+ };
734
+ },
700
735
  },
701
736
  },
702
737
  {
703
- name: "[Gen 8] Camomons",
704
- desc: `Pok&eacute;mon change type to match their first two moves.`,
738
+ name: "[Gen 8] Linked",
739
+ desc: `The first two moves in a Pok&eacute;mon's moveset are used simultaneously.`,
705
740
  threads: [
706
- `&bullet; <a href="https://www.smogon.com/forums/threads/3656413/">Camomons</a>`,
741
+ `&bullet; <a href="https://www.smogon.com/forums/threads/3660421/">Linked</a>`,
707
742
  ],
708
743
 
709
- mod: 'gen8',
710
- // searchShow: false,
711
- ruleset: ['Obtainable', 'Species Clause', 'Nickname Clause', 'OHKO Clause', 'Evasion Moves Clause', 'Team Preview', 'HP Percentage Mod', 'Cancel Mod', 'Dynamax Clause', 'Sleep Clause Mod', 'Endless Battle Clause'],
744
+ mod: 'linked',
745
+ ruleset: ['Standard', 'Dynamax Clause'],
712
746
  banlist: [
713
- 'Calyrex-Ice', 'Calyrex-Shadow', 'Darmanitan-Galar', 'Dialga', 'Dracovish', 'Dragonite', 'Eternatus', 'Genesect', 'Giratina', 'Giratina-Origin',
714
- 'Groudon', 'Ho-Oh', 'Hydreigon', 'Kartana', 'Kyogre', 'Kyurem', 'Kyurem-Black', 'Kyurem-White', 'Landorus-Base', 'Latias', 'Latios', 'Lugia',
715
- 'Lunala', 'Marshadow', 'Mew', 'Mewtwo', 'Naganadel', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane', 'Palkia', 'Pheromosa', 'Rayquaza', 'Reshiram',
716
- 'Reuniclus', 'Shedinja', 'Slowking-Galar', 'Solgaleo', 'Spectrier', 'Tornadus-Therian', 'Volcarona', 'Xerneas', 'Yveltal', 'Zacian', 'Zacian-Crowned',
717
- 'Zamazenta', 'Zamazenta-Crowned', 'Zekrom', 'Zeraora', 'Zygarde-Base', 'Arena Trap', 'Moody', 'Power Construct', 'Shadow Tag', 'Baton Pass',
747
+ 'Calyrex-Ice', 'Calyrex-Shadow', 'Cinderace', 'Darmanitan-Galar', 'Dialga', 'Dracovish', 'Eternatus', 'Genesect', 'Giratina', 'Giratina-Origin', 'Groudon', 'Ho-Oh',
748
+ 'Kyogre', 'Kyurem', 'Kyurem-Black', 'Kyurem-White', 'Landorus-Base', 'Lugia', 'Lunala', 'Magearna', 'Marshadow', 'Mewtwo', 'Naganadel', 'Necrozma-Dawn-Wings',
749
+ 'Necrozma-Dusk-Mane', 'Palkia', 'Pheromosa', 'Rayquaza', 'Reshiram', 'Solgaleo', 'Spectrier', 'Urshifu-Base', 'Xerneas', 'Yveltal', 'Zacian', 'Zacian-Crowned',
750
+ 'Zamazenta', 'Zamazenta-Crowned', 'Zekrom', 'Zygarde-Base', 'Zygarde-Complete', 'Arena Trap', 'Moody', 'Power Construct', 'Sand Veil', 'Shadow Tag', 'Snow Cloak',
751
+ 'Bright Powder', 'King\'s Rock', 'Lax Incense', 'Baton Pass',
718
752
  ],
719
- onModifySpeciesPriority: 2,
720
- onModifySpecies(species, target, source, effect) {
721
- if (!target) return; // Chat command
722
- if (effect && ['imposter', 'transform'].includes(effect.id)) return;
723
- const types = [...new Set(target.baseMoveSlots.slice(0, 2).map(move => this.dex.moves.get(move.id).type))];
724
- return {...species, types: types};
725
- },
726
- onSwitchIn(pokemon) {
727
- this.add('-start', pokemon, 'typechange', (pokemon.illusion || pokemon).getTypes(true).join('/'), '[silent]');
728
- },
729
- onAfterMega(pokemon) {
730
- this.add('-start', pokemon, 'typechange', (pokemon.illusion || pokemon).getTypes(true).join('/'), '[silent]');
753
+ restricted: [
754
+ 'Baneful Bunker', 'Bounce', 'Protect', 'Detect', 'Dig', 'Dive', 'Fly', 'King\'s Shield', 'Nature\'s Madness', 'Night Shade',
755
+ 'Obstruct', 'Phantom Force', 'Seismic Toss', 'Shadow Force', 'Sky Drop', 'Spiky Shield', 'Super Fang',
756
+ ],
757
+ onValidateSet(set) {
758
+ const problems = [];
759
+ for (const [i, moveid] of set.moves.entries()) {
760
+ const move = this.dex.moves.get(moveid);
761
+ if ([0, 1].includes(i) && this.ruleTable.isRestricted(`move:${move.id}`)) {
762
+ problems.push(`${set.name || set.species}'s move ${move.name} cannot be linked.`);
763
+ }
764
+ }
765
+ return problems;
731
766
  },
732
767
  },
733
768
 
@@ -915,9 +950,9 @@ export const Formats: FormatList = [
915
950
  mod: 'gen8',
916
951
  ruleset: ['Standard', 'Dynamax Clause', 'Sleep Moves Clause'],
917
952
  banlist: [
918
- 'Blissey', 'Calyrex-Shadow', 'Chansey', 'Dragapult', 'Hawlucha', 'Marowak-Alola', 'Melmetal', 'Pikachu', 'Toxapex',
953
+ 'Blissey', 'Calyrex-Shadow', 'Chansey', 'Dragapult', 'Hawlucha', 'Mantine', 'Marowak-Alola', 'Melmetal', 'Pikachu', 'Toxapex',
919
954
  'Xerneas', 'Zacian', 'Zacian-Crowned', 'Uber > 1', 'AG ++ Uber > 1', 'Arena Trap', 'Huge Power', 'Moody', 'Pure Power',
920
- 'Shadow Tag', 'Baton Pass',
955
+ 'Shadow Tag', 'Bright Powder', 'Focus Band', 'King\'s Rock', 'Lax Incense', 'Quick Claw', 'Baton Pass',
921
956
  ],
922
957
  onValidateTeam(team) {
923
958
  const gods = new Set<string>();
@@ -1037,7 +1072,15 @@ export const Formats: FormatList = [
1037
1072
 
1038
1073
  mod: 'gen8bdsp',
1039
1074
  ruleset: ['[Gen 8 BDSP] UU'],
1040
- banlist: ['UU', 'RUBL'],
1075
+ banlist: ['UU', 'RUBL', 'Drought'],
1076
+ },
1077
+ {
1078
+ name: "[Gen 8 BDSP] NU",
1079
+
1080
+ mod: 'gen8bdsp',
1081
+ searchShow: false,
1082
+ ruleset: ['[Gen 8 BDSP] RU'],
1083
+ banlist: ['RU', 'NUBL'],
1041
1084
  },
1042
1085
  {
1043
1086
  name: "[Gen 8 BDSP] LC",
@@ -1047,7 +1090,7 @@ export const Formats: FormatList = [
1047
1090
 
1048
1091
  mod: 'gen8bdsp',
1049
1092
  ruleset: ['Little Cup', 'Standard'],
1050
- banlist: ['Gligar', 'Meditite', 'Misdreavus', 'Murkrow', 'Scyther', 'Sneasel', 'Tangela', 'Vulpix', 'Yanma', 'Baton Pass'],
1093
+ banlist: ['Gligar', 'Meditite', 'Misdreavus', 'Murkrow', 'Scyther', 'Sneasel', 'Tangela', 'Vulpix', 'Yanma', 'Moody', 'Baton Pass'],
1051
1094
  },
1052
1095
  {
1053
1096
  name: "[Gen 8 BDSP] Monotype",
@@ -1117,6 +1160,37 @@ export const Formats: FormatList = [
1117
1160
  section: "Challengeable OMs",
1118
1161
  column: 2,
1119
1162
  },
1163
+ {
1164
+ name: "[Gen 8] Camomons",
1165
+ desc: `Pok&eacute;mon change type to match their first two moves.`,
1166
+ threads: [
1167
+ `&bullet; <a href="https://www.smogon.com/forums/threads/3656413/">Camomons</a>`,
1168
+ ],
1169
+
1170
+ mod: 'gen8',
1171
+ searchShow: false,
1172
+ ruleset: ['Obtainable', 'Species Clause', 'Nickname Clause', 'OHKO Clause', 'Evasion Moves Clause', 'Team Preview', 'HP Percentage Mod', 'Cancel Mod', 'Dynamax Clause', 'Sleep Clause Mod', 'Endless Battle Clause'],
1173
+ banlist: [
1174
+ 'Calyrex-Ice', 'Calyrex-Shadow', 'Darmanitan-Galar', 'Dialga', 'Dracovish', 'Dragonite', 'Eternatus', 'Genesect', 'Giratina', 'Giratina-Origin',
1175
+ 'Groudon', 'Ho-Oh', 'Hydreigon', 'Kartana', 'Kyogre', 'Kyurem', 'Kyurem-Black', 'Kyurem-White', 'Landorus-Base', 'Latias', 'Latios', 'Lugia',
1176
+ 'Lunala', 'Marshadow', 'Mew', 'Mewtwo', 'Naganadel', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane', 'Palkia', 'Pheromosa', 'Rayquaza', 'Reshiram',
1177
+ 'Reuniclus', 'Shedinja', 'Slowking-Galar', 'Solgaleo', 'Spectrier', 'Tornadus-Therian', 'Volcarona', 'Xerneas', 'Yveltal', 'Zacian', 'Zacian-Crowned',
1178
+ 'Zamazenta', 'Zamazenta-Crowned', 'Zekrom', 'Zeraora', 'Zygarde-Base', 'Arena Trap', 'Moody', 'Power Construct', 'Shadow Tag', 'Baton Pass',
1179
+ ],
1180
+ onModifySpeciesPriority: 2,
1181
+ onModifySpecies(species, target, source, effect) {
1182
+ if (!target) return; // Chat command
1183
+ if (effect && ['imposter', 'transform'].includes(effect.id)) return;
1184
+ const types = [...new Set(target.baseMoveSlots.slice(0, 2).map(move => this.dex.moves.get(move.id).type))];
1185
+ return {...species, types: types};
1186
+ },
1187
+ onSwitchIn(pokemon) {
1188
+ this.add('-start', pokemon, 'typechange', (pokemon.illusion || pokemon).getTypes(true).join('/'), '[silent]');
1189
+ },
1190
+ onAfterMega(pokemon) {
1191
+ this.add('-start', pokemon, 'typechange', (pokemon.illusion || pokemon).getTypes(true).join('/'), '[silent]');
1192
+ },
1193
+ },
1120
1194
  {
1121
1195
  name: "[Gen 8] Inheritance",
1122
1196
  desc: `Pok&eacute;mon may use the ability and moves of another, as long as they forfeit their own learnset.`,
@@ -1605,6 +1679,53 @@ export const Formats: FormatList = [
1605
1679
  }
1606
1680
  },
1607
1681
  },
1682
+ {
1683
+ name: "[Gen 8] Pokebilities",
1684
+ desc: `Pok&eacute;mon have all of their released abilities simultaneously.`,
1685
+ threads: [
1686
+ `&bullet; <a href="https://www.smogon.com/forums/threads/3679692/">Pok&eacute;bilities</a>`,
1687
+ ],
1688
+ mod: 'pokebilities',
1689
+ searchShow: false,
1690
+ ruleset: ['Standard', 'Dynamax Clause'],
1691
+ banlist: [
1692
+ 'Calyrex-Ice', 'Calyrex-Shadow', 'Cinderace', 'Conkeldurr', 'Darmanitan-Galar', 'Dialga', 'Dracovish', 'Dracozolt',
1693
+ 'Eternatus', 'Excadrill', 'Genesect', 'Giratina', 'Giratina-Origin', 'Groudon', 'Ho-Oh', 'Kyogre', 'Kyurem-Black',
1694
+ 'Kyurem-White', 'Landorus-Base', 'Lugia', 'Lunala', 'Magearna', 'Marshadow', 'Mewtwo', 'Naganadel', 'Necrozma-Dawn-Wings',
1695
+ 'Necrozma-Dusk-Mane', 'Palkia', 'Pheromosa', 'Porygon-Z', 'Rayquaza', 'Reshiram', 'Solgaleo', 'Spectrier', 'Urshifu-Base',
1696
+ 'Xerneas', 'Yveltal', 'Zacian', 'Zacian-Crowned', 'Zamazenta-Base', 'Zekrom', 'Zygarde-Base', 'Power Construct',
1697
+ 'Baton Pass', 'King\'s Rock',
1698
+ // Moody users
1699
+ 'Glalie', 'Octillery', 'Remoraid', 'Snorunt',
1700
+ // Shadow Tag/Arena Trap
1701
+ 'Diglett-Base', 'Dugtrio-Base', 'Gothita', 'Gothitelle', 'Gothorita', 'Trapinch', 'Wobbuffet', 'Wynaut',
1702
+ ],
1703
+ onBegin() {
1704
+ for (const pokemon of this.getAllPokemon()) {
1705
+ if (pokemon.ability === this.toID(pokemon.species.abilities['S'])) {
1706
+ continue;
1707
+ }
1708
+ pokemon.m.innates = Object.keys(pokemon.species.abilities)
1709
+ .filter(key => key !== 'S' && (key !== 'H' || !pokemon.species.unreleasedHidden))
1710
+ .map(key => this.toID(pokemon.species.abilities[key as "0" | "1" | "H" | "S"]))
1711
+ .filter(ability => ability !== pokemon.ability);
1712
+ }
1713
+ },
1714
+ onSwitchInPriority: 2,
1715
+ onSwitchIn(pokemon) {
1716
+ if (pokemon.m.innates) {
1717
+ for (const innate of pokemon.m.innates) {
1718
+ pokemon.addVolatile("ability:" + innate, pokemon);
1719
+ }
1720
+ }
1721
+ },
1722
+ onAfterMega(pokemon) {
1723
+ for (const innate of Object.keys(pokemon.volatiles).filter(i => i.startsWith('ability:'))) {
1724
+ pokemon.removeVolatile(innate);
1725
+ }
1726
+ pokemon.m.innates = undefined;
1727
+ },
1728
+ },
1608
1729
  {
1609
1730
  name: "[Gen 8] The Loser's Game",
1610
1731
  desc: `The first player to lose all of their Pok&eacute;mon wins.`,
@@ -1740,106 +1861,6 @@ export const Formats: FormatList = [
1740
1861
  },
1741
1862
  },
1742
1863
  },
1743
- {
1744
- name: "[Gen 8] Trademarked",
1745
- desc: `Sacrifice your Pok&eacute;mon's ability for a status move that activates on switch-in.`,
1746
- threads: [
1747
- `&bullet; <a href="https://www.smogon.com/forums/threads/3656980/">Trademarked</a>`,
1748
- ],
1749
-
1750
- mod: 'gen8',
1751
- searchShow: false,
1752
- ruleset: ['Standard', 'Dynamax Clause'],
1753
- banlist: [
1754
- 'Calyrex-Ice', 'Calyrex-Shadow', 'Darmanitan-Galar', 'Dialga', 'Dracovish', 'Dragapult', 'Eternatus', 'Kyurem-Black', 'Kyurem-White',
1755
- 'Giratina', 'Giratina-Origin', 'Genesect', 'Groudon', 'Ho-Oh', 'Kartana', 'Kyogre', 'Lugia', 'Lunala', 'Magearna', 'Marshadow',
1756
- 'Melmetal', 'Mewtwo', 'Naganadel', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane', 'Palkia', 'Pheromosa', 'Rayquaza', 'Reshiram',
1757
- 'Solgaleo', 'Urshifu-Base', 'Xerneas', 'Yveltal', 'Zacian', 'Zacian-Crowned', 'Zamazenta', 'Zamazenta-Crowned', 'Zekrom', 'Zygarde-Base',
1758
- 'Arena Trap', 'Moody', 'Power Construct', 'Shadow Tag', 'Baton Pass',
1759
- ],
1760
- restricted: [
1761
- 'Baneful Bunker', 'Block', 'Copycat', 'Corrosive Gas', 'Detect', 'Destiny Bond', 'Disable', 'Encore', 'Fairy Lock', 'Hypnosis', 'Ingrain',
1762
- 'Instruct', 'Lovely Kiss', 'King\'s Shield', 'Mat Block', 'Mean Look', 'move:Metronome', 'Obstruct', 'Octolock', 'Nature Power', 'Parting Shot',
1763
- 'Psycho Shift', 'Protect', 'Roar', 'Sing', 'Skill Swap', 'Sleep Powder', 'Sleep Talk', 'Spiky Shield', 'Spore', 'Substitute', 'Teleport',
1764
- 'Whirlwind', 'Wish', 'Yawn',
1765
- ],
1766
- onValidateTeam(team, format, teamHas) {
1767
- const problems = [];
1768
- for (const trademark in teamHas.trademarks) {
1769
- if (teamHas.trademarks[trademark] > 1) {
1770
- problems.push(`You are limited to 1 of each Trademark.`, `(You have ${teamHas.trademarks[trademark]} Pok\u00e9mon with ${trademark} as a Trademark.)`);
1771
- }
1772
- }
1773
- return problems;
1774
- },
1775
- validateSet(set, teamHas) {
1776
- const dex = this.dex;
1777
- const ability = dex.moves.get(set.ability);
1778
- if (!ability.exists) { // Not even a real move
1779
- return this.validateSet(set, teamHas);
1780
- }
1781
- // Absolute trademark bans
1782
- if (ability.category !== 'Status') {
1783
- return [`${ability.name} is not a status move, and cannot be used as a trademark.`];
1784
- }
1785
- if (ability.forceSwitch || ability.selfSwitch) {
1786
- return [
1787
- `Force-switching and self-switching moves are banned from being used as trademarks.`,
1788
- `(${ability.name} is a ${ability.forceSwitch ? 'force' : 'self'}-switching move.)`,
1789
- ];
1790
- }
1791
- const irrevokablyRestricted = [
1792
- 'Assist', 'Copycat', 'Metronome', 'Mirror Move', 'Sleep Talk', // Could call another unsafe trademark
1793
- 'Skill Swap', // Self-propagates indefinitely
1794
- ];
1795
- if (irrevokablyRestricted.includes(ability.name)) {
1796
- return [`${ability.name} cannot safely function as a trademark.`];
1797
- }
1798
- // Contingent trademark bans
1799
- if (this.ruleTable.isRestricted(`move:${ability.id}`)) {
1800
- return [`${ability.name} is restricted from being used as a trademark.`];
1801
- }
1802
- if (set.moves.map(this.toID).includes(ability.id)) {
1803
- return [`${set.name} may not use ${ability.name} as both a trademark and one of its moves simultaneously.`];
1804
- }
1805
- const customRules = this.format.customRules || [];
1806
- if (!customRules.includes('!obtainableabilities')) customRules.push('!obtainableabilities');
1807
-
1808
- const TeamValidator: typeof import('../sim/team-validator').TeamValidator =
1809
- require('../sim/team-validator').TeamValidator;
1810
-
1811
- const validator = new TeamValidator(dex.formats.get(`${this.format.id}@@@${customRules.join(',')}`));
1812
- const moves = set.moves;
1813
- set.moves = [ability.id];
1814
- set.ability = dex.species.get(set.species).abilities['0'];
1815
- let problems = validator.validateSet(set, {}) || [];
1816
- if (problems.length) return problems;
1817
- set.moves = moves;
1818
- set.ability = dex.species.get(set.species).abilities['0'];
1819
- problems = problems.concat(validator.validateSet(set, teamHas) || []);
1820
- set.ability = ability.id;
1821
- if (!teamHas.trademarks) teamHas.trademarks = {};
1822
- teamHas.trademarks[ability.name] = (teamHas.trademarks[ability.name] || 0) + 1;
1823
- return problems.length ? problems : null;
1824
- },
1825
- pokemon: {
1826
- getAbility() {
1827
- const move = this.battle.dex.moves.get(this.battle.toID(this.ability));
1828
- if (!move.exists) return Object.getPrototypeOf(this).getAbility.call(this);
1829
- return {
1830
- id: move.id,
1831
- name: move.name,
1832
- onStart(this: Battle, pokemon: Pokemon) {
1833
- this.add('-activate', pokemon, 'ability: ' + move.name);
1834
- this.actions.useMove(move, pokemon);
1835
- },
1836
- toString() {
1837
- return "";
1838
- },
1839
- };
1840
- },
1841
- },
1842
- },
1843
1864
 
1844
1865
  // Randomized Metas
1845
1866
  ///////////////////////////////////////////////////////////////////
@@ -2140,40 +2161,39 @@ export const Formats: FormatList = [
2140
2161
  column: 3,
2141
2162
  },
2142
2163
  {
2143
- name: "[Gen 2] UU",
2144
- threads: [`&bullet; <a href="https://www.smogon.com/forums/threads/3576710/">GSC UU</a>`],
2164
+ name: "[Gen 3] UU",
2165
+ threads: [
2166
+ `&bullet; <a href="https://www.smogon.com/forums/threads/3585923/">ADV UU Metagame Discussion</a>`,
2167
+ `&bullet; <a href="https://www.smogon.com/forums/threads/3548578/">ADV UU Viability Rankings</a>`,
2168
+ ],
2145
2169
 
2146
- mod: 'gen2',
2170
+ mod: 'gen3',
2147
2171
  // searchShow: false,
2148
- ruleset: ['[Gen 2] OU'],
2149
- banlist: ['OU', 'UUBL'],
2172
+ ruleset: ['Standard', 'NFE Clause'],
2173
+ banlist: ['Uber', 'OU', 'UUBL', 'Smeargle + Ingrain', 'Baton Pass'],
2174
+ unbanlist: ['Scyther', 'Sand Veil'],
2150
2175
  },
2151
2176
  {
2152
- name: "[Gen 5] NU",
2177
+ name: "[Gen 1] NU",
2153
2178
  threads: [
2154
- `&bullet; <a href="https://www.smogon.com/forums/posts/6431094/">BW2 Sample Teams</a>`,
2155
- `&bullet; <a href="https://www.smogon.com/forums/threads/3484121/">BW2 NU Viability Rankings</a>`,
2179
+ `&bullet; <a href="https://www.smogon.com/forums/threads/3668913/">RBY NU Viability Rankings</a>`,
2156
2180
  ],
2157
2181
 
2158
- mod: 'gen5',
2182
+ mod: 'gen1',
2159
2183
  // searchShow: false,
2160
- ruleset: ['[Gen 5] RU', '!Sleep Moves Clause', 'Sleep Clause Mod'],
2161
- banlist: ['RU', 'NUBL', 'Assist', 'Copycat'],
2184
+ ruleset: ['[Gen 1] UU'],
2185
+ banlist: ['UU', 'NUBL'],
2162
2186
  },
2163
2187
  {
2164
- name: "[Gen 5] LC",
2188
+ name: "[Gen 4] Ubers",
2165
2189
  threads: [
2166
- `&bullet; <a href="https://www.smogon.com/forums/posts/6431094/">BW2 Sample Teams</a>`,
2167
- `&bullet; <a href="https://www.smogon.com/forums/threads/3485860/">BW2 LC Viability Rankings</a>`,
2190
+ `&bullet; <a href="https://www.smogon.com/forums/posts/8286279/">DPP Ubers</a>`,
2168
2191
  ],
2169
2192
 
2170
- mod: 'gen5',
2193
+ mod: 'gen4',
2171
2194
  // searchShow: false,
2172
- ruleset: ['Standard', 'Little Cup', 'Sleep Moves Clause'],
2173
- banlist: [
2174
- 'Gligar', 'Meditite', 'Misdreavus', 'Murkrow', 'Scraggy', 'Scyther', 'Sneasel', 'Tangela', 'Vulpix', 'Yanma',
2175
- 'Sand Rush', 'Sand Veil', 'Berry Juice', 'Soul Dew', 'Baton Pass', 'Dragon Rage', 'Sonic Boom', 'Swagger',
2176
- ],
2195
+ ruleset: ['Standard'],
2196
+ banlist: ['AG'],
2177
2197
  },
2178
2198
 
2179
2199
  // Past Gens OU
@@ -2228,7 +2248,7 @@ export const Formats: FormatList = [
2228
2248
 
2229
2249
  mod: 'gen4',
2230
2250
  ruleset: ['Standard'],
2231
- banlist: ['AG', 'Uber', 'Arena Trap', 'Sand Veil', 'Swinub + Snow Cloak', 'Piloswine + Snow Cloak', 'Mamoswine + Snow Cloak', 'Soul Dew', 'Baton Pass'],
2251
+ banlist: ['AG', 'Uber', 'Arena Trap', 'Sand Veil', 'Swinub + Snow Cloak', 'Piloswine + Snow Cloak', 'Mamoswine + Snow Cloak', 'Soul Dew', 'Baton Pass', 'Swagger'],
2232
2252
  },
2233
2253
  {
2234
2254
  name: "[Gen 3] OU",
@@ -3034,6 +3054,18 @@ export const Formats: FormatList = [
3034
3054
  banlist: ['UU', 'RUBL', 'Shadow Tag', 'Shell Smash + Baton Pass'],
3035
3055
  unbanlist: ['Prankster + Assist', 'Prankster + Copycat', 'Baton Pass'],
3036
3056
  },
3057
+ {
3058
+ name: "[Gen 5] NU",
3059
+ threads: [
3060
+ `&bullet; <a href="https://www.smogon.com/forums/posts/6431094/">BW2 Sample Teams</a>`,
3061
+ `&bullet; <a href="https://www.smogon.com/forums/threads/3484121/">BW2 NU Viability Rankings</a>`,
3062
+ ],
3063
+
3064
+ mod: 'gen5',
3065
+ searchShow: false,
3066
+ ruleset: ['[Gen 5] RU', '!Sleep Moves Clause', 'Sleep Clause Mod'],
3067
+ banlist: ['RU', 'NUBL', 'Assist', 'Copycat'],
3068
+ },
3037
3069
  {
3038
3070
  name: "[Gen 5] PU",
3039
3071
  threads: [
@@ -3045,6 +3077,21 @@ export const Formats: FormatList = [
3045
3077
  ruleset: ['[Gen 5] NU', 'Sleep Moves Clause'],
3046
3078
  banlist: ['NU', 'PUBL'],
3047
3079
  },
3080
+ {
3081
+ name: "[Gen 5] LC",
3082
+ threads: [
3083
+ `&bullet; <a href="https://www.smogon.com/forums/posts/6431094/">BW2 Sample Teams</a>`,
3084
+ `&bullet; <a href="https://www.smogon.com/forums/threads/3485860/">BW2 LC Viability Rankings</a>`,
3085
+ ],
3086
+
3087
+ mod: 'gen5',
3088
+ searchShow: false,
3089
+ ruleset: ['Standard', 'Little Cup', 'Sleep Moves Clause'],
3090
+ banlist: [
3091
+ 'Gligar', 'Meditite', 'Misdreavus', 'Murkrow', 'Scraggy', 'Scyther', 'Sneasel', 'Tangela', 'Vulpix', 'Yanma',
3092
+ 'Sand Rush', 'Sand Veil', 'Berry Juice', 'Soul Dew', 'Baton Pass', 'Dragon Rage', 'Sonic Boom', 'Swagger',
3093
+ ],
3094
+ },
3048
3095
  {
3049
3096
  name: "[Gen 5] Monotype",
3050
3097
  desc: `All the Pok&eacute;mon on a team must share a type.`,
@@ -3169,17 +3216,6 @@ export const Formats: FormatList = [
3169
3216
  section: "DPP Singles",
3170
3217
  column: 5,
3171
3218
  },
3172
- {
3173
- name: "[Gen 4] Ubers",
3174
- threads: [
3175
- `&bullet; <a href="https://www.smogon.com/forums/posts/8286279/">DPP Ubers</a>`,
3176
- ],
3177
-
3178
- mod: 'gen4',
3179
- searchShow: false,
3180
- ruleset: ['Standard'],
3181
- banlist: ['AG'],
3182
- },
3183
3219
  {
3184
3220
  name: "[Gen 4] UU",
3185
3221
  threads: [
@@ -3191,7 +3227,7 @@ export const Formats: FormatList = [
3191
3227
  searchShow: false,
3192
3228
  ruleset: ['[Gen 4] OU'],
3193
3229
  banlist: ['OU', 'UUBL'],
3194
- unbanlist: ['Arena Trap'],
3230
+ unbanlist: ['Arena Trap', 'Swagger'],
3195
3231
  },
3196
3232
  {
3197
3233
  name: "[Gen 4] NU",
@@ -3252,7 +3288,7 @@ export const Formats: FormatList = [
3252
3288
  '[Gen 4] OU', 'Accuracy Moves Clause', 'Sleep Moves Clause', 'Team Preview',
3253
3289
  ],
3254
3290
  banlist: ['Latias', 'Machamp', 'Porygon-Z', 'Shaymin', 'Snorlax', 'Togekiss', 'Focus Sash', 'Destiny Bond', 'Explosion', 'Perish Song', 'Self-Destruct'],
3255
- unbanlist: ['Wobbuffet', 'Wynaut', 'Sand Veil'],
3291
+ unbanlist: ['Wobbuffet', 'Wynaut', 'Sand Veil', 'Swagger'],
3256
3292
  },
3257
3293
  {
3258
3294
  name: "[Gen 4] Anything Goes",
@@ -3288,7 +3324,7 @@ export const Formats: FormatList = [
3288
3324
  searchShow: false,
3289
3325
  ruleset: ['[Gen 4] OU'],
3290
3326
  banlist: ['Explosion'],
3291
- unbanlist: ['Garchomp', 'Latias', 'Latios', 'Manaphy', 'Mew', 'Salamence', 'Wobbuffet', 'Wynaut'],
3327
+ unbanlist: ['Garchomp', 'Latias', 'Latios', 'Manaphy', 'Mew', 'Salamence', 'Wobbuffet', 'Wynaut', 'Swagger'],
3292
3328
  },
3293
3329
  {
3294
3330
  name: "[Gen 4] VGC 2010",
@@ -3339,19 +3375,6 @@ export const Formats: FormatList = [
3339
3375
  ruleset: ['Standard', 'Deoxys Camouflage Clause', 'One Baton Pass Clause'],
3340
3376
  banlist: ['Wobbuffet + Leftovers'],
3341
3377
  },
3342
- {
3343
- name: "[Gen 3] UU",
3344
- threads: [
3345
- `&bullet; <a href="https://www.smogon.com/forums/threads/3585923/">ADV UU Metagame Discussion</a>`,
3346
- `&bullet; <a href="https://www.smogon.com/forums/threads/3548578/">ADV UU Viability Rankings</a>`,
3347
- ],
3348
-
3349
- mod: 'gen3',
3350
- searchShow: false,
3351
- ruleset: ['Standard', 'NFE Clause'],
3352
- banlist: ['Uber', 'OU', 'UUBL', 'Smeargle + Ingrain', 'Baton Pass'],
3353
- unbanlist: ['Scyther', 'Sand Veil'],
3354
- },
3355
3378
  {
3356
3379
  name: "[Gen 3] NU",
3357
3380
  threads: [
@@ -3421,6 +3444,15 @@ export const Formats: FormatList = [
3421
3444
  searchShow: false,
3422
3445
  ruleset: ['Standard'],
3423
3446
  },
3447
+ {
3448
+ name: "[Gen 2] UU",
3449
+ threads: [`&bullet; <a href="https://www.smogon.com/forums/threads/3576710/">GSC UU</a>`],
3450
+
3451
+ mod: 'gen2',
3452
+ searchShow: false,
3453
+ ruleset: ['[Gen 2] OU'],
3454
+ banlist: ['OU', 'UUBL'],
3455
+ },
3424
3456
  {
3425
3457
  name: "[Gen 2] NU",
3426
3458
  threads: [`&bullet; <a href="https://www.smogon.com/forums/threads/3642565/">GSC NU</a>`],
@@ -3502,17 +3534,6 @@ export const Formats: FormatList = [
3502
3534
  ruleset: ['[Gen 1] OU'],
3503
3535
  banlist: ['OU', 'UUBL'],
3504
3536
  },
3505
- {
3506
- name: "[Gen 1] NU",
3507
- threads: [
3508
- `&bullet; <a href="https://www.smogon.com/forums/threads/3668913/">RBY NU Viability Rankings</a>`,
3509
- ],
3510
-
3511
- mod: 'gen1',
3512
- searchShow: false,
3513
- ruleset: ['[Gen 1] UU'],
3514
- banlist: ['UU', 'NUBL'],
3515
- },
3516
3537
  {
3517
3538
  name: "[Gen 1] Japanese OU",
3518
3539
  desc: `Generation 1 with Japanese battle mechanics.`,