@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.
- package/build/config/formats.js +752 -743
- package/build/config/formats.js.map +1 -1
- package/build/data/aliases.js +4 -4
- package/build/data/aliases.js.map +1 -1
- package/build/data/conditions.js +4 -1
- package/build/data/conditions.js.map +1 -1
- package/build/data/formats-data.js +27 -27
- package/build/data/formats-data.js.map +1 -1
- package/build/data/learnsets.js +10 -10
- package/build/data/learnsets.js.map +1 -1
- package/build/data/mods/gen1/moves.js +1 -1
- package/build/data/mods/gen1/moves.js.map +1 -1
- package/build/data/mods/gen1/scripts.js +18 -22
- package/build/data/mods/gen1/scripts.js.map +1 -1
- package/build/data/mods/gen2/scripts.js +16 -23
- package/build/data/mods/gen2/scripts.js.map +1 -1
- package/build/data/mods/gen3/moves.js +2 -1
- package/build/data/mods/gen3/moves.js.map +1 -1
- package/build/data/mods/gen4/conditions.js +6 -0
- package/build/data/mods/gen4/conditions.js.map +1 -1
- package/build/data/mods/gen4/moves.js +2 -1
- package/build/data/mods/gen4/moves.js.map +1 -1
- package/build/data/mods/gen4/scripts.js +2 -1
- package/build/data/mods/gen4/scripts.js.map +1 -1
- package/build/data/mods/gen6/conditions.js +4 -1
- package/build/data/mods/gen6/conditions.js.map +1 -1
- package/build/data/mods/gen7/formats-data.js +2 -2
- package/build/data/mods/gen7/formats-data.js.map +1 -1
- package/build/data/mods/gen7/moves.js +8 -0
- package/build/data/mods/gen7/moves.js.map +1 -1
- package/build/data/moves.js +26 -14
- package/build/data/moves.js.map +1 -1
- package/build/data/rulesets.js +258 -16
- package/build/data/rulesets.js.map +1 -1
- package/build/data/tags.js +3 -3
- package/build/data/tags.js.map +1 -1
- package/build/lib/streams.d.ts +1 -199
- package/build/lib/streams.js +11 -772
- package/build/lib/streams.js.map +1 -1
- package/build/sim/battle-actions.d.ts +1 -1
- package/build/sim/battle-actions.js +18 -42
- package/build/sim/battle-actions.js.map +1 -1
- package/build/sim/battle.d.ts +1 -0
- package/build/sim/battle.js +5 -0
- package/build/sim/battle.js.map +1 -1
- package/build/sim/dex-moves.d.ts +31 -11
- package/build/sim/dex-moves.js +4 -3
- package/build/sim/dex-moves.js.map +1 -1
- package/build/sim/dex-species.js +11 -1
- package/build/sim/dex-species.js.map +1 -1
- package/build/sim/exported-global-types.d.ts +4 -0
- package/build/sim/global-types.d.ts +4 -0
- package/build/sim/pokemon.js +1 -1
- package/build/sim/pokemon.js.map +1 -1
- package/build/sim/side.js +2 -2
- package/build/sim/side.js.map +1 -1
- package/build/sim/team-validator.d.ts +4 -0
- package/build/sim/team-validator.js +37 -11
- package/build/sim/team-validator.js.map +1 -1
- package/config/formats.ts +649 -630
- package/data/aliases.ts +4 -4
- package/data/conditions.ts +4 -1
- package/data/formats-data.ts +27 -27
- package/data/learnsets.ts +10 -10
- package/data/mods/gen1/moves.ts +1 -1
- package/data/mods/gen1/scripts.ts +23 -19
- package/data/mods/gen2/scripts.ts +20 -19
- package/data/mods/gen3/moves.ts +2 -1
- package/data/mods/gen4/conditions.ts +6 -0
- package/data/mods/gen4/moves.ts +2 -1
- package/data/mods/gen4/scripts.ts +1 -1
- package/data/mods/gen6/conditions.ts +4 -1
- package/data/mods/gen7/formats-data.ts +2 -2
- package/data/mods/gen7/moves.ts +8 -0
- package/data/moves.ts +23 -14
- package/data/rulesets.ts +235 -16
- package/data/tags.ts +3 -3
- package/lib/streams.ts +1 -874
- package/package.json +4 -3
- package/sim/battle-actions.ts +19 -40
- package/sim/battle.ts +6 -0
- package/sim/dex-moves.ts +35 -13
- package/sim/dex-species.ts +10 -1
- package/sim/exported-global-types.ts +4 -0
- package/sim/global-types.ts +4 -0
- package/sim/pokemon.ts +1 -1
- package/sim/side.ts +2 -2
- package/sim/team-validator.ts +41 -10
package/build/data/rulesets.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
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
|
-
|
|
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
|