@pkmn/randoms 0.9.5 → 0.9.7
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/index.js +240 -10
- package/build/index.js.map +1 -1
- package/build/index.mjs +240 -10
- package/build/index.mjs.map +1 -1
- package/package.json +2 -2
package/build/index.mjs
CHANGED
|
@@ -43,14 +43,16 @@ function sortBy(array, callback) {
|
|
|
43
43
|
return array.sort((a, b) => compare(callback(a), callback(b)));
|
|
44
44
|
}
|
|
45
45
|
var Multiset = class extends Map {
|
|
46
|
-
|
|
46
|
+
get(key) {
|
|
47
47
|
var _a;
|
|
48
|
-
|
|
48
|
+
return (_a = super.get(key)) != null ? _a : 0;
|
|
49
|
+
}
|
|
50
|
+
add(key) {
|
|
51
|
+
this.set(key, this.get(key) + 1);
|
|
49
52
|
return this;
|
|
50
53
|
}
|
|
51
54
|
remove(key) {
|
|
52
|
-
|
|
53
|
-
const newValue = ((_a = this.get(key)) != null ? _a : 0) - 1;
|
|
55
|
+
const newValue = this.get(key) - 1;
|
|
54
56
|
if (newValue <= 0)
|
|
55
57
|
return this.delete(key);
|
|
56
58
|
this.set(key, newValue);
|
|
@@ -72,9 +74,6 @@ var MoveCounter = class extends Utils.Multiset {
|
|
|
72
74
|
this.damagingMoves = /* @__PURE__ */ new Set();
|
|
73
75
|
this.setupType = "";
|
|
74
76
|
}
|
|
75
|
-
get(key) {
|
|
76
|
-
return super.get(key) || 0;
|
|
77
|
-
}
|
|
78
77
|
};
|
|
79
78
|
var RECOVERY_MOVES = [
|
|
80
79
|
"healorder",
|
|
@@ -10452,9 +10451,6 @@ var MoveCounter2 = class extends Utils.Multiset {
|
|
|
10452
10451
|
this.damagingMoves = /* @__PURE__ */ new Set();
|
|
10453
10452
|
this.ironFist = 0;
|
|
10454
10453
|
}
|
|
10455
|
-
get(key) {
|
|
10456
|
-
return super.get(key) || 0;
|
|
10457
|
-
}
|
|
10458
10454
|
};
|
|
10459
10455
|
var RECOVERY_MOVES8 = [
|
|
10460
10456
|
"healorder",
|
|
@@ -10671,6 +10667,7 @@ var RandomTeams = class {
|
|
|
10671
10667
|
constructor(dex, format, prng) {
|
|
10672
10668
|
this.randomSets = randomSetsJSON7;
|
|
10673
10669
|
this.randomDoublesSets = randomDoublesSetsJSON;
|
|
10670
|
+
this.randomBSSFactorySets = {};
|
|
10674
10671
|
this.dex = dex;
|
|
10675
10672
|
this.gen = this.dex.gen;
|
|
10676
10673
|
this.noStab = NO_STAB8;
|
|
@@ -13017,6 +13014,239 @@ var RandomTeams = class {
|
|
|
13017
13014
|
}
|
|
13018
13015
|
return team;
|
|
13019
13016
|
}
|
|
13017
|
+
randomBSSFactorySet(species, teamData) {
|
|
13018
|
+
var _a;
|
|
13019
|
+
const id = toID5(species.name);
|
|
13020
|
+
const setList = this.randomBSSFactorySets[id].sets;
|
|
13021
|
+
const movesMax = {
|
|
13022
|
+
batonpass: 1,
|
|
13023
|
+
stealthrock: 1,
|
|
13024
|
+
toxicspikes: 1,
|
|
13025
|
+
trickroom: 1,
|
|
13026
|
+
auroraveil: 1
|
|
13027
|
+
};
|
|
13028
|
+
const weatherAbilities = ["drizzle", "drought", "snowwarning", "sandstream"];
|
|
13029
|
+
const terrainAbilities = {
|
|
13030
|
+
electricsurge: "electric",
|
|
13031
|
+
psychicsurge: "psychic",
|
|
13032
|
+
grassysurge: "grassy",
|
|
13033
|
+
seedsower: "grassy",
|
|
13034
|
+
mistysurge: "misty"
|
|
13035
|
+
};
|
|
13036
|
+
const terrainItemsRequire = {
|
|
13037
|
+
electricseed: "electric",
|
|
13038
|
+
psychicseed: "psychic",
|
|
13039
|
+
grassyseed: "grassy",
|
|
13040
|
+
mistyseed: "misty"
|
|
13041
|
+
};
|
|
13042
|
+
const maxWantsTera = 2;
|
|
13043
|
+
const effectivePool = [];
|
|
13044
|
+
for (const curSet of setList) {
|
|
13045
|
+
let reject = false;
|
|
13046
|
+
if (curSet.wantsTera && teamData.wantsTeraCount && teamData.wantsTeraCount >= maxWantsTera) {
|
|
13047
|
+
continue;
|
|
13048
|
+
}
|
|
13049
|
+
if (teamData.weather && weatherAbilities.includes(curSet.ability)) {
|
|
13050
|
+
continue;
|
|
13051
|
+
}
|
|
13052
|
+
if (terrainAbilities[curSet.ability]) {
|
|
13053
|
+
if (!teamData.terrain)
|
|
13054
|
+
teamData.terrain = [];
|
|
13055
|
+
teamData.terrain.push(terrainAbilities[curSet.ability]);
|
|
13056
|
+
}
|
|
13057
|
+
for (const item of curSet.item) {
|
|
13058
|
+
if (terrainItemsRequire[item] && !((_a = teamData.terrain) == null ? void 0 : _a.includes(terrainItemsRequire[item]))) {
|
|
13059
|
+
reject = true;
|
|
13060
|
+
break;
|
|
13061
|
+
}
|
|
13062
|
+
}
|
|
13063
|
+
const curSetMoveVariants = [];
|
|
13064
|
+
for (const move of curSet.moves) {
|
|
13065
|
+
const variantIndex = this.random(move.length);
|
|
13066
|
+
const moveId = toID5(move[variantIndex]);
|
|
13067
|
+
if (movesMax[moveId] && teamData.has[moveId] >= movesMax[moveId]) {
|
|
13068
|
+
reject = true;
|
|
13069
|
+
break;
|
|
13070
|
+
}
|
|
13071
|
+
curSetMoveVariants.push(variantIndex);
|
|
13072
|
+
}
|
|
13073
|
+
if (reject)
|
|
13074
|
+
continue;
|
|
13075
|
+
const set = { set: curSet, moveVariants: curSetMoveVariants };
|
|
13076
|
+
effectivePool.push(set);
|
|
13077
|
+
}
|
|
13078
|
+
if (!effectivePool.length) {
|
|
13079
|
+
if (!teamData.forceResult)
|
|
13080
|
+
return null;
|
|
13081
|
+
for (const curSet of setList) {
|
|
13082
|
+
effectivePool.push({ set: curSet });
|
|
13083
|
+
}
|
|
13084
|
+
}
|
|
13085
|
+
let setData = this.sample(effectivePool);
|
|
13086
|
+
const total = effectivePool.reduce((a, b) => a + b.set.weight, 0);
|
|
13087
|
+
const setRand = this.random(total);
|
|
13088
|
+
let cur = 0;
|
|
13089
|
+
for (const set of effectivePool) {
|
|
13090
|
+
cur += set.set.weight;
|
|
13091
|
+
if (cur > setRand) {
|
|
13092
|
+
setData = set;
|
|
13093
|
+
break;
|
|
13094
|
+
}
|
|
13095
|
+
}
|
|
13096
|
+
const moves = [];
|
|
13097
|
+
for (const [i, moveSlot] of setData.set.moves.entries()) {
|
|
13098
|
+
moves.push(setData.moveVariants ? moveSlot[setData.moveVariants[i]] : this.sample(moveSlot));
|
|
13099
|
+
}
|
|
13100
|
+
return {
|
|
13101
|
+
name: setData.set.species || species.baseSpecies,
|
|
13102
|
+
species: setData.set.species,
|
|
13103
|
+
teraType: this.sampleIfArray(setData.set.teraType),
|
|
13104
|
+
gender: setData.set.gender || species.gender || (this.randomChance(1, 2) ? "M" : "F"),
|
|
13105
|
+
item: this.sampleIfArray(setData.set.item) || "",
|
|
13106
|
+
ability: this.sampleIfArray(setData.set.ability),
|
|
13107
|
+
shiny: this.randomChance(1, 1024),
|
|
13108
|
+
level: 50,
|
|
13109
|
+
happiness: 255,
|
|
13110
|
+
evs: { hp: 0, atk: 0, def: 0, spa: 0, spd: 0, spe: 0, ...setData.set.evs },
|
|
13111
|
+
ivs: { hp: 31, atk: 31, def: 31, spa: 31, spd: 31, spe: 31, ...setData.set.ivs },
|
|
13112
|
+
nature: setData.set.nature || "Serious",
|
|
13113
|
+
moves,
|
|
13114
|
+
wantsTera: setData.set.wantsTera
|
|
13115
|
+
};
|
|
13116
|
+
}
|
|
13117
|
+
randomBSSFactoryTeam(side, depth = 0) {
|
|
13118
|
+
var _a;
|
|
13119
|
+
this.enforceNoDirectCustomBanlistChanges();
|
|
13120
|
+
const forceResult = depth >= 4;
|
|
13121
|
+
const pokemon = [];
|
|
13122
|
+
const pokemonPool = Object.keys(this.randomBSSFactorySets);
|
|
13123
|
+
const teamData = {
|
|
13124
|
+
typeCount: {},
|
|
13125
|
+
typeComboCount: {},
|
|
13126
|
+
baseFormes: {},
|
|
13127
|
+
has: {},
|
|
13128
|
+
wantsTeraCount: 0,
|
|
13129
|
+
forceResult,
|
|
13130
|
+
weaknesses: {},
|
|
13131
|
+
resistances: {}
|
|
13132
|
+
};
|
|
13133
|
+
const weatherAbilitiesSet = {
|
|
13134
|
+
drizzle: "raindance",
|
|
13135
|
+
drought: "sunnyday",
|
|
13136
|
+
snowwarning: "hail",
|
|
13137
|
+
sandstream: "sandstorm"
|
|
13138
|
+
};
|
|
13139
|
+
const resistanceAbilities = {
|
|
13140
|
+
waterabsorb: ["Water"],
|
|
13141
|
+
flashfire: ["Fire"],
|
|
13142
|
+
lightningrod: ["Electric"],
|
|
13143
|
+
voltabsorb: ["Electric"],
|
|
13144
|
+
thickfat: ["Ice", "Fire"],
|
|
13145
|
+
levitate: ["Ground"]
|
|
13146
|
+
};
|
|
13147
|
+
const limitFactor = Math.ceil(this.maxTeamSize / 6);
|
|
13148
|
+
const shuffledSpecies = [];
|
|
13149
|
+
for (const speciesName of pokemonPool) {
|
|
13150
|
+
const sortObject = {
|
|
13151
|
+
speciesName,
|
|
13152
|
+
score: Math.pow(this.prng.next(), 1 / this.randomBSSFactorySets[speciesName].weight)
|
|
13153
|
+
};
|
|
13154
|
+
shuffledSpecies.push(sortObject);
|
|
13155
|
+
}
|
|
13156
|
+
shuffledSpecies.sort((a, b) => a.score - b.score);
|
|
13157
|
+
while (shuffledSpecies.length && pokemon.length < this.maxTeamSize) {
|
|
13158
|
+
const species = this.dex.species.get(shuffledSpecies.pop().speciesName);
|
|
13159
|
+
if (!species.exists)
|
|
13160
|
+
continue;
|
|
13161
|
+
if (this.forceMonotype && !species.types.includes(this.forceMonotype))
|
|
13162
|
+
continue;
|
|
13163
|
+
if (teamData.baseFormes[species.baseSpecies])
|
|
13164
|
+
continue;
|
|
13165
|
+
const types = species.types;
|
|
13166
|
+
let skip = false;
|
|
13167
|
+
if (!this.forceMonotype) {
|
|
13168
|
+
for (const type of types) {
|
|
13169
|
+
if (teamData.typeCount[type] >= 2 * limitFactor && this.randomChance(4, 5)) {
|
|
13170
|
+
skip = true;
|
|
13171
|
+
break;
|
|
13172
|
+
}
|
|
13173
|
+
}
|
|
13174
|
+
}
|
|
13175
|
+
if (skip)
|
|
13176
|
+
continue;
|
|
13177
|
+
const set = this.randomBSSFactorySet(species, teamData);
|
|
13178
|
+
if (!set)
|
|
13179
|
+
continue;
|
|
13180
|
+
let typeCombo = types.slice().sort().join();
|
|
13181
|
+
if (set.ability === "Drought" || set.ability === "Drizzle") {
|
|
13182
|
+
typeCombo = set.ability;
|
|
13183
|
+
}
|
|
13184
|
+
if (!this.forceMonotype && teamData.typeComboCount[typeCombo] >= limitFactor)
|
|
13185
|
+
continue;
|
|
13186
|
+
const itemData = this.dex.items.get(set.item);
|
|
13187
|
+
if (teamData.has[itemData.id])
|
|
13188
|
+
continue;
|
|
13189
|
+
pokemon.push(set);
|
|
13190
|
+
for (const type of types) {
|
|
13191
|
+
if (type in teamData.typeCount) {
|
|
13192
|
+
teamData.typeCount[type]++;
|
|
13193
|
+
} else {
|
|
13194
|
+
teamData.typeCount[type] = 1;
|
|
13195
|
+
}
|
|
13196
|
+
}
|
|
13197
|
+
if (typeCombo in teamData.typeComboCount) {
|
|
13198
|
+
teamData.typeComboCount[typeCombo]++;
|
|
13199
|
+
} else {
|
|
13200
|
+
teamData.typeComboCount[typeCombo] = 1;
|
|
13201
|
+
}
|
|
13202
|
+
teamData.baseFormes[species.baseSpecies] = 1;
|
|
13203
|
+
teamData.has[itemData.id] = 1;
|
|
13204
|
+
if (set.wantsTera) {
|
|
13205
|
+
if (!teamData.wantsTeraCount)
|
|
13206
|
+
teamData.wantsTeraCount = 0;
|
|
13207
|
+
teamData.wantsTeraCount++;
|
|
13208
|
+
}
|
|
13209
|
+
const abilityState = this.dex.abilities.get(set.ability);
|
|
13210
|
+
if (abilityState.id in weatherAbilitiesSet) {
|
|
13211
|
+
teamData.weather = weatherAbilitiesSet[abilityState.id];
|
|
13212
|
+
}
|
|
13213
|
+
for (const move of set.moves) {
|
|
13214
|
+
const moveId = toID5(move);
|
|
13215
|
+
if (moveId in teamData.has) {
|
|
13216
|
+
teamData.has[moveId]++;
|
|
13217
|
+
} else {
|
|
13218
|
+
teamData.has[moveId] = 1;
|
|
13219
|
+
}
|
|
13220
|
+
}
|
|
13221
|
+
for (const typeName of this.dex.types.names()) {
|
|
13222
|
+
if (teamData.resistances[typeName] >= 1)
|
|
13223
|
+
continue;
|
|
13224
|
+
if (((_a = resistanceAbilities[abilityState.id]) == null ? void 0 : _a.includes(typeName)) || !this.dex.getImmunity(typeName, types)) {
|
|
13225
|
+
teamData.resistances[typeName] = (teamData.resistances[typeName] || 0) + 1;
|
|
13226
|
+
if (teamData.resistances[typeName] >= 1)
|
|
13227
|
+
teamData.weaknesses[typeName] = 0;
|
|
13228
|
+
continue;
|
|
13229
|
+
}
|
|
13230
|
+
const typeMod = this.dex.getEffectiveness(typeName, types);
|
|
13231
|
+
if (typeMod < 0) {
|
|
13232
|
+
teamData.resistances[typeName] = (teamData.resistances[typeName] || 0) + 1;
|
|
13233
|
+
if (teamData.resistances[typeName] >= 1)
|
|
13234
|
+
teamData.weaknesses[typeName] = 0;
|
|
13235
|
+
} else if (typeMod > 0) {
|
|
13236
|
+
teamData.weaknesses[typeName] = (teamData.weaknesses[typeName] || 0) + 1;
|
|
13237
|
+
}
|
|
13238
|
+
}
|
|
13239
|
+
}
|
|
13240
|
+
if (!teamData.forceResult && pokemon.length < this.maxTeamSize)
|
|
13241
|
+
return this.randomBSSFactoryTeam(side, ++depth);
|
|
13242
|
+
if (!teamData.forceResult && !this.forceMonotype) {
|
|
13243
|
+
for (const type in teamData.weaknesses) {
|
|
13244
|
+
if (teamData.weaknesses[type] >= 3 * limitFactor)
|
|
13245
|
+
return this.randomBSSFactoryTeam(side, ++depth);
|
|
13246
|
+
}
|
|
13247
|
+
}
|
|
13248
|
+
return pokemon;
|
|
13249
|
+
}
|
|
13020
13250
|
};
|
|
13021
13251
|
|
|
13022
13252
|
// src/index.ts
|