@pkmn/sim 0.4.20 → 0.4.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/config/formats.js +415 -688
- package/build/config/formats.js.map +1 -1
- package/build/data/aliases.js +7 -5
- 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 +18 -18
- package/build/data/formats-data.js.map +1 -1
- package/build/data/learnsets.js +10 -8
- 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 +25 -13
- package/build/data/moves.js.map +1 -1
- package/build/data/rulesets.js +221 -1
- package/build/data/rulesets.js.map +1 -1
- package/build/data/tags.js +2 -2
- 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 +1 -0
- package/build/sim/global-types.d.ts +1 -0
- package/build/sim/side.js +2 -2
- package/build/sim/side.js.map +1 -1
- package/build/sim/team-validator.js +2 -2
- package/build/sim/team-validator.js.map +1 -1
- package/build/sim/tools/runner.d.ts +1 -6
- package/build/sim/tools/runner.js +6 -6
- package/build/sim/tools/runner.js.map +1 -1
- package/config/formats.ts +393 -643
- package/data/aliases.ts +7 -5
- package/data/conditions.ts +4 -1
- package/data/formats-data.ts +18 -18
- package/data/learnsets.ts +10 -8
- 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 +22 -13
- package/data/rulesets.ts +199 -1
- package/data/tags.ts +2 -2
- package/lib/streams.ts +1 -874
- package/package.json +3 -2
- 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 +1 -0
- package/sim/global-types.ts +1 -0
- package/sim/side.ts +2 -2
- package/sim/team-validator.ts +2 -2
- package/sim/tools/runner.ts +2 -0
package/data/moves.ts
CHANGED
|
@@ -1399,7 +1399,7 @@ export const Moves: {[moveid: string]: MoveData} = {
|
|
|
1399
1399
|
pp: 10,
|
|
1400
1400
|
priority: 0,
|
|
1401
1401
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
1402
|
-
|
|
1402
|
+
overrideOffensiveStat: 'def',
|
|
1403
1403
|
secondary: null,
|
|
1404
1404
|
target: "normal",
|
|
1405
1405
|
type: "Fighting",
|
|
@@ -2282,7 +2282,7 @@ export const Moves: {[moveid: string]: MoveData} = {
|
|
|
2282
2282
|
name: "Coaching",
|
|
2283
2283
|
pp: 10,
|
|
2284
2284
|
priority: 0,
|
|
2285
|
-
flags: {bypasssub: 1},
|
|
2285
|
+
flags: {bypasssub: 1, allyanim: 1},
|
|
2286
2286
|
secondary: null,
|
|
2287
2287
|
boosts: {
|
|
2288
2288
|
atk: 1,
|
|
@@ -3387,7 +3387,7 @@ export const Moves: {[moveid: string]: MoveData} = {
|
|
|
3387
3387
|
name: "Dive",
|
|
3388
3388
|
pp: 10,
|
|
3389
3389
|
priority: 0,
|
|
3390
|
-
flags: {contact: 1, charge: 1, protect: 1, mirror: 1, nonsky: 1},
|
|
3390
|
+
flags: {contact: 1, charge: 1, protect: 1, mirror: 1, nonsky: 1, allyanim: 1},
|
|
3391
3391
|
onTryMove(attacker, defender, move) {
|
|
3392
3392
|
if (attacker.removeVolatile(move.id)) {
|
|
3393
3393
|
return;
|
|
@@ -5621,7 +5621,7 @@ export const Moves: {[moveid: string]: MoveData} = {
|
|
|
5621
5621
|
pp: 15,
|
|
5622
5622
|
priority: 0,
|
|
5623
5623
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
5624
|
-
|
|
5624
|
+
overrideOffensivePokemon: 'target',
|
|
5625
5625
|
secondary: null,
|
|
5626
5626
|
target: "normal",
|
|
5627
5627
|
type: "Dark",
|
|
@@ -6509,9 +6509,9 @@ export const Moves: {[moveid: string]: MoveData} = {
|
|
|
6509
6509
|
flags: {},
|
|
6510
6510
|
isMax: "Melmetal",
|
|
6511
6511
|
self: {
|
|
6512
|
-
onHit(source) {
|
|
6512
|
+
onHit(source, target, effect) {
|
|
6513
6513
|
for (const pokemon of source.foes()) {
|
|
6514
|
-
if (!pokemon.volatiles['dynamax']) pokemon.addVolatile('torment');
|
|
6514
|
+
if (!pokemon.volatiles['dynamax']) pokemon.addVolatile('torment', source, effect);
|
|
6515
6515
|
}
|
|
6516
6516
|
},
|
|
6517
6517
|
},
|
|
@@ -7148,7 +7148,7 @@ export const Moves: {[moveid: string]: MoveData} = {
|
|
|
7148
7148
|
name: "Grassy Glide",
|
|
7149
7149
|
pp: 20,
|
|
7150
7150
|
priority: 0,
|
|
7151
|
-
flags: {contact: 1, protect: 1
|
|
7151
|
+
flags: {contact: 1, protect: 1},
|
|
7152
7152
|
onModifyPriority(priority, source, target, move) {
|
|
7153
7153
|
if (this.field.isTerrain('grassyterrain') && source.isGrounded()) {
|
|
7154
7154
|
return priority + 1;
|
|
@@ -12727,7 +12727,7 @@ export const Moves: {[moveid: string]: MoveData} = {
|
|
|
12727
12727
|
name: "Pollen Puff",
|
|
12728
12728
|
pp: 15,
|
|
12729
12729
|
priority: 0,
|
|
12730
|
-
flags: {bullet: 1, protect: 1, mirror: 1},
|
|
12730
|
+
flags: {bullet: 1, protect: 1, mirror: 1, allyanim: 1},
|
|
12731
12731
|
onTryHit(target, source, move) {
|
|
12732
12732
|
if (source.isAlly(target)) {
|
|
12733
12733
|
move.basePower = 0;
|
|
@@ -13309,7 +13309,7 @@ export const Moves: {[moveid: string]: MoveData} = {
|
|
|
13309
13309
|
accuracy: 100,
|
|
13310
13310
|
basePower: 80,
|
|
13311
13311
|
category: "Special",
|
|
13312
|
-
|
|
13312
|
+
overrideDefensiveStat: 'def',
|
|
13313
13313
|
name: "Psyshock",
|
|
13314
13314
|
pp: 10,
|
|
13315
13315
|
priority: 0,
|
|
@@ -13324,7 +13324,7 @@ export const Moves: {[moveid: string]: MoveData} = {
|
|
|
13324
13324
|
accuracy: 100,
|
|
13325
13325
|
basePower: 100,
|
|
13326
13326
|
category: "Special",
|
|
13327
|
-
|
|
13327
|
+
overrideDefensiveStat: 'def',
|
|
13328
13328
|
name: "Psystrike",
|
|
13329
13329
|
pp: 10,
|
|
13330
13330
|
priority: 0,
|
|
@@ -14852,7 +14852,7 @@ export const Moves: {[moveid: string]: MoveData} = {
|
|
|
14852
14852
|
accuracy: 100,
|
|
14853
14853
|
basePower: 85,
|
|
14854
14854
|
category: "Special",
|
|
14855
|
-
|
|
14855
|
+
overrideDefensiveStat: 'def',
|
|
14856
14856
|
name: "Secret Sword",
|
|
14857
14857
|
pp: 10,
|
|
14858
14858
|
priority: 0,
|
|
@@ -18312,11 +18312,12 @@ export const Moves: {[moveid: string]: MoveData} = {
|
|
|
18312
18312
|
volatileStatus: 'torment',
|
|
18313
18313
|
condition: {
|
|
18314
18314
|
noCopy: true,
|
|
18315
|
-
onStart(pokemon) {
|
|
18315
|
+
onStart(pokemon, source, effect) {
|
|
18316
18316
|
if (pokemon.volatiles['dynamax']) {
|
|
18317
18317
|
delete pokemon.volatiles['torment'];
|
|
18318
18318
|
return false;
|
|
18319
18319
|
}
|
|
18320
|
+
if (effect?.id === 'gmaxmeltdown') this.effectState.duration = 3;
|
|
18320
18321
|
this.add('-start', pokemon, 'Torment');
|
|
18321
18322
|
},
|
|
18322
18323
|
onEnd(pokemon) {
|
|
@@ -19436,13 +19437,21 @@ export const Moves: {[moveid: string]: MoveData} = {
|
|
|
19436
19437
|
}
|
|
19437
19438
|
return 5;
|
|
19438
19439
|
},
|
|
19440
|
+
onModifyMove(move, source, target) {
|
|
19441
|
+
// This code is for moves that use defensive stats as the attacking stat; see below for most of the implementation
|
|
19442
|
+
if (!move.overrideOffensiveStat) return;
|
|
19443
|
+
const statAndBoosts = move.overrideOffensiveStat;
|
|
19444
|
+
if (!['def', 'spd'].includes(statAndBoosts)) return;
|
|
19445
|
+
move.overrideOffensiveStat = statAndBoosts === 'def' ? 'spd' : 'def';
|
|
19446
|
+
this.hint(`${move.name} uses ${statAndBoosts === 'def' ? '' : 'Sp. '}Def boosts when Wonder Room is active.`);
|
|
19447
|
+
},
|
|
19439
19448
|
onFieldStart(field, source) {
|
|
19440
19449
|
this.add('-fieldstart', 'move: Wonder Room', '[of] ' + source);
|
|
19441
19450
|
},
|
|
19442
19451
|
onFieldRestart(target, source) {
|
|
19443
19452
|
this.field.removePseudoWeather('wonderroom');
|
|
19444
19453
|
},
|
|
19445
|
-
// Swapping defenses implemented in sim/pokemon.js:Pokemon#calculateStat and Pokemon#getStat
|
|
19454
|
+
// Swapping defenses partially implemented in sim/pokemon.js:Pokemon#calculateStat and Pokemon#getStat
|
|
19446
19455
|
onFieldResidualOrder: 27,
|
|
19447
19456
|
onFieldResidualSubOrder: 5,
|
|
19448
19457
|
onFieldEnd() {
|
package/data/rulesets.ts
CHANGED
|
@@ -1089,7 +1089,9 @@ export const Rulesets: {[k: string]: FormatData} = {
|
|
|
1089
1089
|
if (!nonstandard && !move.isZ && !move.isMax && !this.ruleTable.isRestricted(`move:${move.id}`)) {
|
|
1090
1090
|
const speciesTypes: string[] = [];
|
|
1091
1091
|
const moveTypes: string[] = [];
|
|
1092
|
-
|
|
1092
|
+
// BDSP can't import Pokemon from Home, so it shouldn't grant moves from archaic species types
|
|
1093
|
+
const minObtainableSpeciesGen = this.dex.currentMod === 'gen8bdsp' ? this.dex.gen : species.gen;
|
|
1094
|
+
for (let i = this.dex.gen; i >= minObtainableSpeciesGen && i >= move.gen; i--) {
|
|
1093
1095
|
const dex = this.dex.forGen(i);
|
|
1094
1096
|
moveTypes.push(dex.moves.get(move.name).type);
|
|
1095
1097
|
|
|
@@ -1624,4 +1626,200 @@ export const Rulesets: {[k: string]: FormatData} = {
|
|
|
1624
1626
|
this.lose(target.side);
|
|
1625
1627
|
},
|
|
1626
1628
|
},
|
|
1629
|
+
tiershiftmod: {
|
|
1630
|
+
effectType: "Rule",
|
|
1631
|
+
name: "Tier Shift Mod",
|
|
1632
|
+
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.`,
|
|
1633
|
+
ruleset: ['Overflow Stat Mod'],
|
|
1634
|
+
onBegin() {
|
|
1635
|
+
this.add('rule', 'Tier Shift Mod: Pok\u00e9mon get stat buffs depending on their tier, excluding HP.');
|
|
1636
|
+
},
|
|
1637
|
+
onModifySpecies(species, target, source, effect) {
|
|
1638
|
+
if (!species.baseStats) return;
|
|
1639
|
+
const boosts: {[tier: string]: number} = {
|
|
1640
|
+
uu: 10,
|
|
1641
|
+
rubl: 10,
|
|
1642
|
+
ru: 20,
|
|
1643
|
+
nubl: 20,
|
|
1644
|
+
nu: 30,
|
|
1645
|
+
publ: 30,
|
|
1646
|
+
pu: 40,
|
|
1647
|
+
nfe: 40,
|
|
1648
|
+
lc: 40,
|
|
1649
|
+
};
|
|
1650
|
+
let tier: string = this.toID(species.tier);
|
|
1651
|
+
if (!(tier in boosts)) return;
|
|
1652
|
+
// Non-Pokemon bans in lower tiers
|
|
1653
|
+
if (target) {
|
|
1654
|
+
if (target.set.item === 'lightclay') return;
|
|
1655
|
+
if (['drizzle', 'drought', 'snowwarning'].includes(target.set.ability) && boosts[tier] > 20) tier = 'nubl';
|
|
1656
|
+
}
|
|
1657
|
+
const pokemon = this.dex.deepClone(species);
|
|
1658
|
+
pokemon.bst = pokemon.baseStats['hp'];
|
|
1659
|
+
const boost = boosts[tier];
|
|
1660
|
+
let statName: StatID;
|
|
1661
|
+
for (statName in pokemon.baseStats as StatsTable) {
|
|
1662
|
+
if (statName === 'hp') continue;
|
|
1663
|
+
pokemon.baseStats[statName] = this.clampIntRange(pokemon.baseStats[statName] + boost, 1, 255);
|
|
1664
|
+
pokemon.bst += pokemon.baseStats[statName];
|
|
1665
|
+
}
|
|
1666
|
+
return pokemon;
|
|
1667
|
+
},
|
|
1668
|
+
},
|
|
1669
|
+
crossevolutionmod: {
|
|
1670
|
+
effectType: "Rule",
|
|
1671
|
+
name: "Cross Evolution Mod",
|
|
1672
|
+
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.",
|
|
1673
|
+
ruleset: ['Overflow Stat Mod'],
|
|
1674
|
+
onValidateTeam(team) {
|
|
1675
|
+
const names = new Set<ID>();
|
|
1676
|
+
for (const set of team) {
|
|
1677
|
+
const name = set.name;
|
|
1678
|
+
if (names.has(this.dex.toID(name))) {
|
|
1679
|
+
return [
|
|
1680
|
+
`Your Pok\u00e9mon must have different nicknames.`,
|
|
1681
|
+
`(You have more than one Pok\u00e9mon named '${name}')`,
|
|
1682
|
+
];
|
|
1683
|
+
}
|
|
1684
|
+
names.add(this.dex.toID(name));
|
|
1685
|
+
}
|
|
1686
|
+
if (!names.size) {
|
|
1687
|
+
return [
|
|
1688
|
+
`${this.format.name} works using nicknames; your team has 0 nicknamed Pok\u00e9mon.`,
|
|
1689
|
+
`(If this was intentional, add a nickname to one Pok\u00e9mon that isn't the name of a Pok\u00e9mon species.)`,
|
|
1690
|
+
];
|
|
1691
|
+
}
|
|
1692
|
+
},
|
|
1693
|
+
checkCanLearn(move, species, lsetData, set) {
|
|
1694
|
+
// @ts-ignore
|
|
1695
|
+
if (!set.sp?.exists || !set.crossSpecies?.exists) {
|
|
1696
|
+
return this.checkCanLearn(move, species, lsetData, set);
|
|
1697
|
+
}
|
|
1698
|
+
// @ts-ignore
|
|
1699
|
+
const problem = this.checkCanLearn(move, set.sp);
|
|
1700
|
+
if (!problem) return null;
|
|
1701
|
+
// @ts-ignore
|
|
1702
|
+
if (!set.crossMovesLeft) return problem;
|
|
1703
|
+
// @ts-ignore
|
|
1704
|
+
if (this.checkCanLearn(move, set.crossSpecies)) return problem;
|
|
1705
|
+
// @ts-ignore
|
|
1706
|
+
set.crossMovesLeft--;
|
|
1707
|
+
return null;
|
|
1708
|
+
},
|
|
1709
|
+
validateSet(set, teamHas) {
|
|
1710
|
+
const crossSpecies = this.dex.species.get(set.name);
|
|
1711
|
+
const onChangeSet = this.dex.formats.get('Pokemon').onChangeSet;
|
|
1712
|
+
let problems = onChangeSet?.call(this, set, this.format) || null;
|
|
1713
|
+
if (Array.isArray(problems) && problems.length) return problems;
|
|
1714
|
+
const crossNonstandard = !this.ruleTable.has('standardnatdex') && crossSpecies.isNonstandard === 'Past';
|
|
1715
|
+
const crossIsCap = !this.ruleTable.has('+pokemontag:cap') && crossSpecies.isNonstandard === 'CAP';
|
|
1716
|
+
if (!crossSpecies.exists || crossNonstandard || crossIsCap) return this.validateSet(set, teamHas);
|
|
1717
|
+
const species = this.dex.species.get(set.species);
|
|
1718
|
+
const check = this.checkSpecies(set, species, species, {});
|
|
1719
|
+
if (check) return [check];
|
|
1720
|
+
const nonstandard = !this.ruleTable.has('standardnatdex') && species.isNonstandard === 'Past';
|
|
1721
|
+
const isCap = !this.ruleTable.has('+pokemontag:cap') && species.isNonstandard === 'CAP';
|
|
1722
|
+
if (!species.exists || nonstandard || isCap || species === crossSpecies) return this.validateSet(set, teamHas);
|
|
1723
|
+
if (!species.nfe) return [`${species.name} cannot cross evolve because it doesn't evolve.`];
|
|
1724
|
+
const crossIsUnreleased = (crossSpecies.tier === "Unreleased" && crossSpecies.isNonstandard === "Unobtainable");
|
|
1725
|
+
if (crossSpecies.battleOnly || crossIsUnreleased || !crossSpecies.prevo) {
|
|
1726
|
+
return [`${species.name} cannot cross evolve into ${crossSpecies.name} because it isn't an evolution.`];
|
|
1727
|
+
}
|
|
1728
|
+
if (this.ruleTable.isRestrictedSpecies(crossSpecies)) {
|
|
1729
|
+
return [`${species.name} cannot cross evolve into ${crossSpecies.name} because it is banned.`];
|
|
1730
|
+
}
|
|
1731
|
+
const crossPrevoSpecies = this.dex.species.get(crossSpecies.prevo);
|
|
1732
|
+
if (!crossPrevoSpecies.prevo !== !species.prevo) {
|
|
1733
|
+
return [
|
|
1734
|
+
`${species.name} cannot cross evolve into ${crossSpecies.name} because they are not consecutive evolution stages.`,
|
|
1735
|
+
];
|
|
1736
|
+
}
|
|
1737
|
+
const ability = this.dex.abilities.get(set.ability);
|
|
1738
|
+
if (!this.ruleTable.isRestricted(`ability:${ability.id}`) || Object.values(species.abilities).includes(ability.name)) {
|
|
1739
|
+
set.species = crossSpecies.name;
|
|
1740
|
+
}
|
|
1741
|
+
|
|
1742
|
+
// @ts-ignore
|
|
1743
|
+
set.sp = species;
|
|
1744
|
+
// @ts-ignore
|
|
1745
|
+
set.crossSpecies = crossSpecies;
|
|
1746
|
+
// @ts-ignore
|
|
1747
|
+
set.crossMovesLeft = 2;
|
|
1748
|
+
problems = this.validateSet(set, teamHas);
|
|
1749
|
+
set.name = crossSpecies.name;
|
|
1750
|
+
set.species = species.name;
|
|
1751
|
+
return problems;
|
|
1752
|
+
},
|
|
1753
|
+
onModifySpecies(species, target, source, effect) {
|
|
1754
|
+
if (!target) return; // chat
|
|
1755
|
+
if (effect && ['imposter', 'transform'].includes(effect.id)) return;
|
|
1756
|
+
if (target.set.name === target.set.species) return;
|
|
1757
|
+
const crossSpecies = this.dex.species.get(target.set.name);
|
|
1758
|
+
if (!crossSpecies.exists) return;
|
|
1759
|
+
if (species.battleOnly || !species.nfe) return;
|
|
1760
|
+
const crossIsUnreleased = (crossSpecies.tier === "Unreleased" && crossSpecies.isNonstandard === "Unobtainable");
|
|
1761
|
+
if (crossSpecies.battleOnly || crossIsUnreleased || !crossSpecies.prevo) return;
|
|
1762
|
+
const crossPrevoSpecies = this.dex.species.get(crossSpecies.prevo);
|
|
1763
|
+
if (!crossPrevoSpecies.prevo !== !species.prevo) return;
|
|
1764
|
+
|
|
1765
|
+
const mixedSpecies = this.dex.deepClone(species);
|
|
1766
|
+
mixedSpecies.baseSpecies = mixedSpecies.name = `${species.name}-${crossSpecies.name}`;
|
|
1767
|
+
mixedSpecies.weightkg =
|
|
1768
|
+
Math.max(0.1, +(species.weightkg + crossSpecies.weightkg - crossPrevoSpecies.weightkg)).toFixed(1);
|
|
1769
|
+
mixedSpecies.nfe = false;
|
|
1770
|
+
mixedSpecies.evos = [];
|
|
1771
|
+
mixedSpecies.eggGroups = crossSpecies.eggGroups;
|
|
1772
|
+
mixedSpecies.abilities = crossSpecies.abilities;
|
|
1773
|
+
mixedSpecies.bst = 0;
|
|
1774
|
+
let i: StatID;
|
|
1775
|
+
for (i in species.baseStats) {
|
|
1776
|
+
const statChange = crossSpecies.baseStats[i] - crossPrevoSpecies.baseStats[i];
|
|
1777
|
+
mixedSpecies.baseStats[i] = this.clampIntRange(species.baseStats[i] + statChange, 1, 255);
|
|
1778
|
+
mixedSpecies.bst += mixedSpecies.baseStats[i];
|
|
1779
|
+
}
|
|
1780
|
+
if (crossSpecies.types[0] !== crossPrevoSpecies.types[0]) mixedSpecies.types[0] = crossSpecies.types[0];
|
|
1781
|
+
if (crossSpecies.types[1] !== crossPrevoSpecies.types[1]) {
|
|
1782
|
+
mixedSpecies.types[1] = crossSpecies.types[1] || crossSpecies.types[0];
|
|
1783
|
+
}
|
|
1784
|
+
if (mixedSpecies.types[0] === mixedSpecies.types[1]) mixedSpecies.types = [mixedSpecies.types[0]];
|
|
1785
|
+
|
|
1786
|
+
return mixedSpecies;
|
|
1787
|
+
},
|
|
1788
|
+
onBegin() {
|
|
1789
|
+
for (const pokemon of this.getAllPokemon()) {
|
|
1790
|
+
pokemon.baseSpecies = pokemon.species;
|
|
1791
|
+
}
|
|
1792
|
+
},
|
|
1793
|
+
},
|
|
1794
|
+
revelationmonsmod: {
|
|
1795
|
+
effectType: "Rule",
|
|
1796
|
+
name: "Revelationmons Mod",
|
|
1797
|
+
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).`,
|
|
1798
|
+
onBegin() {
|
|
1799
|
+
this.add('rule', 'Revelationmons Mod: The first moveslots have their types changed to match the Pokémon\'s types');
|
|
1800
|
+
},
|
|
1801
|
+
onValidateSet(set) {
|
|
1802
|
+
const species = this.dex.species.get(set.species);
|
|
1803
|
+
const slotIndex = species.types.length - 1;
|
|
1804
|
+
const problems = [];
|
|
1805
|
+
for (const [i, moveid] of set.moves.entries()) {
|
|
1806
|
+
const move = this.dex.moves.get(moveid);
|
|
1807
|
+
if (!this.ruleTable.isRestricted(`move:${move.id}`)) continue;
|
|
1808
|
+
if (i <= slotIndex) {
|
|
1809
|
+
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'}.`);
|
|
1810
|
+
}
|
|
1811
|
+
}
|
|
1812
|
+
return problems;
|
|
1813
|
+
},
|
|
1814
|
+
onModifyMove(move, pokemon, target) {
|
|
1815
|
+
const types = pokemon.getTypes(true);
|
|
1816
|
+
const noModifyType = [
|
|
1817
|
+
'judgment', 'multiattack', 'naturalgift', 'revelationdance', 'technoblast', 'terrainpulse', 'weatherball',
|
|
1818
|
+
];
|
|
1819
|
+
if (noModifyType.includes(move.id)) return;
|
|
1820
|
+
for (const [i, type] of types.entries()) {
|
|
1821
|
+
if (pokemon.moveSlots[i] && move.id === pokemon.moveSlots[i].id) move.type = type;
|
|
1822
|
+
}
|
|
1823
|
+
},
|
|
1824
|
+
},
|
|
1627
1825
|
};
|
package/data/tags.ts
CHANGED
|
@@ -196,7 +196,7 @@ export const Tags: {[id: string]: TagData} = {
|
|
|
196
196
|
name: "ND UUBL",
|
|
197
197
|
speciesFilter: species => [
|
|
198
198
|
'Aerodactyl-Mega', 'Azumarill', 'Blacephalon', 'Diancie-Mega', 'Gallade-Mega', 'Gardevoir-Mega', 'Gengar', 'Gyarados', 'Gyarados-Mega',
|
|
199
|
-
'Hawlucha', 'Heracross-Mega', 'Hoopa-Unbound', 'Hydreigon', 'Jirachi', 'Latias', 'Latias-Mega', 'Latios', 'Latios-Mega', 'Manaphy',
|
|
199
|
+
'Hawlucha', 'Heracross-Mega', 'Hoopa-Unbound', 'Hydreigon', 'Jirachi', 'Latias', 'Latias-Mega', 'Latios', 'Latios-Mega', 'Manaphy', 'Mew',
|
|
200
200
|
'Pinsir-Mega', 'Sableye-Mega', 'Slowbro-Mega', 'Slowking-Galar', 'Thundurus', 'Thundurus-Therian', 'Venusaur-Mega', 'Xurkitree', 'Zapdos-Galar',
|
|
201
201
|
].includes(species.name),
|
|
202
202
|
},
|
|
@@ -209,7 +209,7 @@ export const Tags: {[id: string]: TagData} = {
|
|
|
209
209
|
},
|
|
210
210
|
dou: {
|
|
211
211
|
name: "DOU",
|
|
212
|
-
speciesFilter: species => species.doublesTier === 'DOU',
|
|
212
|
+
speciesFilter: species => species.doublesTier === 'DOU' || species.doublesTier === '(DOU)',
|
|
213
213
|
},
|
|
214
214
|
dbl: {
|
|
215
215
|
name: "DBL",
|