@pkmn/sim 0.5.21 → 0.5.22

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.
Files changed (61) hide show
  1. package/build/config/formats.js +27 -20
  2. package/build/config/formats.js.map +1 -1
  3. package/build/data/abilities.js +1 -3
  4. package/build/data/abilities.js.map +1 -1
  5. package/build/data/conditions.js +4 -1
  6. package/build/data/conditions.js.map +1 -1
  7. package/build/data/formats-data.js +2 -2
  8. package/build/data/formats-data.js.map +1 -1
  9. package/build/data/mods/gen1/conditions.js +3 -0
  10. package/build/data/mods/gen1/conditions.js.map +1 -1
  11. package/build/data/mods/gen1/moves.js +0 -2
  12. package/build/data/mods/gen1/moves.js.map +1 -1
  13. package/build/data/mods/gen2/conditions.js +3 -0
  14. package/build/data/mods/gen2/conditions.js.map +1 -1
  15. package/build/data/mods/gen3/conditions.js +3 -0
  16. package/build/data/mods/gen3/conditions.js.map +1 -1
  17. package/build/data/mods/gen4/abilities.js +1 -1
  18. package/build/data/mods/gen4/abilities.js.map +1 -1
  19. package/build/data/mods/gen4/conditions.js +3 -0
  20. package/build/data/mods/gen4/conditions.js.map +1 -1
  21. package/build/data/mods/gen4/moves.js +9 -2
  22. package/build/data/mods/gen4/moves.js.map +1 -1
  23. package/build/data/mods/gen5/moves.js +4 -7
  24. package/build/data/mods/gen5/moves.js.map +1 -1
  25. package/build/data/mods/gen5/pokedex.js +24 -0
  26. package/build/data/mods/gen5/pokedex.js.map +1 -1
  27. package/build/data/mods/gen7/abilities.js +8 -0
  28. package/build/data/mods/gen7/abilities.js.map +1 -1
  29. package/build/data/mods/gen7/moves.js +2 -2
  30. package/build/data/mods/gen7/moves.js.map +1 -1
  31. package/build/data/moves.js +8 -3
  32. package/build/data/moves.js.map +1 -1
  33. package/build/data/rulesets.js +39 -0
  34. package/build/data/rulesets.js.map +1 -1
  35. package/build/data/tags.js +1 -1
  36. package/build/data/tags.js.map +1 -1
  37. package/build/sim/pokemon.js +8 -2
  38. package/build/sim/pokemon.js.map +1 -1
  39. package/build/sim/side.js +21 -0
  40. package/build/sim/side.js.map +1 -1
  41. package/config/formats.ts +28 -21
  42. package/data/abilities.ts +1 -3
  43. package/data/conditions.ts +5 -1
  44. package/data/formats-data.ts +2 -2
  45. package/data/mods/gen1/conditions.ts +4 -0
  46. package/data/mods/gen1/moves.ts +0 -1
  47. package/data/mods/gen2/conditions.ts +4 -0
  48. package/data/mods/gen3/conditions.ts +4 -0
  49. package/data/mods/gen4/abilities.ts +1 -1
  50. package/data/mods/gen4/conditions.ts +4 -0
  51. package/data/mods/gen4/moves.ts +9 -2
  52. package/data/mods/gen5/moves.ts +4 -7
  53. package/data/mods/gen5/pokedex.ts +24 -0
  54. package/data/mods/gen7/abilities.ts +8 -0
  55. package/data/mods/gen7/moves.ts +2 -2
  56. package/data/moves.ts +8 -3
  57. package/data/rulesets.ts +36 -0
  58. package/data/tags.ts +1 -1
  59. package/package.json +1 -1
  60. package/sim/pokemon.ts +7 -2
  61. package/sim/side.ts +20 -0
