@pkmn/sim 0.8.3 → 0.8.4

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 (79) hide show
  1. package/build/cjs/config/formats.js +92 -89
  2. package/build/cjs/config/formats.js.map +1 -1
  3. package/build/cjs/data/abilities.js +361 -163
  4. package/build/cjs/data/abilities.js.map +1 -1
  5. package/build/cjs/data/formats-data.js +326 -311
  6. package/build/cjs/data/formats-data.js.map +1 -1
  7. package/build/cjs/data/mods/gen3/abilities.js +6 -5
  8. package/build/cjs/data/mods/gen3/abilities.js.map +1 -1
  9. package/build/cjs/data/mods/gen4/abilities.js +8 -2
  10. package/build/cjs/data/mods/gen4/abilities.js.map +1 -1
  11. package/build/cjs/data/mods/gen4/moves.js +1 -2
  12. package/build/cjs/data/mods/gen4/moves.js.map +1 -1
  13. package/build/cjs/data/mods/gen5/abilities.js +1 -0
  14. package/build/cjs/data/mods/gen5/abilities.js.map +1 -1
  15. package/build/cjs/data/mods/gen6/abilities.js +1 -1
  16. package/build/cjs/data/mods/gen6/abilities.js.map +1 -1
  17. package/build/cjs/data/mods/gen7/abilities.js +2 -2
  18. package/build/cjs/data/mods/gen7/abilities.js.map +1 -1
  19. package/build/cjs/data/mods/gen8/abilities.js +3 -1
  20. package/build/cjs/data/mods/gen8/abilities.js.map +1 -1
  21. package/build/cjs/data/moves.js +27 -38
  22. package/build/cjs/data/moves.js.map +1 -1
  23. package/build/cjs/data/rulesets.js +10 -18
  24. package/build/cjs/data/rulesets.js.map +1 -1
  25. package/build/cjs/data/text/abilities.js +32 -11
  26. package/build/cjs/data/text/abilities.js.map +1 -1
  27. package/build/cjs/data/text/moves.js +8 -8
  28. package/build/cjs/data/text/moves.js.map +1 -1
  29. package/build/cjs/sim/battle-actions.js +2 -1
  30. package/build/cjs/sim/battle-actions.js.map +1 -1
  31. package/build/cjs/sim/battle.js +2 -2
  32. package/build/cjs/sim/battle.js.map +1 -1
  33. package/build/cjs/sim/dex-abilities.d.ts +11 -2
  34. package/build/cjs/sim/dex-abilities.js +1 -0
  35. package/build/cjs/sim/dex-abilities.js.map +1 -1
  36. package/build/cjs/sim/exported-global-types.d.ts +2 -2
  37. package/build/cjs/sim/global-types.d.ts +2 -2
  38. package/build/cjs/sim/pokemon.js +7 -4
  39. package/build/cjs/sim/pokemon.js.map +1 -1
  40. package/build/esm/config/formats.mjs +92 -89
  41. package/build/esm/config/formats.mjs.map +1 -1
  42. package/build/esm/data/abilities.mjs +361 -163
  43. package/build/esm/data/abilities.mjs.map +1 -1
  44. package/build/esm/data/formats-data.mjs +326 -311
  45. package/build/esm/data/formats-data.mjs.map +1 -1
  46. package/build/esm/data/mods/gen3/abilities.mjs +6 -5
  47. package/build/esm/data/mods/gen3/abilities.mjs.map +1 -1
  48. package/build/esm/data/mods/gen4/abilities.mjs +8 -2
  49. package/build/esm/data/mods/gen4/abilities.mjs.map +1 -1
  50. package/build/esm/data/mods/gen4/moves.mjs +1 -2
  51. package/build/esm/data/mods/gen4/moves.mjs.map +1 -1
  52. package/build/esm/data/mods/gen5/abilities.mjs +1 -0
  53. package/build/esm/data/mods/gen5/abilities.mjs.map +1 -1
  54. package/build/esm/data/mods/gen6/abilities.mjs +1 -1
  55. package/build/esm/data/mods/gen6/abilities.mjs.map +1 -1
  56. package/build/esm/data/mods/gen7/abilities.mjs +2 -2
  57. package/build/esm/data/mods/gen7/abilities.mjs.map +1 -1
  58. package/build/esm/data/mods/gen8/abilities.mjs +3 -1
  59. package/build/esm/data/mods/gen8/abilities.mjs.map +1 -1
  60. package/build/esm/data/moves.mjs +27 -38
  61. package/build/esm/data/moves.mjs.map +1 -1
  62. package/build/esm/data/rulesets.mjs +10 -18
  63. package/build/esm/data/rulesets.mjs.map +1 -1
  64. package/build/esm/data/text/abilities.mjs +32 -11
  65. package/build/esm/data/text/abilities.mjs.map +1 -1
  66. package/build/esm/data/text/moves.mjs +8 -8
  67. package/build/esm/data/text/moves.mjs.map +1 -1
  68. package/build/esm/sim/battle-actions.mjs +2 -1
  69. package/build/esm/sim/battle-actions.mjs.map +1 -1
  70. package/build/esm/sim/battle.mjs +2 -2
  71. package/build/esm/sim/battle.mjs.map +1 -1
  72. package/build/esm/sim/dex-abilities.d.mts +11 -2
  73. package/build/esm/sim/dex-abilities.mjs +1 -0
  74. package/build/esm/sim/dex-abilities.mjs.map +1 -1
  75. package/build/esm/sim/exported-global-types.d.mts +2 -2
  76. package/build/esm/sim/global-types.d.mts +2 -2
  77. package/build/esm/sim/pokemon.mjs +7 -4
  78. package/build/esm/sim/pokemon.mjs.map +1 -1
  79. package/package.json +1 -1
@@ -37,6 +37,7 @@ exports.Abilities = void 0;
37
37
  exports.Abilities = {
38
38
  noability: {
39
39
  isNonstandard: "Past",
40
+ flags: {},
40
41
  name: "No Ability",
41
42
  rating: 0.1,
42
43
  num: 0,
@@ -45,6 +46,7 @@ exports.Abilities = {
45
46
  onModifyMove(move) {
46
47
  move.stab = 2;
47
48
  },
49
+ flags: {},
48
50
  name: "Adaptability",
49
51
  rating: 4,
50
52
  num: 91,
@@ -66,18 +68,20 @@ exports.Abilities = {
66
68
  if (move.typeChangerBoosted === this.effect)
67
69
  return this.chainModify([4915, 4096]);
68
70
  },
71
+ flags: {},
69
72
  name: "Aerilate",
70
73
  rating: 4,
71
74
  num: 184,
72
75
  },
73
76
  aftermath: {
74
- name: "Aftermath",
75
77
  onDamagingHitOrder: 1,
76
78
  onDamagingHit(damage, target, source, move) {
77
79
  if (!target.hp && this.checkMoveMakesContact(move, source, target, true)) {
78
80
  this.damage(source.baseMaxhp / 4, source, target);
79
81
  }
80
82
  },
83
+ flags: {},
84
+ name: "Aftermath",
81
85
  rating: 2,
82
86
  num: 106,
83
87
  },
@@ -97,6 +101,7 @@ exports.Abilities = {
97
101
  this.eachEvent('WeatherChange', this.effect);
98
102
  },
99
103
  suppressWeather: true,
104
+ flags: {},
100
105
  name: "Air Lock",
101
106
  rating: 1.5,
102
107
  num: 76,
@@ -118,6 +123,7 @@ exports.Abilities = {
118
123
  return this.chainModify([5325, 4096]);
119
124
  }
120
125
  },
126
+ flags: {},
121
127
  name: "Analytic",
122
128
  rating: 2.5,
123
129
  num: 148,
@@ -130,6 +136,7 @@ exports.Abilities = {
130
136
  this.boost({ atk: 12 }, target, target);
131
137
  }
132
138
  },
139
+ flags: {},
133
140
  name: "Anger Point",
134
141
  rating: 1,
135
142
  num: 83,
@@ -166,6 +173,7 @@ exports.Abilities = {
166
173
  this.boost({ atk: 1, spa: 1, spe: 1, def: -1, spd: -1 }, target, target);
167
174
  }
168
175
  },
176
+ flags: {},
169
177
  name: "Anger Shell",
170
178
  rating: 3,
171
179
  num: 271,
@@ -186,6 +194,7 @@ exports.Abilities = {
186
194
  }
187
195
  }
188
196
  },
197
+ flags: {},
189
198
  name: "Anticipation",
190
199
  rating: 0.5,
191
200
  num: 107,
@@ -207,6 +216,7 @@ exports.Abilities = {
207
216
  pokemon.maybeTrapped = true;
208
217
  }
209
218
  },
219
+ flags: {},
210
220
  name: "Arena Trap",
211
221
  rating: 5,
212
222
  num: 71,
@@ -224,7 +234,7 @@ exports.Abilities = {
224
234
  return false;
225
235
  }
226
236
  },
227
- isBreakable: true,
237
+ flags: { breakable: 1 },
228
238
  name: "Armor Tail",
229
239
  rating: 2.5,
230
240
  num: 296,
@@ -239,7 +249,7 @@ exports.Abilities = {
239
249
  return null;
240
250
  }
241
251
  },
242
- isBreakable: true,
252
+ flags: { breakable: 1 },
243
253
  name: "Aroma Veil",
244
254
  rating: 2,
245
255
  num: 165,
@@ -261,7 +271,7 @@ exports.Abilities = {
261
271
  this.boost({ atk: length }, source, source, this.dex.abilities.get('chillingneigh'));
262
272
  }
263
273
  },
264
- isPermanent: true,
274
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1 },
265
275
  name: "As One (Glastrier)",
266
276
  rating: 3.5,
267
277
  num: 266,
@@ -283,7 +293,7 @@ exports.Abilities = {
283
293
  this.boost({ spa: length }, source, source, this.dex.abilities.get('grimneigh'));
284
294
  }
285
295
  },
286
- isPermanent: true,
296
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1 },
287
297
  name: "As One (Spectrier)",
288
298
  rating: 3.5,
289
299
  num: 267,
@@ -299,7 +309,7 @@ exports.Abilities = {
299
309
  return;
300
310
  move.hasAuraBreak = true;
301
311
  },
302
- isBreakable: true,
312
+ flags: { breakable: 1 },
303
313
  name: "Aura Break",
304
314
  rating: 1,
305
315
  num: 188,
@@ -316,11 +326,13 @@ exports.Abilities = {
316
326
  }
317
327
  }
318
328
  },
329
+ flags: {},
319
330
  name: "Bad Dreams",
320
331
  rating: 1.5,
321
332
  num: 123,
322
333
  },
323
334
  ballfetch: {
335
+ flags: {},
324
336
  name: "Ball Fetch",
325
337
  rating: 0,
326
338
  num: 237,
@@ -333,13 +345,14 @@ exports.Abilities = {
333
345
  return this.chainModify([5325, 4096]);
334
346
  }
335
347
  },
348
+ flags: {},
336
349
  name: "Battery",
337
350
  rating: 0,
338
351
  num: 217,
339
352
  },
340
353
  battlearmor: {
341
354
  onCriticalHit: false,
342
- isBreakable: true,
355
+ flags: { breakable: 1 },
343
356
  name: "Battle Armor",
344
357
  rating: 1,
345
358
  num: 4,
@@ -356,7 +369,7 @@ exports.Abilities = {
356
369
  source.abilityState.battleBondTriggered = true;
357
370
  }
358
371
  },
359
- isPermanent: true,
372
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1 },
360
373
  name: "Battle Bond",
361
374
  rating: 3.5,
362
375
  num: 210,
@@ -378,6 +391,7 @@ exports.Abilities = {
378
391
  this.debug('Beads of Ruin SpD drop');
379
392
  return this.chainModify(0.75);
380
393
  },
394
+ flags: {},
381
395
  name: "Beads of Ruin",
382
396
  rating: 4.5,
383
397
  num: 284,
@@ -389,6 +403,7 @@ exports.Abilities = {
389
403
  this.boost({ [bestStat]: length }, source);
390
404
  }
391
405
  },
406
+ flags: {},
392
407
  name: "Beast Boost",
393
408
  rating: 3.5,
394
409
  num: 224,
@@ -425,6 +440,7 @@ exports.Abilities = {
425
440
  this.boost({ spa: 1 }, target, target);
426
441
  }
427
442
  },
443
+ flags: {},
428
444
  name: "Berserk",
429
445
  rating: 2,
430
446
  num: 201,
@@ -440,7 +456,7 @@ exports.Abilities = {
440
456
  }
441
457
  }
442
458
  },
443
- isBreakable: true,
459
+ flags: { breakable: 1 },
444
460
  name: "Big Pecks",
445
461
  rating: 0.5,
446
462
  num: 145,
@@ -460,6 +476,7 @@ exports.Abilities = {
460
476
  return this.chainModify(1.5);
461
477
  }
462
478
  },
479
+ flags: {},
463
480
  name: "Blaze",
464
481
  rating: 2,
465
482
  num: 66,
@@ -471,7 +488,7 @@ exports.Abilities = {
471
488
  return null;
472
489
  }
473
490
  },
474
- isBreakable: true,
491
+ flags: { breakable: 1 },
475
492
  name: "Bulletproof",
476
493
  rating: 3,
477
494
  num: 171,
@@ -480,6 +497,7 @@ exports.Abilities = {
480
497
  onEatItem(item, pokemon) {
481
498
  this.heal(pokemon.baseMaxhp / 3);
482
499
  },
500
+ flags: {},
483
501
  name: "Cheek Pouch",
484
502
  rating: 2,
485
503
  num: 167,
@@ -490,6 +508,7 @@ exports.Abilities = {
490
508
  this.boost({ atk: length }, source);
491
509
  }
492
510
  },
511
+ flags: {},
493
512
  name: "Chilling Neigh",
494
513
  rating: 3,
495
514
  num: 264,
@@ -500,6 +519,7 @@ exports.Abilities = {
500
519
  return this.chainModify(2);
501
520
  }
502
521
  },
522
+ flags: {},
503
523
  name: "Chlorophyll",
504
524
  rating: 3,
505
525
  num: 34,
@@ -520,7 +540,7 @@ exports.Abilities = {
520
540
  this.add("-fail", target, "unboost", "[from] ability: Clear Body", "[of] " + target);
521
541
  }
522
542
  },
523
- isBreakable: true,
543
+ flags: { breakable: 1 },
524
544
  name: "Clear Body",
525
545
  rating: 2,
526
546
  num: 29,
@@ -541,6 +561,7 @@ exports.Abilities = {
541
561
  this.eachEvent('WeatherChange', this.effect);
542
562
  },
543
563
  suppressWeather: true,
564
+ flags: {},
544
565
  name: "Cloud Nine",
545
566
  rating: 1.5,
546
567
  num: 13,
@@ -564,6 +585,7 @@ exports.Abilities = {
564
585
  }
565
586
  }
566
587
  },
588
+ flags: {},
567
589
  name: "Color Change",
568
590
  rating: 0,
569
591
  num: 16,
@@ -579,7 +601,7 @@ exports.Abilities = {
579
601
  return false;
580
602
  },
581
603
  // Permanent sleep "status" implemented in the relevant sleep-checking effects
582
- isPermanent: true,
604
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1 },
583
605
  name: "Comatose",
584
606
  rating: 4,
585
607
  num: 213,
