@pkmn/sim 0.4.19 → 0.4.23

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 +752 -743
  2. package/build/config/formats.js.map +1 -1
  3. package/build/data/aliases.js +4 -4
  4. package/build/data/aliases.js.map +1 -1
  5. package/build/data/conditions.js +4 -1
  6. package/build/data/conditions.js.map +1 -1
  7. package/build/data/formats-data.js +27 -27
  8. package/build/data/formats-data.js.map +1 -1
  9. package/build/data/learnsets.js +10 -10
  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 +26 -14
  32. package/build/data/moves.js.map +1 -1
  33. package/build/data/rulesets.js +258 -16
  34. package/build/data/rulesets.js.map +1 -1
  35. package/build/data/tags.js +3 -3
  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 +4 -0
  52. package/build/sim/global-types.d.ts +4 -0
  53. package/build/sim/pokemon.js +1 -1
  54. package/build/sim/pokemon.js.map +1 -1
  55. package/build/sim/side.js +2 -2
  56. package/build/sim/side.js.map +1 -1
  57. package/build/sim/team-validator.d.ts +4 -0
  58. package/build/sim/team-validator.js +37 -11
  59. package/build/sim/team-validator.js.map +1 -1
  60. package/config/formats.ts +649 -630
  61. package/data/aliases.ts +4 -4
  62. package/data/conditions.ts +4 -1
  63. package/data/formats-data.ts +27 -27
  64. package/data/learnsets.ts +10 -10
  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 +23 -14
  76. package/data/rulesets.ts +235 -16
  77. package/data/tags.ts +3 -3
  78. package/lib/streams.ts +1 -874
  79. package/package.json +4 -3
  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 +4 -0
  85. package/sim/global-types.ts +4 -0
  86. package/sim/pokemon.ts +1 -1
  87. package/sim/side.ts +2 -2
  88. package/sim/team-validator.ts +41 -10
@@ -76,7 +76,7 @@ exports.Rulesets = {
76
76
  name: 'Standard NatDex',
77
77
  desc: "The standard ruleset for all National Dex tiers",
78
78
  ruleset: [
79
- 'Obtainable', '+Unobtainable', '+Past', 'Team Preview', 'Nickname Clause', 'HP Percentage Mod', 'Cancel Mod', 'Endless Battle Clause',
79
+ 'Obtainable', '+Unobtainable', '+Past', 'Sketch Gen 8 Moves', 'Team Preview', 'Nickname Clause', 'HP Percentage Mod', 'Cancel Mod', 'Endless Battle Clause',
80
80
  ],
81
81
  onValidateSet(set) {
82
82
  // These Pokemon are still unobtainable
@@ -285,9 +285,25 @@ exports.Rulesets = {
285
285
  }
286
286
  },
287
287
  },
