@pkmn/randoms 0.5.9 → 0.5.12
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 -32
- package/build/gen1.js.map +1 -1
- package/build/gen2.js +4 -6
- package/build/gen2.js.map +1 -1
- package/build/gen3.js +8 -6
- package/build/gen3.js.map +1 -1
- package/build/gen4.js +4 -6
- package/build/gen4.js.map +1 -1
- package/build/gen5.js +5 -6
- package/build/gen5.js.map +1 -1
- package/build/gen6.js +14 -13
- package/build/gen6.js.map +1 -1
- package/build/gen7.js +9 -6
- package/build/gen7.js.map +1 -1
- package/build/gen8.d.ts +3 -0
- package/build/gen8.js +52 -32
- package/build/gen8.js.map +1 -1
- package/package.json +2 -2
- package/src/gen1.ts +38 -29
- package/src/gen2.ts +4 -5
- package/src/gen3.ts +7 -6
- package/src/gen4.ts +4 -5
- package/src/gen5.ts +7 -5
- package/src/gen6.ts +16 -14
- package/src/gen7.ts +8 -6
- package/src/gen8.ts +50 -31
package/src/gen1.ts
CHANGED
|
@@ -41,19 +41,24 @@ export class RandomGen1Teams extends RandomGen2Teams {
|
|
|
41
41
|
mbst += (stats["spd"] * 2 + 30 + 63 + 100) + 5;
|
|
42
42
|
mbst += (stats["spe"] * 2 + 30 + 63 + 100) + 5;
|
|
43
43
|
|
|
44
|
-
let level
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
44
|
+
let level;
|
|
45
|
+
if (this.adjustLevel) {
|
|
46
|
+
level = this.adjustLevel;
|
|
47
|
+
} else {
|
|
48
|
+
level = Math.floor(100 * mbstmin / mbst); // Initial level guess will underestimate
|
|
49
|
+
|
|
50
|
+
while (level < 100) {
|
|
51
|
+
mbst = Math.floor((stats["hp"] * 2 + 30 + 63 + 100) * level / 100 + 10);
|
|
52
|
+
// Since damage is roughly proportional to lvl
|
|
53
|
+
mbst += Math.floor(((stats["atk"] * 2 + 30 + 63 + 100) * level / 100 + 5) * level / 100);
|
|
54
|
+
mbst += Math.floor((stats["def"] * 2 + 30 + 63 + 100) * level / 100 + 5);
|
|
55
|
+
mbst += Math.floor(((stats["spa"] * 2 + 30 + 63 + 100) * level / 100 + 5) * level / 100);
|
|
56
|
+
mbst += Math.floor((stats["spd"] * 2 + 30 + 63 + 100) * level / 100 + 5);
|
|
57
|
+
mbst += Math.floor((stats["spe"] * 2 + 30 + 63 + 100) * level / 100 + 5);
|
|
58
|
+
|
|
59
|
+
if (mbst >= mbstmin) break;
|
|
60
|
+
level++;
|
|
61
|
+
}
|
|
57
62
|
}
|
|
58
63
|
|
|
59
64
|
// Random DVs.
|
|
@@ -298,24 +303,24 @@ export class RandomGen1Teams extends RandomGen2Teams {
|
|
|
298
303
|
const SpecialSetup = ['amnesia', 'growth'];
|
|
299
304
|
|
|
300
305
|
// Either add all moves or add none
|
|
301
|
-
if (species.comboMoves && this.randomChance(1, 2)) {
|
|
306
|
+
if (species.comboMoves && species.comboMoves.length <= this.maxMoveCount && this.randomChance(1, 2)) {
|
|
302
307
|
for (const m of species.comboMoves) moves.add(m);
|
|
303
308
|
}
|
|
304
309
|
|
|
305
310
|
// Add one of the semi-mandatory moves
|
|
306
311
|
// Often, these are used so that the Pokemon only gets one of the less useful moves
|
|
307
|
-
if (moves.size <
|
|
312
|
+
if (moves.size < this.maxMoveCount && species.exclusiveMoves) {
|
|
308
313
|
moves.add(this.sample(species.exclusiveMoves));
|
|
309
314
|
}
|
|
310
315
|
|
|
311
316
|
// Add the mandatory move. SD Mew and Amnesia Snorlax are exceptions.
|
|
312
|
-
if (moves.size <
|
|
317
|
+
if (moves.size < this.maxMoveCount && species.essentialMove) {
|
|
313
318
|
moves.add(species.essentialMove);
|
|
314
319
|
}
|
|
315
320
|
|
|
316
|
-
while (moves.size <
|
|
321
|
+
while (moves.size < this.maxMoveCount && movePool.length) {
|
|
317
322
|
// Choose next 4 moves from learnset/viable moves and add them to moves list:
|
|
318
|
-
while (moves.size <
|
|
323
|
+
while (moves.size < this.maxMoveCount && movePool.length) {
|
|
319
324
|
const moveid = this.sampleNoReplace(movePool);
|
|
320
325
|
moves.add(moveid);
|
|
321
326
|
}
|
|
@@ -361,8 +366,7 @@ export class RandomGen1Teams extends RandomGen2Teams {
|
|
|
361
366
|
Caterpie: 100, Metapod: 100, Weedle: 100, Kakuna: 100, Magikarp: 100,
|
|
362
367
|
Ditto: 88,
|
|
363
368
|
};
|
|
364
|
-
|
|
365
|
-
if (customScale[species.name]) level = customScale[species.name];
|
|
369
|
+
const level = this.adjustLevel || customScale[species.name] || levelScale[species.tier] || 80;
|
|
366
370
|
|
|
367
371
|
return {
|
|
368
372
|
name: species.name,
|
|
@@ -420,7 +424,7 @@ export class RandomGen1Teams extends RandomGen2Teams {
|
|
|
420
424
|
if (move.gen <= this.gen && !move.isNonstandard && !move.name.startsWith('Hidden Power ')) {
|
|
421
425
|
moves.push(move.id);
|
|
422
426
|
}
|
|
423
|
-
} while (moves.length <
|
|
427
|
+
} while (moves.length < this.maxMoveCount);
|
|
424
428
|
|
|
425
429
|
// Random EVs
|
|
426
430
|
const evs = {
|
|
@@ -463,16 +467,21 @@ export class RandomGen1Teams extends RandomGen2Teams {
|
|
|
463
467
|
mbst += calcStat(statName as StatID);
|
|
464
468
|
if (statName === 'hp') mbst += 5;
|
|
465
469
|
}
|
|
466
|
-
let level
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
470
|
+
let level;
|
|
471
|
+
if (this.adjustLevel) {
|
|
472
|
+
level = this.adjustLevel;
|
|
473
|
+
} else {
|
|
474
|
+
level = Math.floor(100 * mbstmin / mbst);
|
|
475
|
+
while (level < 100) {
|
|
476
|
+
for (const statName of Object.keys(baseStats)) {
|
|
477
|
+
mbst += calcStat(statName as StatID, level);
|
|
478
|
+
if (statName === 'hp') mbst += 5;
|
|
479
|
+
}
|
|
480
|
+
if (mbst >= mbstmin) break;
|
|
481
|
+
level++;
|
|
471
482
|
}
|
|
472
|
-
if (
|
|
473
|
-
level++;
|
|
483
|
+
if (level > 100) level = 100;
|
|
474
484
|
}
|
|
475
|
-
if (level > 100) level = 100;
|
|
476
485
|
|
|
477
486
|
team.push({
|
|
478
487
|
name: species.baseSpecies,
|
package/src/gen2.ts
CHANGED
|
@@ -175,7 +175,7 @@ export class RandomGen2Teams extends RandomGen3Teams {
|
|
|
175
175
|
|
|
176
176
|
do {
|
|
177
177
|
// Choose next 4 moves from learnset/viable moves and add them to moves list:
|
|
178
|
-
while (moves.size <
|
|
178
|
+
while (moves.size < this.maxMoveCount && movePool.length) {
|
|
179
179
|
const moveid = this.sampleNoReplace(movePool);
|
|
180
180
|
if (moveid.startsWith('hiddenpower')) {
|
|
181
181
|
availableHP--;
|
|
@@ -184,7 +184,7 @@ export class RandomGen2Teams extends RandomGen3Teams {
|
|
|
184
184
|
}
|
|
185
185
|
moves.add(moveid);
|
|
186
186
|
}
|
|
187
|
-
while (moves.size <
|
|
187
|
+
while (moves.size < this.maxMoveCount && rejectedPool.length) {
|
|
188
188
|
const moveid = this.sampleNoReplace(rejectedPool);
|
|
189
189
|
if (moveid.startsWith('hiddenpower')) {
|
|
190
190
|
if (hasHiddenPower) continue;
|
|
@@ -259,7 +259,7 @@ export class RandomGen2Teams extends RandomGen3Teams {
|
|
|
259
259
|
break;
|
|
260
260
|
}
|
|
261
261
|
}
|
|
262
|
-
} while (moves.size <
|
|
262
|
+
} while (moves.size < this.maxMoveCount && (movePool.length || rejectedPool.length));
|
|
263
263
|
|
|
264
264
|
// Adjust IVs for Hidden Power
|
|
265
265
|
for (const setMoveid of moves) {
|
|
@@ -302,8 +302,7 @@ export class RandomGen2Teams extends RandomGen3Teams {
|
|
|
302
302
|
const customScale: {[k: string]: number} = {
|
|
303
303
|
Ditto: 83, Unown: 87, Wobbuffet: 83,
|
|
304
304
|
};
|
|
305
|
-
|
|
306
|
-
if (customScale[species.name]) level = customScale[species.name];
|
|
305
|
+
const level = this.adjustLevel || customScale[species.name] || levelScale[species.tier] || 80;
|
|
307
306
|
|
|
308
307
|
return {
|
|
309
308
|
name: species.name,
|
package/src/gen3.ts
CHANGED
|
@@ -86,6 +86,7 @@ export class RandomGen3Teams extends RandomGen4Teams {
|
|
|
86
86
|
|
|
87
87
|
// Not very useful without their supporting moves
|
|
88
88
|
case 'amnesia': case 'sleeptalk':
|
|
89
|
+
if (moves.has('roar')) return {cull: true};
|
|
89
90
|
if (!moves.has('rest')) return {cull: true};
|
|
90
91
|
if (movePool.length > 1) {
|
|
91
92
|
const rest = movePool.indexOf('rest');
|
|
@@ -176,6 +177,8 @@ export class RandomGen3Teams extends RandomGen4Teams {
|
|
|
176
177
|
return {cull: !!counter.setupType || moves.has('rest') || !!teamDetails.rapidSpin};
|
|
177
178
|
case 'reflect':
|
|
178
179
|
return {cull: !!counter.setupType || !!counter.get('speedsetup')};
|
|
180
|
+
case 'roar':
|
|
181
|
+
return {cull: moves.has('sleeptalk') || moves.has('rest')};
|
|
179
182
|
case 'seismictoss':
|
|
180
183
|
return {cull: !!counter.setupType || moves.has('thunderbolt')};
|
|
181
184
|
case 'spikes':
|
|
@@ -363,7 +366,7 @@ export class RandomGen3Teams extends RandomGen4Teams {
|
|
|
363
366
|
|
|
364
367
|
do {
|
|
365
368
|
// Choose next 4 moves from learnset/viable moves and add them to moves list:
|
|
366
|
-
while (moves.size <
|
|
369
|
+
while (moves.size < this.maxMoveCount && movePool.length) {
|
|
367
370
|
const moveid = this.sampleNoReplace(movePool);
|
|
368
371
|
if (moveid.startsWith('hiddenpower')) {
|
|
369
372
|
availableHP--;
|
|
@@ -373,7 +376,7 @@ export class RandomGen3Teams extends RandomGen4Teams {
|
|
|
373
376
|
moves.add(moveid);
|
|
374
377
|
}
|
|
375
378
|
|
|
376
|
-
while (moves.size <
|
|
379
|
+
while (moves.size < this.maxMoveCount && rejectedPool.length) {
|
|
377
380
|
const moveid = this.sampleNoReplace(rejectedPool);
|
|
378
381
|
if (moveid.startsWith('hiddenpower')) {
|
|
379
382
|
if (hasHiddenPower) continue;
|
|
@@ -397,7 +400,6 @@ export class RandomGen3Teams extends RandomGen4Teams {
|
|
|
397
400
|
) {
|
|
398
401
|
cull = true;
|
|
399
402
|
}
|
|
400
|
-
|
|
401
403
|
const moveIsRejectable = (
|
|
402
404
|
!move.weather &&
|
|
403
405
|
(move.category !== 'Status' || !move.flags.heal) &&
|
|
@@ -489,7 +491,7 @@ export class RandomGen3Teams extends RandomGen4Teams {
|
|
|
489
491
|
break;
|
|
490
492
|
}
|
|
491
493
|
}
|
|
492
|
-
} while (moves.size <
|
|
494
|
+
} while (moves.size < this.maxMoveCount && (movePool.length || rejectedPool.length));
|
|
493
495
|
|
|
494
496
|
if (hasHiddenPower) {
|
|
495
497
|
let hpType;
|
|
@@ -543,8 +545,7 @@ export class RandomGen3Teams extends RandomGen4Teams {
|
|
|
543
545
|
Ditto: 99, Unown: 99,
|
|
544
546
|
};
|
|
545
547
|
const tier = species.tier;
|
|
546
|
-
|
|
547
|
-
if (customScale[species.name]) level = customScale[species.name];
|
|
548
|
+
const level = this.adjustLevel || customScale[species.name] || levelScale[tier] || (species.nfe ? 90 : 80);
|
|
548
549
|
|
|
549
550
|
// Prepare optimal HP
|
|
550
551
|
let hp = Math.floor(Math.floor(2 * species.baseStats.hp + ivs.hp + Math.floor(evs.hp / 4) + 100) * level / 100 + 10);
|
package/src/gen4.ts
CHANGED
|
@@ -547,7 +547,7 @@ export class RandomGen4Teams extends RandomGen5Teams {
|
|
|
547
547
|
|
|
548
548
|
do {
|
|
549
549
|
// Choose next 4 moves from learnset/viable moves and add them to moves list:
|
|
550
|
-
while (moves.size <
|
|
550
|
+
while (moves.size < this.maxMoveCount && movePool.length) {
|
|
551
551
|
const moveid = this.sampleNoReplace(movePool);
|
|
552
552
|
if (moveid.startsWith('hiddenpower')) {
|
|
553
553
|
availableHP--;
|
|
@@ -557,7 +557,7 @@ export class RandomGen4Teams extends RandomGen5Teams {
|
|
|
557
557
|
moves.add(moveid);
|
|
558
558
|
}
|
|
559
559
|
|
|
560
|
-
while (moves.size <
|
|
560
|
+
while (moves.size < this.maxMoveCount && rejectedPool.length) {
|
|
561
561
|
const moveid = this.sampleNoReplace(rejectedPool);
|
|
562
562
|
if (moveid.startsWith('hiddenpower')) {
|
|
563
563
|
if (hasHiddenPower) continue;
|
|
@@ -726,7 +726,7 @@ export class RandomGen4Teams extends RandomGen5Teams {
|
|
|
726
726
|
break;
|
|
727
727
|
}
|
|
728
728
|
}
|
|
729
|
-
} while (moves.size <
|
|
729
|
+
} while (moves.size < this.maxMoveCount && (movePool.length || rejectedPool.length));
|
|
730
730
|
|
|
731
731
|
if (hasHiddenPower) {
|
|
732
732
|
let hpType;
|
|
@@ -802,8 +802,7 @@ export class RandomGen4Teams extends RandomGen5Teams {
|
|
|
802
802
|
const customScale: {[k: string]: number} = {
|
|
803
803
|
Delibird: 100, Ditto: 100, 'Farfetch\u2019d': 100, Unown: 100,
|
|
804
804
|
};
|
|
805
|
-
|
|
806
|
-
if (customScale[species.name]) level = customScale[species.name];
|
|
805
|
+
const level = this.adjustLevel || customScale[species.name] || levelScale[species.tier] || (species.nfe ? 90 : 80);
|
|
807
806
|
|
|
808
807
|
// Prepare optimal HP
|
|
809
808
|
let hp = Math.floor(
|
package/src/gen5.ts
CHANGED
|
@@ -42,6 +42,9 @@ export class RandomGen5Teams extends RandomGen6Teams {
|
|
|
42
42
|
!counter.get('Ground') && !moves.has('rest') && !moves.has('sleeptalk')
|
|
43
43
|
),
|
|
44
44
|
Ice: (movePool, moves, abilities, types, counter) => !counter.get('Ice'),
|
|
45
|
+
Normal: (movePool, moves, abilities, types, counter, species) => (
|
|
46
|
+
movePool.includes('return') && species.baseStats.atk > 80
|
|
47
|
+
),
|
|
45
48
|
Rock: (movePool, moves, abilities, types, counter, species) => !counter.get('Rock') && species.baseStats.atk >= 80,
|
|
46
49
|
Steel: (movePool, moves, abilities, types, counter) => !counter.get('Steel') && abilities.has('Technician'),
|
|
47
50
|
Water: (movePool, moves, abilities, types, counter) => (
|
|
@@ -486,7 +489,7 @@ export class RandomGen5Teams extends RandomGen6Teams {
|
|
|
486
489
|
|
|
487
490
|
do {
|
|
488
491
|
// Choose next 4 moves from learnset/viable moves and add them to moves list:
|
|
489
|
-
while (moves.size <
|
|
492
|
+
while (moves.size < this.maxMoveCount && movePool.length) {
|
|
490
493
|
const moveid = this.sampleNoReplace(movePool);
|
|
491
494
|
if (moveid.startsWith('hiddenpower')) {
|
|
492
495
|
availableHP--;
|
|
@@ -496,7 +499,7 @@ export class RandomGen5Teams extends RandomGen6Teams {
|
|
|
496
499
|
moves.add(moveid);
|
|
497
500
|
}
|
|
498
501
|
|
|
499
|
-
while (moves.size <
|
|
502
|
+
while (moves.size < this.maxMoveCount && rejectedPool.length) {
|
|
500
503
|
const moveid = this.sampleNoReplace(rejectedPool);
|
|
501
504
|
if (moveid.startsWith('hiddenpower')) {
|
|
502
505
|
if (hasHiddenPower) {
|
|
@@ -651,7 +654,7 @@ export class RandomGen5Teams extends RandomGen6Teams {
|
|
|
651
654
|
break;
|
|
652
655
|
}
|
|
653
656
|
}
|
|
654
|
-
} while (moves.size <
|
|
657
|
+
} while (moves.size < this.maxMoveCount && (movePool.length || rejectedPool.length));
|
|
655
658
|
|
|
656
659
|
if (hasHiddenPower) {
|
|
657
660
|
let hpType;
|
|
@@ -736,8 +739,7 @@ export class RandomGen5Teams extends RandomGen6Teams {
|
|
|
736
739
|
const customScale: {[forme: string]: number} = {
|
|
737
740
|
Delibird: 100, 'Farfetch\u2019d': 100, Luvdisc: 100, Unown: 100,
|
|
738
741
|
};
|
|
739
|
-
|
|
740
|
-
if (customScale[species.name]) level = customScale[species.name];
|
|
742
|
+
const level = this.adjustLevel || customScale[species.name] || levelScale[species.tier] || (species.nfe ? 90 : 80);
|
|
741
743
|
|
|
742
744
|
// Prepare optimal HP
|
|
743
745
|
const srWeakness = this.dex.getEffectiveness('Rock', species);
|
package/src/gen6.ts
CHANGED
|
@@ -409,7 +409,11 @@ export class RandomGen6Teams extends RandomGen7Teams {
|
|
|
409
409
|
case 'originpulse': case 'surf':
|
|
410
410
|
return {cull: moves.has('hydropump') || moves.has('scald')};
|
|
411
411
|
case 'scald':
|
|
412
|
-
return {cull:
|
|
412
|
+
return {cull: (
|
|
413
|
+
moves.has('waterfall') ||
|
|
414
|
+
moves.has('waterpulse') ||
|
|
415
|
+
(species.id === 'quagsire' && movePool.includes('recover'))
|
|
416
|
+
)};
|
|
413
417
|
|
|
414
418
|
// Status:
|
|
415
419
|
case 'glare': case 'headbutt':
|
|
@@ -567,7 +571,7 @@ export class RandomGen6Teams extends RandomGen7Teams {
|
|
|
567
571
|
case 'Unburden':
|
|
568
572
|
return (!!species.isMega || abilities.has('Prankster') || !counter.setupType && !moves.has('acrobatics'));
|
|
569
573
|
case 'Water Absorb':
|
|
570
|
-
return (moves.has('raindance') ||
|
|
574
|
+
return (moves.has('raindance') || ['Drizzle', 'Unaware', 'Volt Absorb'].some(a => abilities.has(a)));
|
|
571
575
|
case 'Weak Armor':
|
|
572
576
|
return counter.setupType !== 'Physical';
|
|
573
577
|
}
|
|
@@ -794,9 +798,8 @@ export class RandomGen6Teams extends RandomGen7Teams {
|
|
|
794
798
|
const ivs = {hp: 31, atk: 31, def: 31, spa: 31, spd: 31, spe: 31};
|
|
795
799
|
|
|
796
800
|
const types = new Set(species.types);
|
|
797
|
-
|
|
801
|
+
let abilities = new Set(Object.values(species.abilities));
|
|
798
802
|
if (species.unreleasedHidden) abilities.delete(species.abilities.H);
|
|
799
|
-
|
|
800
803
|
let availableHP = 0;
|
|
801
804
|
for (const setMoveid of movePool) {
|
|
802
805
|
if (setMoveid.startsWith('hiddenpower')) availableHP++;
|
|
@@ -813,7 +816,7 @@ export class RandomGen6Teams extends RandomGen7Teams {
|
|
|
813
816
|
|
|
814
817
|
do {
|
|
815
818
|
// Choose next 4 moves from learnset/viable moves and add them to moves list:
|
|
816
|
-
while (moves.size <
|
|
819
|
+
while (moves.size < this.maxMoveCount && movePool.length) {
|
|
817
820
|
const moveid = this.sampleNoReplace(movePool);
|
|
818
821
|
if (moveid.startsWith('hiddenpower')) {
|
|
819
822
|
availableHP--;
|
|
@@ -823,7 +826,7 @@ export class RandomGen6Teams extends RandomGen7Teams {
|
|
|
823
826
|
moves.add(moveid);
|
|
824
827
|
}
|
|
825
828
|
|
|
826
|
-
while (moves.size <
|
|
829
|
+
while (moves.size < this.maxMoveCount && rejectedPool.length) {
|
|
827
830
|
const moveid = this.sampleNoReplace(rejectedPool);
|
|
828
831
|
if (moveid.startsWith('hiddenpower')) {
|
|
829
832
|
if (hasHiddenPower) continue;
|
|
@@ -967,7 +970,7 @@ export class RandomGen6Teams extends RandomGen7Teams {
|
|
|
967
970
|
break;
|
|
968
971
|
}
|
|
969
972
|
}
|
|
970
|
-
} while (moves.size <
|
|
973
|
+
} while (moves.size < this.maxMoveCount && (movePool.length || rejectedPool.length));
|
|
971
974
|
|
|
972
975
|
if (hasHiddenPower) {
|
|
973
976
|
let hpType;
|
|
@@ -995,10 +998,10 @@ export class RandomGen6Teams extends RandomGen7Teams {
|
|
|
995
998
|
moves.add('thunder');
|
|
996
999
|
}
|
|
997
1000
|
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
const abilityData =
|
|
1001
|
+
if (species.battleOnly && !species.requiredAbility) {
|
|
1002
|
+
abilities = new Set(Object.values(this.dex.species.get(species.battleOnly as string).abilities));
|
|
1003
|
+
}
|
|
1004
|
+
const abilityData = [...abilities].map(a => this.dex.abilities.get(a));
|
|
1002
1005
|
Utils.sortBy(abilityData, abil => -abil.rating);
|
|
1003
1006
|
|
|
1004
1007
|
if (abilityData.length > 1) {
|
|
@@ -1068,8 +1071,7 @@ export class RandomGen6Teams extends RandomGen7Teams {
|
|
|
1068
1071
|
Castform: 100, Delibird: 100, 'Genesect-Douse': 80, Luvdisc: 100, Spinda: 100, Unown: 100,
|
|
1069
1072
|
};
|
|
1070
1073
|
const tier = toID(species.tier).replace('bl', '');
|
|
1071
|
-
|
|
1072
|
-
if (customScale[forme]) level = customScale[forme];
|
|
1074
|
+
const level = this.adjustLevel || customScale[species.name] || levelScale[tier] || (species.nfe ? 90 : 80);
|
|
1073
1075
|
|
|
1074
1076
|
// Prepare optimal HP
|
|
1075
1077
|
const srWeakness = this.dex.getEffectiveness('Rock', species);
|
|
@@ -1197,7 +1199,7 @@ export class RandomGen6Teams extends RandomGen7Teams {
|
|
|
1197
1199
|
item: setData.set.item || '',
|
|
1198
1200
|
ability: setData.set.ability || species.abilities['0'],
|
|
1199
1201
|
shiny: typeof setData.set.shiny === 'undefined' ? this.randomChance(1, 1024) : setData.set.shiny,
|
|
1200
|
-
level: 100,
|
|
1202
|
+
level: this.adjustLevel || 100,
|
|
1201
1203
|
happiness: typeof setData.set.happiness === 'undefined' ? 255 : setData.set.happiness,
|
|
1202
1204
|
evs: setData.set.evs || {hp: 84, atk: 84, def: 84, spa: 84, spd: 84, spe: 84},
|
|
1203
1205
|
ivs: setData.set.ivs || {hp: 31, atk: 31, def: 31, spa: 31, spd: 31, spe: 31},
|
package/src/gen7.ts
CHANGED
|
@@ -1041,7 +1041,7 @@ export class RandomGen7Teams extends RandomTeams {
|
|
|
1041
1041
|
// Random Multi Battle uses doubles move pools, but Ally Switch fails in multi battles
|
|
1042
1042
|
const allySwitch = movePool.indexOf('allyswitch');
|
|
1043
1043
|
if (allySwitch > -1) {
|
|
1044
|
-
if (movePool.length >
|
|
1044
|
+
if (movePool.length > this.maxMoveCount) {
|
|
1045
1045
|
this.fastPop(movePool, allySwitch);
|
|
1046
1046
|
} else {
|
|
1047
1047
|
// Ideally, we'll never get here, but better to have a move that usually does nothing than one that always does
|
|
@@ -1078,7 +1078,7 @@ export class RandomGen7Teams extends RandomTeams {
|
|
|
1078
1078
|
|
|
1079
1079
|
do {
|
|
1080
1080
|
// Choose next 4 moves from learnset/viable moves and add them to moves list:
|
|
1081
|
-
while (moves.size <
|
|
1081
|
+
while (moves.size < this.maxMoveCount && movePool.length) {
|
|
1082
1082
|
const moveid = this.sampleNoReplace(movePool);
|
|
1083
1083
|
if (moveid.startsWith('hiddenpower')) {
|
|
1084
1084
|
availableHP--;
|
|
@@ -1087,7 +1087,7 @@ export class RandomGen7Teams extends RandomTeams {
|
|
|
1087
1087
|
}
|
|
1088
1088
|
moves.add(moveid);
|
|
1089
1089
|
}
|
|
1090
|
-
while (moves.size <
|
|
1090
|
+
while (moves.size < this.maxMoveCount && rejectedPool.length) {
|
|
1091
1091
|
const moveid = this.sampleNoReplace(rejectedPool);
|
|
1092
1092
|
if (moveid.startsWith('hiddenpower')) {
|
|
1093
1093
|
if (hasHiddenPower) continue;
|
|
@@ -1243,7 +1243,7 @@ export class RandomGen7Teams extends RandomTeams {
|
|
|
1243
1243
|
break;
|
|
1244
1244
|
}
|
|
1245
1245
|
}
|
|
1246
|
-
} while (moves.size <
|
|
1246
|
+
} while (moves.size < this.maxMoveCount && (movePool.length || rejectedPool.length));
|
|
1247
1247
|
|
|
1248
1248
|
// Moveset modifications
|
|
1249
1249
|
if (moves.has('autotomize') && moves.has('heavyslam')) {
|
|
@@ -1356,7 +1356,9 @@ export class RandomGen7Teams extends RandomTeams {
|
|
|
1356
1356
|
}
|
|
1357
1357
|
|
|
1358
1358
|
let level: number;
|
|
1359
|
-
if (
|
|
1359
|
+
if (this.adjustLevel) {
|
|
1360
|
+
level = this.adjustLevel;
|
|
1361
|
+
} else if (!isDoubles) {
|
|
1360
1362
|
const levelScale: {[k: string]: number} = {uber: 76, ou: 80, uu: 82, ru: 84, nu: 86, pu: 88};
|
|
1361
1363
|
const customScale: {[k: string]: number} = {
|
|
1362
1364
|
// Banned Ability
|
|
@@ -1726,7 +1728,7 @@ export class RandomGen7Teams extends RandomTeams {
|
|
|
1726
1728
|
const item = this.sampleIfArray(setData.set.item);
|
|
1727
1729
|
const ability = this.sampleIfArray(setData.set.ability);
|
|
1728
1730
|
const nature = this.sampleIfArray(setData.set.nature);
|
|
1729
|
-
const level = setData.set.level || (tier === "LC" ? 5 : 100);
|
|
1731
|
+
const level = this.adjustLevel || setData.set.level || (tier === "LC" ? 5 : 100);
|
|
1730
1732
|
|
|
1731
1733
|
return {
|
|
1732
1734
|
name: setData.set.name || species.baseSpecies,
|
package/src/gen8.ts
CHANGED
|
@@ -103,6 +103,8 @@ export class RandomTeams {
|
|
|
103
103
|
prng: PRNG;
|
|
104
104
|
noStab: string[];
|
|
105
105
|
readonly maxTeamSize: number;
|
|
106
|
+
readonly adjustLevel: number | null;
|
|
107
|
+
readonly maxMoveCount: number;
|
|
106
108
|
readonly forceMonotype: string | undefined;
|
|
107
109
|
|
|
108
110
|
/**
|
|
@@ -119,6 +121,8 @@ export class RandomTeams {
|
|
|
119
121
|
|
|
120
122
|
const ruleTable = this.dex.formats.getRuleTable(format);
|
|
121
123
|
this.maxTeamSize = ruleTable.maxTeamSize;
|
|
124
|
+
this.adjustLevel = ruleTable.adjustLevel;
|
|
125
|
+
this.maxMoveCount = ruleTable.maxMoveCount;
|
|
122
126
|
const forceMonotype = ruleTable.valueRules.get('forcemonotype');
|
|
123
127
|
this.forceMonotype = forceMonotype && this.dex.types.get(forceMonotype).exists ?
|
|
124
128
|
this.dex.types.get(forceMonotype).name : undefined;
|
|
@@ -442,7 +446,7 @@ export class RandomTeams {
|
|
|
442
446
|
}
|
|
443
447
|
}
|
|
444
448
|
|
|
445
|
-
const moves = this.multipleSamplesNoReplace(pool,
|
|
449
|
+
const moves = this.multipleSamplesNoReplace(pool, this.maxMoveCount);
|
|
446
450
|
|
|
447
451
|
// Random EVs
|
|
448
452
|
const evs: StatsTable = {hp: 0, atk: 0, def: 0, spa: 0, spd: 0, spe: 0};
|
|
@@ -483,19 +487,24 @@ export class RandomTeams {
|
|
|
483
487
|
mbst += (stats["spd"] * 2 + 31 + 21 + 100) + 5;
|
|
484
488
|
mbst += (stats["spe"] * 2 + 31 + 21 + 100) + 5;
|
|
485
489
|
|
|
486
|
-
let level
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
490
|
+
let level;
|
|
491
|
+
if (this.adjustLevel) {
|
|
492
|
+
level = this.adjustLevel;
|
|
493
|
+
} else {
|
|
494
|
+
level = Math.floor(100 * mbstmin / mbst); // Initial level guess will underestimate
|
|
495
|
+
|
|
496
|
+
while (level < 100) {
|
|
497
|
+
mbst = Math.floor((stats["hp"] * 2 + 31 + 21 + 100) * level / 100 + 10);
|
|
498
|
+
// Since damage is roughly proportional to level
|
|
499
|
+
mbst += Math.floor(((stats["atk"] * 2 + 31 + 21 + 100) * level / 100 + 5) * level / 100);
|
|
500
|
+
mbst += Math.floor((stats["def"] * 2 + 31 + 21 + 100) * level / 100 + 5);
|
|
501
|
+
mbst += Math.floor(((stats["spa"] * 2 + 31 + 21 + 100) * level / 100 + 5) * level / 100);
|
|
502
|
+
mbst += Math.floor((stats["spd"] * 2 + 31 + 21 + 100) * level / 100 + 5);
|
|
503
|
+
mbst += Math.floor((stats["spe"] * 2 + 31 + 21 + 100) * level / 100 + 5);
|
|
504
|
+
|
|
505
|
+
if (mbst >= mbstmin) break;
|
|
506
|
+
level++;
|
|
507
|
+
}
|
|
499
508
|
}
|
|
500
509
|
|
|
501
510
|
// Random happiness
|
|
@@ -563,7 +572,7 @@ export class RandomTeams {
|
|
|
563
572
|
|
|
564
573
|
banReason = ruleTable.check('basepokemon:' + toID(species.baseSpecies));
|
|
565
574
|
if (banReason) continue;
|
|
566
|
-
if (banReason !== '' || this.dex.species.get(species.baseSpecies).isNonstandard
|
|
575
|
+
if (banReason !== '' || this.dex.species.get(species.baseSpecies).isNonstandard !== species.isNonstandard) {
|
|
567
576
|
const nonexistentCheck = Tags.nonexistent.genericFilter!(species) && nonexistentBanReason;
|
|
568
577
|
let tagWhitelisted = false;
|
|
569
578
|
let tagBlacklisted = false;
|
|
@@ -588,10 +597,10 @@ export class RandomTeams {
|
|
|
588
597
|
}
|
|
589
598
|
}
|
|
590
599
|
}
|
|
600
|
+
speciesPool.push(species);
|
|
591
601
|
const num = species.num;
|
|
592
602
|
if (pool.includes(num)) continue;
|
|
593
603
|
pool.push(num);
|
|
594
|
-
speciesPool.push(species);
|
|
595
604
|
}
|
|
596
605
|
}
|
|
597
606
|
|
|
@@ -825,16 +834,22 @@ export class RandomTeams {
|
|
|
825
834
|
mbst += (stats['spa'] * 2 + 31 + 21 + 100) + 5;
|
|
826
835
|
mbst += (stats['spd'] * 2 + 31 + 21 + 100) + 5;
|
|
827
836
|
mbst += (stats['spe'] * 2 + 31 + 21 + 100) + 5;
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
837
|
+
|
|
838
|
+
let level;
|
|
839
|
+
if (this.adjustLevel) {
|
|
840
|
+
level = this.adjustLevel;
|
|
841
|
+
} else {
|
|
842
|
+
level = Math.floor(100 * mbstmin / mbst);
|
|
843
|
+
while (level < 100) {
|
|
844
|
+
mbst = Math.floor((stats['hp'] * 2 + 31 + 21 + 100) * level / 100 + 10);
|
|
845
|
+
mbst += Math.floor(((stats['atk'] * 2 + 31 + 21 + 100) * level / 100 + 5) * level / 100);
|
|
846
|
+
mbst += Math.floor((stats['def'] * 2 + 31 + 21 + 100) * level / 100 + 5);
|
|
847
|
+
mbst += Math.floor(((stats['spa'] * 2 + 31 + 21 + 100) * level / 100 + 5) * level / 100);
|
|
848
|
+
mbst += Math.floor((stats['spd'] * 2 + 31 + 21 + 100) * level / 100 + 5);
|
|
849
|
+
mbst += Math.floor((stats['spe'] * 2 + 31 + 21 + 100) * level / 100 + 5);
|
|
850
|
+
if (mbst >= mbstmin) break;
|
|
851
|
+
level++;
|
|
852
|
+
}
|
|
838
853
|
}
|
|
839
854
|
|
|
840
855
|
// Random happiness
|
|
@@ -1965,7 +1980,7 @@ export class RandomTeams {
|
|
|
1965
1980
|
// Random Free-For-All also uses doubles move pools, for now
|
|
1966
1981
|
const allySwitch = movePool.indexOf('allyswitch');
|
|
1967
1982
|
if (allySwitch > -1) {
|
|
1968
|
-
if (movePool.length >
|
|
1983
|
+
if (movePool.length > this.maxMoveCount) {
|
|
1969
1984
|
this.fastPop(movePool, allySwitch);
|
|
1970
1985
|
} else {
|
|
1971
1986
|
// Ideally, we'll never get here, but better to have a move that usually does nothing than one that always does
|
|
@@ -1993,7 +2008,7 @@ export class RandomTeams {
|
|
|
1993
2008
|
do {
|
|
1994
2009
|
// Choose next 4 moves from learnset/viable moves and add them to moves list:
|
|
1995
2010
|
const pool = (movePool.length ? movePool : rejectedPool);
|
|
1996
|
-
while (moves.size <
|
|
2011
|
+
while (moves.size < this.maxMoveCount && pool.length) {
|
|
1997
2012
|
const moveid = this.sampleNoReplace(pool);
|
|
1998
2013
|
if (moveid.startsWith('hiddenpower')) {
|
|
1999
2014
|
if (hasHiddenPower) continue;
|
|
@@ -2100,7 +2115,7 @@ export class RandomTeams {
|
|
|
2100
2115
|
break;
|
|
2101
2116
|
}
|
|
2102
2117
|
}
|
|
2103
|
-
} while (moves.size <
|
|
2118
|
+
} while (moves.size < this.maxMoveCount && (movePool.length || rejectedPool.length));
|
|
2104
2119
|
|
|
2105
2120
|
// for BD/SP only
|
|
2106
2121
|
if (hasHiddenPower) {
|
|
@@ -2218,8 +2233,10 @@ export class RandomTeams {
|
|
|
2218
2233
|
}
|
|
2219
2234
|
|
|
2220
2235
|
let level: number;
|
|
2236
|
+
if (this.adjustLevel) {
|
|
2237
|
+
level = this.adjustLevel;
|
|
2221
2238
|
// doubles levelling
|
|
2222
|
-
if (isDoubles && species.randomDoubleBattleLevel) {
|
|
2239
|
+
} else if (isDoubles && species.randomDoubleBattleLevel) {
|
|
2223
2240
|
level = species.randomDoubleBattleLevel;
|
|
2224
2241
|
// No Dmax levelling
|
|
2225
2242
|
} else if (isNoDynamax) {
|
|
@@ -2261,7 +2278,7 @@ export class RandomTeams {
|
|
|
2261
2278
|
PUBL: 87,
|
|
2262
2279
|
PU: 88, "(PU)": 88, NFE: 88,
|
|
2263
2280
|
};
|
|
2264
|
-
const customScale: {[k: string]: number} = {delibird: 100, luvdisc: 100, spinda: 100, unown: 100};
|
|
2281
|
+
const customScale: {[k: string]: number} = {delibird: 100, glalie: 76, luvdisc: 100, spinda: 100, unown: 100};
|
|
2265
2282
|
|
|
2266
2283
|
level = customScale[species.id] || tierScale[species.tier] || 80;
|
|
2267
2284
|
// Arbitrary levelling base on data files (typically winrate-influenced)
|
|
@@ -2549,11 +2566,13 @@ export class RandomTeams {
|
|
|
2549
2566
|
item: this.sampleIfArray(setData.item) || '',
|
|
2550
2567
|
ability: (this.sampleIfArray(setData.ability)),
|
|
2551
2568
|
shiny: this.randomChance(1, 1024),
|
|
2569
|
+
level: this.adjustLevel || 100,
|
|
2552
2570
|
evs: {hp: 0, atk: 0, def: 0, spa: 0, spd: 0, spe: 0, ...setData.evs},
|
|
2553
2571
|
nature: setData.nature,
|
|
2554
2572
|
ivs: {hp: 31, atk: 31, def: 31, spa: 31, spd: 31, spe: 31, ...setData.ivs || {}},
|
|
2555
2573
|
moves: setData.moves.map((move: any) => this.sampleIfArray(move)),
|
|
2556
2574
|
};
|
|
2575
|
+
if (this.adjustLevel) set.level = this.adjustLevel;
|
|
2557
2576
|
pokemon.push(set);
|
|
2558
2577
|
}
|
|
2559
2578
|
return pokemon;
|