@pkmn/sim 0.5.11 → 0.5.14

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 (68) hide show
  1. package/README.md +5 -0
  2. package/build/config/formats.js +356 -288
  3. package/build/config/formats.js.map +1 -1
  4. package/build/data/abilities.js +9 -9
  5. package/build/data/abilities.js.map +1 -1
  6. package/build/data/aliases.js +2 -0
  7. package/build/data/aliases.js.map +1 -1
  8. package/build/data/conditions.js +8 -12
  9. package/build/data/conditions.js.map +1 -1
  10. package/build/data/formats-data.js +33 -32
  11. package/build/data/formats-data.js.map +1 -1
  12. package/build/data/items.js +1 -1
  13. package/build/data/items.js.map +1 -1
  14. package/build/data/mods/gen1/formats-data.js +38 -36
  15. package/build/data/mods/gen1/formats-data.js.map +1 -1
  16. package/build/data/mods/gen1/moves.js +2 -4
  17. package/build/data/mods/gen1/moves.js.map +1 -1
  18. package/build/data/mods/gen3/formats-data.js +1 -1
  19. package/build/data/mods/gen3/formats-data.js.map +1 -1
  20. package/build/data/mods/gen6/formats-data.js +3 -3
  21. package/build/data/mods/gen6/formats-data.js.map +1 -1
  22. package/build/data/moves.js +34 -19
  23. package/build/data/moves.js.map +1 -1
  24. package/build/data/pokedex.js +2 -2
  25. package/build/data/pokedex.js.map +1 -1
  26. package/build/data/rulesets.js +1 -1
  27. package/build/data/rulesets.js.map +1 -1
  28. package/build/data/text/moves.js +1 -0
  29. package/build/data/text/moves.js.map +1 -1
  30. package/build/sim/battle.js +13 -11
  31. package/build/sim/battle.js.map +1 -1
  32. package/build/sim/dex-conditions.js +11 -3
  33. package/build/sim/dex-conditions.js.map +1 -1
  34. package/build/sim/dex-data.js +1 -0
  35. package/build/sim/dex-data.js.map +1 -1
  36. package/build/sim/dex-formats.js +1 -0
  37. package/build/sim/dex-formats.js.map +1 -1
  38. package/build/sim/dex-items.js +1 -0
  39. package/build/sim/dex-items.js.map +1 -1
  40. package/build/sim/dex-moves.js +1 -0
  41. package/build/sim/dex-moves.js.map +1 -1
  42. package/build/sim/dex-species.js +1 -0
  43. package/build/sim/dex-species.js.map +1 -1
  44. package/build/sim/team-validator.js +1 -1
  45. package/build/sim/team-validator.js.map +1 -1
  46. package/config/formats.ts +343 -272
  47. package/data/abilities.ts +9 -9
  48. package/data/aliases.ts +2 -0
  49. package/data/conditions.ts +8 -10
  50. package/data/formats-data.ts +33 -32
  51. package/data/items.ts +1 -1
  52. package/data/mods/gen1/formats-data.ts +38 -36
  53. package/data/mods/gen1/moves.ts +2 -4
  54. package/data/mods/gen3/formats-data.ts +1 -1
  55. package/data/mods/gen6/formats-data.ts +3 -3
  56. package/data/moves.ts +33 -19
  57. package/data/pokedex.ts +2 -2
  58. package/data/rulesets.ts +1 -1
  59. package/data/text/moves.ts +2 -0
  60. package/package.json +2 -2
  61. package/sim/battle.ts +4 -1
  62. package/sim/dex-conditions.ts +10 -3
  63. package/sim/dex-data.ts +1 -0
  64. package/sim/dex-formats.ts +1 -0
  65. package/sim/dex-items.ts +1 -0
  66. package/sim/dex-moves.ts +1 -0
  67. package/sim/dex-species.ts +1 -0
  68. package/sim/team-validator.ts +1 -1
