@pkmn/randoms 0.6.3 → 0.7.0
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.d.ts +5 -3
- package/build/index.js +8036 -33
- package/build/index.js.map +1 -1
- package/build/index.mjs +8039 -0
- package/build/index.mjs.map +1 -0
- package/package.json +8 -9
- package/build/gen1.d.ts +0 -43
- package/build/gen1.js +0 -447
- package/build/gen1.js.map +0 -1
- package/build/gen2.d.ts +0 -13
- package/build/gen2.js +0 -289
- package/build/gen2.js.map +0 -1
- package/build/gen3.d.ts +0 -17
- package/build/gen3.js +0 -621
- package/build/gen3.js.map +0 -1
- package/build/gen4.d.ts +0 -16
- package/build/gen4.js +0 -724
- package/build/gen4.js.map +0 -1
- package/build/gen5.d.ts +0 -16
- package/build/gen5.js +0 -842
- package/build/gen5.js.map +0 -1
- package/build/gen6.d.ts +0 -23
- package/build/gen6.js +0 -1216
- package/build/gen6.js.map +0 -1
- package/build/gen7.d.ts +0 -43
- package/build/gen7.js +0 -2022
- package/build/gen7.js.map +0 -1
- package/build/gen8.d.ts +0 -154
- package/build/gen8.js +0 -2919
- package/build/gen8.js.map +0 -1
- package/build/utils.d.ts +0 -43
- package/build/utils.js +0 -70
- package/build/utils.js.map +0 -1
- package/src/gen1.ts +0 -493
- package/src/gen2.ts +0 -323
- package/src/gen3.ts +0 -688
- package/src/gen4.ts +0 -858
- package/src/gen5.ts +0 -916
- package/src/gen6.ts +0 -1357
- package/src/gen7.ts +0 -2194
- package/src/gen8.ts +0 -3121
- package/src/global.d.ts +0 -6
- package/src/index.ts +0 -46
- package/src/utils.ts +0 -78
package/build/gen5.js
DELETED
|
@@ -1,842 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.RandomGen5Teams = void 0;
|
|
4
|
-
const gen6_1 = require("./gen6");
|
|
5
|
-
const utils_1 = require("./utils");
|
|
6
|
-
const sim_1 = require("@pkmn/sim");
|
|
7
|
-
class RandomGen5Teams extends gen6_1.RandomGen6Teams {
|
|
8
|
-
constructor(dex, format, prng) {
|
|
9
|
-
super(dex, format, prng);
|
|
10
|
-
this.moveEnforcementCheckers = {
|
|
11
|
-
lead: (movePool, moves, abilities, types, counter) => (movePool.includes('stealthrock') &&
|
|
12
|
-
!!counter.get('Status') &&
|
|
13
|
-
!counter.setupType &&
|
|
14
|
-
!counter.get('speedsetup') &&
|
|
15
|
-
!moves.has('substitute')),
|
|
16
|
-
Dark: (movePool, moves, abilities, types, counter) => !counter.get('Dark'),
|
|
17
|
-
Dragon: (movePool, moves, abilities, types, counter) => !counter.get('Dragon'),
|
|
18
|
-
Electric: (movePool, moves, abilities, types, counter) => !counter.get('Electric') || movePool.includes('thunder'),
|
|
19
|
-
Fighting: (movePool, moves, abilities, types, counter, species) => (!counter.get('Fighting') &&
|
|
20
|
-
(species.baseStats.atk >= 90 || abilities.has('Pure Power') || !!counter.setupType || !counter.get('Status'))),
|
|
21
|
-
Fire: (movePool, moves, abilities, types, counter) => !counter.get('Fire'),
|
|
22
|
-
Flying: (movePool, moves, abilities, types, counter) => (!counter.get('Flying') && (types.has('Normal') || abilities.has('Serene Grace'))),
|
|
23
|
-
Ghost: (movePool, moves, abilities, types, counter) => !types.has('Dark') && !counter.get('Ghost'),
|
|
24
|
-
Grass: movePool => movePool.includes('hornleech') || movePool.includes('seedflare'),
|
|
25
|
-
Ground: (movePool, moves, abilities, types, counter) => (!counter.get('Ground') && !moves.has('rest') && !moves.has('sleeptalk')),
|
|
26
|
-
Ice: (movePool, moves, abilities, types, counter) => !counter.get('Ice'),
|
|
27
|
-
Normal: (movePool, moves, abilities, types, counter, species) => (movePool.includes('return') && species.baseStats.atk > 80),
|
|
28
|
-
Rock: (movePool, moves, abilities, types, counter, species) => !counter.get('Rock') && species.baseStats.atk >= 80,
|
|
29
|
-
Steel: (movePool, moves, abilities, types, counter) => !counter.get('Steel') && abilities.has('Technician'),
|
|
30
|
-
Water: (movePool, moves, abilities, types, counter) => (!counter.get('Water') || (abilities.has('Adaptability') && movePool.includes('waterfall'))),
|
|
31
|
-
Contrary: (movePool, moves, abilities, types, counter, species, teamDetails) => (!counter.get('contrary') && species.name !== 'Shuckle'),
|
|
32
|
-
Guts: (movePool, moves, abilities, types) => types.has('Normal') && movePool.includes('facade'),
|
|
33
|
-
'Slow Start': movePool => movePool.includes('substitute'),
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
shouldCullMove(move, types, moves, abilities, counter, movePool, teamDetails, species, isLead) {
|
|
37
|
-
const hasRestTalk = moves.has('rest') && moves.has('sleeptalk');
|
|
38
|
-
switch (move.id) {
|
|
39
|
-
// Not very useful without their supporting moves
|
|
40
|
-
case 'batonpass':
|
|
41
|
-
return { cull: !counter.setupType && !counter.get('speedsetup') && !moves.has('substitute') && !moves.has('wish') };
|
|
42
|
-
case 'endeavor':
|
|
43
|
-
return { cull: !isLead };
|
|
44
|
-
case 'focuspunch':
|
|
45
|
-
return { cull: !moves.has('substitute') || counter.damagingMoves.size < 2 || moves.has('swordsdance') };
|
|
46
|
-
case 'rest':
|
|
47
|
-
return { cull: movePool.includes('sleeptalk') };
|
|
48
|
-
case 'sleeptalk':
|
|
49
|
-
if (movePool.length > 1) {
|
|
50
|
-
const rest = movePool.indexOf('rest');
|
|
51
|
-
if (rest >= 0)
|
|
52
|
-
this.fastPop(movePool, rest);
|
|
53
|
-
}
|
|
54
|
-
return { cull: !moves.has('rest') };
|
|
55
|
-
case 'storedpower':
|
|
56
|
-
return { cull: !counter.setupType && !moves.has('cosmicpower') };
|
|
57
|
-
case 'weatherball':
|
|
58
|
-
return { cull: !moves.has('sunnyday') };
|
|
59
|
-
// Set up once and only if we have the moves for it
|
|
60
|
-
case 'bellydrum':
|
|
61
|
-
case 'bulkup':
|
|
62
|
-
case 'coil':
|
|
63
|
-
case 'curse':
|
|
64
|
-
case 'dragondance':
|
|
65
|
-
case 'honeclaws':
|
|
66
|
-
case 'swordsdance':
|
|
67
|
-
return { cull: (counter.setupType !== 'Physical' || counter.get('physicalsetup') > 1 || (counter.get('Physical') + counter.get('physicalpool') < 2 &&
|
|
68
|
-
!moves.has('batonpass') &&
|
|
69
|
-
!hasRestTalk)), isSetup: true };
|
|
70
|
-
case 'calmmind':
|
|
71
|
-
case 'nastyplot':
|
|
72
|
-
case 'tailglow':
|
|
73
|
-
return { cull: (counter.setupType !== 'Special' || counter.get('specialsetup') > 1 || (counter.get('Special') + counter.get('specialpool') < 2 &&
|
|
74
|
-
!moves.has('batonpass') &&
|
|
75
|
-
!hasRestTalk)), isSetup: true };
|
|
76
|
-
case 'growth':
|
|
77
|
-
case 'shellsmash':
|
|
78
|
-
case 'workup':
|
|
79
|
-
const moveTotal = counter.damagingMoves.size + counter.get('physicalpool') + counter.get('specialpool');
|
|
80
|
-
return {
|
|
81
|
-
cull: (counter.setupType !== 'Mixed' ||
|
|
82
|
-
counter.get('mixedsetup') > 1 ||
|
|
83
|
-
moveTotal < 2 ||
|
|
84
|
-
(move.id === 'growth' && !moves.has('sunnyday'))),
|
|
85
|
-
isSetup: true,
|
|
86
|
-
};
|
|
87
|
-
case 'agility':
|
|
88
|
-
case 'autotomize':
|
|
89
|
-
case 'rockpolish':
|
|
90
|
-
return {
|
|
91
|
-
cull: ((counter.damagingMoves.size < 2 && !counter.setupType && !moves.has('batonpass')) ||
|
|
92
|
-
hasRestTalk),
|
|
93
|
-
isSetup: !counter.setupType,
|
|
94
|
-
};
|
|
95
|
-
// Bad after setup
|
|
96
|
-
case 'bulletpunch':
|
|
97
|
-
return { cull: !!counter.get('speedsetup') };
|
|
98
|
-
case 'circlethrow':
|
|
99
|
-
case 'dragontail':
|
|
100
|
-
return { cull: moves.has('substitute') || (!!counter.setupType && !moves.has('rest') && !moves.has('sleeptalk')) };
|
|
101
|
-
case 'fakeout':
|
|
102
|
-
case 'healingwish':
|
|
103
|
-
return { cull: !!counter.setupType || !!counter.get('recovery') || moves.has('substitute') };
|
|
104
|
-
case 'haze':
|
|
105
|
-
case 'magiccoat':
|
|
106
|
-
case 'pursuit':
|
|
107
|
-
case 'spikes':
|
|
108
|
-
return { cull: !!counter.setupType || !!counter.get('speedsetup') || moves.has('rest') || moves.has('trickroom') };
|
|
109
|
-
case 'leechseed':
|
|
110
|
-
case 'roar':
|
|
111
|
-
case 'whirlwind':
|
|
112
|
-
return { cull: !!counter.setupType || !!counter.get('speedsetup') || moves.has('dragontail') };
|
|
113
|
-
case 'nightshade':
|
|
114
|
-
case 'seismictoss':
|
|
115
|
-
case 'superfang':
|
|
116
|
-
return { cull: !!counter.setupType || counter.damagingMoves.size > 1 };
|
|
117
|
-
case 'protect':
|
|
118
|
-
return { cull: (moves.has('rest') ||
|
|
119
|
-
(counter.setupType && !abilities.has('Speed Boost') && !moves.has('wish')) ||
|
|
120
|
-
moves.has('lightscreen') && moves.has('reflect')) };
|
|
121
|
-
case 'rapidspin':
|
|
122
|
-
return { cull: moves.has('shellsmash') || (!!counter.setupType && counter.get('Status') >= 2) };
|
|
123
|
-
case 'stealthrock':
|
|
124
|
-
return { cull: !!counter.setupType || !!counter.get('speedsetup') || moves.has('rest') || !!teamDetails.stealthRock };
|
|
125
|
-
case 'switcheroo':
|
|
126
|
-
case 'trick':
|
|
127
|
-
return { cull: (counter.get('Physical') + counter.get('Special') < 3 ||
|
|
128
|
-
!!counter.get('priority') ||
|
|
129
|
-
moves.has('rapidspin')) };
|
|
130
|
-
case 'toxic':
|
|
131
|
-
return { cull: !!counter.setupType || !!counter.get('speedsetup') || moves.has('trickroom') };
|
|
132
|
-
case 'toxicspikes':
|
|
133
|
-
return { cull: !!counter.setupType || !!teamDetails.toxicSpikes };
|
|
134
|
-
case 'trickroom':
|
|
135
|
-
return { cull: (!!counter.setupType ||
|
|
136
|
-
!!counter.get('speedsetup') ||
|
|
137
|
-
counter.damagingMoves.size < 2 ||
|
|
138
|
-
moves.has('lightscreen') || moves.has('reflect')) };
|
|
139
|
-
case 'uturn':
|
|
140
|
-
// Infernape doesn't want mixed sets with U-turn
|
|
141
|
-
const infernapeCase = species.id === 'infernape' && !!counter.get('Special');
|
|
142
|
-
return { cull: !!counter.setupType || !!counter.get('speedsetup') || moves.has('batonpass') || infernapeCase };
|
|
143
|
-
case 'voltswitch':
|
|
144
|
-
return { cull: (!!counter.setupType ||
|
|
145
|
-
!!counter.get('speedsetup') ||
|
|
146
|
-
['batonpass', 'magnetrise', 'uturn'].some(m => moves.has(m))) };
|
|
147
|
-
// Ineffective having both
|
|
148
|
-
// Attacks:
|
|
149
|
-
case 'bugbite':
|
|
150
|
-
return { cull: moves.has('uturn') };
|
|
151
|
-
case 'crunch':
|
|
152
|
-
return { cull: !types.has('Dark') && moves.has('suckerpunch') };
|
|
153
|
-
case 'dragonpulse':
|
|
154
|
-
case 'spacialrend':
|
|
155
|
-
return { cull: moves.has('dracometeor') || moves.has('outrage') };
|
|
156
|
-
case 'thunderbolt':
|
|
157
|
-
return { cull: moves.has('wildcharge') };
|
|
158
|
-
case 'drainpunch':
|
|
159
|
-
case 'focusblast':
|
|
160
|
-
return { cull: moves.has('closecombat') || moves.has('lowkick') };
|
|
161
|
-
case 'blueflare':
|
|
162
|
-
case 'flareblitz':
|
|
163
|
-
case 'fierydance':
|
|
164
|
-
case 'flamethrower':
|
|
165
|
-
case 'lavaplume':
|
|
166
|
-
return { cull: ['fireblast', 'overheat', 'vcreate'].some(m => moves.has(m)) };
|
|
167
|
-
case 'bravebird':
|
|
168
|
-
case 'pluck':
|
|
169
|
-
return { cull: moves.has('acrobatics') || moves.has('hurricane') };
|
|
170
|
-
case 'gigadrain':
|
|
171
|
-
return { cull: (!counter.setupType && moves.has('leafstorm')) || moves.has('petaldance') || moves.has('powerwhip') };
|
|
172
|
-
case 'solarbeam':
|
|
173
|
-
return { cull: (!abilities.has('Drought') && !moves.has('sunnyday')) || moves.has('gigadrain') };
|
|
174
|
-
case 'leafstorm':
|
|
175
|
-
return { cull: !!counter.setupType && moves.has('gigadrain') };
|
|
176
|
-
case 'bonemerang':
|
|
177
|
-
case 'earthpower':
|
|
178
|
-
return { cull: moves.has('earthquake') };
|
|
179
|
-
case 'extremespeed':
|
|
180
|
-
case 'headsmash':
|
|
181
|
-
return { cull: moves.has('roost') };
|
|
182
|
-
case 'facade':
|
|
183
|
-
return { cull: moves.has('suckerpunch') && !types.has('Normal') };
|
|
184
|
-
case 'judgment':
|
|
185
|
-
return { cull: counter.setupType !== 'Special' && counter.get('stab') > 1 };
|
|
186
|
-
case 'return':
|
|
187
|
-
return { cull: moves.has('doubleedge') };
|
|
188
|
-
case 'poisonjab':
|
|
189
|
-
return { cull: moves.has('gunkshot') };
|
|
190
|
-
case 'psychic':
|
|
191
|
-
return { cull: moves.has('psyshock') };
|
|
192
|
-
case 'scald':
|
|
193
|
-
case 'surf':
|
|
194
|
-
return { cull: moves.has('hydropump') || moves.has('waterfall') };
|
|
195
|
-
case 'waterspout':
|
|
196
|
-
return { cull: !!counter.get('Status') };
|
|
197
|
-
// Status:
|
|
198
|
-
case 'encore':
|
|
199
|
-
case 'icepunch':
|
|
200
|
-
case 'raindance':
|
|
201
|
-
case 'suckerpunch':
|
|
202
|
-
return { cull: moves.has('thunderwave') || hasRestTalk };
|
|
203
|
-
case 'glare':
|
|
204
|
-
case 'headbutt':
|
|
205
|
-
return { cull: moves.has('bodyslam') };
|
|
206
|
-
case 'healbell':
|
|
207
|
-
return { cull: !!counter.get('speedsetup') || moves.has('magiccoat') };
|
|
208
|
-
case 'moonlight':
|
|
209
|
-
case 'painsplit':
|
|
210
|
-
case 'recover':
|
|
211
|
-
case 'roost':
|
|
212
|
-
case 'softboiled':
|
|
213
|
-
case 'synthesis':
|
|
214
|
-
return { cull: ['leechseed', 'rest', 'wish'].some(m => moves.has(m)) };
|
|
215
|
-
case 'substitute':
|
|
216
|
-
return { cull: ((moves.has('doubleedge') && !abilities.has('rockhead')) ||
|
|
217
|
-
['pursuit', 'rest', 'superpower', 'uturn', 'voltswitch'].some(m => moves.has(m))) };
|
|
218
|
-
case 'thunderwave':
|
|
219
|
-
return { cull: (!!counter.setupType ||
|
|
220
|
-
!!counter.get('speedsetup') ||
|
|
221
|
-
hasRestTalk ||
|
|
222
|
-
moves.has('discharge') || moves.has('trickroom')) };
|
|
223
|
-
case 'willowisp':
|
|
224
|
-
return { cull: moves.has('lavaplume') || moves.has('scald') && !types.has('Ghost') };
|
|
225
|
-
}
|
|
226
|
-
return { cull: false };
|
|
227
|
-
}
|
|
228
|
-
shouldCullAbility(ability, types, moves, abilities, counter, movePool, teamDetails, species) {
|
|
229
|
-
switch (ability) {
|
|
230
|
-
case 'Anger Point':
|
|
231
|
-
case 'Gluttony':
|
|
232
|
-
case 'Keen Eye':
|
|
233
|
-
case 'Moody':
|
|
234
|
-
case 'Sand Veil':
|
|
235
|
-
case 'Snow Cloak':
|
|
236
|
-
case 'Steadfast':
|
|
237
|
-
case 'Weak Armor':
|
|
238
|
-
return true;
|
|
239
|
-
case 'Analytic':
|
|
240
|
-
case 'Download':
|
|
241
|
-
case 'Hyper Cutter':
|
|
242
|
-
return species.nfe;
|
|
243
|
-
case 'Chlorophyll':
|
|
244
|
-
case 'Solar Power':
|
|
245
|
-
return (!moves.has('sunnyday') && !teamDetails.sun);
|
|
246
|
-
case 'Compound Eyes':
|
|
247
|
-
case 'No Guard':
|
|
248
|
-
return !counter.get('inaccurate');
|
|
249
|
-
case 'Contrary':
|
|
250
|
-
case 'Iron Fist':
|
|
251
|
-
case 'Skill Link':
|
|
252
|
-
return !counter.get((0, sim_1.toID)(ability));
|
|
253
|
-
case 'Defiant':
|
|
254
|
-
case 'Moxie':
|
|
255
|
-
return (!counter.get('Physical') && !moves.has('batonpass'));
|
|
256
|
-
case 'Flash Fire':
|
|
257
|
-
return abilities.has('Drought');
|
|
258
|
-
case 'Hydration':
|
|
259
|
-
case 'Rain Dish':
|
|
260
|
-
case 'Swift Swim':
|
|
261
|
-
return (!moves.has('raindance') && !teamDetails.rain);
|
|
262
|
-
case 'Hustle':
|
|
263
|
-
return counter.get('Physical') < 2;
|
|
264
|
-
case 'Ice Body':
|
|
265
|
-
return !teamDetails.hail;
|
|
266
|
-
case 'Immunity':
|
|
267
|
-
return abilities.has('Toxic Boost');
|
|
268
|
-
case 'Intimidate':
|
|
269
|
-
return moves.has('rest') || species.id === 'staraptor';
|
|
270
|
-
case 'Lightning Rod':
|
|
271
|
-
return species.types.includes('Ground');
|
|
272
|
-
case 'Limber':
|
|
273
|
-
return species.types.includes('Electric');
|
|
274
|
-
case 'Mold Breaker':
|
|
275
|
-
return (abilities.has('Adaptability') || moves.has('rest') && moves.has('sleeptalk'));
|
|
276
|
-
case 'Overgrow':
|
|
277
|
-
return !counter.get('Grass');
|
|
278
|
-
case 'Poison Heal':
|
|
279
|
-
return (abilities.has('Technician') && !!counter.get('technician'));
|
|
280
|
-
case 'Prankster':
|
|
281
|
-
return !counter.get('Status');
|
|
282
|
-
case 'Pressure':
|
|
283
|
-
case 'Synchronize':
|
|
284
|
-
return (counter.get('Status') < 2 || abilities.has('Trace'));
|
|
285
|
-
case 'Reckless':
|
|
286
|
-
case 'Rock Head':
|
|
287
|
-
return (!counter.get('recoil') || abilities.has('Sap Sipper'));
|
|
288
|
-
case 'Regenerator':
|
|
289
|
-
return abilities.has('Magic Guard');
|
|
290
|
-
case 'Sand Force':
|
|
291
|
-
case 'Sand Rush':
|
|
292
|
-
return !teamDetails.sand;
|
|
293
|
-
case 'Serene Grace':
|
|
294
|
-
return (!counter.get('serenegrace') || species.id === 'blissey');
|
|
295
|
-
case 'Sheer Force':
|
|
296
|
-
return (!counter.get('sheerforce') || abilities.has('Guts'));
|
|
297
|
-
case 'Sturdy':
|
|
298
|
-
return (!!counter.get('recoil') && !counter.get('recovery'));
|
|
299
|
-
case 'Swarm':
|
|
300
|
-
return !counter.get('Bug');
|
|
301
|
-
case 'Technician':
|
|
302
|
-
return (!counter.get('technician') || moves.has('tailslap'));
|
|
303
|
-
case 'Tinted Lens':
|
|
304
|
-
return (abilities.has('Insomnia') || abilities.has('Magic Guard') || moves.has('protect'));
|
|
305
|
-
case 'Unaware':
|
|
306
|
-
return (!!counter.setupType || abilities.has('Magic Guard'));
|
|
307
|
-
case 'Unburden':
|
|
308
|
-
return species.baseStats.spe > 100 && !moves.has('acrobatics');
|
|
309
|
-
case 'Water Absorb':
|
|
310
|
-
return (abilities.has('Drizzle') || abilities.has('Unaware') || abilities.has('Volt Absorb'));
|
|
311
|
-
}
|
|
312
|
-
return false;
|
|
313
|
-
}
|
|
314
|
-
getHighPriorityItem(ability, types, moves, counter, teamDetails, species, isLead) {
|
|
315
|
-
if (species.requiredItem)
|
|
316
|
-
return species.requiredItem;
|
|
317
|
-
if (species.requiredItems)
|
|
318
|
-
return this.sample(species.requiredItems);
|
|
319
|
-
if (species.name === 'Marowak')
|
|
320
|
-
return 'Thick Club';
|
|
321
|
-
if (species.name === 'Farfetch\u2019d')
|
|
322
|
-
return 'Stick';
|
|
323
|
-
if (species.name === 'Pikachu')
|
|
324
|
-
return 'Light Ball';
|
|
325
|
-
if (species.name === 'Shedinja' || species.name === 'Smeargle')
|
|
326
|
-
return 'Focus Sash';
|
|
327
|
-
if (species.name === 'Unown')
|
|
328
|
-
return 'Choice Specs';
|
|
329
|
-
if (species.name === 'Wobbuffet' && moves.has('destinybond') && this.randomChance(1, 2))
|
|
330
|
-
return 'Custap Berry';
|
|
331
|
-
if (ability === 'Imposter')
|
|
332
|
-
return 'Choice Scarf';
|
|
333
|
-
if (moves.has('switcheroo') || moves.has('trick')) {
|
|
334
|
-
if (species.baseStats.spe >= 60 && species.baseStats.spe <= 108 && !counter.get('priority')) {
|
|
335
|
-
return 'Choice Scarf';
|
|
336
|
-
}
|
|
337
|
-
else {
|
|
338
|
-
return (counter.get('Physical') > counter.get('Special')) ? 'Choice Band' : 'Choice Specs';
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
if (species.nfe)
|
|
342
|
-
return 'Eviolite';
|
|
343
|
-
if (moves.has('shellsmash'))
|
|
344
|
-
return 'White Herb';
|
|
345
|
-
if (ability === 'Harvest' || moves.has('bellydrum'))
|
|
346
|
-
return 'Sitrus Berry';
|
|
347
|
-
if ((ability === 'Magic Guard' || ability === 'Sheer Force') && counter.damagingMoves.size > 1)
|
|
348
|
-
return 'Life Orb';
|
|
349
|
-
if (ability === 'Poison Heal' ||
|
|
350
|
-
ability === 'Toxic Boost' ||
|
|
351
|
-
(ability === 'Quick Feet' && moves.has('facade')) ||
|
|
352
|
-
moves.has('psychoshift')) {
|
|
353
|
-
return 'Toxic Orb';
|
|
354
|
-
}
|
|
355
|
-
if (moves.has('rest') && !moves.has('sleeptalk') && ability !== 'Natural Cure' && ability !== 'Shed Skin') {
|
|
356
|
-
return 'Chesto Berry';
|
|
357
|
-
}
|
|
358
|
-
if (ability === 'Guts' && moves.has('facade')) {
|
|
359
|
-
return (types.has('Fire') || moves.has('uturn') || moves.has('voltswitch')) ? 'Toxic Orb' : 'Flame Orb';
|
|
360
|
-
}
|
|
361
|
-
if (moves.has('raindance'))
|
|
362
|
-
return (ability === 'Forecast') ? 'Damp Rock' : 'Life Orb';
|
|
363
|
-
if (moves.has('sunnyday'))
|
|
364
|
-
return (ability === 'Forecast' || ability === 'Flower Gift') ? 'Heat Rock' : 'Life Orb';
|
|
365
|
-
if (moves.has('lightscreen') && moves.has('reflect'))
|
|
366
|
-
return 'Light Clay';
|
|
367
|
-
if (moves.has('acrobatics'))
|
|
368
|
-
return 'Flying Gem';
|
|
369
|
-
if (ability === 'Unburden')
|
|
370
|
-
return moves.has('fakeout') ? 'Normal Gem' : `${species.types[0]} Gem`;
|
|
371
|
-
}
|
|
372
|
-
getLowPriorityItem(ability, types, moves, abilities, counter, teamDetails, species, isLead) {
|
|
373
|
-
if (ability === 'Speed Boost' &&
|
|
374
|
-
!moves.has('substitute') &&
|
|
375
|
-
counter.get('Physical') + counter.get('Special') > 2) {
|
|
376
|
-
return 'Life Orb';
|
|
377
|
-
}
|
|
378
|
-
if (counter.get('Physical') >= 4 &&
|
|
379
|
-
['dragontail', 'fakeout', 'flamecharge'].every(m => !moves.has(m)) &&
|
|
380
|
-
!moves.has('suckerpunch') &&
|
|
381
|
-
(!moves.has('rapidspin') || this.dex.getEffectiveness('Rock', species) < 1)) {
|
|
382
|
-
return ((species.baseStats.atk >= 100 || abilities.has('Huge Power')) &&
|
|
383
|
-
species.baseStats.spe >= 60 && species.baseStats.spe <= 108 &&
|
|
384
|
-
!counter.get('priority') &&
|
|
385
|
-
this.randomChance(2, 3)) ? 'Choice Scarf' : 'Choice Band';
|
|
386
|
-
}
|
|
387
|
-
if (counter.get('Special') >= 4 || (counter.get('Special') >= 3 && moves.has('uturn'))) {
|
|
388
|
-
return (species.baseStats.spa >= 100 &&
|
|
389
|
-
species.baseStats.spe >= 60 && species.baseStats.spe <= 108 &&
|
|
390
|
-
!moves.has('uturn') &&
|
|
391
|
-
(ability === 'Download' || moves.has('eruption') || moves.has('waterspout') || this.randomChance(2, 3))) ? 'Choice Scarf' : 'Choice Specs';
|
|
392
|
-
}
|
|
393
|
-
if (counter.setupType && moves.has('outrage'))
|
|
394
|
-
return 'Lum Berry';
|
|
395
|
-
if (this.dex.getEffectiveness('Ground', species) >= 2 && ability !== 'Levitate')
|
|
396
|
-
return 'Air Balloon';
|
|
397
|
-
if (types.has('Poison') ||
|
|
398
|
-
['bodyslam', 'dragontail', 'protect', 'scald', 'sleeptalk', 'substitute'].some(m => moves.has(m))) {
|
|
399
|
-
return 'Leftovers';
|
|
400
|
-
}
|
|
401
|
-
if (species.name === 'Palkia' && (moves.has('dracometeor') || moves.has('spacialrend')) && moves.has('hydropump')) {
|
|
402
|
-
return 'Lustrous Orb';
|
|
403
|
-
}
|
|
404
|
-
if (counter.damagingMoves.size >= 4 && ability !== 'Sturdy') {
|
|
405
|
-
return moves.has('uturn') ? 'Expert Belt' : 'Life Orb';
|
|
406
|
-
}
|
|
407
|
-
if (isLead &&
|
|
408
|
-
counter.get('hazards') &&
|
|
409
|
-
!counter.get('recovery') &&
|
|
410
|
-
ability !== 'Regenerator' &&
|
|
411
|
-
species.baseStats.hp + species.baseStats.def + species.baseStats.spd <= 275) {
|
|
412
|
-
return ability === 'Sturdy' ? 'Custap Berry' : 'Focus Sash';
|
|
413
|
-
}
|
|
414
|
-
if (moves.has('voltswitch') && species.baseStats.spe <= 90) {
|
|
415
|
-
return 'Leftovers';
|
|
416
|
-
}
|
|
417
|
-
if (counter.damagingMoves.size >= 3 &&
|
|
418
|
-
species.baseStats.spe >= 40 &&
|
|
419
|
-
species.baseStats.hp + species.baseStats.def + species.baseStats.spd <= 275 &&
|
|
420
|
-
ability !== 'Sturdy' &&
|
|
421
|
-
!moves.has('rapidspin') && !moves.has('uturn')) {
|
|
422
|
-
return 'Life Orb';
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
randomSet(species, teamDetails = {}, isLead = false) {
|
|
426
|
-
species = this.dex.species.get(species);
|
|
427
|
-
let forme = species.name;
|
|
428
|
-
if (typeof species.battleOnly === 'string') {
|
|
429
|
-
// Only change the forme. The species has custom moves, and may have different typing and requirements.
|
|
430
|
-
forme = species.battleOnly;
|
|
431
|
-
}
|
|
432
|
-
if (species.cosmeticFormes) {
|
|
433
|
-
forme = this.sample([species.name].concat(species.cosmeticFormes));
|
|
434
|
-
}
|
|
435
|
-
const movePool = (species.randomBattleMoves || Object.keys(this.dex.species.getLearnset(species.id))).slice();
|
|
436
|
-
const rejectedPool = [];
|
|
437
|
-
const moves = new Set();
|
|
438
|
-
let ability = '';
|
|
439
|
-
const evs = { hp: 85, atk: 85, def: 85, spa: 85, spd: 85, spe: 85 };
|
|
440
|
-
const ivs = { hp: 31, atk: 31, def: 31, spa: 31, spd: 31, spe: 31 };
|
|
441
|
-
const types = new Set(species.types);
|
|
442
|
-
const abilities = new Set(Object.values(species.abilities));
|
|
443
|
-
if (species.unreleasedHidden)
|
|
444
|
-
abilities.delete(species.abilities.H);
|
|
445
|
-
let availableHP = 0;
|
|
446
|
-
for (const setMoveid of movePool) {
|
|
447
|
-
if (setMoveid.startsWith('hiddenpower'))
|
|
448
|
-
availableHP++;
|
|
449
|
-
}
|
|
450
|
-
let counter;
|
|
451
|
-
// We use a special variable to track Hidden Power
|
|
452
|
-
// so that we can check for all Hidden Powers at once
|
|
453
|
-
let hasHiddenPower = false;
|
|
454
|
-
do {
|
|
455
|
-
// Choose next 4 moves from learnset/viable moves and add them to moves list:
|
|
456
|
-
while (moves.size < this.maxMoveCount && movePool.length) {
|
|
457
|
-
const moveid = this.sampleNoReplace(movePool);
|
|
458
|
-
if (moveid.startsWith('hiddenpower')) {
|
|
459
|
-
availableHP--;
|
|
460
|
-
if (hasHiddenPower)
|
|
461
|
-
continue;
|
|
462
|
-
hasHiddenPower = true;
|
|
463
|
-
}
|
|
464
|
-
moves.add(moveid);
|
|
465
|
-
}
|
|
466
|
-
while (moves.size < this.maxMoveCount && rejectedPool.length) {
|
|
467
|
-
const moveid = this.sampleNoReplace(rejectedPool);
|
|
468
|
-
if (moveid.startsWith('hiddenpower')) {
|
|
469
|
-
if (hasHiddenPower) {
|
|
470
|
-
continue;
|
|
471
|
-
}
|
|
472
|
-
hasHiddenPower = true;
|
|
473
|
-
}
|
|
474
|
-
moves.add(moveid);
|
|
475
|
-
}
|
|
476
|
-
counter = this.queryMoves(moves, species.types, abilities, movePool);
|
|
477
|
-
// Iterate through the moves again, this time to cull them:
|
|
478
|
-
for (const moveid of moves) {
|
|
479
|
-
const move = this.dex.moves.get(moveid);
|
|
480
|
-
let { cull, isSetup } = this.shouldCullMove(move, types, moves, abilities, counter, movePool, teamDetails, species, isLead);
|
|
481
|
-
// This move doesn't satisfy our setup requirements:
|
|
482
|
-
if ((move.category === 'Physical' && counter.setupType === 'Special') ||
|
|
483
|
-
(move.category === 'Special' && counter.setupType === 'Physical')) {
|
|
484
|
-
// Reject STABs last in case the setup type changes later on
|
|
485
|
-
const stabs = counter.get(species.types[0]) + (counter.get(species.types[1]) || 0);
|
|
486
|
-
if (!types.has(move.type) || stabs > 1 || counter.get(move.category) < 2)
|
|
487
|
-
cull = true;
|
|
488
|
-
}
|
|
489
|
-
if (!isSetup &&
|
|
490
|
-
counter.setupType &&
|
|
491
|
-
counter.setupType !== 'Mixed' &&
|
|
492
|
-
move.category !== counter.setupType &&
|
|
493
|
-
counter.get(counter.setupType) < 2 &&
|
|
494
|
-
!moves.has('batonpass') &&
|
|
495
|
-
(move.category !== 'Status' || !move.flags.heal) &&
|
|
496
|
-
moveid !== 'sleeptalk' && (move.category !== 'Status' || (counter.get(counter.setupType) + counter.get('Status') > 3 &&
|
|
497
|
-
counter.get('physicalsetup') + counter.get('specialsetup') < 2))) {
|
|
498
|
-
// Mono-attacking with setup and RestTalk is allowed
|
|
499
|
-
// Reject Status moves only if there is nothing else to reject
|
|
500
|
-
cull = true;
|
|
501
|
-
}
|
|
502
|
-
if (counter.setupType === 'Special' &&
|
|
503
|
-
moveid === 'hiddenpower' &&
|
|
504
|
-
species.types.length > 1 &&
|
|
505
|
-
counter.get('Special') <= 2 &&
|
|
506
|
-
!types.has(move.type) &&
|
|
507
|
-
!counter.get('Physical') &&
|
|
508
|
-
counter.get('specialpool')) {
|
|
509
|
-
// Hidden Power isn't good enough
|
|
510
|
-
cull = true;
|
|
511
|
-
}
|
|
512
|
-
const runEnforcementChecker = (checkerName) => {
|
|
513
|
-
if (!this.moveEnforcementCheckers[checkerName])
|
|
514
|
-
return false;
|
|
515
|
-
return this.moveEnforcementCheckers[checkerName](movePool, moves, abilities, types, counter, species, teamDetails);
|
|
516
|
-
};
|
|
517
|
-
// Pokemon should have moves that benefit their Type/Ability/Weather, as well as moves required by its forme
|
|
518
|
-
if (!cull &&
|
|
519
|
-
!['judgment', 'quiverdance', 'sleeptalk'].includes(moveid) &&
|
|
520
|
-
!isSetup && !move.weather && !move.damage && (move.category !== 'Status' || !move.flags.heal) && (move.category === 'Status' ||
|
|
521
|
-
!types.has(move.type) ||
|
|
522
|
-
move.basePower && move.basePower < 40 && !move.multihit) && (counter.get('physicalsetup') + counter.get('specialsetup') < 2 && (!counter.setupType ||
|
|
523
|
-
counter.setupType === 'Mixed' ||
|
|
524
|
-
(move.category !== counter.setupType && move.category !== 'Status') ||
|
|
525
|
-
counter.get(counter.setupType) + counter.get('Status') > 3))) {
|
|
526
|
-
if ((!counter.get('stab') &&
|
|
527
|
-
!counter.get('damage') && (species.types.length > 1 ||
|
|
528
|
-
(species.types[0] !== 'Normal' && species.types[0] !== 'Psychic') ||
|
|
529
|
-
!moves.has('icebeam') ||
|
|
530
|
-
species.baseStats.spa >= species.baseStats.spd)) || (!counter.get('recovery') &&
|
|
531
|
-
!counter.setupType &&
|
|
532
|
-
!moves.has('healingwish') &&
|
|
533
|
-
(counter.get('Status') > 1 || (species.nfe && !!counter.get('Status'))) &&
|
|
534
|
-
(movePool.includes('recover') || movePool.includes('roost') || movePool.includes('softboiled'))) || (movePool.includes('darkvoid') ||
|
|
535
|
-
movePool.includes('quiverdance') ||
|
|
536
|
-
(species.requiredMove && movePool.includes((0, sim_1.toID)(species.requiredMove)))) || (isLead && runEnforcementChecker('lead'))) {
|
|
537
|
-
cull = true;
|
|
538
|
-
}
|
|
539
|
-
else {
|
|
540
|
-
for (const type of types) {
|
|
541
|
-
if (runEnforcementChecker(type)) {
|
|
542
|
-
cull = true;
|
|
543
|
-
}
|
|
544
|
-
}
|
|
545
|
-
for (const abil of abilities) {
|
|
546
|
-
if (runEnforcementChecker(abil)) {
|
|
547
|
-
cull = true;
|
|
548
|
-
}
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
|
-
// Sleep Talk shouldn't be selected without Rest
|
|
553
|
-
if (moveid === 'rest' && cull) {
|
|
554
|
-
const sleeptalk = movePool.indexOf('sleeptalk');
|
|
555
|
-
if (sleeptalk >= 0) {
|
|
556
|
-
if (movePool.length < 2) {
|
|
557
|
-
cull = false;
|
|
558
|
-
}
|
|
559
|
-
else {
|
|
560
|
-
this.fastPop(movePool, sleeptalk);
|
|
561
|
-
}
|
|
562
|
-
}
|
|
563
|
-
}
|
|
564
|
-
// Remove rejected moves from the move list
|
|
565
|
-
const isHP = moveid.startsWith('hiddenpower');
|
|
566
|
-
if (cull &&
|
|
567
|
-
(movePool.length - availableHP || availableHP && (isHP || !hasHiddenPower))) {
|
|
568
|
-
if (move.category !== 'Status' && !move.damage && !move.flags.charge &&
|
|
569
|
-
(!isHP || !availableHP))
|
|
570
|
-
rejectedPool.push(moveid);
|
|
571
|
-
moves.delete(moveid);
|
|
572
|
-
if (isHP)
|
|
573
|
-
hasHiddenPower = false;
|
|
574
|
-
break;
|
|
575
|
-
}
|
|
576
|
-
if (cull && rejectedPool.length) {
|
|
577
|
-
moves.delete(moveid);
|
|
578
|
-
if (moveid.startsWith('hiddenpower'))
|
|
579
|
-
hasHiddenPower = false;
|
|
580
|
-
break;
|
|
581
|
-
}
|
|
582
|
-
}
|
|
583
|
-
} while (moves.size < this.maxMoveCount && (movePool.length || rejectedPool.length));
|
|
584
|
-
if (hasHiddenPower) {
|
|
585
|
-
let hpType;
|
|
586
|
-
for (const move of moves) {
|
|
587
|
-
if (move.startsWith('hiddenpower'))
|
|
588
|
-
hpType = move.substr(11);
|
|
589
|
-
}
|
|
590
|
-
if (!hpType)
|
|
591
|
-
throw new Error(`hasHiddenPower is true, but no Hidden Power move was found.`);
|
|
592
|
-
const HPivs = this.dex.types.get(hpType).HPivs;
|
|
593
|
-
let iv;
|
|
594
|
-
for (iv in HPivs) {
|
|
595
|
-
ivs[iv] = HPivs[iv];
|
|
596
|
-
}
|
|
597
|
-
}
|
|
598
|
-
const abilityData = Array.from(abilities).map(a => this.dex.abilities.get(a));
|
|
599
|
-
utils_1.Utils.sortBy(abilityData, abil => -abil.rating);
|
|
600
|
-
if (abilityData.length > 1) {
|
|
601
|
-
// Sort abilities by rating with an element of randomness
|
|
602
|
-
if (abilityData[2] && abilityData[1].rating <= abilityData[2].rating && this.randomChance(1, 2)) {
|
|
603
|
-
[abilityData[1], abilityData[2]] = [abilityData[2], abilityData[1]];
|
|
604
|
-
}
|
|
605
|
-
if (abilityData[0].rating <= abilityData[1].rating) {
|
|
606
|
-
if (this.randomChance(1, 2))
|
|
607
|
-
[abilityData[0], abilityData[1]] = [abilityData[1], abilityData[0]];
|
|
608
|
-
}
|
|
609
|
-
else if (abilityData[0].rating - 0.6 <= abilityData[1].rating) {
|
|
610
|
-
if (this.randomChance(2, 3))
|
|
611
|
-
[abilityData[0], abilityData[1]] = [abilityData[1], abilityData[0]];
|
|
612
|
-
}
|
|
613
|
-
// Start with the first abiility and work our way through, culling as we go
|
|
614
|
-
ability = abilityData[0].name;
|
|
615
|
-
while (this.shouldCullAbility(ability, types, moves, abilities, counter, movePool, teamDetails, species)) {
|
|
616
|
-
if (ability === abilityData[0].name && abilityData[1].rating >= 1) {
|
|
617
|
-
ability = abilityData[1].name;
|
|
618
|
-
}
|
|
619
|
-
else if (ability === abilityData[1].name && abilityData[2] && abilityData[2].rating >= 1) {
|
|
620
|
-
ability = abilityData[2].name;
|
|
621
|
-
}
|
|
622
|
-
else {
|
|
623
|
-
ability = abilityData[0].name;
|
|
624
|
-
break;
|
|
625
|
-
}
|
|
626
|
-
}
|
|
627
|
-
if (abilities.has('Guts') && moves.has('facade') && (ability !== 'Quick Feet' || !counter.setupType)) {
|
|
628
|
-
ability = 'Guts';
|
|
629
|
-
}
|
|
630
|
-
else if (abilities.has('Prankster') && counter.get('Status') > 1) {
|
|
631
|
-
ability = 'Prankster';
|
|
632
|
-
}
|
|
633
|
-
else if (abilities.has('Quick Feet') && moves.has('facade')) {
|
|
634
|
-
ability = 'Quick Feet';
|
|
635
|
-
}
|
|
636
|
-
else if (abilities.has('Swift Swim') && moves.has('raindance')) {
|
|
637
|
-
ability = 'Swift Swim';
|
|
638
|
-
}
|
|
639
|
-
}
|
|
640
|
-
else {
|
|
641
|
-
ability = abilityData[0].name;
|
|
642
|
-
}
|
|
643
|
-
let item = this.getHighPriorityItem(ability, types, moves, counter, teamDetails, species, isLead);
|
|
644
|
-
if (item === undefined) {
|
|
645
|
-
item = this.getLowPriorityItem(ability, types, moves, abilities, counter, teamDetails, species, isLead);
|
|
646
|
-
}
|
|
647
|
-
if (item === undefined)
|
|
648
|
-
item = 'Leftovers';
|
|
649
|
-
if (item === 'Leftovers' && types.has('Poison')) {
|
|
650
|
-
item = 'Black Sludge';
|
|
651
|
-
}
|
|
652
|
-
const levelScale = {
|
|
653
|
-
Uber: 76,
|
|
654
|
-
OU: 80,
|
|
655
|
-
'(OU)': 82,
|
|
656
|
-
UUBL: 82,
|
|
657
|
-
UU: 82,
|
|
658
|
-
RUBL: 84,
|
|
659
|
-
RU: 84,
|
|
660
|
-
NUBL: 86,
|
|
661
|
-
NU: 86,
|
|
662
|
-
'(NU)': 88,
|
|
663
|
-
PUBL: 88,
|
|
664
|
-
PU: 88,
|
|
665
|
-
'(PU)': 90,
|
|
666
|
-
};
|
|
667
|
-
const customScale = {
|
|
668
|
-
Delibird: 100, 'Farfetch\u2019d': 100, Luvdisc: 100, Unown: 100,
|
|
669
|
-
};
|
|
670
|
-
const level = this.adjustLevel || customScale[species.name] || levelScale[species.tier] || (species.nfe ? 90 : 80);
|
|
671
|
-
// Prepare optimal HP
|
|
672
|
-
const srWeakness = this.dex.getEffectiveness('Rock', species);
|
|
673
|
-
while (evs.hp > 1) {
|
|
674
|
-
const hp = Math.floor(Math.floor(2 * species.baseStats.hp + (ivs.hp || 31) + Math.floor(evs.hp / 4) + 100) * level / 100 + 10);
|
|
675
|
-
if (moves.has('bellydrum') && item === 'Sitrus Berry') {
|
|
676
|
-
// Belly Drum should activate Sitrus Berry
|
|
677
|
-
if (hp % 2 === 0)
|
|
678
|
-
break;
|
|
679
|
-
}
|
|
680
|
-
else {
|
|
681
|
-
// Maximize number of Stealth Rock switch-ins
|
|
682
|
-
if (srWeakness <= 0 || hp % (4 / srWeakness) > 0)
|
|
683
|
-
break;
|
|
684
|
-
}
|
|
685
|
-
evs.hp -= 4;
|
|
686
|
-
}
|
|
687
|
-
// Minimize confusion damage
|
|
688
|
-
if (!counter.get('Physical') && !moves.has('transform')) {
|
|
689
|
-
evs.atk = 0;
|
|
690
|
-
ivs.atk = hasHiddenPower ? (ivs.atk || 31) - 28 : 0;
|
|
691
|
-
}
|
|
692
|
-
if (['gyroball', 'metalburst', 'trickroom'].some(m => moves.has(m))) {
|
|
693
|
-
evs.spe = 0;
|
|
694
|
-
ivs.spe = hasHiddenPower ? (ivs.spe || 31) - 28 : 0;
|
|
695
|
-
}
|
|
696
|
-
return {
|
|
697
|
-
name: species.baseSpecies,
|
|
698
|
-
species: forme,
|
|
699
|
-
gender: species.gender,
|
|
700
|
-
shiny: this.randomChance(1, 1024),
|
|
701
|
-
moves: Array.from(moves),
|
|
702
|
-
ability,
|
|
703
|
-
evs,
|
|
704
|
-
ivs,
|
|
705
|
-
item,
|
|
706
|
-
level,
|
|
707
|
-
};
|
|
708
|
-
}
|
|
709
|
-
randomTeam() {
|
|
710
|
-
this.enforceNoDirectCustomBanlistChanges();
|
|
711
|
-
const seed = this.prng.seed;
|
|
712
|
-
const ruleTable = this.dex.formats.getRuleTable(this.format);
|
|
713
|
-
const pokemon = [];
|
|
714
|
-
// For Monotype
|
|
715
|
-
const isMonotype = !!this.forceMonotype || ruleTable.has('sametypeclause');
|
|
716
|
-
const typePool = this.dex.types.names();
|
|
717
|
-
const type = this.forceMonotype || this.sample(typePool);
|
|
718
|
-
const baseFormes = {};
|
|
719
|
-
const tierCount = {};
|
|
720
|
-
const typeCount = {};
|
|
721
|
-
const typeComboCount = {};
|
|
722
|
-
const teamDetails = {};
|
|
723
|
-
const pokemonPool = this.getPokemonPool(type, pokemon, isMonotype);
|
|
724
|
-
while (pokemonPool.length && pokemon.length < this.maxTeamSize) {
|
|
725
|
-
const species = this.dex.species.get(this.sampleNoReplace(pokemonPool));
|
|
726
|
-
if (!species.exists || !species.randomBattleMoves)
|
|
727
|
-
continue;
|
|
728
|
-
// Limit to one of each species (Species Clause)
|
|
729
|
-
if (baseFormes[species.baseSpecies])
|
|
730
|
-
continue;
|
|
731
|
-
// Adjust rate for species with multiple sets
|
|
732
|
-
switch (species.baseSpecies) {
|
|
733
|
-
case 'Arceus':
|
|
734
|
-
if (this.randomChance(16, 17) && !isMonotype)
|
|
735
|
-
continue;
|
|
736
|
-
break;
|
|
737
|
-
case 'Rotom':
|
|
738
|
-
if (this.gen < 5 && this.randomChance(5, 6) && !isMonotype)
|
|
739
|
-
continue;
|
|
740
|
-
break;
|
|
741
|
-
case 'Basculin':
|
|
742
|
-
case 'Castform':
|
|
743
|
-
case 'Cherrim':
|
|
744
|
-
case 'Meloetta':
|
|
745
|
-
if (this.randomChance(1, 2))
|
|
746
|
-
continue;
|
|
747
|
-
break;
|
|
748
|
-
}
|
|
749
|
-
// Illusion shouldn't be in the last slot
|
|
750
|
-
if (species.name === 'Zoroark' && pokemon.length > 4)
|
|
751
|
-
continue;
|
|
752
|
-
// Dynamically scale limits for different team sizes. The default and minimum value is 1.
|
|
753
|
-
const limitFactor = Math.round(this.maxTeamSize / 6) || 1;
|
|
754
|
-
const tier = species.tier;
|
|
755
|
-
// Limit two Pokemon per tier
|
|
756
|
-
if (this.gen === 5 && !isMonotype && !this.forceMonotype && tierCount[tier] >= 2 * limitFactor)
|
|
757
|
-
continue;
|
|
758
|
-
const set = this.randomSet(species, teamDetails, pokemon.length === 0);
|
|
759
|
-
const types = species.types;
|
|
760
|
-
if (!isMonotype && !this.forceMonotype) {
|
|
761
|
-
// Limit two of any type
|
|
762
|
-
let skip = false;
|
|
763
|
-
for (const typeName of types) {
|
|
764
|
-
if (typeCount[typeName] >= 2 * limitFactor) {
|
|
765
|
-
skip = true;
|
|
766
|
-
break;
|
|
767
|
-
}
|
|
768
|
-
}
|
|
769
|
-
if (skip)
|
|
770
|
-
continue;
|
|
771
|
-
}
|
|
772
|
-
// Limit one of any type combination, two in Monotype
|
|
773
|
-
let typeCombo = types.slice().sort().join();
|
|
774
|
-
if (set.ability === 'Drought' || set.ability === 'Drizzle' || set.ability === 'Sand Stream') {
|
|
775
|
-
// Drought, Drizzle and Sand Stream don't count towards the type combo limit
|
|
776
|
-
typeCombo = set.ability;
|
|
777
|
-
if (typeCombo in typeComboCount)
|
|
778
|
-
continue;
|
|
779
|
-
}
|
|
780
|
-
else if (!this.forceMonotype) {
|
|
781
|
-
if (typeComboCount[typeCombo] >= (isMonotype ? 2 : 1) * limitFactor)
|
|
782
|
-
continue;
|
|
783
|
-
}
|
|
784
|
-
// Okay, the set passes, add it to our team
|
|
785
|
-
pokemon.push(set);
|
|
786
|
-
if (pokemon.length === this.maxTeamSize) {
|
|
787
|
-
// Set Zoroark's level to be the same as the last Pokemon
|
|
788
|
-
const illusion = teamDetails.illusion;
|
|
789
|
-
if (illusion)
|
|
790
|
-
pokemon[illusion - 1].level = pokemon[this.maxTeamSize - 1].level;
|
|
791
|
-
break;
|
|
792
|
-
}
|
|
793
|
-
// Now that our Pokemon has passed all checks, we can increment our counters
|
|
794
|
-
baseFormes[species.baseSpecies] = 1;
|
|
795
|
-
// Increment tier counter
|
|
796
|
-
if (tierCount[tier]) {
|
|
797
|
-
tierCount[tier]++;
|
|
798
|
-
}
|
|
799
|
-
else {
|
|
800
|
-
tierCount[tier] = 1;
|
|
801
|
-
}
|
|
802
|
-
// Increment type counters
|
|
803
|
-
for (const typeName of types) {
|
|
804
|
-
if (typeName in typeCount) {
|
|
805
|
-
typeCount[typeName]++;
|
|
806
|
-
}
|
|
807
|
-
else {
|
|
808
|
-
typeCount[typeName] = 1;
|
|
809
|
-
}
|
|
810
|
-
}
|
|
811
|
-
if (typeCombo in typeComboCount) {
|
|
812
|
-
typeComboCount[typeCombo]++;
|
|
813
|
-
}
|
|
814
|
-
else {
|
|
815
|
-
typeComboCount[typeCombo] = 1;
|
|
816
|
-
}
|
|
817
|
-
// Team details
|
|
818
|
-
if (set.ability === 'Snow Warning' || set.moves.includes('hail'))
|
|
819
|
-
teamDetails.hail = 1;
|
|
820
|
-
if (set.ability === 'Drizzle' || set.moves.includes('raindance'))
|
|
821
|
-
teamDetails.rain = 1;
|
|
822
|
-
if (set.ability === 'Sand Stream')
|
|
823
|
-
teamDetails.sand = 1;
|
|
824
|
-
if (set.moves.includes('stealthrock'))
|
|
825
|
-
teamDetails.stealthRock = 1;
|
|
826
|
-
if (set.moves.includes('toxicspikes'))
|
|
827
|
-
teamDetails.toxicSpikes = 1;
|
|
828
|
-
if (set.moves.includes('rapidspin'))
|
|
829
|
-
teamDetails.rapidSpin = 1;
|
|
830
|
-
// For setting Zoroark's level
|
|
831
|
-
if (set.ability === 'Illusion')
|
|
832
|
-
teamDetails.illusion = pokemon.length;
|
|
833
|
-
}
|
|
834
|
-
if (pokemon.length < this.maxTeamSize && pokemon.length < 12) {
|
|
835
|
-
throw new Error(`Could not build a random team for ${this.format} (seed=${seed})`);
|
|
836
|
-
}
|
|
837
|
-
return pokemon;
|
|
838
|
-
}
|
|
839
|
-
}
|
|
840
|
-
exports.RandomGen5Teams = RandomGen5Teams;
|
|
841
|
-
exports.default = RandomGen5Teams;
|
|
842
|
-
//# sourceMappingURL=gen5.js.map
|