@@ -589,8 +611,7 @@ exports.Abilities = {
589
611
  if (this.gameType !== 'doubles')
590
612
  return;
591
613
  const ally = pokemon.allies()[0];
592
- if (!ally || pokemon.transformed ||
593
- pokemon.baseSpecies.baseSpecies !== 'Tatsugiri' || ally.baseSpecies.baseSpecies !== 'Dondozo') {
614
+ if (!ally || pokemon.baseSpecies.baseSpecies !== 'Tatsugiri' || ally.baseSpecies.baseSpecies !== 'Dondozo') {
594
615
  // Handle any edge cases
595
616
  if (pokemon.getVolatile('commanding'))
596
617
  pokemon.removeVolatile('commanding');
@@ -614,6 +635,7 @@ exports.Abilities = {
614
635
  pokemon.removeVolatile('commanding');
615
636
  }
616
637
  },
638
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1 },
617
639
  name: "Commander",
618
640
  rating: 0,
619
641
  num: 279,
@@ -637,6 +659,7 @@ exports.Abilities = {
637
659
  this.boost({ spa: 2 }, target, target, null, false, true);
638
660
  }
639
661
  },
662
+ flags: {},
640
663
  name: "Competitive",
641
664
  rating: 2.5,
642
665
  num: 172,
@@ -649,6 +672,7 @@ exports.Abilities = {
649
672
  this.debug('compoundeyes - enhancing accuracy');
650
673
  return this.chainModify([5325, 4096]);
651
674
  },
675
+ flags: {},
652
676
  name: "Compound Eyes",
653
677
  rating: 3,
654
678
  num: 14,
@@ -662,13 +686,14 @@ exports.Abilities = {
662
686
  boost[i] *= -1;
663
687
  }
664
688
  },
665
- isBreakable: true,
689
+ flags: { breakable: 1 },
666
690
  name: "Contrary",
667
691
  rating: 4.5,
668
692
  num: 126,
669
693
  },
670
694
  corrosion: {
671
695
  // Implemented in sim/pokemon.js:Pokemon#setStatus
696
+ flags: {},
672
697
  name: "Corrosion",
673
698
  rating: 2.5,
674
699
  num: 212,
@@ -695,6 +720,7 @@ exports.Abilities = {
695
720
  }
696
721
  this.add('-copyboost', pokemon, ally, '[from] ability: Costar');
697
722
  },
723
+ flags: {},
698
724
  name: "Costar",
699
725
  rating: 0,
700
726
  num: 294,
@@ -712,6 +738,7 @@ exports.Abilities = {
712
738
  this.boost({ spe: -1 }, pokemon, target, null, true);
713
739
  }
714
740
  },
741
+ flags: {},
715
742
  name: "Cotton Down",
716
743
  rating: 2,
717
744
  num: 238,
@@ -746,6 +773,7 @@ exports.Abilities = {
746
773
  }
747
774
  },
748
775
  },
776
+ flags: {},
749
777
  name: "Cud Chew",
750
778
  rating: 2,
751
779
  num: 291,
@@ -757,6 +785,7 @@ exports.Abilities = {
757
785
  this.add('-clearboost', ally, '[from] ability: Curious Medicine', '[of] ' + pokemon);
758
786
  }
759
787
  },
788
+ flags: {},
760
789
  name: "Curious Medicine",
761
790
  rating: 0,
762
791
  num: 261,
@@ -771,6 +800,7 @@ exports.Abilities = {
771
800
  }
772
801
  }
773
802
  },
803
+ flags: {},
774
804
  name: "Cursed Body",
775
805
  rating: 2,
776
806
  num: 130,
@@ -783,6 +813,7 @@ exports.Abilities = {
783
813
  }
784
814
  }
785
815
  },
816
+ flags: {},
786
817
  name: "Cute Charm",
787
818
  rating: 0.5,
788
819
  num: 56,
@@ -800,12 +831,13 @@ exports.Abilities = {
800
831
  return false;
801
832
  }
802
833
  },
803
- isBreakable: true,
834
+ flags: { breakable: 1 },
804
835
  name: "Damp",
805
836
  rating: 0.5,
806
837
  num: 6,
807
838
  },
808
839
  dancer: {
840
+ flags: {},
809
841
  name: "Dancer",
810
842
  // implemented in runMove in scripts.js
811
843
  rating: 1.5,
@@ -827,6 +859,7 @@ exports.Abilities = {
827
859
  return;
828
860
  return this.chainModify([move.hasAuraBreak ? 3072 : 5448, 4096]);
829
861
  },
862
+ flags: {},
830
863
  name: "Dark Aura",
831
864
  rating: 3,
832
865
  num: 186,
@@ -838,6 +871,7 @@ exports.Abilities = {
838
871
  pokemon.shieldBoost = true;
839
872
  this.boost({ def: 1 }, pokemon);
840
873
  },
874
+ flags: {},
841
875
  name: "Dauntless Shield",
842
876
  rating: 3.5,
843
877
  num: 235,
@@ -855,7 +889,7 @@ exports.Abilities = {
855
889
  return false;
856
890
  }
857
891
  },
858
- isBreakable: true,
892
+ flags: { breakable: 1 },
859
893
  name: "Dazzling",
860
894
  rating: 2.5,
861
895
  num: 219,
@@ -873,6 +907,7 @@ exports.Abilities = {
873
907
  return this.chainModify(0.5);
874
908
  }
875
909
  },
910
+ flags: {},
876
911
  name: "Defeatist",
877
912
  rating: -1,
878
913
  num: 129,
@@ -896,6 +931,7 @@ exports.Abilities = {
896
931
  this.boost({ atk: 2 }, target, target, null, false, true);
897
932
  }
898
933
  },
934
+ flags: {},
899
935
  name: "Defiant",
900
936
  rating: 3,
901
937
  num: 128,
@@ -922,6 +958,7 @@ exports.Abilities = {
922
958
  }
923
959
  this.field.clearWeather();
924
960
  },
961
+ flags: {},
925
962
  name: "Delta Stream",
926
963
  rating: 4,
927
964
  num: 191,
@@ -948,6 +985,7 @@ exports.Abilities = {
948
985
  }
949
986
  this.field.clearWeather();
950
987
  },
988
+ flags: {},
951
989
  name: "Desolate Land",
952
990
  rating: 4.5,
953
991
  num: 190,
@@ -955,8 +993,7 @@ exports.Abilities = {
955
993
  disguise: {
956
994
  onDamagePriority: 1,
957
995
  onDamage(damage, target, source, effect) {
958
- if (effect && effect.effectType === 'Move' &&
959
- ['mimikyu', 'mimikyutotem'].includes(target.species.id) && !target.transformed) {
996
+ if (effect?.effectType === 'Move' && ['mimikyu', 'mimikyutotem'].includes(target.species.id)) {
960
997
  this.add('-activate', target, 'ability: Disguise');
961
998
  this.effectState.busted = true;
962
999
  return 0;
@@ -965,7 +1002,7 @@ exports.Abilities = {
965
1002
  onCriticalHit(target, source, move) {
966
1003
  if (!target)
967
1004
  return;
968
- if (!['mimikyu', 'mimikyutotem'].includes(target.species.id) || target.transformed) {
1005
+ if (!['mimikyu', 'mimikyutotem'].includes(target.species.id)) {
969
1006
  return;
970
1007
  }
971
1008
  const hitSub = target.volatiles['substitute'] && !move.flags['bypasssub'] && !(move.infiltrates && this.gen >= 6);
@@ -978,7 +1015,7 @@ exports.Abilities = {
978
1015
  onEffectiveness(typeMod, target, type, move) {
979
1016
  if (!target || move.category === 'Status')
980
1017
  return;
981
- if (!['mimikyu', 'mimikyutotem'].includes(target.species.id) || target.transformed) {
1018
+ if (!['mimikyu', 'mimikyutotem'].includes(target.species.id)) {
982
1019
  return;
983
1020
  }
984
1021
  const hitSub = target.volatiles['substitute'] && !move.flags['bypasssub'] && !(move.infiltrates && this.gen >= 6);
@@ -995,8 +1032,10 @@ exports.Abilities = {
995
1032
  this.damage(pokemon.baseMaxhp / 8, pokemon, pokemon, this.dex.species.get(speciesid));
996
1033
  }
997
1034
  },
998
- isBreakable: true,
999
- isPermanent: true,
1035
+ flags: {
1036
+ failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1,
1037
+ breakable: 1, notransform: 1,
1038
+ },
1000
1039
  name: "Disguise",
1001
1040
  rating: 3.5,
1002
1041
  num: 209,
@@ -1016,6 +1055,7 @@ exports.Abilities = {
1016
1055
  this.boost({ atk: 1 });
1017
1056
  }
1018
1057
  },
1058
+ flags: {},
1019
1059
  name: "Download",
1020
1060
  rating: 3.5,
1021
1061
  num: 88,
@@ -1035,6 +1075,7 @@ exports.Abilities = {
1035
1075
  return this.chainModify(1.5);
1036
1076
  }
1037
1077
  },
1078
+ flags: {},
1038
1079
  name: "Dragon's Maw",
1039
1080
  rating: 3.5,
1040
1081
  num: 263,
@@ -1049,6 +1090,7 @@ exports.Abilities = {
1049
1090
  }
1050
1091
  this.field.setWeather('raindance');
1051
1092
  },
1093
+ flags: {},
1052
1094
  name: "Drizzle",
1053
1095
  rating: 4,
1054
1096
  num: 2,
@@ -1063,6 +1105,7 @@ exports.Abilities = {
1063
1105
  }
1064
1106
  this.field.setWeather('sunnyday');
1065
1107
  },
1108
+ flags: {},
1066
1109
  name: "Drought",
1067
1110
  rating: 4,
1068
1111
  num: 70,
@@ -1092,12 +1135,13 @@ exports.Abilities = {
1092
1135
  this.damage(target.baseMaxhp / 8, target, target);
1093
1136
  }
1094
1137
  },
1095
- isBreakable: true,
1138
+ flags: { breakable: 1 },
1096
1139
  name: "Dry Skin",
1097
1140
  rating: 3,
1098
1141
  num: 87,
1099
1142
  },
1100
1143
  earlybird: {
1144
+ flags: {},
1101
1145
  name: "Early Bird",
1102
1146
  // Implemented in statuses.js
1103
1147
  rating: 1.5,
@@ -1112,7 +1156,7 @@ exports.Abilities = {
1112
1156
  return null;
1113
1157
  }
1114
1158
  },
1115
- isBreakable: true,
1159
+ flags: { breakable: 1 },
1116
1160
  name: "Earth Eater",
1117
1161
  rating: 3.5,
1118
1162
  num: 297,
@@ -1132,6 +1176,7 @@ exports.Abilities = {
1132
1176
  }
1133
1177
  }
1134
1178
  },
1179
+ flags: {},
1135
1180
  name: "Effect Spore",
1136
1181
  rating: 2,
1137
1182
  num: 27,
@@ -1140,6 +1185,7 @@ exports.Abilities = {
1140
1185
  onStart(source) {
1141
1186
  this.field.setTerrain('electricterrain');
1142
1187
  },
1188
+ flags: {},
1143
1189
  name: "Electric Surge",
1144
1190
  rating: 4,
1145
1191
  num: 226,
@@ -1149,13 +1195,14 @@ exports.Abilities = {
1149
1195
  onDamagingHit(damage, target, source, move) {
1150
1196
  target.addVolatile('charge');
1151
1197
  },
1198
+ flags: {},
1152
1199
  name: "Electromorphosis",
1153
1200
  rating: 3,
1154
1201
  num: 280,
1155
1202
  },
1156
1203
  embodyaspectcornerstone: {
1157
1204
  onStart(pokemon) {
1158
- if (pokemon.baseSpecies.name === 'Ogerpon-Cornerstone-Tera' && !pokemon.transformed && !this.effectState.embodied) {
1205
+ if (pokemon.baseSpecies.name === 'Ogerpon-Cornerstone-Tera' && !this.effectState.embodied) {
1159
1206
  this.effectState.embodied = true;
1160
1207
  this.boost({ def: 1 }, pokemon);
1161
1208
  }
@@ -1163,13 +1210,14 @@ exports.Abilities = {
1163
1210
  onSwitchIn() {
1164
1211
  delete this.effectState.embodied;
1165
1212
  },
1213
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, notransform: 1 },
1166
1214
  name: "Embody Aspect (Cornerstone)",
1167
1215
  rating: 3.5,
1168
1216
  num: 304,
1169
1217
  },
1170
1218
  embodyaspecthearthflame: {
1171
1219
  onStart(pokemon) {
1172
- if (pokemon.baseSpecies.name === 'Ogerpon-Hearthflame-Tera' && !pokemon.transformed && !this.effectState.embodied) {
1220
+ if (pokemon.baseSpecies.name === 'Ogerpon-Hearthflame-Tera' && !this.effectState.embodied) {
1173
1221
  this.effectState.embodied = true;
1174
1222
  this.boost({ atk: 1 }, pokemon);
1175
1223
  }
@@ -1177,13 +1225,14 @@ exports.Abilities = {
1177
1225
  onSwitchIn() {
1178
1226
  delete this.effectState.embodied;
1179
1227
  },
1228
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, notransform: 1 },
1180
1229
  name: "Embody Aspect (Hearthflame)",
1181
1230
  rating: 3.5,
1182
1231
  num: 303,
1183
1232
  },
1184
1233
  embodyaspectteal: {
1185
1234
  onStart(pokemon) {
1186
- if (pokemon.baseSpecies.name === 'Ogerpon-Teal-Tera' && !pokemon.transformed && !this.effectState.embodied) {
1235
+ if (pokemon.baseSpecies.name === 'Ogerpon-Teal-Tera' && !this.effectState.embodied) {
1187
1236
  this.effectState.embodied = true;
1188
1237
  this.boost({ spe: 1 }, pokemon);
1189
1238
  }
@@ -1191,13 +1240,14 @@ exports.Abilities = {
1191
1240
  onSwitchIn() {
1192
1241
  delete this.effectState.embodied;
1193
1242
  },
1243
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, notransform: 1 },
1194
1244
  name: "Embody Aspect (Teal)",
1195
1245
  rating: 3.5,
1196
1246
  num: 301,
1197
1247
  },
1198
1248
  embodyaspectwellspring: {
1199
1249
  onStart(pokemon) {
1200
- if (pokemon.baseSpecies.name === 'Ogerpon-Wellspring-Tera' && !pokemon.transformed && !this.effectState.embodied) {
1250
+ if (pokemon.baseSpecies.name === 'Ogerpon-Wellspring-Tera' && !this.effectState.embodied) {
1201
1251
  this.effectState.embodied = true;
1202
1252
  this.boost({ spd: 1 }, pokemon);
1203
1253
  }
@@ -1205,6 +1255,7 @@ exports.Abilities = {
1205
1255
  onSwitchIn() {
1206
1256
  delete this.effectState.embodied;
1207
1257
  },
1258
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, notransform: 1 },
1208
1259
  name: "Embody Aspect (Wellspring)",
1209
1260
  rating: 3.5,
1210
1261
  num: 302,
@@ -1221,6 +1272,7 @@ exports.Abilities = {
1221
1272
  target.switchFlag = true;
1222
1273
  this.add('-activate', target, 'ability: Emergency Exit');
1223
1274
  },
1275
+ flags: {},
1224
1276
  name: "Emergency Exit",
1225
1277
  rating: 1,
1226
1278
  num: 194,
@@ -1241,6 +1293,7 @@ exports.Abilities = {
1241
1293
  return;
1242
1294
  return this.chainModify([move.hasAuraBreak ? 3072 : 5448, 4096]);
1243
1295
  },
1296
+ flags: {},
1244
1297
  name: "Fairy Aura",
1245
1298
  rating: 3,
1246
1299
  num: 187,
@@ -1252,7 +1305,7 @@ exports.Abilities = {
1252
1305
  return this.chainModify(0.75);
1253
1306
  }
1254
1307
  },
1255
- isBreakable: true,
1308
+ flags: { breakable: 1 },
1256
1309
  name: "Filter",
1257
1310
  rating: 3,
1258
1311
  num: 111,
@@ -1265,6 +1318,7 @@ exports.Abilities = {
1265
1318
  }
1266
1319
  }
1267
1320
  },
1321
+ flags: {},
1268
1322
  name: "Flame Body",
1269
1323
  rating: 2,
1270
1324
  num: 49,
@@ -1276,6 +1330,7 @@ exports.Abilities = {
1276
1330
  return this.chainModify(1.5);
1277
1331
  }
1278
1332
  },
1333
+ flags: {},
1279
1334
  name: "Flare Boost",
1280
1335
  rating: 2,
1281
1336
  num: 138,
@@ -1316,7 +1371,7 @@ exports.Abilities = {
1316
1371
  this.add('-end', target, 'ability: Flash Fire', '[silent]');
1317
1372
  },
1318
1373
  },
1319
- isBreakable: true,
1374
+ flags: { breakable: 1 },
1320
1375
  name: "Flash Fire",
1321
1376
  rating: 3.5,
1322
1377
  num: 18,
@@ -1357,7 +1412,7 @@ exports.Abilities = {
1357
1412
  return this.chainModify(1.5);
1358
1413
  }
1359
1414
  },
1360
- isBreakable: true,
1415
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, breakable: 1 },
1361
1416
  name: "Flower Gift",
1362
1417
  rating: 1,
1363
1418
  num: 122,
@@ -1397,7 +1452,7 @@ exports.Abilities = {
1397
1452
  return null;
1398
1453
  }
1399
1454
  },
1400
- isBreakable: true,
1455
+ flags: { breakable: 1 },
1401
1456
  name: "Flower Veil",
1402
1457
  rating: 0,
1403
1458
  num: 166,
@@ -1411,7 +1466,7 @@ exports.Abilities = {
1411
1466
  mod /= 2;
1412
1467
  return this.chainModify(mod);
1413
1468
  },
1414
- isBreakable: true,
1469
+ flags: { breakable: 1 },
1415
1470
  name: "Fluffy",
1416
1471
  rating: 3.5,
1417
1472
  num: 218,
@@ -1449,6 +1504,7 @@ exports.Abilities = {
1449
1504
  pokemon.formeChange(forme, this.effect, false, '[msg]');
1450
1505
  }
1451
1506
  },
1507
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1 },
1452
1508
  name: "Forecast",
1453
1509
  rating: 2,
1454
1510
  num: 59,
@@ -1483,19 +1539,20 @@ exports.Abilities = {
1483
1539
  const [warnMoveName, warnTarget] = this.sample(warnMoves);
1484
1540
  this.add('-activate', pokemon, 'ability: Forewarn', warnMoveName, '[of] ' + warnTarget);
1485
1541
  },
1542
+ flags: {},
1486
1543
  name: "Forewarn",
1487
1544
  rating: 0.5,
1488
1545
  num: 108,
1489
1546
  },
1490
1547
  friendguard: {
1491
- name: "Friend Guard",
1492
1548
  onAnyModifyDamage(damage, source, target, move) {
1493
1549
  if (target !== this.effectState.target && target.isAlly(this.effectState.target)) {
1494
1550
  this.debug('Friend Guard weaken');
1495
1551
  return this.chainModify(0.75);
1496
1552
  }
1497
1553
  },
1498
- isBreakable: true,
1554
+ flags: { breakable: 1 },
1555
+ name: "Friend Guard",
1499
1556
  rating: 0,
1500
1557
  num: 132,
1501
1558
  },
@@ -1507,6 +1564,7 @@ exports.Abilities = {
1507
1564
  }
1508
1565
  }
