@pkmn/sim 0.5.6 → 0.5.9

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 (52) hide show
  1. package/build/config/formats.js +482 -283
  2. package/build/config/formats.js.map +1 -1
  3. package/build/data/aliases.js +0 -2
  4. package/build/data/aliases.js.map +1 -1
  5. package/build/data/formats-data.js +12 -12
  6. package/build/data/formats-data.js.map +1 -1
  7. package/build/data/items.js +2 -2
  8. package/build/data/items.js.map +1 -1
  9. package/build/data/learnsets.js +5 -6
  10. package/build/data/learnsets.js.map +1 -1
  11. package/build/data/mods/gen2/moves.js +13 -1
  12. package/build/data/mods/gen2/moves.js.map +1 -1
  13. package/build/data/mods/gen3/formats-data.js +2 -2
  14. package/build/data/mods/gen3/formats-data.js.map +1 -1
  15. package/build/data/mods/gen4/formats-data.js +4 -4
  16. package/build/data/mods/gen4/formats-data.js.map +1 -1
  17. package/build/data/mods/gen4/moves.js +7 -5
  18. package/build/data/mods/gen4/moves.js.map +1 -1
  19. package/build/data/mods/gen5/moves.js +6 -4
  20. package/build/data/mods/gen5/moves.js.map +1 -1
  21. package/build/data/mods/gen6/items.js +2 -2
  22. package/build/data/mods/gen6/items.js.map +1 -1
  23. package/build/data/mods/gen7/moves.js +3 -3
  24. package/build/data/mods/gen7/moves.js.map +1 -1
  25. package/build/data/mods/gen7/pokedex.js +5 -0
  26. package/build/data/mods/gen7/pokedex.js.map +1 -1
  27. package/build/data/moves.js +6 -5
  28. package/build/data/moves.js.map +1 -1
  29. package/build/data/pokedex.js +3 -3
  30. package/build/data/pokedex.js.map +1 -1
  31. package/build/data/rulesets.js +23 -139
  32. package/build/data/rulesets.js.map +1 -1
  33. package/build/sim/team-validator.js +11 -0
  34. package/build/sim/team-validator.js.map +1 -1
  35. package/config/formats.ts +464 -279
  36. package/data/aliases.ts +0 -2
  37. package/data/formats-data.ts +12 -12
  38. package/data/items.ts +2 -2
  39. package/data/learnsets.ts +5 -6
  40. package/data/mods/gen2/moves.ts +13 -1
  41. package/data/mods/gen3/formats-data.ts +2 -2
  42. package/data/mods/gen4/formats-data.ts +4 -4
  43. package/data/mods/gen4/moves.ts +6 -4
  44. package/data/mods/gen5/moves.ts +6 -4
  45. package/data/mods/gen6/items.ts +2 -2
  46. package/data/mods/gen7/moves.ts +3 -3
  47. package/data/mods/gen7/pokedex.ts +5 -0
  48. package/data/moves.ts +6 -5
  49. package/data/pokedex.ts +3 -3
  50. package/data/rulesets.ts +21 -125
  51. package/package.json +2 -2
  52. package/sim/team-validator.ts +13 -0
@@ -217,8 +217,8 @@ exports.Formats = [
217
217
  mod: 'gen8',
218
218
  ruleset: ['[Gen 8] PU'],
219
219
  banlist: [
220
- 'PU', 'Aurorus', 'Centiskorch', 'Drampa', 'Exeggutor-Alola', 'Gallade', 'Haunter', 'Magmortar', 'Magneton', 'Omastar', 'Rotom-Frost',
221
- 'Turtonator', 'Vanilluxe', 'Vikavolt', 'Silvally-Dragon', 'Silvally-Ground', 'Sneasel', 'Damp Rock', 'Grassy Seed',
220
+ 'PU', 'Arctovish', 'Aurorus', 'Centiskorch', 'Drampa', 'Exeggutor-Alola', 'Gallade', 'Haunter', 'Magmortar', 'Magneton', 'Omastar',
221
+ 'Rotom-Frost', 'Turtonator', 'Vanilluxe', 'Vikavolt', 'Silvally-Dragon', 'Silvally-Ground', 'Sneasel', 'Damp Rock', 'Grassy Seed',
222
222
  ],
223
223
  },
