@pkmn/sim 0.6.2 → 0.6.4

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 (39) hide show
  1. package/build/config/formats.js +98 -76
  2. package/build/config/formats.js.map +1 -1
  3. package/build/data/abilities.js +1 -1
  4. package/build/data/abilities.js.map +1 -1
  5. package/build/data/formats-data.js +3 -3
  6. package/build/data/formats-data.js.map +1 -1
  7. package/build/data/mods/gen1/moves.js +3 -2
  8. package/build/data/mods/gen1/moves.js.map +1 -1
  9. package/build/data/mods/gen1/scripts.js +75 -40
  10. package/build/data/mods/gen1/scripts.js.map +1 -1
  11. package/build/data/mods/gen2/scripts.js +1 -1
  12. package/build/data/moves.js +8 -6
  13. package/build/data/moves.js.map +1 -1
  14. package/build/data/pokedex.js +5 -0
  15. package/build/data/pokedex.js.map +1 -1
  16. package/build/data/rulesets.js +58 -0
  17. package/build/data/rulesets.js.map +1 -1
  18. package/build/sim/battle-queue.js +4 -3
  19. package/build/sim/battle-queue.js.map +1 -1
  20. package/build/sim/battle.js +8 -4
  21. package/build/sim/battle.js.map +1 -1
  22. package/build/sim/dex-species.d.ts +2 -0
  23. package/build/sim/dex-species.js.map +1 -1
  24. package/build/sim/team-validator.js +4 -0
  25. package/build/sim/team-validator.js.map +1 -1
  26. package/config/formats.ts +101 -73
  27. package/data/abilities.ts +1 -1
  28. package/data/formats-data.ts +3 -3
  29. package/data/mods/gen1/moves.ts +3 -2
  30. package/data/mods/gen1/scripts.ts +73 -39
  31. package/data/mods/gen2/scripts.ts +1 -1
  32. package/data/moves.ts +8 -6
  33. package/data/pokedex.ts +5 -0
  34. package/data/rulesets.ts +59 -0
  35. package/package.json +1 -1
  36. package/sim/battle-queue.ts +4 -3
  37. package/sim/battle.ts +6 -4
  38. package/sim/dex-species.ts +2 -0
  39. package/sim/team-validator.ts +5 -0
@@ -151,7 +151,7 @@ exports.Formats = [
151
151
  mod: 'gen8',
152
152
  ruleset: ['Little Cup', 'Standard', 'Dynamax Clause'],
153
153
  banlist: [
154
- 'Corsola-Galar', 'Cutiefly', 'Drifloon', 'Gastly', 'Gothita', 'Rufflet', 'Scraggy', 'Scyther', 'Sneasel', 'Swirlix',
154
+ 'Corsola-Galar', 'Cutiefly', 'Drifloon', 'Gastly', 'Gothita', 'Magby', 'Rufflet', 'Scraggy', 'Scyther', 'Sneasel', 'Swirlix',
155
155
  'Tangela', 'Vullaby', 'Vulpix-Alola', 'Woobat', 'Zigzagoon-Base', 'Chlorophyll', 'Moody', 'Baton Pass', 'Sticky Web',
156
156
  ],
157
157
  },
