@pkmn/randoms 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/gen1.js +42 -71
- package/build/gen1.js.map +1 -1
- package/build/gen2.js +2 -2
- package/build/gen2.js.map +1 -1
- package/build/gen3.js +1 -1
- package/build/gen3.js.map +1 -1
- package/build/gen4.js +1 -1
- package/build/gen4.js.map +1 -1
- package/build/gen5.js +1 -1
- package/build/gen5.js.map +1 -1
- package/build/gen6.d.ts +7 -3
- package/build/gen6.js +2 -2
- package/build/gen6.js.map +1 -1
- package/build/gen7.d.ts +23 -2
- package/build/gen7.js +16 -11
- package/build/gen7.js.map +1 -1
- package/build/gen8.js +92 -65
- package/build/gen8.js.map +1 -1
- package/package.json +2 -2
- package/src/gen1.ts +44 -73
- package/src/gen2.ts +2 -2
- package/src/gen3.ts +1 -1
- package/src/gen4.ts +1 -1
- package/src/gen5.ts +1 -1
- package/src/gen6.ts +4 -4
- package/src/gen7.ts +30 -11
- package/src/gen8.ts +91 -66
package/build/gen8.js
CHANGED
|
@@ -133,7 +133,7 @@ class RandomTeams {
|
|
|
133
133
|
Poison: (movePool, moves, abilities, types, counter) => {
|
|
134
134
|
if (counter.get('Poison'))
|
|
135
135
|
return false;
|
|
136
|
-
return types.has('Ground') || types.has('Psychic') || !!counter.setupType || movePool.includes('gunkshot');
|
|
136
|
+
return types.has('Ground') || types.has('Psychic') || types.has('Grass') || !!counter.setupType || movePool.includes('gunkshot');
|
|
137
137
|
},
|
|
138
138
|
Psychic: (movePool, moves, abilities, types, counter) => {
|
|
139
139
|
if (counter.get('Psychic'))
|
|
@@ -153,7 +153,7 @@ class RandomTeams {
|
|
|
153
153
|
Water: (movePool, moves, abilities, types, counter, species) => {
|
|
154
154
|
if (!counter.get('Water') && !moves.has('hypervoice'))
|
|
155
155
|
return true;
|
|
156
|
-
if (
|
|
156
|
+
if (['hypervoice', 'liquidation', 'surgingstrikes'].some(m => movePool.includes(m)))
|
|
157
157
|
return true;
|
|
158
158
|
return abilities.has('Huge Power') && movePool.includes('aquajet');
|
|
159
159
|
},
|
|
@@ -233,11 +233,10 @@ class RandomTeams {
|
|
|
233
233
|
return move.id !== 'bodypress';
|
|
234
234
|
}
|
|
235
235
|
randomCCTeam() {
|
|
236
|
-
var _a;
|
|
237
236
|
const dex = this.dex;
|
|
238
237
|
const team = [];
|
|
239
|
-
const natures =
|
|
240
|
-
const items =
|
|
238
|
+
const natures = this.dex.natures.all();
|
|
239
|
+
const items = this.dex.items.all();
|
|
241
240
|
const randomN = this.randomNPokemon(this.maxTeamSize, this.forceMonotype);
|
|
242
241
|
for (let forme of randomN) {
|
|
243
242
|
let species = dex.species.get(forme);
|
|
@@ -247,8 +246,8 @@ class RandomTeams {
|
|
|
247
246
|
let item = '';
|
|
248
247
|
if (this.gen >= 2) {
|
|
249
248
|
do {
|
|
250
|
-
item = this.sample(items);
|
|
251
|
-
} while (this.dex.items.get(item).gen > this.gen || this.dex.
|
|
249
|
+
item = this.sample(items).name;
|
|
250
|
+
} while (this.dex.items.get(item).gen > this.gen || this.dex.items.get(item).isNonstandard);
|
|
252
251
|
}
|
|
253
252
|
// Make sure forme is legal
|
|
254
253
|
if (species.battleOnly) {
|
|
@@ -270,33 +269,34 @@ class RandomTeams {
|
|
|
270
269
|
let itemData = this.dex.items.get(item);
|
|
271
270
|
if (itemData.forcedForme && forme === this.dex.species.get(itemData.forcedForme).baseSpecies) {
|
|
272
271
|
do {
|
|
273
|
-
|
|
274
|
-
|
|
272
|
+
itemData = this.sample(items);
|
|
273
|
+
item = itemData.name;
|
|
275
274
|
} while (itemData.gen > this.gen ||
|
|
276
275
|
itemData.isNonstandard ||
|
|
277
276
|
(itemData.forcedForme && forme === this.dex.species.get(itemData.forcedForme).baseSpecies));
|
|
278
277
|
}
|
|
279
278
|
// Random legal ability
|
|
280
279
|
const abilities = Object.values(species.abilities).filter(a => this.dex.abilities.get(a).gen <= this.gen);
|
|
281
|
-
const ability = this.gen <= 2 ? '
|
|
280
|
+
const ability = this.gen <= 2 ? 'No Ability' : this.sample(abilities);
|
|
282
281
|
// Four random unique moves from the movepool
|
|
283
282
|
let pool = ['struggle'];
|
|
284
283
|
if (forme === 'Smeargle') {
|
|
285
|
-
pool =
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
284
|
+
pool = this.dex.moves
|
|
285
|
+
.all()
|
|
286
|
+
.filter(move => !(move.isNonstandard || move.isZ || move.isMax || move.realMove))
|
|
287
|
+
.map(m => m.id);
|
|
289
288
|
}
|
|
290
289
|
else {
|
|
291
290
|
const formes = ['gastrodoneast', 'pumpkaboosuper', 'zygarde10'];
|
|
292
|
-
let learnset =
|
|
293
|
-
|
|
294
|
-
this.dex.
|
|
291
|
+
let learnset = this.dex.species.getLearnset(species.id);
|
|
292
|
+
if (formes.includes(species.id) || !learnset) {
|
|
293
|
+
learnset = this.dex.species.getLearnset(this.dex.species.get(species.baseSpecies).id);
|
|
294
|
+
}
|
|
295
295
|
if (learnset) {
|
|
296
296
|
pool = Object.keys(learnset).filter(moveid => learnset[moveid].find(learned => learned.startsWith(String(this.gen))));
|
|
297
297
|
}
|
|
298
298
|
if (species.changesFrom) {
|
|
299
|
-
learnset = this.dex.
|
|
299
|
+
learnset = this.dex.species.getLearnset((0, sim_1.toID)(species.changesFrom));
|
|
300
300
|
const basePool = Object.keys(learnset).filter(moveid => learnset[moveid].find(learned => learned.startsWith(String(this.gen))));
|
|
301
301
|
pool = [...new Set(pool.concat(basePool))];
|
|
302
302
|
}
|
|
@@ -322,7 +322,7 @@ class RandomTeams {
|
|
|
322
322
|
spe: this.random(32),
|
|
323
323
|
};
|
|
324
324
|
// Random nature
|
|
325
|
-
const nature = this.sample(natures);
|
|
325
|
+
const nature = this.sample(natures).name;
|
|
326
326
|
// Level balance--calculate directly from stats rather than using some silly lookup table
|
|
327
327
|
const mbstmin = 1307; // Sunkern has the lowest modified base stat total, and that total is 807
|
|
328
328
|
let stats = species.baseStats;
|
|
@@ -357,15 +357,15 @@ class RandomTeams {
|
|
|
357
357
|
name: species.baseSpecies,
|
|
358
358
|
species: species.name,
|
|
359
359
|
gender: species.gender,
|
|
360
|
-
item
|
|
361
|
-
ability
|
|
362
|
-
moves
|
|
363
|
-
evs
|
|
364
|
-
ivs
|
|
365
|
-
nature
|
|
360
|
+
item,
|
|
361
|
+
ability,
|
|
362
|
+
moves,
|
|
363
|
+
evs,
|
|
364
|
+
ivs,
|
|
365
|
+
nature,
|
|
366
366
|
level,
|
|
367
|
-
happiness
|
|
368
|
-
shiny
|
|
367
|
+
happiness,
|
|
368
|
+
shiny,
|
|
369
369
|
});
|
|
370
370
|
}
|
|
371
371
|
return team;
|
|
@@ -381,15 +381,14 @@ class RandomTeams {
|
|
|
381
381
|
throw new Error(`"${requiredType}" is not a valid type.`);
|
|
382
382
|
}
|
|
383
383
|
const pool = [];
|
|
384
|
-
for (const
|
|
385
|
-
if (
|
|
386
|
-
(this.dex.data.FormatsData[id].isNonstandard && this.dex.data.FormatsData[id].isNonstandard !== 'Unobtainable'))
|
|
384
|
+
for (const species of this.dex.species.all()) {
|
|
385
|
+
if (species.isNonstandard && species.isNonstandard !== 'Unobtainable')
|
|
387
386
|
continue;
|
|
388
|
-
if (requiredType && !
|
|
387
|
+
if (requiredType && !species.types.includes(requiredType))
|
|
389
388
|
continue;
|
|
390
|
-
if (minSourceGen &&
|
|
389
|
+
if (minSourceGen && species.gen < minSourceGen)
|
|
391
390
|
continue;
|
|
392
|
-
const num =
|
|
391
|
+
const num = species.num;
|
|
393
392
|
if (num <= 0 || pool.includes(num))
|
|
394
393
|
continue;
|
|
395
394
|
if (num > last)
|
|
@@ -402,10 +401,9 @@ class RandomTeams {
|
|
|
402
401
|
hasDexNumber[num] = i;
|
|
403
402
|
}
|
|
404
403
|
const formes = [];
|
|
405
|
-
for (const
|
|
406
|
-
if (!(
|
|
404
|
+
for (const species of this.dex.species.all()) {
|
|
405
|
+
if (!(species.num in hasDexNumber))
|
|
407
406
|
continue;
|
|
408
|
-
const species = this.dex.species.get(id);
|
|
409
407
|
if (species.gen <= this.gen && (!species.isNonstandard || species.isNonstandard === 'Unobtainable')) {
|
|
410
408
|
if (!formes[hasDexNumber[species.num]])
|
|
411
409
|
formes[hasDexNumber[species.num]] = [];
|
|
@@ -423,35 +421,38 @@ class RandomTeams {
|
|
|
423
421
|
}
|
|
424
422
|
randomHCTeam() {
|
|
425
423
|
const team = [];
|
|
426
|
-
const itemPool =
|
|
427
|
-
const abilityPool =
|
|
428
|
-
const movePool =
|
|
429
|
-
const naturePool =
|
|
424
|
+
const itemPool = [...this.dex.items.all()];
|
|
425
|
+
const abilityPool = [...this.dex.abilities.all()];
|
|
426
|
+
const movePool = [...this.dex.moves.all()];
|
|
427
|
+
const naturePool = this.dex.natures.all();
|
|
430
428
|
const randomN = this.randomNPokemon(this.maxTeamSize, this.forceMonotype);
|
|
431
429
|
for (const forme of randomN) {
|
|
432
430
|
// Choose forme
|
|
433
431
|
const species = this.dex.species.get(forme);
|
|
434
432
|
// Random unique item
|
|
435
433
|
let item = '';
|
|
434
|
+
let itemData;
|
|
436
435
|
if (this.gen >= 2) {
|
|
437
436
|
do {
|
|
438
|
-
|
|
439
|
-
|
|
437
|
+
itemData = this.sampleNoReplace(itemPool);
|
|
438
|
+
item = itemData.name;
|
|
439
|
+
} while (itemData.gen > this.gen || itemData.isNonstandard);
|
|
440
440
|
}
|
|
441
441
|
// Random unique ability
|
|
442
|
-
let ability = '
|
|
442
|
+
let ability = 'No Ability';
|
|
443
|
+
let abilityData;
|
|
443
444
|
if (this.gen >= 3) {
|
|
444
445
|
do {
|
|
445
|
-
|
|
446
|
-
|
|
446
|
+
abilityData = this.sampleNoReplace(abilityPool);
|
|
447
|
+
ability = abilityData.name;
|
|
448
|
+
} while (abilityData.gen > this.gen || abilityData.isNonstandard);
|
|
447
449
|
}
|
|
448
450
|
// Random unique moves
|
|
449
451
|
const m = [];
|
|
450
452
|
do {
|
|
451
|
-
const
|
|
452
|
-
const move = this.dex.moves.get(moveid);
|
|
453
|
+
const move = this.sampleNoReplace(movePool);
|
|
453
454
|
if (move.gen <= this.gen && !move.isNonstandard && !move.name.startsWith('Hidden Power ')) {
|
|
454
|
-
m.push(
|
|
455
|
+
m.push(move.id);
|
|
455
456
|
}
|
|
456
457
|
} while (m.length < 4);
|
|
457
458
|
// Random EVs
|
|
@@ -480,7 +481,7 @@ class RandomTeams {
|
|
|
480
481
|
spe: this.random(32),
|
|
481
482
|
};
|
|
482
483
|
// Random nature
|
|
483
|
-
const nature = this.sample(naturePool);
|
|
484
|
+
const nature = this.sample(naturePool).name;
|
|
484
485
|
// Level balance
|
|
485
486
|
const mbstmin = 1307;
|
|
486
487
|
const stats = species.baseStats;
|
|
@@ -510,15 +511,15 @@ class RandomTeams {
|
|
|
510
511
|
name: species.baseSpecies,
|
|
511
512
|
species: species.name,
|
|
512
513
|
gender: species.gender,
|
|
513
|
-
item
|
|
514
|
-
ability
|
|
514
|
+
item,
|
|
515
|
+
ability,
|
|
515
516
|
moves: m,
|
|
516
|
-
evs
|
|
517
|
-
ivs
|
|
518
|
-
nature
|
|
517
|
+
evs,
|
|
518
|
+
ivs,
|
|
519
|
+
nature,
|
|
519
520
|
level,
|
|
520
|
-
happiness
|
|
521
|
-
shiny
|
|
521
|
+
happiness,
|
|
522
|
+
shiny,
|
|
522
523
|
});
|
|
523
524
|
}
|
|
524
525
|
return team;
|
|
@@ -1136,9 +1137,8 @@ class RandomTeams {
|
|
|
1136
1137
|
return (moves.has('rapidspin') || species.nfe || isDoubles);
|
|
1137
1138
|
case 'Blaze':
|
|
1138
1139
|
return (isDoubles && abilities.has('Solar Power')) || (!isDoubles && !isNoDynamax && species.id === 'charizard');
|
|
1139
|
-
case 'Bulletproof':
|
|
1140
|
-
|
|
1141
|
-
return !!counter.setupType;
|
|
1140
|
+
// case 'Bulletproof': case 'Overcoat':
|
|
1141
|
+
// return !!counter.setupType;
|
|
1142
1142
|
case 'Chlorophyll':
|
|
1143
1143
|
return (species.baseStats.spe > 100 || !counter.get('Fire') && !moves.has('sunnyday') && !teamDetails.sun);
|
|
1144
1144
|
case 'Cloud Nine':
|
|
@@ -1545,7 +1545,7 @@ class RandomTeams {
|
|
|
1545
1545
|
const randMoves = (isDoubles && species.randomDoubleBattleMoves) ||
|
|
1546
1546
|
(isNoDynamax && species.randomBattleNoDynamaxMoves) ||
|
|
1547
1547
|
species.randomBattleMoves;
|
|
1548
|
-
const movePool = (randMoves || Object.keys(this.dex.
|
|
1548
|
+
const movePool = (randMoves || Object.keys(this.dex.species.getLearnset(species.id))).slice();
|
|
1549
1549
|
if (this.format.gameType === 'multi' || this.format.gameType === 'freeforall') {
|
|
1550
1550
|
// Random Multi Battle uses doubles move pools, but Ally Switch fails in multi battles
|
|
1551
1551
|
// Random Free-For-All also uses doubles move pools, for now
|
|
@@ -1767,8 +1767,10 @@ class RandomTeams {
|
|
|
1767
1767
|
forme = 'Pikachu' + this.sample(['', '-Original', '-Hoenn', '-Sinnoh', '-Unova', '-Kalos', '-Alola', '-Partner', '-World']);
|
|
1768
1768
|
}
|
|
1769
1769
|
let level;
|
|
1770
|
+
// doubles levelling
|
|
1770
1771
|
if (isDoubles && species.randomDoubleBattleLevel) {
|
|
1771
1772
|
level = species.randomDoubleBattleLevel;
|
|
1773
|
+
// No Dmax levelling
|
|
1772
1774
|
}
|
|
1773
1775
|
else if (isNoDynamax) {
|
|
1774
1776
|
const tier = species.name.endsWith('-Gmax') ? this.dex.species.get(species.changesFrom).tier : species.tier;
|
|
@@ -1795,9 +1797,29 @@ class RandomTeams {
|
|
|
1795
1797
|
decidueye: 87, noivern: 85, magnezone: 82, slowking: 81,
|
|
1796
1798
|
};
|
|
1797
1799
|
level = customScale[species.id] || tierScale[tier];
|
|
1800
|
+
// BDSP tier levelling
|
|
1801
|
+
}
|
|
1802
|
+
else if (this.dex.currentMod === 'gen8bdsp') {
|
|
1803
|
+
const tierScale = {
|
|
1804
|
+
Uber: 76,
|
|
1805
|
+
OU: 80,
|
|
1806
|
+
UUBL: 81,
|
|
1807
|
+
UU: 82,
|
|
1808
|
+
RUBL: 83,
|
|
1809
|
+
RU: 84,
|
|
1810
|
+
NUBL: 85,
|
|
1811
|
+
NU: 86,
|
|
1812
|
+
PUBL: 87,
|
|
1813
|
+
PU: 88, "(PU)": 88, NFE: 88,
|
|
1814
|
+
};
|
|
1815
|
+
// to override tier scaling if needed
|
|
1816
|
+
const customScale = {};
|
|
1817
|
+
level = customScale[species.id] || tierScale[species.tier];
|
|
1818
|
+
// Arbitrary levelling base on data files (typically winrate-influenced)
|
|
1798
1819
|
}
|
|
1799
1820
|
else if (species.randomBattleLevel) {
|
|
1800
1821
|
level = species.randomBattleLevel;
|
|
1822
|
+
// Default to level 80
|
|
1801
1823
|
}
|
|
1802
1824
|
else {
|
|
1803
1825
|
level = 80;
|
|
@@ -1807,7 +1829,7 @@ class RandomTeams {
|
|
|
1807
1829
|
const srWeakness = srImmunity ? 0 : this.dex.getEffectiveness('Rock', species);
|
|
1808
1830
|
while (evs.hp > 1) {
|
|
1809
1831
|
const hp = Math.floor(Math.floor(2 * species.baseStats.hp + ivs.hp + Math.floor(evs.hp / 4) + 100) * level / 100 + 10);
|
|
1810
|
-
const multipleOfFourNecessary = (moves.has('substitute') && (item === 'Sitrus Berry' ||
|
|
1832
|
+
const multipleOfFourNecessary = (moves.has('substitute') && !['Leftovers', 'Black Sludge'].includes(item) && (item === 'Sitrus Berry' ||
|
|
1811
1833
|
item === 'Salac Berry' ||
|
|
1812
1834
|
ability === 'Power Construct'));
|
|
1813
1835
|
if (multipleOfFourNecessary) {
|
|
@@ -1835,7 +1857,13 @@ class RandomTeams {
|
|
|
1835
1857
|
if (moves.has('shellsidearm') && item === 'Choice Specs')
|
|
1836
1858
|
evs.atk -= 8;
|
|
1837
1859
|
// Minimize confusion damage
|
|
1838
|
-
|
|
1860
|
+
const noAttackStatMoves = [...moves].every(m => {
|
|
1861
|
+
const move = this.dex.moves.get(m);
|
|
1862
|
+
if (move.damageCallback || move.damage)
|
|
1863
|
+
return false;
|
|
1864
|
+
return move.category !== 'Physical' || move.id === 'bodypress';
|
|
1865
|
+
});
|
|
1866
|
+
if (noAttackStatMoves && !moves.has('transform') && (!moves.has('shellsidearm') || !counter.get('Status'))) {
|
|
1839
1867
|
evs.atk = 0;
|
|
1840
1868
|
ivs.atk = 0;
|
|
1841
1869
|
}
|
|
@@ -1863,8 +1891,7 @@ class RandomTeams {
|
|
|
1863
1891
|
getPokemonPool(type, pokemonToExclude = [], isMonotype = false) {
|
|
1864
1892
|
const exclude = pokemonToExclude.map(p => (0, sim_1.toID)(p.species));
|
|
1865
1893
|
const pokemonPool = [];
|
|
1866
|
-
for (
|
|
1867
|
-
let species = this.dex.species.get(id);
|
|
1894
|
+
for (let species of this.dex.species.all()) {
|
|
1868
1895
|
if (species.gen > this.gen || exclude.includes(species.id))
|
|
1869
1896
|
continue;
|
|
1870
1897
|
if (isMonotype) {
|
|
@@ -1876,7 +1903,7 @@ class RandomTeams {
|
|
|
1876
1903
|
continue;
|
|
1877
1904
|
}
|
|
1878
1905
|
}
|
|
1879
|
-
pokemonPool.push(id);
|
|
1906
|
+
pokemonPool.push(species.id);
|
|
1880
1907
|
}
|
|
1881
1908
|
return pokemonPool;
|
|
1882
1909
|
}
|