224
224
  {
@@ -333,6 +333,11 @@ exports.Formats = [
333
333
  },
334
334
  {
335
335
  name: "[Gen 8] VGC 2022",
336
+ threads: [
337
+ `&bullet; <a href="https://www.smogon.com/forums/threads/3677186/">VGC 2022 Metagame Discussion</a>`,
338
+ `&bullet; <a href="https://www.smogon.com/forums/threads/3695848/">VGC 2022 Sample Teams</a>`,
339
+ `&bullet; <a href="https://www.smogon.com/forums/threads/3696395/">VGC 2022 Viability Rankings</a>`,
340
+ ],
336
341
  mod: 'gen8',
337
342
  gameType: 'doubles',
338
343
  ruleset: ['Flat Rules', '!! Adjust Level = 50', 'Min Source Gen = 8', 'VGC Timer', 'Limit Two Restricted'],
@@ -383,7 +388,7 @@ exports.Formats = [
383
388
  'HP Percentage Mod', 'Cancel Mod',
384
389
  ],
385
390
  banlist: [
386
- 'Pokestar Spirit', 'Shedinja + Sturdy', 'Battle Bond', 'Cheek Pouch', 'Cursed Body', 'Dry Skin', 'Fluffy', 'Fur Coat', 'Gorilla Tactics',
391
+ 'Pokestar Spirit', 'Shedinja + Sturdy', 'Battle Bond', 'Cheek Pouch', 'Cursed Body', 'Dry Skin', 'Fur Coat', 'Gorilla Tactics',
387
392
  'Grassy Surge', 'Huge Power', 'Ice Body', 'Iron Barbs', 'Libero', 'Moody', 'Neutralizing Gas', 'Parental Bond', 'Perish Body', 'Poison Heal',
388
393
  'Power Construct', 'Pressure', 'Protean', 'Pure Power', 'Rain Dish', 'Rough Skin', 'Sand Spit', 'Sand Stream', 'Snow Warning', 'Stamina',
389
394
  'Volt Absorb', 'Water Absorb', 'Wonder Guard', 'Abomasite', 'Aguav Berry', 'Assault Vest', 'Berry', 'Berry Juice', 'Berserk Gene',
@@ -438,11 +443,11 @@ exports.Formats = [
438
443
  ruleset: ['Standard NatDex', 'OHKO Clause', 'Evasion Moves Clause', 'Species Clause', 'Dynamax Clause', 'Sleep Clause Mod'],
439
444
  banlist: [
440
445
  'Alakazam-Mega', 'Arceus', 'Blastoise-Mega', 'Blaziken-Mega', 'Calyrex-Ice', 'Calyrex-Shadow', 'Cinderace', 'Darkrai',
441
- 'Darmanitan-Galar', 'Deoxys-Attack', 'Deoxys-Base', 'Deoxys-Speed', 'Dialga', 'Dracovish', 'Dragapult', 'Eternatus',
446
+ 'Darmanitan-Galar', 'Deoxys-Attack', 'Deoxys-Base', 'Deoxys-Speed', 'Dialga', 'Dracovish', 'Eternatus',
442
447
  'Genesect', 'Gengar-Mega', 'Giratina', 'Giratina-Origin', 'Groudon', 'Ho-Oh', 'Kangaskhan-Mega', 'Kyogre', 'Kyurem-Black',
443
448
  'Kyurem-White', 'Landorus-Base', 'Lucario-Mega', 'Lugia', 'Lunala', 'Magearna', 'Marshadow', 'Metagross-Mega', 'Mewtwo',
444
449
  'Naganadel', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane', 'Necrozma-Ultra', 'Palkia', 'Pheromosa', 'Rayquaza', 'Reshiram',
445
- 'Salamence-Mega', 'Shaymin-Sky', 'Solgaleo', 'Spectrier', 'Urshifu-Base', 'Xerneas', 'Yveltal', 'Zacian',
450
+ 'Salamence-Mega', 'Shaymin-Sky', 'Solgaleo', 'Spectrier', 'Tornadus-Therian', 'Urshifu-Base', 'Xerneas', 'Yveltal', 'Zacian',
446
451
  'Zacian-Crowned', 'Zamazenta', 'Zamazenta-Crowned', 'Zekrom', 'Zygarde-Base', 'Zygarde-Complete', 'Arena Trap', 'Moody',
447
452
  'Power Construct', 'Sand Veil', 'Shadow Tag', 'Snow Cloak', 'Bright Powder', 'King\'s Rock', 'Lax Incense', 'Razor Fang',
448
453
  'Quick Claw', 'Baton Pass',
@@ -467,17 +472,16 @@ exports.Formats = [
467
472
  'Drizzle', 'Drought',
468
473
  // Slowbronite is banned so it doesn't validate on Galarian Slowbro
469
474
  'Slowbronite',
470
- // NatDex suspect
471
- 'Tornadus-Therian',
475
+ // NDOU suspect
476
+ 'Dragapult',
472
477
  ],
473
478
  // Used to distinguish UU from below UU in the client
474
479
  restricted: [
475
- 'Aegislash', 'Alakazam-Base', 'Altaria-Mega', 'Amoonguss', 'Beedrill-Mega', 'Blaziken-Base', 'Breloom', 'Celesteela',
476
- 'Chandelure', 'Donphan', 'Dracozolt', 'Dragonite', 'Feraligatr', 'Gastrodon', 'Hatterene', 'Hippowdon', 'Infernape',
477
- 'Keldeo', 'Krookodile', 'Mamoswine', 'Mandibuzz', 'Manectric-Mega', 'Melmetal', 'Mienshao', 'Moltres-Base',
478
- 'Nidoking', 'Nidoqueen', 'Nihilego', 'Quagsire', 'Regieleki', 'Ribombee', 'Rotom-Heat', 'Rotom-Wash', 'Salamence',
479
- 'Scizor', 'Skarmory', 'Slowking-Base', 'Swampert-Base', 'Talonflame', 'Tangrowth', 'Tornadus-Base', 'Umbreon',
480
- 'Urshifu-Rapid-Strike',
480
+ 'Aegislash', 'Alakazam-Base', 'Altaria-Mega', 'Amoonguss', 'Azumarill', 'Beedrill-Mega', 'Blaziken-Base', 'Breloom', 'Celesteela',
481
+ 'Chandelure', 'Donphan', 'Dracozolt', 'Dragonite', 'Feraligatr', 'Gastrodon', 'Hatterene', 'Hippowdon', 'Infernape', 'Keldeo',
482
+ 'Krookodile', 'Mamoswine', 'Mandibuzz', 'Manectric-Mega', 'Melmetal', 'Mienshao', 'Moltres-Base', 'Nidoking', 'Nidoqueen', 'Nihilego',
483
+ 'Quagsire', 'Regieleki', 'Ribombee', 'Rotom-Heat', 'Rotom-Wash', 'Salamence', 'Scizor', 'Skarmory', 'Slowking-Base', 'Swampert-Base',
484
+ 'Talonflame', 'Tangrowth', 'Tornadus-Base', 'Umbreon', 'Urshifu-Rapid-Strike',
481
485
  ],
482
486
  },
483
487
  {
@@ -587,133 +591,212 @@ exports.Formats = [
587
591
  column: 2,
588
592
  },
589
593
  {
590
- name: "[Gen 8] Trademarked",
591
- desc: `Sacrifice your Pok&eacute;mon's ability for a status move that activates on switch-in.`,
594
+ name: "[Gen 8] Shared Power",
595
+ desc: `Once a Pok&eacute;mon switches in, its ability is shared with the rest of the team.`,
592
596
  threads: [
593
- `&bullet; <a href="https://www.smogon.com/forums/threads/3656980/">Trademarked</a>`,
597
+ `&bullet; <a href="https://www.smogon.com/forums/threads/3660877/">Shared Power</a>`,
594
598
  ],
595
- mod: 'gen8',
599
+ mod: 'sharedpower',
596
600
  // searchShow: false,
597
601
  ruleset: ['Standard', 'Dynamax Clause'],
598
602
  banlist: [
599
- 'Calyrex-Ice', 'Calyrex-Shadow', 'Darmanitan-Galar', 'Dialga', 'Dracovish', 'Dragapult', 'Eternatus', 'Kyurem-Black', 'Kyurem-White',
600
- 'Giratina', 'Giratina-Origin', 'Genesect', 'Groudon', 'Ho-Oh', 'Kartana', 'Kyogre', 'Lugia', 'Lunala', 'Magearna', 'Marowak-Alola',
601
- 'Marshadow', 'Melmetal', 'Mewtwo', 'Naganadel', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane', 'Palkia', 'Pheromosa', 'Rayquaza',
602
- 'Reshiram', 'Solgaleo', 'Urshifu-Base', 'Xerneas', 'Yveltal', 'Zacian', 'Zacian-Crowned', 'Zamazenta', 'Zamazenta-Crowned', 'Zekrom',
603
- 'Zygarde-Base', 'Arena Trap', 'Moody', 'Power Construct', 'Shadow Tag', 'Baton Pass',
603
+ 'Calyrex-Ice', 'Calyrex-Shadow', 'Darmanitan-Galar', 'Dialga', 'Dracovish', 'Eternatus', 'Genesect', 'Giratina',
604
+ 'Giratina-Origin', 'Groudon', 'Ho-Oh', 'Kyogre', 'Kyurem-Black', 'Kyurem-White', 'Lugia', 'Lunala', 'Magearna',
605
+ 'Marshadow', 'Melmetal', 'Mewtwo', 'Naganadel', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane', 'Palkia',
606
+ 'Pheromosa', 'Rayquaza', 'Reshiram', 'Shedinja', 'Solgaleo', 'Urshifu-Base', 'Urshifu-Rapid-Strike',
607
+ 'Xerneas', 'Yveltal', 'Zacian', 'Zacian-Crowned', 'Zamazenta', 'Zamazenta-Crowned', 'Zekrom',
608
+ 'Arena Trap', 'Contrary', 'Drizzle ++ Swift Swim', 'Drought ++ Chlorophyll', 'Electric Surge ++ Surge Surfer',
609
+ 'Fur Coat', 'Guts', 'Harvest', 'Huge Power', 'Imposter', 'Innards Out', 'Libero', 'Magic Bounce', 'Magic Guard',
610
+ 'Magnet Pull', 'Mold Breaker', 'Moody', 'Neutralizing Gas', 'Power Construct', 'Queenly Majesty', 'Quick Draw',
611
+ 'Regenerator', 'Sand Rush', 'Sand Veil', 'Shadow Tag', 'Simple', 'Snow Cloak', 'Snow Warning ++ Slush Rush', 'Speed Boost',
612
+ 'Stakeout', 'Steelworker ++ Steely Spirit', 'Tinted Lens', 'Triage', 'Unaware', 'Unburden', 'Water Bubble',
613
+ 'Baton Pass',
604
614
  ],
605
- restricted: [
606
- 'Baneful Bunker', 'Block', 'Copycat', 'Corrosive Gas', 'Detect', 'Destiny Bond', 'Disable', 'Encore', 'Fairy Lock', 'Hypnosis', 'Ingrain',
607
- 'Instruct', 'Lovely Kiss', 'King\'s Shield', 'Mat Block', 'Mean Look', 'Memento', 'move:Metronome', 'Obstruct', 'Octolock', 'Nature Power',
608
- 'Parting Shot', 'Psycho Shift', 'Protect', 'Roar', 'Sing', 'Skill Swap', 'Sleep Powder', 'Sleep Talk', 'Spiky Shield', 'Spore', 'Substitute',
609
- 'Teleport', 'Whirlwind', 'Wish', 'Yawn',
615
+ getSharedPower(pokemon) {
616
+ const sharedPower = new Set();
617
+ for (const ally of pokemon.side.pokemon) {
618
+ if (ally.previouslySwitchedIn > 0) {
619
+ if (pokemon.battle.dex.currentMod !== 'sharedpower' && ['trace', 'mirrorarmor'].includes(ally.baseAbility)) {
620
+ sharedPower.add('noability');
621
+ continue;
622
+ }
623
+ sharedPower.add(ally.baseAbility);
624
+ }
625
+ }
626
+ sharedPower.delete(pokemon.baseAbility);
627
+ return sharedPower;
628
+ },
629
+ onBeforeSwitchIn(pokemon) {
630
+ let format = this.format;
631
+ if (!format.getSharedPower)
632
+ format = this.dex.formats.get('gen8sharedpower');
633
+ for (const ability of format.getSharedPower(pokemon)) {
634
+ const effect = 'ability:' + ability;
635
+ pokemon.volatiles[effect] = { id: this.toID(effect), target: pokemon };
636
+ if (!pokemon.m.abils)
637
+ pokemon.m.abils = [];
638
+ if (!pokemon.m.abils.includes(effect))
639
+ pokemon.m.abils.push(effect);
640
+ }
641
+ },
642
+ onSwitchInPriority: 2,
643
+ onSwitchIn(pokemon) {
644
+ let format = this.format;
645
+ if (!format.getSharedPower)
646
+ format = this.dex.formats.get('gen8sharedpower');
647
+ for (const ability of format.getSharedPower(pokemon)) {
648
+ if (ability === 'noability') {
649
+ 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.`);
650
+ }
651
+ const effect = 'ability:' + ability;
652
+ delete pokemon.volatiles[effect];
653
+ pokemon.addVolatile(effect);
654
+ }
655
+ },
656
+ },
657
+ {
658
+ name: "[Gen 8] Cross Evolution",
659
+ 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.`,
660
+ threads: [
661
+ `&bullet; <a href="https://www.smogon.com/forums/threads/3657562/">Cross Evolution</a>`,
610
662
  ],
611
- onValidateTeam(team, format, teamHas) {
612
- const problems = [];
613
- for (const trademark in teamHas.trademarks) {
614
- if (teamHas.trademarks[trademark] > 1) {
615
- problems.push(`You are limited to 1 of each Trademark.`, `(You have ${teamHas.trademarks[trademark]} Pok\u00e9mon with ${trademark} as a Trademark.)`);
663
+ mod: 'gen8',
664
+ // searchShow: false,
665
+ ruleset: ['Standard', 'Overflow Stat Mod', 'Dynamax Clause'],
666
+ banlist: ['Corsola-Galar', 'Sneasel', 'Type: Null', 'Arena Trap', 'Ice Scales', 'Moody', 'King\'s Rock', 'Baton Pass'],
667
+ restricted: ['Chansey', 'Lunala', 'Shedinja', 'Solgaleo', 'Gorilla Tactics', 'Huge Power', 'Pure Power', 'Shadow Tag'],
668
+ onValidateTeam(team) {
669
+ const names = new Set();
670
+ for (const set of team) {
671
+ const name = set.name;
672
+ if (names.has(this.dex.toID(name))) {
673
+ return [
674
+ `Your Pok\u00e9mon must have different nicknames.`,
675
+ `(You have more than one Pok\u00e9mon named '${name}')`,
676
+ ];
616
677
  }
678
+ names.add(this.dex.toID(name));
617
679
  }
618
- return problems;
680
+ if (!names.size) {
681
+ return [
682
+ `${this.format.name} works using nicknames; your team has 0 nicknamed Pok\u00e9mon.`,
683
+ `(If this was intentional, add a nickname to one Pok\u00e9mon that isn't the name of a Pok\u00e9mon species.)`,
684
+ ];
685
+ }
686
+ },
687
+ checkCanLearn(move, species, lsetData, set) {
688
+ // @ts-ignore
689
+ if (!set.sp?.exists || !set.crossSpecies?.exists) {
690
+ return this.checkCanLearn(move, species, lsetData, set);
691
+ }
692
+ // @ts-ignore
693
+ const problem = this.checkCanLearn(move, set.sp);
694
+ if (!problem)
695
+ return null;
696
+ // @ts-ignore
697
+ if (!set.crossMovesLeft)
698
+ return problem;
699
+ // @ts-ignore
700
+ if (this.checkCanLearn(move, set.crossSpecies))
701
+ return problem;
702
+ // @ts-ignore
703
+ set.crossMovesLeft--;
704
+ return null;
619
705
  },
620
706
  validateSet(set, teamHas) {
621
- const dex = this.dex;
622
- const ability = dex.moves.get(set.ability);
623
- if (!ability.exists) { // Not even a real move
707
+ const crossSpecies = this.dex.species.get(set.name);
708
+ let problems = this.dex.formats.get('Pokemon').onChangeSet?.call(this, set, this.format) || null;
709
+ if (Array.isArray(problems) && problems.length)
710
+ return problems;
711
+ const crossNonstandard = (!this.ruleTable.has('standardnatdex') && crossSpecies.isNonstandard === 'Past') ||
712
+ crossSpecies.isNonstandard === 'Future';
713
+ const crossIsCap = !this.ruleTable.has('+pokemontag:cap') && crossSpecies.isNonstandard === 'CAP';
714
+ if (!crossSpecies.exists || crossNonstandard || crossIsCap)
715
+ return this.validateSet(set, teamHas);
716
+ const species = this.dex.species.get(set.species);
717
+ const check = this.checkSpecies(set, species, species, {});
718
+ if (check)
719
+ return [check];
720
+ const nonstandard = !this.ruleTable.has('standardnatdex') && species.isNonstandard === 'Past';
721
+ const isCap = !this.ruleTable.has('+pokemontag:cap') && species.isNonstandard === 'CAP';
722
+ if (!species.exists || nonstandard || isCap || species === crossSpecies)
624
723
  return this.validateSet(set, teamHas);
724
+ if (!species.nfe)
725
+ return [`${species.name} cannot cross evolve because it doesn't evolve.`];
726
+ const crossIsUnreleased = (crossSpecies.tier === "Unreleased" && crossSpecies.isNonstandard === "Unobtainable");
727
+ if (crossSpecies.battleOnly || crossIsUnreleased || !crossSpecies.prevo) {
728
+ return [`${species.name} cannot cross evolve into ${crossSpecies.name} because it isn't an evolution.`];
625
729
  }
626
- // Absolute trademark bans
627
- if (ability.category !== 'Status') {
628
- return [`${ability.name} is not a status move, and cannot be used as a trademark.`];
730
+ if (this.ruleTable.isRestrictedSpecies(crossSpecies)) {
731
+ return [`${species.name} cannot cross evolve into ${crossSpecies.name} because it is banned.`];
629
732
  }
630
- if (ability.forceSwitch || ability.selfSwitch) {
733
+ const crossPrevoSpecies = this.dex.species.get(crossSpecies.prevo);
734
+ if (!crossPrevoSpecies.prevo !== !species.prevo) {
631
735
  return [
632
- `Force-switching and self-switching moves are banned from being used as trademarks.`,
633
- `(${ability.name} is a ${ability.forceSwitch ? 'force' : 'self'}-switching move.)`,
736
+ `${species.name} cannot cross evolve into ${crossSpecies.name} because they are not consecutive evolution stages.`,
634
737
  ];
635
738
  }
636
- const irrevokablyRestricted = [
637
- 'Assist', 'Copycat', 'Metronome', 'Mirror Move', 'Sleep Talk',
638
- 'Skill Swap', // Self-propagates indefinitely
639
- ];
640
- if (irrevokablyRestricted.includes(ability.name)) {
641
- return [`${ability.name} cannot safely function as a trademark.`];
739
+ const ability = this.dex.abilities.get(set.ability);
740
+ if (!this.ruleTable.isRestricted(`ability:${ability.id}`) || Object.values(species.abilities).includes(ability.name)) {
741
+ set.species = crossSpecies.name;
642
742
  }
643
- // Contingent trademark bans
644
- if (this.ruleTable.isRestricted(`move:${ability.id}`)) {
645
- return [`${ability.name} is restricted from being used as a trademark.`];
743
+ // @ts-ignore
744
+ set.sp = species;
745
+ // @ts-ignore
746
+ set.crossSpecies = crossSpecies;
747
+ // @ts-ignore
748
+ set.crossMovesLeft = 2;
749
+ problems = this.validateSet(set, teamHas);
750
+ set.name = crossSpecies.name;
751
+ set.species = species.name;
752
+ return problems;
753
+ },
754
+ onModifySpecies(species, target, source, effect) {
755
+ if (!target)
756
+ return; // chat
757
+ if (effect && ['imposter', 'transform'].includes(effect.id))
758
+ return;
759
+ if (target.set.name === target.set.species)
760
+ return;
761
+ const crossSpecies = this.dex.species.get(target.set.name);
762
+ if (!crossSpecies.exists)
763
+ return;
764
+ if (species.battleOnly || !species.nfe)
765
+ return;
766
+ const crossIsUnreleased = (crossSpecies.tier === "Unreleased" && crossSpecies.isNonstandard === "Unobtainable");
767
+ if (crossSpecies.battleOnly || crossIsUnreleased || !crossSpecies.prevo)
768
+ return;
769
+ const crossPrevoSpecies = this.dex.species.get(crossSpecies.prevo);
770
+ if (!crossPrevoSpecies.prevo !== !species.prevo)
771
+ return;
772
+ const mixedSpecies = this.dex.deepClone(species);
773
+ mixedSpecies.baseSpecies = mixedSpecies.name = `${species.name}-${crossSpecies.name}`;
774
+ mixedSpecies.weightkg =
775
+ Math.max(0.1, +(species.weightkg + crossSpecies.weightkg - crossPrevoSpecies.weightkg)).toFixed(1);
776
+ mixedSpecies.nfe = false;
777
+ mixedSpecies.evos = [];
778
+ mixedSpecies.eggGroups = crossSpecies.eggGroups;
779
+ mixedSpecies.abilities = crossSpecies.abilities;
780
+ mixedSpecies.bst = 0;
781
+ let i;
782
+ for (i in species.baseStats) {
783
+ const statChange = crossSpecies.baseStats[i] - crossPrevoSpecies.baseStats[i];
784
+ mixedSpecies.baseStats[i] = this.clampIntRange(species.baseStats[i] + statChange, 1, 255);
785
+ mixedSpecies.bst += mixedSpecies.baseStats[i];
646
786
  }
647
- if (set.moves.map(this.toID).includes(ability.id)) {
648
- return [`${set.name} may not use ${ability.name} as both a trademark and one of its moves simultaneously.`];
787
+ if (crossSpecies.types[0] !== crossPrevoSpecies.types[0])
788
+ mixedSpecies.types[0] = crossSpecies.types[0];
789
+ if (crossSpecies.types[1] !== crossPrevoSpecies.types[1]) {
790
+ mixedSpecies.types[1] = crossSpecies.types[1] || crossSpecies.types[0];
649
791
  }
650
- const customRules = this.format.customRules || [];
651
- if (!customRules.includes('!obtainableabilities'))
652
- customRules.push('!obtainableabilities');
653
- const TeamValidator = require('../sim/team-validator').TeamValidator;
654
- const validator = new TeamValidator(dex.formats.get(`${this.format.id}@@@${customRules.join(',')}`));
655
- const moves = set.moves;
656
- set.moves = [ability.id];
657
- set.ability = dex.species.get(set.species).abilities['0'];
658
- let problems = validator.validateSet(set, {}) || [];
659
- if (problems.length)
660
- return problems;
661
- set.moves = moves;
662
- set.ability = dex.species.get(set.species).abilities['0'];
663
- problems = problems.concat(validator.validateSet(set, teamHas) || []);
664
- set.ability = ability.id;
665
- if (!teamHas.trademarks)
666
- teamHas.trademarks = {};
667
- teamHas.trademarks[ability.name] = (teamHas.trademarks[ability.name] || 0) + 1;
668
- return problems.length ? problems : null;
669
- },
670
- pokemon: {
671
- getAbility() {
672
- const move = this.battle.dex.moves.get(this.battle.toID(this.ability));
673
- if (!move.exists)
674
- return Object.getPrototypeOf(this).getAbility.call(this);
675
- return {
676
- id: move.id,
677
- name: move.name,
678
- onStart(pokemon) {
679
- this.add('-activate', pokemon, 'ability: ' + move.name);
680
- this.actions.useMove(move, pokemon);
681
- },
682
- toString() {
683
- return "";
684
- },
685
- };
686
- },
792
+ if (mixedSpecies.types[0] === mixedSpecies.types[1])
793
+ mixedSpecies.types = [mixedSpecies.types[0]];
794
+ return mixedSpecies;
687
795
  },
688
- },
689
- {
690
- name: "[Gen 8] Linked",
691
- desc: `The first two moves in a Pok&eacute;mon's moveset are used simultaneously.`,
692
- threads: [
693
- `&bullet; <a href="https://www.smogon.com/forums/threads/3660421/">Linked</a>`,
694
- ],
695
- mod: 'linked',
696
- ruleset: ['Standard', 'Dynamax Clause'],
697
- banlist: [
698
- 'Calyrex-Ice', 'Calyrex-Shadow', 'Cinderace', 'Darmanitan-Galar', 'Dialga', 'Dracovish', 'Eternatus', 'Genesect', 'Giratina', 'Giratina-Origin', 'Groudon', 'Ho-Oh',
699
- 'Kyogre', 'Kyurem', 'Kyurem-Black', 'Kyurem-White', 'Landorus-Base', 'Lugia', 'Lunala', 'Magearna', 'Marshadow', 'Mewtwo', 'Naganadel', 'Necrozma-Dawn-Wings',
700
- 'Necrozma-Dusk-Mane', 'Palkia', 'Pheromosa', 'Rayquaza', 'Reshiram', 'Solgaleo', 'Spectrier', 'Urshifu-Base', 'Xerneas', 'Yveltal', 'Zacian', 'Zacian-Crowned',
701
- 'Zamazenta', 'Zamazenta-Crowned', 'Zekrom', 'Zygarde-Base', 'Zygarde-Complete', 'Arena Trap', 'Moody', 'Power Construct', 'Sand Veil', 'Shadow Tag', 'Snow Cloak',
702
- 'Bright Powder', 'King\'s Rock', 'Lax Incense', 'Baton Pass',
703
- ],
704
- restricted: [
705
- 'Baneful Bunker', 'Bounce', 'Protect', 'Detect', 'Dig', 'Dive', 'Fly', 'King\'s Shield', 'Nature\'s Madness', 'Night Shade',
706
- 'Obstruct', 'Phantom Force', 'Seismic Toss', 'Shadow Force', 'Sky Drop', 'Spiky Shield', 'Super Fang',
707
- ],
708
- onValidateSet(set) {
709
- const problems = [];
710
- for (const [i, moveid] of set.moves.entries()) {
711
- const move = this.dex.moves.get(moveid);
712
- if ([0, 1].includes(i) && this.ruleTable.isRestricted(`move:${move.id}`)) {
713
- problems.push(`${set.name || set.species}'s move ${move.name} cannot be linked.`);
714
- }
796
+ onBegin() {
797
+ for (const pokemon of this.getAllPokemon()) {
798
+ pokemon.baseSpecies = pokemon.species;
715
799
  }
716
- return problems;
717
800
  },
718
801
  },
719
802
  // Other Metagames
@@ -773,8 +856,8 @@ exports.Formats = [
773
856
  'Melmetal', 'Mewtwo', 'Naganadel', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane', 'Noivern', 'Palkia', 'Pheromosa', 'Rayquaza', 'Regigigas', 'Reshiram', 'Shedinja',
774
857
  'Solgaleo', 'Spectrier', 'Urshifu-Base', 'Urshifu-Rapid-Strike', 'Victini', 'Weavile', 'Xerneas', 'Yveltal', 'Zacian', 'Zacian-Crowned', 'Zamazenta-Base', 'Zekrom',
775
858
  'Zeraora', 'Zygarde-Base', 'Arena Trap', 'Comatose', 'Contrary', 'Fluffy', 'Fur Coat', 'Gorilla Tactics', 'Huge Power', 'Ice Scales', 'Illusion', 'Imposter',
776
- 'Innards Out', 'Intrepid Sword', 'Libero', 'Magnet Pull', 'Moody', 'Neutralizing Gas', 'Parental Bond', 'Poison Heal', 'Power Construct', 'Protean', 'Pure Power',
777
- 'Shadow Tag', 'Simple', 'Stakeout', 'Speed Boost', 'Water Bubble', 'Wonder Guard', 'King\'s Rock', 'Baton Pass',
859
+ 'Innards Out', 'Intrepid Sword', 'Libero', 'Magnet Pull', 'Moody', 'Neutralizing Gas', 'Parental Bond', 'Poison Heal', 'Protean', 'Pure Power', 'Shadow Tag',
860
+ 'Simple', 'Stakeout', 'Speed Boost', 'Water Bubble', 'Wonder Guard', 'King\'s Rock', 'Baton Pass',
778
861
  ],
779
862
  onValidateSet(set) {
780
863
  // Temporary fix until battle-only is implemented properly
@@ -859,17 +942,17 @@ exports.Formats = [
859
942
  mod: 'gen8',
860
943
  ruleset: ['Standard', 'STABmons Move Legality', 'Dynamax Clause', 'Sleep Moves Clause', '!Sleep Clause Mod'],
861
944
  banlist: [
862
- 'Aegislash', 'Blacephalon', 'Calyrex-Ice', 'Calyrex-Shadow', 'Darmanitan-Galar', 'Dialga', 'Dracovish', 'Dragapult', 'Dragonite',
863
- 'Eternatus', 'Genesect', 'Garchomp', 'Giratina', 'Giratina-Origin', 'Groudon', 'Ho-Oh', 'Kartana', 'Kyogre', 'Kyurem-Black',
864
- 'Kyurem-White', 'Landorus', 'Landorus-Therian', 'Lugia', 'Lunala', 'Marshadow', 'Mewtwo', 'Naganadel', 'Necrozma-Dawn-Wings',
865
- 'Necrozma-Dusk-Mane', 'Palkia', 'Pheromosa', 'Porygon-Z', 'Rayquaza', 'Reshiram', 'Silvally', 'Solgaleo', 'Spectrier', 'Tapu Bulu',
866
- 'Tapu Koko', 'Thundurus-Base', 'Urshifu-Base', 'Xerneas', 'Yveltal', 'Zacian', 'Zacian-Crowned', 'Zamazenta', 'Zamazenta-Crowned',
867
- 'Zapdos-Galar', 'Zekrom', 'Zygarde-Base', 'Arena Trap', 'Magnet Pull', 'Moody', 'Power Construct', 'Shadow Tag', 'King\'s Rock',
868
- 'Baton Pass',
945
+ 'Aegislash', 'Blacephalon', 'Calyrex-Ice', 'Calyrex-Shadow', 'Darmanitan-Galar', 'Dialga', 'Dracovish', 'Dragapult', 'Dragonite', 'Eternatus',
946
+ 'Genesect', 'Garchomp', 'Giratina', 'Giratina-Origin', 'Groudon', 'Ho-Oh', 'Kartana', 'Kyogre', 'Kyurem-Black', 'Kyurem-White', 'Landorus',
947
+ 'Landorus-Therian', 'Lugia', 'Lunala', 'Magearna', 'Marshadow', 'Mewtwo', 'Naganadel', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane', 'Palkia',
948
+ 'Pheromosa', 'Porygon-Z', 'Rayquaza', 'Reshiram', 'Silvally', 'Solgaleo', 'Spectrier', 'Tapu Bulu', 'Tapu Koko', 'Tapu Lele', 'Thundurus-Base',
949
+ 'Urshifu-Base', 'Xerneas', 'Yveltal', 'Zacian', 'Zacian-Crowned', 'Zamazenta', 'Zamazenta-Crowned', 'Zapdos-Galar', 'Zekrom', 'Zygarde-Base',
950
+ 'Arena Trap', 'Magnet Pull', 'Moody', 'Power Construct', 'Shadow Tag', 'King\'s Rock', 'Baton Pass',
869
951
  ],
870
952
  restricted: [
871
953
  'Acupressure', 'Astral Barrage', 'Belly Drum', 'Bolt Beak', 'Clangorous Soul', 'Double Iron Bash', 'Electrify', 'Extreme Speed', 'Fishious Rend',
872
- 'Geomancy', 'Glacial Lance', 'Oblivion Wing', 'Precipice Blades', 'Shell Smash', 'Shift Gear', 'Thousand Arrows', 'V-create', 'Wicked Blow',
954
+ 'Geomancy', 'Glacial Lance', 'Oblivion Wing', 'Precipice Blades', 'Shell Smash', 'Shift Gear', 'Thousand Arrows', 'Thunderous Kick', 'V-create',
955
+ 'Wicked Blow',
873
956
  ],
874
957
  },
875
958
  {
@@ -895,9 +978,9 @@ exports.Formats = [
895
978
  mod: 'gen8',
896
979
  ruleset: ['Standard', 'Dynamax Clause', 'Sleep Moves Clause'],
897
980
  banlist: [
898
- 'Blissey', 'Calyrex-Shadow', 'Chansey', 'Dragapult', 'Hawlucha', 'Mantine', 'Marowak-Alola', 'Melmetal', 'Pikachu', 'Toxapex',
981
+ 'Blissey', 'Calyrex-Shadow', 'Chansey', 'Dragapult', 'Hawlucha', 'Marowak-Alola', 'Melmetal', 'Pikachu', 'Toxapex',
899
982
  'Xerneas', 'Zacian', 'Zacian-Crowned', 'Uber > 1', 'AG ++ Uber > 1', 'Arena Trap', 'Huge Power', 'Moody', 'Pure Power',
900
- 'Shadow Tag', 'Bright Powder', 'Focus Band', 'King\'s Rock', 'Lax Incense', 'Quick Claw', 'Baton Pass',
983
+ 'Shadow Tag', 'Swift Swim', 'Bright Powder', 'Focus Band', 'King\'s Rock', 'Lax Incense', 'Quick Claw', 'Baton Pass',
901
984
  ],
902
985
  onValidateTeam(team) {
903
986
  const gods = new Set();
@@ -1018,8 +1101,10 @@ exports.Formats = [
1018
1101
  },
1019
1102
  {
1020
1103
  name: "[Gen 8 BDSP] NU",
1104
+ threads: [
1105
+ `&bullet; <a href="https://www.smogon.com/forums/threads/3697080/">BDSP NU</a>`,
1106
+ ],
1021
1107
  mod: 'gen8bdsp',
1022
- searchShow: false,
1023
1108
  ruleset: ['[Gen 8 BDSP] RU'],
1024
1109
  banlist: ['RU', 'NUBL'],
1025
1110
  },
@@ -1102,7 +1187,7 @@ exports.Formats = [
1102
1187
  ],
1103
1188
  mod: 'gen8',
1104
1189
  searchShow: false,
1105
- 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'],
1190
+ ruleset: ['Standard', 'Dynamax Clause', 'Camomons Mod'],
1106
1191
  banlist: [
1107
1192
  'Calyrex-Ice', 'Calyrex-Shadow', 'Darmanitan-Galar', 'Dialga', 'Dracovish', 'Dragonite', 'Eternatus', 'Genesect', 'Giratina', 'Giratina-Origin',
1108
1193
  'Groudon', 'Ho-Oh', 'Hydreigon', 'Kartana', 'Kyogre', 'Kyurem', 'Kyurem-Black', 'Kyurem-White', 'Landorus-Base', 'Latias', 'Latios', 'Lugia',
@@ -1110,21 +1195,6 @@ exports.Formats = [
1110
1195
  'Reuniclus', 'Shedinja', 'Slowking-Galar', 'Solgaleo', 'Spectrier', 'Tornadus-Therian', 'Volcarona', 'Xerneas', 'Yveltal', 'Zacian', 'Zacian-Crowned',
1111
1196
  'Zamazenta', 'Zamazenta-Crowned', 'Zekrom', 'Zeraora', 'Zygarde-Base', 'Arena Trap', 'Moody', 'Power Construct', 'Shadow Tag', 'Baton Pass',
1112
1197
  ],
1113
- onModifySpeciesPriority: 2,
1114
- onModifySpecies(species, target, source, effect) {
1115
- if (!target)
1116
- return; // Chat command
1117
- if (effect && ['imposter', 'transform'].includes(effect.id))
1118
- return;
1119
- const types = [...new Set(target.baseMoveSlots.slice(0, 2).map(move => this.dex.moves.get(move.id).type))];
1120
- return { ...species, types: types };
1121
- },
1122
- onSwitchIn(pokemon) {
1123
- this.add('-start', pokemon, 'typechange', (pokemon.illusion || pokemon).getTypes(true).join('/'), '[silent]');
1124
- },
1125
- onAfterMega(pokemon) {
1126
- this.add('-start', pokemon, 'typechange', (pokemon.illusion || pokemon).getTypes(true).join('/'), '[silent]');
1127
- },
1128
1198
  },
1129
1199
  {
1130
1200
  name: "[Gen 8] Inheritance",
@@ -1314,6 +1384,38 @@ exports.Formats = [
1314
1384
  this.add('-start', pokemon, donorTemplate.name, '[silent]');
1315
1385
  },
1316
1386
  },
1387
+ {
1388
+ name: "[Gen 8] Linked",
1389
+ desc: `The first two moves in a Pok&eacute;mon's moveset are used simultaneously.`,
1390
+ threads: [
1391
+ `&bullet; <a href="https://www.smogon.com/forums/threads/3660421/">Linked</a>`,
1392
+ ],
1393
+ mod: 'linked',
1394
+ searchShow: false,
1395
+ ruleset: ['Standard', 'Dynamax Clause'],
1396
+ banlist: [
1397
+ 'Calyrex-Ice', 'Calyrex-Shadow', 'Cinderace', 'Cloyster', 'Darmanitan-Galar', 'Dialga', 'Dracovish', 'Eternatus', 'Genesect', 'Giratina',
1398
+ 'Giratina-Origin', 'Groudon', 'Ho-Oh', 'Kartana', 'Kyogre', 'Kyurem', 'Kyurem-Black', 'Kyurem-White', 'Landorus-Base', 'Lugia', 'Lunala',
1399
+ 'Magearna', 'Marshadow', 'Mewtwo', 'Naganadel', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane', 'Palkia', 'Pheromosa', 'Rayquaza', 'Reshiram',
1400
+ 'Solgaleo', 'Spectrier', 'Urshifu-Base', 'Volcarona', 'Xerneas', 'Yveltal', 'Zacian', 'Zacian-Crowned', 'Zamazenta', 'Zamazenta-Crowned',
1401
+ 'Zekrom', 'Zygarde-Base', 'Zygarde-Complete', 'Arena Trap', 'Chlorophyll', 'Moody', 'Power Construct', 'Sand Rush', 'Sand Veil', 'Shadow Tag',
1402
+ 'Slush Rush', 'Snow Cloak', 'Speed Boost', 'Surge Surfer', 'Swift Swim', 'Unburden', 'Bright Powder', 'King\'s Rock', 'Lax Incense', 'Baton Pass',
1403
+ ],
1404
+ restricted: [
1405
+ 'Baneful Bunker', 'Bounce', 'Protect', 'Detect', 'Dig', 'Dive', 'Fly', 'King\'s Shield', 'Nature\'s Madness', 'Night Shade',
1406
+ 'Obstruct', 'Phantom Force', 'Seismic Toss', 'Shadow Force', 'Sky Drop', 'Spiky Shield', 'Super Fang', 'Trick Room',
1407
+ ],
1408
+ onValidateSet(set) {
1409
+ const problems = [];
1410
+ for (const [i, moveid] of set.moves.entries()) {
1411
+ const move = this.dex.moves.get(moveid);
1412
+ if ([0, 1].includes(i) && this.ruleTable.isRestricted(`move:${move.id}`)) {
1413
+ problems.push(`${set.name || set.species}'s move ${move.name} cannot be linked.`);
1414
+ }
1415
+ }
1416
+ return problems;
1417
+ },
1418
+ },
1317
1419
  {
1318
1420
  name: "[Gen 8] Multibility",
1319
1421
  desc: `Run a second ability at the cost of giving up a Pok&eacute;mon's item slot.`,
@@ -1554,88 +1656,24 @@ exports.Formats = [
1554
1656
  }
1555
1657
  modStats[statName] = tr(tr(2 * stat + set.ivs[usedStat] + tr(set.evs[usedStat] / 4)) * set.level / 100 + 5);
1556
1658
  }
1557
- if ('hp' in baseStats) {
1558
- const stat = baseStats['hp'];
1559
- modStats['hp'] = tr(tr(2 * stat + set.ivs['hp'] + tr(set.evs['hp'] / 4) + 100) * set.level / 100 + 10);
1560
- }
1561
- return this.natureModify(modStats, set);
1562
- },
1563
- natureModify(stats, set) {
1564
- const tr = this.trunc;
1565
- const nature = this.dex.natures.get(set.nature);
1566
- let s;
1567
- if (nature.plus) {
1568
- s = nature.minus;
1569
- const stat = this.ruleTable.has('overflowstatmod') ? Math.min(stats[s], 595) : stats[s];
1570
- stats[s] = this.ruleTable.has('overflowstatmod') ? Math.min(stats[nature.plus], 728) : stats[nature.plus];
1571
- stats[nature.plus] = tr(tr(stat * 110, 16) / 100);
1572
- }
1573
- return stats;
1574
- },
1575
- },
1576
- },
1577
- {
1578
- name: "[Gen 8] Shared Power",
1579
- desc: `Once a Pok&eacute;mon switches in, its ability is shared with the rest of the team.`,
1580
- threads: [
1581
- `&bullet; <a href="https://www.smogon.com/forums/threads/3660877/">Shared Power</a>`,
1582
- ],
1583
- mod: 'sharedpower',
1584
- searchShow: false,
1585
- ruleset: ['Standard', 'Dynamax Clause'],
1586
- banlist: [
1587
- 'Calyrex-Ice', 'Calyrex-Shadow', 'Darmanitan-Galar', 'Dialga', 'Dracovish', 'Eternatus', 'Genesect', 'Giratina',
1588
- 'Giratina-Origin', 'Groudon', 'Ho-Oh', 'Kyogre', 'Kyurem-Black', 'Kyurem-White', 'Lugia', 'Lunala', 'Magearna',
1589
- 'Marshadow', 'Melmetal', 'Mewtwo', 'Naganadel', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane', 'Palkia',
1590
- 'Pheromosa', 'Rayquaza', 'Reshiram', 'Shedinja', 'Solgaleo', 'Urshifu-Base', 'Urshifu-Rapid-Strike',
1591
- 'Xerneas', 'Yveltal', 'Zacian', 'Zacian-Crowned', 'Zamazenta', 'Zamazenta-Crowned', 'Zekrom',
1592
- 'Arena Trap', 'Contrary', 'Drizzle ++ Swift Swim', 'Drought ++ Chlorophyll', 'Electric Surge ++ Surge Surfer',
1593
- 'Fur Coat', 'Guts', 'Harvest', 'Huge Power', 'Imposter', 'Innards Out', 'Libero', 'Magic Bounce', 'Magic Guard',
1594
- 'Magnet Pull', 'Mold Breaker', 'Moody', 'Neutralizing Gas', 'Power Construct', 'Queenly Majesty', 'Quick Draw',
1595
- 'Regenerator', 'Sand Rush', 'Sand Veil', 'Shadow Tag', 'Simple', 'Snow Cloak', 'Snow Warning ++ Slush Rush', 'Speed Boost',
1596
- 'Stakeout', 'Steelworker ++ Steely Spirit', 'Tinted Lens', 'Triage', 'Unaware', 'Unburden', 'Water Bubble',
1597
- 'Baton Pass',
1598
- ],
1599
- getSharedPower(pokemon) {
1600
- const sharedPower = new Set();
1601
- for (const ally of pokemon.side.pokemon) {
1602
- if (ally.previouslySwitchedIn > 0) {
1603
- if (pokemon.battle.dex.currentMod !== 'sharedpower' && ['trace', 'mirrorarmor'].includes(ally.baseAbility)) {
1604
- sharedPower.add('noability');
1605
- continue;
1606
- }
1607
- sharedPower.add(ally.baseAbility);
1608
- }
1609
- }
1610
- sharedPower.delete(pokemon.baseAbility);
1611
- return sharedPower;
1612
- },
1613
- onBeforeSwitchIn(pokemon) {
1614
- let format = this.format;
1615
- if (!format.getSharedPower)
1616
- format = this.dex.formats.get('gen8sharedpower');
1617
- for (const ability of format.getSharedPower(pokemon)) {
1618
- const effect = 'ability:' + ability;
1619
- pokemon.volatiles[effect] = { id: this.toID(effect), target: pokemon };
1620
- if (!pokemon.m.abils)
1621
- pokemon.m.abils = [];
1622
- if (!pokemon.m.abils.includes(effect))
1623
- pokemon.m.abils.push(effect);
1624
- }
1625
- },
1626
- onSwitchInPriority: 2,
1627
- onSwitchIn(pokemon) {
1628
- let format = this.format;
1629
- if (!format.getSharedPower)
1630
- format = this.dex.formats.get('gen8sharedpower');
1631
- for (const ability of format.getSharedPower(pokemon)) {
1632
- if (ability === 'noability') {
1633
- 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.`);
1634
- }
1635
- const effect = 'ability:' + ability;
1636
- delete pokemon.volatiles[effect];
1637
- pokemon.addVolatile(effect);
1638
- }
1659
+ if ('hp' in baseStats) {
1660
+ const stat = baseStats['hp'];
1661
+ modStats['hp'] = tr(tr(2 * stat + set.ivs['hp'] + tr(set.evs['hp'] / 4) + 100) * set.level / 100 + 10);
1662
+ }
1663
+ return this.natureModify(modStats, set);
1664
+ },
1665
+ natureModify(stats, set) {
1666
+ const tr = this.trunc;
1667
+ const nature = this.dex.natures.get(set.nature);
1668
+ let s;
1669
+ if (nature.plus) {
1670
+ s = nature.minus;
1671
+ const stat = this.ruleTable.has('overflowstatmod') ? Math.min(stats[s], 595) : stats[s];
1672
+ stats[s] = this.ruleTable.has('overflowstatmod') ? Math.min(stats[nature.plus], 728) : stats[nature.plus];
1673
+ stats[nature.plus] = tr(tr(stat * 110, 16) / 100);
1674
+ }
1675
+ return stats;
1676
+ },
1639
1677
  },
1640
1678
  },
1641
1679
  {
@@ -1659,6 +1697,21 @@ exports.Formats = [
1659
1697
  // Shadow Tag/Arena Trap
1660
1698
  'Diglett-Base', 'Dugtrio-Base', 'Gothita', 'Gothitelle', 'Gothorita', 'Trapinch', 'Wobbuffet', 'Wynaut',
1661
1699
  ],
1700
+ onValidateSet(set) {
1701
+ const species = this.dex.species.get(set.species);
1702
+ const unSeenAbilities = Object.keys(species.abilities)
1703
+ .filter(key => key !== 'S' && (key !== 'H' || !species.unreleasedHidden))
1704
+ .map(key => species.abilities[key])
1705
+ .filter(ability => ability !== set.ability);
1706
+ if (unSeenAbilities.length && this.toID(set.ability) !== this.toID(species.abilities['S'])) {
1707
+ for (const abilityName of unSeenAbilities) {
1708
+ const banReason = this.ruleTable.check('ability:' + this.toID(abilityName));
1709
+ if (banReason) {
1710
+ return [`${set.name}'s ability ${abilityName} is ${banReason}.`];
1711
+ }
1712
+ }
1713
+ }
1714
+ },
1662
1715
  onBegin() {
1663
1716
  for (const pokemon of this.getAllPokemon()) {
1664
1717
  if (pokemon.ability === this.toID(pokemon.species.abilities['S'])) {
@@ -1685,6 +1738,116 @@ exports.Formats = [
1685
1738
  pokemon.m.innates = undefined;
1686
1739
  },
1687
1740
  },
1741
+ {
1742
+ name: "[Gen 8] Trademarked",
1743
+ desc: `Sacrifice your Pok&eacute;mon's ability for a status move that activates on switch-in.`,
1744
+ threads: [
1745
+ `&bullet; <a href="https://www.smogon.com/forums/threads/3656980/">Trademarked</a>`,
1746
+ ],
1747
+ mod: 'gen8',
1748
+ // While bugs are being fixed
1749
+ searchShow: false,
1750
+ challengeShow: false,
1751
+ tournamentShow: false,
1752
+ ruleset: ['Standard', 'Dynamax Clause'],
1753
+ banlist: [
1754
+ 'Calyrex-Ice', 'Calyrex-Shadow', 'Darmanitan-Galar', 'Dialga', 'Dracovish', 'Dragapult', 'Eternatus', 'Kyurem-Black', 'Kyurem-White', 'Giratina',
1755
+ 'Giratina-Origin', 'Genesect', 'Groudon', 'Ho-Oh', 'Kartana', 'Kyogre', 'Lugia', 'Lunala', 'Magearna', 'Marowak-Alola', 'Marshadow', 'Melmetal',
1756
+ 'Mewtwo', 'Naganadel', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane', 'Palkia', 'Pheromosa', 'Rayquaza', 'Reshiram', 'Solgaleo', 'Spectrier',
1757
+ 'Urshifu-Base', 'Victini', 'Xerneas', 'Yveltal', 'Zacian', 'Zacian-Crowned', 'Zamazenta', 'Zamazenta-Crowned', 'Zekrom', 'Zygarde-Base',
1758
+ 'Arena Trap', 'Moody', 'Neutralizing Gas', 'Power Construct', 'Shadow Tag', 'Baton Pass',
1759
+ ],
1760
+ restricted: [
1761
+ 'Baneful Bunker', 'Block', 'Copycat', 'Corrosive Gas', 'Detect', 'Destiny Bond', 'Disable', 'Encore', 'Fairy Lock', 'Hypnosis', 'Ingrain',
1762
+ 'Instruct', 'Lovely Kiss', 'King\'s Shield', 'Mat Block', 'Mean Look', 'Memento', 'move:Metronome', 'Obstruct', 'Octolock', 'Nature Power',
1763
+ 'Parting Shot', 'Psycho Shift', 'Protect', 'Roar', 'Sing', 'Skill Swap', 'Sleep Powder', 'Sleep Talk', 'Spiky Shield', 'Spore', 'Substitute',
1764
+ 'Switcheroo', 'Teleport', 'Trick', 'Whirlwind', 'Wish', 'Yawn',
1765
+ ],
1766
+ onValidateTeam(team, format, teamHas) {
1767
+ const problems = [];
1768
+ for (const trademark in teamHas.trademarks) {
1769
+ if (teamHas.trademarks[trademark] > 1) {
1770
+ problems.push(`You are limited to 1 of each Trademark.`, `(You have ${teamHas.trademarks[trademark]} Pok\u00e9mon with ${trademark} as a Trademark.)`);
1771
+ }
1772
+ }
1773
+ return problems;
1774
+ },
1775
+ validateSet(set, teamHas) {
1776
+ const dex = this.dex;
1777
+ const ability = dex.moves.get(set.ability);
1778
+ if (!ability.exists) { // Not even a real move
1779
+ return this.validateSet(set, teamHas);
1780
+ }
1781
+ // Absolute trademark bans
1782
+ if (ability.category !== 'Status') {
1783
+ return [`${ability.name} is not a status move, and cannot be used as a trademark.`];
1784
+ }
1785
+ if (ability.forceSwitch || ability.selfSwitch) {
1786
+ return [
1787
+ `Force-switching and self-switching moves are banned from being used as trademarks.`,
1788
+ `(${ability.name} is a ${ability.forceSwitch ? 'force' : 'self'}-switching move.)`,
1789
+ ];
1790
+ }
1791
+ const irrevokablyRestricted = [
1792
+ 'Assist', 'Copycat', 'Metronome', 'Mirror Move', 'Sleep Talk',
1793
+ 'Recycle', 'Trace',
1794
+ 'Skill Swap', // Self-propagates indefinitely
1795
+ ];
1796
+ for (const m of set.moves) {
1797
+ const move = dex.moves.get(m);
1798
+ if (irrevokablyRestricted.includes(move.name)) {
1799
+ return [`${move.name} is banned from Trademark, irrespective of custom rules, because it can cause endless turns.`];
1800
+ }
1801
+ }
1802
+ if (irrevokablyRestricted.includes(ability.name)) {
1803
+ return [`${ability.name} cannot safely function as a trademark.`];
1804
+ }
1805
+ // Contingent trademark bans
1806
+ if (this.ruleTable.isRestricted(`move:${ability.id}`)) {
1807
+ return [`${ability.name} is restricted from being used as a trademark.`];
1808
+ }
1809
+ if (set.moves.map(this.toID).includes(ability.id)) {
1810
+ return [`${set.name} may not use ${ability.name} as both a trademark and one of its moves simultaneously.`];
1811
+ }
1812
+ const customRules = this.format.customRules || [];
1813
+ if (!customRules.includes('!obtainableabilities'))
1814
+ customRules.push('!obtainableabilities');
1815
+ const TeamValidator = require('../sim/team-validator').TeamValidator;
1816
+ const validator = new TeamValidator(dex.formats.get(`${this.format.id}@@@${customRules.join(',')}`));
1817
+ const moves = set.moves;
1818
+ set.moves = [ability.id];
1819
+ set.ability = dex.species.get(set.species).abilities['0'];
1820
+ let problems = validator.validateSet(set, {}) || [];
1821
+ if (problems.length)
1822
+ return problems;
1823
+ set.moves = moves;
1824
+ set.ability = dex.species.get(set.species).abilities['0'];
1825
+ problems = problems.concat(validator.validateSet(set, teamHas) || []);
1826
+ set.ability = ability.id;
1827
+ if (!teamHas.trademarks)
1828
+ teamHas.trademarks = {};
1829
+ teamHas.trademarks[ability.name] = (teamHas.trademarks[ability.name] || 0) + 1;
1830
+ return problems.length ? problems : null;
1831
+ },
1832
+ pokemon: {
1833
+ getAbility() {
1834
+ const move = this.battle.dex.moves.get(this.battle.toID(this.ability));
1835
+ if (!move.exists)
1836
+ return Object.getPrototypeOf(this).getAbility.call(this);
1837
+ return {
1838
+ id: move.id,
1839
+ name: move.name,
1840
+ onStart(pokemon) {
1841
+ this.add('-activate', pokemon, 'ability: ' + move.name);
1842
+ this.actions.useMove(move, pokemon);
1843
+ },
1844
+ toString() {
1845
+ return "";
1846
+ },
1847
+ };
1848
+ },
1849
+ },
1850
+ },
1688
1851
  {
1689
1852
  name: "[Gen 8] The Loser's Game",
1690
1853
  desc: `The first player to lose all of their Pok&eacute;mon wins.`,
@@ -1826,6 +1989,41 @@ exports.Formats = [
1826
1989
  searchShow: false,
1827
1990
  ruleset: ['[Gen 8] Random Battle', 'Dynamax Clause'],
1828
1991
  },
1992
+ {
1993
+ name: "[Gen 8] Random Battle Mayhem",
1994
+ desc: `[Gen 8] Random Battle (No Dmax) with Team Preview and elements of Camomons, Inverse, Scalemons, and Shared Power.`,
1995
+ mod: 'sharedpower',
1996
+ team: 'random',
1997
+ searchShow: false,
1998
+ ruleset: ['[Gen 8] Random Battle', 'Team Preview', 'Dynamax Clause', 'Camomons Mod', 'Inverse Mod', 'Scalemons Mod'],
1999
+ onBeforeSwitchIn(pokemon) {
2000
+ let format = this.format;
2001
+ if (!format.getSharedPower)
2002
+ format = this.dex.formats.get('gen8sharedpower');
2003
+ for (const ability of format.getSharedPower(pokemon)) {
2004
+ const effect = 'ability:' + ability;
2005
+ pokemon.volatiles[effect] = { id: this.toID(effect), target: pokemon };
2006
+ if (!pokemon.m.abils)
2007
+ pokemon.m.abils = [];
2008
+ if (!pokemon.m.abils.includes(effect))
2009
+ pokemon.m.abils.push(effect);
2010
+ }
2011
+ },
2012
+ onSwitchInPriority: 2,
2013
+ onSwitchIn(pokemon) {
2014
+ let format = this.format;
2015
+ if (!format.getSharedPower)
2016
+ format = this.dex.formats.get('gen8sharedpower');
2017
+ for (const ability of format.getSharedPower(pokemon)) {
2018
+ if (ability === 'noability') {
2019
+ 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.`);
2020
+ }
2021
+ const effect = 'ability:' + ability;
2022
+ delete pokemon.volatiles[effect];
2023
+ pokemon.addVolatile(effect);
2024
+ }
2025
+ },
2026
+ },
1829
2027
  {
1830
2028
  name: "[Gen 8] BSS Factory",
1831
2029
  desc: `Randomized 3v3 Singles featuring Pok&eacute;mon and movesets popular in Battle Stadium Singles.`,
@@ -2082,36 +2280,42 @@ exports.Formats = [
2082
2280
  column: 3,
2083
2281
  },
2084
2282
  {
2085
- name: "[Gen 3] UU",
2283
+ name: "[Gen 4] UU",
2086
2284
  threads: [
2087
- `&bullet; <a href="https://www.smogon.com/forums/threads/3585923/">ADV UU Metagame Discussion</a>`,
2088
- `&bullet; <a href="https://www.smogon.com/forums/threads/3548578/">ADV UU Viability Rankings</a>`,
2285
+ `&bullet; <a href="https://www.smogon.com/forums/threads/3532624/">DPP UU Metagame Discussion</a>`,
2286
+ `&bullet; <a href="https://www.smogon.com/forums/threads/3503638/">DPP UU Viability Rankings</a>`,
2089
2287
  ],
2090
- mod: 'gen3',
2288
+ mod: 'gen4',
2091
2289
  // searchShow: false,
2092
- ruleset: ['Standard', 'NFE Clause'],
2093
- banlist: ['Uber', 'OU', 'UUBL', 'Smeargle + Ingrain', 'Baton Pass'],
2094
- unbanlist: ['Scyther', 'Sand Veil'],
2290
+ ruleset: ['[Gen 4] OU'],
2291
+ banlist: ['OU', 'UUBL'],
2292
+ unbanlist: ['Arena Trap', 'Swagger'],
2095
2293
  },
2096
2294
  {
2097
- name: "[Gen 1] NU",
2295
+ name: "[Gen 7] LC",
2098
2296
  threads: [
2099
- `&bullet; <a href="https://www.smogon.com/forums/threads/3668913/">RBY NU Viability Rankings</a>`,
2297
+ `&bullet; <a href="https://www.smogon.com/dex/sm/formats/lc/">USM LC Banlist</a>`,
2298
+ `&bullet; <a href="https://www.smogon.com/forums/threads/3639319/">USM LC Sample Teams</a>`,
2299
+ `&bullet; <a href="https://www.smogon.com/forums/threads/3621440/">USM LC Viability Rankings</a>`,
2100
2300
  ],
2101
- mod: 'gen1',
2301
+ mod: 'gen7',
2102
2302
  // searchShow: false,
2103
- ruleset: ['[Gen 1] UU'],
2104
- banlist: ['UU', 'NUBL'],
2303
+ ruleset: ['Little Cup', 'Standard', 'Swagger Clause'],
2304
+ banlist: [
2305
+ 'Aipom', 'Cutiefly', 'Drifloon', 'Gligar', 'Gothita', 'Meditite', 'Misdreavus', 'Murkrow', 'Porygon',
2306
+ 'Scyther', 'Sneasel', 'Swirlix', 'Tangela', 'Trapinch', 'Vulpix-Base', 'Wingull', 'Yanma',
2307
+ 'Eevium Z', 'Baton Pass', 'Dragon Rage', 'Sonic Boom', 'Sticky Web',
2308
+ ],
2105
2309
  },
2106
2310
  {
2107
- name: "[Gen 4] Ubers",
2311
+ name: "[Gen 5] PU",
2108
2312
  threads: [
2109
- `&bullet; <a href="https://www.smogon.com/forums/posts/8286279/">DPP Ubers</a>`,
2313
+ `&bullet; <a href="https://www.smogon.com/forums/posts/7326932/">BW2 PU</a>`,
2110
2314
  ],
2111
- mod: 'gen4',
2315
+ mod: 'gen5',
2112
2316
  // searchShow: false,
2113
- ruleset: ['Standard'],
2114
- banlist: ['AG'],
2317
+ ruleset: ['[Gen 5] NU', 'Sleep Moves Clause'],
2318
+ banlist: ['NU', 'PUBL'],
2115
2319
  },
2116
2320
  // Past Gens OU
2117
2321
  ///////////////////////////////////////////////////////////////////
@@ -2384,22 +2588,6 @@ exports.Formats = [
2384
2588
  ruleset: ['[Gen 7] NU'],
2385
2589
  banlist: ['NU', 'PUBL'],
2386
2590
  },
2387
- {
2388
- name: "[Gen 7] LC",
2389
- threads: [
2390
- `&bullet; <a href="https://www.smogon.com/dex/sm/formats/lc/">USM LC Banlist</a>`,
2391
- `&bullet; <a href="https://www.smogon.com/forums/threads/3639319/">USM LC Sample Teams</a>`,
2392
- `&bullet; <a href="https://www.smogon.com/forums/threads/3621440/">USM LC Viability Rankings</a>`,
2393
- ],
2394
- mod: 'gen7',
2395
- searchShow: false,
2396
- ruleset: ['Little Cup', 'Standard', 'Swagger Clause'],
2397
- banlist: [
2398
- 'Aipom', 'Cutiefly', 'Drifloon', 'Gligar', 'Gothita', 'Meditite', 'Misdreavus', 'Murkrow', 'Porygon',
2399
- 'Scyther', 'Sneasel', 'Swirlix', 'Tangela', 'Trapinch', 'Vulpix-Base', 'Wingull', 'Yanma',
2400
- 'Eevium Z', 'Baton Pass', 'Dragon Rage', 'Sonic Boom', 'Sticky Web',
2401
- ],
2402
- },
2403
2591
  {
2404
2592
  name: "[Gen 7] Monotype",
2405
2593
  desc: `All the Pok&eacute;mon on a team must share a type.`,
@@ -2716,14 +2904,15 @@ exports.Formats = [
2716
2904
  mod: 'gen6',
2717
2905
  searchShow: false,
2718
2906
  ruleset: [
2719
- 'Max Team Size = 3', 'Picked Team Size = 1',
2720
- 'Obtainable', 'Nickname Clause', 'Moody Clause', 'OHKO Clause', 'Evasion Moves Clause', 'Accuracy Moves Clause', 'Swagger Clause', 'Endless Battle Clause', 'HP Percentage Mod', 'Cancel Mod', 'Team Preview',
2907
+ 'Max Team Size = 3', 'Picked Team Size = 1', 'Obtainable', 'Nickname Clause', 'Moody Clause', 'OHKO Clause',
2908
+ 'Evasion Moves Clause', 'Accuracy Moves Clause', 'Swagger Clause', 'Endless Battle Clause', 'HP Percentage Mod',
2909
+ 'Cancel Mod', 'Team Preview',
2721
2910
  ],
2722
2911
  banlist: [
2723
2912
  'Arceus', 'Blaziken', 'Darkrai', 'Deoxys-Base', 'Deoxys-Attack', 'Deoxys-Defense', 'Dialga', 'Giratina',
2724
2913
  'Giratina-Origin', 'Groudon', 'Ho-Oh', 'Kangaskhan-Mega', 'Kyogre', 'Kyurem-White', 'Lugia', 'Mewtwo',
2725
2914
  'Palkia', 'Rayquaza', 'Reshiram', 'Salamence-Mega', 'Shaymin-Sky', 'Xerneas', 'Yveltal', 'Zekrom',
2726
- 'Focus Sash', 'Soul Dew', 'Perish Song',
2915
+ 'Focus Sash', 'Soul Dew', 'Grass Whistle', 'Hypnosis', 'Perish Song', 'Sing', 'Yawn',
2727
2916
  ],
2728
2917
  },
2729
2918
  {
@@ -2916,16 +3105,6 @@ exports.Formats = [
2916
3105
  ruleset: ['[Gen 5] RU', '!Sleep Moves Clause', 'Sleep Clause Mod'],
2917
3106
  banlist: ['RU', 'NUBL', 'Assist', 'Copycat'],
2918
3107
  },
2919
- {
2920
- name: "[Gen 5] PU",
2921
- threads: [
2922
- `&bullet; <a href="https://www.smogon.com/forums/posts/7326932/">BW2 PU</a>`,
2923
- ],
2924
- mod: 'gen5',
2925
- searchShow: false,
2926
- ruleset: ['[Gen 5] NU', 'Sleep Moves Clause'],
2927
- banlist: ['NU', 'PUBL'],
2928
- },
2929
3108
  {
2930
3109
  name: "[Gen 5] LC",
2931
3110
  threads: [
@@ -2962,7 +3141,7 @@ exports.Formats = [
2962
3141
  'Picked Team Size = 1', 'Max Team Size = 3',
2963
3142
  'Standard', 'Baton Pass Clause', 'Swagger Clause', 'Accuracy Moves Clause',
2964
3143
  ],
2965
- banlist: ['Uber', 'Cottonee', 'Dragonite', 'Kyurem-Black', 'Mew', 'Togekiss', 'Whimsicott', 'Victini', 'Bright Powder', 'Focus Band', 'Focus Sash', 'Lax Incense', 'Quick Claw', 'Soul Dew', 'Perish Song'],
3144
+ banlist: ['Uber', 'Cottonee', 'Dragonite', 'Jirachi', 'Kyurem-Black', 'Mew', 'Togekiss', 'Whimsicott', 'Victini', 'Bright Powder', 'Focus Band', 'Focus Sash', 'Lax Incense', 'Quick Claw', 'Soul Dew', 'Perish Song'],
2966
3145
  unbanlist: ['Genesect', 'Landorus', 'Manaphy', 'Thundurus', 'Tornadus-Therian'],
2967
3146
  },
2968
3147
  {
@@ -3051,16 +3230,14 @@ exports.Formats = [
3051
3230
  column: 5,
3052
3231
  },
3053
3232
  {
3054
- name: "[Gen 4] UU",
3233
+ name: "[Gen 4] Ubers",
3055
3234
  threads: [
3056
- `&bullet; <a href="https://www.smogon.com/forums/threads/3532624/">DPP UU Metagame Discussion</a>`,
3057
- `&bullet; <a href="https://www.smogon.com/forums/threads/3503638/">DPP UU Viability Rankings</a>`,
3235
+ `&bullet; <a href="https://www.smogon.com/forums/posts/8286279/">DPP Ubers</a>`,
3058
3236
  ],
3059
3237
  mod: 'gen4',
3060
3238
  searchShow: false,
3061
- ruleset: ['[Gen 4] OU'],
3062
- banlist: ['OU', 'UUBL'],
3063
- unbanlist: ['Arena Trap', 'Swagger'],
3239
+ ruleset: ['Standard'],
3240
+ banlist: ['AG'],
3064
3241
  },
3065
3242
  {
3066
3243
  name: "[Gen 4] NU",
@@ -3193,6 +3370,18 @@ exports.Formats = [
3193
3370
  ruleset: ['Standard', 'Deoxys Camouflage Clause', 'One Baton Pass Clause'],
3194
3371
  banlist: ['Wobbuffet + Leftovers'],
3195
3372
  },
3373
+ {
3374
+ name: "[Gen 3] UU",
3375
+ threads: [
3376
+ `&bullet; <a href="https://www.smogon.com/forums/threads/3585923/">ADV UU Metagame Discussion</a>`,
3377
+ `&bullet; <a href="https://www.smogon.com/forums/threads/3548578/">ADV UU Viability Rankings</a>`,
3378
+ ],
3379
+ mod: 'gen3',
3380
+ searchShow: false,
3381
+ ruleset: ['Standard', 'NFE Clause'],
3382
+ banlist: ['Uber', 'OU', 'UUBL', 'Smeargle + Ingrain', 'Baton Pass'],
3383
+ unbanlist: ['Scyther', 'Sand Veil'],
3384
+ },
3196
3385
  {
3197
3386
  name: "[Gen 3] NU",
3198
3387
  threads: [
@@ -3282,7 +3471,7 @@ exports.Formats = [
3282
3471
  '[Gen 2] OU', 'Accuracy Moves Clause', 'Sleep Moves Clause', 'Team Preview',
3283
3472
  ],
3284
3473
  banlist: [
3285
- 'Clefable', 'Snorlax', 'Zapdos', 'Berserk Gene', 'Bright Powder', 'Focus Band', 'King\'s Rock', 'Quick Claw',
3474
+ 'Alakazam', 'Clefable', 'Snorlax', 'Zapdos', 'Berserk Gene', 'Bright Powder', 'Focus Band', 'King\'s Rock', 'Quick Claw',
3286
3475
  'Attract', 'Destiny Bond', 'Explosion', 'Perish Song', 'Present', 'Self-Destruct', 'Swagger',
3287
3476
  ],
3288
3477
  },
@@ -3338,6 +3527,16 @@ exports.Formats = [
3338
3527
  ruleset: ['[Gen 1] OU'],
3339
3528
  banlist: ['OU', 'UUBL'],
3340
3529
  },
3530
+ {
3531
+ name: "[Gen 1] NU",
3532
+ threads: [
3533
+ `&bullet; <a href="https://www.smogon.com/forums/threads/3668913/">RBY NU Viability Rankings</a>`,
3534
+ ],
3535
+ mod: 'gen1',
3536
+ searchShow: false,
3537
+ ruleset: ['[Gen 1] UU'],
3538
+ banlist: ['UU', 'NUBL'],
3539
+ },
3341
3540
  {
3342
3541
  name: "[Gen 1] Japanese OU",
3343
3542
  desc: `Generation 1 with Japanese battle mechanics.`,