@pkmn/sim 0.4.20 → 0.4.24

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 (88) hide show
  1. package/build/config/formats.js +415 -688
  2. package/build/config/formats.js.map +1 -1
  3. package/build/data/aliases.js +7 -5
  4. package/build/data/aliases.js.map +1 -1
  5. package/build/data/conditions.js +4 -1
  6. package/build/data/conditions.js.map +1 -1
  7. package/build/data/formats-data.js +18 -18
  8. package/build/data/formats-data.js.map +1 -1
  9. package/build/data/learnsets.js +10 -8
  10. package/build/data/learnsets.js.map +1 -1
  11. package/build/data/mods/gen1/moves.js +1 -1
  12. package/build/data/mods/gen1/moves.js.map +1 -1
  13. package/build/data/mods/gen1/scripts.js +18 -22
  14. package/build/data/mods/gen1/scripts.js.map +1 -1
  15. package/build/data/mods/gen2/scripts.js +16 -23
  16. package/build/data/mods/gen2/scripts.js.map +1 -1
  17. package/build/data/mods/gen3/moves.js +2 -1
  18. package/build/data/mods/gen3/moves.js.map +1 -1
  19. package/build/data/mods/gen4/conditions.js +6 -0
  20. package/build/data/mods/gen4/conditions.js.map +1 -1
  21. package/build/data/mods/gen4/moves.js +2 -1
  22. package/build/data/mods/gen4/moves.js.map +1 -1
  23. package/build/data/mods/gen4/scripts.js +2 -1
  24. package/build/data/mods/gen4/scripts.js.map +1 -1
  25. package/build/data/mods/gen6/conditions.js +4 -1
  26. package/build/data/mods/gen6/conditions.js.map +1 -1
  27. package/build/data/mods/gen7/formats-data.js +2 -2
  28. package/build/data/mods/gen7/formats-data.js.map +1 -1
  29. package/build/data/mods/gen7/moves.js +8 -0
  30. package/build/data/mods/gen7/moves.js.map +1 -1
  31. package/build/data/moves.js +25 -13
  32. package/build/data/moves.js.map +1 -1
  33. package/build/data/rulesets.js +221 -1
  34. package/build/data/rulesets.js.map +1 -1
  35. package/build/data/tags.js +2 -2
  36. package/build/data/tags.js.map +1 -1
  37. package/build/lib/streams.d.ts +1 -199
  38. package/build/lib/streams.js +11 -772
  39. package/build/lib/streams.js.map +1 -1
  40. package/build/sim/battle-actions.d.ts +1 -1
  41. package/build/sim/battle-actions.js +18 -42
  42. package/build/sim/battle-actions.js.map +1 -1
  43. package/build/sim/battle.d.ts +1 -0
  44. package/build/sim/battle.js +5 -0
  45. package/build/sim/battle.js.map +1 -1
  46. package/build/sim/dex-moves.d.ts +31 -11
  47. package/build/sim/dex-moves.js +4 -3
  48. package/build/sim/dex-moves.js.map +1 -1
  49. package/build/sim/dex-species.js +11 -1
  50. package/build/sim/dex-species.js.map +1 -1
  51. package/build/sim/exported-global-types.d.ts +1 -0
  52. package/build/sim/global-types.d.ts +1 -0
  53. package/build/sim/side.js +2 -2
  54. package/build/sim/side.js.map +1 -1
  55. package/build/sim/team-validator.js +2 -2
  56. package/build/sim/team-validator.js.map +1 -1
  57. package/build/sim/tools/runner.d.ts +1 -6
  58. package/build/sim/tools/runner.js +6 -6
  59. package/build/sim/tools/runner.js.map +1 -1
  60. package/config/formats.ts +393 -643
  61. package/data/aliases.ts +7 -5
  62. package/data/conditions.ts +4 -1
  63. package/data/formats-data.ts +18 -18
  64. package/data/learnsets.ts +10 -8
  65. package/data/mods/gen1/moves.ts +1 -1
  66. package/data/mods/gen1/scripts.ts +23 -19
  67. package/data/mods/gen2/scripts.ts +20 -19
  68. package/data/mods/gen3/moves.ts +2 -1
  69. package/data/mods/gen4/conditions.ts +6 -0
  70. package/data/mods/gen4/moves.ts +2 -1
  71. package/data/mods/gen4/scripts.ts +1 -1
  72. package/data/mods/gen6/conditions.ts +4 -1
  73. package/data/mods/gen7/formats-data.ts +2 -2
  74. package/data/mods/gen7/moves.ts +8 -0
  75. package/data/moves.ts +22 -13
  76. package/data/rulesets.ts +199 -1
  77. package/data/tags.ts +2 -2
  78. package/lib/streams.ts +1 -874
  79. package/package.json +3 -2
  80. package/sim/battle-actions.ts +19 -40
  81. package/sim/battle.ts +6 -0
  82. package/sim/dex-moves.ts +35 -13
  83. package/sim/dex-species.ts +10 -1
  84. package/sim/exported-global-types.ts +1 -0
  85. package/sim/global-types.ts +1 -0
  86. package/sim/side.ts +2 -2
  87. package/sim/team-validator.ts +2 -2
  88. package/sim/tools/runner.ts +2 -0
@@ -52,6 +52,12 @@ exports.Formats = [
52
52
  rated: false,
53
53
  ruleset: ['Obtainable', 'Species Clause', 'HP Percentage Mod', 'Cancel Mod', 'Sleep Clause Mod'],
54
54
  },
55
+ {
56
+ name: "[Gen 8] Random Battle (Blitz)",
57
+ mod: 'gen8',
58
+ team: 'random',
59
+ ruleset: ['[Gen 8] Random Battle', 'Blitz'],
60
+ },
55
61
  {
56
62
  name: "[Gen 8] Multi Random Battle",
57
63
  mod: 'gen8',
@@ -123,8 +129,8 @@ exports.Formats = [
123
129
  ],
124
130
  mod: 'gen8',
125
131
  ruleset: ['[Gen 8] RU'],
126
- banlist: ['RU', 'NUBL', 'Drizzle', 'Drought', 'Snow Warning'],
127
- unbanlist: ['Snorlax'],
132
+ banlist: ['RU', 'NUBL', 'Drizzle', 'Drought'],
133
+ unbanlist: ['Indeedee'],
128
134
  },
129
135
  {
130
136
  name: "[Gen 8] PU",
@@ -134,7 +140,7 @@ exports.Formats = [
134
140
  ],
135
141
  mod: 'gen8',
136
142
  ruleset: ['[Gen 8] NU'],
137
- banlist: ['NU', 'PUBL', 'Snorlax'],
143
+ banlist: ['NU', 'PUBL', 'Indeedee'],
138
144
  },