package/config/formats.ts CHANGED
@@ -167,7 +167,7 @@ export const Formats: FormatList = [
167
167
  mod: 'gen8',
168
168
  ruleset: ['Little Cup', 'Standard', 'Dynamax Clause'],
169
169
  banlist: [
170
- 'Corsola-Galar', 'Cutiefly', 'Drifloon', 'Gastly', 'Gothita', 'Rufflet', 'Scraggy', 'Scyther', 'Sneasel', 'Swirlix', 'Tangela', 'Vulpix-Alola', 'Woobat', 'Zigzagoon-Base',
170
+ 'Corsola-Galar', 'Cutiefly', 'Drifloon', 'Gastly', 'Gothita', 'Rufflet', 'Scraggy', 'Scyther', 'Sneasel', 'Swirlix', 'Tangela', 'Vullaby', 'Vulpix-Alola', 'Woobat', 'Zigzagoon-Base',
171
171
  'Chlorophyll', 'Moody', 'Baton Pass', 'Sticky Web',
172
172
  ],
173
173
  },
@@ -252,7 +252,7 @@ export const Formats: FormatList = [
252
252
  // LC OU
253
253
  'Abra', 'Carvanha', 'Diglett-Base', 'Dwebble', 'Ferroseed', 'Foongus', 'Frillish', 'Grookey', 'Koffing',
254
254
  'Larvesta', 'Magby', 'Magnemite', 'Mareanie', 'Mienfoo', 'Mudbray', 'Natu', 'Onix', 'Pawniard',
255
- 'Ponyta-Base', 'Porygon', 'Slowpoke-Base', 'Staryu', 'Timburr', 'Trapinch', 'Tyrunt', 'Vullaby',
255
+ 'Ponyta-Base', 'Porygon', 'Slowpoke-Base', 'Staryu', 'Timburr', 'Trapinch', 'Tyrunt',
256
256
  // LC UUBL
257
257
  'Archen', 'Farfetch\u2019d-Galar', 'Scorbunny', 'Shellder', 'Wingull',
258
258
  ],
@@ -289,15 +289,6 @@ export const Formats: FormatList = [
289
289
  ruleset: ['Flat Rules', '!! Adjust Level = 50', 'Min Source Gen = 8', 'Limit Two Restricted'],
290
290
  restricted: ['Restricted Legendary'],
291
291
  },
292
- {
293
- name: "[Gen 8] Single Battle Cup",
294
- threads: [
295
- `&bullet; <a href="https://www.pokemon.com/us/pokemon-news/register-now-for-the-single-battle-cup-competition/">Single Battle Cup</a>`,
296
- ],
297
-
298
- mod: 'gen8',
299
- ruleset: ['Flat Rules', '!! Adjust Level = 50', 'Min Source Gen = 8'],
300
- },
301
292
  {
302
293
  name: "[Gen 8] Custom Game",
303
294
 
@@ -461,6 +452,18 @@ export const Formats: FormatList = [
461
452
  }
462
453
  },
463
454
  },
