@pkmn/sim 0.5.9 → 0.5.12

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 (73) hide show
  1. package/README.md +5 -0
  2. package/build/config/formats.js +364 -296
  3. package/build/config/formats.js.map +1 -1
  4. package/build/data/abilities.js +7 -7
  5. package/build/data/abilities.js.map +1 -1
  6. package/build/data/aliases.js +3 -0
  7. package/build/data/aliases.js.map +1 -1
  8. package/build/data/conditions.js +8 -12
  9. package/build/data/conditions.js.map +1 -1
  10. package/build/data/formats-data.js +36 -35
  11. package/build/data/formats-data.js.map +1 -1
  12. package/build/data/items.js +1 -1
  13. package/build/data/items.js.map +1 -1
  14. package/build/data/learnsets.js +5 -4
  15. package/build/data/learnsets.js.map +1 -1
  16. package/build/data/mods/gen1/moves.js +2 -4
  17. package/build/data/mods/gen1/moves.js.map +1 -1
  18. package/build/data/mods/gen3/formats-data.js +2 -2
  19. package/build/data/mods/gen3/formats-data.js.map +1 -1
  20. package/build/data/mods/gen7/formats-data.js +1 -1
  21. package/build/data/mods/gen7/formats-data.js.map +1 -1
  22. package/build/data/moves.js +14 -12
  23. package/build/data/moves.js.map +1 -1
  24. package/build/data/pokedex.js +2 -2
  25. package/build/data/pokedex.js.map +1 -1
  26. package/build/data/tags.js +4 -4
  27. package/build/data/tags.js.map +1 -1
  28. package/build/data/text/moves.js +1 -0
  29. package/build/data/text/moves.js.map +1 -1
  30. package/build/lib/index.js +5 -1
  31. package/build/lib/index.js.map +1 -1
  32. package/build/lib/streams.js +5 -1
  33. package/build/lib/streams.js.map +1 -1
  34. package/build/sim/battle-actions.js +0 -6
  35. package/build/sim/battle-actions.js.map +1 -1
  36. package/build/sim/battle-queue.js +1 -3
  37. package/build/sim/battle-queue.js.map +1 -1
  38. package/build/sim/battle.js +13 -11
  39. package/build/sim/battle.js.map +1 -1
  40. package/build/sim/dex-conditions.js +10 -3
  41. package/build/sim/dex-conditions.js.map +1 -1
  42. package/build/sim/dex.js +5 -1
  43. package/build/sim/dex.js.map +1 -1
  44. package/build/sim/index.js +5 -1
  45. package/build/sim/index.js.map +1 -1
  46. package/build/sim/team-validator.js +1 -1
  47. package/build/sim/team-validator.js.map +1 -1
  48. package/build/sim/teams.js +5 -1
  49. package/build/sim/teams.js.map +1 -1
  50. package/build/sim/tools/index.js +5 -1
  51. package/build/sim/tools/index.js.map +1 -1
  52. package/build/sim/tools/runner.js +5 -1
  53. package/build/sim/tools/runner.js.map +1 -1
  54. package/config/formats.ts +350 -280
  55. package/data/abilities.ts +7 -7
  56. package/data/aliases.ts +3 -0
  57. package/data/conditions.ts +8 -10
  58. package/data/formats-data.ts +36 -35
  59. package/data/items.ts +1 -1
  60. package/data/learnsets.ts +5 -4
  61. package/data/mods/gen1/moves.ts +2 -4
  62. package/data/mods/gen3/formats-data.ts +2 -2
  63. package/data/mods/gen7/formats-data.ts +1 -1
  64. package/data/moves.ts +13 -12
  65. package/data/pokedex.ts +2 -2
  66. package/data/tags.ts +4 -4
  67. package/data/text/moves.ts +2 -0
  68. package/package.json +2 -2
  69. package/sim/battle-actions.ts +0 -7
  70. package/sim/battle-queue.ts +1 -3
  71. package/sim/battle.ts +4 -1
  72. package/sim/dex-conditions.ts +9 -3
  73. package/sim/team-validator.ts +1 -1
package/config/formats.ts CHANGED
@@ -167,7 +167,7 @@ export const Formats: FormatList = [
167
167
  mod: 'gen8',
168
168
  ruleset: ['Little Cup', 'Standard', 'Dynamax Clause'],
169
169
  banlist: [
170
- 'Corsola-Galar', 'Cutiefly', 'Drifloon', 'Gastly', 'Gothita', 'Rufflet', 'Scraggy', 'Scyther', 'Sneasel', 'Swirlix', 'Tangela', 'Vullaby', 'Vulpix-Alola', 'Woobat', 'Zigzagoon-Base',
170
+ 'Corsola-Galar', 'Drifloon', 'Rufflet', 'Scraggy', 'Scyther', 'Sneasel', 'Swirlix', 'Tangela', 'Vulpix-Alola', 'Woobat', 'Zigzagoon-Base',
171
171
  'Chlorophyll', 'Moody', 'Baton Pass', 'Sticky Web',
172
172
  ],
173
173
  },
@@ -187,7 +187,7 @@ export const Formats: FormatList = [
187
187
  'Kartana', 'Kyogre', 'Kyurem-Black', 'Kyurem-White', 'Landorus-Base', 'Lugia', 'Lunala', 'Magearna', 'Marshadow', 'Mewtwo', 'Naganadel',
188
188
  'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane', 'Palkia', 'Pheromosa', 'Rayquaza', 'Reshiram', 'Solgaleo', 'Urshifu-Base', 'Xerneas', 'Yveltal',
189
189
  'Zacian', 'Zacian-Crowned', 'Zamazenta', 'Zamazenta-Crowned', 'Zekrom', 'Zygarde-Base', 'Moody', 'Power Construct', 'Shadow Tag', 'Bright Powder',
190
- 'Damp Rock', 'Focus Band', 'King\'s Rock', 'Lax Incense', 'Quick Claw', 'Smooth Rock', 'Terrain Extender', 'Baton Pass',
190
+ 'Damp Rock', 'Focus Band', 'King\'s Rock', 'Lax Incense', 'Quick Claw', 'Smooth Rock', 'Terrain Extender', 'Acupressure', 'Baton Pass',
191
191
  ],
192
192
  },
