@pkmn/randoms 0.4.24 → 0.5.2
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/gen3.js +14 -0
- package/build/gen3.js.map +1 -1
- package/build/gen4.js +2 -0
- package/build/gen4.js.map +1 -1
- package/build/gen5.js +2 -0
- package/build/gen5.js.map +1 -1
- package/build/gen6.js +5 -1
- package/build/gen6.js.map +1 -1
- package/build/gen7.js +26 -0
- package/build/gen7.js.map +1 -1
- package/build/gen8.js +37 -9
- package/build/gen8.js.map +1 -1
- package/package.json +2 -2
- package/src/gen3.ts +14 -0
- package/src/gen4.ts +1 -0
- package/src/gen5.ts +1 -0
- package/src/gen6.ts +6 -1
- package/src/gen7.ts +29 -0
- package/src/gen8.ts +34 -10
package/src/gen7.ts
CHANGED
|
@@ -9,7 +9,9 @@ import {
|
|
|
9
9
|
PRNGSeed,
|
|
10
10
|
PlayerOptions,
|
|
11
11
|
RandomTeamsTypes,
|
|
12
|
+
SparseStatsTable,
|
|
12
13
|
Species,
|
|
14
|
+
StatID,
|
|
13
15
|
StatsTable,
|
|
14
16
|
toID,
|
|
15
17
|
} from '@pkmn/sim';
|
|
@@ -27,6 +29,19 @@ interface BattleFactorySet {
|
|
|
27
29
|
evs?: Partial<StatsTable>;
|
|
28
30
|
ivs?: Partial<StatsTable>;
|
|
29
31
|
}
|
|
32
|
+
|
|
33
|
+
const ZeroAttackHPIVs: {[k: string]: SparseStatsTable} = {
|
|
34
|
+
grass: {hp: 30, spa: 30},
|
|
35
|
+
fire: {spa: 30, spe: 30},
|
|
36
|
+
ice: {def: 30},
|
|
37
|
+
ground: {spa: 30, spd: 30},
|
|
38
|
+
fighting: {def: 30, spa: 30, spd: 30, spe: 30},
|
|
39
|
+
electric: {def: 30, spe: 30},
|
|
40
|
+
psychic: {spe: 30},
|
|
41
|
+
flying: {spa: 30, spd: 30, spe: 30},
|
|
42
|
+
rock: {def: 30, spd: 30, spe: 30},
|
|
43
|
+
};
|
|
44
|
+
|
|
30
45
|
export class RandomGen7Teams extends RandomTeams {
|
|
31
46
|
constructor(dex: ModdedDex, format: Format, prng: PRNG | PRNGSeed | null) {
|
|
32
47
|
super(dex, format, prng);
|
|
@@ -1423,6 +1438,20 @@ export class RandomGen7Teams extends RandomTeams {
|
|
|
1423
1438
|
ivs.spe = 0;
|
|
1424
1439
|
}
|
|
1425
1440
|
|
|
1441
|
+
// Fix IVs for non-Bottle Cap-able sets
|
|
1442
|
+
if (hasHiddenPower && level < 100) {
|
|
1443
|
+
let hpType;
|
|
1444
|
+
for (const move of moves) {
|
|
1445
|
+
if (move.startsWith('hiddenpower')) hpType = move.substr(11);
|
|
1446
|
+
}
|
|
1447
|
+
if (!hpType) throw new Error(`hasHiddenPower is true, but no Hidden Power move was found.`);
|
|
1448
|
+
const HPivs = ivs.atk === 0 ? ZeroAttackHPIVs[hpType] : this.dex.types.get(hpType).HPivs;
|
|
1449
|
+
let iv: StatID;
|
|
1450
|
+
for (iv in HPivs) {
|
|
1451
|
+
ivs[iv] = HPivs[iv]!;
|
|
1452
|
+
}
|
|
1453
|
+
}
|
|
1454
|
+
|
|
1426
1455
|
return {
|
|
1427
1456
|
name: species.baseSpecies,
|
|
1428
1457
|
species: forme,
|
package/src/gen8.ts
CHANGED
|
@@ -934,7 +934,8 @@ export class RandomTeams {
|
|
|
934
934
|
!!counter.setupType ||
|
|
935
935
|
!!counter.get('speedsetup') ||
|
|
936
936
|
!!teamDetails.stealthRock ||
|
|
937
|
-
['rest', 'substitute', 'trickroom', 'teleport'].some(m => moves.has(m))
|
|
937
|
+
['rest', 'substitute', 'trickroom', 'teleport'].some(m => moves.has(m)) ||
|
|
938
|
+
(species.id === 'palossand' && movePool.includes('shoreup')),
|
|
938
939
|
};
|
|
939
940
|
case 'stickyweb':
|
|
940
941
|
return {cull: counter.setupType === 'Special' || !!teamDetails.stickyWeb};
|
|
@@ -1231,7 +1232,7 @@ export class RandomTeams {
|
|
|
1231
1232
|
isNoDynamax: boolean
|
|
1232
1233
|
): boolean {
|
|
1233
1234
|
if ([
|
|
1234
|
-
'Flare Boost', 'Hydration', 'Ice Body', 'Innards Out', 'Insomnia', 'Misty Surge',
|
|
1235
|
+
'Flare Boost', 'Hydration', 'Ice Body', 'Immunity', 'Innards Out', 'Insomnia', 'Misty Surge',
|
|
1235
1236
|
'Quick Feet', 'Rain Dish', 'Snow Cloak', 'Steadfast', 'Steam Engine',
|
|
1236
1237
|
].includes(ability)) return true;
|
|
1237
1238
|
|
|
@@ -1650,7 +1651,6 @@ export class RandomTeams {
|
|
|
1650
1651
|
!counter.get('drain') && !counter.get('recoil') && !counter.get('recovery') &&
|
|
1651
1652
|
((defensiveStatTotal <= 250 && counter.get('hazards')) || defensiveStatTotal <= 210)
|
|
1652
1653
|
) return 'Focus Sash';
|
|
1653
|
-
if (!isDoubles && ability === 'Water Bubble') return 'Mystic Water';
|
|
1654
1654
|
if (
|
|
1655
1655
|
moves.has('clangoroussoul') ||
|
|
1656
1656
|
// We manually check for speed-boosting moves, rather than using `counter.get('speedsetup')`,
|
|
@@ -1758,12 +1758,19 @@ export class RandomTeams {
|
|
|
1758
1758
|
|
|
1759
1759
|
const moves = new Set<string>();
|
|
1760
1760
|
let counter: MoveCounter;
|
|
1761
|
+
// This is just for BDSP Unown;
|
|
1762
|
+
// it can be removed from this file if BDSP gets its own random-teams file in the future.
|
|
1763
|
+
let hasHiddenPower = false;
|
|
1761
1764
|
|
|
1762
1765
|
do {
|
|
1763
1766
|
// Choose next 4 moves from learnset/viable moves and add them to moves list:
|
|
1764
1767
|
const pool = (movePool.length ? movePool : rejectedPool);
|
|
1765
1768
|
while (moves.size < 4 && pool.length) {
|
|
1766
1769
|
const moveid = this.sampleNoReplace(pool);
|
|
1770
|
+
if (moveid.startsWith('hiddenpower')) {
|
|
1771
|
+
if (hasHiddenPower) continue;
|
|
1772
|
+
hasHiddenPower = true;
|
|
1773
|
+
}
|
|
1767
1774
|
moves.add(moveid);
|
|
1768
1775
|
}
|
|
1769
1776
|
|
|
@@ -1854,17 +1861,33 @@ export class RandomTeams {
|
|
|
1854
1861
|
|
|
1855
1862
|
// Remove rejected moves from the move list
|
|
1856
1863
|
if (cull && movePool.length) {
|
|
1864
|
+
if (moveid.startsWith('hiddenpower')) hasHiddenPower = false;
|
|
1857
1865
|
if (move.category !== 'Status' && !move.damage) rejectedPool.push(moveid);
|
|
1858
1866
|
moves.delete(moveid);
|
|
1859
1867
|
break;
|
|
1860
1868
|
}
|
|
1861
1869
|
if (cull && rejectedPool.length) {
|
|
1870
|
+
if (moveid.startsWith('hiddenpower')) hasHiddenPower = false;
|
|
1862
1871
|
moves.delete(moveid);
|
|
1863
1872
|
break;
|
|
1864
1873
|
}
|
|
1865
1874
|
}
|
|
1866
1875
|
} while (moves.size < 4 && (movePool.length || rejectedPool.length));
|
|
1867
1876
|
|
|
1877
|
+
// for BD/SP only
|
|
1878
|
+
if (hasHiddenPower) {
|
|
1879
|
+
let hpType;
|
|
1880
|
+
for (const move of moves) {
|
|
1881
|
+
if (move.startsWith('hiddenpower')) hpType = move.substr(11);
|
|
1882
|
+
}
|
|
1883
|
+
if (!hpType) throw new Error(`hasHiddenPower is true, but no Hidden Power move was found.`);
|
|
1884
|
+
const HPivs = this.dex.types.get(hpType).HPivs;
|
|
1885
|
+
let iv: StatID;
|
|
1886
|
+
for (iv in HPivs) {
|
|
1887
|
+
ivs[iv] = HPivs[iv]!;
|
|
1888
|
+
}
|
|
1889
|
+
}
|
|
1890
|
+
|
|
1868
1891
|
const abilityData = Array.from(abilities).map(a => this.dex.abilities.get(a));
|
|
1869
1892
|
Utils.sortBy(abilityData, abil => -abil.rating);
|
|
1870
1893
|
|
|
@@ -1973,7 +1996,7 @@ export class RandomTeams {
|
|
|
1973
1996
|
// No Dmax levelling
|
|
1974
1997
|
} else if (isNoDynamax) {
|
|
1975
1998
|
const tier = species.name.endsWith('-Gmax') ? this.dex.species.get(species.changesFrom).tier : species.tier;
|
|
1976
|
-
const tierScale:
|
|
1999
|
+
const tierScale: Partial<Record<Species['tier'], number>> = {
|
|
1977
2000
|
Uber: 76,
|
|
1978
2001
|
OU: 80,
|
|
1979
2002
|
UUBL: 81,
|
|
@@ -1995,11 +2018,11 @@ export class RandomTeams {
|
|
|
1995
2018
|
delibird: 100, vespiquen: 96, pikachu: 92, shedinja: 92, solrock: 90, arctozolt: 88, reuniclus: 87,
|
|
1996
2019
|
decidueye: 87, noivern: 85, magnezone: 82, slowking: 81,
|
|
1997
2020
|
};
|
|
1998
|
-
level = customScale[species.id] || tierScale[tier];
|
|
2021
|
+
level = customScale[species.id] || tierScale[tier] || 80;
|
|
1999
2022
|
// BDSP tier levelling
|
|
2000
2023
|
} else if (this.dex.currentMod === 'gen8bdsp') {
|
|
2001
|
-
const tierScale:
|
|
2002
|
-
Uber: 76,
|
|
2024
|
+
const tierScale: Partial<Record<Species['tier'], number>> = {
|
|
2025
|
+
Uber: 76, Unreleased: 76,
|
|
2003
2026
|
OU: 80,
|
|
2004
2027
|
UUBL: 81,
|
|
2005
2028
|
UU: 82,
|
|
@@ -2010,10 +2033,9 @@ export class RandomTeams {
|
|
|
2010
2033
|
PUBL: 87,
|
|
2011
2034
|
PU: 88, "(PU)": 88, NFE: 88,
|
|
2012
2035
|
};
|
|
2013
|
-
// to override tier scaling if needed
|
|
2014
2036
|
const customScale: {[k: string]: number} = {};
|
|
2015
2037
|
|
|
2016
|
-
level = customScale[species.id] || tierScale[species.tier];
|
|
2038
|
+
level = customScale[species.id] || tierScale[species.tier] || 80;
|
|
2017
2039
|
// Arbitrary levelling base on data files (typically winrate-influenced)
|
|
2018
2040
|
} else if (species.randomBattleLevel) {
|
|
2019
2041
|
level = species.randomBattleLevel;
|
|
@@ -2185,7 +2207,10 @@ export class RandomTeams {
|
|
|
2185
2207
|
const limitFactor = Math.round(this.maxTeamSize / 6) || 1;
|
|
2186
2208
|
|
|
2187
2209
|
// Limit one Pokemon per tier, two for Monotype
|
|
2210
|
+
// This limitation is not applied to BD/SP team generation, because tiering for BD/SP is not yet complete,
|
|
2211
|
+
// meaning that most Pokémon are in OU.
|
|
2188
2212
|
if (
|
|
2213
|
+
this.dex.currentMod !== 'gen8bdsp' &&
|
|
2189
2214
|
(tierCount[tier] >= (this.forceMonotype || isMonotype ? 2 : 1) * limitFactor) &&
|
|
2190
2215
|
!this.randomChance(1, Math.pow(5, tierCount[tier]))
|
|
2191
2216
|
) {
|
|
@@ -2215,7 +2240,6 @@ export class RandomTeams {
|
|
|
2215
2240
|
|
|
2216
2241
|
// Okay, the set passes, add it to our team
|
|
2217
2242
|
pokemon.push(set);
|
|
2218
|
-
|
|
2219
2243
|
if (pokemon.length === this.maxTeamSize) {
|
|
2220
2244
|
// Set Zoroark's level to be the same as the last Pokemon
|
|
2221
2245
|
const illusion = teamDetails.illusion;
|