1509
1566
  },
1567
+ flags: {},
1510
1568
  name: "Frisk",
1511
1569
  rating: 1.5,
1512
1570
  num: 119,
@@ -1527,6 +1585,7 @@ exports.Abilities = {
1527
1585
  this.add("-fail", target, "unboost", "[from] ability: Full Metal Body", "[of] " + target);
1528
1586
  }
1529
1587
  },
1588
+ flags: {},
1530
1589
  name: "Full Metal Body",
1531
1590
  rating: 2,
1532
1591
  num: 230,
@@ -1536,7 +1595,7 @@ exports.Abilities = {
1536
1595
  onModifyDef(def) {
1537
1596
  return this.chainModify(2);
1538
1597
  },
1539
- isBreakable: true,
1598
+ flags: { breakable: 1 },
1540
1599
  name: "Fur Coat",
1541
1600
  rating: 4,
1542
1601
  num: 169,
@@ -1546,6 +1605,7 @@ exports.Abilities = {
1546
1605
  if (move?.type === 'Flying' && pokemon.hp === pokemon.maxhp)
1547
1606
  return priority + 1;
1548
1607
  },
1608
+ flags: {},
1549
1609
  name: "Gale Wings",
1550
1610
  rating: 1.5,
1551
1611
  num: 177,
@@ -1567,20 +1627,22 @@ exports.Abilities = {
1567
1627
  if (move.typeChangerBoosted === this.effect)
1568
1628
  return this.chainModify([4915, 4096]);
1569
1629
  },
1630
+ flags: {},
1570
1631
  name: "Galvanize",
1571
1632
  rating: 4,
1572
1633
  num: 206,
1573
1634
  },
1574
1635
  gluttony: {
1575
- name: "Gluttony",
1576
- rating: 1.5,
1577
- num: 82,
1578
1636
  onStart(pokemon) {
1579
1637
  pokemon.abilityState.gluttony = true;
1580
1638
  },
1581
1639
  onDamage(item, pokemon) {
1582
1640
  pokemon.abilityState.gluttony = true;
1583
1641
  },
1642
+ flags: {},
1643
+ name: "Gluttony",
1644
+ rating: 1.5,
1645
+ num: 82,
1584
1646
  },
1585
1647
  goodasgold: {
1586
1648
  onTryHit(target, source, move) {
@@ -1589,7 +1651,7 @@ exports.Abilities = {
1589
1651
  return null;
1590
1652
  }
1591
1653
  },
1592
- isBreakable: true,
1654
+ flags: { breakable: 1 },
1593
1655
  name: "Good as Gold",
1594
1656
  rating: 5,
1595
1657
  num: 283,
@@ -1601,6 +1663,7 @@ exports.Abilities = {
1601
1663
  this.boost({ spe: -1 }, source, target, null, true);
1602
1664
  }
1603
1665
  },
1666
+ flags: {},
1604
1667
  name: "Gooey",
1605
1668
  rating: 2,
1606
1669
  num: 183,
@@ -1648,6 +1711,7 @@ exports.Abilities = {
1648
1711
  onEnd(pokemon) {
1649
1712
  pokemon.abilityState.choiceLock = "";
1650
1713
  },
1714
+ flags: {},
1651
1715
  name: "Gorilla Tactics",
1652
1716
  rating: 4.5,
1653
1717
  num: 255,
@@ -1658,7 +1722,7 @@ exports.Abilities = {
1658
1722
  if (this.field.isTerrain('grassyterrain'))
1659
1723
  return this.chainModify(1.5);
1660
1724
  },
1661
- isBreakable: true,
1725
+ flags: { breakable: 1 },
1662
1726
  name: "Grass Pelt",
1663
1727
  rating: 0.5,
1664
1728
  num: 179,
@@ -1667,6 +1731,7 @@ exports.Abilities = {
1667
1731
  onStart(source) {
1668
1732
  this.field.setTerrain('grassyterrain');
1669
1733
  },
1734
+ flags: {},
1670
1735
  name: "Grassy Surge",
1671
1736
  rating: 4,
1672
1737
  num: 229,
@@ -1677,6 +1742,7 @@ exports.Abilities = {
1677
1742
  this.boost({ spa: length }, source);
1678
1743
  }
1679
1744
  },
1745
+ flags: {},
1680
1746
  name: "Grim Neigh",
1681
1747
  rating: 3,
1682
1748
  num: 265,
@@ -1693,14 +1759,14 @@ exports.Abilities = {
1693
1759
  this.boost({ atk: 1 }, target, target, null, false, true);
1694
1760
  }
1695
1761
  },
1696
- isBreakable: true,
1762
+ flags: { breakable: 1 },
1697
1763
  name: "Guard Dog",
1698
1764
  rating: 2,
1699
1765
  num: 275,
1700
1766
  },
1701
1767
  gulpmissile: {
1702
1768
  onDamagingHit(damage, target, source, move) {
1703
- if (!source.hp || !source.isActive || target.transformed || target.isSemiInvulnerable())
1769
+ if (!source.hp || !source.isActive || target.isSemiInvulnerable())
1704
1770
  return;
1705
1771
  if (['cramorantgulping', 'cramorantgorging'].includes(target.species.id)) {
1706
1772
  this.damage(source.baseMaxhp / 4, source, target);
@@ -1715,13 +1781,12 @@ exports.Abilities = {
1715
1781
  },
1716
1782
  // The Dive part of this mechanic is implemented in Dive's `onTryMove` in moves.ts
1717
1783
  onSourceTryPrimaryHit(target, source, effect) {
1718
- if (effect && effect.id === 'surf' && source.hasAbility('gulpmissile') &&
1719
- source.species.name === 'Cramorant' && !source.transformed) {
1784
+ if (effect?.id === 'surf' && source.hasAbility('gulpmissile') && source.species.name === 'Cramorant') {
1720
1785
  const forme = source.hp <= source.maxhp / 2 ? 'cramorantgorging' : 'cramorantgulping';
1721
1786
  source.formeChange(forme, effect);
1722
1787
  }
1723
1788
  },
1724
- isPermanent: true,
1789
+ flags: { cantsuppress: 1, notransform: 1 },
1725
1790
  name: "Gulp Missile",
1726
1791
  rating: 2.5,
1727
1792
  num: 241,
@@ -1733,6 +1798,7 @@ exports.Abilities = {
1733
1798
  return this.chainModify(1.5);
1734
1799
  }
1735
1800
  },
1801
+ flags: {},
1736
1802
  name: "Guts",
1737
1803
  rating: 3.5,
1738
1804
  num: 62,
@@ -1750,12 +1816,12 @@ exports.Abilities = {
1750
1816
  return this.chainModify([5461, 4096]);
1751
1817
  }
1752
1818
  },
1819
+ flags: {},
1753
1820
  name: "Hadron Engine",
1754
1821
  rating: 4.5,
1755
1822
  num: 289,
1756
1823
  },
1757
1824
  harvest: {
1758
- name: "Harvest",
1759
1825
  onResidualOrder: 28,
1760
1826
  onResidualSubOrder: 2,
1761
1827
  onResidual(pokemon) {
@@ -1767,11 +1833,12 @@ exports.Abilities = {
1767
1833
  }
1768
1834
  }
1769
1835
  },
1836
+ flags: {},
1837
+ name: "Harvest",
1770
1838
  rating: 2.5,
1771
1839
  num: 139,
1772
1840
  },
1773
1841
  healer: {
1774
- name: "Healer",
1775
1842
  onResidualOrder: 5,
1776
1843
  onResidualSubOrder: 3,
1777
1844
  onResidual(pokemon) {
@@ -1782,6 +1849,8 @@ exports.Abilities = {
1782
1849
  }
1783
1850
  }
1784
1851
  },
1852
+ flags: {},
1853
+ name: "Healer",
1785
1854
  rating: 0,
1786
1855
  num: 131,
1787
1856
  },
@@ -1805,7 +1874,7 @@ exports.Abilities = {
1805
1874
  return damage / 2;
1806
1875
  }
1807
1876
  },
1808
- isBreakable: true,
1877
+ flags: { breakable: 1 },
1809
1878
  name: "Heatproof",
1810
1879
  rating: 2,
1811
1880
  num: 85,
@@ -1815,12 +1884,13 @@ exports.Abilities = {
1815
1884
  onModifyWeight(weighthg) {
1816
1885
  return weighthg * 2;
1817
1886
  },
1818
- isBreakable: true,
1887
+ flags: { breakable: 1 },
1819
1888
  name: "Heavy Metal",
1820
1889
  rating: 0,
1821
1890
  num: 134,
1822
1891
  },
1823
1892
  honeygather: {
1893
+ flags: {},
1824
1894
  name: "Honey Gather",
1825
1895
  rating: 0,
1826
1896
  num: 118,
@@ -1831,6 +1901,7 @@ exports.Abilities = {
1831
1901
  this.heal(ally.baseMaxhp / 4, ally, pokemon);
1832
1902
  }
1833
1903
  },
1904
+ flags: {},
1834
1905
  name: "Hospitality",
1835
1906
  rating: 0,
1836
1907
  num: 299,
@@ -1840,6 +1911,7 @@ exports.Abilities = {
1840
1911
  onModifyAtk(atk) {
1841
1912
  return this.chainModify(2);
1842
1913
  },
1914
+ flags: {},
1843
1915
  name: "Huge Power",
1844
1916
  rating: 5,
1845
1917
  num: 37,
@@ -1847,11 +1919,12 @@ exports.Abilities = {
1847
1919
  hungerswitch: {
1848
1920
  onResidualOrder: 29,
1849
1921
  onResidual(pokemon) {
1850
- if (pokemon.species.baseSpecies !== 'Morpeko' || pokemon.transformed || pokemon.terastallized)
1922
+ if (pokemon.species.baseSpecies !== 'Morpeko' || pokemon.terastallized)
1851
1923
  return;
1852
1924
  const targetForme = pokemon.species.name === 'Morpeko' ? 'Morpeko-Hangry' : 'Morpeko';
1853
1925
  pokemon.formeChange(targetForme);
1854
1926
  },
1927
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, notransform: 1 },
1855
1928
  name: "Hunger Switch",
1856
1929
  rating: 1,
1857
1930
  num: 258,
@@ -1868,6 +1941,7 @@ exports.Abilities = {
1868
1941
  return this.chainModify([3277, 4096]);
1869
1942
  }
1870
1943
  },
1944
+ flags: {},
1871
1945
  name: "Hustle",
1872
1946
  rating: 3.5,
1873
1947
  num: 55,
@@ -1882,6 +1956,7 @@ exports.Abilities = {
1882
1956
  pokemon.cureStatus();
1883
1957
  }
1884
1958
  },
1959
+ flags: {},
1885
1960
  name: "Hydration",
1886
1961
  rating: 1.5,
1887
1962
  num: 93,
@@ -1897,7 +1972,7 @@ exports.Abilities = {
1897
1972
  }
1898
1973
  }
1899
1974
  },
1900
- isBreakable: true,
1975
+ flags: { breakable: 1 },
1901
1976
  name: "Hyper Cutter",
1902
1977
  rating: 1.5,
1903
1978
  num: 52,
@@ -1912,14 +1987,14 @@ exports.Abilities = {
1912
1987
  if (type === 'hail')
1913
1988
  return false;
1914
1989
  },
1990
+ flags: {},
1915
1991
  name: "Ice Body",
1916
1992
  rating: 1,
1917
1993
  num: 115,
1918
1994
  },