193
193
  {
@@ -206,7 +206,7 @@ export const Formats: FormatList = [
206
206
  ],
207
207
  banlist: [
208
208
  'Calyrex-Ice', 'Calyrex-Shadow', 'Cinderace', 'Dialga', 'Dragonite', 'Eternatus', 'Genesect', 'Giratina', 'Giratina-Origin', 'Groudon', 'Ho-Oh', 'Jirachi',
209
- 'Kyogre', 'Kyurem-Black', 'Kyurem-White', 'Lugia', 'Lunala', 'Magearna', 'Marshadow', 'Melmetal', 'Mew', 'Mewtwo', 'Mimikyu', 'Necrozma-Dawn-Wings',
209
+ 'Kyogre', 'Kyurem-Black', 'Kyurem-White', 'Lugia', 'Lunala', 'Magearna', 'Marshadow', 'Melmetal', 'Mew', 'Mewtwo', 'Mimikyu', 'Necrozma', 'Necrozma-Dawn-Wings',
210
210
  'Necrozma-Dusk-Mane', 'Palkia', 'Rayquaza', 'Reshiram', 'Sableye', 'Snorlax', 'Solgaleo', 'Victini', 'Xerneas', 'Yveltal', 'Zacian', 'Zacian-Crowned',
211
211
  'Zamazenta', 'Zamazenta-Crowned', 'Zekrom', 'Moody', 'Power Construct', 'Bright Powder', 'Focus Band', 'Focus Sash', 'Lax Incense', 'Quick Claw', 'Perish Song',
212
212
  ],
@@ -249,9 +249,9 @@ export const Formats: FormatList = [
249
249
  ruleset: ['[Gen 8] LC'],
250
250
  banlist: [
251
251
  // LC OU
252
- 'Abra', 'Carvanha', 'Croagunk', 'Diglett-Base', 'Dwebble', 'Ferroseed', 'Foongus', 'Frillish', 'Grookey',
253
- 'Koffing', 'Larvesta', 'Magnemite', 'Mareanie', 'Mienfoo', 'Mudbray', 'Munchlax', 'Natu', 'Onix', 'Pawniard',
254
- 'Ponyta', 'Ponyta-Galar', 'Porygon', 'Slowpoke-Base', 'Staryu', 'Timburr', 'Trapinch', 'Tyrunt', 'Vulpix',
252
+ 'Abra', 'Carvanha', 'Diglett-Base', 'Dwebble', 'Ferroseed', 'Foongus', 'Frillish', 'Grookey', 'Koffing',
253
+ 'Larvesta', 'Magby', 'Magnemite', 'Mareanie', 'Mienfoo', 'Mudbray', 'Munchlax', 'Natu', 'Onix', 'Pawniard',
254
+ 'Ponyta', 'Ponyta-Galar', 'Porygon', 'Slowpoke-Base', 'Staryu', 'Timburr', 'Trapinch', 'Tyrunt',
255
255
  // LC UUBL
256
256
  'Farfetch\u2019d-Galar', 'Scorbunny', 'Shellder', 'Wingull',
257
257
  ],
@@ -405,8 +405,8 @@ export const Formats: FormatList = [
405
405
  banlist: [
406
406
  'Calyrex-Ice', 'Calyrex-Shadow', 'Dialga', 'Eternatus', 'Giratina', 'Giratina-Origin', 'Groudon', 'Ho-Oh', 'Jirachi', 'Kyogre',
407
407
  'Kyurem-White', 'Lugia', 'Lunala', 'Magearna', 'Marshadow', 'Melmetal', 'Mewtwo', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane', 'Palkia',
408
- 'Rayquaza', 'Reshiram', 'Solgaleo', 'Urshifu-Base', 'Xerneas', 'Yveltal', 'Zacian', 'Zacian-Crowned', 'Zamazenta', 'Zamazenta-Crowned',
409
- 'Zekrom', 'Power Construct', 'Focus Sash', 'Ally Switch', 'Final Gambit', 'Perish Song', 'Swagger',
408
+ 'Rayquaza', 'Reshiram', 'Solgaleo', 'Tornadus-Base', 'Urshifu-Base', 'Urshifu-Rapid-Strike', 'Xerneas', 'Yveltal', 'Zacian', 'Zacian-Crowned',
409
+ 'Zamazenta', 'Zamazenta-Crowned', 'Zekrom', 'Moody', 'Power Construct', 'Focus Sash', 'Ally Switch', 'Final Gambit', 'Perish Song', 'Swagger',
410
410
  ],
411
411
  },
412
412
  {
@@ -480,8 +480,8 @@ export const Formats: FormatList = [
480
480
  mod: 'gen8',
481
481
  ruleset: ['Standard NatDex', 'OHKO Clause', 'Evasion Moves Clause', 'Species Clause', 'Dynamax Clause', 'Sleep Clause Mod'],
482
482
  banlist: [
483
- 'Alakazam-Mega', 'Arceus', 'Blastoise-Mega', 'Blaziken-Mega', 'Calyrex-Ice', 'Calyrex-Shadow', 'Cinderace', 'Darkrai',
484
- 'Darmanitan-Galar', 'Deoxys-Attack', 'Deoxys-Base', 'Deoxys-Speed', 'Dialga', 'Dracovish', 'Eternatus',
483
+ 'Alakazam-Mega', 'Arceus', 'Blastoise-Mega', 'Calyrex-Ice', 'Calyrex-Shadow', 'Cinderace', 'Darkrai',
484
+ 'Darmanitan-Galar', 'Deoxys-Attack', 'Deoxys-Base', 'Deoxys-Speed', 'Dialga', 'Dracovish', 'Dragapult', 'Eternatus',
485
485
  'Genesect', 'Gengar-Mega', 'Giratina', 'Giratina-Origin', 'Groudon', 'Ho-Oh', 'Kangaskhan-Mega', 'Kyogre', 'Kyurem-Black',
486
486
  'Kyurem-White', 'Landorus-Base', 'Lucario-Mega', 'Lugia', 'Lunala', 'Magearna', 'Marshadow', 'Metagross-Mega', 'Mewtwo',
487
487
  'Naganadel', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane', 'Necrozma-Ultra', 'Palkia', 'Pheromosa', 'Rayquaza', 'Reshiram',
@@ -511,16 +511,16 @@ export const Formats: FormatList = [
511
511
  'Drizzle', 'Drought',
512
512
  // Slowbronite is banned so it doesn't validate on Galarian Slowbro
513
513
  'Slowbronite',
514
- // NDOU suspect
515
- 'Dragapult',
514
+ // Ban for ou suspect
515
+ 'Blaziken-Mega',
516
516
  ],
517
517
  // Used to distinguish UU from below UU in the client
518
518
  restricted: [
519
- 'Aegislash', 'Alakazam-Base', 'Altaria-Mega', 'Amoonguss', 'Azumarill', 'Beedrill-Mega', 'Blaziken-Base', 'Breloom', 'Celesteela',
520
- 'Chandelure', 'Donphan', 'Dracozolt', 'Dragonite', 'Feraligatr', 'Gastrodon', 'Hatterene', 'Hippowdon', 'Infernape', 'Keldeo',
521
- 'Krookodile', 'Mamoswine', 'Mandibuzz', 'Manectric-Mega', 'Melmetal', 'Mienshao', 'Moltres-Base', 'Nidoking', 'Nidoqueen', 'Nihilego',
522
- 'Quagsire', 'Regieleki', 'Ribombee', 'Rotom-Heat', 'Rotom-Wash', 'Salamence', 'Scizor', 'Skarmory', 'Slowking-Base', 'Swampert-Base',
523
- 'Talonflame', 'Tangrowth', 'Tornadus-Base', 'Umbreon', 'Urshifu-Rapid-Strike',
519
+ 'Aegislash', 'Altaria-Mega', 'Amoonguss', 'Azumarill', 'Beedrill-Mega', 'Breloom', 'Celesteela', 'Chandelure', 'Donphan', 'Dracozolt',
520
+ 'Dragonite', 'Feraligatr', 'Gastrodon', 'Hatterene', 'Hippowdon', 'Infernape', 'Keldeo', 'Krookodile', 'Mamoswine', 'Mandibuzz',
521
+ 'Manectric-Mega', 'Melmetal', 'Mienshao', 'Moltres-Base', 'Nidoking', 'Nidoqueen', 'Nihilego', 'Quagsire', 'Regieleki', 'Ribombee',
522
+ 'Rotom-Heat', 'Rotom-Wash', 'Salamence', 'Scizor', 'Skarmory', 'Slowking-Base', 'Swampert-Base', 'Talonflame', 'Tangrowth', 'Tornadus-Base',
523
+ 'Umbreon', 'Urshifu-Rapid-Strike',
524
524
  ],
525
525
  },
526
526
  {
@@ -639,197 +639,43 @@ export const Formats: FormatList = [
639
639
  column: 2,
640
640
  },
641
641
  {
642
- name: "[Gen 8] Shared Power",
643
- desc: `Once a Pokémon switches in, its ability is shared with the rest of the team.`,
642
+ name: "[Gen 8] Sketchmons",
643
+ desc: `Every Pokémon gets a new move once.`,
644
644
  threads: [
645
- `&bullet; <a href="https://www.smogon.com/forums/threads/3660877/">Shared Power</a>`,
645
+ `&bullet; <a href="https://www.smogon.com/forums/threads/3680298/">Sketchmons</a>`,
646
646
  ],
647
647
 
648
- mod: 'sharedpower',
649
- // searchShow: false,
650
- ruleset: ['Standard', 'Dynamax Clause'],
648
+ mod: 'gen8',
649
+ ruleset: ['Standard', 'Sketchmons Move Legality', 'Dynamax Clause'],
651
650
  banlist: [
652
- 'Calyrex-Ice', 'Calyrex-Shadow', 'Darmanitan-Galar', 'Dialga', 'Dracovish', 'Eternatus', 'Genesect', 'Giratina',
653
- 'Giratina-Origin', 'Groudon', 'Ho-Oh', 'Kyogre', 'Kyurem-Black', 'Kyurem-White', 'Lugia', 'Lunala', 'Magearna',
654
- 'Marshadow', 'Melmetal', 'Mewtwo', 'Naganadel', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane', 'Palkia',
655
- 'Pheromosa', 'Rayquaza', 'Reshiram', 'Shedinja', 'Solgaleo', 'Urshifu-Base', 'Urshifu-Rapid-Strike',
656
- 'Xerneas', 'Yveltal', 'Zacian', 'Zacian-Crowned', 'Zamazenta', 'Zamazenta-Crowned', 'Zekrom',
657
- 'Arena Trap', 'Contrary', 'Drizzle ++ Swift Swim', 'Drought ++ Chlorophyll', 'Electric Surge ++ Surge Surfer',
658
- 'Fur Coat', 'Guts', 'Harvest', 'Huge Power', 'Imposter', 'Innards Out', 'Libero', 'Magic Bounce', 'Magic Guard',
659
- 'Magnet Pull', 'Mold Breaker', 'Moody', 'Neutralizing Gas', 'Power Construct', 'Queenly Majesty', 'Quick Draw',
660
- 'Regenerator', 'Sand Rush', 'Sand Veil', 'Shadow Tag', 'Simple', 'Snow Cloak', 'Snow Warning ++ Slush Rush', 'Speed Boost',
661
- 'Stakeout', 'Steelworker ++ Steely Spirit', 'Tinted Lens', 'Triage', 'Unaware', 'Unburden', 'Water Bubble',
662
- 'Baton Pass',
651
+ 'Calyrex-Ice', 'Calyrex-Shadow', 'Cinderace', 'Darmanitan-Galar', 'Dialga', 'Dracovish', 'Dragapult', 'Eternatus', 'Genesect', 'Giratina',
652
+ 'Giratina-Origin', 'Groudon', 'Hawlucha', 'Ho-Oh', 'Kartana', 'Kyogre', 'Kyurem-Black', 'Kyurem-White', 'Landorus-Base', 'Lugia', 'Lunala',
653
+ 'Marshadow', 'Mewtwo', 'Naganadel', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane', 'Palkia', 'Porygon-Z', 'Pheromosa', 'Rayquaza', 'Regieleki',
654
+ 'Reshiram', 'Rillaboom', 'Shedinja', 'Solgaleo', 'Spectrier', 'Swoobat', 'Urshifu-Base', 'Xerneas', 'Yveltal', 'Zacian', 'Zacian-Crowned',
655
+ 'Zamazenta', 'Zamazenta-Crowned', 'Zekrom', 'Zeraora', 'Zygarde-Base', 'Arena Trap', 'Magnet Pull', 'Moody', 'Power Construct', 'Sand Rush',
656
+ 'Shadow Tag', 'King\'s Rock', 'Baton Pass',
657
+ ],
658
+ restricted: [
659
+ 'Acupressure', 'Astral Barrage', 'Belly Drum', 'Bolt Beak', 'Clangorous Soul', 'Double Iron Bash', 'Electrify', 'Extreme Speed', 'Fishious Rend',
660
+ 'Geomancy', 'Glacial Lance', 'Lovely Kiss', 'No Retreat', 'Oblivion Wing', 'Octolock', 'Quiver Dance', 'Secret Sword', 'Shell Smash', 'Shift Gear',
661
+ 'Sleep Powder', 'Spore', 'Thousand Arrows', 'Transform', 'V-create', 'Wicked Blow',
663
662
  ],
664
- getSharedPower(pokemon) {
665
- const sharedPower = new Set<string>();
666
- for (const ally of pokemon.side.pokemon) {
667
- if (ally.previouslySwitchedIn > 0) {
668
- if (pokemon.battle.dex.currentMod !== 'sharedpower' && ['trace', 'mirrorarmor'].includes(ally.baseAbility)) {
669
- sharedPower.add('noability');
670
- continue;
671
- }
672
- sharedPower.add(ally.baseAbility);
673
- }
674
- }
675
- sharedPower.delete(pokemon.baseAbility);
676
- return sharedPower;
677
- },
678
- onBeforeSwitchIn(pokemon) {
679
- let format = this.format;
680
- if (!format.getSharedPower) format = this.dex.formats.get('gen8sharedpower');
681
- for (const ability of format.getSharedPower!(pokemon)) {
682
- const effect = 'ability:' + ability;
683
- pokemon.volatiles[effect] = {id: this.toID(effect), target: pokemon};
684
- if (!pokemon.m.abils) pokemon.m.abils = [];
685
- if (!pokemon.m.abils.includes(effect)) pokemon.m.abils.push(effect);
686
- }
687
- },
688
- onSwitchInPriority: 2,
689
- onSwitchIn(pokemon) {
690
- let format = this.format;
691
- if (!format.getSharedPower) format = this.dex.formats.get('gen8sharedpower');
692
- for (const ability of format.getSharedPower!(pokemon)) {
693
- if (ability === 'noability') {
694
- this.hint(`Mirror Armor and Trace break in Shared Power formats that don't use Shared Power as a base, so they get removed from non-base users.`);
695
- }
696
- const effect = 'ability:' + ability;
697
- delete pokemon.volatiles[effect];
698
- pokemon.addVolatile(effect);
699
- }
700
- },
701
663
  },
702
664
  {
703
- name: "[Gen 8] Cross Evolution",
704
- desc: `Give a Pok&eacute;mon a Pok&eacute;mon name of the next evolution stage as a nickname to inherit stat changes, typing, abilities, and up to 2 moves from the next stage Pok&eacute;mon.`,
665
+ name: "[Gen 8] Flipped",
666
+ desc: `Pok&eacute;mon have their base stats flipped.`,
705
667
  threads: [
706
- `&bullet; <a href="https://www.smogon.com/forums/threads/3657562/">Cross Evolution</a>`,
668
+ `&bullet; <a href="https://www.smogon.com/forums/threads/3662020/">Flipped</a>`,
707
669
  ],
708
670
 
709
671
  mod: 'gen8',
710
- // searchShow: false,
711
- ruleset: ['Standard', 'Overflow Stat Mod', 'Dynamax Clause'],
712
- banlist: ['Corsola-Galar', 'Sneasel', 'Type: Null', 'Arena Trap', 'Ice Scales', 'Moody', 'King\'s Rock', 'Baton Pass'],
713
- restricted: ['Chansey', 'Lunala', 'Shedinja', 'Solgaleo', 'Gorilla Tactics', 'Huge Power', 'Pure Power', 'Shadow Tag'],
714
- onValidateTeam(team) {
715
- const names = new Set<ID>();
716
- for (const set of team) {
717
- const name = set.name;
718
- if (names.has(this.dex.toID(name))) {
719
- return [
720
- `Your Pok\u00e9mon must have different nicknames.`,
721
- `(You have more than one Pok\u00e9mon named '${name}')`,
722
- ];
723
- }
724
- names.add(this.dex.toID(name));
725
- }
726
- if (!names.size) {
727
- return [
728
- `${this.format.name} works using nicknames; your team has 0 nicknamed Pok\u00e9mon.`,
729
- `(If this was intentional, add a nickname to one Pok\u00e9mon that isn't the name of a Pok\u00e9mon species.)`,
730
- ];
731
- }
732
- },
733
- checkCanLearn(move, species, lsetData, set) {
734
- // @ts-ignore
735
- if (!set.sp?.exists || !set.crossSpecies?.exists) {
736
- return this.checkCanLearn(move, species, lsetData, set);
737
- }
738
- // @ts-ignore
739
- const problem = this.checkCanLearn(move, set.sp);
740
- if (!problem) return null;
741
- // @ts-ignore
742
- if (!set.crossMovesLeft) return problem;
743
- // @ts-ignore
744
- if (this.checkCanLearn(move, set.crossSpecies)) return problem;
745
- // @ts-ignore
746
- set.crossMovesLeft--;
747
- return null;
748
- },
749
- validateSet(set, teamHas) {
750
- const crossSpecies = this.dex.species.get(set.name);
751
- let problems = this.dex.formats.get('Pokemon').onChangeSet?.call(this, set, this.format) || null;
752
- if (Array.isArray(problems) && problems.length) return problems;
753
- const crossNonstandard = (!this.ruleTable.has('standardnatdex') && crossSpecies.isNonstandard === 'Past') ||
754
- crossSpecies.isNonstandard === 'Future';
755
- const crossIsCap = !this.ruleTable.has('+pokemontag:cap') && crossSpecies.isNonstandard === 'CAP';
756
- if (!crossSpecies.exists || crossNonstandard || crossIsCap) return this.validateSet(set, teamHas);
757
- const species = this.dex.species.get(set.species);
758
- const check = this.checkSpecies(set, species, species, {});
759
- if (check) return [check];
760
- const nonstandard = !this.ruleTable.has('standardnatdex') && species.isNonstandard === 'Past';
761
- const isCap = !this.ruleTable.has('+pokemontag:cap') && species.isNonstandard === 'CAP';
762
- if (!species.exists || nonstandard || isCap || species === crossSpecies) return this.validateSet(set, teamHas);
763
- if (!species.nfe) return [`${species.name} cannot cross evolve because it doesn't evolve.`];
764
- const crossIsUnreleased = (crossSpecies.tier === "Unreleased" && crossSpecies.isNonstandard === "Unobtainable");
765
- if (crossSpecies.battleOnly || crossIsUnreleased || !crossSpecies.prevo) {
766
- return [`${species.name} cannot cross evolve into ${crossSpecies.name} because it isn't an evolution.`];
767
- }
768
- if (this.ruleTable.isRestrictedSpecies(crossSpecies)) {
769
- return [`${species.name} cannot cross evolve into ${crossSpecies.name} because it is banned.`];
770
- }
771
- const crossPrevoSpecies = this.dex.species.get(crossSpecies.prevo);
772
- if (!crossPrevoSpecies.prevo !== !species.prevo) {
773
- return [
774
- `${species.name} cannot cross evolve into ${crossSpecies.name} because they are not consecutive evolution stages.`,
775
- ];
776
- }
777
- const ability = this.dex.abilities.get(set.ability);
778
- if (!this.ruleTable.isRestricted(`ability:${ability.id}`) || Object.values(species.abilities).includes(ability.name)) {
779
- set.species = crossSpecies.name;
780
- }
781
-
782
- // @ts-ignore
783
- set.sp = species;
784
- // @ts-ignore
785
- set.crossSpecies = crossSpecies;
786
- // @ts-ignore
787
- set.crossMovesLeft = 2;
788
- problems = this.validateSet(set, teamHas);
789
- set.name = crossSpecies.name;
790
- set.species = species.name;
791
- return problems;
792
- },
793
- onModifySpecies(species, target, source, effect) {
794
- if (!target) return; // chat
795
- if (effect && ['imposter', 'transform'].includes(effect.id)) return;
796
- if (target.set.name === target.set.species) return;
797
- const crossSpecies = this.dex.species.get(target.set.name);
798
- if (!crossSpecies.exists) return;
799
- if (species.battleOnly || !species.nfe) return;
800
- const crossIsUnreleased = (crossSpecies.tier === "Unreleased" && crossSpecies.isNonstandard === "Unobtainable");
801
- if (crossSpecies.battleOnly || crossIsUnreleased || !crossSpecies.prevo) return;
802
- const crossPrevoSpecies = this.dex.species.get(crossSpecies.prevo);
803
- if (!crossPrevoSpecies.prevo !== !species.prevo) return;
804
-
805
- const mixedSpecies = this.dex.deepClone(species);
806
- mixedSpecies.baseSpecies = mixedSpecies.name = `${species.name}-${crossSpecies.name}`;
807
- mixedSpecies.weightkg =
808
- Math.max(0.1, +(species.weightkg + crossSpecies.weightkg - crossPrevoSpecies.weightkg)).toFixed(1);
809
- mixedSpecies.nfe = false;
810
- mixedSpecies.evos = [];
811
- mixedSpecies.eggGroups = crossSpecies.eggGroups;
812
- mixedSpecies.abilities = crossSpecies.abilities;
813
- mixedSpecies.bst = 0;
814
- let i: StatID;
815
- for (i in species.baseStats) {
816
- const statChange = crossSpecies.baseStats[i] - crossPrevoSpecies.baseStats[i];
817
- mixedSpecies.baseStats[i] = this.clampIntRange(species.baseStats[i] + statChange, 1, 255);
818
- mixedSpecies.bst += mixedSpecies.baseStats[i];
819
- }
820
- if (crossSpecies.types[0] !== crossPrevoSpecies.types[0]) mixedSpecies.types[0] = crossSpecies.types[0];
821
- if (crossSpecies.types[1] !== crossPrevoSpecies.types[1]) {
822
- mixedSpecies.types[1] = crossSpecies.types[1] || crossSpecies.types[0];
823
- }
824
- if (mixedSpecies.types[0] === mixedSpecies.types[1]) mixedSpecies.types = [mixedSpecies.types[0]];
825
-
826
- return mixedSpecies;
827
- },
828
- onBegin() {
829
- for (const pokemon of this.getAllPokemon()) {
830
- pokemon.baseSpecies = pokemon.species;
831
- }
832
- },
672
+ ruleset: ['Standard', 'Flipped Mod', 'Dynamax Clause'],
673
+ banlist: [
674
+ 'Azumarill', 'Blissey', 'Calyrex-Ice', 'Calyrex-Shadow', 'Dialga', 'Eternatus', 'Giratina', 'Giratina-Origin', 'Groudon', 'Ho-Oh', 'Kyogre',
675
+ 'Kyurem-Black', 'Kyurem-White', 'Lugia', 'Lunala', 'Marshadow', 'Mewtwo', 'Necrozma-Dawn Wings', 'Necrozma-Dusk Mane', 'Palkia', 'Rayquaza',
676
+ 'Reshiram', 'Solgaleo', 'Steelix', 'Xerneas', 'Yveltal', 'Zacian', 'Zacian-Crowned', 'Zamazenta', 'Zamazenta-Crowned', 'Zekrom', 'Zygarde-Base',
677
+ 'Psychic Surge', 'Psychic Terrain', 'Shell Smash',
678
+ ],
833
679
  },
834
680
 
835
681
  // Other Metagames
@@ -885,15 +731,16 @@ export const Formats: FormatList = [
885
731
  ],
886
732
 
887
733
  mod: 'gen8',
888
- ruleset: ['Obtainable', '!Obtainable Abilities', 'Species Clause', 'Nickname Clause', '2 Ability Clause', 'OHKO Clause', 'Evasion Moves Clause', 'Team Preview', 'HP Percentage Mod', 'Cancel Mod', 'Dynamax Clause', 'Sleep Moves Clause', 'Endless Battle Clause'],
734
+ ruleset: ['Standard', '!Obtainable Abilities', '2 Ability Clause', 'Dynamax Clause', 'Sleep Moves Clause', '!Sleep Clause Mod'],
889
735
  banlist: [
890
- 'Archeops', 'Blacephalon', 'Buzzwole', 'Calyrex-Ice', 'Calyrex-Shadow', 'Dialga', 'Dracovish', 'Dragapult', 'Dragonite', 'Eternatus', 'Gengar', 'Giratina',
891
- 'Giratina-Origin', 'Groudon', 'Ho-Oh', 'Kartana', 'Keldeo', 'Kyogre', 'Kyurem', 'Kyurem-Black', 'Kyurem-White', 'Lugia', 'Lunala', 'Magearna', 'Marshadow',
892
- 'Melmetal', 'Mewtwo', 'Naganadel', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane', 'Noivern', 'Palkia', 'Pheromosa', 'Rayquaza', 'Regigigas', 'Reshiram', 'Shedinja',
893
- 'Solgaleo', 'Spectrier', 'Urshifu-Base', 'Urshifu-Rapid-Strike', 'Victini', 'Weavile', 'Xerneas', 'Yveltal', 'Zacian', 'Zacian-Crowned', 'Zamazenta-Base', 'Zekrom',
894
- 'Zeraora', 'Zygarde-Base', 'Arena Trap', 'Comatose', 'Contrary', 'Fluffy', 'Fur Coat', 'Gorilla Tactics', 'Huge Power', 'Ice Scales', 'Illusion', 'Imposter',
895
- 'Innards Out', 'Intrepid Sword', 'Libero', 'Magnet Pull', 'Moody', 'Neutralizing Gas', 'Parental Bond', 'Poison Heal', 'Protean', 'Pure Power', 'Shadow Tag',
896
- 'Simple', 'Stakeout', 'Speed Boost', 'Water Bubble', 'Wonder Guard', 'King\'s Rock', 'Baton Pass',
736
+ 'Archeops', 'Blacephalon', 'Buzzwole', 'Calyrex-Ice', 'Calyrex-Shadow', 'Dialga', 'Dracovish', 'Dragapult', 'Dragonite', 'Eternatus',
737
+ 'Gengar', 'Giratina', 'Giratina-Origin', 'Groudon', 'Ho-Oh', 'Kartana', 'Keldeo', 'Kyogre', 'Kyurem', 'Kyurem-Black', 'Kyurem-White',
738
+ 'Lugia', 'Lunala', 'Magearna', 'Marshadow', 'Melmetal', 'Mewtwo', 'Naganadel', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane', 'Noivern',
739
+ 'Palkia', 'Pheromosa', 'Rayquaza', 'Regigigas', 'Reshiram', 'Shedinja', 'Solgaleo', 'Spectrier', 'Urshifu', 'Urshifu-Rapid-Strike',
740
+ 'Victini', 'Weavile', 'Xerneas', 'Yveltal', 'Zacian', 'Zacian-Crowned', 'Zamazenta-Base', 'Zekrom', 'Zeraora', 'Zygarde-Base',
741
+ 'Arena Trap', 'Comatose', 'Contrary', 'Fluffy', 'Fur Coat', 'Gorilla Tactics', 'Huge Power', 'Ice Scales', 'Illusion', 'Imposter',
742
+ 'Innards Out', 'Intrepid Sword', 'Libero', 'Magnet Pull', 'Moody', 'Neutralizing Gas', 'Parental Bond', 'Poison Heal', 'Protean',
743
+ 'Pure Power', 'Shadow Tag', 'Simple', 'Stakeout', 'Speed Boost', 'Water Bubble', 'Wonder Guard', 'King\'s Rock', 'Baton Pass',
897
744
  ],
898
745
  onValidateSet(set) {
899
746
  // Temporary fix until battle-only is implemented properly
@@ -914,15 +761,15 @@ export const Formats: FormatList = [
914
761
  ],
915
762
 
916
763
  mod: 'mixandmega',
917
- ruleset: ['Obtainable', 'Species Clause', 'Nickname Clause', 'OHKO Clause', 'Evasion Moves Clause', 'Team Preview', 'HP Percentage Mod', 'Cancel Mod', 'Overflow Stat Mod', 'Dynamax Clause', 'Sleep Clause Mod', 'Endless Battle Clause'],
764
+ ruleset: ['Standard', 'Overflow Stat Mod', 'Dynamax Clause'],
918
765
  banlist: [
919
- 'Calyrex-Shadow', 'Kyogre', 'Zacian',
766
+ 'Calyrex-Shadow', 'Eternatus', 'Kyogre', 'Zacian',
920
767
  'Beedrillite', 'Blazikenite', 'Gengarite', 'Kangaskhanite', 'Mawilite', 'Medichamite', 'Pidgeotite',
921
768
  'Moody', 'Shadow Tag', 'Baton Pass', 'Electrify',
922
769
  ],
923
770
  restricted: [
924
- 'Calyrex-Ice', 'Dialga', 'Eternatus', 'Gengar', 'Giratina', 'Groudon', 'Ho-Oh', 'Kyurem-Black', 'Kyurem-White',
925
- 'Lugia', 'Lunala', 'Marshadow', 'Melmetal', 'Mewtwo', 'Naganadel', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane',
771
+ 'Calyrex-Ice', 'Dialga', 'Gengar', 'Giratina', 'Groudon', 'Ho-Oh', 'Kyurem-Black', 'Kyurem-White', 'Lugia',
772
+ 'Lunala', 'Marshadow', 'Melmetal', 'Mewtwo', 'Naganadel', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane',
926
773
  'Palkia', 'Pheromosa', 'Rayquaza', 'Regigigas', 'Reshiram', 'Urshifu', 'Urshifu-Rapid-Strike', 'Xerneas',
927
774
  'Yveltal', 'Zekrom', 'Zygarde-Complete',
928
775
  ],
@@ -931,8 +778,15 @@ export const Formats: FormatList = [
931
778
  for (const set of team) {
932
779
  const item = this.dex.items.get(set.item);
933
780
  if (!item.megaStone) continue;
781
+ const natdex = this.ruleTable.has('standardnatdex');
782
+ if (natdex && item.id !== 'ultranecroziumz') continue;
934
783
  const species = this.dex.species.get(set.species);
935
- if (species.isNonstandard) return [`${species.baseSpecies} does not exist in gen 8.`];
784
+ if (species.isNonstandard && !this.ruleTable.has(`+${this.toID(species.isNonstandard)}`)) {
785
+ return [`${species.baseSpecies} does not exist in gen 8.`];
786
+ }
787
+ if (natdex && species.name.startsWith('Necrozma-') && item.id === 'ultranecroziumz') {
788
+ continue;
789
+ }
936
790
  if (this.ruleTable.isRestrictedSpecies(species) || this.toID(set.ability) === 'powerconstruct') {
937
791
  return [`${species.name} is not allowed to hold ${item.name}.`];
938
792
  }
@@ -1002,8 +856,8 @@ export const Formats: FormatList = [
1002
856
  mod: 'gen8',
1003
857
  ruleset: ['Not Fully Evolved', 'Standard', 'Dynamax Clause'],
1004
858
  banlist: [
1005
- 'Chansey', 'Doublade', 'Haunter', 'Kadabra', 'Magneton', 'Mr. Mime-Galar', 'Pawniard', 'Pikachu', 'Porygon2',
1006
- 'Rhydon', 'Scyther', 'Sneasel', 'Type: Null', 'Vulpix-Base', 'Arena Trap', 'Shadow Tag', 'Baton Pass',
859
+ 'Chansey', 'Doublade', 'Golbat', 'Haunter', 'Kadabra', 'Magmar', 'Magneton', 'Mr. Mime-Galar', 'Pawniard', 'Pikachu',
860
+ 'Porygon2', 'Rhydon', 'Scyther', 'Sneasel', 'Type: Null', 'Vulpix-Base', 'Arena Trap', 'Shadow Tag', 'Baton Pass',
1007
861
  ],
1008
862
  },
1009
863
  {
@@ -1016,17 +870,29 @@ export const Formats: FormatList = [
1016
870
  mod: 'gen8',
1017
871
  ruleset: ['Standard', 'Dynamax Clause', 'Sleep Moves Clause'],
1018
872
  banlist: [
1019
- 'Blissey', 'Calyrex-Shadow', 'Chansey', 'Dragapult', 'Hawlucha', 'Marowak-Alola', 'Melmetal', 'Pikachu', 'Toxapex',
1020
- 'Xerneas', 'Zacian', 'Zacian-Crowned', 'Uber > 1', 'AG ++ Uber > 1', 'Arena Trap', 'Huge Power', 'Moody', 'Pure Power',
1021
- 'Shadow Tag', 'Swift Swim', 'Bright Powder', 'Focus Band', 'King\'s Rock', 'Lax Incense', 'Quick Claw', 'Baton Pass',
873
+ 'Blissey', 'Calyrex-Shadow', 'Chansey', 'Dragapult', 'Eternatus', 'Hawlucha', 'Marowak-Alola', 'Melmetal', 'Pikachu',
874
+ 'Toxapex', 'Xerneas', 'Zacian', 'Zacian-Crowned', 'Uber > 1', 'AG ++ Uber > 1', 'Arena Trap', 'Huge Power', 'Moody',
875
+ 'Pure Power', 'Shadow Tag', 'Swift Swim', 'Bright Powder', 'Focus Band', 'King\'s Rock', 'Lax Incense', 'Quick Claw',
876
+ 'Baton Pass',
1022
877
  ],
1023
878
  onValidateTeam(team) {
1024
879
  const gods = new Set<string>();
1025
880
  for (const set of team) {
1026
881
  let species = this.dex.species.get(set.species);
1027
882
  if (typeof species.battleOnly === 'string') species = this.dex.species.get(species.battleOnly);
1028
- if (['ag', 'uber'].includes(this.toID(species.tier)) || this.toID(set.ability) === 'powerconstruct') {
1029
- gods.add(species.name);
883
+ if (set.item && this.dex.items.get(set.item).megaStone) {
884
+ const item = this.dex.items.get(set.item);
885
+ if (item.megaEvolves === species.baseSpecies) {
886
+ species = this.dex.species.get(item.megaStone);
887
+ }
888
+ }
889
+ if (this.ruleTable.has('standardnatdex')) {
890
+ const format = this.dex.formats.getRuleTable(this.dex.formats.get('gen8nationaldex'));
891
+ if (format.isBannedSpecies(species)) gods.add(species.name);
892
+ } else {
893
+ if (['ag', 'uber'].includes(this.toID(species.tier)) || this.toID(set.ability) === 'powerconstruct') {
894
+ gods.add(species.name);
895
+ }
1030
896
  }
1031
897
  }
1032
898
  if (gods.size > 1) {
@@ -1038,7 +904,10 @@ export const Formats: FormatList = [
1038
904
  if (source || !target?.side) return;
1039
905
  const god = target.side.team.find(set => {
1040
906
  let godSpecies = this.dex.species.get(set.species);
1041
- const validator = this.dex.formats.getRuleTable(this.dex.formats.get(`gen${this.gen}ou`));
907
+ const isNatDex = this.format.ruleTable?.has('standardnatdex');
908
+ const validator = this.dex.formats.getRuleTable(
909
+ this.dex.formats.get(`gen${isNatDex && this.gen < 8 ? 8 : this.gen}${isNatDex ? 'nationaldex' : 'ou'}`)
910
+ );
1042
911
  if (this.toID(set.ability) === 'powerconstruct') {
1043
912
  return true;
1044
913
  }
@@ -1055,6 +924,9 @@ export const Formats: FormatList = [
1055
924
  if (godSpecies.forme === 'Crowned') {
1056
925
  godSpecies = this.dex.species.get(godSpecies.changesFrom || godSpecies.baseSpecies);
1057
926
  }
927
+ if (typeof godSpecies.battleOnly === 'string') {
928
+ godSpecies = this.dex.species.get(godSpecies.battleOnly);
929
+ }
1058
930
  newSpecies.bst -= newSpecies.baseStats[stat];
1059
931
  newSpecies.baseStats[stat] = godSpecies.baseStats[stat];
1060
932
  newSpecies.bst += newSpecies.baseStats[stat];
@@ -1148,7 +1020,7 @@ export const Formats: FormatList = [
1148
1020
 
1149
1021
  mod: 'gen8bdsp',
1150
1022
  ruleset: ['[Gen 8 BDSP] RU'],
1151
- banlist: ['RU', 'NUBL'],
1023
+ banlist: ['RU', 'NUBL', 'Damp Rock', 'Heat Rock'],
1152
1024
  },
1153
1025
  {
1154
1026
  name: "[Gen 8 BDSP] LC",
@@ -1158,7 +1030,7 @@ export const Formats: FormatList = [
1158
1030
 
1159
1031
  mod: 'gen8bdsp',
1160
1032
  ruleset: ['Little Cup', 'Standard'],
1161
- banlist: ['Gligar', 'Meditite', 'Misdreavus', 'Murkrow', 'Scyther', 'Sneasel', 'Tangela', 'Vulpix', 'Yanma', 'Moody', 'Baton Pass'],
1033
+ banlist: ['Gligar', 'Meditite', 'Misdreavus', 'Murkrow', 'Scyther', 'Sneasel', 'Tangela', 'Vulpix', 'Yanma', 'Moody', 'Baton Pass', 'Sticky Web'],
1162
1034
  },
1163
1035
  {
1164
1036
  name: "[Gen 8 BDSP] Monotype",
@@ -1169,7 +1041,7 @@ export const Formats: FormatList = [
1169
1041
  mod: 'gen8bdsp',
1170
1042
  ruleset: ['Standard', 'Same Type Clause'],
1171
1043
  banlist: [
1172
- 'Dialga', 'Giratina', 'Giratina-Origin', 'Groudon', 'Ho-Oh', 'Kyogre', 'Lugia', 'Mewtwo', 'Palkia', 'Rayquaza',
1044
+ 'Arceus', 'Darkrai', 'Dialga', 'Giratina', 'Giratina-Origin', 'Groudon', 'Ho-Oh', 'Kyogre', 'Lugia', 'Mewtwo', 'Palkia', 'Rayquaza', 'Shaymin-Sky',
1173
1045
  'Arena Trap', 'Moody', 'Shadow Tag', 'Damp Rock', 'King\'s Rock', 'Razor Fang', 'Baton Pass',
1174
1046
  ],
1175
1047
  },
@@ -1190,6 +1062,7 @@ export const Formats: FormatList = [
1190
1062
  ],
1191
1063
 
1192
1064
  mod: 'gen8bdsp',
1065
+ searchShow: false,
1193
1066
  ruleset: ['Flat Rules', 'Min Source Gen = 8'],
1194
1067
  },
1195
1068
  {
@@ -1240,12 +1113,149 @@ export const Formats: FormatList = [
1240
1113
  ruleset: ['Standard', 'Dynamax Clause', 'Camomons Mod'],
1241
1114
  banlist: [
1242
1115
  'Calyrex-Ice', 'Calyrex-Shadow', 'Darmanitan-Galar', 'Dialga', 'Dracovish', 'Dragonite', 'Eternatus', 'Genesect', 'Giratina', 'Giratina-Origin',
1243
- 'Groudon', 'Ho-Oh', 'Hydreigon', 'Kartana', 'Kyogre', 'Kyurem', 'Kyurem-Black', 'Kyurem-White', 'Landorus-Base', 'Latias', 'Latios', 'Lugia',
1244
- 'Lunala', 'Marshadow', 'Mew', 'Mewtwo', 'Naganadel', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane', 'Palkia', 'Pheromosa', 'Rayquaza', 'Reshiram',
1245
- 'Reuniclus', 'Shedinja', 'Slowking-Galar', 'Solgaleo', 'Spectrier', 'Tornadus-Therian', 'Volcarona', 'Xerneas', 'Yveltal', 'Zacian', 'Zacian-Crowned',
1246
- 'Zamazenta', 'Zamazenta-Crowned', 'Zekrom', 'Zeraora', 'Zygarde-Base', 'Arena Trap', 'Moody', 'Power Construct', 'Shadow Tag', 'Baton Pass',
1116
+ 'Groudon', 'Ho-Oh', 'Hydreigon', 'Kartana', 'Kyogre', 'Kyurem', 'Kyurem-Black', 'Kyurem-White', 'Landorus-Base', 'Lugia', 'Lunala', 'Marshadow',
1117
+ 'Mew', 'Mewtwo', 'Naganadel', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane', 'Palkia', 'Pheromosa', 'Rayquaza', 'Reshiram', 'Shedinja', 'Solgaleo',
1118
+ 'Spectrier', 'Tornadus-Therian', 'Volcarona', 'Xerneas', 'Yveltal', 'Zacian', 'Zacian-Crowned', 'Zamazenta', 'Zamazenta-Crowned', 'Zekrom', 'Zeraora',
1119
+ 'Zygarde-Base', 'Arena Trap', 'Moody', 'Power Construct', 'Shadow Tag', 'Baton Pass', 'Calm Mind',
1247
1120
  ],
1248
1121
  },
1122
+ {
1123
+ name: "[Gen 8] Cross Evolution",
1124
+ desc: `Give a Pok&eacute;mon a Pok&eacute;mon name of the next evolution stage as a nickname to inherit stat changes, typing, abilities, and up to 2 moves from the next stage Pok&eacute;mon.`,
1125
+ threads: [
1126
+ `&bullet; <a href="https://www.smogon.com/forums/threads/3657562/">Cross Evolution</a>`,
1127
+ ],
1128
+
1129
+ mod: 'gen8',
1130
+ searchShow: false,
1131
+ ruleset: ['Standard', 'Overflow Stat Mod', 'Dynamax Clause', '2 Ability Clause'],
1132
+ banlist: ['Corsola-Galar', 'Sneasel', 'Type: Null', 'Arena Trap', 'Ice Scales', 'Moody', 'King\'s Rock', 'Baton Pass'],
1133
+ restricted: ['Chansey', 'Lunala', 'Shedinja', 'Solgaleo', 'Gorilla Tactics', 'Huge Power', 'Pure Power', 'Shadow Tag'],
1134
+ onValidateTeam(team) {
1135
+ const names = new Set<ID>();
1136
+ for (const set of team) {
1137
+ const name = set.name;
1138
+ if (names.has(this.dex.toID(name))) {
1139
+ return [
1140
+ `Your Pok\u00e9mon must have different nicknames.`,
1141
+ `(You have more than one Pok\u00e9mon named '${name}')`,
1142
+ ];
1143
+ }
1144
+ names.add(this.dex.toID(name));
1145
+ }
1146
+ if (!names.size) {
1147
+ return [
1148
+ `${this.format.name} works using nicknames; your team has 0 nicknamed Pok\u00e9mon.`,
1149
+ `(If this was intentional, add a nickname to one Pok\u00e9mon that isn't the name of a Pok\u00e9mon species.)`,
1150
+ ];
1151
+ }
1152
+ },
1153
+ checkCanLearn(move, species, lsetData, set) {
1154
+ // @ts-ignore
1155
+ if (!set.sp?.exists || !set.crossSpecies?.exists) {
1156
+ return this.checkCanLearn(move, species, lsetData, set);
1157
+ }
1158
+ // @ts-ignore
1159
+ const problem = this.checkCanLearn(move, set.sp);
1160
+ if (!problem) return null;
1161
+ // @ts-ignore
1162
+ if (!set.crossMovesLeft) return problem;
1163
+ // @ts-ignore
1164
+ if (this.checkCanLearn(move, set.crossSpecies)) return problem;
1165
+ // @ts-ignore
1166
+ set.crossMovesLeft--;
1167
+ return null;
1168
+ },
1169
+ validateSet(set, teamHas) {
1170
+ const crossSpecies = this.dex.species.get(set.name);
1171
+ let problems = this.dex.formats.get('Pokemon').onChangeSet?.call(this, set, this.format) || null;
1172
+ if (Array.isArray(problems) && problems.length) return problems;
1173
+ const crossNonstandard = (!this.ruleTable.has('standardnatdex') && crossSpecies.isNonstandard === 'Past') ||
1174
+ crossSpecies.isNonstandard === 'Future';
1175
+ const crossIsCap = !this.ruleTable.has('+pokemontag:cap') && crossSpecies.isNonstandard === 'CAP';
1176
+ if (!crossSpecies.exists || crossNonstandard || crossIsCap) return this.validateSet(set, teamHas);
1177
+ const species = this.dex.species.get(set.species);
1178
+ const check = this.checkSpecies(set, species, species, {});
1179
+ if (check) return [check];
1180
+ const nonstandard = !this.ruleTable.has('standardnatdex') && species.isNonstandard === 'Past';
1181
+ const isCap = !this.ruleTable.has('+pokemontag:cap') && species.isNonstandard === 'CAP';
1182
+ if (!species.exists || nonstandard || isCap || species === crossSpecies) return this.validateSet(set, teamHas);
1183
+ if (!species.nfe) return [`${species.name} cannot cross evolve because it doesn't evolve.`];
1184
+ const crossIsUnreleased = (crossSpecies.tier === "Unreleased" && crossSpecies.isNonstandard === "Unobtainable");
1185
+ if (crossSpecies.battleOnly || crossIsUnreleased || !crossSpecies.prevo) {
1186
+ return [`${species.name} cannot cross evolve into ${crossSpecies.name} because it isn't an evolution.`];
1187
+ }
1188
+ if (this.ruleTable.isRestrictedSpecies(crossSpecies)) {
1189
+ return [`${species.name} cannot cross evolve into ${crossSpecies.name} because it is banned.`];
1190
+ }
1191
+ const crossPrevoSpecies = this.dex.species.get(crossSpecies.prevo);
1192
+ if (!crossPrevoSpecies.prevo !== !species.prevo) {
1193
+ return [
1194
+ `${species.name} cannot cross evolve into ${crossSpecies.name} because they are not consecutive evolution stages.`,
1195
+ ];
1196
+ }
1197
+ const item = this.dex.items.get(set.item);
1198
+ if (item.itemUser?.length) {
1199
+ if (!item.itemUser.includes(crossSpecies.name) || crossSpecies.name !== species.name) {
1200
+ return [`${species.name} cannot use ${item.name} because it is cross evolved into ${crossSpecies.name}.`];
1201
+ }
1202
+ }
1203
+ const ability = this.dex.abilities.get(set.ability);
1204
+ if (!this.ruleTable.isRestricted(`ability:${ability.id}`) || Object.values(species.abilities).includes(ability.name)) {
1205
+ set.species = crossSpecies.name;
1206
+ }
1207
+
1208
+ // @ts-ignore
1209
+ set.sp = species;
1210
+ // @ts-ignore
1211
+ set.crossSpecies = crossSpecies;
1212
+ // @ts-ignore
1213
+ set.crossMovesLeft = 2;
1214
+ problems = this.validateSet(set, teamHas);
1215
+ set.name = crossSpecies.name;
1216
+ set.species = species.name;
1217
+ return problems;
1218
+ },
1219
+ onModifySpecies(species, target, source, effect) {
1220
+ if (!target) return; // chat
1221
+ if (effect && ['imposter', 'transform'].includes(effect.id)) return;
1222
+ if (target.set.name === target.set.species) return;
1223
+ const crossSpecies = this.dex.species.get(target.set.name);
1224
+ if (!crossSpecies.exists) return;
1225
+ if (species.battleOnly || !species.nfe) return;
1226
+ const crossIsUnreleased = (crossSpecies.tier === "Unreleased" && crossSpecies.isNonstandard === "Unobtainable");
1227
+ if (crossSpecies.battleOnly || crossIsUnreleased || !crossSpecies.prevo) return;
1228
+ const crossPrevoSpecies = this.dex.species.get(crossSpecies.prevo);
1229
+ if (!crossPrevoSpecies.prevo !== !species.prevo) return;
1230
+
1231
+ const mixedSpecies = this.dex.deepClone(species);
1232
+ mixedSpecies.weightkg =
1233
+ Math.max(0.1, +(species.weightkg + crossSpecies.weightkg - crossPrevoSpecies.weightkg)).toFixed(1);
1234
+ mixedSpecies.nfe = false;
1235
+ mixedSpecies.evos = [];
1236
+ mixedSpecies.eggGroups = crossSpecies.eggGroups;
1237
+ mixedSpecies.abilities = crossSpecies.abilities;
1238
+ mixedSpecies.bst = 0;
1239
+ let i: StatID;
1240
+ for (i in species.baseStats) {
1241
+ const statChange = crossSpecies.baseStats[i] - crossPrevoSpecies.baseStats[i];
1242
+ mixedSpecies.baseStats[i] = this.clampIntRange(species.baseStats[i] + statChange, 1, 255);
1243
+ mixedSpecies.bst += mixedSpecies.baseStats[i];
1244
+ }
1245
+ if (crossSpecies.types[0] !== crossPrevoSpecies.types[0]) mixedSpecies.types[0] = crossSpecies.types[0];
1246
+ if (crossSpecies.types[1] !== crossPrevoSpecies.types[1]) {
1247
+ mixedSpecies.types[1] = crossSpecies.types[1] || crossSpecies.types[0];
1248
+ }
1249
+ if (mixedSpecies.types[0] === mixedSpecies.types[1]) mixedSpecies.types = [mixedSpecies.types[0]];
1250
+
1251
+ return mixedSpecies;
1252
+ },
1253
+ onBegin() {
1254
+ for (const pokemon of this.getAllPokemon()) {
1255
+ pokemon.baseSpecies = pokemon.species;
1256
+ }
1257
+ },
1258
+ },
1249
1259
  {
1250
1260
  name: "[Gen 8] Inheritance",
1251
1261
  desc: `Pok&eacute;mon may use the ability and moves of another, as long as they forfeit their own learnset.`,
@@ -1768,6 +1778,67 @@ export const Formats: FormatList = [
1768
1778
  pokemon.m.innates = undefined;
1769
1779
  },
1770
1780
  },
1781
+ {
1782
+ name: "[Gen 8] Shared Power",
1783
+ desc: `Once a Pok&eacute;mon switches in, its ability is shared with the rest of the team.`,
1784
+ threads: [
1785
+ `&bullet; <a href="https://www.smogon.com/forums/threads/3660877/">Shared Power</a>`,
1786
+ ],
1787
+
1788
+ mod: 'sharedpower',
1789
+ searchShow: false,
1790
+ ruleset: ['Standard', 'Dynamax Clause'],
1791
+ banlist: [
1792
+ 'Calyrex-Ice', 'Calyrex-Shadow', 'Darmanitan-Galar', 'Dialga', 'Dracovish', 'Eternatus', 'Genesect', 'Giratina',
1793
+ 'Giratina-Origin', 'Groudon', 'Ho-Oh', 'Kyogre', 'Kyurem-Black', 'Kyurem-White', 'Lugia', 'Lunala', 'Magearna',
1794
+ 'Marshadow', 'Melmetal', 'Mewtwo', 'Naganadel', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane', 'Palkia',
1795
+ 'Pheromosa', 'Rayquaza', 'Reshiram', 'Shedinja', 'Solgaleo', 'Urshifu-Base', 'Urshifu-Rapid-Strike',
1796
+ 'Xerneas', 'Yveltal', 'Zacian', 'Zacian-Crowned', 'Zamazenta', 'Zamazenta-Crowned', 'Zekrom',
1797
+ 'Arena Trap', 'Contrary', 'Drizzle ++ Swift Swim', 'Drought ++ Chlorophyll', 'Electric Surge ++ Surge Surfer',
1798
+ 'Fur Coat', 'Guts', 'Harvest', 'Huge Power', 'Imposter', 'Innards Out', 'Libero', 'Magic Bounce', 'Magic Guard',
1799
+ 'Magnet Pull', 'Mold Breaker', 'Moody', 'Neutralizing Gas', 'Power Construct', 'Queenly Majesty', 'Quick Draw',
1800
+ 'Regenerator', 'Sand Rush', 'Sand Veil', 'Shadow Tag', 'Simple', 'Snow Cloak', 'Snow Warning ++ Slush Rush',
1801
+ 'Speed Boost', 'Stakeout', 'Steelworker ++ Steely Spirit', 'Stench', 'Tinted Lens', 'Triage', 'Unaware',
1802
+ 'Unburden', 'Water Bubble', 'King\'s Rock', 'Baton Pass',
1803
+ ],
1804
+ getSharedPower(pokemon) {
1805
+ const sharedPower = new Set<string>();
1806
+ for (const ally of pokemon.side.pokemon) {
1807
+ if (ally.previouslySwitchedIn > 0) {
1808
+ if (pokemon.battle.dex.currentMod !== 'sharedpower' && ['trace', 'mirrorarmor'].includes(ally.baseAbility)) {
1809
+ sharedPower.add('noability');
1810
+ continue;
1811
+ }
1812
+ sharedPower.add(ally.baseAbility);
1813
+ }
1814
+ }
1815
+ sharedPower.delete(pokemon.baseAbility);
1816
+ return sharedPower;
1817
+ },
1818
+ onBeforeSwitchIn(pokemon) {
1819
+ let format = this.format;
1820
+ if (!format.getSharedPower) format = this.dex.formats.get('gen8sharedpower');
1821
+ for (const ability of format.getSharedPower!(pokemon)) {
1822
+ const effect = 'ability:' + ability;
1823
+ pokemon.volatiles[effect] = {id: this.toID(effect), target: pokemon};
1824
+ if (!pokemon.m.abils) pokemon.m.abils = [];
1825
+ if (!pokemon.m.abils.includes(effect)) pokemon.m.abils.push(effect);
1826
+ }
1827
+ },
1828
+ onSwitchInPriority: 2,
1829
+ onSwitchIn(pokemon) {
1830
+ let format = this.format;
1831
+ if (!format.getSharedPower) format = this.dex.formats.get('gen8sharedpower');
1832
+ for (const ability of format.getSharedPower!(pokemon)) {
1833
+ if (ability === 'noability') {
1834
+ this.hint(`Mirror Armor and Trace break in Shared Power formats that don't use Shared Power as a base, so they get removed from non-base users.`);
1835
+ }
1836
+ const effect = 'ability:' + ability;
1837
+ delete pokemon.volatiles[effect];
1838
+ pokemon.addVolatile(effect);
1839
+ }
1840
+ },
1841
+ },
1771
1842
  {
1772
1843
  name: "[Gen 8] Trademarked",
1773
1844
  desc: `Sacrifice your Pok&eacute;mon's ability for a status move that activates on switch-in.`,
@@ -2042,7 +2113,6 @@ export const Formats: FormatList = [
2042
2113
 
2043
2114
  mod: 'sharedpower',
2044
2115
  team: 'random',
2045
- searchShow: false,
2046
2116
  ruleset: ['[Gen 8] Random Battle', 'Team Preview', 'Dynamax Clause', 'Camomons Mod', 'Inverse Mod', 'Scalemons Mod'],
2047
2117
  onBeforeSwitchIn(pokemon) {
2048
2118
  let format = this.format;
@@ -2345,45 +2415,40 @@ export const Formats: FormatList = [
2345
2415
  column: 3,
2346
2416
  },
2347
2417
  {
2348
- name: "[Gen 4] UU",
2418
+ name: "[Gen 5] UU",
2349
2419
  threads: [
2350
- `&bullet; <a href="https://www.smogon.com/forums/threads/3532624/">DPP UU Metagame Discussion</a>`,
2351
- `&bullet; <a href="https://www.smogon.com/forums/threads/3503638/">DPP UU Viability Rankings</a>`,
2420
+ `&bullet; <a href="https://www.smogon.com/forums/threads/3474024/">BW2 UU Viability Rankings</a>`,
2421
+ `&bullet; <a href="https://www.smogon.com/forums/posts/6431094/">BW2 Sample Teams</a>`,
2352
2422
  ],
2353
2423
 
2354
- mod: 'gen4',
2424
+ mod: 'gen5',
2355
2425
  // searchShow: false,
2356
- ruleset: ['[Gen 4] OU'],
2357
- banlist: ['OU', 'UUBL'],
2358
- unbanlist: ['Arena Trap', 'Swagger'],
2426
+ ruleset: ['Standard', 'Evasion Abilities Clause', 'Swagger Clause', 'Sleep Clause Mod'],
2427
+ banlist: ['Uber', 'OU', 'UUBL', 'Arena Trap', 'Drought', 'Sand Stream', 'Snow Warning', 'Prankster + Assist', 'Prankster + Copycat', 'Baton Pass'],
2359
2428
  },
2360
2429
  {
2361
- name: "[Gen 7] LC",
2430
+ name: "[Gen 5] NU",
2362
2431
  threads: [
2363
- `&bullet; <a href="https://www.smogon.com/dex/sm/formats/lc/">USM LC Banlist</a>`,
2364
- `&bullet; <a href="https://www.smogon.com/forums/threads/3639319/">USM LC Sample Teams</a>`,
2365
- `&bullet; <a href="https://www.smogon.com/forums/threads/3621440/">USM LC Viability Rankings</a>`,
2432
+ `&bullet; <a href="https://www.smogon.com/forums/posts/6431094/">BW2 Sample Teams</a>`,
2433
+ `&bullet; <a href="https://www.smogon.com/forums/threads/3484121/">BW2 NU Viability Rankings</a>`,
2366
2434
  ],
2367
2435
 
2368
- mod: 'gen7',
2436
+ mod: 'gen5',
2369
2437
  // searchShow: false,
2370
- ruleset: ['Little Cup', 'Standard', 'Swagger Clause'],
2371
- banlist: [
2372
- 'Aipom', 'Cutiefly', 'Drifloon', 'Gligar', 'Gothita', 'Meditite', 'Misdreavus', 'Murkrow', 'Porygon',
2373
- 'Scyther', 'Sneasel', 'Swirlix', 'Tangela', 'Trapinch', 'Vulpix-Base', 'Wingull', 'Yanma',
2374
- 'Eevium Z', 'Baton Pass', 'Dragon Rage', 'Sonic Boom', 'Sticky Web',
2375
- ],
2438
+ ruleset: ['[Gen 5] RU', '!Sleep Moves Clause', 'Sleep Clause Mod'],
2439
+ banlist: ['RU', 'NUBL', 'Assist', 'Copycat'],
2376
2440
  },
2377
2441
  {
2378
- name: "[Gen 5] PU",
2442
+ name: "[Gen 6] PU",
2379
2443
  threads: [
2380
- `&bullet; <a href="https://www.smogon.com/forums/posts/7326932/">BW2 PU</a>`,
2444
+ `&bullet; <a href="https://www.smogon.com/dex/xy/tags/pu/">ORAS PU Banlist</a>`,
2445
+ `&bullet; <a href="https://www.smogon.com/forums/threads/3528743/">ORAS PU Viability Rankings</a>`,
2381
2446
  ],
2382
2447
 
2383
- mod: 'gen5',
2448
+ mod: 'gen6',
2384
2449
  // searchShow: false,
2385
- ruleset: ['[Gen 5] NU', 'Sleep Moves Clause'],
2386
- banlist: ['NU', 'PUBL'],
2450
+ ruleset: ['[Gen 6] NU'],
2451
+ banlist: ['NU', 'PUBL', 'Chatter'],
2387
2452
  },
2388
2453
 
2389
2454
  // Past Gens OU
@@ -2676,6 +2741,23 @@ export const Formats: FormatList = [
2676
2741
  ruleset: ['[Gen 7] NU'],
2677
2742
  banlist: ['NU', 'PUBL'],
2678
2743
  },
2744
+ {
2745
+ name: "[Gen 7] LC",
2746
+ threads: [
2747
+ `&bullet; <a href="https://www.smogon.com/dex/sm/formats/lc/">USM LC Banlist</a>`,
2748
+ `&bullet; <a href="https://www.smogon.com/forums/threads/3639319/">USM LC Sample Teams</a>`,
2749
+ `&bullet; <a href="https://www.smogon.com/forums/threads/3621440/">USM LC Viability Rankings</a>`,
2750
+ ],
2751
+
2752
+ mod: 'gen7',
2753
+ searchShow: false,
2754
+ ruleset: ['Little Cup', 'Standard', 'Swagger Clause'],
2755
+ banlist: [
2756
+ 'Aipom', 'Cutiefly', 'Drifloon', 'Gligar', 'Gothita', 'Meditite', 'Misdreavus', 'Murkrow', 'Porygon',
2757
+ 'Scyther', 'Sneasel', 'Swirlix', 'Tangela', 'Trapinch', 'Vulpix-Base', 'Wingull', 'Yanma',
2758
+ 'Eevium Z', 'Baton Pass', 'Dragon Rage', 'Sonic Boom', 'Sticky Web',
2759
+ ],
2760
+ },
2679
2761
  {
2680
2762
  name: "[Gen 7] Monotype",
2681
2763
  desc: `All the Pok&eacute;mon on a team must share a type.`,
@@ -2963,18 +3045,6 @@ export const Formats: FormatList = [
2963
3045
  ruleset: ['[Gen 6] RU'],
2964
3046
  banlist: ['RU', 'NUBL'],
2965
3047
  },
2966
- {
2967
- name: "[Gen 6] PU",
2968
- threads: [
2969
- `&bullet; <a href="https://www.smogon.com/dex/xy/tags/pu/">ORAS PU Banlist</a>`,
2970
- `&bullet; <a href="https://www.smogon.com/forums/threads/3528743/">ORAS PU Viability Rankings</a>`,
2971
- ],
2972
-
2973
- mod: 'gen6',
2974
- searchShow: false,
2975
- ruleset: ['[Gen 6] NU'],
2976
- banlist: ['NU', 'PUBL', 'Chatter'],
2977
- },
2978
3048
  {
2979
3049
  name: "[Gen 6] LC",
2980
3050
  threads: [
@@ -3203,18 +3273,6 @@ export const Formats: FormatList = [
3203
3273
  searchShow: false,
3204
3274
  ruleset: ['Standard', 'Sleep Clause Mod'],
3205
3275
  },
3206
- {
3207
- name: "[Gen 5] UU",
3208
- threads: [
3209
- `&bullet; <a href="https://www.smogon.com/forums/threads/3474024/">BW2 UU Viability Rankings</a>`,
3210
- `&bullet; <a href="https://www.smogon.com/forums/posts/6431094/">BW2 Sample Teams</a>`,
3211
- ],
3212
-
3213
- mod: 'gen5',
3214
- searchShow: false,
3215
- ruleset: ['Standard', 'Evasion Abilities Clause', 'Swagger Clause', 'Sleep Clause Mod'],
3216
- banlist: ['Uber', 'OU', 'UUBL', 'Arena Trap', 'Drought', 'Sand Stream', 'Snow Warning', 'Prankster + Assist', 'Prankster + Copycat', 'Baton Pass'],
3217
- },
3218
3276
  {
3219
3277
  name: "[Gen 5] RU",
3220
3278
  threads: [
@@ -3229,16 +3287,15 @@ export const Formats: FormatList = [
3229
3287
  unbanlist: ['Prankster + Assist', 'Prankster + Copycat', 'Baton Pass'],
3230
3288
  },
3231
3289
  {
3232
- name: "[Gen 5] NU",
3290
+ name: "[Gen 5] PU",
3233
3291
  threads: [
3234
- `&bullet; <a href="https://www.smogon.com/forums/posts/6431094/">BW2 Sample Teams</a>`,
3235
- `&bullet; <a href="https://www.smogon.com/forums/threads/3484121/">BW2 NU Viability Rankings</a>`,
3292
+ `&bullet; <a href="https://www.smogon.com/forums/posts/7326932/">BW2 PU</a>`,
3236
3293
  ],
3237
3294
 
3238
3295
  mod: 'gen5',
3239
3296
  searchShow: false,
3240
- ruleset: ['[Gen 5] RU', '!Sleep Moves Clause', 'Sleep Clause Mod'],
3241
- banlist: ['RU', 'NUBL', 'Assist', 'Copycat'],
3297
+ ruleset: ['[Gen 5] NU', 'Sleep Moves Clause'],
3298
+ banlist: ['NU', 'PUBL'],
3242
3299
  },
3243
3300
  {
3244
3301
  name: "[Gen 5] LC",
@@ -3329,7 +3386,7 @@ export const Formats: FormatList = [
3329
3386
  gameType: 'doubles',
3330
3387
  searchShow: false,
3331
3388
  ruleset: ['Flat Rules'],
3332
- banlist: ['Dark Void', 'Sky Drop', 'Soul Dew'],
3389
+ banlist: ['Chatot', 'Dark Void', 'Sky Drop', 'Soul Dew'],
3333
3390
  },
3334
3391
  {
3335
3392
  name: "[Gen 5] VGC 2012",
@@ -3390,6 +3447,19 @@ export const Formats: FormatList = [
3390
3447
  ruleset: ['Standard'],
3391
3448
  banlist: ['AG'],
3392
3449
  },
3450
+ {
3451
+ name: "[Gen 4] UU",
3452
+ threads: [
3453
+ `&bullet; <a href="https://www.smogon.com/forums/threads/3532624/">DPP UU Metagame Discussion</a>`,
3454
+ `&bullet; <a href="https://www.smogon.com/forums/threads/3503638/">DPP UU Viability Rankings</a>`,
3455
+ ],
3456
+
3457
+ mod: 'gen4',
3458
+ searchShow: false,
3459
+ ruleset: ['[Gen 4] OU'],
3460
+ banlist: ['OU', 'UUBL'],
3461
+ unbanlist: ['Arena Trap', 'Swagger'],
3462
+ },
3393
3463
  {
3394
3464
  name: "[Gen 4] NU",
3395
3465
  threads: [
@@ -3504,7 +3574,7 @@ export const Formats: FormatList = [
3504
3574
  gameType: 'doubles',
3505
3575
  searchShow: false,
3506
3576
  ruleset: ['Flat Rules', '! Adjust Level Down', 'Max Level = 50', 'Max Team Size = 4'],
3507
- banlist: ['Soul Dew', 'Rotom-Heat', 'Rotom-Wash', 'Rotom-Frost', 'Rotom-Fan', 'Rotom-Mow'],
3577
+ banlist: ['Tyranitar', 'Rotom', 'Judgment', 'Soul Dew'],
3508
3578
  },
3509
3579
  {
3510
3580
  name: "[Gen 4] Doubles Custom Game",