288
- alolapokedex: {
288
+ oldalolapokedex: {
289
289
  effectType: 'ValidatorRule',
290
- name: 'Alola Pokedex',
290
+ name: 'Old Alola Pokedex',
291
+ desc: "Only allows Pokémon native to the Alola region (SUMO)",
292
+ banlist: ['Pikachu-Partner', 'Marowak-Alola-Totem', 'Ribombee-Totem', 'Araquanid-Totem', 'Lycanroc-Dusk', 'Necrozma-Dusk-Mane', 'Necrozma-Dawn-Wings'],
293
+ onValidateSet(set, format) {
294
+ const alolaDex = [
295
+ "Rowlet", "Dartrix", "Decidueye", "Litten", "Torracat", "Incineroar", "Popplio", "Brionne", "Primarina", "Pikipek", "Trumbeak", "Toucannon", "Yungoos", "Gumshoos", "Rattata-Alola", "Raticate-Alola", "Caterpie", "Metapod", "Butterfree", "Ledyba", "Ledian", "Spinarak", "Ariados", "Pichu", "Pikachu", "Raichu-Alola", "Grubbin", "Charjabug", "Vikavolt", "Bonsly", "Sudowoodo", "Happiny", "Chansey", "Blissey", "Munchlax", "Snorlax", "Slowpoke", "Slowbro", "Slowking", "Wingull", "Pelipper", "Abra", "Kadabra", "Alakazam", "Meowth-Alola", "Persian-Alola", "Magnemite", "Magneton", "Magnezone", "Grimer-Alola", "Muk-Alola", "Growlithe", "Arcanine", "Drowzee", "Hypno", "Makuhita", "Hariyama", "Smeargle", "Crabrawler", "Crabominable", "Gastly", "Haunter", "Gengar", "Drifloon", "Drifblim", "Misdreavus", "Mismagius", "Zubat", "Golbat", "Crobat", "Diglett-Alola", "Dugtrio-Alola", "Spearow", "Fearow", "Rufflet", "Braviary", "Vullaby", "Mandibuzz", "Mankey", "Primeape", "Delibird", "Oricorio", "Cutiefly", "Ribombee", "Petilil", "Lilligant", "Cottonee", "Whimsicott", "Psyduck", "Golduck", "Magikarp", "Gyarados", "Barboach", "Whiscash", "Machop", "Machoke", "Machamp", "Roggenrola", "Boldore", "Gigalith", "Carbink", "Sableye", "Rockruff", "Lycanroc", "Spinda", "Tentacool", "Tentacruel", "Finneon", "Lumineon", "Wishiwashi", "Luvdisc", "Corsola", "Mareanie", "Toxapex", "Shellder", "Cloyster", "Bagon", "Shelgon", "Salamence", "Lillipup", "Herdier", "Stoutland", "Eevee", "Vaporeon", "Jolteon", "Flareon", "Espeon", "Umbreon", "Leafeon", "Glaceon", "Sylveon", "Mudbray", "Mudsdale", "Igglybuff", "Jigglypuff", "Wigglytuff", "Tauros", "Miltank", "Surskit", "Masquerain", "Dewpider", "Araquanid", "Fomantis", "Lurantis", "Morelull", "Shiinotic", "Paras", "Parasect", "Poliwag", "Poliwhirl", "Poliwrath", "Politoed", "Goldeen", "Seaking", "Feebas", "Milotic", "Alomomola", "Fletchling", "Fletchinder", "Talonflame", "Salandit", "Salazzle", "Cubone", "Marowak-Alola", "Kangaskhan", "Magby", "Magmar", "Magmortar", "Stufful", "Bewear", "Bounsweet", "Steenee", "Tsareena", "Comfey", "Pinsir", "Oranguru", "Passimian", "Goomy", "Sliggoo", "Goodra", "Castform", "Wimpod", "Golisopod", "Staryu", "Starmie", "Sandygast", "Palossand", "Cranidos", "Rampardos", "Shieldon", "Bastiodon", "Archen", "Archeops", "Tirtouga", "Carracosta", "Phantump", "Trevenant", "Nosepass", "Probopass", "Pyukumuku", "Chinchou", "Lanturn", "Type: Null", "Silvally", "Zygarde", "Trubbish", "Garbodor", "Skarmory", "Ditto", "Cleffa", "Clefairy", "Clefable", "Minior", "Beldum", "Metang", "Metagross", "Porygon", "Porygon2", "Porygon-Z", "Pancham", "Pangoro", "Komala", "Torkoal", "Turtonator", "Togedemaru", "Elekid", "Electabuzz", "Electivire", "Geodude-Alola", "Graveler-Alola", "Golem-Alola", "Sandile", "Krokorok", "Krookodile", "Trapinch", "Vibrava", "Flygon", "Gible", "Gabite", "Garchomp", "Klefki", "Mimikyu", "Bruxish", "Drampa", "Absol", "Snorunt", "Glalie", "Froslass", "Sneasel", "Weavile", "Sandshrew-Alola", "Sandslash-Alola", "Vulpix-Alola", "Ninetales-Alola", "Vanillite", "Vanillish", "Vanilluxe", "Snubbull", "Granbull", "Shellos", "Gastrodon", "Relicanth", "Dhelmise", "Carvanha", "Sharpedo", "Wailmer", "Wailord", "Lapras", "Exeggcute", "Exeggutor-Alola", "Jangmo-o", "Hakamo-o", "Kommo-o", "Emolga", "Scyther", "Scizor", "Murkrow", "Honchkrow", "Riolu", "Lucario", "Dratini", "Dragonair", "Dragonite", "Aerodactyl", "Tapu Koko", "Tapu Lele", "Tapu Bulu", "Tapu Fini", "Cosmog", "Cosmoem", "Solgaleo", "Lunala", "Nihilego", "Buzzwole", "Pheromosa", "Xurkitree", "Celesteela", "Kartana", "Guzzlord", "Necrozma", "Magearna", "Marshadow",
296
+ ];
297
+ const species = this.dex.species.get(set.species || set.name);
298
+ if (!alolaDex.includes(species.baseSpecies) && !alolaDex.includes(species.name) &&
299
+ !this.ruleTable.has('+' + species.id)) {
300
+ return [`${species.baseSpecies} is not in the Old Alola Pokédex.`];
301
+ }
302
+ },
303
+ },
304
+ newalolapokedex: {
305
+ effectType: 'ValidatorRule',
306
+ name: 'New Alola Pokedex',
291
307
  desc: "Only allows Pokémon native to the Alola region (US/UM)",
292
308
  onValidateSet(set, format) {
293
309
  const alolaDex = [
@@ -296,7 +312,7 @@ exports.Rulesets = {
296
312
  const species = this.dex.species.get(set.species || set.name);
297
313
  if (!alolaDex.includes(species.baseSpecies) && !alolaDex.includes(species.name) &&
298
314
  !this.ruleTable.has('+' + species.id)) {
299
- return [`${species.baseSpecies} is not in the Alola Pokédex.`];
315
+ return [`${species.baseSpecies} is not in the New Alola Pokédex.`];
300
316
  }
301
317
  },
302
318
  },
@@ -556,6 +572,8 @@ exports.Rulesets = {
556
572
  this.add('rule', '2 Ability Clause: Limit two of each ability');
557
573
  },
558
574
  onValidateTeam(team) {
575
+ if (this.format.id === 'gen8multibility')
576
+ return;
559
577
  const abilityTable = new Map();
560
578
  const base = {
561
579
  airlock: 'cloudnine',
@@ -974,16 +992,14 @@ exports.Rulesets = {
974
992
  else {
975
993
  typeTable = typeTable.filter(type => species.types.includes(type));
976
994
  }
977
- if (this.gen >= 7) {
978
- const item = this.dex.items.get(set.item);
979
- if (item.megaStone && species.baseSpecies === item.megaEvolves) {
980
- species = this.dex.species.get(item.megaStone);
981
- typeTable = typeTable.filter(type => species.types.includes(type));
982
- }
983
- if (item.id === "ultranecroziumz" && species.baseSpecies === "Necrozma") {
984
- species = this.dex.species.get("Necrozma-Ultra");
985
- typeTable = typeTable.filter(type => species.types.includes(type));
986
- }
995
+ const item = this.dex.items.get(set.item);
996
+ if (item.megaStone && species.baseSpecies === item.megaEvolves) {
997
+ species = this.dex.species.get(item.megaStone);
998
+ typeTable = typeTable.filter(type => species.types.includes(type));
999
+ }
1000
+ if (item.id === "ultranecroziumz" && species.baseSpecies === "Necrozma") {
1001
+ species = this.dex.species.get("Necrozma-Ultra");
1002
+ typeTable = typeTable.filter(type => species.types.includes(type));
987
1003
  }
988
1004
  if (!typeTable.length)
989
1005
  return [`Your team must share a type.`];
@@ -1088,7 +1104,9 @@ exports.Rulesets = {
1088
1104
  if (!nonstandard && !move.isZ && !move.isMax && !this.ruleTable.isRestricted(`move:${move.id}`)) {
1089
1105
  const speciesTypes = [];
1090
1106
  const moveTypes = [];
1091
- for (let i = this.dex.gen; i >= species.gen && i >= move.gen; i--) {
1107
+ // BDSP can't import Pokemon from Home, so it shouldn't grant moves from archaic species types
1108
+ const minObtainableSpeciesGen = this.dex.currentMod === 'gen8bdsp' ? this.dex.gen : species.gen;
1109
+ for (let i = this.dex.gen; i >= minObtainableSpeciesGen && i >= move.gen; i--) {
1092
1110
  const dex = this.dex.forGen(i);
1093
1111
  moveTypes.push(dex.moves.get(move.name).type);
1094
1112
  const pokemon = dex.species.get(species.name);
@@ -1204,6 +1222,12 @@ exports.Rulesets = {
1204
1222
  }
1205
1223
  },
1206
1224
  },
1225
+ 'sketchgen8moves': {
1226
+ effectType: 'ValidatorRule',
1227
+ name: 'Sketch Gen 8 Moves',
1228
+ desc: "Allows Pokémon who learn Sketch to learn any Gen 8 move (normally, Sketch is not usable in Gen 8).",
1229
+ // Implemented in sim/team-validator.ts
1230
+ },
1207
1231
  mimicglitch: {
1208
1232
  effectType: 'ValidatorRule',
1209
1233
  name: 'Mimic Glitch',
@@ -1389,7 +1413,7 @@ exports.Rulesets = {
1389
1413
  hasValue: 'positive-integer',
1390
1414
  // hardcoded in sim/side
1391
1415
  onValidateRule() {
1392
- if (!this.ruleTable.has('teampreview')) {
1416
+ if (!(this.ruleTable.has('teampreview') || this.ruleTable.has('teamtypepreview'))) {
1393
1417
  throw new Error(`The "Picked Team Size" rule${this.ruleTable.blame('pickedteamsize')} requires Team Preview.`);
1394
1418
  }
1395
1419
  },
@@ -1619,5 +1643,223 @@ exports.Rulesets = {
1619
1643
  this.lose(target.side);
1620
1644
  },
1621
1645
  },
1646
+ tiershiftmod: {
1647
+ effectType: "Rule",
1648
+ name: "Tier Shift Mod",
1649
+ desc: `Poké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.`,
1650
+ ruleset: ['Overflow Stat Mod'],
1651
+ onBegin() {
1652
+ this.add('rule', 'Tier Shift Mod: Pok\u00e9mon get stat buffs depending on their tier, excluding HP.');
1653
+ },
1654
+ onModifySpecies(species, target, source, effect) {
1655
+ if (!species.baseStats)
1656
+ return;
1657
+ const boosts = {
1658
+ uu: 10,
1659
+ rubl: 10,
1660
+ ru: 20,
1661
+ nubl: 20,
1662
+ nu: 30,
1663
+ publ: 30,
1664
+ pu: 40,
1665
+ nfe: 40,
1666
+ lc: 40,
1667
+ };
1668
+ let tier = this.toID(species.tier);
1669
+ if (!(tier in boosts))
1670
+ return;
1671
+ // Non-Pokemon bans in lower tiers
1672
+ if (target) {
1673
+ if (target.set.item === 'lightclay')
1674
+ return;
1675
+ if (['drizzle', 'drought', 'snowwarning'].includes(target.set.ability) && boosts[tier] > 20)
1676
+ tier = 'nubl';
1677
+ }
1678
+ const pokemon = this.dex.deepClone(species);
1679
+ pokemon.bst = pokemon.baseStats['hp'];
1680
+ const boost = boosts[tier];
1681
+ let statName;
1682
+ for (statName in pokemon.baseStats) {
1683
+ if (statName === 'hp')
1684
+ continue;
1685
+ pokemon.baseStats[statName] = this.clampIntRange(pokemon.baseStats[statName] + boost, 1, 255);
1686
+ pokemon.bst += pokemon.baseStats[statName];
1687
+ }
1688
+ return pokemon;
1689
+ },
1690
+ },
1691
+ crossevolutionmod: {
1692
+ effectType: "Rule",
1693
+ name: "Cross Evolution Mod",
1694
+ desc: "Give a Pokémon a Poké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émon.",
1695
+ ruleset: ['Overflow Stat Mod'],
1696
+ onValidateTeam(team) {
1697
+ const names = new Set();
1698
+ for (const set of team) {
1699
+ const name = set.name;
1700
+ if (names.has(this.dex.toID(name))) {
1701
+ return [
1702
+ `Your Pok\u00e9mon must have different nicknames.`,
1703
+ `(You have more than one Pok\u00e9mon named '${name}')`,
1704
+ ];
1705
+ }
1706
+ names.add(this.dex.toID(name));
1707
+ }
1708
+ if (!names.size) {
1709
+ return [
1710
+ `${this.format.name} works using nicknames; your team has 0 nicknamed Pok\u00e9mon.`,
1711
+ `(If this was intentional, add a nickname to one Pok\u00e9mon that isn't the name of a Pok\u00e9mon species.)`,
1712
+ ];
1713
+ }
1714
+ },
1715
+ checkCanLearn(move, species, lsetData, set) {
1716
+ // @ts-ignore
1717
+ if (!set.sp?.exists || !set.crossSpecies?.exists) {
1718
+ return this.checkCanLearn(move, species, lsetData, set);
1719
+ }
1720
+ // @ts-ignore
1721
+ const problem = this.checkCanLearn(move, set.sp);
1722
+ if (!problem)
1723
+ return null;
1724
+ // @ts-ignore
1725
+ if (!set.crossMovesLeft)
1726
+ return problem;
1727
+ // @ts-ignore
1728
+ if (this.checkCanLearn(move, set.crossSpecies))
1729
+ return problem;
1730
+ // @ts-ignore
1731
+ set.crossMovesLeft--;
1732
+ return null;
1733
+ },
1734
+ validateSet(set, teamHas) {
1735
+ const crossSpecies = this.dex.species.get(set.name);
1736
+ const onChangeSet = this.dex.formats.get('Pokemon').onChangeSet;
1737
+ let problems = onChangeSet?.call(this, set, this.format) || null;
1738
+ if (Array.isArray(problems) && problems.length)
1739
+ return problems;
1740
+ const crossNonstandard = !this.ruleTable.has('standardnatdex') && crossSpecies.isNonstandard === 'Past';
1741
+ const crossIsCap = !this.ruleTable.has('+pokemontag:cap') && crossSpecies.isNonstandard === 'CAP';
1742
+ if (!crossSpecies.exists || crossNonstandard || crossIsCap)
1743
+ return this.validateSet(set, teamHas);
1744
+ const species = this.dex.species.get(set.species);
1745
+ const check = this.checkSpecies(set, species, species, {});
1746
+ if (check)
1747
+ return [check];
1748
+ const nonstandard = !this.ruleTable.has('standardnatdex') && species.isNonstandard === 'Past';
1749
+ const isCap = !this.ruleTable.has('+pokemontag:cap') && species.isNonstandard === 'CAP';
1750
+ if (!species.exists || nonstandard || isCap || species === crossSpecies)
1751
+ return this.validateSet(set, teamHas);
1752
+ if (!species.nfe)
1753
+ return [`${species.name} cannot cross evolve because it doesn't evolve.`];
1754
+ const crossIsUnreleased = (crossSpecies.tier === "Unreleased" && crossSpecies.isNonstandard === "Unobtainable");
1755
+ if (crossSpecies.battleOnly || crossIsUnreleased || !crossSpecies.prevo) {
1756
+ return [`${species.name} cannot cross evolve into ${crossSpecies.name} because it isn't an evolution.`];
1757
+ }
1758
+ if (this.ruleTable.isRestrictedSpecies(crossSpecies)) {
1759
+ return [`${species.name} cannot cross evolve into ${crossSpecies.name} because it is banned.`];
1760
+ }
1761
+ const crossPrevoSpecies = this.dex.species.get(crossSpecies.prevo);
1762
+ if (!crossPrevoSpecies.prevo !== !species.prevo) {
1763
+ return [
1764
+ `${species.name} cannot cross evolve into ${crossSpecies.name} because they are not consecutive evolution stages.`,
1765
+ ];
1766
+ }
1767
+ const ability = this.dex.abilities.get(set.ability);
1768
+ if (!this.ruleTable.isRestricted(`ability:${ability.id}`) || Object.values(species.abilities).includes(ability.name)) {
1769
+ set.species = crossSpecies.name;
1770
+ }
1771
+ // @ts-ignore
1772
+ set.sp = species;
1773
+ // @ts-ignore
1774
+ set.crossSpecies = crossSpecies;
1775
+ // @ts-ignore
1776
+ set.crossMovesLeft = 2;
1777
+ problems = this.validateSet(set, teamHas);
1778
+ set.name = crossSpecies.name;
1779
+ set.species = species.name;
1780
+ return problems;
1781
+ },
1782
+ onModifySpecies(species, target, source, effect) {
1783
+ if (!target)
1784
+ return; // chat
1785
+ if (effect && ['imposter', 'transform'].includes(effect.id))
1786
+ return;
1787
+ if (target.set.name === target.set.species)
1788
+ return;
1789
+ const crossSpecies = this.dex.species.get(target.set.name);
1790
+ if (!crossSpecies.exists)
1791
+ return;
1792
+ if (species.battleOnly || !species.nfe)
1793
+ return;
1794
+ const crossIsUnreleased = (crossSpecies.tier === "Unreleased" && crossSpecies.isNonstandard === "Unobtainable");
1795
+ if (crossSpecies.battleOnly || crossIsUnreleased || !crossSpecies.prevo)
1796
+ return;
1797
+ const crossPrevoSpecies = this.dex.species.get(crossSpecies.prevo);
1798
+ if (!crossPrevoSpecies.prevo !== !species.prevo)
1799
+ return;
1800
+ const mixedSpecies = this.dex.deepClone(species);
1801
+ mixedSpecies.baseSpecies = mixedSpecies.name = `${species.name}-${crossSpecies.name}`;
1802
+ mixedSpecies.weightkg =
1803
+ Math.max(0.1, +(species.weightkg + crossSpecies.weightkg - crossPrevoSpecies.weightkg)).toFixed(1);
1804
+ mixedSpecies.nfe = false;
1805
+ mixedSpecies.evos = [];
1806
+ mixedSpecies.eggGroups = crossSpecies.eggGroups;
1807
+ mixedSpecies.abilities = crossSpecies.abilities;
1808
+ mixedSpecies.bst = 0;
1809
+ let i;
1810
+ for (i in species.baseStats) {
1811
+ const statChange = crossSpecies.baseStats[i] - crossPrevoSpecies.baseStats[i];
1812
+ mixedSpecies.baseStats[i] = this.clampIntRange(species.baseStats[i] + statChange, 1, 255);
1813
+ mixedSpecies.bst += mixedSpecies.baseStats[i];
1814
+ }
1815
+ if (crossSpecies.types[0] !== crossPrevoSpecies.types[0])
1816
+ mixedSpecies.types[0] = crossSpecies.types[0];
1817
+ if (crossSpecies.types[1] !== crossPrevoSpecies.types[1]) {
1818
+ mixedSpecies.types[1] = crossSpecies.types[1] || crossSpecies.types[0];
1819
+ }
1820
+ if (mixedSpecies.types[0] === mixedSpecies.types[1])
1821
+ mixedSpecies.types = [mixedSpecies.types[0]];
1822
+ return mixedSpecies;
1823
+ },
1824
+ onBegin() {
1825
+ for (const pokemon of this.getAllPokemon()) {
1826
+ pokemon.baseSpecies = pokemon.species;
1827
+ }
1828
+ },
1829
+ },
1830
+ revelationmonsmod: {
1831
+ effectType: "Rule",
1832
+ name: "Revelationmons Mod",
1833
+ desc: `The moves in the first slot(s) of a Pokémon's set have their types changed to match the Pokémon's type(s).`,
1834
+ onBegin() {
1835
+ this.add('rule', 'Revelationmons Mod: The first moveslots have their types changed to match the Pokémon\'s types');
1836
+ },
1837
+ onValidateSet(set) {
1838
+ const species = this.dex.species.get(set.species);
1839
+ const slotIndex = species.types.length - 1;
1840
+ const problems = [];
1841
+ for (const [i, moveid] of set.moves.entries()) {
1842
+ const move = this.dex.moves.get(moveid);
1843
+ if (!this.ruleTable.isRestricted(`move:${move.id}`))
1844
+ continue;
1845
+ if (i <= slotIndex) {
1846
+ problems.push(`${move.name} can't be in moveslot ${i + 1} because it's restricted from being in the first ${slotIndex + 1 > 1 ? `${slotIndex + 1} slots` : 'slot'}.`);
1847
+ }
1848
+ }
1849
+ return problems;
1850
+ },
1851
+ onModifyMove(move, pokemon, target) {
1852
+ const types = pokemon.getTypes(true);
1853
+ const noModifyType = [
1854
+ 'judgment', 'multiattack', 'naturalgift', 'revelationdance', 'technoblast', 'terrainpulse', 'weatherball',
1855
+ ];
1856
+ if (noModifyType.includes(move.id))
1857
+ return;
1858
+ for (const [i, type] of types.entries()) {
1859
+ if (pokemon.moveSlots[i] && move.id === pokemon.moveSlots[i].id)
1860
+ move.type = type;
1861
+ }
1862
+ },
1863
+ },
1622
1864
  };
1623
1865
  //# sourceMappingURL=rulesets.js.map