1919
1995
  iceface: {
1920
1996
  onStart(pokemon) {
1921
- if (this.field.isWeather(['hail', 'snow']) &&
1922
- pokemon.species.id === 'eiscuenoice' && !pokemon.transformed) {
1997
+ if (this.field.isWeather(['hail', 'snow']) && pokemon.species.id === 'eiscuenoice') {
1923
1998
  this.add('-activate', pokemon, 'ability: Ice Face');
1924
1999
  this.effectState.busted = false;
1925
2000
  pokemon.formeChange('Eiscue', this.effect, true);
@@ -1927,8 +2002,7 @@ exports.Abilities = {
1927
2002
  },
1928
2003
  onDamagePriority: 1,
1929
2004
  onDamage(damage, target, source, effect) {
1930
- if (effect && effect.effectType === 'Move' && effect.category === 'Physical' &&
1931
- target.species.id === 'eiscue' && !target.transformed) {
2005
+ if (effect?.effectType === 'Move' && effect.category === 'Physical' && target.species.id === 'eiscue') {
1932
2006
  this.add('-activate', target, 'ability: Ice Face');
1933
2007
  this.effectState.busted = true;
1934
2008
  return 0;
@@ -1937,7 +2011,7 @@ exports.Abilities = {
1937
2011
  onCriticalHit(target, type, move) {
1938
2012
  if (!target)
1939
2013
  return;
1940
- if (move.category !== 'Physical' || target.species.id !== 'eiscue' || target.transformed)
2014
+ if (move.category !== 'Physical' || target.species.id !== 'eiscue')
1941
2015
  return;
1942
2016
  if (target.volatiles['substitute'] && !(move.flags['bypasssub'] || move.infiltrates))
1943
2017
  return;
@@ -1948,7 +2022,7 @@ exports.Abilities = {
1948
2022
  onEffectiveness(typeMod, target, type, move) {
1949
2023
  if (!target)
1950
2024
  return;
1951
- if (move.category !== 'Physical' || target.species.id !== 'eiscue' || target.transformed)
2025
+ if (move.category !== 'Physical' || target.species.id !== 'eiscue')
1952
2026
  return;
1953
2027
  const hitSub = target.volatiles['substitute'] && !move.flags['bypasssub'] && !(move.infiltrates && this.gen >= 6);
1954
2028
  if (hitSub)
@@ -1968,15 +2042,16 @@ exports.Abilities = {
1968
2042
  return;
1969
2043
  if (!pokemon.hp)
1970
2044
  return;
1971
- if (this.field.isWeather(['hail', 'snow']) &&
1972
- pokemon.species.id === 'eiscuenoice' && !pokemon.transformed) {
2045
+ if (this.field.isWeather(['hail', 'snow']) && pokemon.species.id === 'eiscuenoice') {
1973
2046
  this.add('-activate', pokemon, 'ability: Ice Face');
1974
2047
  this.effectState.busted = false;
1975
2048
  pokemon.formeChange('Eiscue', this.effect, true);
1976
2049
  }
1977
2050
  },
1978
- isBreakable: true,
1979
- isPermanent: true,
2051
+ flags: {
2052
+ failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1,
2053
+ breakable: 1, notransform: 1,
2054
+ },
1980
2055
  name: "Ice Face",
1981
2056
  rating: 3,
1982
2057
  num: 248,
@@ -1987,7 +2062,7 @@ exports.Abilities = {
1987
2062
  return this.chainModify(0.5);
1988
2063
  }
1989
2064
  },
1990
- isBreakable: true,
2065
+ flags: { breakable: 1 },
1991
2066
  name: "Ice Scales",
1992
2067
  rating: 4,
1993
2068
  num: 246,
@@ -2006,7 +2081,7 @@ exports.Abilities = {
2006
2081
  onModifyMove(move) {
2007
2082
  move.ignoreEvasion = true;
2008
2083
  },
2009
- isBreakable: true,
2084
+ flags: { breakable: 1 },
2010
2085
  name: "Illuminate",
2011
2086
  rating: 0.5,
2012
2087
  num: 35,
@@ -2048,6 +2123,7 @@ exports.Abilities = {
2048
2123
  onFaint(pokemon) {
2049
2124
  pokemon.illusion = null;
2050
2125
  },
2126
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1 },
2051
2127
  name: "Illusion",
2052
2128
  rating: 4.5,
2053
2129
  num: 149,
@@ -2067,7 +2143,7 @@ exports.Abilities = {
2067
2143
  }
2068
2144
  return false;
2069
2145
  },
2070
- isBreakable: true,
2146
+ flags: { breakable: 1 },
2071
2147
  name: "Immunity",
2072
2148
  rating: 2,
2073
2149
  num: 17,
@@ -2089,6 +2165,7 @@ exports.Abilities = {
2089
2165
  }
2090
2166
  this.effectState.switchingIn = false;
2091
2167
  },
2168
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1 },
2092
2169
  name: "Imposter",
2093
2170
  rating: 5,
2094
2171
  num: 150,
@@ -2097,18 +2174,20 @@ exports.Abilities = {
2097
2174
  onModifyMove(move) {
2098
2175
  move.infiltrates = true;
2099
2176
  },
2177
+ flags: {},
2100
2178
  name: "Infiltrator",
2101
2179
  rating: 2.5,
2102
2180
  num: 151,
2103
2181
  },
2104
2182
  innardsout: {
2105
- name: "Innards Out",
2106
2183
  onDamagingHitOrder: 1,
2107
2184
  onDamagingHit(damage, target, source, move) {
2108
2185
  if (!target.hp) {
2109
2186
  this.damage(target.getUndynamaxedHP(damage), source, target);
2110
2187
  }
2111
2188
  },
2189
+ flags: {},
2190
+ name: "Innards Out",
2112
2191
  rating: 4,
2113
2192
  num: 215,
2114
2193
  },
@@ -2123,7 +2202,7 @@ exports.Abilities = {
2123
2202
  this.add('-fail', target, 'unboost', 'Attack', '[from] ability: Inner Focus', '[of] ' + target);
2124
2203
  }
2125
2204
  },
2126
- isBreakable: true,
2205
+ flags: { breakable: 1 },
2127
2206
  name: "Inner Focus",
2128
2207
  rating: 1,
2129
2208
  num: 39,
@@ -2149,7 +2228,7 @@ exports.Abilities = {
2149
2228
  return null;
2150
2229
  }
2151
2230
  },
2152
- isBreakable: true,
2231
+ flags: { breakable: 1 },
2153
2232
  name: "Insomnia",
2154
2233
  rating: 1.5,
2155
2234
  num: 15,
@@ -2170,6 +2249,7 @@ exports.Abilities = {
2170
2249
  }
2171
2250
  }
2172
2251
  },
2252
+ flags: {},
2173
2253
  name: "Intimidate",
2174
2254
  rating: 3.5,
2175
2255
  num: 22,
@@ -2181,6 +2261,7 @@ exports.Abilities = {
2181
2261
  pokemon.swordBoost = true;
2182
2262
  this.boost({ atk: 1 }, pokemon);
2183
2263
  },
2264
+ flags: {},
2184
2265
  name: "Intrepid Sword",
2185
2266
  rating: 4,
2186
2267
  num: 234,
@@ -2192,6 +2273,7 @@ exports.Abilities = {
2192
2273
  this.damage(source.baseMaxhp / 8, source, target);
2193
2274
  }
2194
2275
  },
2276
+ flags: {},
2195
2277
  name: "Iron Barbs",
2196
2278
  rating: 2.5,
2197
2279
  num: 160,
@@ -2204,6 +2286,7 @@ exports.Abilities = {
2204
2286
  return this.chainModify([4915, 4096]);
2205
2287
  }
2206
2288
  },
2289
+ flags: {},
2207
2290
  name: "Iron Fist",
2208
2291
  rating: 3,
2209
2292
  num: 89,
@@ -2214,6 +2297,7 @@ exports.Abilities = {
2214
2297
  this.boost({ atk: 1 });
2215
2298
  }
2216
2299
  },
2300
+ flags: {},
2217
2301
  name: "Justified",
2218
2302
  rating: 2.5,
2219
2303
  num: 154,
@@ -2232,7 +2316,7 @@ exports.Abilities = {
2232
2316
  onModifyMove(move) {
2233
2317
  move.ignoreEvasion = true;
2234
2318
  },
2235
- isBreakable: true,
2319
+ flags: { breakable: 1 },
2236
2320
  name: "Keen Eye",
2237
2321
  rating: 0.5,
2238
2322
  num: 51,
@@ -2242,6 +2326,7 @@ exports.Abilities = {
2242
2326
  onStart(pokemon) {
2243
2327
  this.singleEvent('End', pokemon.getItem(), pokemon.itemState, pokemon);
2244
2328
  },
2329
+ flags: {},
2245
2330
  name: "Klutz",
2246
2331
  rating: -1,
2247
2332
  num: 103,
@@ -2261,14 +2346,14 @@ exports.Abilities = {
2261
2346
  return null;
2262
2347
  }
2263
2348
  },
2264
- isBreakable: true,
2349
+ flags: { breakable: 1 },
2265
2350
  name: "Leaf Guard",
2266
2351
  rating: 0.5,
2267
2352
  num: 102,
2268
2353
  },
2269
2354
  levitate: {
2270
2355
  // airborneness implemented in sim/pokemon.js:Pokemon#isGrounded
2271
- isBreakable: true,
2356
+ flags: { breakable: 1 },
2272
2357
  name: "Levitate",
2273
2358
  rating: 3.5,
2274
2359
  num: 26,
@@ -2290,6 +2375,7 @@ exports.Abilities = {
2290
2375
  onSwitchIn() {
2291
2376
  delete this.effectState.libero;
2292
2377
  },
2378
+ flags: {},
2293
2379
  name: "Libero",
2294
2380
  rating: 4,
2295
2381
  num: 236,
@@ -2298,7 +2384,7 @@ exports.Abilities = {
2298
2384
  onModifyWeight(weighthg) {
2299
2385
  return this.trunc(weighthg / 2);
2300
2386
  },
2301
- isBreakable: true,
2387
+ flags: { breakable: 1 },
2302
2388
  name: "Light Metal",
2303
2389
  rating: 1,
2304
2390
  num: 135,
@@ -2325,7 +2411,7 @@ exports.Abilities = {
2325
2411
  return this.effectState.target;
2326
2412
  }
2327
2413
  },
2328
- isBreakable: true,
2414
+ flags: { breakable: 1 },
2329
2415
  name: "Lightning Rod",
2330
2416
  rating: 3,
2331
2417
  num: 31,
@@ -2345,7 +2431,7 @@ exports.Abilities = {
2345
2431
  }
2346
2432
  return false;
2347
2433
  },
2348
- isBreakable: true,
2434
+ flags: { breakable: 1 },
2349
2435
  name: "Limber",
2350
2436
  rating: 2,
2351
2437
  num: 7,
@@ -2353,7 +2439,7 @@ exports.Abilities = {
2353
2439
  lingeringaroma: {
2354
2440
  onDamagingHit(damage, target, source, move) {
2355
2441
  const sourceAbility = source.getAbility();
2356
- if (sourceAbility.isPermanent || sourceAbility.id === 'lingeringaroma') {
2442
+ if (sourceAbility.flags['cantsuppress'] || sourceAbility.id === 'lingeringaroma') {
2357
2443
  return;
2358
2444
  }
2359
2445
  if (this.checkMoveMakesContact(move, source, target, !source.isAlly(target))) {
@@ -2363,6 +2449,7 @@ exports.Abilities = {
2363
2449
  }
2364
2450
  }
2365
2451
  },
2452
+ flags: {},
2366
2453
  name: "Lingering Aroma",
2367
2454
  rating: 2,
2368
2455
  num: 268,
@@ -2376,6 +2463,7 @@ exports.Abilities = {
2376
2463
  return 0;
2377
2464
  }
2378
2465
  },
2466
+ flags: {},
2379
2467
  name: "Liquid Ooze",
2380
2468
  rating: 2.5,
2381
2469
  num: 64,
@@ -2387,6 +2475,7 @@ exports.Abilities = {
2387
2475
  move.type = 'Water';
2388
2476
  }
2389
2477
  },
2478
+ flags: {},
2390
2479
  name: "Liquid Voice",
2391
2480
  rating: 1.5,
2392
2481
  num: 204,
@@ -2395,12 +2484,12 @@ exports.Abilities = {
2395
2484
  onModifyMove(move) {
2396
2485
  delete move.flags['contact'];
2397
2486
  },
2487
+ flags: {},
2398
2488
  name: "Long Reach",
2399
2489
  rating: 1,
2400
2490
  num: 203,
2401
2491
  },
2402
2492
  magicbounce: {
2403
- name: "Magic Bounce",
2404
2493
  onTryHitPriority: 1,
2405
2494
  onTryHit(target, source, move) {
2406
2495
  if (target === source || move.hasBounced || !move.flags['reflectable']) {
@@ -2425,7 +2514,8 @@ exports.Abilities = {
2425
2514
  condition: {
2426
2515
  duration: 1,
2427
2516
  },
2428
- isBreakable: true,
2517
+ flags: { breakable: 1 },
2518
+ name: "Magic Bounce",
2429
2519
  rating: 4,
2430
2520
  num: 156,
2431
2521
  },
@@ -2437,6 +2527,7 @@ exports.Abilities = {
2437
2527
  return false;
2438
2528
  }
2439
2529
  },
2530
+ flags: {},
2440
2531
  name: "Magic Guard",
2441
2532
  rating: 4,
2442
2533
  num: 98,
@@ -2458,6 +2549,7 @@ exports.Abilities = {
2458
2549
  this.add('-item', source, yourItem, '[from] ability: Magician', '[of] ' + target);
2459
2550
  }
2460
2551
  },
2552
+ flags: {},
2461
2553
  name: "Magician",
2462
2554
  rating: 1,
2463
2555
  num: 170,
@@ -2473,7 +2565,7 @@ exports.Abilities = {
2473
2565
  if (type === 'frz')
2474
2566
  return false;
2475
2567
  },
2476
- isBreakable: true,
2568
+ flags: { breakable: 1 },
2477
2569
  name: "Magma Armor",
2478
2570
  rating: 0.5,
2479
2571
  num: 40,
@@ -2493,6 +2585,7 @@ exports.Abilities = {
2493
2585
  pokemon.maybeTrapped = true;
2494
2586
  }
2495
2587
  },
2588
+ flags: {},
2496
2589
  name: "Magnet Pull",
2497
2590
  rating: 4,
2498
2591
  num: 42,
@@ -2504,7 +2597,7 @@ exports.Abilities = {
2504
2597
  return this.chainModify(1.5);
2505
2598
  }
2506
2599
  },
2507
- isBreakable: true,
2600
+ flags: { breakable: 1 },
2508
2601
  name: "Marvel Scale",
2509
2602
  rating: 2.5,
2510
2603
  num: 63,
@@ -2516,6 +2609,7 @@ exports.Abilities = {
2516
2609
  return this.chainModify(1.5);
2517
2610
  }
2518
2611
  },
2612
+ flags: {},
2519
2613
  name: "Mega Launcher",
2520
2614
  rating: 3,
2521
2615
  num: 178,
@@ -2525,6 +2619,7 @@ exports.Abilities = {
2525
2619
  if (target && ['psn', 'tox'].includes(target.status))
2526
2620
  return 5;
2527
2621
  },
2622
+ flags: {},
2528
2623
  name: "Merciless",
2529
2624
  rating: 1.5,
2530
2625
  num: 196,
@@ -2564,6 +2659,7 @@ exports.Abilities = {
2564
2659
  this.add('-end', pokemon, 'typechange', '[silent]');
2565
2660
  }
2566
2661
  },
2662
+ flags: {},
2567
2663
  name: "Mimicry",
2568
2664
  rating: 0,
2569
2665
  num: 250,
@@ -2589,6 +2685,7 @@ exports.Abilities = {
2589
2685
  move.ignoreImmunity['Normal'] = true;
2590
2686
  }
2591
2687
  },
2688
+ flags: { breakable: 1 },
2592
2689
  name: "Mind's Eye",
2593
2690
  rating: 0,
2594
2691
  num: 300,
@@ -2602,6 +2699,7 @@ exports.Abilities = {
2602
2699
  }
2603
2700
  }
2604
2701
  },
2702
+ flags: {},
2605
2703
  name: "Minus",
2606
2704
  rating: 0,
2607
2705
  num: 58,
@@ -2626,7 +2724,7 @@ exports.Abilities = {
2626
2724
  }