@@ -231,8 +231,8 @@ exports.Formats = [
231
231
  banlist: [
232
232
  // LC OU
233
233
  'Abra', 'Carvanha', 'Diglett-Base', 'Dwebble', 'Ferroseed', 'Foongus', 'Frillish', 'Grookey', 'Koffing',
234
- 'Larvesta', 'Magby', 'Magnemite', 'Mareanie', 'Mienfoo', 'Mudbray', 'Natu', 'Onix', 'Pawniard',
235
- 'Ponyta-Base', 'Porygon', 'Staryu', 'Timburr', 'Trapinch', 'Tyrunt',
234
+ 'Larvesta', 'Magnemite', 'Mareanie', 'Mienfoo', 'Mudbray', 'Natu', 'Onix', 'Pawniard', 'Ponyta-Base',
235
+ 'Porygon', 'Staryu', 'Timburr', 'Trapinch', 'Tyrunt',
236
236
  // LC UUBL
237
237
  'Archen', 'Farfetch\u2019d-Galar', 'Scorbunny', 'Shellder', 'Wingull',
238
238
  ],
@@ -475,6 +475,7 @@ exports.Formats = [
475
475
  mod: 'gen8',
476
476
  ruleset: ['[Gen 8] National Dex'],
477
477
  banlist: ['ND OU', 'ND UUBL', 'Drizzle', 'Drought', 'Light Clay', 'Slowbronite'],
478
+ unbanlist: ['Hydreigon'],
478
479
  },
479
480
  {
480
481
  name: "[Gen 8] National Dex RU",
@@ -484,7 +485,7 @@ exports.Formats = [
484
485
  mod: 'gen8',
485
486
  searchShow: false,
486
487
  ruleset: ['[Gen 8] National Dex UU'],
487
- banlist: ['ND UU', 'ND RUBL'],
488
+ banlist: ['ND UU', 'ND RUBL', 'Hydreigon'],
488
489
  },
489
490
  {
490
491
  name: "[Gen 8] National Dex Monotype",
@@ -637,7 +638,7 @@ exports.Formats = [
637
638
  'Yveltal', 'Zacian', 'Zacian-Crowned', 'Zamazenta-Base', 'Zekrom', 'Zeraora', 'Zygarde-Base', 'Arena Trap', 'Comatose', 'Contrary', 'Fluffy',
638
639
  'Fur Coat', 'Gorilla Tactics', 'Huge Power', 'Ice Scales', 'Illusion', 'Imposter', 'Innards Out', 'Intrepid Sword', 'Libero', 'Magic Bounce',
639
640
  'Magnet Pull', 'Moody', 'Neutralizing Gas', 'Parental Bond', 'Poison Heal', 'Protean', 'Pure Power', 'Shadow Tag', 'Simple', 'Stakeout',
640
- 'Speed Boost', 'Unburden', 'Water Bubble', 'Wonder Guard', 'King\'s Rock', 'Baton Pass',
641
+ 'Speed Boost', 'Unburden', 'Water Bubble', 'Wonder Guard', 'King\'s Rock', 'Baton Pass', 'Electrify',
641
642
  ],
642
643
  },
643
644
  {
@@ -754,70 +755,12 @@ exports.Formats = [
754
755
  `&bullet; <a href="https://www.smogon.com/forums/threads/3660461/">Godly Gift</a>`,
755
756
  ],
756
757
  mod: 'gen8',
757
- ruleset: ['Standard OMs', 'Sleep Moves Clause'],
758
+ ruleset: ['Standard OMs', 'Sleep Moves Clause', 'Godly Gift Mod'],
758
759
  banlist: [
759
760
  'Blissey', 'Calyrex-Shadow', 'Chansey', 'Crawdaunt', 'Dragapult', 'Eternatus', 'Hawlucha', 'Kyogre', 'Marowak-Alola', 'Melmetal',
760
- 'Nidoking', 'Nidoqueen', 'Pikachu', 'Toxapex', 'Xerneas', 'Zacian', 'Zacian-Crowned', 'Uber > 1', 'AG ++ Uber > 1', 'Arena Trap',
761
- 'Huge Power', 'Moody', 'Pure Power', 'Shadow Tag', 'Swift Swim', 'Bright Powder', 'Focus Band', 'King\'s Rock', 'Lax Incense',
762
- 'Quick Claw', 'Baton Pass',
761
+ 'Nidoking', 'Nidoqueen', 'Pikachu', 'Toxapex', 'Xerneas', 'Zacian', 'Zacian-Crowned', 'Arena Trap', 'Huge Power', 'Moody',
762
+ 'Pure Power', 'Shadow Tag', 'Swift Swim', 'Bright Powder', 'Focus Band', 'King\'s Rock', 'Lax Incense', 'Quick Claw', 'Baton Pass',
763
763
  ],
764
- onValidateTeam(team) {
765
- const gods = new Set();
766
- for (const set of team) {
767
- let species = this.dex.species.get(set.species);
768
- if (typeof species.battleOnly === 'string')
769
- species = this.dex.species.get(species.battleOnly);
770
- if (set.item && this.dex.items.get(set.item).megaStone) {
771
- const item = this.dex.items.get(set.item);
772
- if (item.megaEvolves === species.baseSpecies) {
773
- species = this.dex.species.get(item.megaStone);
774
- }
775
- }
776
- if (this.ruleTable.has('standardnatdex')) {
777
- const format = this.dex.formats.getRuleTable(this.dex.formats.get('gen8nationaldex'));
778
- if (format.isBannedSpecies(species))
779
- gods.add(species.name);
780
- }
781
- else {
782
- if (['ag', 'uber'].includes(this.toID(species.tier)) || this.toID(set.ability) === 'powerconstruct') {
783
- gods.add(species.name);
784
- }
785
- }
786
- }
787
- if (gods.size > 1) {
788
- return [`You have too many Gods.`, `(${Array.from(gods).join(', ')} are Gods.)`];
789
- }
790
- },
791
- onModifySpeciesPriority: 3,
792
- onModifySpecies(species, target, source) {
793
- if (source || !target?.side)
794
- return;
795
- const god = target.side.team.find(set => {
796
- let godSpecies = this.dex.species.get(set.species);
797
- const isNatDex = this.format.ruleTable?.has('standardnatdex');
798
- const validator = this.dex.formats.getRuleTable(this.dex.formats.get(`gen${isNatDex && this.gen < 8 ? 8 : this.gen}${isNatDex ? 'nationaldex' : 'ou'}`));
799
- if (this.toID(set.ability) === 'powerconstruct') {
800
- return true;
801
- }
802
- if (set.item) {
803
- const item = this.dex.items.get(set.item);
804
- if (item.megaEvolves === set.species)
805
- godSpecies = this.dex.species.get(item.megaStone);
806
- }
807
- const isBanned = validator.isBannedSpecies(godSpecies);
808
- return isBanned;
809
- }) || target.side.team[0];
810
- const stat = Dex.stats.ids()[target.side.team.indexOf(target.set)];
811
- const newSpecies = this.dex.deepClone(species);
812
- let godSpecies = this.dex.species.get(god.species);
813
- if (typeof godSpecies.battleOnly === 'string') {
814
- godSpecies = this.dex.species.get(godSpecies.battleOnly);
815
- }
816
- newSpecies.bst -= newSpecies.baseStats[stat];
817
- newSpecies.baseStats[stat] = godSpecies.baseStats[stat];
818
- newSpecies.bst += newSpecies.baseStats[stat];
819
- return newSpecies;
820
- },
821
764
  },
822
765
  {
823
766
  name: "[Gen 8] Free-For-All",
@@ -1630,9 +1573,9 @@ exports.Formats = [
1630
1573
  'Calyrex-Ice', 'Calyrex-Shadow', 'Dialga', 'Eternatus', 'Giratina', 'Giratina-Origin', 'Groudon', 'Ho-Oh',
1631
1574
  'Jirachi', 'Kyogre', 'Kyurem-White', 'Lugia', 'Lunala', 'Magearna', 'Marshadow', 'Melmetal', 'Mewtwo',
1632
1575
  'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane', 'Palkia', 'Rayquaza', 'Reshiram', 'Solgaleo', 'Urshifu-Base',
1633
- 'Xerneas', 'Yveltal', 'Zacian', 'Zacian-Crowned', 'Zamazenta', 'Zamazenta-Crowned', 'Zekrom', 'Emergency Exit',
1634
- 'Huge Power', 'Moody', 'Power Construct', 'Shadow Tag', 'Wimp Out', 'Wonder Guard', 'Bolt Beak', 'Fishious Rend',
1635
- 'Shell Smash', 'Swagger',
1576
+ 'Xerneas', 'Yveltal', 'Zacian', 'Zacian-Crowned', 'Zamazenta', 'Zamazenta-Crowned', 'Zekrom', 'Contrary',
1577
+ 'Emergency Exit', 'Huge Power', 'Moody', 'Power Construct', 'Serene Grace', 'Shadow Tag', 'Wimp Out',
1578
+ 'Wonder Guard', 'Ally Switch', 'Bolt Beak', 'Fishious Rend', 'Shell Smash', 'Swagger',
1636
1579
  ],
1637
1580
  onBeforeSwitchIn(pokemon) {
1638
1581
  pokemon.m.curMoves = this.dex.deepClone(pokemon.moves);
@@ -2128,11 +2071,90 @@ exports.Formats = [
2128
2071
  column: 2,
2129
2072
  },
2130
2073
  {
2131
- name: "[Gen 7] Pick-Your-Team Random Battle",
2132
- mod: 'gen7',
2074
+ name: "[Gen 4] Shared Power Random Battle",
2075
+ desc: `[Gen 4] Random Battle with aspects of [Gen 8] Shared Power`,
2076
+ mod: 'gen4',
2133
2077
  team: 'random',
2134
- ruleset: ['[Gen 7] Random Battle', 'Max Team Size = 12', 'Picked Team Size = 6', 'Team Preview'],
2135
- desc: `Twelve Pokémon sets are randomly chosen, then you pick six for your team!`,
2078
+ ruleset: ['[Gen 4] Random Battle', 'Team Preview'],
2079
+ getSharedPower(pokemon) {
2080
+ const sharedPower = new Set();
2081
+ for (const ally of pokemon.side.pokemon) {
2082
+ if (ally.previouslySwitchedIn > 0) {
2083
+ if (pokemon.battle.dex.currentMod !== 'sharedpower' && ['trace', 'mirrorarmor'].includes(ally.baseAbility)) {
2084
+ sharedPower.add('noability');
2085
+ continue;
2086
+ }
2087
+ sharedPower.add(ally.baseAbility);
2088
+ }
2089
+ }
2090
+ sharedPower.delete(pokemon.baseAbility);
2091
+ return sharedPower;
2092
+ },
2093
+ onBeforeSwitchIn(pokemon) {
2094
+ let format = this.format;
2095
+ if (!format.getSharedPower)
2096
+ format = this.dex.formats.get('gen8sharedpower');
2097
+ for (const ability of format.getSharedPower(pokemon)) {
2098
+ const effect = 'ability:' + ability;
2099
+ pokemon.volatiles[effect] = { id: this.toID(effect), target: pokemon };
2100
+ if (!pokemon.m.abils)
2101
+ pokemon.m.abils = [];
2102
+ if (!pokemon.m.abils.includes(effect))
2103
+ pokemon.m.abils.push(effect);
2104
+ }
2105
+ },
2106
+ onSwitchInPriority: 2,
2107
+ onSwitchIn(pokemon) {
2108
+ let format = this.format;
2109
+ if (!format.getSharedPower)
2110
+ format = this.dex.formats.get('gen8sharedpower');
2111
+ for (const ability of format.getSharedPower(pokemon)) {
2112
+ if (ability === 'noability') {
2113
+ 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.`);
2114
+ }
2115
+ const effect = 'ability:' + ability;
2116
+ delete pokemon.volatiles[effect];
2117
+ pokemon.addVolatile(effect);
2118
+ }
2119
+ },
2120
+ field: {
2121
+ suppressingWeather() {
2122
+ for (const pokemon of this.battle.getAllActive()) {
2123
+ const innates = Object.keys(pokemon.volatiles).filter(x => x.startsWith('ability:'));
2124
+ if (pokemon && !pokemon.ignoringAbility() &&
2125
+ (pokemon.getAbility().suppressWeather || innates.some(x => (this.battle.dex.abilities.get(x.replace('ability:', '')).suppressWeather)))) {
2126
+ return true;
2127
+ }
2128
+ }
2129
+ return false;
2130
+ },
2131
+ },
2132
+ pokemon: {
2133
+ hasAbility(ability) {
2134
+ if (this.ignoringAbility())
2135
+ return false;
2136
+ if (Array.isArray(ability))
2137
+ return ability.some(abil => this.hasAbility(abil));
2138
+ const abilityid = this.battle.toID(ability);
2139
+ return this.ability === abilityid || !!this.volatiles['ability:' + abilityid];
2140
+ },
2141
+ ignoringAbility() {
2142
+ // Check if any active pokemon have the ability Neutralizing Gas
2143
+ let neutralizinggas = false;
2144
+ for (const pokemon of this.battle.getAllActive()) {
2145
+ // can't use hasAbility because it would lead to infinite recursion
2146
+ if ((pokemon.ability === 'neutralizinggas' || pokemon.m.abils?.includes('ability:neutralizinggas')) &&
2147
+ !pokemon.volatiles['gastroacid'] && !pokemon.abilityState.ending) {
2148
+ neutralizinggas = true;
2149
+ break;
2150
+ }
2151
+ }
2152
+ return !!((this.battle.gen >= 5 && !this.isActive) ||
2153
+ ((this.volatiles['gastroacid'] ||
2154
+ (neutralizinggas && (this.ability !== 'neutralizinggas' ||
2155
+ this.m.abils?.includes('ability:neutralizinggas')))) && !this.getAbility().isPermanent));
2156
+ },
2157
+ },
2136
2158
  },
2137
2159
  // Randomized Metas
2138
2160
  ///////////////////////////////////////////////////////////////////
@@ -2477,9 +2499,9 @@ exports.Formats = [
2477
2499
  mod: 'gen3',
2478
2500
  // searchShow: false,
2479
2501
  gameType: 'doubles',
2480
- ruleset: ['Standard', '!Sleep Clause Mod', '!Switch Priority Clause Mod'],
2481
- banlist: ['Uber'],
2482
- unbanlist: ['Deoxys-Speed', 'Wobbuffet', 'Wynaut'],
2502
+ ruleset: ['Standard', '!Switch Priority Clause Mod'],
2503
+ banlist: ['Uber', 'Soul Dew', 'Swagger'],
2504
+ unbanlist: ['Deoxys-Defense', 'Latias', 'Wobbuffet', 'Wynaut'],
2483
2505
  },
2484
2506
  {
2485
2507
  name: "[Gen 3] UU",