455
+ {
456
+ name: "[Gen 8] Jump! Magikarp!",
457
+ desc: `Every team must contain Magikarp and bring it to the game.`,
458
+ threads: [
459
+ `&bullet; <a href="https://www.smogon.com/forums/threads/3704588/">Jump! Magikarp!</a>`,
460
+ ],
461
+
462
+ mod: 'gen8',
463
+ gameType: 'doubles',
464
+ ruleset: ['Flat Rules', '!! Picked Team Size = 2', '!! Adjust Level = 50', 'Min Source Gen = 8', 'Force Select = Magikarp'],
465
+ banlist: ['Sub-Legendary'],
466
+ },
464
467
  {
465
468
  name: "[Gen 8] Doubles Custom Game",
466
469
 
@@ -634,11 +637,12 @@ export const Formats: FormatList = [
634
637
  mod: 'gen8',
635
638
  ruleset: ['Standard', '!Sleep Clause Mod', 'Sleep Moves Clause', 'Dynamax Clause'],
636
639
  banlist: [
637
- 'Calyrex-Ice', 'Calyrex-Shadow', 'Cinderace', 'Darmanitan-Galar', 'Dialga', 'Dracovish', 'Eternatus', 'Genesect', 'Giratina', 'Giratina-Origin',
638
- 'Groudon', 'Ho-Oh', 'Kartana', 'Kyogre', 'Kyurem', 'Kyurem-Black', 'Kyurem-White', 'Landorus-Base', 'Lugia', 'Lunala', 'Magearna', 'Marshadow',
639
- 'Mewtwo', 'Naganadel', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane', 'Palkia', 'Pheromosa', 'Rayquaza', 'Regieleki', 'Reshiram', 'Solgaleo',
640
- 'Spectrier', 'Urshifu-Base', 'Xerneas', 'Yveltal', 'Zacian', 'Zacian-Crowned', 'Zamazenta', 'Zamazenta-Crowned', 'Zekrom', 'Zygarde-Base',
641
- 'Arena Trap', 'Magnet Pull', 'Moody', 'Power Construct', 'Shadow Tag', 'TR29 (Baton Pass)', 'TR82 (Stored Power)', 'Baton Pass',
640
+ 'Calyrex-Ice', 'Calyrex-Shadow', 'Cinderace', 'Darmanitan-Galar', 'Dialga', 'Dracovish', 'Dragapult', 'Eternatus', 'Genesect', 'Giratina',
641
+ 'Giratina-Origin', 'Groudon', 'Ho-Oh', 'Kartana', 'Kyogre', 'Kyurem', 'Kyurem-Black', 'Kyurem-White', 'Landorus-Base', 'Lugia', 'Lunala',
642
+ 'Magearna', 'Marshadow', 'Melmetal', 'Mewtwo', 'Naganadel', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane', 'Palkia', 'Pheromosa', 'Rayquaza',
643
+ 'Regieleki', 'Reshiram', 'Rillaboom', 'Solgaleo', 'Spectrier', 'Urshifu-Base', 'Xerneas', 'Yveltal', 'Zacian', 'Zacian-Crowned', 'Zamazenta',
644
+ 'Zamazenta-Crowned', 'Zekrom', 'Zygarde-Base', 'Arena Trap', 'Magnet Pull', 'Moody', 'Power Construct', 'Shadow Tag', 'TR29 (Baton Pass)',
645
+ 'TR82 (Stored Power)', 'Baton Pass',
642
646
  ],
643
647
  onValidateSet(set) {
644
648
  if (!set.item) return;
@@ -2456,7 +2460,10 @@ export const Formats: FormatList = [
2456
2460
  'Picked Team Size = 1', 'Max Team Size = 3',
2457
2461
  '[Gen 3] OU', 'Accuracy Moves Clause', 'Sleep Moves Clause', 'Team Preview', '!Freeze Clause Mod',
2458
2462
  ],
2459
- banlist: ['Clefable', 'Slaking', 'Snorlax', 'Suicune', 'Destiny Bond', 'Explosion', 'Ingrain', 'Perish Song', 'Self-Destruct', 'Bright Powder', 'Focus Band', 'King\'s Rock', 'Lax Incense', 'Quick Claw'],
2463
+ banlist: [
2464
+ 'Clefable', 'Slaking', 'Snorlax', 'Suicune', 'Zapdos', 'Destiny Bond', 'Explosion', 'Ingrain', 'Perish Song',
2465
+ 'Self-Destruct', 'Bright Powder', 'Focus Band', 'King\'s Rock', 'Lax Incense', 'Quick Claw',
2466
+ ],
2460
2467
  unbanlist: ['Mr. Mime', 'Wobbuffet', 'Wynaut', 'Sand Veil'],
2461
2468
  },
2462
2469
  {
@@ -2513,7 +2520,7 @@ export const Formats: FormatList = [
2513
2520
  ],
2514
2521
 
2515
2522
  mod: 'gen5',
2516
- ruleset: ['Standard', 'Evasion Abilities Clause', 'Sleep Moves Clause', 'Swagger Clause'],
2523
+ ruleset: ['Standard', 'Evasion Abilities Clause', 'Sleep Moves Clause', 'Swagger Clause', 'Gems Clause'],
2517
2524
  banlist: ['Uber', 'Arena Trap', 'Drizzle ++ Swift Swim', 'Drought ++ Chlorophyll', 'Sand Rush', 'Shadow Tag', 'King\'s Rock', 'Razor Fang', 'Soul Dew', 'Assist', 'Baton Pass'],
2518
2525
  },
2519
2526
  {
@@ -2548,7 +2555,7 @@ export const Formats: FormatList = [
2548
2555
 
2549
2556
  mod: 'gen2',
2550
2557
  ruleset: ['Standard'],
2551
- banlist: ['Uber'],
2558
+ banlist: ['Uber', 'Mean Look + Baton Pass', 'Spider Web + Baton Pass'],
2552
2559
  },
2553
2560
  {
2554
2561
  name: "[Gen 1] OU",
@@ -2807,7 +2814,7 @@ export const Formats: FormatList = [
2807
2814
  'Arceus', 'Darkrai', 'Deoxys-Base', 'Deoxys-Attack', 'Deoxys-Defense', 'Dialga', 'Giratina', 'Giratina-Origin', 'Groudon', 'Ho-Oh', 'Kangaskhan-Mega',
2808
2815
  'Kyogre', 'Kyurem-Black', 'Kyurem-White', 'Lugia', 'Lunala', 'Marshadow', 'Mewtwo', 'Mimikyu', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane',
2809
2816
  'Palkia', 'Rayquaza', 'Reshiram', 'Salamence-Mega', 'Shaymin-Sky', 'Snorlax', 'Solgaleo', 'Tapu Koko', 'Xerneas', 'Yveltal', 'Zekrom',
2810
- 'Moody', 'Focus Sash', 'Perish Song', 'Detect + Fightinium Z',
2817
+ 'Moody', 'Focus Sash', 'Grass Whistle', 'Hypnosis', 'Perish Song', 'Sing', 'Detect + Fightinium Z',
2811
2818
  ],
2812
2819
  },
2813
2820
  {
@@ -3382,7 +3389,7 @@ export const Formats: FormatList = [
3382
3389
 
3383
3390
  mod: 'gen5',
3384
3391
  searchShow: false,
3385
- ruleset: ['[Gen 5] OU', 'Same Type Clause'],
3392
+ ruleset: ['[Gen 5] OU', 'Same Type Clause', '!Gems Clause'],
3386
3393
  },
3387
3394
  {
3388
3395
  name: "[Gen 5] 1v1",
package/data/abilities.ts CHANGED
@@ -642,7 +642,6 @@ export const Abilities: {[abilityid: string]: AbilityData} = {
642
642
  if (move.auraBooster !== this.effectState.target) return;
643
643
  return this.chainModify([move.hasAuraBreak ? 3072 : 5448, 4096]);
644
644
  },
645
- isBreakable: true,
646
645
  name: "Dark Aura",
647
646
  rating: 3,
648
647
  num: 186,
@@ -956,7 +955,6 @@ export const Abilities: {[abilityid: string]: AbilityData} = {
956
955
  if (move.auraBooster !== this.effectState.target) return;
957
956
  return this.chainModify([move.hasAuraBreak ? 3072 : 5448, 4096]);
958
957
  },
959
- isBreakable: true,
960
958
  name: "Fairy Aura",
961
959
  rating: 3,
962
960
  num: 187,
@@ -2326,7 +2324,7 @@ export const Abilities: {[abilityid: string]: AbilityData} = {
2326
2324
  if (pokemon.showCure === undefined) pokemon.showCure = true;
2327
2325
 
2328
2326
  if (pokemon.showCure) this.add('-curestatus', pokemon, pokemon.status, '[from] ability: Natural Cure');
2329
- pokemon.setStatus('');
2327
+ pokemon.clearStatus();
2330
2328
 
2331
2329
  // only reset .showCure if it's false
2332
2330
  // (once you know a Pokemon has Natural Cure, its cures are always known)
@@ -57,6 +57,10 @@ export const Conditions: {[k: string]: ConditionData} = {
57
57
  // 1-3 turns
58
58
  this.effectState.startTime = this.random(2, 5);
59
59
  this.effectState.time = this.effectState.startTime;
60
+
61
+ if (target.removeVolatile('nightmare')) {
62
+ this.add('-end', target, 'Nightmare', '[silent]');
63
+ }
60
64
  },
61
65
  onBeforeMovePriority: 10,
62
66
  onBeforeMove(pokemon, target, move) {
@@ -101,7 +105,7 @@ export const Conditions: {[k: string]: ConditionData} = {
101
105
  onModifyMove(move, pokemon) {
102
106
  if (move.flags['defrost']) {
103
107
  this.add('-curestatus', pokemon, 'frz', '[from] move: ' + move);
104
- pokemon.setStatus('');
108
+ pokemon.clearStatus();
105
109
  }
106
110
  },
107
111
  onAfterMoveSecondary(target, source, move) {
@@ -4082,7 +4082,7 @@ export const FormatsData: {[k: string]: SpeciesFormatsData} = {
4082
4082
  tier: "Illegal",
4083
4083
  },
4084
4084
  vullaby: {
4085
- tier: "LC",
4085
+ tier: "NFE",
4086
4086
  },
4087
4087
  mandibuzz: {
4088
4088
  randomBattleMoves: ["bravebird", "defog", "foulplay", "roost", "toxic"],
@@ -5594,7 +5594,7 @@ export const FormatsData: {[k: string]: SpeciesFormatsData} = {
5594
5594
  randomBattleLevel: 80,
5595
5595
  randomDoubleBattleMoves: ["airslash", "hydropump", "icebeam", "muddywater", "shadowball", "uturn"],
5596
5596
  randomDoubleBattleLevel: 84,
5597
- tier: "PU",
5597
+ tier: "PUBL",
5598
5598
  doublesTier: "(DUU)",
5599
5599
  },
5600
5600
  inteleongmax: {
@@ -68,6 +68,10 @@ export const Conditions: {[id: string]: ModdedConditionData} = {
68
68
  // 1-7 turns
69
69
  this.effectState.startTime = this.random(1, 8);
70
70
  this.effectState.time = this.effectState.startTime;
71
+
72
+ if (target.removeVolatile('nightmare')) {
73
+ this.add('-end', target, 'Nightmare', '[silent]');
74
+ }
71
75
  },
72
76
  onBeforeMovePriority: 10,
73
77
  onBeforeMove(pokemon, target, move) {
@@ -759,7 +759,6 @@ export const Moves: {[k: string]: ModdedMoveData} = {
759
759
  }
760
760
  // We only prevent when hp is less than one quarter.
761
761
  // If you use substitute at exactly one quarter, you faint.
762
- if (target.hp === target.maxhp / 4) target.faint();
763
762
  if (target.hp < target.maxhp / 4) {
764
763
  this.add('-fail', target, 'move: Substitute', '[weak]');
765
764
  return null;
@@ -35,6 +35,10 @@ export const Conditions: {[k: string]: ModdedConditionData} = {
35
35
  }
36
36
  // 1-6 turns
37
37
  this.effectState.time = this.random(2, 8);
38
+
39
+ if (target.removeVolatile('nightmare')) {
40
+ this.add('-end', target, 'Nightmare', '[silent]');
41
+ }
38
42
  },
39
43
  onBeforeMovePriority: 10,
40
44
  onBeforeMove(pokemon, target, move) {
@@ -12,6 +12,10 @@ export const Conditions: {[k: string]: ModdedConditionData} = {
12
12
  this.effectState.time = this.random(2, 6);
13
13
  // Turns spent using Sleep Talk/Snore immediately before switching out while asleep
14
14
  this.effectState.skippedTime = 0;
15
+
16
+ if (target.removeVolatile('nightmare')) {
17
+ this.add('-end', target, 'Nightmare', '[silent]');
18
+ }
15
19
  },
16
20
  onSwitchIn(target) {
17
21
  this.effectState.time += this.effectState.skippedTime;
@@ -281,7 +281,7 @@ export const Abilities: {[k: string]: ModdedAbilityData} = {
281
281
  // in gen 3-4, Natural Cure's curing is always known to both players
282
282
 
283
283
  this.add('-curestatus', pokemon, pokemon.status, '[from] ability: Natural Cure');
284
- pokemon.setStatus('');
284
+ pokemon.clearStatus();
285
285
  },
286
286
  },
287
287
  normalize: {
@@ -30,6 +30,10 @@ export const Conditions: {[k: string]: ModdedConditionData} = {
30
30
  }
31
31
  // 1-4 turns
32
32
  this.effectState.time = this.random(2, 6);
33
+
34
+ if (target.removeVolatile('nightmare')) {
35
+ this.add('-end', target, 'Nightmare', '[silent]');
36
+ }
33
37
  },
34
38
  onBeforeMovePriority: 10,
35
39
  onBeforeMove(pokemon, target, move) {
@@ -759,7 +759,7 @@ export const Moves: {[k: string]: ModdedMoveData} = {
759
759
  onSwitchIn(target) {
760
760
  if (target.hp > 0) {
761
761
  target.heal(target.maxhp);
762
- target.setStatus('');
762
+ target.clearStatus();
763
763
  this.add('-heal', target, target.getHealth, '[from] move: Healing Wish');
764
764
  target.side.removeSlotCondition(target, 'healingwish');
765
765
  target.lastMove = this.lastMove;
@@ -940,7 +940,7 @@ export const Moves: {[k: string]: ModdedMoveData} = {
940
940
  }
941
941
  if (target.hp > 0) {
942
942
  target.heal(target.maxhp);
943
- target.setStatus('');
943
+ target.clearStatus();
944
944
  for (const moveSlot of target.moveSlots) {
945
945
  moveSlot.pp = moveSlot.maxpp;
946
946
  }
@@ -1395,6 +1395,13 @@ export const Moves: {[k: string]: ModdedMoveData} = {
1395
1395
  inherit: true,
1396
1396
  accuracy: 90,
1397
1397
  },
1398
+ secretpower: {
1399
+ inherit: true,
1400
+ secondary: {
1401
+ chance: 30,
1402
+ status: 'par',
1403
+ },
1404
+ },
1398
1405
  sketch: {
1399
1406
  inherit: true,
1400
1407
  onHit(target, source) {
@@ -753,13 +753,10 @@ export const Moves: {[k: string]: ModdedMoveData} = {
753
753
  },
754
754
  secretpower: {
755
755
  inherit: true,
756
- condition: {
757
- duration: 1,
758
- onAfterMoveSecondarySelf(source, target, move) {
759
- if (this.randomChance(3, 10)) {
760
- this.boost({accuracy: -1}, target, source);
761
- }
762
- source.removeVolatile('secretpower');
756
+ secondary: {
757
+ chance: 30,
758
+ boosts: {
759
+ accuracy: -1,
763
760
  },
764
761
  },
765
762
  },
@@ -422,6 +422,30 @@ export const Pokedex: {[k: string]: ModdedSpeciesData} = {
422
422
  inherit: true,
423
423
  baseStats: {hp: 85, atk: 100, def: 90, spa: 45, spd: 90, spe: 80},
424
424
  },
425
+ pansage: {
426
+ inherit: true,
427
+ maleOnlyHidden: true,
428
+ },
429
+ simisage: {
430
+ inherit: true,
431
+ maleOnlyHidden: true,
432
+ },
433
+ pansear: {
434
+ inherit: true,
435
+ maleOnlyHidden: true,
436
+ },
437
+ simisear: {
438
+ inherit: true,
439
+ maleOnlyHidden: true,
440
+ },
441
+ panpour: {
442
+ inherit: true,
443
+ maleOnlyHidden: true,
444
+ },
445
+ simipour: {
446
+ inherit: true,
447
+ maleOnlyHidden: true,
448
+ },
425
449
  unfezant: {
426
450
  inherit: true,
427
451
  baseStats: {hp: 80, atk: 105, def: 80, spa: 65, spd: 55, spe: 93},
@@ -8,6 +8,14 @@ export const Abilities: {[k: string]: ModdedAbilityData} = {
8
8
  }
9
9
  },
10
10
  },
11
+ darkaura: {
12
+ inherit: true,
13
+ isBreakable: true,
14
+ },
15
+ fairyaura: {
16
+ inherit: true,
17
+ isBreakable: true,
18
+ },
11
19
  innerfocus: {
12
20
  inherit: true,
13
21
  rating: 1,
@@ -381,7 +381,7 @@ export const Moves: {[k: string]: ModdedMoveData} = {
381
381
  onSwitchIn(target) {
382
382
  if (!target.fainted) {
383
383
  target.heal(target.maxhp);
384
- target.setStatus('');
384
+ target.clearStatus();
385
385
  this.add('-heal', target, target.getHealth, '[from] move: Healing Wish');
386
386
  target.side.removeSlotCondition(target, 'healingwish');
387
387
  }
@@ -608,7 +608,7 @@ export const Moves: {[k: string]: ModdedMoveData} = {
608
608
  onSwitchIn(target) {
609
609
  if (!target.fainted) {
610
610
  target.heal(target.maxhp);
611
- target.setStatus('');
611
+ target.clearStatus();
612
612
  for (const moveSlot of target.moveSlots) {
613
613
  moveSlot.pp = moveSlot.maxpp;
614
614
  }
package/data/moves.ts CHANGED
@@ -7828,7 +7828,7 @@ export const Moves: {[moveid: string]: MoveData} = {
7828
7828
  onSwap(target) {
7829
7829
  if (!target.fainted && (target.hp < target.maxhp || target.status)) {
7830
7830
  target.heal(target.maxhp);
7831
- target.setStatus('');
7831
+ target.clearStatus();
7832
7832
  this.add('-heal', target, target.getHealth, '[from] move: Healing Wish');
7833
7833
  target.side.removeSlotCondition(target, 'healingwish');
7834
7834
  }
@@ -9081,7 +9081,12 @@ export const Moves: {[moveid: string]: MoveData} = {
9081
9081
  return false;
9082
9082
  }
9083
9083
  this.add('-singleturn', target, 'move: Instruct', '[of] ' + source);
9084
- this.actions.runMove(target.lastMove.id, target, target.lastMoveTargetLoc!);
9084
+ this.queue.prioritizeAction(this.queue.resolveAction({
9085
+ choice: 'move',
9086
+ pokemon: target,
9087
+ moveid: target.lastMove.id,
9088
+ targetLoc: target.lastMoveTargetLoc!,
9089
+ })[0] as MoveAction);
9085
9090
  },
9086
9091
  secondary: null,
9087
9092
  target: "normal",
@@ -9929,7 +9934,7 @@ export const Moves: {[moveid: string]: MoveData} = {
9929
9934
  )
9930
9935
  ) {
9931
9936
  target.heal(target.maxhp);
9932
- target.setStatus('');
9937
+ target.clearStatus();
9933
9938
  for (const moveSlot of target.moveSlots) {
9934
9939
  moveSlot.pp = moveSlot.maxpp;
9935
9940
  }
package/data/rulesets.ts CHANGED
@@ -399,6 +399,29 @@ export const Rulesets: {[k: string]: FormatData} = {
399
399
  }
400
400
  },
401
401
  },
402
+ forceselect: {
403
+ effectType: 'ValidatorRule',
404
+ name: 'Force Select',
405
+ desc: `Forces a Pokemon to be on the team and selected at Team Preview. Usage: Force Select = [Pokemon], e.g. "Force Select = Magikarp"`,
406
+ hasValue: true,
407
+ onValidateRule(value) {
408
+ if (!this.dex.species.get(value).exists) throw new Error(`Misspelled Pokemon "${value}"`);
409
+ },
410
+ onValidateTeam(team) {
411
+ let hasSelection = false;
412
+ const species = this.dex.species.get(this.ruleTable.valueRules.get('forceselect'));
413
+ for (const set of team) {
414
+ if (species.name === set.species) {
415
+ hasSelection = true;
416
+ break;
417
+ }
418
+ }
419
+ if (!hasSelection) {
420
+ return [`Your team must contain ${species.name}.`];
421
+ }
422
+ },
423
+ // hardcoded in sim/side
424
+ },
402
425
  evlimits: {
403
426
  effectType: 'ValidatorRule',
404
427
  name: 'EV Limits',
@@ -1262,6 +1285,19 @@ export const Rulesets: {[k: string]: FormatData} = {
1262
1285
  }
1263
1286
  },
1264
1287
  },
1288
+ gemsclause: {
1289
+ effectType: 'ValidatorRule',
1290
+ name: 'Gems Clause',
1291
+ desc: "Bans all Gems",
1292
+ onValidateSet(set) {
1293
+ if (!set.item) return;
1294
+ const item = this.dex.items.get(set.item);
1295
+ if (item.isGem) {
1296
+ if (this.ruleTable.has(`+item:${item.id}`)) return;
1297
+ return [`${item.name} is banned due to Gems Clause.`];
1298
+ }
1299
+ },
1300
+ },
1265
1301
  'sketchgen8moves': {
1266
1302
  effectType: 'ValidatorRule',
1267
1303
  name: 'Sketch Gen 8 Moves',
package/data/tags.ts CHANGED
@@ -200,7 +200,7 @@ export const Tags: {[id: string]: TagData} = {
200
200
  'Aerodactyl-Mega', 'Alakazam', 'Blacephalon', 'Blaziken', 'Diancie-Mega', 'Gallade-Mega', 'Gardevoir-Mega', 'Gengar', 'Gyarados',
201
201
  'Gyarados-Mega', 'Hawlucha', 'Heracross-Mega', 'Hoopa-Unbound', 'Hydreigon', 'Jirachi', 'Latias', 'Latias-Mega', 'Latios',
202
202
  'Latios-Mega', 'Manaphy', 'Medicham-Mega', 'Melmetal', 'Mew', 'Moltres-Galar', 'Pinsir-Mega', 'Sableye-Mega', 'Slowbro-Mega',
203
- 'Slowking-Galar', 'Thundurus', 'Thundurus-Therian', 'Venusaur-Mega', 'Xurkitree', 'Zapdos-Galar',
203
+ 'Slowking-Galar', 'Thundurus', 'Venusaur-Mega', 'Xurkitree', 'Zapdos-Galar',
204
204
  ].includes(species.name),
205
205
  },
206
206
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pkmn/sim",
3
- "version": "0.5.21",
3
+ "version": "0.5.22",
4
4
  "description": "An automatically generated extraction of just the simulator portion of Pokémon Showdown",
5
5
  "homepage": "https://psim.us",
6
6
  "main": "build/sim/index.js",
package/sim/pokemon.ts CHANGED
@@ -1522,7 +1522,7 @@ export class Pokemon {
1522
1522
  cureStatus(silent = false) {
1523
1523
  if (!this.hp || !this.status) return false;
1524
1524
  this.battle.add('-curestatus', this, this.status, silent ? '[silent]' : '[msg]');
1525
- if (this.status === 'slp' && !this.hasAbility('comatose') && this.removeVolatile('nightmare')) {
1525
+ if (this.status === 'slp' && this.removeVolatile('nightmare')) {
1526
1526
  this.battle.add('-end', this, 'Nightmare', '[silent]');
1527
1527
  }
1528
1528
  this.setStatus('');
@@ -1599,7 +1599,12 @@ export class Pokemon {
1599
1599
  * Unlike cureStatus, does not give cure message
1600
1600
  */
1601
1601
  clearStatus() {
1602
- return this.setStatus('');
1602
+ if (!this.hp || !this.status) return false;
1603
+ if (this.status === 'slp' && this.removeVolatile('nightmare')) {
1604
+ this.battle.add('-end', this, 'Nightmare', '[silent]');
1605
+ }
1606
+ this.setStatus('');
1607
+ return true;
1603
1608
  }
1604
1609
 
1605
1610
  getStatus() {
package/sim/side.ts CHANGED
@@ -796,6 +796,26 @@ export class Side {
796
796
  }
797
797
  }
798
798
  }
799
+ if (ruleTable.valueRules.has('forceselect')) {
800
+ const species = this.battle.dex.species.get(ruleTable.valueRules.get('forceselect'));
801
+ if (!data) {
802
+ // autoChoose
803
+ positions = [...this.pokemon.keys()].filter(pos => this.pokemon[pos].species.name === species.name)
804
+ .concat([...this.pokemon.keys()].filter(pos => this.pokemon[pos].species.name !== species.name))
805
+ .slice(0, pickedTeamSize);
806
+ } else {
807
+ let hasSelection = false;
808
+ for (const pos of positions) {
809
+ if (this.pokemon[pos].species.name === species.name) {
810
+ hasSelection = true;
811
+ break;
812
+ }
813
+ }
814
+ if (!hasSelection) {
815
+ return this.emitChoiceError(`You must bring ${species.name} to the battle.`);
816
+ }
817
+ }
818
+ }
799
819
  for (const [index, pos] of positions.entries()) {
800
820
  this.choice.switchIns.add(pos);
801
821
  this.choice.actions.push({