2627
2725
  }
2628
2726
  },
2629
- isBreakable: true,
2727
+ flags: { breakable: 1 },
2630
2728
  name: "Mirror Armor",
2631
2729
  rating: 2,
2632
2730
  num: 240,
@@ -2635,6 +2733,7 @@ exports.Abilities = {
2635
2733
  onStart(source) {
2636
2734
  this.field.setTerrain('mistyterrain');
2637
2735
  },
2736
+ flags: {},
2638
2737
  name: "Misty Surge",
2639
2738
  rating: 3.5,
2640
2739
  num: 228,
@@ -2646,6 +2745,7 @@ exports.Abilities = {
2646
2745
  onModifyMove(move) {
2647
2746
  move.ignoreAbility = true;
2648
2747
  },
2748
+ flags: {},
2649
2749
  name: "Mold Breaker",
2650
2750
  rating: 3,
2651
2751
  num: 104,
@@ -2681,6 +2781,7 @@ exports.Abilities = {
2681
2781
  boost[randomStat] = -1;
2682
2782
  this.boost(boost, pokemon, pokemon);
2683
2783
  },
2784
+ flags: {},
2684
2785
  name: "Moody",
2685
2786
  rating: 5,
2686
2787
  num: 141,
@@ -2694,7 +2795,7 @@ exports.Abilities = {
2694
2795
  return null;
2695
2796
  }
2696
2797
  },
2697
- isBreakable: true,
2798
+ flags: { breakable: 1 },
2698
2799
  name: "Motor Drive",
2699
2800
  rating: 3,
2700
2801
  num: 78,
@@ -2705,6 +2806,7 @@ exports.Abilities = {
2705
2806
  this.boost({ atk: length }, source);
2706
2807
  }
2707
2808
  },
2809
+ flags: {},
2708
2810
  name: "Moxie",
2709
2811
  rating: 3,
2710
2812
  num: 153,
@@ -2716,23 +2818,22 @@ exports.Abilities = {
2716
2818
  return this.chainModify(0.5);
2717
2819
  }
2718
2820
  },
2719
- isBreakable: true,
2821
+ flags: { breakable: 1 },
2720
2822
  name: "Multiscale",
2721
2823
  rating: 3.5,
2722
2824
  num: 136,
2723
2825
  },
2724
2826
  multitype: {
2725
2827
  // Multitype's type-changing itself is implemented in statuses.js
2726
- isPermanent: true,
2828
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1 },
2727
2829
  name: "Multitype",
2728
2830
  rating: 4,
2729
2831
  num: 121,
2730
2832
  },
2731
2833
  mummy: {
2732
- name: "Mummy",
2733
2834
  onDamagingHit(damage, target, source, move) {
2734
2835
  const sourceAbility = source.getAbility();
2735
- if (sourceAbility.isPermanent || sourceAbility.id === 'mummy') {
2836
+ if (sourceAbility.flags['cantsuppress'] || sourceAbility.id === 'mummy') {
2736
2837
  return;
2737
2838
  }
2738
2839
  if (this.checkMoveMakesContact(move, source, target, !source.isAlly(target))) {
@@ -2742,6 +2843,8 @@ exports.Abilities = {
2742
2843
  }
2743
2844
  }
2744
2845
  },
2846
+ flags: {},
2847
+ name: "Mummy",
2745
2848
  rating: 2,
2746
2849
  num: 152,
2747
2850
  },
@@ -2757,6 +2860,7 @@ exports.Abilities = {
2757
2860
  move.ignoreAbility = true;
2758
2861
  }
2759
2862
  },
2863
+ flags: {},
2760
2864
  name: "Mycelium Might",
2761
2865
  rating: 2,
2762
2866
  num: 298,
@@ -2839,6 +2943,7 @@ exports.Abilities = {
2839
2943
  if (!pokemon.showCure)
2840
2944
  pokemon.showCure = undefined;
2841
2945
  },
2946
+ flags: {},
2842
2947
  name: "Natural Cure",
2843
2948
  rating: 2.5,
2844
2949
  num: 30,
@@ -2849,6 +2954,7 @@ exports.Abilities = {
2849
2954
  return this.chainModify([5120, 4096]);
2850
2955
  }
2851
2956
  },
2957
+ flags: {},
2852
2958
  name: "Neuroforce",
2853
2959
  rating: 2.5,
2854
2960
  num: 233,
@@ -2856,8 +2962,6 @@ exports.Abilities = {
2856
2962
  neutralizinggas: {
2857
2963
  // Ability suppression implemented in sim/pokemon.ts:Pokemon#ignoringAbility
2858
2964
  onPreStart(pokemon) {
2859
- if (pokemon.transformed)
2860
- return;
2861
2965
  this.add('-ability', pokemon, 'Neutralizing Gas');
2862
2966
  pokemon.abilityState.ending = false;
2863
2967
  const strongWeathers = ['desolateland', 'primordialsea', 'deltastream'];
@@ -2903,7 +3007,7 @@ exports.Abilities = {
2903
3007
  this.speedSort(sortedActive);
2904
3008
  for (const pokemon of sortedActive) {
2905
3009
  if (pokemon !== source) {
2906
- if (pokemon.getAbility().isPermanent)
3010
+ if (pokemon.getAbility().flags['cantsuppress'])
2907
3011
  continue; // does not interact with e.g Ice Face, Zen Mode
2908
3012
  if (pokemon.hasItem('abilityshield'))
2909
3013
  continue; // don't restart abilities that weren't suppressed
@@ -2915,6 +3019,7 @@ exports.Abilities = {
2915
3019
  }
2916
3020
  }
2917
3021
  },
3022
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, notransform: 1 },
2918
3023
  name: "Neutralizing Gas",
2919
3024
  rating: 3.5,
2920
3025
  num: 256,
@@ -2931,6 +3036,7 @@ exports.Abilities = {
2931
3036
  }
2932
3037
  return accuracy;
2933
3038
  },
3039
+ flags: {},
2934
3040
  name: "No Guard",
2935
3041
  rating: 4,
2936
3042
  num: 99,
@@ -2953,6 +3059,7 @@ exports.Abilities = {
2953
3059
  if (move.typeChangerBoosted === this.effect)
2954
3060
  return this.chainModify([4915, 4096]);
2955
3061
  },
3062
+ flags: {},
2956
3063
  name: "Normalize",
2957
3064
  rating: 0,
2958
3065
  num: 96,
@@ -2986,7 +3093,7 @@ exports.Abilities = {
2986
3093
  this.add('-fail', target, 'unboost', 'Attack', '[from] ability: Oblivious', '[of] ' + target);
2987
3094
  }
2988
3095
  },
2989
- isBreakable: true,
3096
+ flags: { breakable: 1 },
2990
3097
  name: "Oblivious",
2991
3098
  rating: 1.5,
2992
3099
  num: 12,
@@ -3007,6 +3114,7 @@ exports.Abilities = {
3007
3114
  return;
3008
3115
  this.boost(positiveBoosts, pokemon);
3009
3116
  },
3117
+ flags: {},
3010
3118
  name: "Opportunist",
3011
3119
  rating: 3,
3012
3120
  num: 290,
@@ -3027,6 +3135,7 @@ exports.Abilities = {
3027
3135
  return this.chainModify([5461, 4096]);
3028
3136
  }
3029
3137
  },
3138
+ flags: {},
3030
3139
  name: "Orichalcum Pulse",
3031
3140
  rating: 4.5,
3032
3141
  num: 288,
@@ -3043,7 +3152,7 @@ exports.Abilities = {
3043
3152
  return null;
3044
3153
  }
3045
3154
  },
3046
- isBreakable: true,
3155
+ flags: { breakable: 1 },
3047
3156
  name: "Overcoat",
3048
3157
  rating: 2,
3049
3158
  num: 142,
@@ -3063,6 +3172,7 @@ exports.Abilities = {
3063
3172
  return this.chainModify(1.5);
3064
3173
  }
3065
3174
  },
3175
+ flags: {},
3066
3176
  name: "Overgrow",
3067
3177
  rating: 2,
3068
3178
  num: 65,
@@ -3089,7 +3199,7 @@ exports.Abilities = {
3089
3199
  this.add('-fail', target, 'unboost', 'Attack', '[from] ability: Own Tempo', '[of] ' + target);
3090
3200
  }
3091
3201
  },
3092
- isBreakable: true,
3202
+ flags: { breakable: 1 },
3093
3203
  name: "Own Tempo",
3094
3204
  rating: 1.5,
3095
3205
  num: 20,
@@ -3109,6 +3219,7 @@ exports.Abilities = {
3109
3219
  return secondaries.filter(effect => effect.volatileStatus === 'flinch');
3110
3220
  }
3111
3221
  },
3222
+ flags: {},
3112
3223
  name: "Parental Bond",
3113
3224
  rating: 4.5,
3114
3225
  num: 185,
@@ -3151,7 +3262,7 @@ exports.Abilities = {
3151
3262
  }
3152
3263
  return false;
3153
3264
  },
3154
- isBreakable: true,
3265
+ flags: { breakable: 1 },
3155
3266
  name: "Pastel Veil",
3156
3267
  rating: 2,
3157
3268
  num: 257,
@@ -3171,6 +3282,7 @@ exports.Abilities = {
3171
3282
  pokemon.addVolatile('perishsong');
3172
3283
  }
3173
3284
  },
3285
+ flags: {},
3174
3286
  name: "Perish Body",
3175
3287
  rating: 1,
3176
3288
  num: 253,
@@ -3193,6 +3305,7 @@ exports.Abilities = {
3193
3305
  this.add('-item', target, yourItem, '[from] ability: Pickpocket', '[of] ' + source);
3194
3306
  }
3195
3307
  },
3308
+ flags: {},
3196
3309
  name: "Pickpocket",
3197
3310
  rating: 1,
3198
3311
  num: 124,
@@ -3212,6 +3325,7 @@ exports.Abilities = {
3212
3325
  this.add('-item', pokemon, this.dex.items.get(item), '[from] ability: Pickup');
3213
3326
  pokemon.setItem(item);
3214
3327
  },
3328
+ flags: {},
3215
3329
  name: "Pickup",
3216
3330
  rating: 0.5,
3217
3331
  num: 53,
@@ -3233,6 +3347,7 @@ exports.Abilities = {
3233
3347
  if (move.typeChangerBoosted === this.effect)
3234
3348
  return this.chainModify([4915, 4096]);
3235
3349
  },
3350
+ flags: {},
3236
3351
  name: "Pixilate",
3237
3352
  rating: 4,
3238
3353
  num: 182,
@@ -3246,6 +3361,7 @@ exports.Abilities = {
3246
3361
  }
3247
3362
  }
3248
3363
  },
3364
+ flags: {},
3249
3365
  name: "Plus",
3250
3366
  rating: 0,
3251
3367
  num: 57,
@@ -3258,6 +3374,7 @@ exports.Abilities = {
3258
3374
  return false;
3259
3375
  }
3260
3376
  },
3377
+ flags: {},
3261
3378
  name: "Poison Heal",
3262
3379
  rating: 4,
3263
3380
  num: 90,
@@ -3270,6 +3387,7 @@ exports.Abilities = {
3270
3387
  }
3271
3388
  }
3272
3389
  },
3390
+ flags: {},
3273
3391
  name: "Poison Point",
3274
3392
  rating: 1.5,
3275
3393
  num: 38,
@@ -3282,6 +3400,7 @@ exports.Abilities = {
3282
3400
  target.addVolatile('confusion');
3283
3401
  }
3284
3402
  },
3403
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1 },
3285
3404
  name: "Poison Puppeteer",
3286
3405
  rating: 3,
3287
3406
  num: 310,
@@ -3297,6 +3416,7 @@ exports.Abilities = {
3297
3416
  }
3298
3417
  }
3299
3418
  },
3419
+ flags: {},
3300
3420
  name: "Poison Touch",
3301
3421
  rating: 2,
3302
3422
  num: 143,
@@ -3316,7 +3436,7 @@ exports.Abilities = {
3316
3436
  pokemon.maxhp = newMaxHP;
3317
3437
  this.add('-heal', pokemon, pokemon.getHealth, '[silent]');
3318
3438
  },
3319
- isPermanent: true,
3439
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1 },
3320
3440
  name: "Power Construct",
3321
3441
  rating: 5,
3322
3442
  num: 211,
@@ -3326,15 +3446,13 @@ exports.Abilities = {
3326
3446
  if (!this.effectState.target.hp)
3327
3447
  return;
3328
3448
  const ability = target.getAbility();
3329
- const additionalBannedAbilities = [
3330
- 'noability', 'commander', 'flowergift', 'forecast', 'hungerswitch', 'illusion', 'imposter', 'neutralizinggas', 'powerofalchemy', 'receiver', 'trace', 'wonderguard',
3331
- ];
3332
- if (target.getAbility().isPermanent || additionalBannedAbilities.includes(target.ability))
3449
+ if (ability.flags['noreceiver'] || ability.id === 'noability')
3333
3450
  return;
3334
3451
  if (this.effectState.target.setAbility(ability)) {
3335
3452
  this.add('-ability', this.effectState.target, ability, '[from] ability: Power of Alchemy', '[of] ' + target);
3336
3453
  }
3337
3454
  },
3455
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1 },
3338
3456
  name: "Power of Alchemy",
3339
3457
  rating: 0,
3340
3458
  num: 223,
@@ -3347,6 +3465,7 @@ exports.Abilities = {
3347
3465
  return this.chainModify([5325, 4096]);
3348
3466
  }
3349
3467
  },
3468
+ flags: {},
3350
3469
  name: "Power Spot",
3351
3470
  rating: 0,
3352
3471
  num: 249,
@@ -3358,6 +3477,7 @@ exports.Abilities = {
3358
3477
  return priority + 1;
3359
3478
  }
3360
3479
  },
3480
+ flags: {},
3361
3481
  name: "Prankster",
3362
3482
  rating: 4,
3363
3483
  num: 158,
@@ -3371,6 +3491,7 @@ exports.Abilities = {
3371
3491
  return;
3372
3492
  return 1;
3373
3493
  },
3494
+ flags: {},
3374
3495
  name: "Pressure",
3375
3496
  rating: 2.5,
3376
3497
  num: 46,
@@ -3397,6 +3518,7 @@ exports.Abilities = {
3397
3518
  }
3398
3519
  this.field.clearWeather();
3399
3520
  },
3521
+ flags: {},
3400
3522
  name: "Primordial Sea",
3401
3523
  rating: 4.5,
3402
3524
  num: 189,
@@ -3408,6 +3530,7 @@ exports.Abilities = {
3408
3530
  return this.chainModify(0.75);
3409
3531
  }
3410
3532
  },
3533
+ flags: {},
3411
3534
  name: "Prism Armor",
3412
3535
  rating: 3,
3413
3536
  num: 232,
@@ -3418,6 +3541,7 @@ exports.Abilities = {
3418
3541
  // most of the implementation is in Battle#getTarget
3419
3542
  move.tracksTarget = move.target !== 'scripted';
3420
3543
  },
3544
+ flags: {},
3421
3545
  name: "Propeller Tail",
3422
3546
  rating: 0,
3423
3547
  num: 239,
