@pkmn/sim 0.5.16 → 0.5.17
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/config/formats.js +32 -51
- package/build/config/formats.js.map +1 -1
- package/build/data/items.js +1 -3
- package/build/data/items.js.map +1 -1
- package/build/data/learnsets.js +2 -2
- package/build/data/learnsets.js.map +1 -1
- package/build/data/mods/gen1/formats-data.js +1 -1
- package/build/data/mods/gen1/formats-data.js.map +1 -1
- package/build/data/mods/gen1/moves.js +1 -4
- package/build/data/mods/gen1/moves.js.map +1 -1
- package/build/data/mods/gen3/moves.js +0 -7
- package/build/data/mods/gen3/moves.js.map +1 -1
- package/build/data/mods/gen3/scripts.js +2 -2
- package/build/data/mods/gen3/scripts.js.map +1 -1
- package/build/data/mods/gen4/moves.js +1 -1
- package/build/data/mods/gen4/moves.js.map +1 -1
- package/build/data/mods/gen4/rulesets.js +2 -1
- package/build/data/mods/gen4/rulesets.js.map +1 -1
- package/build/data/mods/gen5/rulesets.js +2 -1
- package/build/data/mods/gen5/rulesets.js.map +1 -1
- package/build/data/mods/gen7/formats-data.js +4 -4
- package/build/data/mods/gen7/formats-data.js.map +1 -1
- package/build/data/mods/gen7/rulesets.js +2 -1
- package/build/data/mods/gen7/rulesets.js.map +1 -1
- package/build/data/moves.js +55 -74
- package/build/data/moves.js.map +1 -1
- package/build/data/pokedex.js +2 -2
- package/build/data/pokedex.js.map +1 -1
- package/build/data/rulesets.js +3 -4
- package/build/data/rulesets.js.map +1 -1
- package/build/data/text/items.js +1 -0
- package/build/data/text/items.js.map +1 -1
- package/build/data/text/moves.js +5 -3
- package/build/data/text/moves.js.map +1 -1
- package/build/sim/battle-actions.js +9 -1
- package/build/sim/battle-actions.js.map +1 -1
- package/build/sim/battle.js +39 -1
- package/build/sim/battle.js.map +1 -1
- package/build/sim/dex-conditions.d.ts +1 -0
- package/build/sim/dex-conditions.js.map +1 -1
- package/build/sim/exported-global-types.d.ts +1 -0
- package/build/sim/global-types.d.ts +1 -0
- package/build/sim/team-validator.js +15 -4
- package/build/sim/team-validator.js.map +1 -1
- package/build/sim/tools/exhaustive-runner.d.ts +8 -0
- package/build/sim/tools/exhaustive-runner.js +18 -7
- package/build/sim/tools/exhaustive-runner.js.map +1 -1
- package/config/formats.ts +32 -51
- package/data/items.ts +1 -3
- package/data/learnsets.ts +2 -2
- package/data/mods/gen1/formats-data.ts +1 -1
- package/data/mods/gen1/moves.ts +1 -4
- package/data/mods/gen3/moves.ts +0 -7
- package/data/mods/gen3/scripts.ts +3 -3
- package/data/mods/gen4/moves.ts +1 -1
- package/data/mods/gen4/rulesets.ts +2 -1
- package/data/mods/gen5/rulesets.ts +2 -1
- package/data/mods/gen7/formats-data.ts +4 -4
- package/data/mods/gen7/rulesets.ts +2 -1
- package/data/moves.ts +55 -65
- package/data/pokedex.ts +2 -2
- package/data/rulesets.ts +3 -6
- package/data/text/items.ts +2 -0
- package/data/text/moves.ts +6 -3
- package/package.json +1 -1
- package/sim/battle-actions.ts +13 -1
- package/sim/battle.ts +38 -1
- package/sim/dex-conditions.ts +1 -0
- package/sim/exported-global-types.ts +3 -0
- package/sim/global-types.ts +3 -0
- package/sim/team-validator.ts +16 -4
- package/sim/tools/exhaustive-runner.ts +29 -11
package/data/text/moves.ts
CHANGED
|
@@ -1934,6 +1934,8 @@ export const MovesText: {[k: string]: MoveText} = {
|
|
|
1934
1934
|
name: "Flip Turn",
|
|
1935
1935
|
desc: "If this move is successful and the user has not fainted, the user switches out even if it is trapped and is replaced immediately by a selected party member. The user does not switch out if there are no unfainted party members, or if the target switched out using an Eject Button or through the effect of the Emergency Exit or Wimp Out Abilities.",
|
|
1936
1936
|
shortDesc: "User switches out after damaging the target.",
|
|
1937
|
+
|
|
1938
|
+
switchOut: "#uturn",
|
|
1937
1939
|
},
|
|
1938
1940
|
floatyfall: {
|
|
1939
1941
|
name: "Floaty Fall",
|
|
@@ -3695,7 +3697,7 @@ export const MovesText: {[k: string]: MoveText} = {
|
|
|
3695
3697
|
},
|
|
3696
3698
|
metronome: {
|
|
3697
3699
|
name: "Metronome",
|
|
3698
|
-
desc: "A random move is selected for use, other than After You, Apple Acid, Assist, Astral Barrage, Aura Wheel, Baneful Bunker, Beak Blast, Behemoth Bash, Behemoth Blade, Belch, Bestow, Body Press, Branch Poke, Breaking Swipe, Celebrate, Chatter, Clangorous Soul, Copycat, Counter, Covet, Crafty Shield, Decorate, Destiny Bond, Detect, Diamond Storm, Double Iron Bash, Dragon Ascent, Dragon Energy, Drum Beating, Dynamax Cannon, Endure, Eternabeam, False Surrender, Feint, Fiery Wrath, Fleur Cannon, Focus Punch, Follow Me, Freeze Shock, Freezing Glare, Glacial Lance, Grav Apple, Helping Hand, Hold Hands, Hyperspace Fury, Hyperspace Hole, Ice Burn, Instruct, Jungle Healing, King's Shield, Life Dew, Light of Ruin, Mat Block, Me First, Meteor Assault, Metronome, Mimic, Mind Blown, Mirror Coat, Mirror Move, Moongeist Beam, Nature Power, Nature's Madness, Obstruct, Origin Pulse, Overdrive, Photon Geyser, Plasma Fists, Precipice Blades, Protect, Pyro Ball, Quash, Quick Guard, Rage Powder, Relic Song, Secret Sword, Shell Trap, Sketch, Sleep Talk, Snap Trap, Snarl, Snatch, Snore, Spectral Thief, Spiky Shield, Spirit Break, Spotlight, Steam Eruption, Steel Beam, Strange Steam, Struggle, Sunsteel Strike, Surging Strikes, Switcheroo, Techno Blast, Thief, Thousand Arrows, Thousand Waves, Thunder Cage, Thunderous Kick, Transform, Trick, V-create, Wicked Blow, or Wide Guard.",
|
|
3700
|
+
desc: "A random move is selected for use, other than After You, Apple Acid, Assist, Astral Barrage, Aura Wheel, Baneful Bunker, Beak Blast, Behemoth Bash, Behemoth Blade, Belch, Bestow, Body Press, Branch Poke, Breaking Swipe, Celebrate, Chatter, Clangorous Soul, Copycat, Counter, Covet, Crafty Shield, Decorate, Destiny Bond, Detect, Diamond Storm, Double Iron Bash, Dragon Ascent, Dragon Energy, Dragon Hammer, Drum Beating, Dynamax Cannon, Endure, Eternabeam, False Surrender, Feint, Fiery Wrath, Fleur Cannon, Focus Punch, Follow Me, Freeze Shock, Freezing Glare, Glacial Lance, Grav Apple, Helping Hand, Hold Hands, Hyperspace Fury, Hyperspace Hole, Ice Burn, Instruct, Jungle Healing, King's Shield, Life Dew, Light of Ruin, Mat Block, Me First, Meteor Assault, Metronome, Mimic, Mind Blown, Mirror Coat, Mirror Move, Moongeist Beam, Nature Power, Nature's Madness, Obstruct, Origin Pulse, Overdrive, Photon Geyser, Plasma Fists, Precipice Blades, Protect, Pyro Ball, Quash, Quick Guard, Rage Powder, Relic Song, Secret Sword, Shell Trap, Sketch, Sleep Talk, Snap Trap, Snarl, Snatch, Snore, Spectral Thief, Spiky Shield, Spirit Break, Spotlight, Steam Eruption, Steel Beam, Strange Steam, Struggle, Sunsteel Strike, Surging Strikes, Switcheroo, Techno Blast, Thief, Thousand Arrows, Thousand Waves, Thunder Cage, Thunderous Kick, Transform, Trick, V-create, Wicked Blow, or Wide Guard.",
|
|
3699
3701
|
shortDesc: "Picks a random move.",
|
|
3700
3702
|
gen7: {
|
|
3701
3703
|
desc: "A random move is selected for use, other than After You, Assist, Baneful Bunker, Beak Blast, Belch, Bestow, Celebrate, Chatter, Copycat, Counter, Covet, Crafty Shield, Destiny Bond, Detect, Diamond Storm, Dragon Ascent, Endure, Feint, Fleur Cannon, Focus Punch, Follow Me, Freeze Shock, Helping Hand, Hold Hands, Hyperspace Fury, Hyperspace Hole, Ice Burn, Instruct, King's Shield, Light of Ruin, Mat Block, Me First, Metronome, Mimic, Mind Blown, Mirror Coat, Mirror Move, Nature Power, Origin Pulse, Photon Geyser, Plasma Fists, Precipice Blades, Protect, Quash, Quick Guard, Rage Powder, Relic Song, Secret Sword, Shell Trap, Sketch, Sleep Talk, Snarl, Snatch, Snore, Spectral Thief, Spiky Shield, Spotlight, Steam Eruption, Struggle, Switcheroo, Techno Blast, Thief, Thousand Arrows, Thousand Waves, Transform, Trick, V-create, or Wide Guard.",
|
|
@@ -3707,13 +3709,13 @@ export const MovesText: {[k: string]: MoveText} = {
|
|
|
3707
3709
|
desc: "A random move is selected for use, other than After You, Assist, Bestow, Chatter, Copycat, Counter, Covet, Destiny Bond, Detect, Endure, Feint, Focus Punch, Follow Me, Freeze Shock, Helping Hand, Ice Burn, Me First, Metronome, Mimic, Mirror Coat, Mirror Move, Nature Power, Protect, Quash, Quick Guard, Rage Powder, Relic Song, Secret Sword, Sketch, Sleep Talk, Snarl, Snatch, Snore, Struggle, Switcheroo, Techno Blast, Thief, Transform, Trick, V-create, or Wide Guard.",
|
|
3708
3710
|
},
|
|
3709
3711
|
gen4: {
|
|
3710
|
-
desc: "A random move is selected for use, other than Assist, Chatter, Copycat, Counter, Covet, Destiny Bond, Detect, Endure, Feint, Focus Punch, Follow Me, Helping Hand, Me First, Metronome, Mimic, Mirror Coat, Mirror Move, Protect, Sketch, Sleep Talk, Snatch, Struggle, Switcheroo, Thief, or
|
|
3712
|
+
desc: "A random move is selected for use, other than Assist, Chatter, Copycat, Counter, Covet, Destiny Bond, Detect, Endure, Feint, Focus Punch, Follow Me, Helping Hand, Me First, Metronome, Mimic, Mirror Coat, Mirror Move, Protect, Sketch, Sleep Talk, Snatch, Struggle, Switcheroo, Thief, Trick, or any move the user already knows.",
|
|
3711
3713
|
},
|
|
3712
3714
|
gen3: {
|
|
3713
3715
|
desc: "A random move is selected for use, other than Counter, Covet, Destiny Bond, Detect, Endure, Focus Punch, Follow Me, Helping Hand, Metronome, Mimic, Mirror Coat, Protect, Sketch, Sleep Talk, Snatch, Struggle, Thief, or Trick.",
|
|
3714
3716
|
},
|
|
3715
3717
|
gen2: {
|
|
3716
|
-
desc: "A random move is selected for use, other than Counter, Destiny Bond, Detect, Endure, Metronome, Mimic, Mirror Coat, Protect, Sketch, Sleep Talk, Struggle, or
|
|
3718
|
+
desc: "A random move is selected for use, other than Counter, Destiny Bond, Detect, Endure, Metronome, Mimic, Mirror Coat, Protect, Sketch, Sleep Talk, Struggle, Thief, or any move the user already knows.",
|
|
3717
3719
|
},
|
|
3718
3720
|
gen1: {
|
|
3719
3721
|
desc: "A random move is selected for use, other than Metronome or Struggle.",
|
|
@@ -4167,6 +4169,7 @@ export const MovesText: {[k: string]: MoveText} = {
|
|
|
4167
4169
|
},
|
|
4168
4170
|
|
|
4169
4171
|
heal: "#memento",
|
|
4172
|
+
switchOut: "#uturn",
|
|
4170
4173
|
},
|
|
4171
4174
|
payback: {
|
|
4172
4175
|
name: "Payback",
|
package/package.json
CHANGED
package/sim/battle-actions.ts
CHANGED
|
@@ -133,6 +133,8 @@ export class BattleActions {
|
|
|
133
133
|
oldActive.isActive = false;
|
|
134
134
|
oldActive.isStarted = false;
|
|
135
135
|
oldActive.usedItemThisTurn = false;
|
|
136
|
+
oldActive.statsRaisedThisTurn = false;
|
|
137
|
+
oldActive.statsLoweredThisTurn = false;
|
|
136
138
|
oldActive.position = pokemon.position;
|
|
137
139
|
pokemon.position = pos;
|
|
138
140
|
side.pokemon[pokemon.position] = pokemon;
|
|
@@ -178,7 +180,17 @@ export class BattleActions {
|
|
|
178
180
|
}
|
|
179
181
|
runSwitch(pokemon: Pokemon) {
|
|
180
182
|
this.battle.runEvent('Swap', pokemon);
|
|
181
|
-
|
|
183
|
+
|
|
184
|
+
if (this.battle.gen >= 5) {
|
|
185
|
+
this.battle.runEvent('SwitchIn', pokemon);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
this.battle.runEvent('EntryHazard', pokemon);
|
|
189
|
+
|
|
190
|
+
if (this.battle.gen <= 4) {
|
|
191
|
+
this.battle.runEvent('SwitchIn', pokemon);
|
|
192
|
+
}
|
|
193
|
+
|
|
182
194
|
if (this.battle.gen <= 2 && !pokemon.side.faintedThisTurn && pokemon.draggedIn !== this.battle.turn) {
|
|
183
195
|
this.battle.runEvent('AfterSwitchInSelf', pokemon);
|
|
184
196
|
}
|
package/sim/battle.ts
CHANGED
|
@@ -711,7 +711,7 @@ export class Battle {
|
|
|
711
711
|
}
|
|
712
712
|
}
|
|
713
713
|
|
|
714
|
-
if (
|
|
714
|
+
if (['Invulnerability', 'TryHit', 'DamagingHit', 'EntryHazard'].includes(eventid)) {
|
|
715
715
|
handlers.sort(Battle.compareLeftToRightOrder);
|
|
716
716
|
} else if (fastExit) {
|
|
717
717
|
handlers.sort(Battle.compareRedirectOrder);
|
|
@@ -2413,6 +2413,43 @@ export class Battle {
|
|
|
2413
2413
|
|
|
2414
2414
|
this.add('start');
|
|
2415
2415
|
|
|
2416
|
+
// Change Zacian/Zamazenta into their Crowned formes
|
|
2417
|
+
for (const pokemon of this.getAllPokemon()) {
|
|
2418
|
+
let rawSpecies: Species | null = null;
|
|
2419
|
+
if (pokemon.species.id === 'zacian' && pokemon.item === 'rustedsword') {
|
|
2420
|
+
rawSpecies = this.dex.species.get('Zacian-Crowned');
|
|
2421
|
+
} else if (pokemon.species.id === 'zamazenta' && pokemon.item === 'rustedshield') {
|
|
2422
|
+
rawSpecies = this.dex.species.get('Zamazenta-Crowned');
|
|
2423
|
+
}
|
|
2424
|
+
if (!rawSpecies) continue;
|
|
2425
|
+
const species = pokemon.setSpecies(rawSpecies);
|
|
2426
|
+
if (!species) continue;
|
|
2427
|
+
pokemon.baseSpecies = rawSpecies;
|
|
2428
|
+
pokemon.details = species.name + (pokemon.level === 100 ? '' : ', L' + pokemon.level) +
|
|
2429
|
+
(pokemon.gender === '' ? '' : ', ' + pokemon.gender) + (pokemon.set.shiny ? ', shiny' : '');
|
|
2430
|
+
pokemon.setAbility(species.abilities['0'], null, true);
|
|
2431
|
+
pokemon.baseAbility = pokemon.ability;
|
|
2432
|
+
|
|
2433
|
+
const behemothMove: {[k: string]: string} = {
|
|
2434
|
+
'Zacian-Crowned': 'behemothblade', 'Zamazenta-Crowned': 'behemothbash',
|
|
2435
|
+
};
|
|
2436
|
+
const ironHead = pokemon.baseMoves.indexOf('ironhead');
|
|
2437
|
+
if (ironHead >= 0) {
|
|
2438
|
+
const move = this.dex.moves.get(behemothMove[rawSpecies.name]);
|
|
2439
|
+
pokemon.baseMoveSlots[ironHead] = {
|
|
2440
|
+
move: move.name,
|
|
2441
|
+
id: move.id,
|
|
2442
|
+
pp: (move.noPPBoosts || move.isZ) ? move.pp : move.pp * 8 / 5,
|
|
2443
|
+
maxpp: (move.noPPBoosts || move.isZ) ? move.pp : move.pp * 8 / 5,
|
|
2444
|
+
target: move.target,
|
|
2445
|
+
disabled: false,
|
|
2446
|
+
disabledSource: '',
|
|
2447
|
+
used: false,
|
|
2448
|
+
};
|
|
2449
|
+
pokemon.moveSlots = pokemon.baseMoveSlots.slice();
|
|
2450
|
+
}
|
|
2451
|
+
}
|
|
2452
|
+
|
|
2416
2453
|
if (this.format.onBattleStart) this.format.onBattleStart.call(this);
|
|
2417
2454
|
for (const rule of this.ruleTable.keys()) {
|
|
2418
2455
|
if ('+*-!'.includes(rule.charAt(0))) continue;
|
package/sim/dex-conditions.ts
CHANGED
|
@@ -53,6 +53,7 @@ export interface EventMethods {
|
|
|
53
53
|
onDragOut?: (this: Battle, pokemon: Pokemon, source?: Pokemon, move?: ActiveMove) => void;
|
|
54
54
|
onEatItem?: (this: Battle, item: Item, pokemon: Pokemon) => void;
|
|
55
55
|
onEffectiveness?: MoveEventMethods['onEffectiveness'];
|
|
56
|
+
onEntryHazard?: (this: Battle, pokemon: Pokemon) => void;
|
|
56
57
|
onFaint?: CommonHandlers['VoidEffect'];
|
|
57
58
|
onFlinch?: ((this: Battle, pokemon: Pokemon) => boolean | void) | boolean;
|
|
58
59
|
onFractionalPriority?: CommonHandlers['ModifierSourceMove'] | -0.1;
|
|
@@ -312,6 +312,9 @@ export interface ModdedBattlePokemon {
|
|
|
312
312
|
clearBoosts?: (this: Pokemon) => void;
|
|
313
313
|
calculateStat?: (this: Pokemon, statName: StatIDExceptHP, boost: number, modifier?: number) => number;
|
|
314
314
|
cureStatus?: (this: Pokemon, silent?: boolean) => boolean;
|
|
315
|
+
formeChange?: (
|
|
316
|
+
this: Pokemon, speciesId: string | Species, source: Effect, isPermanent?: boolean, message?: string
|
|
317
|
+
) => boolean;
|
|
315
318
|
getAbility?: (this: Pokemon) => Ability;
|
|
316
319
|
getActionSpeed?: (this: Pokemon) => number;
|
|
317
320
|
getItem?: (this: Pokemon) => Item;
|
package/sim/global-types.ts
CHANGED
|
@@ -312,6 +312,9 @@ interface ModdedBattlePokemon {
|
|
|
312
312
|
clearBoosts?: (this: Pokemon) => void;
|
|
313
313
|
calculateStat?: (this: Pokemon, statName: StatIDExceptHP, boost: number, modifier?: number) => number;
|
|
314
314
|
cureStatus?: (this: Pokemon, silent?: boolean) => boolean;
|
|
315
|
+
formeChange?: (
|
|
316
|
+
this: Pokemon, speciesId: string | Species, source: Effect, isPermanent?: boolean, message?: string
|
|
317
|
+
) => boolean;
|
|
315
318
|
getAbility?: (this: Pokemon) => Ability;
|
|
316
319
|
getActionSpeed?: (this: Pokemon) => number;
|
|
317
320
|
getItem?: (this: Pokemon) => Item;
|
package/sim/team-validator.ts
CHANGED
|
@@ -543,6 +543,10 @@ export class TeamValidator {
|
|
|
543
543
|
tierSpecies = dex.species.get('Kyogre-Primal');
|
|
544
544
|
} else if (canMegaEvo && species.id === 'rayquaza' && set.moves.map(toID).includes('dragonascent' as ID)) {
|
|
545
545
|
tierSpecies = dex.species.get('Rayquaza-Mega');
|
|
546
|
+
} else if (item.id === 'rustedsword' && species.id === 'zacian') {
|
|
547
|
+
tierSpecies = dex.species.get('Zacian-Crowned');
|
|
548
|
+
} else if (item.id === 'rustedshield' && species.id === 'zamazenta') {
|
|
549
|
+
tierSpecies = dex.species.get('Zamazenta-Crowned');
|
|
546
550
|
}
|
|
547
551
|
}
|
|
548
552
|
|
|
@@ -1315,10 +1319,10 @@ export class TeamValidator {
|
|
|
1315
1319
|
const crowned: {[k: string]: string} = {
|
|
1316
1320
|
'Zacian-Crowned': 'behemothblade', 'Zamazenta-Crowned': 'behemothbash',
|
|
1317
1321
|
};
|
|
1318
|
-
if (
|
|
1319
|
-
const
|
|
1320
|
-
if (
|
|
1321
|
-
set.moves[
|
|
1322
|
+
if (species.name in crowned) {
|
|
1323
|
+
const behemothMove = set.moves.map(toID).indexOf(crowned[species.name] as ID);
|
|
1324
|
+
if (behemothMove >= 0) {
|
|
1325
|
+
set.moves[behemothMove] = 'ironhead';
|
|
1322
1326
|
}
|
|
1323
1327
|
}
|
|
1324
1328
|
return problems;
|
|
@@ -1328,6 +1332,14 @@ export class TeamValidator {
|
|
|
1328
1332
|
const dex = this.dex;
|
|
1329
1333
|
const ruleTable = this.ruleTable;
|
|
1330
1334
|
|
|
1335
|
+
// https://www.smogon.com/forums/posts/8659168
|
|
1336
|
+
if (
|
|
1337
|
+
(tierSpecies.id === 'zamazentacrowned' && species.id === 'zamazenta') ||
|
|
1338
|
+
(tierSpecies.id === 'zaciancrowned' && species.id === 'zacian')
|
|
1339
|
+
) {
|
|
1340
|
+
species = tierSpecies;
|
|
1341
|
+
}
|
|
1342
|
+
|
|
1331
1343
|
setHas['pokemon:' + species.id] = true;
|
|
1332
1344
|
setHas['basepokemon:' + toID(species.baseSpecies)] = true;
|
|
1333
1345
|
|
|
@@ -19,10 +19,18 @@ export interface ExhaustiveRunnerOptions {
|
|
|
19
19
|
maxGames?: number;
|
|
20
20
|
maxFailures?: number;
|
|
21
21
|
dual?: boolean | 'debug';
|
|
22
|
+
possible?: ExhaustiveRunnerPossibilites;
|
|
22
23
|
runner?: (options: RunnerOptions) => Promise<void>;
|
|
23
24
|
cmd?: (cycles: number, format: string, seed: string) => string;
|
|
24
25
|
}
|
|
25
26
|
|
|
27
|
+
export interface ExhaustiveRunnerPossibilites {
|
|
28
|
+
pokemon?: ID[];
|
|
29
|
+
items?: ID[];
|
|
30
|
+
abilities?: ID[];
|
|
31
|
+
moves?: ID[];
|
|
32
|
+
}
|
|
33
|
+
|
|
26
34
|
export class ExhaustiveRunner {
|
|
27
35
|
static readonly DEFAULT_CYCLES = 1;
|
|
28
36
|
static readonly MAX_FAILURES = 10;
|
|
@@ -46,6 +54,7 @@ export class ExhaustiveRunner {
|
|
|
46
54
|
private readonly maxGames?: number;
|
|
47
55
|
private readonly maxFailures?: number;
|
|
48
56
|
private readonly dual: boolean | 'debug';
|
|
57
|
+
private readonly possible?: ExhaustiveRunnerPossibilites;
|
|
49
58
|
|
|
50
59
|
private readonly runner: (options: RunnerOptions) => Promise<void>;
|
|
51
60
|
private readonly cmd: (cycles: number, format: string, seed: string) => string;
|
|
@@ -63,6 +72,7 @@ export class ExhaustiveRunner {
|
|
|
63
72
|
this.maxFailures = options.maxFailures || ExhaustiveRunner.MAX_FAILURES;
|
|
64
73
|
this.dual = options.dual || false;
|
|
65
74
|
this.runner = options.runner || ((o: RunnerOptions) => new Runner(o).run());
|
|
75
|
+
this.possible = options.possible;
|
|
66
76
|
this.cmd = options.cmd || ((cycles: number, format: string, seed: string) =>
|
|
67
77
|
`node tools/simulate exhaustive --cycles=${cycles} --format=${format} --seed=${seed}`);
|
|
68
78
|
|
|
@@ -93,7 +103,7 @@ export class ExhaustiveRunner {
|
|
|
93
103
|
error: true,
|
|
94
104
|
});
|
|
95
105
|
|
|
96
|
-
if (this.log) this.logProgress(pools);
|
|
106
|
+
if (this.log) this.logProgress(dex, pools);
|
|
97
107
|
} catch (err) {
|
|
98
108
|
this.failures++;
|
|
99
109
|
console.error(
|
|
@@ -110,23 +120,31 @@ export class ExhaustiveRunner {
|
|
|
110
120
|
|
|
111
121
|
private createPools(dex: typeof Dex): Pools {
|
|
112
122
|
return {
|
|
113
|
-
pokemon: new Pool(
|
|
114
|
-
(
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
123
|
+
pokemon: new Pool(this.possible?.pokemon ??
|
|
124
|
+
ExhaustiveRunner.onlyValid(dex.gen, dex.data.Pokedex, p => dex.species.get(p), (_, p) =>
|
|
125
|
+
(p.name !== 'Pichu-Spiky-eared' && p.name.substr(0, 8) !== 'Pikachu-')), this.prng),
|
|
126
|
+
items: new Pool(this.possible?.items ??
|
|
127
|
+
ExhaustiveRunner.onlyValid(dex.gen, dex.data.Items, i => dex.items.get(i)), this.prng),
|
|
128
|
+
abilities: new Pool(this.possible?.abilities ??
|
|
129
|
+
ExhaustiveRunner.onlyValid(dex.gen, dex.data.Abilities, a => dex.abilities.get(a)), this.prng),
|
|
130
|
+
moves: new Pool(this.possible?.moves ??
|
|
131
|
+
ExhaustiveRunner.onlyValid(dex.gen, dex.data.Moves, m => dex.moves.get(m), m =>
|
|
132
|
+
(m !== 'struggle' && (m === 'hiddenpower' || m.substr(0, 11) !== 'hiddenpower'))), this.prng),
|
|
119
133
|
};
|
|
120
134
|
}
|
|
121
135
|
|
|
122
|
-
private logProgress(p: Pools) {
|
|
136
|
+
private logProgress(dex: typeof Dex, p: Pools) {
|
|
123
137
|
// `\r` = return to the beginning of the line
|
|
124
138
|
// `\x1b[k` (`\e[K`) = clear all characters from cursor position to EOL
|
|
125
139
|
if (this.games) process.stdout.write('\r\x1b[K');
|
|
140
|
+
|
|
141
|
+
const msg = [`[${this.format}] P:${p.pokemon}`];
|
|
142
|
+
if (dex.gen >= 2) msg.push(`I:${p.items}`);
|
|
143
|
+
if (dex.gen >= 3) msg.push(`A:${p.abilities}`);
|
|
144
|
+
msg.push(`M:${p.moves} = ${this.games}`);
|
|
145
|
+
|
|
126
146
|
// Deliberately don't print a `\n` character so that we can overwrite
|
|
127
|
-
process.stdout.write(
|
|
128
|
-
`[${this.format}] P:${p.pokemon} I:${p.items} A:${p.abilities} M:${p.moves} = ${this.games}`
|
|
129
|
-
);
|
|
147
|
+
process.stdout.write(msg.join(' '));
|
|
130
148
|
}
|
|
131
149
|
|
|
132
150
|
private static getSignatures(dex: typeof Dex, pools: Pools): Map<string, {item: string, move?: string}[]> {
|