@pkmn/sim 0.5.5 → 0.5.8
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 +325 -254
- 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/formats-data.js +130 -17
- package/build/data/formats-data.js.map +1 -1
- package/build/data/items.js +2 -2
- package/build/data/items.js.map +1 -1
- package/build/data/learnsets.js +6 -5
- package/build/data/learnsets.js.map +1 -1
- package/build/data/mods/gen2/moves.js +13 -1
- package/build/data/mods/gen2/moves.js.map +1 -1
- package/build/data/mods/gen3/formats-data.js +3 -3
- package/build/data/mods/gen3/formats-data.js.map +1 -1
- package/build/data/mods/gen4/formats-data.js +4 -4
- package/build/data/mods/gen4/formats-data.js.map +1 -1
- package/build/data/mods/gen4/moves.js +7 -5
- package/build/data/mods/gen4/moves.js.map +1 -1
- package/build/data/mods/gen5/formats-data.js +1 -1
- package/build/data/mods/gen5/formats-data.js.map +1 -1
- package/build/data/mods/gen5/moves.js +6 -4
- package/build/data/mods/gen5/moves.js.map +1 -1
- package/build/data/mods/gen6/formats-data.js +3 -2
- package/build/data/mods/gen6/formats-data.js.map +1 -1
- package/build/data/mods/gen6/items.js +2 -2
- package/build/data/mods/gen6/items.js.map +1 -1
- package/build/data/mods/gen7/formats-data.js +2 -1
- package/build/data/mods/gen7/formats-data.js.map +1 -1
- package/build/data/mods/gen7/moves.js +3 -3
- package/build/data/mods/gen7/moves.js.map +1 -1
- package/build/data/mods/gen7/pokedex.js +4 -0
- package/build/data/mods/gen7/pokedex.js.map +1 -1
- package/build/data/moves.js +6 -5
- package/build/data/moves.js.map +1 -1
- package/build/data/pokedex.js +480 -11
- package/build/data/pokedex.js.map +1 -1
- package/build/data/rulesets.js +26 -1
- package/build/data/rulesets.js.map +1 -1
- package/build/sim/battle.js +23 -22
- package/build/sim/battle.js.map +1 -1
- package/build/sim/dex-species.js +5 -2
- 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/team-validator.js +11 -0
- package/build/sim/team-validator.js.map +1 -1
- package/config/formats.ts +327 -257
- package/data/aliases.ts +4 -4
- package/data/formats-data.ts +130 -17
- package/data/items.ts +2 -2
- package/data/learnsets.ts +6 -5
- package/data/mods/gen2/moves.ts +13 -1
- package/data/mods/gen3/formats-data.ts +3 -3
- package/data/mods/gen4/formats-data.ts +4 -4
- package/data/mods/gen4/moves.ts +6 -4
- package/data/mods/gen5/formats-data.ts +1 -1
- package/data/mods/gen5/moves.ts +6 -4
- package/data/mods/gen6/formats-data.ts +3 -2
- package/data/mods/gen6/items.ts +2 -2
- package/data/mods/gen7/formats-data.ts +2 -1
- package/data/mods/gen7/moves.ts +3 -3
- package/data/mods/gen7/pokedex.ts +4 -0
- package/data/moves.ts +6 -5
- package/data/pokedex.ts +480 -11
- package/data/rulesets.ts +23 -1
- package/package.json +2 -2
- package/sim/battle.ts +24 -23
- package/sim/dex-species.ts +5 -2
- package/sim/exported-global-types.ts +1 -0
- package/sim/global-types.ts +1 -0
- package/sim/team-validator.ts +13 -0
package/data/rulesets.ts
CHANGED
|
@@ -1219,6 +1219,27 @@ export const Rulesets: {[k: string]: FormatData} = {
|
|
|
1219
1219
|
}
|
|
1220
1220
|
},
|
|
1221
1221
|
},
|
|
1222
|
+
camomonsmod: {
|
|
1223
|
+
effectType: 'Rule',
|
|
1224
|
+
name: 'Camomons Mod',
|
|
1225
|
+
desc: `Pokémon have their types set to match their first two moves.`,
|
|
1226
|
+
onBegin() {
|
|
1227
|
+
this.add('rule', 'Camomons Mod: Pok\u00e9mon have their types set to match their first two moves.');
|
|
1228
|
+
},
|
|
1229
|
+
onModifySpeciesPriority: 2,
|
|
1230
|
+
onModifySpecies(species, target, source, effect) {
|
|
1231
|
+
if (!target) return; // Chat command
|
|
1232
|
+
if (effect && ['imposter', 'transform'].includes(effect.id)) return;
|
|
1233
|
+
const types = [...new Set(target.baseMoveSlots.slice(0, 2).map(move => this.dex.moves.get(move.id).type))];
|
|
1234
|
+
return {...species, types: types};
|
|
1235
|
+
},
|
|
1236
|
+
onSwitchIn(pokemon) {
|
|
1237
|
+
this.add('-start', pokemon, 'typechange', (pokemon.illusion || pokemon).getTypes(true).join('/'), '[silent]');
|
|
1238
|
+
},
|
|
1239
|
+
onAfterMega(pokemon) {
|
|
1240
|
+
this.add('-start', pokemon, 'typechange', (pokemon.illusion || pokemon).getTypes(true).join('/'), '[silent]');
|
|
1241
|
+
},
|
|
1242
|
+
},
|
|
1222
1243
|
allowtradeback: {
|
|
1223
1244
|
effectType: 'ValidatorRule',
|
|
1224
1245
|
name: 'Allow Tradeback',
|
|
@@ -1834,7 +1855,7 @@ export const Rulesets: {[k: string]: FormatData} = {
|
|
|
1834
1855
|
name: "Revelationmons Mod",
|
|
1835
1856
|
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).`,
|
|
1836
1857
|
onBegin() {
|
|
1837
|
-
this.add('rule', 'Revelationmons Mod: The first moveslots have their types changed to match the Pok
|
|
1858
|
+
this.add('rule', 'Revelationmons Mod: The first moveslots have their types changed to match the Pok\u00e9mon\'s types');
|
|
1838
1859
|
},
|
|
1839
1860
|
onValidateSet(set) {
|
|
1840
1861
|
const species = this.dex.species.get(set.species);
|
|
@@ -1856,6 +1877,7 @@ export const Rulesets: {[k: string]: FormatData} = {
|
|
|
1856
1877
|
];
|
|
1857
1878
|
if (noModifyType.includes(move.id)) return;
|
|
1858
1879
|
for (const [i, type] of types.entries()) {
|
|
1880
|
+
if (!this.dex.types.isName(type)) continue;
|
|
1859
1881
|
if (pokemon.moveSlots[i] && move.id === pokemon.moveSlots[i].id) move.type = type;
|
|
1860
1882
|
}
|
|
1861
1883
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pkmn/sim",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.8",
|
|
4
4
|
"description": "An automatically generated extraction of just the simulator portion of Pokémon Showdown",
|
|
5
5
|
"homepage": "https://psim.us",
|
|
6
6
|
"main": "build/sim/index.js",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"@pkmn/streams": "^1.0.0"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
|
-
"mocha": "^9.1
|
|
34
|
+
"mocha": "^9.2.1"
|
|
35
35
|
},
|
|
36
36
|
"scripts": {
|
|
37
37
|
"compile": "tsc -p .",
|
package/sim/battle.ts
CHANGED
|
@@ -1553,29 +1553,8 @@ export class Battle {
|
|
|
1553
1553
|
maybeTriggerEndlessBattleClause(
|
|
1554
1554
|
trappedBySide: boolean[], stalenessBySide: ('internal' | 'external' | undefined)[]
|
|
1555
1555
|
) {
|
|
1556
|
-
if (this.turn <= 100) return;
|
|
1557
|
-
|
|
1558
|
-
// the turn limit is not a part of Endless Battle Clause
|
|
1559
|
-
if (this.turn >= 1000) {
|
|
1560
|
-
this.add('message', `It is turn 1000. You have hit the turn limit!`);
|
|
1561
|
-
this.tie();
|
|
1562
|
-
return true;
|
|
1563
|
-
}
|
|
1564
|
-
if (
|
|
1565
|
-
(this.turn >= 500 && this.turn % 100 === 0) || // every 100 turns past turn 500,
|
|
1566
|
-
(this.turn >= 900 && this.turn % 10 === 0) || // every 10 turns past turn 900,
|
|
1567
|
-
this.turn >= 990 // every turn past turn 990
|
|
1568
|
-
) {
|
|
1569
|
-
const turnsLeft = 1000 - this.turn;
|
|
1570
|
-
const turnsLeftText = (turnsLeft === 1 ? `1 turn` : `${turnsLeft} turns`);
|
|
1571
|
-
this.add('bigerror', `You will auto-tie if the battle doesn't end in ${turnsLeftText} (on turn 1000).`);
|
|
1572
|
-
}
|
|
1573
|
-
|
|
1574
|
-
if (!this.ruleTable.has('endlessbattleclause')) return;
|
|
1575
|
-
// for now, FFA doesn't support Endless Battle Clause
|
|
1576
|
-
if (this.format.gameType === 'freeforall') return;
|
|
1577
|
-
|
|
1578
1556
|
// Gen 1 Endless Battle Clause triggers
|
|
1557
|
+
// These are checked before the 100 turn minimum as the battle cannot progress if they are true
|
|
1579
1558
|
if (this.gen <= 1) {
|
|
1580
1559
|
const noProgressPossible = this.sides.every(side => {
|
|
1581
1560
|
const foeAllGhosts = side.foe.pokemon.every(pokemon => pokemon.types.includes('Ghost'));
|
|
@@ -1593,7 +1572,7 @@ export class Battle {
|
|
|
1593
1572
|
// a pokemon can't lose PP if it Transforms into a pokemon with only Transform
|
|
1594
1573
|
(pokemon.moves.every(moveid => moveid === 'transform') && foeAllTransform) ||
|
|
1595
1574
|
// Struggle can't damage yourself if every foe is a Ghost
|
|
1596
|
-
pokemon.moveSlots.every(slot => slot.pp === 0) && foeAllGhosts
|
|
1575
|
+
(pokemon.moveSlots.every(slot => slot.pp === 0) && foeAllGhosts)
|
|
1597
1576
|
));
|
|
1598
1577
|
});
|
|
1599
1578
|
if (noProgressPossible) {
|
|
@@ -1602,6 +1581,28 @@ export class Battle {
|
|
|
1602
1581
|
}
|
|
1603
1582
|
}
|
|
1604
1583
|
|
|
1584
|
+
if (this.turn <= 100) return;
|
|
1585
|
+
|
|
1586
|
+
// the turn limit is not a part of Endless Battle Clause
|
|
1587
|
+
if (this.turn >= 1000) {
|
|
1588
|
+
this.add('message', `It is turn 1000. You have hit the turn limit!`);
|
|
1589
|
+
this.tie();
|
|
1590
|
+
return true;
|
|
1591
|
+
}
|
|
1592
|
+
if (
|
|
1593
|
+
(this.turn >= 500 && this.turn % 100 === 0) || // every 100 turns past turn 500,
|
|
1594
|
+
(this.turn >= 900 && this.turn % 10 === 0) || // every 10 turns past turn 900,
|
|
1595
|
+
this.turn >= 990 // every turn past turn 990
|
|
1596
|
+
) {
|
|
1597
|
+
const turnsLeft = 1000 - this.turn;
|
|
1598
|
+
const turnsLeftText = (turnsLeft === 1 ? `1 turn` : `${turnsLeft} turns`);
|
|
1599
|
+
this.add('bigerror', `You will auto-tie if the battle doesn't end in ${turnsLeftText} (on turn 1000).`);
|
|
1600
|
+
}
|
|
1601
|
+
|
|
1602
|
+
if (!this.ruleTable.has('endlessbattleclause')) return;
|
|
1603
|
+
// for now, FFA doesn't support Endless Battle Clause
|
|
1604
|
+
if (this.format.gameType === 'freeforall') return;
|
|
1605
|
+
|
|
1605
1606
|
// Are all Pokemon on every side stale, with at least one side containing an externally stale Pokemon?
|
|
1606
1607
|
if (!stalenessBySide.every(s => !!s) || !stalenessBySide.some(s => s === 'external')) return;
|
|
1607
1608
|
|
package/sim/dex-species.ts
CHANGED
|
@@ -295,7 +295,7 @@ export class Species extends BasicEffect implements Readonly<BasicEffect & Speci
|
|
|
295
295
|
if (Array.isArray(data.changesFrom)) this.changesFrom = data.changesFrom[0];
|
|
296
296
|
|
|
297
297
|
if (!this.gen && this.num >= 1) {
|
|
298
|
-
if (this.num >= 810 || ['Gmax', 'Galar', 'Galar-Zen'].includes(this.forme)) {
|
|
298
|
+
if (this.num >= 810 || ['Gmax', 'Galar', 'Galar-Zen', 'Hisui'].includes(this.forme)) {
|
|
299
299
|
this.gen = 8;
|
|
300
300
|
} else if (this.num >= 722 || this.forme.startsWith('Alola') || this.forme === 'Starter') {
|
|
301
301
|
this.gen = 7;
|
|
@@ -492,7 +492,10 @@ export class DexSpecies {
|
|
|
492
492
|
species.tier = species.doublesTier = 'Illegal';
|
|
493
493
|
}
|
|
494
494
|
}
|
|
495
|
-
species.nfe =
|
|
495
|
+
species.nfe = species.evos.some(evo => {
|
|
496
|
+
const evoSpecies = this.get(evo);
|
|
497
|
+
return !evoSpecies.isNonstandard || evoSpecies.isNonstandard === species?.isNonstandard;
|
|
498
|
+
});
|
|
496
499
|
species.canHatch = species.canHatch ||
|
|
497
500
|
(!['Ditto', 'Undiscovered'].includes(species.eggGroups[0]) && !species.prevo && species.name !== 'Manaphy');
|
|
498
501
|
if (this.dex.gen === 1) species.bst -= species.baseStats.spd;
|
|
@@ -373,6 +373,7 @@ export interface ModdedBattleScriptsData extends Partial<BattleScriptsData> {
|
|
|
373
373
|
init?: (this: ModdedDex) => void;
|
|
374
374
|
natureModify?: (this: Battle, stats: StatsTable, set: PokemonSet) => StatsTable;
|
|
375
375
|
nextTurn?: (this: Battle) => void;
|
|
376
|
+
runAction?: (this: Battle, action: Action) => void;
|
|
376
377
|
spreadModify?: (this: Battle, baseStats: StatsTable, set: PokemonSet) => StatsTable;
|
|
377
378
|
suppressingWeather?: (this: Battle) => boolean;
|
|
378
379
|
trunc?: (n: number) => number;
|
package/sim/global-types.ts
CHANGED
|
@@ -373,6 +373,7 @@ interface ModdedBattleScriptsData extends Partial<BattleScriptsData> {
|
|
|
373
373
|
init?: (this: ModdedDex) => void;
|
|
374
374
|
natureModify?: (this: Battle, stats: StatsTable, set: PokemonSet) => StatsTable;
|
|
375
375
|
nextTurn?: (this: Battle) => void;
|
|
376
|
+
runAction?: (this: Battle, action: Action) => void;
|
|
376
377
|
spreadModify?: (this: Battle, baseStats: StatsTable, set: PokemonSet) => StatsTable;
|
|
377
378
|
suppressingWeather?: (this: Battle) => boolean;
|
|
378
379
|
trunc?: (n: number) => number;
|
package/sim/team-validator.ts
CHANGED
|
@@ -1564,6 +1564,19 @@ export class TeamValidator {
|
|
|
1564
1564
|
|
|
1565
1565
|
setHas['ability:' + ability.id] = true;
|
|
1566
1566
|
|
|
1567
|
+
if (this.format.id === 'gen8pokebilities') {
|
|
1568
|
+
const species = dex.species.get(set.species);
|
|
1569
|
+
const unSeenAbilities = Object.keys(species.abilities)
|
|
1570
|
+
.filter(key => key !== 'S' && (key !== 'H' || !species.unreleasedHidden))
|
|
1571
|
+
.map(key => species.abilities[key as "0" | "1" | "H" | "S"]);
|
|
1572
|
+
|
|
1573
|
+
if (ability.id !== this.toID(species.abilities['S'])) {
|
|
1574
|
+
for (const abilityName of unSeenAbilities) {
|
|
1575
|
+
setHas['ability:' + toID(abilityName)] = true;
|
|
1576
|
+
}
|
|
1577
|
+
}
|
|
1578
|
+
}
|
|
1579
|
+
|
|
1567
1580
|
let banReason = ruleTable.check('ability:' + ability.id);
|
|
1568
1581
|
if (banReason) {
|
|
1569
1582
|
return `${set.name}'s ability ${ability.name} is ${banReason}.`;
|