@@ -3439,6 +3563,7 @@ exports.Abilities = {
3439
3563
  onSwitchIn(pokemon) {
3440
3564
  delete this.effectState.protean;
3441
3565
  },
3566
+ flags: {},
3442
3567
  name: "Protean",
3443
3568
  rating: 4,
3444
3569
  num: 168,
@@ -3448,8 +3573,6 @@ exports.Abilities = {
3448
3573
  this.singleEvent('WeatherChange', this.effect, this.effectState, pokemon);
3449
3574
  },
3450
3575
  onWeatherChange(pokemon) {
3451
- if (pokemon.transformed)
3452
- return;
3453
3576
  // Protosynthesis is not affected by Utility Umbrella
3454
3577
  if (this.field.isWeather('sunnyday')) {
3455
3578
  pokemon.addVolatile('protosynthesis');
@@ -3513,6 +3636,7 @@ exports.Abilities = {
3513
3636
  this.add('-end', pokemon, 'Protosynthesis');
3514
3637
  },
3515
3638
  },
3639
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, notransform: 1 },
3516
3640
  name: "Protosynthesis",
3517
3641
  rating: 3,
3518
3642
  num: 281,
@@ -3521,6 +3645,7 @@ exports.Abilities = {
3521
3645
  onStart(source) {
3522
3646
  this.field.setTerrain('psychicterrain');
3523
3647
  },
3648
+ flags: {},
3524
3649
  name: "Psychic Surge",
3525
3650
  rating: 4,
3526
3651
  num: 227,
@@ -3539,7 +3664,7 @@ exports.Abilities = {
3539
3664
  return this.chainModify(0.5);
3540
3665
  }
3541
3666
  },
3542
- isBreakable: true,
3667
+ flags: { breakable: 1 },
3543
3668
  name: "Punk Rock",
3544
3669
  rating: 3.5,
3545
3670
  num: 244,
@@ -3549,6 +3674,7 @@ exports.Abilities = {
3549
3674
  onModifyAtk(atk) {
3550
3675
  return this.chainModify(2);
3551
3676
  },
3677
+ flags: {},
3552
3678
  name: "Pure Power",
3553
3679
  rating: 5,
3554
3680
  num: 74,
@@ -3580,7 +3706,7 @@ exports.Abilities = {
3580
3706
  return this.chainModify(0.5);
3581
3707
  }
3582
3708
  },
3583
- isBreakable: true,
3709
+ flags: { breakable: 1 },
3584
3710
  name: "Purifying Salt",
3585
3711
  rating: 4,
3586
3712
  num: 272,
@@ -3590,8 +3716,6 @@ exports.Abilities = {
3590
3716
  this.singleEvent('TerrainChange', this.effect, this.effectState, pokemon);
3591
3717
  },
3592
3718
  onTerrainChange(pokemon) {
3593
- if (pokemon.transformed)
3594
- return;
3595
3719
  if (this.field.isTerrain('electricterrain')) {
3596
3720
  pokemon.addVolatile('quarkdrive');
3597
3721
  }
@@ -3654,6 +3778,7 @@ exports.Abilities = {
3654
3778
  this.add('-end', pokemon, 'Quark Drive');
3655
3779
  },
3656
3780
  },
3781
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, notransform: 1 },
3657
3782
  name: "Quark Drive",
3658
3783
  rating: 3,
3659
3784
  num: 282,
@@ -3671,7 +3796,7 @@ exports.Abilities = {
3671
3796
  return false;
3672
3797
  }
3673
3798
  },
3674
- isBreakable: true,
3799
+ flags: { breakable: 1 },
3675
3800
  name: "Queenly Majesty",
3676
3801
  rating: 2.5,
3677
3802
  num: 214,
@@ -3684,6 +3809,7 @@ exports.Abilities = {
3684
3809
  return 0.1;
3685
3810
  }
3686
3811
  },
3812
+ flags: {},
3687
3813
  name: "Quick Draw",
3688
3814
  rating: 2.5,
3689
3815
  num: 259,
@@ -3694,6 +3820,7 @@ exports.Abilities = {
3694
3820
  return this.chainModify(1.5);
3695
3821
  }
3696
3822
  },
3823
+ flags: {},
3697
3824
  name: "Quick Feet",
3698
3825
  rating: 2.5,
3699
3826
  num: 95,
@@ -3706,6 +3833,7 @@ exports.Abilities = {
3706
3833
  this.heal(target.baseMaxhp / 16);
3707
3834
  }
3708
3835
  },
3836
+ flags: {},
3709
3837
  name: "Rain Dish",
3710
3838
  rating: 1.5,
3711
3839
  num: 44,
@@ -3721,6 +3849,7 @@ exports.Abilities = {
3721
3849
  this.boost({ spe: 1 });
3722
3850
  }
3723
3851
  },
3852
+ flags: {},
3724
3853
  name: "Rattled",
3725
3854
  rating: 1,
3726
3855
  num: 155,
@@ -3730,15 +3859,13 @@ exports.Abilities = {
3730
3859
  if (!this.effectState.target.hp)
3731
3860
  return;
3732
3861
  const ability = target.getAbility();
3733
- const additionalBannedAbilities = [
3734
- 'noability', 'commander', 'flowergift', 'forecast', 'hungerswitch', 'illusion', 'imposter', 'neutralizinggas', 'powerofalchemy', 'receiver', 'trace', 'wonderguard',
3735
- ];
3736
- if (target.getAbility().isPermanent || additionalBannedAbilities.includes(target.ability))
3862
+ if (ability.flags['noreceiver'] || ability.id === 'noability')
3737
3863
  return;
3738
3864
  if (this.effectState.target.setAbility(ability)) {
3739
3865
  this.add('-ability', this.effectState.target, ability, '[from] ability: Receiver', '[of] ' + target);
3740
3866
  }
3741
3867
  },
3868
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1 },
3742
3869
  name: "Receiver",
3743
3870
  rating: 0,
3744
3871
  num: 222,
@@ -3751,6 +3878,7 @@ exports.Abilities = {
3751
3878
  return this.chainModify([4915, 4096]);
3752
3879
  }
3753
3880
  },
3881
+ flags: {},
3754
3882
  name: "Reckless",
3755
3883
  rating: 3,
3756
3884
  num: 120,
@@ -3772,6 +3900,7 @@ exports.Abilities = {
3772
3900
  if (move.typeChangerBoosted === this.effect)
3773
3901
  return this.chainModify([4915, 4096]);
3774
3902
  },
3903
+ flags: {},
3775
3904
  name: "Refrigerate",
3776
3905
  rating: 4,
3777
3906
  num: 174,
@@ -3780,6 +3909,7 @@ exports.Abilities = {
3780
3909
  onSwitchOut(pokemon) {
3781
3910
  pokemon.heal(pokemon.baseMaxhp / 3);
3782
3911
  },
3912
+ flags: {},
3783
3913
  name: "Regenerator",
3784
3914
  rating: 4.5,
3785
3915
  num: 144,
@@ -3820,6 +3950,7 @@ exports.Abilities = {
3820
3950
  // Record if the pokemon ate a berry to resist the attack
3821
3951
  pokemon.abilityState.berryWeaken = weakenBerries.includes(item.name);
3822
3952
  },
3953
+ flags: {},
3823
3954
  name: "Ripen",
3824
3955
  rating: 2,
3825
3956
  num: 247,
@@ -3838,13 +3969,14 @@ exports.Abilities = {
3838
3969
  }
3839
3970
  }
3840
3971
  },
3972
+ flags: {},
3841
3973
  name: "Rivalry",
3842
3974
  rating: 0,
3843
3975
  num: 79,
3844
3976
  },
3845
3977
  rkssystem: {
3846
3978
  // RKS System's type-changing itself is implemented in statuses.js
3847
- isPermanent: true,
3979
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1 },
3848
3980
  name: "RKS System",
3849
3981
  rating: 4,
3850
3982
  num: 225,
@@ -3858,6 +3990,7 @@ exports.Abilities = {
3858
3990
  return null;
3859
3991
  }
3860
3992
  },
3993
+ flags: {},
3861
3994
  name: "Rock Head",
3862
3995
  rating: 3,
3863
3996
  num: 69,
@@ -3877,6 +4010,7 @@ exports.Abilities = {
3877
4010
  return this.chainModify(1.5);
3878
4011
  }
3879
4012
  },
4013
+ flags: {},
3880
4014
  name: "Rocky Payload",
3881
4015
  rating: 3.5,
3882
4016
  num: 276,
@@ -3888,11 +4022,13 @@ exports.Abilities = {
3888
4022
  this.damage(source.baseMaxhp / 8, source, target);
3889
4023
  }
3890
4024
  },
4025
+ flags: {},
3891
4026
  name: "Rough Skin",
3892
4027
  rating: 2.5,
3893
4028
  num: 24,
3894
4029
  },
3895
4030
  runaway: {
4031
+ flags: {},
3896
4032
  name: "Run Away",
3897
4033
  rating: 0,
3898
4034
  num: 50,
@@ -3911,6 +4047,7 @@ exports.Abilities = {
3911
4047
  if (type === 'sandstorm')
3912
4048
  return false;
3913
4049
  },
4050
+ flags: {},
3914
4051
  name: "Sand Force",
3915
4052
  rating: 2,
3916
4053
  num: 159,
@@ -3925,6 +4062,7 @@ exports.Abilities = {
3925
4062
  if (type === 'sandstorm')
3926
4063
  return false;
3927
4064
  },
4065
+ flags: {},
3928
4066
  name: "Sand Rush",
3929
4067
  rating: 3,
3930
4068
  num: 146,
@@ -3933,6 +4071,7 @@ exports.Abilities = {
3933
4071
  onDamagingHit(damage, target, source, move) {
3934
4072
  this.field.setWeather('sandstorm');
3935
4073
  },
4074
+ flags: {},
3936
4075
  name: "Sand Spit",
3937
4076
  rating: 1,
3938
4077
  num: 245,
@@ -3941,6 +4080,7 @@ exports.Abilities = {
3941
4080
  onStart(source) {
3942
4081
  this.field.setWeather('sandstorm');
3943
4082
  },
4083
+ flags: {},
3944
4084
  name: "Sand Stream",
3945
4085
  rating: 4,
3946
4086
  num: 45,
@@ -3959,7 +4099,7 @@ exports.Abilities = {
3959
4099
  return this.chainModify([3277, 4096]);
3960
4100
  }
3961
4101
  },
3962
- isBreakable: true,
4102
+ flags: { breakable: 1 },
3963
4103
  name: "Sand Veil",
3964
4104
  rating: 1.5,
3965
4105
  num: 8,
@@ -3981,7 +4121,7 @@ exports.Abilities = {
3981
4121
  this.boost({ atk: 1 }, this.effectState.target);
3982
4122
  }
3983
4123
  },
3984
- isBreakable: true,
4124
+ flags: { breakable: 1 },
3985
4125
  name: "Sap Sipper",
3986
4126
  rating: 3,
3987
4127
  num: 157,
@@ -4017,7 +4157,7 @@ exports.Abilities = {
4017
4157
  }
4018
4158
  }
4019
4159
  },
4020
- isPermanent: true,
4160
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1 },
4021
4161
  name: "Schooling",
4022
4162
  rating: 3,
4023
4163
  num: 208,
@@ -4038,6 +4178,7 @@ exports.Abilities = {
4038
4178
  this.add('-fail', target, 'unboost', 'Attack', '[from] ability: Scrappy', '[of] ' + target);
4039
4179
  }
4040
4180
  },
4181
+ flags: {},
4041
4182
  name: "Scrappy",
4042
4183
  rating: 3,
4043
4184
  num: 113,
@@ -4057,6 +4198,7 @@ exports.Abilities = {
4057
4198
  }
4058
4199
  }
4059
4200
  },
4201
+ flags: {},
4060
4202
  name: "Screen Cleaner",
4061
4203
  rating: 2,
4062
4204
  num: 251,
@@ -4065,6 +4207,7 @@ exports.Abilities = {
4065
4207
  onDamagingHit(damage, target, source, move) {
4066
4208
  this.field.setTerrain('grassyterrain');
4067
4209
  },
4210
+ flags: {},
4068
4211
  name: "Seed Sower",
4069
4212
  rating: 2.5,
4070
4213
  num: 269,
@@ -4082,6 +4225,7 @@ exports.Abilities = {
4082
4225
  if (move.self?.chance)
4083
4226
  move.self.chance *= 2;
4084
4227
  },
4228
+ flags: {},
4085
4229
  name: "Serene Grace",
4086
4230
  rating: 3.5,
4087
4231
  num: 32,
@@ -4093,6 +4237,7 @@ exports.Abilities = {
4093
4237
  return this.chainModify(0.5);
4094
4238
  }
4095
4239
  },
4240
+ flags: {},
4096
4241
  name: "Shadow Shield",
4097
4242
  rating: 3.5,
4098
4243
  num: 231,
@@ -4112,6 +4257,7 @@ exports.Abilities = {
4112
4257
  pokemon.maybeTrapped = true;
4113
4258
  }
4114
4259
  },
4260
+ flags: {},
4115
4261
  name: "Shadow Tag",
4116
4262
  rating: 5,
4117
4263
  num: 23,
@@ -4124,6 +4270,7 @@ exports.Abilities = {
4124
4270
  return this.chainModify(1.5);
4125
4271
  }
4126
4272
  },
4273
+ flags: {},
4127
4274
  name: "Sharpness",
4128
4275
  rating: 3.5,
4129
4276
  num: 292,
@@ -4138,6 +4285,7 @@ exports.Abilities = {
4138
4285
  pokemon.cureStatus();
4139
4286
  }
4140
4287
  },
4288
+ flags: {},
4141
4289
  name: "Shed Skin",
4142
4290
  rating: 3,
4143
4291
  num: 61,
@@ -4159,13 +4307,14 @@ exports.Abilities = {
4159
4307
  if (move.hasSheerForce)
4160
4308
  return this.chainModify([5325, 4096]);
4161
4309
  },
4310
+ flags: {},
4162
4311
  name: "Sheer Force",
4163
4312
  rating: 3.5,
4164
4313
  num: 125,
4165
4314
  },
4166
4315
  shellarmor: {
4167
4316
  onCriticalHit: false,
4168
- isBreakable: true,
4317
+ flags: { breakable: 1 },
4169
4318
  name: "Shell Armor",
4170
4319
  rating: 1,
4171
4320
  num: 75,
@@ -4175,7 +4324,7 @@ exports.Abilities = {
4175
4324
  this.debug('Shield Dust prevent secondary');
4176
4325
  return secondaries.filter(effect => !!(effect.self || effect.dustproof));
4177
4326
  },
4178
- isBreakable: true,
4327
+ flags: { breakable: 1 },
4179
4328
  name: "Shield Dust",
4180
4329
  rating: 2,
4181
4330
  num: 19,
@@ -4226,7 +4375,7 @@ exports.Abilities = {
4226
4375
  this.add('-immune', target, '[from] ability: Shields Down');
4227
4376
  return null;
4228
4377
  },
4229
- isPermanent: true,
4378
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1 },
4230
4379
  name: "Shields Down",
4231
4380
  rating: 3,
4232
4381
  num: 197,
@@ -4240,7 +4389,7 @@ exports.Abilities = {
4240
4389
  boost[i] *= 2;
4241
4390
  }
4242
4391
  },
4243
- isBreakable: true,
4392
+ flags: { breakable: 1 },
4244
4393
  name: "Simple",
4245
4394
  rating: 4,
4246
4395
  num: 86,
@@ -4254,6 +4403,7 @@ exports.Abilities = {
4254
4403
  delete move.multiaccuracy;
4255
4404
  }
4256
4405
  },
4406
+ flags: {},
4257
4407
  name: "Skill Link",
4258
4408
  rating: 3,
4259
4409
  num: 92,
@@ -4284,6 +4434,7 @@ exports.Abilities = {
4284
4434
  this.add('-end', target, 'Slow Start');
4285
4435
  },
4286
4436
  },
4437
+ flags: {},
4287
4438
  name: "Slow Start",
4288
4439
  rating: -1,
4289
4440
  num: 112,
@@ -4294,6 +4445,7 @@ exports.Abilities = {
4294
4445
  return this.chainModify(2);
4295
4446
  }
4296
4447
  },