@@ -61,7 +61,7 @@ export const FormatsData: {[k: string]: ModdedSpeciesFormatsData} = {
61
61
  butterfree: {
62
62
  randomBattleMoves: ["psychic", "sleeppowder", "stunspore"],
63
63
  exclusiveMoves: ["megadrain", "psywave"],
64
- tier: "NU",
64
+ tier: "PU",
65
65
  },
66
66
  weedle: {
67
67
  randomBattleMoves: ["poisonsting", "stringshot"],
@@ -75,25 +75,27 @@ export const FormatsData: {[k: string]: ModdedSpeciesFormatsData} = {
75
75
  randomBattleMoves: ["megadrain", "swordsdance", "twineedle"],
76
76
  exclusiveMoves: ["doubleedge", "doubleedge", "hyperbeam"],
77
77
  comboMoves: ["agility", "hyperbeam", "swordsdance", "twineedle"],
78
- tier: "NU",
78
+ tier: "PU",
79
79
  },
80
80
  pidgey: {
81
81
  randomBattleMoves: ["agility", "doubleedge", "skyattack"],
82
- exclusiveMoves: ["mimic", "mirrormove", "reflect", "sandattack", "substitute", "toxic"],
82
+ exclusiveMoves: ["mimic", "mirrormove", "reflect", "sandattack", "substitute", "quickattack", "toxic"],
83
83
  tier: "LC",
84
84
  },
85
85
  pidgeotto: {
86
86
  randomBattleMoves: ["agility", "doubleedge", "skyattack"],
87
- exclusiveMoves: ["mimic", "mirrormove", "reflect", "sandattack", "substitute", "toxic"],
87
+ exclusiveMoves: ["mimic", "mirrormove", "reflect", "sandattack", "substitute", "quickattack", "toxic"],
88
88
  tier: "NFE",
89
89
  },
90
90
  pidgeot: {
91
91
  randomBattleMoves: ["agility", "doubleedge", "hyperbeam"],
92
- exclusiveMoves: ["mimic", "mirrormove", "reflect", "sandattack", "skyattack", "skyattack", "substitute", "toxic"],
93
- tier: "NU",
92
+ exclusiveMoves: ["mimic", "mirrormove", "reflect", "sandattack", "skyattack", "skyattack", "substitute", "quickattack", "toxic"],
93
+ tier: "PU",
94
94
  },
95
95
  rattata: {
96
- randomBattleMoves: ["blizzard", "bodyslam", "thunderbolt"],
96
+ randomBattleMoves: ["blizzard", "bodyslam"],
97
+ // The two Thunderbolts are not a mistake, but specifically requested
98
+ exclusiveMoves: ["thunderbolt", "thunderbolt", "quickattack"],
97
99
  essentialMove: "superfang",
98
100
  tier: "LC",
99
101
  },
@@ -109,7 +111,7 @@ export const FormatsData: {[k: string]: ModdedSpeciesFormatsData} = {
109
111
  },
110
112
  fearow: {
111
113
  randomBattleMoves: ["agility", "doubleedge", "drillpeck", "hyperbeam"],
112
- tier: "NU",
114
+ tier: "PU",
113
115
  },
114
116
  ekans: {
115
117
  randomBattleMoves: ["bodyslam", "earthquake", "glare", "rockslide"],
@@ -118,7 +120,7 @@ export const FormatsData: {[k: string]: ModdedSpeciesFormatsData} = {
118
120
  arbok: {
119
121
  randomBattleMoves: ["earthquake", "glare", "hyperbeam"],
120
122
  exclusiveMoves: ["bodyslam", "rockslide"],
121
- tier: "NU",
123
+ tier: "PU",
122
124
  },
123
125
  pikachu: {
124
126
  randomBattleMoves: ["surf", "thunderwave"],
@@ -140,7 +142,7 @@ export const FormatsData: {[k: string]: ModdedSpeciesFormatsData} = {
140
142
  sandslash: {
141
143
  randomBattleMoves: ["bodyslam", "rockslide", "swordsdance"],
142
144
  essentialMove: "earthquake",
143
- tier: "NU",
145
+ tier: "PU",
144
146
  },
145
147
  nidoranf: {
146
148
  randomBattleMoves: ["blizzard", "bodyslam", "thunderbolt"],
@@ -155,7 +157,7 @@ export const FormatsData: {[k: string]: ModdedSpeciesFormatsData} = {
155
157
  nidoqueen: {
156
158
  randomBattleMoves: ["blizzard", "bodyslam", "thunderbolt"],
157
159
  essentialMove: "earthquake",
158
- tier: "NU",
160
+ tier: "PU",
159
161
  },
160
162
  nidoranm: {
161
163
  randomBattleMoves: ["blizzard", "bodyslam", "thunderbolt"],
@@ -211,7 +213,7 @@ export const FormatsData: {[k: string]: ModdedSpeciesFormatsData} = {
211
213
  },
212
214
  golbat: {
213
215
  randomBattleMoves: ["confuseray", "doubleedge", "hyperbeam", "megadrain"],
214
- tier: "NU",
216
+ tier: "PU",
215
217
  },
216
218
  oddish: {
217
219
  randomBattleMoves: ["doubleedge", "sleeppowder"],
@@ -228,7 +230,7 @@ export const FormatsData: {[k: string]: ModdedSpeciesFormatsData} = {
228
230
  vileplume: {
229
231
  randomBattleMoves: ["bodyslam", "sleeppowder", "stunspore", "swordsdance"],
230
232
  essentialMove: "megadrain",
231
- tier: "NU",
233
+ tier: "PU",
232
234
  },
233
235
  paras: {
234
236
  randomBattleMoves: ["bodyslam", "megadrain"],
@@ -240,7 +242,7 @@ export const FormatsData: {[k: string]: ModdedSpeciesFormatsData} = {
240
242
  randomBattleMoves: ["bodyslam", "megadrain"],
241
243
  essentialMove: "spore",
242
244
  exclusiveMoves: ["growth", "hyperbeam", "slash", "stunspore", "stunspore", "swordsdance"],
243
- tier: "NU",
245
+ tier: "PU",
244
246
  },
245
247
  venonat: {
246
248
  randomBattleMoves: ["psychic", "sleeppowder", "stunspore"],
@@ -294,7 +296,7 @@ export const FormatsData: {[k: string]: ModdedSpeciesFormatsData} = {
294
296
  primeape: {
295
297
  randomBattleMoves: ["bodyslam", "rockslide", "submission"],
296
298
  exclusiveMoves: ["counter", "hyperbeam", "hyperbeam"],
297
- tier: "NU",
299
+ tier: "PU",
298
300
  },
299
301
  growlithe: {
300
302
  randomBattleMoves: ["bodyslam", "fireblast", "flamethrower", "reflect"],
@@ -303,7 +305,7 @@ export const FormatsData: {[k: string]: ModdedSpeciesFormatsData} = {
303
305
  arcanine: {
304
306
  randomBattleMoves: ["bodyslam", "fireblast", "hyperbeam"],
305
307
  exclusiveMoves: ["flamethrower", "reflect"],
306
- tier: "NU",
308
+ tier: "PU",
307
309
  },
308
310
  poliwag: {
309
311
  randomBattleMoves: ["blizzard", "surf"],
@@ -315,7 +317,7 @@ export const FormatsData: {[k: string]: ModdedSpeciesFormatsData} = {
315
317
  randomBattleMoves: ["blizzard", "surf"],
316
318
  essentialMove: "amnesia",
317
319
  exclusiveMoves: ["counter", "hypnosis", "hypnosis", "psychic"],
318
- tier: "NFE",
320
+ tier: "NU",
319
321
  },
320
322
  poliwrath: {
321
323
  randomBattleMoves: ["blizzard", "bodyslam", "earthquake", "submission"],
@@ -352,7 +354,7 @@ export const FormatsData: {[k: string]: ModdedSpeciesFormatsData} = {
352
354
  machamp: {
353
355
  randomBattleMoves: ["bodyslam", "earthquake", "submission"],
354
356
  exclusiveMoves: ["counter", "hyperbeam", "rockslide", "rockslide"],
355
- tier: "NU",
357
+ tier: "PU",
356
358
  },
357
359
  bellsprout: {
358
360
  randomBattleMoves: ["doubleedge", "sleeppowder", "stunspore", "swordsdance"],
@@ -400,7 +402,7 @@ export const FormatsData: {[k: string]: ModdedSpeciesFormatsData} = {
400
402
  },
401
403
  rapidash: {
402
404
  randomBattleMoves: ["agility", "bodyslam", "fireblast", "hyperbeam"],
403
- tier: "NU",
405
+ tier: "PU",
404
406
  },
405
407
  slowpoke: {
406
408
  randomBattleMoves: ["earthquake", "surf"],
@@ -422,12 +424,12 @@ export const FormatsData: {[k: string]: ModdedSpeciesFormatsData} = {
422
424
  magneton: {
423
425
  randomBattleMoves: ["thunder", "thunderbolt", "thunderwave"],
424
426
  exclusiveMoves: ["doubleedge", "hyperbeam", "hyperbeam", "mimic", "substitute", "toxic"],
425
- tier: "NU",
427
+ tier: "PU",
426
428
  },
427
429
  farfetchd: {
428
430
  randomBattleMoves: ["agility", "bodyslam", "swordsdance"],
429
431
  essentialMove: "slash",
430
- tier: "NU",
432
+ tier: "PU",
431
433
  },
432
434
  doduo: {
433
435
  randomBattleMoves: ["agility", "bodyslam", "doubleedge", "drillpeck"],
@@ -457,7 +459,7 @@ export const FormatsData: {[k: string]: ModdedSpeciesFormatsData} = {
457
459
  randomBattleMoves: ["bodyslam", "sludge"],
458
460
  essentialMove: "explosion",
459
461
  exclusiveMoves: ["fireblast", "hyperbeam", "megadrain", "megadrain"],
460
- tier: "NU",
462
+ tier: "PU",
461
463
  },
462
464
  shellder: {
463
465
  randomBattleMoves: ["blizzard", "doubleedge", "explosion", "surf"],
@@ -488,7 +490,7 @@ export const FormatsData: {[k: string]: ModdedSpeciesFormatsData} = {
488
490
  },
489
491
  onix: {
490
492
  randomBattleMoves: ["bodyslam", "earthquake", "explosion", "rockslide"],
491
- tier: "NU",
493
+ tier: "PU",
492
494
  },
493
495
  drowzee: {
494
496
  randomBattleMoves: ["hypnosis", "psychic", "thunderwave"],
@@ -516,13 +518,13 @@ export const FormatsData: {[k: string]: ModdedSpeciesFormatsData} = {
516
518
  electrode: {
517
519
  randomBattleMoves: ["explosion", "thunderbolt", "thunderwave"],
518
520
  exclusiveMoves: ["hyperbeam", "screech", "thunder", "toxic"],
519
- tier: "NU",
521
+ tier: "PU",
520
522
  },
521
523
  exeggcute: {
522
524
  randomBattleMoves: ["sleeppowder", "stunspore"],
523
525
  essentialMove: "psychic",
524
526
  exclusiveMoves: ["doubleedge", "explosion", "explosion"],
525
- tier: "LC",
527
+ tier: "NU",
526
528
  },
527
529
  exeggutor: {
528
530
  randomBattleMoves: ["explosion", "psychic", "sleeppowder"],
@@ -535,23 +537,23 @@ export const FormatsData: {[k: string]: ModdedSpeciesFormatsData} = {
535
537
  },
536
538
  marowak: {
537
539
  randomBattleMoves: ["blizzard", "bodyslam", "earthquake", "seismictoss"],
538
- tier: "NU",
540
+ tier: "PU",
539
541
  },
540
542
  hitmonlee: {
541
543
  randomBattleMoves: ["bodyslam", "highjumpkick", "seismictoss"],
542
544
  exclusiveMoves: ["counter", "counter", "meditate"],
543
- tier: "NU",
545
+ tier: "PU",
544
546
  },
545
547
  hitmonchan: {
546
548
  randomBattleMoves: ["bodyslam", "seismictoss", "submission"],
547
549
  exclusiveMoves: ["agility", "counter", "counter"],
548
- tier: "NU",
550
+ tier: "PU",
549
551
  },
550
552
  lickitung: {
551
553
  randomBattleMoves: ["hyperbeam", "swordsdance"],
552
554
  essentialMove: "bodyslam",
553
555
  exclusiveMoves: ["blizzard", "earthquake", "earthquake", "earthquake"],
554
- tier: "NU",
556
+ tier: "PU",
555
557
  },
556
558
  koffing: {
557
559
  randomBattleMoves: ["explosion", "fireblast", "sludge", "thunderbolt"],
@@ -559,7 +561,7 @@ export const FormatsData: {[k: string]: ModdedSpeciesFormatsData} = {
559
561
  },
560
562
  weezing: {
561
563
  randomBattleMoves: ["explosion", "fireblast", "sludge", "thunderbolt"],
562
- tier: "NU",
564
+ tier: "PU",
563
565
  },
564
566
  rhyhorn: {
565
567
  randomBattleMoves: ["bodyslam", "earthquake", "rockslide", "substitute"],
@@ -606,7 +608,7 @@ export const FormatsData: {[k: string]: ModdedSpeciesFormatsData} = {
606
608
  seaking: {
607
609
  randomBattleMoves: ["blizzard", "doubleedge", "surf"],
608
610
  exclusiveMoves: ["agility", "agility", "hyperbeam"],
609
- tier: "NU",
611
+ tier: "PU",
610
612
  },
611
613
  staryu: {
612
614
  randomBattleMoves: ["blizzard", "thunderbolt", "thunderwave"],
@@ -626,7 +628,7 @@ export const FormatsData: {[k: string]: ModdedSpeciesFormatsData} = {
626
628
  },
627
629
  scyther: {
628
630
  randomBattleMoves: ["agility", "hyperbeam", "slash", "swordsdance"],
629
- tier: "NU",
631
+ tier: "PU",
630
632
  },
631
633
  jynx: {
632
634
  randomBattleMoves: ["blizzard", "lovelykiss", "psychic"],
@@ -640,12 +642,12 @@ export const FormatsData: {[k: string]: ModdedSpeciesFormatsData} = {
640
642
  magmar: {
641
643
  randomBattleMoves: ["bodyslam", "confuseray", "fireblast"],
642
644
  exclusiveMoves: ["hyperbeam", "psychic"],
643
- tier: "NU",
645
+ tier: "PU",
644
646
  },
645
647
  pinsir: {
646
648
  randomBattleMoves: ["bodyslam", "hyperbeam", "swordsdance"],
647
649
  exclusiveMoves: ["seismictoss", "submission", "submission"],
648
- tier: "NU",
650
+ tier: "PU",
649
651
  },
650
652
  tauros: {
651
653
  randomBattleMoves: ["bodyslam", "earthquake", "hyperbeam"],
@@ -669,7 +671,7 @@ export const FormatsData: {[k: string]: ModdedSpeciesFormatsData} = {
669
671
  },
670
672
  ditto: {
671
673
  randomBattleMoves: ["transform"],
672
- tier: "NU",
674
+ tier: "PU",
673
675
  },
674
676
  eevee: {
675
677
  randomBattleMoves: ["doubleedge", "quickattack", "reflect"],
@@ -690,7 +692,7 @@ export const FormatsData: {[k: string]: ModdedSpeciesFormatsData} = {
690
692
  },
691
693
  flareon: {
692
694
  randomBattleMoves: ["bodyslam", "fireblast", "hyperbeam", "quickattack"],
693
- tier: "NU",
695
+ tier: "PU",
694
696
  },
695
697
  porygon: {
696
698
  randomBattleMoves: ["blizzard", "thunderwave"],
@@ -196,12 +196,10 @@ export const Moves: {[k: string]: ModdedMoveData} = {
196
196
  },
197
197
  conversion: {
198
198
  inherit: true,
199
- volatileStatus: 'conversion',
200
- accuracy: true,
201
199
  target: "normal",
202
200
  onHit(target, source) {
203
- source.types = target.types;
204
- this.add('-start', source, 'typechange', source.types.join(', '), '[from] move: Conversion', '[of] ' + source);
201
+ source.setType(target.getTypes(true));
202
+ this.add('-start', source, 'typechange', source.types.join('/'), '[from] move: Conversion', '[of] ' + target);
205
203
  },
206
204
  },
207
205
  counter: {
@@ -694,7 +694,7 @@ export const FormatsData: {[k: string]: ModdedSpeciesFormatsData} = {
694
694
  tier: "NFE",
695
695
  },
696
696
  azumarill: {
697
- randomBattleMoves: ["encore", "focuspunch", "hiddenpowerghost", "hydropump", "return", "substitute"],
697
+ randomBattleMoves: ["brickbreak", "encore", "hiddenpowerghost", "hydropump", "return"],
698
698
  tier: "UU",
699
699
  },
700
700
  sudowoodo: {
@@ -2245,7 +2245,7 @@ export const FormatsData: {[k: string]: ModdedSpeciesFormatsData} = {
2245
2245
  doublesTier: "NFE",
2246
2246
  },
2247
2247
  infernape: {
2248
- randomBattleMoves: ["closecombat", "earthquake", "fireblast", "flareblitz", "grassknot", "machpunch", "nastyplot", "stealthrock", "stoneedge", "uturn", "vacuumwave"],
2248
+ randomBattleMoves: ["closecombat", "earthquake", "fireblast", "flareblitz", "grassknot", "machpunch", "stealthrock", "stoneedge", "uturn"],
2249
2249
  randomDoubleBattleMoves: ["closecombat", "fakeout", "feint", "flareblitz", "grassknot", "heatwave", "machpunch", "protect", "stoneedge", "taunt", "thunderpunch", "uturn"],
2250
2250
  tier: "UU",
2251
2251
  doublesTier: "DUU",
@@ -3279,8 +3279,8 @@ export const FormatsData: {[k: string]: ModdedSpeciesFormatsData} = {
3279
3279
  tier: "NFE",
3280
3280
  },
3281
3281
  haxorus: {
3282
- randomBattleMoves: ["dragondance", "earthquake", "outrage", "poisonjab", "swordsdance", "taunt"],
3283
- randomDoubleBattleMoves: ["dragonclaw", "dragondance", "earthquake", "poisonjab", "protect", "substitute", "swordsdance", "taunt"],
3282
+ randomBattleMoves: ["dragondance", "earthquake", "outrage", "poisonjab", "swordsdance"],
3283
+ randomDoubleBattleMoves: ["dragonclaw", "dragondance", "earthquake", "poisonjab", "protect", "substitute", "swordsdance"],
3284
3284
  tier: "UU",
3285
3285
  doublesTier: "(DUU)",
3286
3286
  },
package/data/moves.ts CHANGED
@@ -664,9 +664,9 @@ export const Moves: {[moveid: string]: MoveData} = {
664
664
  return false;
665
665
  }
666
666
 
667
- if (effect.id === 'cutecharm') {
667
+ if (effect.name === 'Cute Charm') {
668
668
  this.add('-start', pokemon, 'Attract', '[from] ability: Cute Charm', '[of] ' + source);
669
- } else if (effect.id === 'destinyknot') {
669
+ } else if (effect.name === 'Destiny Knot') {
670
670
  this.add('-start', pokemon, 'Attract', '[from] item: Destiny Knot', '[of] ' + source);
671
671
  } else {
672
672
  this.add('-start', pokemon, 'Attract');
@@ -1006,6 +1006,13 @@ export const Moves: {[moveid: string]: MoveData} = {
1006
1006
  pp: 40,
1007
1007
  priority: 0,
1008
1008
  flags: {},
1009
+ onHit(target) {
1010
+ if (!this.canSwitch(target.side)) {
1011
+ this.attrLastMove('[still]');
1012
+ this.add('-fail', target);
1013
+ return this.NOT_FAIL;
1014
+ }
1015
+ },
1009
1016
  self: {
1010
1017
  onHit(source) {
1011
1018
  source.skipBeforeSwitchOutEventFlag = true;
@@ -4103,7 +4110,7 @@ export const Moves: {[moveid: string]: MoveData} = {
4103
4110
  },
4104
4111
  onFieldStart(field, source, effect) {
4105
4112
  if (effect?.effectType === 'Ability') {
4106
- this.add('-fieldstart', 'move: Electric Terrain', '[from] ability: ' + effect, '[of] ' + source);
4113
+ this.add('-fieldstart', 'move: Electric Terrain', '[from] ability: ' + effect.name, '[of] ' + source);
4107
4114
  } else {
4108
4115
  this.add('-fieldstart', 'move: Electric Terrain');
4109
4116
  }
@@ -7196,7 +7203,7 @@ export const Moves: {[moveid: string]: MoveData} = {
7196
7203
  },
7197
7204
  onFieldStart(field, source, effect) {
7198
7205
  if (effect?.effectType === 'Ability') {
7199
- this.add('-fieldstart', 'move: Grassy Terrain', '[from] ability: ' + effect, '[of] ' + source);
7206
+ this.add('-fieldstart', 'move: Grassy Terrain', '[from] ability: ' + effect.name, '[of] ' + source);
7200
7207
  } else {
7201
7208
  this.add('-fieldstart', 'move: Grassy Terrain');
7202
7209
  }
@@ -7800,10 +7807,12 @@ export const Moves: {[moveid: string]: MoveData} = {
7800
7807
  pp: 10,
7801
7808
  priority: 0,
7802
7809
  flags: {snatch: 1, heal: 1},
7803
- onTryHit(pokemon, target, move) {
7804
- if (!this.canSwitch(pokemon.side)) {
7810
+ onHit(target, source, move) {
7811
+ if (!this.canSwitch(target.side)) {
7805
7812
  delete move.selfdestruct;
7806
- return false;
7813
+ this.attrLastMove('[still]');
7814
+ this.add('-fail', target);
7815
+ return this.NOT_FAIL;
7807
7816
  }
7808
7817
  },
7809
7818
  selfdestruct: "ifHit",
@@ -9894,10 +9903,12 @@ export const Moves: {[moveid: string]: MoveData} = {
9894
9903
  pp: 10,
9895
9904
  priority: 0,
9896
9905
  flags: {snatch: 1, heal: 1, dance: 1},
9897
- onTryHit(pokemon, target, move) {
9898
- if (!this.canSwitch(pokemon.side)) {
9906
+ onHit(target, source, move) {
9907
+ if (!this.canSwitch(target.side)) {
9899
9908
  delete move.selfdestruct;
9900
- return false;
9909
+ this.attrLastMove('[still]');
9910
+ this.add('-fail', target);
9911
+ return this.NOT_FAIL;
9901
9912
  }
9902
9913
  },
9903
9914
  selfdestruct: "ifHit",
@@ -11449,7 +11460,7 @@ export const Moves: {[moveid: string]: MoveData} = {
11449
11460
  },
11450
11461
  onFieldStart(field, source, effect) {
11451
11462
  if (effect?.effectType === 'Ability') {
11452
- this.add('-fieldstart', 'move: Misty Terrain', '[from] ability: ' + effect, '[of] ' + source);
11463
+ this.add('-fieldstart', 'move: Misty Terrain', '[from] ability: ' + effect.name, '[of] ' + source);
11453
11464
  } else {
11454
11465
  this.add('-fieldstart', 'move: Misty Terrain');
11455
11466
  }
@@ -13244,7 +13255,7 @@ export const Moves: {[moveid: string]: MoveData} = {
13244
13255
  },
13245
13256
  onFieldStart(field, source, effect) {
13246
13257
  if (effect?.effectType === 'Ability') {
13247
- this.add('-fieldstart', 'move: Psychic Terrain', '[from] ability: ' + effect, '[of] ' + source);
13258
+ this.add('-fieldstart', 'move: Psychic Terrain', '[from] ability: ' + effect.name, '[of] ' + source);
13248
13259
  } else {
13249
13260
  this.add('-fieldstart', 'move: Psychic Terrain');
13250
13261
  }
@@ -14122,17 +14133,18 @@ export const Moves: {[moveid: string]: MoveData} = {
14122
14133
  num: 804,
14123
14134
  accuracy: 100,
14124
14135
  basePower: 70,
14136
+ basePowerCallback(source, target, move) {
14137
+ if (this.field.isTerrain('electricterrain') && target.isGrounded()) {
14138
+ if (!source.isAlly(target)) this.hint(`${move.name}'s BP doubled on grounded target.`);
14139
+ return move.basePower * 2;
14140
+ }
14141
+ return move.basePower;
14142
+ },
14125
14143
  category: "Special",
14126
14144
  name: "Rising Voltage",
14127
14145
  pp: 20,
14128
14146
  priority: 0,
14129
14147
  flags: {protect: 1, mirror: 1},
14130
- onBasePower(basePower, pokemon, target) {
14131
- if (this.field.isTerrain('electricterrain') && target.isGrounded()) {
14132
- this.debug('terrain buff');
14133
- return this.chainModify(2);
14134
- }
14135
- },
14136
14148
  secondary: null,
14137
14149
  target: "normal",
14138
14150
  type: "Electric",
@@ -17944,8 +17956,10 @@ export const Moves: {[moveid: string]: MoveData} = {
17944
17956
  pp: 20,
17945
17957
  priority: -6,
17946
17958
  flags: {},
17959
+ onTry(source) {
17960
+ return !!this.canSwitch(source.side);
17961
+ },
17947
17962
  selfSwitch: true,
17948
- onTryHit: true,
17949
17963
  secondary: null,
17950
17964
  target: "self",
17951
17965
  type: "Psychic",
package/data/pokedex.ts CHANGED
@@ -16366,7 +16366,7 @@ export const Pokedex: {[speciesid: string]: SpeciesData} = {
16366
16366
  color: "Green",
16367
16367
  prevo: "Basculin-White-Striped",
16368
16368
  evoType: "other",
16369
- evoCondition: "Receive 294+ recoil from one move without fainting",
16369
+ evoCondition: "Receive 294+ recoil without fainting",
16370
16370
  eggGroups: ["Water 2"],
16371
16371
  otherFormes: ["Basculegion-F"],
16372
16372
  formeOrder: ["Basculegion", "Basculegion-F"],
@@ -16385,7 +16385,7 @@ export const Pokedex: {[speciesid: string]: SpeciesData} = {
16385
16385
  color: "Green",
16386
16386
  prevo: "Basculin-White-Striped",
16387
16387
  evoType: "other",
16388
- evoCondition: "Receive 294+ recoil from one move without fainting",
16388
+ evoCondition: "Receive 294+ recoil without fainting",
16389
16389
  eggGroups: ["Water 2"],
16390
16390
  },
16391
16391
  sneasler: {
package/data/rulesets.ts CHANGED
@@ -671,7 +671,7 @@ export const Rulesets: {[k: string]: FormatData} = {
671
671
  name: 'Gravity Sleep Clause',
672
672
  desc: "Bans sleep moves below 100% accuracy, in conjunction with Gravity or Gigantamax Orbeetle",
673
673
  banlist: [
674
- 'Gravity ++ Grass Whistle', 'Gravity ++ Hypnosis', 'Gravity ++ Lovely Kiss', 'Gravity ++ Sing', 'Gravity ++ Sleep Powder',
674
+ 'Gravity ++ Dark Void', 'Gravity ++ Grass Whistle', 'Gravity ++ Hypnosis', 'Gravity ++ Lovely Kiss', 'Gravity ++ Sing', 'Gravity ++ Sleep Powder',
675
675
  ],
676
676
  onValidateTeam(team) {
677
677
  let hasOrbeetle = false;
@@ -900,6 +900,8 @@ export const MovesText: {[k: string]: MoveText} = {
900
900
  desc: "Causes the user's types to become the same as the current types of the target.",
901
901
  shortDesc: "User becomes the same type as the target.",
902
902
  },
903
+
904
+ typeChange: " Converted type to [SOURCE]'s!", // gen 1 only
903
905
  },
904
906
  conversion2: {
905
907
  name: "Conversion 2",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pkmn/sim",
3
- "version": "0.5.11",
3
+ "version": "0.5.14",
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",
@@ -27,7 +27,7 @@
27
27
  "sim"
28
28
  ],
29
29
  "dependencies": {
30
- "@pkmn/sets": "^2.0.0",
30
+ "@pkmn/sets": "^3.0.0",
31
31
  "@pkmn/streams": "^1.0.0"
32
32
  },
33
33
  "devDependencies": {
package/sim/battle.ts CHANGED
@@ -479,6 +479,7 @@ export class Battle {
479
479
  if (!handler.state.duration) {
480
480
  const endCallArgs = handler.endCallArgs || [handler.effectHolder, effect.id];
481
481
  handler.end.call(...endCallArgs as [any, ...any[]]);
482
+ if (this.ended) return;
482
483
  continue;
483
484
  }
484
485
  }
@@ -1557,8 +1558,9 @@ export class Battle {
1557
1558
  // These are checked before the 100 turn minimum as the battle cannot progress if they are true
1558
1559
  if (this.gen <= 1) {
1559
1560
  const noProgressPossible = this.sides.every(side => {
1560
- const foeAllGhosts = side.foe.pokemon.every(pokemon => pokemon.types.includes('Ghost'));
1561
+ const foeAllGhosts = side.foe.pokemon.every(pokemon => pokemon.fainted || pokemon.types.includes('Ghost'));
1561
1562
  const foeAllTransform = side.foe.pokemon.every(pokemon => (
1563
+ pokemon.fainted ||
1562
1564
  // true if transforming into this pokemon would lead to an endless battle
1563
1565
  // Transform will fail (depleting PP) if used against Ditto in Stadium 1
1564
1566
  (this.dex.currentMod !== 'gen1stadium' || pokemon.species.id !== 'ditto') &&
@@ -1567,6 +1569,7 @@ export class Battle {
1567
1569
  pokemon.moves.every(moveid => moveid === 'transform')
1568
1570
  ));
1569
1571
  return side.pokemon.every(pokemon => (
1572
+ pokemon.fainted ||
1570
1573
  // frozen pokemon can't thaw in gen 1 without outside help
1571
1574
  pokemon.status === 'frz' ||
1572
1575
  // a pokemon can't lose PP if it Transforms into a pokemon with only Transform
@@ -640,6 +640,7 @@ export class Condition extends BasicEffect implements
640
640
 
641
641
  constructor(data: AnyObject) {
642
642
  super(data);
643
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
643
644
  data = this;
644
645
  this.effectType = (['Weather', 'Status'].includes(data.effectType) ? data.effectType : 'Condition');
645
646
  }
@@ -659,7 +660,10 @@ export class DexConditions {
659
660
  if (!name) return EMPTY_CONDITION;
660
661
  if (typeof name !== 'string') return name as Condition;
661
662
 
662
- return this.getByID(name.startsWith('item:') || name.startsWith('ability:') ? name as ID : toID(name));
663
+ const special = name.startsWith('item:') ? `item:${toID(name.slice(5))}` as ID :
664
+ name.startsWith('ability:') ? `ability:${toID(name.slice(8))}` as ID :
665
+ name.startsWith('move:') ? `move:${toID(name.slice(5))}` as ID : undefined;
666
+ return this.getByID(special || toID(name));
663
667
  }
664
668
 
665
669
  getByID(id: ID): Condition {
@@ -671,10 +675,13 @@ export class DexConditions {
671
675
  let found;
672
676
  if (id.startsWith('item:')) {
673
677
  const item = this.dex.items.getByID(id.slice(5) as ID);
674
- condition = {...item, id: 'item:' + item.id as ID} as any as Condition;
678
+ condition = item as any as Condition;
675
679
  } else if (id.startsWith('ability:')) {
676
680
  const ability = this.dex.abilities.getByID(id.slice(8) as ID);
677
- condition = {...ability, id: 'ability:' + ability.id as ID} as any as Condition;
681
+ condition = ability as any as Condition;
682
+ } else if (id.startsWith('move:')) {
683
+ const move = this.dex.moves.getByID(id.slice(5) as ID);
684
+ condition = move as any as Condition;
678
685
  } else if (this.dex.data.Rulesets.hasOwnProperty(id)) {
679
686
  condition = this.dex.formats.get(id) as any as Condition;
680
687
  } else if (this.dex.data.Conditions.hasOwnProperty(id)) {
package/sim/dex-data.ts CHANGED
@@ -148,6 +148,7 @@ export class Nature extends BasicEffect implements Readonly<BasicEffect & Nature
148
148
  readonly minus?: StatIDExceptHP;
149
149
  constructor(data: AnyObject) {
150
150
  super(data);
151
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
151
152
  data = this;
152
153
 
153
154
  this.fullname = `nature: ${this.name}`;
@@ -435,6 +435,7 @@ export class Format extends BasicEffect implements Readonly<BasicEffect> {
435
435
 
436
436
  constructor(data: AnyObject) {
437
437
  super(data);
438
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
438
439
  data = this;
439
440
 
440
441
  this.mod = Utils.getString(data.mod) || 'gen8';
package/sim/dex-items.ts CHANGED
@@ -113,6 +113,7 @@ export class Item extends BasicEffect implements Readonly<BasicEffect> {
113
113
 
114
114
  constructor(data: AnyObject) {
115
115
  super(data);
116
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
116
117
  data = this;
117
118
 
118
119
  this.fullname = `item: ${this.name}`;
package/sim/dex-moves.ts CHANGED
@@ -470,6 +470,7 @@ export class DataMove extends BasicEffect implements Readonly<BasicEffect & Move
470
470
 
471
471
  constructor(data: AnyObject) {
472
472
  super(data);
473
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
473
474
  data = this;
474
475
 
475
476
  this.fullname = `move: ${this.name}`;
@@ -242,6 +242,7 @@ export class Species extends BasicEffect implements Readonly<BasicEffect & Speci
242
242
 
243
243
  constructor(data: AnyObject) {
244
244
  super(data);
245
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
245
246
  data = this;
246
247
 
247
248
  this.fullname = `pokemon: ${data.name}`;
@@ -712,7 +712,7 @@ export class TeamValidator {
712
712
  }
713
713
 
714
714
  let isFromRBYEncounter = false;
715
- if (this.gen === 1 && !this.ruleTable.has('allowtradeback')) {
715
+ if (this.gen === 1 && ruleTable.has('obtainablemisc') && !this.ruleTable.has('allowtradeback')) {
716
716
  let lowestEncounterLevel;
717
717
  for (const encounter of learnsetSpecies.encounters || []) {
718
718
  if (encounter.generation !== 1) continue;