139
145
  {
140
146
  name: "[Gen 8] LC",
@@ -220,8 +226,8 @@ exports.Formats = [
220
226
  ruleset: ['[Gen 8] LC'],
221
227
  banlist: [
222
228
  // LC OU
223
- 'Abra', 'Archen', 'Carvanha', 'Dewpider', 'Diglett-Base', 'Dwebble', 'Ferroseed', 'Foongus', 'Frillish', 'Grookey',
224
- 'Koffing', 'Larvesta', 'Magnemite', 'Mareanie', 'Mienfoo', 'Mudbray', 'Munchlax', 'Natu', 'Onix', 'Pawniard', 'Ponyta',
229
+ 'Abra', 'Archen', 'Carvanha', 'Diglett-Base', 'Dwebble', 'Ferroseed', 'Foongus', 'Frillish', 'Grookey', 'Koffing',
230
+ 'Larvesta', 'Magnemite', 'Mareanie', 'Mienfoo', 'Mudbray', 'Munchlax', 'Natu', 'Onix', 'Pawniard', 'Ponyta',
225
231
  'Ponyta-Galar', 'Porygon', 'Slowpoke-Base', 'Spritzee', 'Staryu', 'Timburr', 'Trapinch', 'Tyrunt', 'Vulpix',
226
232
  // LC UUBL
227
233
  'Farfetch\u2019d-Galar', 'Scorbunny', 'Shellder', 'Wingull',
@@ -240,6 +246,11 @@ exports.Formats = [
240
246
  },
241
247
  {
242
248
  name: "[Gen 8] CAP LC",
249
+ threads: [
250
+ `&bullet; <a href="https://www.smogon.com/forums/threads/3691918/">CAP LC Metagame Discussion</a>`,
251
+ `&bullet; <a href="https://www.smogon.com/forums/posts/8997714/">CAP LC Sample Teams</a>`,
252
+ `&bullet; <a href="https://www.smogon.com/forums/posts/8997713/">CAP LC Viability Rankings</a>`,
253
+ ],
243
254
  mod: 'gen8',
244
255
  searchShow: false,
245
256
  ruleset: ['[Gen 8] LC', '+CAP'],
@@ -247,7 +258,7 @@ exports.Formats = [
247
258
  {
248
259
  name: "[Gen 8] Battle Stadium Singles",
249
260
  mod: 'gen8',
250
- ruleset: ['Flat Rules', '!! Adjust Level = 50', 'Min Source Gen = 8', 'Limit One Restricted', 'Dynamax Clause'],
261
+ ruleset: ['Flat Rules', '!! Adjust Level = 50', 'Min Source Gen = 8', 'Limit One Restricted'],
251
262
  restricted: ['Restricted Legendary'],
252
263
  },
253
264
  {
@@ -325,15 +336,10 @@ exports.Formats = [
325
336
  banlist: ['Corsola-Galar', 'Cutiefly', 'Ponyta-Base', 'Scyther', 'Sneasel', 'Swirlix', 'Tangela', 'Vulpix', 'Vulpix-Alola'],
326
337
  },
327
338
  {
328
- name: "[Gen 8] VGC 2021 Series 10",
329
- threads: [
330
- `&bullet; <a href="https://www.smogon.com/forums/threads/3677186/">VGC 2021 Series 10 Metagame Discussion</a>`,
331
- `&bullet; <a href="https://www.smogon.com/forums/threads/3689153/">VGC 2021 Series 10 Sample Teams</a>`,
332
- `&bullet; <a href="https://www.smogon.com/forums/threads/3688166/">VGC 2021 Series 10 Viability Rankings</a>`,
333
- ],
339
+ name: "[Gen 8] VGC 2021 Series 11",
334
340
  mod: 'gen8',
335
341
  gameType: 'doubles',
336
- ruleset: ['Flat Rules', '!! Adjust Level = 50', 'Min Source Gen = 8', 'VGC Timer', 'Limit One Restricted', 'Dynamax Clause'],
342
+ ruleset: ['Flat Rules', '!! Adjust Level = 50', 'Min Source Gen = 8', 'VGC Timer', 'Limit One Restricted'],
337
343
  restricted: ['Restricted Legendary'],
338
344
  },
339
345
  {
@@ -350,33 +356,6 @@ exports.Formats = [
350
356
  searchShow: false,
351
357
  ruleset: ['Flat Rules', '!! Adjust Level = 50', 'Min Source Gen = 8', 'VGC Timer'],
352
358
  },
353
- {
354
- name: "[Gen 8] Spooky Cup 2021",
355
- threads: [
356
- `&bull; <a href="https://www.smogon.com/forums/threads/3691909/">Spooky Cup 2021</a>`,
357
- ],
358
- mod: 'gen8',
359
- gameType: 'doubles',
360
- ruleset: ['Flat Rules', '!! Adjust Level = 50', 'Min Source Gen = 8'],
361
- onValidateSet(set) {
362
- const spookyMonsList = [
363
- 'Vileplume', 'Tentacruel', 'Gengar', 'Marowak', 'Weezing', 'Mr. Mime', 'Pinsir', 'Ditto', 'Omastar', 'Kabutops', 'Aerodactyl',
364
- 'Noctowl', 'Crobat', 'Espeon', 'Umbreon', 'Wobbuffet', 'Shiftry', 'Shedinja', 'Exploud', 'Sableye', 'Mawile', 'Sharpedo',
365
- 'Lunatone', 'Crawdaunt', 'Baltoy', 'Claydol', 'Absol', 'Glalie', 'Drifblim', 'Skuntank', 'Spiritomb', 'Drapion', 'Toxicroak',
366
- 'Abomasnow', 'Weavile', 'Tangrowth', 'Electivire', 'Magmortar', 'Dusknoir', 'Froslass', 'Rotom', 'Liepard', 'Gigalith',
367
- 'Swoobat', 'Scolipede', 'Basculin', 'Krookodile', 'Sigilyph', 'Cofagrigus', 'Garbodor', 'Zoroark', 'Gothitelle', 'Jellicent',
368
- 'Galvantula', 'Beheeyem', 'Chandelure', 'Golurk', 'Bisharp', 'Mandibuzz', 'Hydreigon', 'Volcarona', 'Pangoro', 'Meowstic',
369
- 'Aegislash', 'Slurpuff', 'Malamar', 'Trevenant', 'Gourgeist', 'Noivern', 'Decidueye', 'Incineroar', 'Toxapex', 'Araquanid',
370
- 'Shiinotic', 'Salazzle', 'Bewear', 'Golisopod', 'Palossand', 'Silvally', 'Mimikyu', 'Dhelmise', 'Nihilego', 'Xurkitree',
371
- 'Guzzlord', 'Poipole', 'Naganadel', 'Blacephalon', 'Corviknight', 'Orbeetle', 'Thievul', 'Coalossal', 'Centiskorch', 'Grapploct',
372
- 'Polteageist', 'Hatterene', 'Grimmsnarl', 'Obstagoon', 'Cursola', 'Mr. Rime', 'Runerigus', 'Dracovish', 'Dragapult', 'Spectrier',
373
- ];
374
- const species = this.dex.species.get(set.species);
375
- if (!spookyMonsList.includes(species.baseSpecies) && species.id !== 'lycanrocmidnight') {
376
- return [`${species.name} is banned for not looking spooky enough.`];
377
- }
378
- },
379
- },
380
359
  {
381
360
  name: "[Gen 8] 2v2 Doubles",
382
361
  desc: `Double battle where you bring four Pok&eacute;mon to Team Preview and choose only two.`,
@@ -513,8 +492,8 @@ exports.Formats = [
513
492
  'Arceus', 'Blastoise-Mega', 'Blaziken', 'Calyrex-Ice', 'Calyrex-Shadow', 'Darkrai', 'Deoxys-Base', 'Deoxys-Attack', 'Dialga', 'Dracovish', 'Dragapult',
514
493
  'Eternatus', 'Genesect', 'Gengar-Mega', 'Giratina', 'Giratina-Origin', 'Groudon', 'Ho-Oh', 'Hoopa-Unbound', 'Kangaskhan-Mega', 'Kartana', 'Kyogre',
515
494
  'Kyurem-Black', 'Kyurem-White', 'Lucario-Mega', 'Lugia', 'Lunala', 'Magearna', 'Marshadow', 'Mawile-Mega', 'Medicham-Mega', 'Metagross-Mega', 'Mewtwo',
516
- 'Naganadel', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane', 'Palkia', 'Pheromosa', 'Rayquaza', 'Reshiram', 'Salamence-Mega', 'Shaymin-Sky', 'Solgaleo',
517
- 'Spectrier', 'Urshifu-Base', 'Xerneas', 'Yveltal', 'Zacian', 'Zacian-Crowned', 'Zamazenta', 'Zamazenta-Crowned', 'Zekrom', 'Zygarde-Base',
495
+ 'Moltres-Galar', 'Naganadel', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane', 'Palkia', 'Pheromosa', 'Rayquaza', 'Reshiram', 'Salamence-Mega', 'Shaymin-Sky',
496
+ 'Solgaleo', 'Spectrier', 'Urshifu-Base', 'Xerneas', 'Yveltal', 'Zacian', 'Zacian-Crowned', 'Zamazenta', 'Zamazenta-Crowned', 'Zekrom', 'Zygarde-Base',
518
497
  'Battle Bond', 'Moody', 'Power Construct', 'Shadow Tag',
519
498
  'Bright Powder', 'Damp Rock', 'Focus Band', 'King\'s Rock', 'Lax Incense', 'Quick Claw', 'Smooth Rock', 'Terrain Extender', 'Baton Pass',
520
499
  ],
@@ -538,6 +517,7 @@ exports.Formats = [
538
517
  `&bullet; <a href="https://www.smogon.com/forums/threads/3674163/">Fusion Evolution UU</a>`,
539
518
  ],
540
519
  mod: "fusionevolutionuu",
520
+ searchShow: false,
541
521
  ruleset: ['Standard NatDex', 'OHKO Clause', 'Evasion Moves Clause', 'Species Clause', 'Dynamax Clause', 'Sleep Clause Mod', 'Z-Move Clause', 'Data Mod', 'Mega Data Mod'],
542
522
  banlist: [
543
523
  'All Pokemon', 'Lopunnite', 'Tapu Lop-Mega', 'Red Orb', 'Grousle-Primal',
@@ -579,231 +559,43 @@ exports.Formats = [
579
559
  column: 2,
580
560
  },
581
561
  {
582
- name: "[Gen 8] Multibility",
583
- desc: `Run a second ability at the cost of giving up a Pok&eacute;mon's item slot.`,
562
+ name: "[Gen 8] Sketchmons",
563
+ desc: `Pok&eacute;mon can learn one of any move they don't normally learn, barring the few that are banned.`,
584
564
  threads: [
585
- `&bullet; <a href="https://www.smogon.com/forums/threads/3688892/">Multibility</a>`,
565
+ `&bullet; <a href="https://www.smogon.com/forums/threads/3680298/">Sketchmons</a>`,
586
566
  ],
587
567
  mod: 'gen8',
588
- ruleset: ['Standard', 'Dynamax Clause', '2 Ability Clause', 'Sleep Moves Clause', '!Sleep Clause Mod'],
568
+ ruleset: ['Standard', 'Dynamax Clause', 'Sketchmons Move Legality'],
589
569
  banlist: [
590
- 'Calyrex-Ice', 'Calyrex-Shadow', 'Cinderace', 'Darmanitan-Galar', 'Dialga', 'Dracovish', 'Dragonite', 'Eternatus',
591
- 'Genesect', 'Giratina', 'Giratina-Origin', 'Groudon', 'Ho-Oh', 'Kartana', 'Kyogre', 'Kyurem-Black', 'Kyurem-White',
592
- 'Lugia', 'Lunala', 'Magearna', 'Marshadow', 'Melmetal', 'Mewtwo', 'Naganadel', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane',
593
- 'Palkia', 'Pheromosa', 'Rayquaza', 'Reshiram', 'Shedinja', 'Solgaleo', 'Spectrier', 'Urshifu-Base', 'Xerneas',
594
- 'Yveltal', 'Zacian', 'Zacian-Crowned', 'Zamazenta', 'Zamazenta-Crowned', 'Zekrom', 'Zygarde-Base', 'Arena Trap',
595
- 'Chlorophyll', 'Magnet Pull', 'Moody', 'Power Construct', 'Sand Rush', 'Shadow Tag', 'Slush Rush', 'Swift Swim',
596
- 'Stench', 'Trace', 'King\'s Rock', 'Baton Pass',
570
+ 'Calyrex-Ice', 'Calyrex-Shadow', 'Cinderace', 'Darmanitan-Galar', 'Dialga', 'Dracovish', 'Dragapult', 'Eternatus', 'Genesect',
571
+ 'Giratina', 'Giratina-Origin', 'Groudon', 'Hawlucha', 'Ho-Oh', 'Kartana', 'Kyogre', 'Kyurem-Black', 'Kyurem-White', 'Landorus-Base',
572
+ 'Lugia', 'Lunala', 'Marshadow', 'Mewtwo', 'Naganadel', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane', 'Palkia', 'Pheromosa',
573
+ 'Porygon-Z', 'Rayquaza', 'Regieleki', 'Reshiram', 'Rillaboom', 'Shedinja', 'Solgaleo', 'Spectrier', 'Swoobat', 'Tapu Bulu',
574
+ 'Urshifu-Base', 'Xerneas', 'Yveltal', 'Zacian', 'Zacian-Crowned', 'Zamazenta', 'Zamazenta-Crowned', 'Zekrom', 'Zeraora', 'Zygarde-Base',
575
+ 'Arena Trap', 'Moody', 'Power Construct', 'Sand Rush', 'Shadow Tag', 'King\'s Rock', 'Baton Pass',
597
576
  ],
598
577
  restricted: [
599
- 'Comatose', 'Contrary', 'Fluffy', 'Fur Coat', 'Huge Power', 'Ice Scales', 'Illusion', 'Imposter', 'Innards Out',
600
- 'Intrepid Sword', 'Libero', 'Neutralizing Gas', 'Parental Bond', 'Protean', 'Pure Power', 'Simple', 'Speed Boost',
601
- 'Stakeout', 'Tinted Lens', 'Unaware', 'Water Bubble', 'Wonder Guard',
602
- 'Emergency Exit + Regenerator', 'Wimp Out + Regenerator',
578
+ 'Acupressure', 'Astral Barrage', 'Belly Drum', 'Bolt Beak', 'Clangorous Soul', 'Double Iron Bash', 'Electrify', 'Extreme Speed',
579
+ 'Fishious Rend', 'Geomancy', 'Glacial Lance', 'Lovely Kiss', 'No Retreat', 'Oblivion Wing', 'Octolock', 'Quiver Dance', 'Secret Sword',
580
+ 'Shell Smash', 'Shift Gear', 'Sleep Powder', 'Spore', 'Thousand Arrows', 'Transform', 'V-create', 'Wicked Blow',
603
581
  ],
604
- validateSet(set, teamHas) {
605
- const ability = this.dex.abilities.get(set.ability);
606
- const item = this.dex.abilities.get(set.item);
607
- if (!item.exists)
608
- return this.validateSet(set, teamHas);
609
- const problems = [];
610
- if (item.isNonstandard && !this.ruleTable.has(`+ability:${item.id}`)) {
611
- problems.push(`${item.name} is banned.`);
612
- }
613
- if (ability.id === item.id) {
614
- problems.push(`${set.species} has ${ability.name} as an ability and as an item.`);
615
- }
616
- if (this.ruleTable.isRestricted(`ability:${item.id}`) || this.ruleTable.isBanned(`ability:${item.id}`)) {
617
- problems.push(`${set.species}'s second ability (${item.name}) can only be used as an ability.`);
618
- }
619
- if ((ability.id === 'regenerator' && ['emergencyexit', 'wimpout'].includes(item.id)) ||
620
- (item.id === 'regenerator' && ['emergencyexit', 'wimpout'].includes(ability.id))) {
621
- problems.push(`${ability.name} and ${item.name} are banned together.`);
622
- }
623
- const itemStr = set.item;
624
- set.item = '';
625
- const problem = this.validateSet(set, teamHas);
626
- if (problem?.length)
627
- problems.push(...problem);
628
- set.item = itemStr;
629
- return problems;
630
- },
631
- onValidateTeam(team) {
632
- if (!this.ruleTable.has('2abilityclause'))
633
- return;
634
- const abilityTable = new Map();
635
- const base = {
636
- airlock: 'cloudnine',
637
- battlearmor: 'shellarmor',
638
- clearbody: 'whitesmoke',
639
- dazzling: 'queenlymajesty',
640
- emergencyexit: 'wimpout',
641
- filter: 'solidrock',
642
- gooey: 'tanglinghair',
643
- insomnia: 'vitalspirit',
644
- ironbarbs: 'roughskin',
645
- libero: 'protean',
646
- minus: 'plus',
647
- moxie: 'chillingneigh',
648
- powerofalchemy: 'receiver',
649
- propellertail: 'stalwart',
650
- teravolt: 'moldbreaker',
651
- turboblaze: 'moldbreaker',
652
- };
653
- const abilities = [];
654
- for (const set of team) {
655
- abilities.push([set.ability, set.item].map((abil) => {
656
- const id = this.toID(abil);
657
- return base[id] || id;
658
- }));
659
- }
660
- for (const [abilityid, itemid] of abilities) {
661
- const ability = this.dex.abilities.get(abilityid);
662
- const item = this.dex.abilities.get(itemid);
663
- if (ability.exists)
664
- abilityTable.set(ability.id, (abilityTable.get(ability.id) || 0) + 1);
665
- if (item.exists)
666
- abilityTable.set(item.id, (abilityTable.get(item.id) || 0) + 1);
667
- }
668
- for (const [abilityid, size] of abilityTable) {
669
- if (size > 2) {
670
- return [
671
- `You are limited to two of each ability by 2 Ability Clause.`,
672
- `(You have more than two ${this.dex.abilities.get(abilityid).name} variants)`,
673
- ];
674
- }
675
- }
676
- },
677
- onSwitchOut(pokemon) {
678
- const item = this.dex.abilities.get(pokemon.item);
679
- if (item.exists) {
680
- this.singleEvent('End', item, pokemon.itemState, pokemon);
681
- }
682
- },
683
- onFaint(pokemon) {
684
- const item = this.dex.abilities.get(pokemon.item);
685
- if (item.exists) {
686
- this.singleEvent('End', item, pokemon.itemState, pokemon);
687
- }
688
- },
689
- field: {
690
- suppressingWeather() {
691
- for (const pokemon of this.battle.getAllActive()) {
692
- const item = this.battle.dex.abilities.get(pokemon.item);
693
- if (pokemon && !pokemon.ignoringAbility() &&
694
- (pokemon.getAbility().suppressWeather || (item.exists && item.suppressWeather))) {
695
- return true;
696
- }
697
- }
698
- return false;
699
- },
700
- },
701
- pokemon: {
702
- getItem() {
703
- const ability = this.battle.dex.abilities.get(this.item);
704
- if (!ability.exists)
705
- return Object.getPrototypeOf(this).getItem.call(this);
706
- return { ...ability, ignoreKlutz: true, onTakeItem: false };
707
- },
708
- hasItem(item) {
709
- const ownItem = this.item;
710
- if (this.battle.dex.abilities.get(ownItem).exists)
711
- return false;
712
- if (this.ignoringItem())
713
- return false;
714
- if (!Array.isArray(item))
715
- return ownItem === this.battle.toID(item);
716
- return item.map(this.battle.toID).includes(ownItem);
717
- },
718
- hasAbility(ability) {
719
- if (this.ignoringAbility())
720
- return false;
721
- if (Array.isArray(ability))
722
- return ability.some(abil => this.hasAbility(abil));
723
- const abilityid = this.battle.toID(ability);
724
- const item = this.battle.dex.abilities.get(this.item);
725
- return this.ability === abilityid || (item.exists && item.id === abilityid);
726
- },
727
- ignoringAbility() {
728
- // Check if any active pokemon have the ability Neutralizing Gas
729
- let neutralizinggas = false;
730
- for (const pokemon of this.battle.getAllActive()) {
731
- // can't use hasAbility because it would lead to infinite recursion
732
- if ((pokemon.ability === 'neutralizinggas' || pokemon.item === 'neutralizinggas') &&
733
- !pokemon.volatiles['gastroacid'] && !pokemon.abilityState.ending) {
734
- neutralizinggas = true;
735
- break;
736
- }
737
- }
738
- return !!((this.battle.gen >= 5 && !this.isActive) ||
739
- ((this.volatiles['gastroacid'] || (neutralizinggas && this.ability !== 'neutralizinggas' &&
740
- this.item !== 'neutralizinggas')) && !this.getAbility().isPermanent));
741
- },
742
- ignoringItem() {
743
- let nGas = false;
744
- for (const pokemon of this.battle.getAllActive()) {
745
- // can't use hasAbility because it would lead to infinite recursion
746
- if (((pokemon.ability === 'neutralizinggas' && !pokemon.abilityState.ending) ||
747
- (pokemon.item === 'neutralizinggas' && !pokemon.itemState.ending)) &&
748
- !pokemon.volatiles['gastroacid'] && !pokemon.abilityState.ending) {
749
- nGas = true;
750
- break;
751
- }
752
- }
753
- const item = this.battle.dex.abilities.get(this.item);
754
- return !!((this.battle.gen >= 5 && !this.isActive) ||
755
- (this.hasAbility('klutz') && !this.getItem().ignoreKlutz) ||
756
- this.volatiles['embargo'] || this.battle.field.pseudoWeather['magicroom'] ||
757
- (item.exists && item.id !== 'neutralizinggas' && (nGas || this.volatiles['gastroacid'])));
758
- },
759
- takeItem(source) {
760
- if (!this.isActive)
761
- return false;
762
- if (!this.item)
763
- return false;
764
- if (this.battle.dex.abilities.get(this.item).exists)
765
- return false;
766
- if (!source)
767
- source = this;
768
- if (this.battle.gen === 4) {
769
- if (this.battle.toID(this.ability) === 'multitype')
770
- return false;
771
- if (source && this.battle.toID(source.ability) === 'multitype')
772
- return false;
773
- }
774
- const item = this.getItem();
775
- if (this.battle.runEvent('TakeItem', this, source, null, item)) {
776
- this.item = '';
777
- this.itemState = { id: '', target: this };
778
- this.pendingStaleness = undefined;
779
- return item;
780
- }
781
- return false;
782
- },
783
- },
784
582
  },
785
583
  {
786
- name: "[Gen 8] 350 Cup",
787
- desc: `Pok&eacute;mon with a BST of 350 or lower get their base stats doubled.`,
584
+ name: "[Gen 8] AAA Doubles",
585
+ desc: `Pok&eacute;mon have access to almost any ability, in a doubles setting.`,
788
586
  threads: [
789
- `&bullet; <a href="https://www.smogon.com/forums/threads/3656554/">350 Cup</a>`,
587
+ `&bullet; <a href="https://www.smogon.com/forums/posts/8299984">AAA Doubles</a>`,
790
588
  ],
791
589
  mod: 'gen8',
792
- ruleset: ['Standard', 'Dynamax Clause'],
793
- banlist: ['Abra', 'Gastly', 'Pawniard', 'Rufflet', 'Woobat', 'Arena Trap', 'Shadow Tag', 'Eviolite', 'Light Ball', 'Baton Pass'],
794
- onModifySpecies(species, target, source, effect) {
795
- if (effect && ['imposter', 'transform'].includes(effect.id))
796
- return;
797
- const newSpecies = this.dex.deepClone(species);
798
- if (newSpecies.bst <= 350) {
799
- newSpecies.bst = 0;
800
- for (const stat in newSpecies.baseStats) {
801
- newSpecies.baseStats[stat] *= 2;
802
- newSpecies.bst += newSpecies.baseStats[stat];
803
- }
804
- }
805
- return newSpecies;
806
- },
590
+ gameType: 'doubles',
591
+ ruleset: ['[Gen 8] Doubles OU', 'Sleep Clause Mod', '2 Ability Clause', '!Obtainable Abilities'],
592
+ banlist: [
593
+ 'Kyurem-Black', 'Regigigas', 'Shedinja', 'Urshifu-Rapid-Strike', 'Zygarde-Base', 'Anger Point', 'Arena Trap', 'Comatose', 'Contrary',
594
+ 'Dancer', 'Desolate Land', 'Fluffy', 'Fur Coat', 'Gorilla Tactics', 'Huge Power', 'Ice Scales', 'Illusion', 'Imposter', 'Innards Out',
595
+ 'Intrepid Sword', 'Libero', 'Moody', 'Neutralizing Gas', 'Parental Bond', 'Prankster', 'Primordial Sea', 'Protean', 'Pure Power',
596
+ 'Rattled', 'Serene Grace', 'Simple', 'Soul-Heart', 'Stakeout', 'Steam Engine', 'Speed Boost', 'Water Bubble', 'Water Compaction',
597
+ 'Wonder Guard', 'King\'s Rock', 'Weakness Policy', 'Beat Up', 'Stored Power',
598
+ ],
807
599
  },
808
600
  // Other Metagames
809
601
  ///////////////////////////////////////////////////////////////////
@@ -870,7 +662,7 @@ exports.Formats = [
870
662
  const itemTable = new Set();
871
663
  for (const set of team) {
872
664
  const item = this.dex.items.get(set.item);
873
- if (!item?.megaStone)
665
+ if (!item.megaStone)
874
666
  continue;
875
667
  const species = this.dex.species.get(set.species);
876
668
  if (species.isNonstandard)
@@ -922,7 +714,7 @@ exports.Formats = [
922
714
  'Archeops', 'Buzzwole', 'Calyrex-Ice', 'Calyrex-Shadow', 'Dialga', 'Dracovish', 'Dragapult', 'Dragonite', 'Eternatus', 'Gengar', 'Giratina', 'Giratina-Origin',
923
715
  'Groudon', 'Ho-Oh', 'Kartana', 'Keldeo', 'Kyogre', 'Kyurem', 'Kyurem-Black', 'Kyurem-White', 'Lugia', 'Lunala', 'Magearna', 'Marshadow', 'Melmetal', 'Mewtwo',
924
716
  'Naganadel', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane', 'Noivern', 'Palkia', 'Pheromosa', 'Rayquaza', 'Regigigas', 'Reshiram', 'Shedinja', 'Solgaleo', 'Spectrier',
925
- 'Urshifu-Base', 'Urshifu-Rapid-Strike', 'Victini', 'Xerneas', 'Yveltal', 'Zacian', 'Zacian-Crowned', 'Zamazenta-Base', 'Zekrom', 'Zeraora', 'Zygarde-Base',
717
+ 'Urshifu-Base', 'Urshifu-Rapid-Strike', 'Victini', 'Weavile', 'Xerneas', 'Yveltal', 'Zacian', 'Zacian-Crowned', 'Zamazenta-Base', 'Zekrom', 'Zeraora', 'Zygarde-Base',
926
718
  'Arena Trap', 'Comatose', 'Contrary', 'Fluffy', 'Fur Coat', 'Gorilla Tactics', 'Huge Power', 'Ice Scales', 'Illusion', 'Imposter', 'Innards Out', 'Intrepid Sword',
927
719
  'Libero', 'Magnet Pull', 'Moody', 'Neutralizing Gas', 'Parental Bond', 'Poison Heal', 'Power Construct', 'Protean', 'Pure Power', 'Shadow Tag', 'Simple', 'Stakeout',
928
720
  'Speed Boost', 'Water Bubble', 'Wonder Guard', 'King\'s Rock', 'Baton Pass',
@@ -946,11 +738,12 @@ exports.Formats = [
946
738
  mod: 'gen8',
947
739
  ruleset: ['Standard', 'STABmons Move Legality', 'Dynamax Clause', 'Sleep Moves Clause'],
948
740
  banlist: [
949
- 'Calyrex-Ice', 'Calyrex-Shadow', 'Darmanitan-Galar', 'Dialga', 'Dracovish', 'Dragapult', 'Eternatus', 'Genesect', 'Giratina', 'Giratina-Origin',
950
- 'Groudon', 'Ho-Oh', 'Kartana', 'Kyogre', 'Kyurem-Black', 'Kyurem-White', 'Landorus', 'Landorus-Therian', 'Lugia', 'Lunala', 'Marshadow', 'Mewtwo',
951
- 'Naganadel', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane', 'Palkia', 'Pheromosa', 'Porygon-Z', 'Rayquaza', 'Reshiram', 'Silvally', 'Solgaleo',
952
- 'Spectrier', 'Tapu Koko', 'Thundurus-Base', 'Urshifu-Base', 'Xerneas', 'Yveltal', 'Zacian', 'Zacian-Crowned', 'Zamazenta', 'Zamazenta-Crowned',
953
- 'Zapdos-Galar', 'Zekrom', 'Zygarde-Base', 'Arena Trap', 'Magnet Pull', 'Moody', 'Power Construct', 'Shadow Tag', 'King\'s Rock', 'Baton Pass',
741
+ 'Calyrex-Ice', 'Calyrex-Shadow', 'Darmanitan-Galar', 'Dialga', 'Dracovish', 'Dragapult', 'Eternatus', 'Genesect', 'Garchomp', 'Giratina',
742
+ 'Giratina-Origin', 'Groudon', 'Ho-Oh', 'Kartana', 'Kyogre', 'Kyurem-Black', 'Kyurem-White', 'Landorus', 'Landorus-Therian', 'Lugia', 'Lunala',
743
+ 'Marshadow', 'Mewtwo', 'Naganadel', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane', 'Palkia', 'Pheromosa', 'Porygon-Z', 'Rayquaza', 'Reshiram',
744
+ 'Silvally', 'Solgaleo', 'Spectrier', 'Tapu Bulu', 'Tapu Koko', 'Thundurus-Base', 'Urshifu-Base', 'Xerneas', 'Yveltal', 'Zacian', 'Zacian-Crowned',
745
+ 'Zamazenta', 'Zamazenta-Crowned', 'Zapdos-Galar', 'Zekrom', 'Zygarde-Base', 'Arena Trap', 'Magnet Pull', 'Moody', 'Power Construct', 'Shadow Tag',
746
+ 'King\'s Rock', 'Baton Pass',
954
747
  ],
955
748
  restricted: [
956
749
  'Acupressure', 'Astral Barrage', 'Belly Drum', 'Bolt Beak', 'Clangorous Soul', 'Double Iron Bash', 'Electrify', 'Extreme Speed', 'Fishious Rend',
@@ -990,37 +783,72 @@ exports.Formats = [
990
783
  ],
991
784
  },
992
785
  {
993
- name: "[Gen 8] Bonus Type",
994
- desc: `Pok&eacute;mon can be nicknamed the name of a type to have that type added onto their current ones.`,
786
+ section: "BD/SP",
787
+ column: 2,
788
+ },
789
+ {
790
+ name: "[Gen 8 BDSP] Random Battle",
791
+ desc: `Randomized teams of level-balanced Pok&eacute;mon with sets that are generated to be competitively viable.`,
792
+ mod: 'gen8bdsp',
793
+ team: 'random',
794
+ ruleset: ['[Gen 8] Random Battle', '!PotD'],
795
+ },
796
+ {
797
+ name: "[Gen 8 BDSP] OU",
995
798
  threads: [
996
- `&bullet; <a href="https://www.smogon.com/forums/threads/3683173/">Bonus Type</a>`,
997
- ],
998
- mod: 'gen8',
999
- searchShow: false,
1000
- ruleset: ['Standard', 'Dynamax Clause', 'Bonus Type Rule', '!Nickname Clause'],
1001
- banlist: [
1002
- 'Calyrex-Ice', 'Calyrex-Shadow', 'Darmanitan-Galar', 'Dialga', 'Dracovish', 'Dragapult', 'Dragonite', 'Eternatus', 'Genesect',
1003
- 'Giratina', 'Giratina-Origin', 'Groudon', 'Ho-Oh', 'Kartana', 'Kyogre', 'Kyurem-Black', 'Kyurem-White', 'Landorus-Base', 'Lugia',
1004
- 'Lunala', 'Magearna', 'Marshadow', 'Mewtwo', 'Naganadel', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane', 'Palkia', 'Pheromosa',
1005
- 'Rayquaza', 'Reshiram', 'Shedinja', 'Solgaleo', 'Spectrier', 'Urshifu-Base', 'Xerneas', 'Yveltal', 'Zacian', 'Zacian-Crowned',
1006
- 'Zamazenta', 'Zamazenta-Crowned', 'Zekrom', 'Zygarde-Base', 'Arena Trap', 'Moody', 'Power Construct', 'Shadow Tag', 'Baton Pass',
1007
- 'Final Gambit', 'Flower Shield',
799
+ `&bullet; <a href="https://www.smogon.com/forums/threads/3693629/">BDSP OU Metagame Discussion</a>`,
800
+ `&bullet; <a href="https://www.smogon.com/forums/threads/3693620/">BDSP OU Viability List</a>`,
1008
801
  ],
802
+ mod: 'gen8bdsp',
803
+ ruleset: ['Standard'],
804
+ banlist: ['Uber', 'Arena Trap', 'Drizzle', 'Moody', 'Shadow Tag', 'King\'s Rock', 'Razor Fang', 'Baton Pass'],
1009
805
  },
1010
806
  {
1011
- name: "[Gen 8] Camomons",
1012
- desc: `Pok&eacute;mon change type to match their first two moves.`,
807
+ name: "[Gen 8 BDSP] Doubles OU",
1013
808
  threads: [
1014
- `&bullet; <a href="https://www.smogon.com/forums/threads/3656413/">Camomons</a>`,
809
+ `&bullet; <a href="https://www.smogon.com/forums/threads/3693891/">BDSP Doubles OU</a>`,
1015
810
  ],
1016
- mod: 'gen8',
811
+ mod: 'gen8bdsp',
812
+ gameType: 'doubles',
1017
813
  searchShow: false,
1018
- 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'],
1019
- banlist: [
1020
- 'Calyrex-Ice', 'Calyrex-Shadow', 'Darmanitan-Galar', 'Dialga', 'Dracovish', 'Dragonite', 'Eternatus', 'Genesect', 'Giratina', 'Giratina-Origin', 'Groudon',
1021
- 'Ho-Oh', 'Hydreigon', 'Kartana', 'Kyogre', 'Kyurem', 'Kyurem-Black', 'Kyurem-White', 'Landorus-Base', 'Latias', 'Latios', 'Lugia', 'Lunala', 'Marshadow',
1022
- 'Mewtwo', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane', 'Palkia', 'Pheromosa', 'Rayquaza', 'Reshiram', 'Shedinja', 'Slowking-Galar', 'Solgaleo', 'Xerneas',
1023
- 'Yveltal', 'Zacian', 'Zacian-Crowned', 'Zamazenta', 'Zamazenta-Crowned', 'Zekrom', 'Zeraora', 'Zygarde-Base',
814
+ ruleset: ['Standard Doubles'],
815
+ banlist: ['DUber', 'Swagger'],
816
+ },
817
+ {
818
+ name: "[Gen 8 BDSP] Battle Festival Doubles",
819
+ mod: 'gen8bdsp',
820
+ gameType: 'doubles',
821
+ // VGC Timer is temporary
822
+ ruleset: ['Flat Rules', 'Min Source Gen = 8', 'VGC Timer'],
823
+ },
824
+ {
825
+ name: "[Gen 8 BDSP] Pure Hackmons",
826
+ desc: `Anything that can be hacked in-game and is usable in local battles is allowed.`,
827
+ threads: [
828
+ `&bullet; <a href="https://www.smogon.com/forums/threads/3693868/">Pure Hackmons</a>`,
829
+ ],
830
+ mod: 'gen8bdsp',
831
+ searchShow: false,
832
+ ruleset: ['-Nonexistent', 'Team Preview', 'HP Percentage Mod', 'Cancel Mod', 'Endless Battle Clause'],
833
+ },
834
+ {
835
+ section: "Challengeable OMs",
836
+ column: 2,
837
+ },
838
+ {
839
+ name: "[Gen 8] Camomons",
840
+ desc: `Pok&eacute;mon change type to match their first two moves.`,
841
+ threads: [
842
+ `&bullet; <a href="https://www.smogon.com/forums/threads/3656413/">Camomons</a>`,
843
+ ],
844
+ mod: 'gen8',
845
+ searchShow: false,
846
+ 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'],
847
+ banlist: [
848
+ 'Calyrex-Ice', 'Calyrex-Shadow', 'Darmanitan-Galar', 'Dialga', 'Dracovish', 'Dragonite', 'Eternatus', 'Genesect', 'Giratina', 'Giratina-Origin', 'Groudon',
849
+ 'Ho-Oh', 'Hydreigon', 'Kartana', 'Kyogre', 'Kyurem', 'Kyurem-Black', 'Kyurem-White', 'Landorus-Base', 'Latias', 'Latios', 'Lugia', 'Lunala', 'Marshadow',
850
+ 'Mewtwo', 'Naganadel', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane', 'Palkia', 'Pheromosa', 'Rayquaza', 'Reshiram', 'Shedinja', 'Slowking-Galar', 'Solgaleo',
851
+ 'Tornadus-Therian', 'Xerneas', 'Yveltal', 'Zacian', 'Zacian-Crowned', 'Zamazenta', 'Zamazenta-Crowned', 'Zekrom', 'Zeraora', 'Zygarde-Base',
1024
852
  'Arena Trap', 'Moody', 'Power Construct', 'Shadow Tag', 'Baton Pass',
1025
853
  ],
1026
854
  onModifySpeciesPriority: 2,
@@ -1039,151 +867,6 @@ exports.Formats = [
1039
867
  this.add('-start', pokemon, 'typechange', (pokemon.illusion || pokemon).getTypes(true).join('/'), '[silent]');
1040
868
  },
1041
869
  },
1042
- {
1043
- name: "[Gen 8] Cross Evolution",
1044
- 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.`,
1045
- threads: [
1046
- `&bullet; <a href="https://www.smogon.com/forums/threads/3657562/">Cross Evolution</a>`,
1047
- ],
1048
- mod: 'gen8',
1049
- searchShow: false,
1050
- ruleset: ['Standard', 'Overflow Stat Mod', 'Dynamax Clause'],
1051
- banlist: ['Corsola-Galar', 'Sneasel', 'Type: Null', 'Arena Trap', 'Ice Scales', 'Moody', 'King\'s Rock', 'Baton Pass'],
1052
- restricted: ['Chansey', 'Lunala', 'Shedinja', 'Solgaleo', 'Gorilla Tactics', 'Huge Power', 'Pure Power', 'Shadow Tag'],
1053
- onValidateTeam(team) {
1054
- const names = new Set();
1055
- for (const set of team) {
1056
- const name = set.name;
1057
- if (names.has(this.dex.toID(name))) {
1058
- return [
1059
- `Your Pok\u00e9mon must have different nicknames.`,
1060
- `(You have more than one Pok\u00e9mon named '${name}')`,
1061
- ];
1062
- }
1063
- names.add(this.dex.toID(name));
1064
- }
1065
- if (!names.size) {
1066
- return [
1067
- `${this.format.name} works using nicknames; your team has 0 nicknamed Pok\u00e9mon.`,
1068
- `(If this was intentional, add a nickname to one Pok\u00e9mon that isn't the name of a Pok\u00e9mon species.)`,
1069
- ];
1070
- }
1071
- },
1072
- checkCanLearn(move, species, lsetData, set) {
1073
- // @ts-ignore
1074
- if (!set.sp?.exists || !set.crossSpecies?.exists) {
1075
- return this.checkCanLearn(move, species, lsetData, set);
1076
- }
1077
- // @ts-ignore
1078
- const problem = this.checkCanLearn(move, set.sp);
1079
- if (!problem)
1080
- return null;
1081
- // @ts-ignore
1082
- if (!set.crossMovesLeft)
1083
- return problem;
1084
- // @ts-ignore
1085
- if (this.checkCanLearn(move, set.crossSpecies))
1086
- return problem;
1087
- // @ts-ignore
1088
- set.crossMovesLeft--;
1089
- return null;
1090
- },
1091
- validateSet(set, teamHas) {
1092
- const crossSpecies = this.dex.species.get(set.name);
1093
- const onChangeSet = this.dex.formats.get('Pokemon').onChangeSet;
1094
- let problems = onChangeSet?.call(this, set, this.format) || null;
1095
- if (Array.isArray(problems) && problems.length)
1096
- return problems;
1097
- const crossNonstandard = !this.ruleTable.has('standardnatdex') && crossSpecies.isNonstandard === 'Past';
1098
- const crossIsCap = !this.ruleTable.has('+pokemontag:cap') && crossSpecies.isNonstandard === 'CAP';
1099
- if (!crossSpecies.exists || crossNonstandard || crossIsCap)
1100
- return this.validateSet(set, teamHas);
1101
- const species = this.dex.species.get(set.species);
1102
- const check = this.checkSpecies(set, species, species, {});
1103
- if (check)
1104
- return [check];
1105
- const nonstandard = !this.ruleTable.has('standardnatdex') && species.isNonstandard === 'Past';
1106
- const isCap = !this.ruleTable.has('+pokemontag:cap') && species.isNonstandard === 'CAP';
1107
- if (!species.exists || nonstandard || isCap || species === crossSpecies)
1108
- return this.validateSet(set, teamHas);
1109
- if (!species.nfe)
1110
- return [`${species.name} cannot cross evolve because it doesn't evolve.`];
1111
- const crossIsUnreleased = (crossSpecies.tier === "Unreleased" && crossSpecies.isNonstandard === "Unobtainable");
1112
- if (crossSpecies.battleOnly || crossIsUnreleased || !crossSpecies.prevo) {
1113
- return [`${species.name} cannot cross evolve into ${crossSpecies.name} because it isn't an evolution.`];
1114
- }
1115
- if (this.ruleTable.isRestrictedSpecies(crossSpecies)) {
1116
- return [`${species.name} cannot cross evolve into ${crossSpecies.name} because it is banned.`];
1117
- }
1118
- const crossPrevoSpecies = this.dex.species.get(crossSpecies.prevo);
1119
- if (!crossPrevoSpecies.prevo !== !species.prevo) {
1120
- return [
1121
- `${species.name} cannot cross evolve into ${crossSpecies.name} because they are not consecutive evolution stages.`,
1122
- ];
1123
- }
1124
- const ability = this.dex.abilities.get(set.ability);
1125
- if (!this.ruleTable.isRestricted(`ability:${ability.id}`) || Object.values(species.abilities).includes(ability.name)) {
1126
- set.species = crossSpecies.name;
1127
- }
1128
- // @ts-ignore
1129
- set.sp = species;
1130
- // @ts-ignore
1131
- set.crossSpecies = crossSpecies;
1132
- // @ts-ignore
1133
- set.crossMovesLeft = 2;
1134
- problems = this.validateSet(set, teamHas);
1135
- set.name = crossSpecies.name;
1136
- set.species = species.name;
1137
- return problems;
1138
- },
1139
- onModifySpecies(species, target, source, effect) {
1140
- if (!target)
1141
- return; // chat
1142
- if (effect && ['imposter', 'transform'].includes(effect.id))
1143
- return;
1144
- if (target.set.name === target.set.species)
1145
- return;
1146
- const crossSpecies = this.dex.species.get(target.set.name);
1147
- if (!crossSpecies.exists)
1148
- return;
1149
- if (species.battleOnly || !species.nfe)
1150
- return;
1151
- const crossIsUnreleased = (crossSpecies.tier === "Unreleased" && crossSpecies.isNonstandard === "Unobtainable");
1152
- if (crossSpecies.battleOnly || crossIsUnreleased || !crossSpecies.prevo)
1153
- return;
1154
- const crossPrevoSpecies = this.dex.species.get(crossSpecies.prevo);
1155
- if (!crossPrevoSpecies.prevo !== !species.prevo)
1156
- return;
1157
- const mixedSpecies = this.dex.deepClone(species);
1158
- mixedSpecies.baseSpecies = mixedSpecies.name = `${species.name}-${crossSpecies.name}`;
1159
- mixedSpecies.weightkg =
1160
- Math.max(0.1, +(species.weightkg + crossSpecies.weightkg - crossPrevoSpecies.weightkg)).toFixed(1);
1161
- mixedSpecies.nfe = false;
1162
- mixedSpecies.evos = [];
1163
- mixedSpecies.eggGroups = crossSpecies.eggGroups;
1164
- mixedSpecies.abilities = crossSpecies.abilities;
1165
- mixedSpecies.bst = 0;
1166
- let i;
1167
- for (i in species.baseStats) {
1168
- const statChange = crossSpecies.baseStats[i] - crossPrevoSpecies.baseStats[i];
1169
- mixedSpecies.baseStats[i] = this.clampIntRange(species.baseStats[i] + statChange, 1, 255);
1170
- mixedSpecies.bst += mixedSpecies.baseStats[i];
1171
- }
1172
- if (crossSpecies.types[0] !== crossPrevoSpecies.types[0])
1173
- mixedSpecies.types[0] = crossSpecies.types[0];
1174
- if (crossSpecies.types[1] !== crossPrevoSpecies.types[1]) {
1175
- mixedSpecies.types[1] = crossSpecies.types[1] || crossSpecies.types[0];
1176
- }
1177
- if (mixedSpecies.types[0] === mixedSpecies.types[1])
1178
- mixedSpecies.types = [mixedSpecies.types[0]];
1179
- return mixedSpecies;
1180
- },
1181
- onBegin() {
1182
- for (const pokemon of this.getAllPokemon()) {
1183
- pokemon.baseSpecies = pokemon.species;
1184
- }
1185
- },
1186
- },
1187
870
  {
1188
871
  name: "[Gen 8] Godly Gift",
1189
872
  desc: `Each Pok&eacute;mon receives one base stat from a God (AG/Uber Pok&eacute;mon) depending on its position in the team. If there is no Uber Pok&eacute;mon, it uses the Pok&eacute;mon in the first slot.`,
@@ -1345,7 +1028,7 @@ exports.Formats = [
1345
1028
  return null;
1346
1029
  },
1347
1030
  onValidateTeam(team, f, teamHas) {
1348
- if (this.format.ruleTable?.has('2abilityclause')) {
1031
+ if (this.ruleTable.has('2abilityclause')) {
1349
1032
  const abilityTable = new Map();
1350
1033
  const base = {
1351
1034
  airlock: 'cloudnine',
@@ -1377,77 +1060,263 @@ exports.Formats = [
1377
1060
  `(You have more than two ${this.dex.abilities.get(ability).name} variants)`,
1378
1061
  ];
1379
1062
  }
1380
- abilityTable.set(ability, (abilityTable.get(ability) || 0) + 1);
1063
+ abilityTable.set(ability, (abilityTable.get(ability) || 0) + 1);
1064
+ }
1065
+ }
1066
+ // Donor Clause
1067
+ const evoFamilyLists = [];
1068
+ for (const set of team) {
1069
+ const abilitySources = teamHas.abilitySources?.[this.dex.toID(set.species)];
1070
+ if (!abilitySources)
1071
+ continue;
1072
+ let format = this.format;
1073
+ if (!format.getEvoFamily)
1074
+ format = this.dex.formats.get('gen8inheritance');
1075
+ evoFamilyLists.push(abilitySources.map(format.getEvoFamily));
1076
+ }
1077
+ // Checking actual full incompatibility would require expensive algebra.
1078
+ // Instead, we only check the trivial case of multiple Pokémon only legal for exactly one family. FIXME?
1079
+ const requiredFamilies = Object.create(null);
1080
+ for (const evoFamilies of evoFamilyLists) {
1081
+ if (evoFamilies.length !== 1)
1082
+ continue;
1083
+ const [familyId] = evoFamilies;
1084
+ if (!(familyId in requiredFamilies))
1085
+ requiredFamilies[familyId] = 1;
1086
+ requiredFamilies[familyId]++;
1087
+ if (requiredFamilies[familyId] > 2) {
1088
+ return [
1089
+ `You are limited to up to two inheritances from each evolution family by the Donor Clause.`,
1090
+ `(You inherit more than twice from ${this.dex.species.get(familyId).name}).`,
1091
+ ];
1092
+ }
1093
+ }
1094
+ },
1095
+ onBegin() {
1096
+ for (const pokemon of this.getAllPokemon()) {
1097
+ if (pokemon.baseAbility.includes('0')) {
1098
+ const donor = pokemon.baseAbility.split('0')[1];
1099
+ pokemon.m.donor = this.toID(donor);
1100
+ pokemon.baseAbility = this.toID(pokemon.baseAbility.split('0')[0]);
1101
+ pokemon.ability = pokemon.baseAbility;
1102
+ }
1103
+ }
1104
+ },
1105
+ onSwitchIn(pokemon) {
1106
+ if (!pokemon.m.donor)
1107
+ return;
1108
+ const donorTemplate = this.dex.species.get(pokemon.m.donor);
1109
+ if (!donorTemplate.exists)
1110
+ return;
1111
+ // Place volatiles on the Pokémon to show the donor details.
1112
+ this.add('-start', pokemon, donorTemplate.name, '[silent]');
1113
+ },
1114
+ },
1115
+ {
1116
+ name: "[Gen 8] Multibility",
1117
+ desc: `Run a second ability at the cost of giving up a Pok&eacute;mon's item slot.`,
1118
+ threads: [
1119
+ `&bullet; <a href="https://www.smogon.com/forums/threads/3688892/">Multibility</a>`,
1120
+ ],
1121
+ mod: 'gen8',
1122
+ searchShow: false,
1123
+ ruleset: ['Standard', 'Dynamax Clause', '2 Ability Clause', 'Sleep Moves Clause', '!Sleep Clause Mod'],
1124
+ banlist: [
1125
+ 'Calyrex-Ice', 'Calyrex-Shadow', 'Cinderace', 'Darmanitan-Galar', 'Dialga', 'Dracovish', 'Dragonite', 'Eternatus',
1126
+ 'Genesect', 'Giratina', 'Giratina-Origin', 'Groudon', 'Ho-Oh', 'Kartana', 'Kyogre', 'Kyurem-Black', 'Kyurem-White',
1127
+ 'Lugia', 'Lunala', 'Magearna', 'Marshadow', 'Melmetal', 'Mewtwo', 'Naganadel', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane',
1128
+ 'Palkia', 'Pheromosa', 'Rayquaza', 'Reshiram', 'Shedinja', 'Solgaleo', 'Spectrier', 'Urshifu-Base', 'Xerneas',
1129
+ 'Yveltal', 'Zacian', 'Zacian-Crowned', 'Zamazenta', 'Zamazenta-Crowned', 'Zekrom', 'Zygarde-Base', 'Arena Trap',
1130
+ 'Chlorophyll', 'Magnet Pull', 'Moody', 'Power Construct', 'Sand Rush', 'Shadow Tag', 'Slush Rush', 'Swift Swim',
1131
+ 'Stench', 'Trace', 'King\'s Rock', 'Baton Pass',
1132
+ ],
1133
+ restricted: [
1134
+ 'Comatose', 'Contrary', 'Fluffy', 'Fur Coat', 'Huge Power', 'Ice Scales', 'Illusion', 'Imposter', 'Innards Out',
1135
+ 'Intrepid Sword', 'Libero', 'Neutralizing Gas', 'Parental Bond', 'Protean', 'Pure Power', 'Simple', 'Speed Boost',
1136
+ 'Stakeout', 'Tinted Lens', 'Unaware', 'Water Bubble', 'Wonder Guard',
1137
+ 'Emergency Exit + Regenerator', 'Wimp Out + Regenerator',
1138
+ ],
1139
+ validateSet(set, teamHas) {
1140
+ const ability = this.dex.abilities.get(set.ability);
1141
+ const item = this.dex.abilities.get(set.item);
1142
+ if (!item.exists)
1143
+ return this.validateSet(set, teamHas);
1144
+ const problems = [];
1145
+ if (item.isNonstandard && !this.ruleTable.has(`+ability:${item.id}`)) {
1146
+ problems.push(`${item.name} is banned.`);
1147
+ }
1148
+ if (ability.id === item.id) {
1149
+ problems.push(`${set.species} has ${ability.name} as an ability and as an item.`);
1150
+ }
1151
+ if (this.ruleTable.isRestricted(`ability:${item.id}`) || this.ruleTable.isBanned(`ability:${item.id}`)) {
1152
+ problems.push(`${set.species}'s second ability (${item.name}) can only be used as an ability.`);
1153
+ }
1154
+ if ((ability.id === 'regenerator' && ['emergencyexit', 'wimpout'].includes(item.id)) ||
1155
+ (item.id === 'regenerator' && ['emergencyexit', 'wimpout'].includes(ability.id))) {
1156
+ problems.push(`${ability.name} and ${item.name} are banned together.`);
1157
+ }
1158
+ const itemStr = set.item;
1159
+ set.item = '';
1160
+ const problem = this.validateSet(set, teamHas);
1161
+ if (problem?.length)
1162
+ problems.push(...problem);
1163
+ set.item = itemStr;
1164
+ return problems;
1165
+ },
1166
+ onValidateTeam(team) {
1167
+ if (!this.ruleTable.has('2abilityclause'))
1168
+ return;
1169
+ const abilityTable = new Map();
1170
+ const base = {
1171
+ airlock: 'cloudnine',
1172
+ battlearmor: 'shellarmor',
1173
+ clearbody: 'whitesmoke',
1174
+ dazzling: 'queenlymajesty',
1175
+ emergencyexit: 'wimpout',
1176
+ filter: 'solidrock',
1177
+ gooey: 'tanglinghair',
1178
+ insomnia: 'vitalspirit',
1179
+ ironbarbs: 'roughskin',
1180
+ libero: 'protean',
1181
+ minus: 'plus',
1182
+ moxie: 'chillingneigh',
1183
+ powerofalchemy: 'receiver',
1184
+ propellertail: 'stalwart',
1185
+ teravolt: 'moldbreaker',
1186
+ turboblaze: 'moldbreaker',
1187
+ };
1188
+ const abilities = [];
1189
+ for (const set of team) {
1190
+ abilities.push([set.ability, set.item].map((abil) => {
1191
+ const id = this.toID(abil);
1192
+ return base[id] || id;
1193
+ }));
1194
+ }
1195
+ for (const [abilityid, itemid] of abilities) {
1196
+ const ability = this.dex.abilities.get(abilityid);
1197
+ const item = this.dex.abilities.get(itemid);
1198
+ if (ability.exists)
1199
+ abilityTable.set(ability.id, (abilityTable.get(ability.id) || 0) + 1);
1200
+ if (item.exists)
1201
+ abilityTable.set(item.id, (abilityTable.get(item.id) || 0) + 1);
1202
+ }
1203
+ for (const [abilityid, size] of abilityTable) {
1204
+ if (size > 2) {
1205
+ return [
1206
+ `You are limited to two of each ability by 2 Ability Clause.`,
1207
+ `(You have more than two ${this.dex.abilities.get(abilityid).name} variants)`,
1208
+ ];
1209
+ }
1210
+ }
1211
+ },
1212
+ onSwitchOut(pokemon) {
1213
+ const item = this.dex.abilities.get(pokemon.item);
1214
+ if (item.exists) {
1215
+ this.singleEvent('End', item, pokemon.itemState, pokemon);
1216
+ }
1217
+ },
1218
+ onFaint(pokemon) {
1219
+ const item = this.dex.abilities.get(pokemon.item);
1220
+ if (item.exists) {
1221
+ this.singleEvent('End', item, pokemon.itemState, pokemon);
1222
+ }
1223
+ },
1224
+ field: {
1225
+ suppressingWeather() {
1226
+ for (const pokemon of this.battle.getAllActive()) {
1227
+ const item = this.battle.dex.abilities.get(pokemon.item);
1228
+ if (pokemon && !pokemon.ignoringAbility() &&
1229
+ (pokemon.getAbility().suppressWeather || (item.exists && item.suppressWeather))) {
1230
+ return true;
1231
+ }
1232
+ }
1233
+ return false;
1234
+ },
1235
+ },
1236
+ pokemon: {
1237
+ getItem() {
1238
+ const ability = this.battle.dex.abilities.get(this.item);
1239
+ if (!ability.exists)
1240
+ return Object.getPrototypeOf(this).getItem.call(this);
1241
+ return { ...ability, ignoreKlutz: true, onTakeItem: false };
1242
+ },
1243
+ hasItem(item) {
1244
+ const ownItem = this.item;
1245
+ if (this.battle.dex.abilities.get(ownItem).exists)
1246
+ return false;
1247
+ if (this.ignoringItem())
1248
+ return false;
1249
+ if (!Array.isArray(item))
1250
+ return ownItem === this.battle.toID(item);
1251
+ return item.map(this.battle.toID).includes(ownItem);
1252
+ },
1253
+ hasAbility(ability) {
1254
+ if (this.ignoringAbility())
1255
+ return false;
1256
+ if (Array.isArray(ability))
1257
+ return ability.some(abil => this.hasAbility(abil));
1258
+ const abilityid = this.battle.toID(ability);
1259
+ const item = this.battle.dex.abilities.get(this.item);
1260
+ return this.ability === abilityid || (item.exists && item.id === abilityid);
1261
+ },
1262
+ ignoringAbility() {
1263
+ // Check if any active pokemon have the ability Neutralizing Gas
1264
+ let neutralizinggas = false;
1265
+ for (const pokemon of this.battle.getAllActive()) {
1266
+ // can't use hasAbility because it would lead to infinite recursion
1267
+ if ((pokemon.ability === 'neutralizinggas' || pokemon.item === 'neutralizinggas') &&
1268
+ !pokemon.volatiles['gastroacid'] && !pokemon.abilityState.ending) {
1269
+ neutralizinggas = true;
1270
+ break;
1271
+ }
1272
+ }
1273
+ return !!((this.battle.gen >= 5 && !this.isActive) ||
1274
+ ((this.volatiles['gastroacid'] || (neutralizinggas && this.ability !== 'neutralizinggas' &&
1275
+ this.item !== 'neutralizinggas')) && !this.getAbility().isPermanent));
1276
+ },
1277
+ ignoringItem() {
1278
+ let nGas = false;
1279
+ for (const pokemon of this.battle.getAllActive()) {
1280
+ // can't use hasAbility because it would lead to infinite recursion
1281
+ if (((pokemon.ability === 'neutralizinggas' && !pokemon.abilityState.ending) ||
1282
+ (pokemon.item === 'neutralizinggas' && !pokemon.itemState.ending)) &&
1283
+ !pokemon.volatiles['gastroacid'] && !pokemon.abilityState.ending) {
1284
+ nGas = true;
1285
+ break;
1286
+ }
1381
1287
  }
1382
- }
1383
- // Donor Clause
1384
- const evoFamilyLists = [];
1385
- for (const set of team) {
1386
- const abilitySources = teamHas.abilitySources?.[this.dex.toID(set.species)];
1387
- if (!abilitySources)
1388
- continue;
1389
- let format = this.format;
1390
- if (!format.getEvoFamily)
1391
- format = this.dex.formats.get('gen8inheritance');
1392
- evoFamilyLists.push(abilitySources.map(format.getEvoFamily));
1393
- }
1394
- // Checking actual full incompatibility would require expensive algebra.
1395
- // Instead, we only check the trivial case of multiple Pokémon only legal for exactly one family. FIXME?
1396
- const requiredFamilies = Object.create(null);
1397
- for (const evoFamilies of evoFamilyLists) {
1398
- if (evoFamilies.length !== 1)
1399
- continue;
1400
- const [familyId] = evoFamilies;
1401
- if (!(familyId in requiredFamilies))
1402
- requiredFamilies[familyId] = 1;
1403
- requiredFamilies[familyId]++;
1404
- if (requiredFamilies[familyId] > 2) {
1405
- return [
1406
- `You are limited to up to two inheritances from each evolution family by the Donor Clause.`,
1407
- `(You inherit more than twice from ${this.dex.species.get(familyId).name}).`,
1408
- ];
1288
+ const item = this.battle.dex.abilities.get(this.item);
1289
+ return !!((this.battle.gen >= 5 && !this.isActive) ||
1290
+ (this.hasAbility('klutz') && !this.getItem().ignoreKlutz) ||
1291
+ this.volatiles['embargo'] || this.battle.field.pseudoWeather['magicroom'] ||
1292
+ (item.exists && item.id !== 'neutralizinggas' && (nGas || this.volatiles['gastroacid'])));
1293
+ },
1294
+ takeItem(source) {
1295
+ if (!this.isActive)
1296
+ return false;
1297
+ if (!this.item)
1298
+ return false;
1299
+ if (this.battle.dex.abilities.get(this.item).exists)
1300
+ return false;
1301
+ if (!source)
1302
+ source = this;
1303
+ if (this.battle.gen === 4) {
1304
+ if (this.battle.toID(this.ability) === 'multitype')
1305
+ return false;
1306
+ if (source && this.battle.toID(source.ability) === 'multitype')
1307
+ return false;
1409
1308
  }
1410
- }
1411
- },
1412
- onBegin() {
1413
- for (const pokemon of this.getAllPokemon()) {
1414
- if (pokemon.baseAbility.includes('0')) {
1415
- const donor = pokemon.baseAbility.split('0')[1];
1416
- pokemon.m.donor = this.toID(donor);
1417
- pokemon.baseAbility = this.toID(pokemon.baseAbility.split('0')[0]);
1418
- pokemon.ability = pokemon.baseAbility;
1309
+ const item = this.getItem();
1310
+ if (this.battle.runEvent('TakeItem', this, source, null, item)) {
1311
+ this.item = '';
1312
+ this.itemState = { id: '', target: this };
1313
+ this.pendingStaleness = undefined;
1314
+ return item;
1419
1315
  }
1420
- }
1421
- },
1422
- onSwitchIn(pokemon) {
1423
- if (!pokemon.m.donor)
1424
- return;
1425
- const donorTemplate = this.dex.species.get(pokemon.m.donor);
1426
- if (!donorTemplate.exists)
1427
- return;
1428
- // Place volatiles on the Pokémon to show the donor details.
1429
- this.add('-start', pokemon, donorTemplate.name, '[silent]');
1316
+ return false;
1317
+ },
1430
1318
  },
1431
1319
  },
1432
- {
1433
- name: "[Gen 8] Inverse",
1434
- desc: `The type chart is inverted. Normal is super effective against Ghost, and vice versa, etc.`,
1435
- threads: [
1436
- `&bullet; <a href="https://www.smogon.com/forums/threads/3666858/">Inverse</a>`,
1437
- ],
1438
- mod: 'gen8',
1439
- searchShow: false,
1440
- ruleset: ['Standard', 'Dynamax Clause', 'Inverse Mod'],
1441
- banlist: [
1442
- 'Calyrex-Ice', 'Calyrex-Shadow', 'Cinderace', 'Darmanitan-Galar', 'Dialga', 'Diggersby', 'Dracovish',
1443
- 'Dracozolt', 'Eternatus', 'Genesect', 'Giratina', 'Giratina-Origin', 'Groudon', 'Ho-Oh', 'Kartana',
1444
- 'Kyogre', 'Kyurem-Black', 'Kyurem-White', 'Landorus-Base', 'Lugia', 'Lunala', 'Marshadow', 'Mewtwo',
1445
- 'Naganadel', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane', 'Palkia', 'Pheromosa', 'Porygon-Z', 'Rayquaza',
1446
- 'Regidrago', 'Regieleki', 'Reshiram', 'Rillaboom', 'Solgaleo', 'Spectrier', 'Urshifu-Base', 'Xerneas',
1447
- 'Yveltal', 'Zacian', 'Zacian-Crowned', 'Zamazenta-Base', 'Zekrom', 'Arena Trap', 'Moody', 'Power Construct',
1448
- 'Shadow Tag', 'King\'s Rock', 'Baton Pass',
1449
- ],
1450
- },
1451
1320
  {
1452
1321
  name: "[Gen 8] Nature Swap",
1453
1322
  desc: `Pok&eacute;mon have their base stats swapped depending on their nature.`,
@@ -1503,16 +1372,6 @@ exports.Formats = [
1503
1372
  },
1504
1373
  },
1505
1374
  },
1506
- {
1507
- name: "[Gen 8] Pure Hackmons",
1508
- desc: `Anything that can be hacked in-game and is usable in local battles is allowed.`,
1509
- threads: [
1510
- `&bullet; <a href="https://www.smogon.com/forums/threads/3656851/">Pure Hackmons</a>`,
1511
- ],
1512
- mod: 'gen8',
1513
- searchShow: false,
1514
- ruleset: ['-Nonexistent', 'Team Preview', 'HP Percentage Mod', 'Cancel Mod', 'Endless Battle Clause'],
1515
- },
1516
1375
  {
1517
1376
  name: "[Gen 8] Shared Power",
1518
1377
  desc: `Once a Pok&eacute;mon switches in, its ability is shared with the rest of the team.`,
@@ -1577,29 +1436,6 @@ exports.Formats = [
1577
1436
  }
1578
1437
  },
1579
1438
  },
1580
- {
1581
- name: "[Gen 8] Sketchmons",
1582
- desc: `Pok&eacute;mon can learn one of any move they don't normally learn, barring the few that are banned.`,
1583
- threads: [
1584
- `&bullet; <a href="https://www.smogon.com/forums/threads/3680298/">Sketchmons</a>`,
1585
- ],
1586
- mod: 'gen8',
1587
- searchShow: false,
1588
- ruleset: ['Standard', 'Dynamax Clause', 'Sketchmons Move Legality'],
1589
- banlist: [
1590
- 'Calyrex-Ice', 'Calyrex-Shadow', 'Cinderace', 'Darmanitan-Galar', 'Dialga', 'Dracovish', 'Dragapult', 'Eternatus', 'Excadrill',
1591
- 'Genesect', 'Giratina', 'Giratina-Origin', 'Groudon', 'Hawlucha', 'Ho-Oh', 'Kartana', 'Kyogre', 'Kyurem-Black', 'Kyurem-White',
1592
- 'Landorus-Base', 'Lugia', 'Lunala', 'Marshadow', 'Mewtwo', 'Naganadel', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane', 'Palkia',
1593
- 'Pheromosa', 'Porygon-Z', 'Rayquaza', 'Regieleki', 'Reshiram', 'Rillaboom', 'Shedinja', 'Solgaleo', 'Spectrier', 'Swoobat',
1594
- 'Urshifu-Base', 'Xerneas', 'Yveltal', 'Zacian', 'Zacian-Crowned', 'Zamazenta', 'Zamazenta-Crowned', 'Zekrom', 'Zeraora',
1595
- 'Zygarde-Base', 'Arena Trap', 'Moody', 'Power Construct', 'Shadow Tag', 'King\'s Rock', 'Baton Pass',
1596
- ],
1597
- restricted: [
1598
- 'Acupressure', 'Astral Barrage', 'Belly Drum', 'Bolt Beak', 'Clangorous Soul', 'Double Iron Bash', 'Electrify', 'Extreme Speed',
1599
- 'Fishious Rend', 'Geomancy', 'Glacial Lance', 'Lovely Kiss', 'No Retreat', 'Oblivion Wing', 'Octolock', 'Quiver Dance', 'Secret Sword',
1600
- 'Shell Smash', 'Shift Gear', 'Sleep Powder', 'Spore', 'Thousand Arrows', 'Transform', 'V-create', 'Wicked Blow',
1601
- ],
1602
- },
1603
1439
  {
1604
1440
  name: "[Gen 8] The Loser's Game",
1605
1441
  desc: `The first player to lose all of their Pok&eacute;mon wins.`,
@@ -1722,54 +1558,6 @@ exports.Formats = [
1722
1558
  },
1723
1559
  },
1724
1560
  },
1725
- {
1726
- name: "[Gen 8] Tier Shift",
1727
- desc: `Pok&eacute;mon below OU get their stats, excluding HP, boosted. UU/RUBL get +10, RU/NUBL get +20, NU/PUBL get +30, and PU or lower get +40.`,
1728
- threads: [
1729
- `&bullet; <a href="https://www.smogon.com/forums/threads/3662165/">Tier Shift</a>`,
1730
- ],
1731
- mod: 'gen8',
1732
- searchShow: false,
1733
- ruleset: ['[Gen 8] OU', 'Overflow Stat Mod'],
1734
- banlist: ['Damp Rock', 'Eviolite', 'Heat Rock'],
1735
- unbanlist: ['Zamazenta-Crowned'],
1736
- onModifySpecies(species, target, source, effect) {
1737
- if (!species.baseStats)
1738
- return;
1739
- const boosts = {
1740
- uu: 10,
1741
- rubl: 10,
1742
- ru: 20,
1743
- nubl: 20,
1744
- nu: 30,
1745
- publ: 30,
1746
- pu: 40,
1747
- nfe: 40,
1748
- lc: 40,
1749
- };
1750
- let tier = this.toID(species.tier);
1751
- if (!(tier in boosts))
1752
- return;
1753
- // Non-Pokemon bans in lower tiers
1754
- if (target) {
1755
- if (target.set.item === 'lightclay')
1756
- return;
1757
- if (['drizzle', 'drought', 'snowwarning'].includes(target.set.ability) && boosts[tier] > 20)
1758
- tier = 'nubl';
1759
- }
1760
- const pokemon = this.dex.deepClone(species);
1761
- pokemon.bst = pokemon.baseStats['hp'];
1762
- const boost = boosts[tier];
1763
- let statName;
1764
- for (statName in pokemon.baseStats) {
1765
- if (statName === 'hp')
1766
- continue;
1767
- pokemon.baseStats[statName] = this.clampIntRange(pokemon.baseStats[statName] + boost, 1, 255);
1768
- pokemon.bst += pokemon.baseStats[statName];
1769
- }
1770
- return pokemon;
1771
- },
1772
- },
1773
1561
  {
1774
1562
  name: "[Gen 8] Trademarked",
1775
1563
  desc: `Sacrifice your Pok&eacute;mon's ability for a status move that activates on switch-in.`,
@@ -1870,72 +1658,6 @@ exports.Formats = [
1870
1658
  },
1871
1659
  },
1872
1660
  },
1873
- {
1874
- name: "[Gen 8] STABmons Mix and Mega",
1875
- desc: `Pok&eacute;mon can use any move of their typing, in addition to the moves they can normally learn. Mega evolve any Pok&eacute;mon with any mega stone and no limit. Boosts based on mega evolution from gen 7.`,
1876
- threads: [
1877
- `&bullet; <a href="https://www.smogon.com/forums/posts/8299984/">STABmons Mix and Mega</a>`,
1878
- ],
1879
- mod: 'mixandmega',
1880
- searchShow: false,
1881
- ruleset: ['Standard', 'Dynamax Clause', 'Overflow Stat Mod', 'STABmons Move Legality'],
1882
- banlist: [
1883
- 'Calyrex-Shadow', 'Kyogre', 'Zacian', 'Zacian-Crowned', 'Moody', 'Shadow Tag', 'Beedrillite', 'Blazikenite', 'Gengarite',
1884
- 'Kangaskhanite', 'Mawilite', 'Medichamite', 'Pidgeotite', 'Baton Pass', 'Electrify', 'King\'s Rock',
1885
- ],
1886
- restricted: [
1887
- 'Calyrex-Ice', 'Dialga', 'Dragapult', 'Dragonite', 'Eternatus', 'Genesect', 'Gengar', 'Giratina', 'Giratina-Origin',
1888
- 'Groudon', 'Ho-Oh', 'Kartana', 'Keldeo', 'Kyurem-Black', 'Kyurem-White', 'Landorus-Therian', 'Lugia', 'Lunala',
1889
- 'Marshadow', 'Melmetal', 'Mewtwo', 'Naganadel', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane', 'Palkia', 'Rayquaza',
1890
- 'Regigigas', 'Reshiram', 'Tapu Koko', 'Thundurus', 'Thundurus-Therian', 'Urshifu-Base', 'Xerneas', 'Yveltal', 'Zekrom',
1891
- 'Zeraora', 'Zygarde-Base', 'Zygarde-Complete',
1892
- 'Acupressure', 'Astral Barrage', 'Belly Drum', 'Bolt Beak', 'Boomburst', 'Clangorous Soul', 'Double Iron Bash',
1893
- 'Extreme Speed', 'Fishious Rend', 'Geomancy', 'Glacial Lance', 'Lovely Kiss', 'Precipice Blades', 'Shell Smash',
1894
- 'Shift Gear', 'Sleep Powder', 'Spore', 'Thousand Arrows', 'Transform', 'V-create', 'Wicked Blow',
1895
- ],
1896
- onValidateTeam(team) {
1897
- const itemTable = new Set();
1898
- for (const set of team) {
1899
- const item = this.dex.items.get(set.item);
1900
- if (!item?.megaStone)
1901
- continue;
1902
- const species = this.dex.species.get(set.species);
1903
- if (species.isNonstandard)
1904
- return [`${species.baseSpecies} does not exist in gen 8.`];
1905
- if (this.ruleTable.isRestrictedSpecies(species) || this.toID(set.ability) === 'powerconstruct') {
1906
- return [`${species.name} is not allowed to hold ${item.name}.`];
1907
- }
1908
- if (itemTable.has(item.id)) {
1909
- return [`You are limited to one of each mega stone.`, `(You have more than one ${item.name})`];
1910
- }
1911
- itemTable.add(item.id);
1912
- }
1913
- },
1914
- onBegin() {
1915
- for (const pokemon of this.getAllPokemon()) {
1916
- pokemon.m.originalSpecies = pokemon.baseSpecies.name;
1917
- }
1918
- },
1919
- onSwitchIn(pokemon) {
1920
- // @ts-ignore
1921
- const oMegaSpecies = this.dex.species.get(pokemon.species.originalMega);
1922
- if (oMegaSpecies.exists && pokemon.m.originalSpecies !== oMegaSpecies.baseSpecies) {
1923
- // Place volatiles on the Pokémon to show its mega-evolved condition and details
1924
- this.add('-start', pokemon, oMegaSpecies.requiredItem || oMegaSpecies.requiredMove, '[silent]');
1925
- const oSpecies = this.dex.species.get(pokemon.m.originalSpecies);
1926
- if (oSpecies.types.length !== pokemon.species.types.length || oSpecies.types[1] !== pokemon.species.types[1]) {
1927
- this.add('-start', pokemon, 'typechange', pokemon.species.types.join('/'), '[silent]');
1928
- }
1929
- }
1930
- },
1931
- onSwitchOut(pokemon) {
1932
- // @ts-ignore
1933
- const oMegaSpecies = this.dex.species.get(pokemon.species.originalMega);
1934
- if (oMegaSpecies.exists && pokemon.m.originalSpecies !== oMegaSpecies.baseSpecies) {
1935
- this.add('-end', pokemon, oMegaSpecies.requiredItem || oMegaSpecies.requiredMove, '[silent]');
1936
- }
1937
- },
1938
- },
1939
1661
  // Randomized Metas
1940
1662
  ///////////////////////////////////////////////////////////////////
1941
1663
  {
@@ -1952,6 +1674,7 @@ exports.Formats = [
1952
1674
  name: "[Gen 8] Random Battle (No Dmax)",
1953
1675
  mod: 'gen8',
1954
1676
  team: 'random',
1677
+ searchShow: false,
1955
1678
  ruleset: ['[Gen 8] Random Battle', 'Dynamax Clause'],
1956
1679
  },
1957
1680
  {
@@ -2206,33 +1929,37 @@ exports.Formats = [
2206
1929
  column: 3,
2207
1930
  },
2208
1931
  {
2209
- name: "[Gen 5] Ubers",
1932
+ name: "[Gen 6] Ubers",
2210
1933
  threads: [
2211
- `&bullet; <a href="https://www.smogon.com/forums/posts/8286278/">BW2 Ubers</a>`,
1934
+ `&bullet; <a href="https://www.smogon.com/forums/posts/8286277/">ORAS Ubers</a>`,
2212
1935
  ],
2213
- mod: 'gen5',
1936
+ mod: 'gen6',
2214
1937
  // searchShow: false,
2215
- ruleset: ['Standard', 'Sleep Clause Mod'],
1938
+ ruleset: ['Standard', 'Swagger Clause', 'Mega Rayquaza Clause'],
2216
1939
  },
2217
1940
  {
2218
- name: "[Gen 7] PU",
1941
+ name: "[Gen 4] UU",
2219
1942
  threads: [
2220
- `&bullet; <a href="https://www.smogon.com/forums/threads/3611496/">USM PU Sample Teams</a>`,
2221
- `&bullet; <a href="https://www.smogon.com/forums/threads/3614892/">USM PU Viability Rankings</a>`,
1943
+ `&bullet; <a href="https://www.smogon.com/forums/threads/3532624/">DPP UU Metagame Discussion</a>`,
1944
+ `&bullet; <a href="https://www.smogon.com/forums/threads/3503638/">DPP UU Viability Rankings</a>`,
2222
1945
  ],
2223
- mod: 'gen7',
1946
+ mod: 'gen4',
2224
1947
  // searchShow: false,
2225
- ruleset: ['[Gen 7] NU'],
2226
- banlist: ['NU', 'PUBL'],
1948
+ ruleset: ['[Gen 4] OU'],
1949
+ banlist: ['OU', 'UUBL'],
1950
+ unbanlist: ['Arena Trap'],
2227
1951
  },
2228
1952
  {
2229
- name: "[Gen 2] NC2000 + Crystal Moves",
1953
+ name: "[Gen 3] Doubles OU",
2230
1954
  threads: [
2231
- `&bullet; <a href="https://www.smogon.com/forums/threads/3682691/">Nintendo Cup 2000 Resource Hub</a>`,
2232
- `&bullet; <a href="https://www.smogon.com/forums/threads/3677370/">Differences between Nintendo Cup 2000 and GSC OU</a>`,
1955
+ `&bullet; <a href="https://www.smogon.com/forums/threads/3666831/">ADV Doubles OU</a>`,
2233
1956
  ],
2234
- mod: 'gen2stadium2',
2235
- ruleset: ['[Gen 2] Nintendo Cup 2000', 'Evasion Moves Clause', 'OHKO Clause', '!Nintendo Cup 2000 Move Legality'],
1957
+ mod: 'gen3',
1958
+ // searchShow: false,
1959
+ gameType: 'doubles',
1960
+ ruleset: ['Standard', '!Sleep Clause Mod', '!Switch Priority Clause Mod'],
1961
+ banlist: ['Uber'],
1962
+ unbanlist: ['Deoxys-Speed', 'Wobbuffet', 'Wynaut'],
2236
1963
  },
2237
1964
  // Past Gens OU
2238
1965
  ///////////////////////////////////////////////////////////////////
@@ -2485,6 +2212,17 @@ exports.Formats = [
2485
2212
  ruleset: ['[Gen 7] RU'],
2486
2213
  banlist: ['RU', 'NUBL', 'Drought'],
2487
2214
  },
2215
+ {
2216
+ name: "[Gen 7] PU",
2217
+ threads: [
2218
+ `&bullet; <a href="https://www.smogon.com/forums/threads/3611496/">USM PU Sample Teams</a>`,
2219
+ `&bullet; <a href="https://www.smogon.com/forums/threads/3614892/">USM PU Viability Rankings</a>`,
2220
+ ],
2221
+ mod: 'gen7',
2222
+ searchShow: false,
2223
+ ruleset: ['[Gen 7] NU'],
2224
+ banlist: ['NU', 'PUBL'],
2225
+ },
2488
2226
  {
2489
2227
  name: "[Gen 7] LC",
2490
2228
  threads: [
@@ -2722,15 +2460,6 @@ exports.Formats = [
2722
2460
  section: "OR/AS Singles",
2723
2461
  column: 4,
2724
2462
  },
2725
- {
2726
- name: "[Gen 6] Ubers",
2727
- threads: [
2728
- `&bullet; <a href="https://www.smogon.com/forums/posts/8286277/">ORAS Ubers</a>`,
2729
- ],
2730
- mod: 'gen6',
2731
- searchShow: false,
2732
- ruleset: ['Standard', 'Swagger Clause', 'Mega Rayquaza Clause'],
2733
- },
2734
2463
  {
2735
2464
  name: "[Gen 6] UU",
2736
2465
  threads: [
@@ -2973,6 +2702,15 @@ exports.Formats = [
2973
2702
  section: "B2/W2 Singles",
2974
2703
  column: 4,
2975
2704
  },
2705
+ {
2706
+ name: "[Gen 5] Ubers",
2707
+ threads: [
2708
+ `&bullet; <a href="https://www.smogon.com/forums/posts/8286278/">BW2 Ubers</a>`,
2709
+ ],
2710
+ mod: 'gen5',
2711
+ searchShow: false,
2712
+ ruleset: ['Standard', 'Sleep Clause Mod'],
2713
+ },
2976
2714
  {
2977
2715
  name: "[Gen 5] UU",
2978
2716
  threads: [
@@ -2981,8 +2719,8 @@ exports.Formats = [
2981
2719
  ],
2982
2720
  mod: 'gen5',
2983
2721
  searchShow: false,
2984
- ruleset: ['Standard', 'Evasion Abilities Clause', 'Baton Pass Clause', 'Swagger Clause', 'Sleep Clause Mod'],
2985
- banlist: ['Uber', 'OU', 'UUBL', 'Arena Trap', 'Drought', 'Sand Stream', 'Snow Warning'],
2722
+ ruleset: ['Standard', 'Evasion Abilities Clause', 'Swagger Clause', 'Sleep Clause Mod'],
2723
+ banlist: ['Uber', 'OU', 'UUBL', 'Arena Trap', 'Drought', 'Sand Stream', 'Snow Warning', 'Prankster + Assist', 'Prankster + Copycat', 'Baton Pass'],
2986
2724
  },
2987
2725
  {
2988
2726
  name: "[Gen 5] RU",
@@ -2992,8 +2730,9 @@ exports.Formats = [
2992
2730
  ],
2993
2731
  mod: 'gen5',
2994
2732
  searchShow: false,
2995
- ruleset: ['[Gen 5] UU', '!Sleep Clause Mod', 'Sleep Moves Clause'],
2733
+ ruleset: ['[Gen 5] UU', 'Baton Pass Clause', '!Sleep Clause Mod', 'Sleep Moves Clause'],
2996
2734
  banlist: ['UU', 'RUBL', 'Shadow Tag', 'Shell Smash + Baton Pass'],
2735
+ unbanlist: ['Prankster + Assist', 'Prankster + Copycat', 'Baton Pass'],
2997
2736
  },
2998
2737
  {
2999
2738
  name: "[Gen 5] NU",
@@ -3003,8 +2742,8 @@ exports.Formats = [
3003
2742
  ],
3004
2743
  mod: 'gen5',
3005
2744
  searchShow: false,
3006
- ruleset: ['[Gen 5] RU', '!Sleep Moves Clause', 'Sleep Clause Mod', '+Shadow Tag'],
3007
- banlist: ['RU', 'NUBL', 'Prankster + Assist'],
2745
+ ruleset: ['[Gen 5] RU', '!Sleep Moves Clause', 'Sleep Clause Mod'],
2746
+ banlist: ['RU', 'NUBL', 'Assist', 'Copycat'],
3008
2747
  },
3009
2748
  {
3010
2749
  name: "[Gen 5] PU",
@@ -3014,7 +2753,7 @@ exports.Formats = [
3014
2753
  mod: 'gen5',
3015
2754
  searchShow: false,
3016
2755
  ruleset: ['[Gen 5] NU', 'Sleep Moves Clause'],
3017
- banlist: ['NU', 'Combusken', 'Gothorita', 'Linoone', 'Riolu', 'Rotom-Frost', 'Throh', 'Vigoroth'],
2756
+ banlist: ['NU', 'Combusken', 'Gothorita', 'Linoone', 'Riolu', 'Rotom-Frost', 'Simipour', 'Throh', 'Vigoroth'],
3018
2757
  },
3019
2758
  {
3020
2759
  name: "[Gen 5] LC",
@@ -3150,18 +2889,6 @@ exports.Formats = [
3150
2889
  ruleset: ['Standard'],
3151
2890
  banlist: ['AG'],
3152
2891
  },
3153
- {
3154
- name: "[Gen 4] UU",
3155
- threads: [
3156
- `&bullet; <a href="https://www.smogon.com/forums/threads/3532624/">DPP UU Metagame Discussion</a>`,
3157
- `&bullet; <a href="https://www.smogon.com/forums/threads/3503638/">DPP UU Viability Rankings</a>`,
3158
- ],
3159
- mod: 'gen4',
3160
- searchShow: false,
3161
- ruleset: ['[Gen 4] OU'],
3162
- banlist: ['OU', 'UUBL'],
3163
- unbanlist: ['Arena Trap'],
3164
- },
3165
2892
  {
3166
2893
  name: "[Gen 4] NU",
3167
2894
  threads: [
@@ -3380,7 +3107,7 @@ exports.Formats = [
3380
3107
  'Picked Team Size = 1', 'Max Team Size = 3',
3381
3108
  '[Gen 2] OU', 'Accuracy Moves Clause', 'Sleep Moves Clause', 'Team Preview',
3382
3109
  ],
3383
- banlist: ['Clefable', 'Snorlax', 'Zapdos', 'Berserk Gene', 'Bright Powder', 'Focus Band', 'King\'s Rock', 'Quick Claw', 'Destiny Bond', 'Explosion', 'Present', 'Self-Destruct'],
3110
+ banlist: ['Clefable', 'Snorlax', 'Zapdos', 'Berserk Gene', 'Bright Powder', 'Focus Band', 'King\'s Rock', 'Quick Claw', 'Destiny Bond', 'Explosion', 'Perish Song', 'Present', 'Self-Destruct'],
3384
3111
  },
3385
3112
  {
3386
3113
  name: "[Gen 2] Nintendo Cup 2000",