4448
+ flags: {},
4297
4449
  name: "Slush Rush",
4298
4450
  rating: 3,
4299
4451
  num: 202,
@@ -4305,6 +4457,7 @@ exports.Abilities = {
4305
4457
  return this.chainModify(1.5);
4306
4458
  }
4307
4459
  },
4460
+ flags: {},
4308
4461
  name: "Sniper",
4309
4462
  rating: 2,
4310
4463
  num: 97,
@@ -4323,7 +4476,7 @@ exports.Abilities = {
4323
4476
  return this.chainModify([3277, 4096]);
4324
4477
  }
4325
4478
  },
4326
- isBreakable: true,
4479
+ flags: { breakable: 1 },
4327
4480
  name: "Snow Cloak",
4328
4481
  rating: 1.5,
4329
4482
  num: 81,
@@ -4332,6 +4485,7 @@ exports.Abilities = {
4332
4485
  onStart(source) {
4333
4486
  this.field.setWeather('snow');
4334
4487
  },
4488
+ flags: {},
4335
4489
  name: "Snow Warning",
4336
4490
  rating: 4,
4337
4491
  num: 117,
@@ -4350,6 +4504,7 @@ exports.Abilities = {
4350
4504
  this.damage(target.baseMaxhp / 8, target, target);
4351
4505
  }
4352
4506
  },
4507
+ flags: {},
4353
4508
  name: "Solar Power",
4354
4509
  rating: 2,
4355
4510
  num: 94,
@@ -4361,7 +4516,7 @@ exports.Abilities = {
4361
4516
  return this.chainModify(0.75);
4362
4517
  }
4363
4518
  },
4364
- isBreakable: true,
4519
+ flags: { breakable: 1 },
4365
4520
  name: "Solid Rock",
4366
4521
  rating: 3,
4367
4522
  num: 116,
@@ -4371,6 +4526,7 @@ exports.Abilities = {
4371
4526
  onAnyFaint() {
4372
4527
  this.boost({ spa: 1 }, this.effectState.target);
4373
4528
  },
4529
+ flags: {},
4374
4530
  name: "Soul-Heart",
4375
4531
  rating: 3.5,
4376
4532
  num: 220,
@@ -4387,7 +4543,7 @@ exports.Abilities = {
4387
4543
  this.add('-immune', this.effectState.target, '[from] ability: Soundproof');
4388
4544
  }
4389
4545
  },
4390
- isBreakable: true,
4546
+ flags: { breakable: 1 },
4391
4547
  name: "Soundproof",
4392
4548
  rating: 2,
4393
4549
  num: 43,
@@ -4400,6 +4556,7 @@ exports.Abilities = {
4400
4556
  this.boost({ spe: 1 });
4401
4557
  }
4402
4558
  },
4559
+ flags: {},
4403
4560
  name: "Speed Boost",
4404
4561
  rating: 4.5,
4405
4562
  num: 3,
@@ -4419,12 +4576,14 @@ exports.Abilities = {
4419
4576
  return this.chainModify(2);
4420
4577
  }
4421
4578
  },
4579
+ flags: {},
4422
4580
  name: "Stakeout",
4423
4581
  rating: 4.5,
4424
4582
  num: 198,
4425
4583
  },
4426
4584
  stall: {
4427
4585
  onFractionalPriority: -0.1,
4586
+ flags: {},
4428
4587
  name: "Stall",
4429
4588
  rating: -1,
4430
4589
  num: 100,
@@ -4435,6 +4594,7 @@ exports.Abilities = {
4435
4594
  // most of the implementation is in Battle#getTarget
4436
4595
  move.tracksTarget = move.target !== 'scripted';
4437
4596
  },
4597
+ flags: {},
4438
4598
  name: "Stalwart",
4439
4599
  rating: 0,
4440
4600
  num: 242,
@@ -4443,6 +4603,7 @@ exports.Abilities = {
4443
4603
  onDamagingHit(damage, target, source, effect) {
4444
4604
  this.boost({ def: 1 });
4445
4605
  },
4606
+ flags: {},
4446
4607
  name: "Stamina",
4447
4608
  rating: 4,
4448
4609
  num: 192,
@@ -4458,7 +4619,7 @@ exports.Abilities = {
4458
4619
  if (attacker.species.name !== targetForme)
4459
4620
  attacker.formeChange(targetForme);
4460
4621
  },
4461
- isPermanent: true,
4622
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1 },
4462
4623
  name: "Stance Change",
4463
4624
  rating: 4,
4464
4625
  num: 176,
@@ -4471,6 +4632,7 @@ exports.Abilities = {
4471
4632
  }
4472
4633
  }
4473
4634
  },
4635
+ flags: {},
4474
4636
  name: "Static",
4475
4637
  rating: 2,
4476
4638
  num: 9,
@@ -4479,6 +4641,7 @@ exports.Abilities = {
4479
4641
  onFlinch(pokemon) {
4480
4642
  this.boost({ spe: 1 });
4481
4643
  },
4644
+ flags: {},
4482
4645
  name: "Steadfast",
4483
4646
  rating: 1,
4484
4647
  num: 80,
@@ -4489,6 +4652,7 @@ exports.Abilities = {
4489
4652
  this.boost({ spe: 6 });
4490
4653
  }
4491
4654
  },
4655
+ flags: {},
4492
4656
  name: "Steam Engine",
4493
4657
  rating: 2,
4494
4658
  num: 243,
@@ -4508,6 +4672,7 @@ exports.Abilities = {
4508
4672
  return this.chainModify(1.5);
4509
4673
  }
4510
4674
  },
4675
+ flags: {},
4511
4676
  name: "Steelworker",
4512
4677
  rating: 3.5,
4513
4678
  num: 200,
@@ -4520,6 +4685,7 @@ exports.Abilities = {
4520
4685
  return this.chainModify(1.5);
4521
4686
  }
4522
4687
  },
4688
+ flags: {},
4523
4689
  name: "Steely Spirit",
4524
4690
  rating: 3.5,
4525
4691
  num: 252,
@@ -4541,6 +4707,7 @@ exports.Abilities = {
4541
4707
  });
4542
4708
  }
4543
4709
  },
4710
+ flags: {},
4544
4711
  name: "Stench",
4545
4712
  rating: 0.5,
4546
4713
  num: 1,
@@ -4556,7 +4723,7 @@ exports.Abilities = {
4556
4723
  return false;
4557
4724
  }
4558
4725
  },
4559
- isBreakable: true,
4726
+ flags: { breakable: 1 },
4560
4727
  name: "Sticky Hold",
4561
4728
  rating: 1.5,
4562
4729
  num: 60,
@@ -4583,7 +4750,7 @@ exports.Abilities = {
4583
4750
  return this.effectState.target;
4584
4751
  }
4585
4752
  },
4586
- isBreakable: true,
4753
+ flags: { breakable: 1 },
4587
4754
  name: "Storm Drain",
4588
4755
  rating: 3,
4589
4756
  num: 114,
@@ -4595,6 +4762,7 @@ exports.Abilities = {
4595
4762
  return this.chainModify(1.5);
4596
4763
  }
4597
4764
  },
4765
+ flags: {},
4598
4766
  name: "Strong Jaw",
4599
4767
  rating: 3.5,
4600
4768
  num: 173,
@@ -4613,7 +4781,7 @@ exports.Abilities = {
4613
4781
  return target.hp - 1;
4614
4782
  }
4615
4783
  },
4616
- isBreakable: true,
4784
+ flags: { breakable: 1 },
4617
4785
  name: "Sturdy",
4618
4786
  rating: 3,
4619
4787
  num: 5,
@@ -4624,7 +4792,7 @@ exports.Abilities = {
4624
4792
  this.add('-activate', pokemon, 'ability: Suction Cups');
4625
4793
  return null;
4626
4794
  },
4627
- isBreakable: true,
4795
+ flags: { breakable: 1 },
4628
4796
  name: "Suction Cups",
4629
4797
  rating: 1,
4630
4798
  num: 21,
@@ -4633,6 +4801,7 @@ exports.Abilities = {
4633
4801
  onModifyCritRatio(critRatio) {
4634
4802
  return critRatio + 1;
4635
4803
  },
4804
+ flags: {},
4636
4805
  name: "Super Luck",
4637
4806
  rating: 1.5,
4638
4807
  num: 105,
@@ -4657,6 +4826,7 @@ exports.Abilities = {
4657
4826
  }
4658
4827
  }
4659
4828
  },
4829
+ flags: {},
4660
4830
  name: "Supersweet Syrup",
4661
4831
  rating: 1.5,
4662
4832
  num: 306,
@@ -4681,6 +4851,7 @@ exports.Abilities = {
4681
4851
  return this.chainModify([powMod[this.effectState.fallen], 4096]);
4682
4852
  }
4683
4853
  },
4854
+ flags: {},
4684
4855
  name: "Supreme Overlord",
4685
4856
  rating: 4,
4686
4857
  num: 293,
@@ -4691,6 +4862,7 @@ exports.Abilities = {
4691
4862
  return this.chainModify(2);
4692
4863
  }
4693
4864
  },
4865
+ flags: {},
4694
4866
  name: "Surge Surfer",
4695
4867
  rating: 3,
4696
4868
  num: 207,
@@ -4710,12 +4882,12 @@ exports.Abilities = {
4710
4882
  return this.chainModify(1.5);
4711
4883
  }
4712
4884
  },
4885
+ flags: {},
4713
4886
  name: "Swarm",
4714
4887
  rating: 2,
4715
4888
  num: 68,
4716
4889
  },
4717
4890
  sweetveil: {
4718
- name: "Sweet Veil",
4719
4891
  onAllySetStatus(status, target, source, effect) {
4720
4892
  if (status.id === 'slp') {
4721
4893
  this.debug('Sweet Veil interrupts sleep');
@@ -4732,7 +4904,8 @@ exports.Abilities = {
4732
4904
  return null;
4733
4905
  }
4734
4906
  },
4735
- isBreakable: true,
4907
+ flags: { breakable: 1 },
4908
+ name: "Sweet Veil",
4736
4909
  rating: 2,
4737
4910
  num: 175,
4738
4911
  },
@@ -4742,6 +4915,7 @@ exports.Abilities = {
4742
4915
  return this.chainModify(2);
4743
4916
  }
4744
4917
  },
4918
+ flags: {},
4745
4919
  name: "Swift Swim",
4746
4920
  rating: 3,
4747
4921
  num: 33,
@@ -4761,6 +4935,7 @@ exports.Abilities = {
4761
4935
  }
4762
4936
  this.add('-activate', source, 'ability: Symbiosis', myItem, '[of] ' + pokemon);
4763
4937
  },
4938
+ flags: {},
4764
4939
  name: "Symbiosis",
4765
4940
  rating: 0,
4766
4941
  num: 180,
@@ -4778,6 +4953,7 @@ exports.Abilities = {
4778
4953
  // and show messages when activating against it.
4779
4954
  source.trySetStatus(status, target, { status: status.id, id: 'synchronize' });
4780
4955
  },
4956
+ flags: {},
4781
4957
  name: "Synchronize",
4782
4958
  rating: 2,
4783
4959
  num: 28,
@@ -4799,6 +4975,7 @@ exports.Abilities = {
4799
4975
  this.debug('Sword of Ruin Def drop');
4800
4976
  return this.chainModify(0.75);
4801
4977
  },
4978
+ flags: {},
4802
4979
  name: "Sword of Ruin",
4803
4980
  rating: 4.5,
4804
4981
  num: 285,
@@ -4820,6 +4997,7 @@ exports.Abilities = {
4820
4997
  this.debug('Tablets of Ruin Atk drop');
4821
4998
  return this.chainModify(0.75);
4822
4999
  },
5000
+ flags: {},
4823
5001
  name: "Tablets of Ruin",
4824
5002
  rating: 4.5,
4825
5003
  num: 284,
@@ -4834,7 +5012,7 @@ exports.Abilities = {
4834
5012
  return this.chainModify(0.5);
4835
5013
  }
4836
5014
  },
4837
- isBreakable: true,
5015
+ flags: { breakable: 1 },
4838
5016
  name: "Tangled Feet",
4839
5017
  rating: 1,
4840
5018
  num: 77,
@@ -4846,6 +5024,7 @@ exports.Abilities = {
4846
5024
  this.boost({ spe: -1 }, source, target, null, true);
4847
5025
  }
4848
5026
  },
5027
+ flags: {},
4849
5028
  name: "Tangling Hair",
4850
5029
  rating: 2,
4851
5030
  num: 221,
@@ -4860,6 +5039,7 @@ exports.Abilities = {
4860
5039
  return this.chainModify(1.5);
4861
5040
  }
4862
5041
  },
5042
+ flags: {},
4863
5043
  name: "Technician",
4864
5044
  rating: 3.5,
4865
5045
  num: 101,
@@ -4871,7 +5051,7 @@ exports.Abilities = {
4871
5051
  return null;
4872
5052
  }
4873
5053
  },
4874
- isBreakable: true,
5054
+ flags: { breakable: 1 },
4875
5055
  name: "Telepathy",
4876
5056
  rating: 0,
4877
5057
  num: 140,
@@ -4886,13 +5066,14 @@ exports.Abilities = {
4886
5066
  this.field.clearTerrain();
4887
5067
  }
4888
5068
  },
5069
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1 },
4889
5070
  name: "Teraform Zero",
4890
5071
  rating: 3,
4891
5072
  num: 309,
4892
5073
  },
4893
5074
  terashell: {
4894
5075
  onEffectiveness(typeMod, target, type, move) {
4895
- if (!target || target.species.name !== 'Terapagos-Terastal')
5076
+ if (!target || target.baseSpecies.name !== 'Terapagos-Terastal')
4896
5077
  return;
4897
5078
  if (this.effectState.resisted)
4898
5079
  return -1; // all hits of multi-hit move should be not very effective
@@ -4909,21 +5090,21 @@ exports.Abilities = {
4909
5090
  onAnyAfterMove() {
4910
5091
  this.effectState.resisted = false;
4911
5092
  },
4912
- isBreakable: true,
5093
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, breakable: 1 },
4913
5094
  name: "Tera Shell",
4914
5095
  rating: 3.5,
4915
5096
  num: 308,
4916
5097
  },
4917
5098
  terashift: {
4918
5099
  onPreStart(pokemon) {
4919
- if (pokemon.baseSpecies.baseSpecies !== 'Terapagos' || pokemon.transformed)
5100
+ if (pokemon.baseSpecies.baseSpecies !== 'Terapagos')
4920
5101
  return;
4921
5102
  if (pokemon.species.forme !== 'Terastal') {
4922
5103
  this.add('-activate', pokemon, 'ability: Tera Shift');
4923
5104
  pokemon.formeChange('Terapagos-Terastal', this.effect, true);
4924
5105
  }
4925
5106
  },
4926
- isPermanent: true,
5107
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1, notransform: 1 },
4927
5108
  name: "Tera Shift",
4928
5109
  rating: 3,
4929
5110
  num: 307,
@@ -4935,6 +5116,7 @@ exports.Abilities = {
4935
5116
  onModifyMove(move) {
4936
5117
  move.ignoreAbility = true;
4937
5118
  },
5119
+ flags: {},
4938
5120
  name: "Teravolt",
4939
5121
  rating: 3,
4940
5122
  num: 164,
@@ -4959,6 +5141,7 @@ exports.Abilities = {
4959
5141
  }
4960
5142
  return false;
4961
5143
  },
5144
+ flags: { breakable: 1 },
4962
5145
  name: "Thermal Exchange",
4963
5146
  rating: 2.5,
4964
5147
  num: 270,
@@ -4978,7 +5161,7 @@ exports.Abilities = {
4978
5161
  return this.chainModify(0.5);
4979
5162
  }
4980
5163
  },
4981
- isBreakable: true,
5164
+ flags: { breakable: 1 },
4982
5165
  name: "Thick Fat",
4983
5166
  rating: 3.5,
4984
5167
  num: 47,
@@ -4990,6 +5173,7 @@ exports.Abilities = {
4990
5173
  return this.chainModify(2);
4991
5174
  }
4992
5175
  },
5176
+ flags: {},
4993
5177
  name: "Tinted Lens",
4994
5178
  rating: 4,
4995
5179
  num: 110,
@@ -5009,6 +5193,7 @@ exports.Abilities = {
5009
5193
  return this.chainModify(1.5);
5010
5194
  }
5011
5195
  },
5196
+ flags: {},
5012
5197
  name: "Torrent",
5013
5198
  rating: 2,
5014
5199
  num: 67,
@@ -5020,6 +5205,7 @@ exports.Abilities = {
5020
5205
  return this.chainModify([5325, 4096]);
5021
5206
  }
5022
5207
  },
5208
+ flags: {},
5023
5209
  name: "Tough Claws",
5024
5210
  rating: 3.5,
5025
5211
  num: 181,
@@ -5031,6 +5217,7 @@ exports.Abilities = {
5031
5217
  return this.chainModify(1.5);
5032
5218
  }
5033
5219
  },
5220
+ flags: {},
5034
5221
  name: "Toxic Boost",
5035
5222
  rating: 3,
5036
5223
  num: 137,
@@ -5044,6 +5231,7 @@ exports.Abilities = {
5044
5231
  target.trySetStatus('tox', source);
5045
5232
  }
5046
5233
  },
5234
+ flags: {},
5047
5235
  name: "Toxic Chain",
5048
5236
  rating: 4.5,
5049
5237
  num: 305,
@@ -5057,6 +5245,7 @@ exports.Abilities = {
5057
5245
  side.addSideCondition('toxicspikes', target);
5058
5246
  }
5059
5247
  },
5248
+ flags: {},
5060
5249
  name: "Toxic Debris",
5061
5250
  rating: 3.5,
5062
5251
  num: 295,
@@ -5077,11 +5266,7 @@ exports.Abilities = {
5077
5266
  onUpdate(pokemon) {
5078
5267
  if (!pokemon.isStarted || this.effectState.gaveUp)
5079
5268
  return;
5080
- const additionalBannedAbilities = [
5081
- // Zen Mode included here for compatability with Gen 5-6
5082
- 'noability', 'commander', 'flowergift', 'forecast', 'hungerswitch', 'illusion', 'imposter', 'neutralizinggas', 'powerofalchemy', 'receiver', 'trace', 'zenmode',
5083
- ];
5084
- const possibleTargets = pokemon.adjacentFoes().filter(target => (!target.getAbility().isPermanent && !additionalBannedAbilities.includes(target.ability)));
5269
+ const possibleTargets = pokemon.adjacentFoes().filter(target => !target.getAbility().flags['notrace'] && target.ability !== 'noability');
5085
5270
  if (!possibleTargets.length)
5086
5271
  return;
5087
5272
  const target = this.sample(possibleTargets);
@@ -5090,6 +5275,7 @@ exports.Abilities = {
5090
5275
  this.add('-ability', pokemon, ability, '[from] ability: Trace', '[of] ' + target);
5091
5276
  }
5092
5277
  },
5278
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1 },
5093
5279
  name: "Trace",
5094
5280
  rating: 2.5,
5095
5281
  num: 36,
@@ -5109,6 +5295,7 @@ exports.Abilities = {
5109
5295
  return this.chainModify([5325, 4096]);
5110
5296
  }
5111
5297
  },
5298
+ flags: {},
5112
5299
  name: "Transistor",
5113
5300
  rating: 3.5,
5114
5301
  num: 262,
@@ -5118,6 +5305,7 @@ exports.Abilities = {
5118
5305
  if (move?.flags['heal'])
5119
5306
  return priority + 3;
5120
5307
  },
5308
+ flags: {},
5121
5309
  name: "Triage",
5122
5310
  rating: 3.5,
5123
5311
  num: 205,
@@ -5138,6 +5326,7 @@ exports.Abilities = {
5138
5326
  pokemon.addVolatile('truant');
5139
5327
  },
5140
5328
  condition: {},
5329
+ flags: {},
5141
5330
  name: "Truant",
5142
5331
  rating: -1,
5143
5332
  num: 54,
@@ -5149,12 +5338,12 @@ exports.Abilities = {
5149
5338
  onModifyMove(move) {
5150
5339
  move.ignoreAbility = true;
5151
5340
  },
5341
+ flags: {},
5152
5342
  name: "Turboblaze",
5153
5343
  rating: 3,
5154
5344
  num: 163,
5155
5345
  },
5156
5346
  unaware: {
5157
- name: "Unaware",
5158
5347
  onAnyModifyBoost(boosts, pokemon) {
5159
5348
  const unawareUser = this.effectState.target;
5160
5349
  if (unawareUser === pokemon)
@@ -5171,7 +5360,8 @@ exports.Abilities = {
5171
5360
  boosts['accuracy'] = 0;
5172
5361
  }
5173
5362
  },
5174
- isBreakable: true,
5363
+ flags: { breakable: 1 },
5364
+ name: "Unaware",
5175
5365
  rating: 4,
5176
5366
  num: 109,
5177
5367
  },
@@ -5194,6 +5384,7 @@ exports.Abilities = {
5194
5384
  }
5195
5385
  },
5196
5386
  },
5387
+ flags: {},
5197
5388
  name: "Unburden",
5198
5389
  rating: 3.5,
5199
5390
  num: 84,
@@ -5215,6 +5406,7 @@ exports.Abilities = {
5215
5406
  onFoeTryEatItem() {
5216
5407
  return !this.effectState.unnerved;
5217
5408
  },
5409
+ flags: {},
5218
5410
  name: "Unnerve",
5219
5411
  rating: 1,
5220
5412
  num: 127,
@@ -5224,6 +5416,7 @@ exports.Abilities = {
5224
5416
  if (move.flags['contact'])
5225
5417
  delete move.flags['protect'];
5226
5418
  },
5419
+ flags: {},
5227
5420
  name: "Unseen Fist",
5228
5421
  rating: 2,
5229
5422
  num: 260,
@@ -5245,6 +5438,7 @@ exports.Abilities = {
5245
5438
  this.debug('Vessel of Ruin SpA drop');
5246
5439
  return this.chainModify(0.75);
5247
5440
  },
5441
+ flags: {},
5248
5442
  name: "Vessel of Ruin",
5249
5443
  rating: 4.5,
5250
5444
  num: 284,
@@ -5256,6 +5450,7 @@ exports.Abilities = {
5256
5450
  return this.chainModify([4506, 4096]);
5257
5451
  }
5258
5452
  },
5453
+ flags: {},
5259
5454
  name: "Victory Star",
5260
5455
  rating: 2,
5261
5456
  num: 162,
@@ -5281,7 +5476,7 @@ exports.Abilities = {
5281
5476
  return null;
5282
5477
  }
5283
5478
  },
5284
- isBreakable: true,
5479
+ flags: { breakable: 1 },
5285
5480
  name: "Vital Spirit",
5286
5481
  rating: 1.5,
5287
5482
  num: 72,
@@ -5295,18 +5490,15 @@ exports.Abilities = {
5295
5490
  return null;
5296
5491
  }
5297
5492
  },
5298
- isBreakable: true,
5493
+ flags: { breakable: 1 },
5299
5494
  name: "Volt Absorb",
5300
5495
  rating: 3.5,
5301
5496
  num: 10,
5302
5497
  },
5303
5498
  wanderingspirit: {
5304
5499
  onDamagingHit(damage, target, source, move) {
5305
- const additionalBannedAbilities = ['commander', 'hungerswitch', 'illusion', 'neutralizinggas', 'wonderguard'];
5306
- if (source.getAbility().isPermanent || additionalBannedAbilities.includes(source.ability) ||
5307
- target.volatiles['dynamax']) {
5500
+ if (source.getAbility().flags['failskillswap'] || target.volatiles['dynamax'])
5308
5501
  return;
5309
- }
5310
5502
  if (this.checkMoveMakesContact(move, source, target)) {
5311
5503
  const targetCanBeSet = this.runEvent('SetAbility', target, source, this.effect, source.ability);
5312
5504
  if (!targetCanBeSet)
@@ -5323,6 +5515,7 @@ exports.Abilities = {
5323
5515
  target.setAbility(sourceAbility);
5324
5516
  }
5325
5517
  },
5518
+ flags: {},
5326
5519
  name: "Wandering Spirit",
5327
5520
  rating: 2.5,
5328
5521
  num: 254,
@@ -5336,7 +5529,7 @@ exports.Abilities = {
5336
5529
  return null;
5337
5530
  }
5338
5531
  },
5339
- isBreakable: true,
5532
+ flags: { breakable: 1 },
5340
5533
  name: "Water Absorb",
5341
5534
  rating: 3.5,
5342
5535
  num: 11,
@@ -5378,7 +5571,7 @@ exports.Abilities = {
5378
5571
  }
5379
5572
  return false;
5380
5573
  },
5381
- isBreakable: true,
5574
+ flags: { breakable: 1 },
5382
5575
  name: "Water Bubble",
5383
5576
  rating: 4.5,
5384
5577
  num: 199,
@@ -5389,6 +5582,7 @@ exports.Abilities = {
5389
5582
  this.boost({ def: 2 });
5390
5583
  }
5391
5584
  },
5585
+ flags: {},
5392
5586
  name: "Water Compaction",
5393
5587
  rating: 1.5,
5394
5588
  num: 195,
@@ -5408,7 +5602,7 @@ exports.Abilities = {
5408
5602
  }
5409
5603
  return false;
5410
5604
  },
5411
- isBreakable: true,
5605
+ flags: { breakable: 1 },
5412
5606
  name: "Water Veil",
5413
5607
  rating: 2,
5414
5608
  num: 41,
@@ -5419,6 +5613,7 @@ exports.Abilities = {
5419
5613
  this.boost({ def: -1, spe: 2 }, target, target);
5420
5614
  }
5421
5615
  },
5616
+ flags: {},
5422
5617
  name: "Weak Armor",
5423
5618
  rating: 1,
5424
5619
  num: 133,
@@ -5432,7 +5627,7 @@ exports.Abilities = {
5432
5627
  return null;
5433
5628
  }
5434
5629
  },
5435
- isBreakable: true,
5630
+ flags: { breakable: 1 },
5436
5631
  name: "Well-Baked Body",
5437
5632
  rating: 3.5,
5438
5633
  num: 273,
@@ -5453,7 +5648,7 @@ exports.Abilities = {
5453
5648
  this.add("-fail", target, "unboost", "[from] ability: White Smoke", "[of] " + target);
5454
5649
  }
5455
5650
  },
5456
- isBreakable: true,
5651
+ flags: { breakable: 1 },
5457
5652
  name: "White Smoke",
5458
5653
  rating: 2,
5459
5654
  num: 73,
@@ -5470,6 +5665,7 @@ exports.Abilities = {
5470
5665
  target.switchFlag = true;
5471
5666
  this.add('-activate', target, 'ability: Wimp Out');
5472
5667
  },
5668
+ flags: {},
5473
5669
  name: "Wimp Out",
5474
5670
  rating: 1,
5475
5671
  num: 193,
@@ -5487,6 +5683,7 @@ exports.Abilities = {
5487
5683
  pokemon.addVolatile('charge');
5488
5684
  }
5489
5685
  },
5686
+ flags: {},
5490
5687
  name: "Wind Power",
5491
5688
  rating: 1,
5492
5689
  num: 277,
@@ -5511,7 +5708,7 @@ exports.Abilities = {
5511
5708
  this.boost({ atk: 1 }, pokemon, pokemon);
5512
5709
  }
5513
5710
  },
5514
- isBreakable: true,
5711
+ flags: { breakable: 1 },
5515
5712
  name: "Wind Rider",
5516
5713
  rating: 3.5,
5517
5714
  // We do not want Brambleghast to get Infiltrator in Randbats
@@ -5534,7 +5731,7 @@ exports.Abilities = {
5534
5731
  return null;
5535
5732
  }
5536
5733
  },
5537
- isBreakable: true,
5734
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, failskillswap: 1, breakable: 1 },
5538
5735
  name: "Wonder Guard",
5539
5736
  rating: 5,
5540
5737
  num: 25,
@@ -5547,7 +5744,7 @@ exports.Abilities = {
5547
5744
  return 50;
5548
5745
  }
5549
5746
  },
5550
- isBreakable: true,
5747
+ flags: { breakable: 1 },
5551
5748
  name: "Wonder Skin",
5552
5749
  rating: 2,
5553
5750
  num: 147,
@@ -5592,14 +5789,14 @@ exports.Abilities = {
5592
5789
  }
5593
5790
  },
5594
5791
  },
5595
- isPermanent: true,
5792
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1 },
5596
5793
  name: "Zen Mode",
5597
5794
  rating: 0,
5598
5795
  num: 161,
5599
5796
  },
5600
5797
  zerotohero: {
5601
5798
  onSwitchOut(pokemon) {
5602
- if (pokemon.baseSpecies.baseSpecies !== 'Palafin' || pokemon.transformed)
5799
+ if (pokemon.baseSpecies.baseSpecies !== 'Palafin')
5603
5800
  return;
5604
5801
  if (pokemon.species.forme !== 'Hero') {
5605
5802
  pokemon.formeChange('Palafin-Hero', this.effect, true);
@@ -5612,14 +5809,14 @@ exports.Abilities = {
5612
5809
  if (!this.effectState.switchingIn)
5613
5810
  return;
5614
5811
  this.effectState.switchingIn = false;
5615
- if (pokemon.baseSpecies.baseSpecies !== 'Palafin' || pokemon.transformed)
5812
+ if (pokemon.baseSpecies.baseSpecies !== 'Palafin')
5616
5813
  return;
5617
5814
  if (!this.effectState.heroMessageDisplayed && pokemon.species.forme === 'Hero') {
5618
5815
  this.add('-activate', pokemon, 'ability: Zero to Hero');
5619
5816
  this.effectState.heroMessageDisplayed = true;
5620
5817
  }
5621
5818
  },
5622
- isPermanent: true,
5819
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1, notransform: 1 },
5623
5820
  name: "Zero to Hero",
5624
5821
  rating: 5,
5625
5822
  num: 278,
@@ -5638,14 +5835,13 @@ exports.Abilities = {
5638
5835
  }
5639
5836
  },
5640
5837
  isNonstandard: "CAP",
5641
- isBreakable: true,
5838
+ flags: { breakable: 1 },
5642
5839
  name: "Mountaineer",
5643
5840
  rating: 3,
5644
5841
  num: -2,
5645
5842
  },
5646
5843
  rebound: {
5647
5844
  isNonstandard: "CAP",
5648
- name: "Rebound",
5649
5845
  onTryHitPriority: 1,
5650
5846
  onTryHit(target, source, move) {
5651
5847
  if (this.effectState.target.activeTurns)
@@ -5672,14 +5868,16 @@ exports.Abilities = {
5672
5868
  condition: {
5673
5869
  duration: 1,
5674
5870
  },
5675
- isBreakable: true,
5871
+ flags: { breakable: 1 },
5872
+ name: "Rebound",
5676
5873
  rating: 3,
5677
5874
  num: -3,
5678
5875
  },
5679
5876
  persistent: {
5680
5877
  isNonstandard: "CAP",
5681
- name: "Persistent",
5682
5878
  // implemented in the corresponding move
5879
+ flags: {},
5880
+ name: "Persistent",
5683
5881
  rating: 3,
5684
5882
  num: -4,
5685
5883
  },