@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
@@ -34,6 +34,7 @@ Ratings and how they work:
34
34
  export const Abilities = {
35
35
  noability: {
36
36
  isNonstandard: "Past",
37
+ flags: {},
37
38
  name: "No Ability",
38
39
  rating: 0.1,
39
40
  num: 0,
@@ -42,6 +43,7 @@ export const Abilities = {
42
43
  onModifyMove(move) {
43
44
  move.stab = 2;
44
45
  },
46
+ flags: {},
45
47
  name: "Adaptability",
46
48
  rating: 4,
47
49
  num: 91,
@@ -63,18 +65,20 @@ export const Abilities = {
63
65
  if (move.typeChangerBoosted === this.effect)
64
66
  return this.chainModify([4915, 4096]);
65
67
  },
68
+ flags: {},
66
69
  name: "Aerilate",
67
70
  rating: 4,
68
71
  num: 184,
69
72
  },
70
73
  aftermath: {
71
- name: "Aftermath",
72
74
  onDamagingHitOrder: 1,
73
75
  onDamagingHit(damage, target, source, move) {
74
76
  if (!target.hp && this.checkMoveMakesContact(move, source, target, true)) {
75
77
  this.damage(source.baseMaxhp / 4, source, target);
76
78
  }
77
79
  },
80
+ flags: {},
81
+ name: "Aftermath",
78
82
  rating: 2,
79
83
  num: 106,
80
84
  },
@@ -94,6 +98,7 @@ export const Abilities = {
94
98
  this.eachEvent('WeatherChange', this.effect);
95
99
  },
96
100
  suppressWeather: true,
101
+ flags: {},
97
102
  name: "Air Lock",
98
103
  rating: 1.5,
99
104
  num: 76,
@@ -115,6 +120,7 @@ export const Abilities = {
115
120
  return this.chainModify([5325, 4096]);
116
121
  }
117
122
  },
123
+ flags: {},
118
124
  name: "Analytic",
119
125
  rating: 2.5,
120
126
  num: 148,
@@ -127,6 +133,7 @@ export const Abilities = {
127
133
  this.boost({ atk: 12 }, target, target);
128
134
  }
129
135
  },
136
+ flags: {},
130
137
  name: "Anger Point",
131
138
  rating: 1,
132
139
  num: 83,
@@ -163,6 +170,7 @@ export const Abilities = {
163
170
  this.boost({ atk: 1, spa: 1, spe: 1, def: -1, spd: -1 }, target, target);
164
171
  }
165
172
  },
173
+ flags: {},
166
174
  name: "Anger Shell",
167
175
  rating: 3,
168
176
  num: 271,
@@ -183,6 +191,7 @@ export const Abilities = {
183
191
  }
184
192
  }
185
193
  },
194
+ flags: {},
186
195
  name: "Anticipation",
187
196
  rating: 0.5,
188
197
  num: 107,
@@ -204,6 +213,7 @@ export const Abilities = {
204
213
  pokemon.maybeTrapped = true;
205
214
  }
206
215
  },
216
+ flags: {},
207
217
  name: "Arena Trap",
208
218
  rating: 5,
209
219
  num: 71,
@@ -221,7 +231,7 @@ export const Abilities = {
221
231
  return false;
222
232
  }
223
233
  },
224
- isBreakable: true,
234
+ flags: { breakable: 1 },
225
235
  name: "Armor Tail",
226
236
  rating: 2.5,
227
237
  num: 296,
@@ -236,7 +246,7 @@ export const Abilities = {
236
246
  return null;
237
247
  }
238
248
  },
239
- isBreakable: true,
249
+ flags: { breakable: 1 },
240
250
  name: "Aroma Veil",
241
251
  rating: 2,
242
252
  num: 165,
@@ -258,7 +268,7 @@ export const Abilities = {
258
268
  this.boost({ atk: length }, source, source, this.dex.abilities.get('chillingneigh'));
259
269
  }
260
270
  },
261
- isPermanent: true,
271
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1 },
262
272
  name: "As One (Glastrier)",
263
273
  rating: 3.5,
264
274
  num: 266,
@@ -280,7 +290,7 @@ export const Abilities = {
280
290
  this.boost({ spa: length }, source, source, this.dex.abilities.get('grimneigh'));
281
291
  }
282
292
  },
283
- isPermanent: true,
293
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1 },
284
294
  name: "As One (Spectrier)",
285
295
  rating: 3.5,
286
296
  num: 267,
@@ -296,7 +306,7 @@ export const Abilities = {
296
306
  return;
297
307
  move.hasAuraBreak = true;
298
308
  },
299
- isBreakable: true,
309
+ flags: { breakable: 1 },
300
310
  name: "Aura Break",
301
311
  rating: 1,
302
312
  num: 188,
@@ -313,11 +323,13 @@ export const Abilities = {
313
323
  }
314
324
  }
315
325
  },
326
+ flags: {},
316
327
  name: "Bad Dreams",
317
328
  rating: 1.5,
318
329
  num: 123,
319
330
  },
320
331
  ballfetch: {
332
+ flags: {},
321
333
  name: "Ball Fetch",
322
334
  rating: 0,
323
335
  num: 237,
@@ -330,13 +342,14 @@ export const Abilities = {
330
342
  return this.chainModify([5325, 4096]);
331
343
  }
332
344
  },
345
+ flags: {},
333
346
  name: "Battery",
334
347
  rating: 0,
335
348
  num: 217,
336
349
  },
337
350
  battlearmor: {
338
351
  onCriticalHit: false,
339
- isBreakable: true,
352
+ flags: { breakable: 1 },
340
353
  name: "Battle Armor",
341
354
  rating: 1,
342
355
  num: 4,
@@ -353,7 +366,7 @@ export const Abilities = {
353
366
  source.abilityState.battleBondTriggered = true;
354
367
  }
355
368
  },
356
- isPermanent: true,
369
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1 },
357
370
  name: "Battle Bond",
358
371
  rating: 3.5,
359
372
  num: 210,
@@ -375,6 +388,7 @@ export const Abilities = {
375
388
  this.debug('Beads of Ruin SpD drop');
376
389
  return this.chainModify(0.75);
377
390
  },
391
+ flags: {},
378
392
  name: "Beads of Ruin",
379
393
  rating: 4.5,
380
394
  num: 284,
@@ -386,6 +400,7 @@ export const Abilities = {
386
400
  this.boost({ [bestStat]: length }, source);
387
401
  }
388
402
  },
403
+ flags: {},
389
404
  name: "Beast Boost",
390
405
  rating: 3.5,
391
406
  num: 224,
@@ -422,6 +437,7 @@ export const Abilities = {
422
437
  this.boost({ spa: 1 }, target, target);
423
438
  }
424
439
  },
440
+ flags: {},
425
441
  name: "Berserk",
426
442
  rating: 2,
427
443
  num: 201,
@@ -437,7 +453,7 @@ export const Abilities = {
437
453
  }
438
454
  }
439
455
  },
440
- isBreakable: true,
456
+ flags: { breakable: 1 },
441
457
  name: "Big Pecks",
442
458
  rating: 0.5,
443
459
  num: 145,
@@ -457,6 +473,7 @@ export const Abilities = {
457
473
  return this.chainModify(1.5);
458
474
  }
459
475
  },
476
+ flags: {},
460
477
  name: "Blaze",
461
478
  rating: 2,
462
479
  num: 66,
@@ -468,7 +485,7 @@ export const Abilities = {
468
485
  return null;
469
486
  }
470
487
  },
471
- isBreakable: true,
488
+ flags: { breakable: 1 },
472
489
  name: "Bulletproof",
473
490
  rating: 3,
474
491
  num: 171,
@@ -477,6 +494,7 @@ export const Abilities = {
477
494
  onEatItem(item, pokemon) {
478
495
  this.heal(pokemon.baseMaxhp / 3);
479
496
  },
497
+ flags: {},
480
498
  name: "Cheek Pouch",
481
499
  rating: 2,
482
500
  num: 167,
@@ -487,6 +505,7 @@ export const Abilities = {
487
505
  this.boost({ atk: length }, source);
488
506
  }
489
507
  },
508
+ flags: {},
490
509
  name: "Chilling Neigh",
491
510
  rating: 3,
492
511
  num: 264,
@@ -497,6 +516,7 @@ export const Abilities = {
497
516
  return this.chainModify(2);
498
517
  }
499
518
  },
519
+ flags: {},
500
520
  name: "Chlorophyll",
501
521
  rating: 3,
502
522
  num: 34,
@@ -517,7 +537,7 @@ export const Abilities = {
517
537
  this.add("-fail", target, "unboost", "[from] ability: Clear Body", "[of] " + target);
518
538
  }
519
539
  },
520
- isBreakable: true,
540
+ flags: { breakable: 1 },
521
541
  name: "Clear Body",
522
542
  rating: 2,
523
543
  num: 29,
@@ -538,6 +558,7 @@ export const Abilities = {
538
558
  this.eachEvent('WeatherChange', this.effect);
539
559
  },
540
560
  suppressWeather: true,
561
+ flags: {},
541
562
  name: "Cloud Nine",
542
563
  rating: 1.5,
543
564
  num: 13,
@@ -561,6 +582,7 @@ export const Abilities = {
561
582
  }
562
583
  }
563
584
  },
585
+ flags: {},
564
586
  name: "Color Change",
565
587
  rating: 0,
566
588
  num: 16,
@@ -576,7 +598,7 @@ export const Abilities = {
576
598
  return false;
577
599
  },
578
600
  // Permanent sleep "status" implemented in the relevant sleep-checking effects
579
- isPermanent: true,
601
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1 },
580
602
  name: "Comatose",
581
603
  rating: 4,
582
604
  num: 213,
@@ -586,8 +608,7 @@ export const Abilities = {
586
608
  if (this.gameType !== 'doubles')
587
609
  return;
588
610
  const ally = pokemon.allies()[0];
589
- if (!ally || pokemon.transformed ||
590
- pokemon.baseSpecies.baseSpecies !== 'Tatsugiri' || ally.baseSpecies.baseSpecies !== 'Dondozo') {
611
+ if (!ally || pokemon.baseSpecies.baseSpecies !== 'Tatsugiri' || ally.baseSpecies.baseSpecies !== 'Dondozo') {
591
612
  // Handle any edge cases
592
613
  if (pokemon.getVolatile('commanding'))
593
614
  pokemon.removeVolatile('commanding');
@@ -611,6 +632,7 @@ export const Abilities = {
611
632
  pokemon.removeVolatile('commanding');
612
633
  }
613
634
  },
635
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1 },
614
636
  name: "Commander",
615
637
  rating: 0,
616
638
  num: 279,
@@ -634,6 +656,7 @@ export const Abilities = {
634
656
  this.boost({ spa: 2 }, target, target, null, false, true);
635
657
  }
636
658
  },
659
+ flags: {},
637
660
  name: "Competitive",
638
661
  rating: 2.5,
639
662
  num: 172,
@@ -646,6 +669,7 @@ export const Abilities = {
646
669
  this.debug('compoundeyes - enhancing accuracy');
647
670
  return this.chainModify([5325, 4096]);
648
671
  },
672
+ flags: {},
649
673
  name: "Compound Eyes",
650
674
  rating: 3,
651
675
  num: 14,
@@ -659,13 +683,14 @@ export const Abilities = {
659
683
  boost[i] *= -1;
660
684
  }
661
685
  },
662
- isBreakable: true,
686
+ flags: { breakable: 1 },
663
687
  name: "Contrary",
664
688
  rating: 4.5,
665
689
  num: 126,
666
690
  },
667
691
  corrosion: {
668
692
  // Implemented in sim/pokemon.js:Pokemon#setStatus
693
+ flags: {},
669
694
  name: "Corrosion",
670
695
  rating: 2.5,
671
696
  num: 212,
@@ -692,6 +717,7 @@ export const Abilities = {
692
717
  }
693
718
  this.add('-copyboost', pokemon, ally, '[from] ability: Costar');
694
719
  },
720
+ flags: {},
695
721
  name: "Costar",
696
722
  rating: 0,
697
723
  num: 294,
@@ -709,6 +735,7 @@ export const Abilities = {
709
735
  this.boost({ spe: -1 }, pokemon, target, null, true);
710
736
  }
711
737
  },
738
+ flags: {},
712
739
  name: "Cotton Down",
713
740
  rating: 2,
714
741
  num: 238,
@@ -743,6 +770,7 @@ export const Abilities = {
743
770
  }
744
771
  },
745
772
  },
773
+ flags: {},
746
774
  name: "Cud Chew",
747
775
  rating: 2,
748
776
  num: 291,
@@ -754,6 +782,7 @@ export const Abilities = {
754
782
  this.add('-clearboost', ally, '[from] ability: Curious Medicine', '[of] ' + pokemon);
755
783
  }
756
784
  },
785
+ flags: {},
757
786
  name: "Curious Medicine",
758
787
  rating: 0,
759
788
  num: 261,
@@ -768,6 +797,7 @@ export const Abilities = {
768
797
  }
769
798
  }
770
799
  },
800
+ flags: {},
771
801
  name: "Cursed Body",
772
802
  rating: 2,
773
803
  num: 130,
@@ -780,6 +810,7 @@ export const Abilities = {
780
810
  }
781
811
  }
782
812
  },
813
+ flags: {},
783
814
  name: "Cute Charm",
784
815
  rating: 0.5,
785
816
  num: 56,
@@ -797,12 +828,13 @@ export const Abilities = {
797
828
  return false;
798
829
  }
799
830
  },
800
- isBreakable: true,
831
+ flags: { breakable: 1 },
801
832
  name: "Damp",
802
833
  rating: 0.5,
803
834
  num: 6,
804
835
  },
805
836
  dancer: {
837
+ flags: {},
806
838
  name: "Dancer",
807
839
  // implemented in runMove in scripts.js
808
840
  rating: 1.5,
@@ -824,6 +856,7 @@ export const Abilities = {
824
856
  return;
825
857
  return this.chainModify([move.hasAuraBreak ? 3072 : 5448, 4096]);
826
858
  },
859
+ flags: {},
827
860
  name: "Dark Aura",
828
861
  rating: 3,
829
862
  num: 186,
@@ -835,6 +868,7 @@ export const Abilities = {
835
868
  pokemon.shieldBoost = true;
836
869
  this.boost({ def: 1 }, pokemon);
837
870
  },
871
+ flags: {},
838
872
  name: "Dauntless Shield",
839
873
  rating: 3.5,
840
874
  num: 235,
@@ -852,7 +886,7 @@ export const Abilities = {
852
886
  return false;
853
887
  }
854
888
  },
855
- isBreakable: true,
889
+ flags: { breakable: 1 },
856
890
  name: "Dazzling",
857
891
  rating: 2.5,
858
892
  num: 219,
@@ -870,6 +904,7 @@ export const Abilities = {
870
904
  return this.chainModify(0.5);
871
905
  }
872
906
  },
907
+ flags: {},
873
908
  name: "Defeatist",
874
909
  rating: -1,
875
910
  num: 129,
@@ -893,6 +928,7 @@ export const Abilities = {
893
928
  this.boost({ atk: 2 }, target, target, null, false, true);
894
929
  }
895
930
  },
931
+ flags: {},
896
932
  name: "Defiant",
897
933
  rating: 3,
898
934
  num: 128,
@@ -919,6 +955,7 @@ export const Abilities = {
919
955
  }
920
956
  this.field.clearWeather();
921
957
  },
958
+ flags: {},
922
959
  name: "Delta Stream",
923
960
  rating: 4,
924
961
  num: 191,
@@ -945,6 +982,7 @@ export const Abilities = {
945
982
  }
946
983
  this.field.clearWeather();
947
984
  },
985
+ flags: {},
948
986
  name: "Desolate Land",
949
987
  rating: 4.5,
950
988
  num: 190,
@@ -952,8 +990,7 @@ export const Abilities = {
952
990
  disguise: {
953
991
  onDamagePriority: 1,
954
992
  onDamage(damage, target, source, effect) {
955
- if (effect && effect.effectType === 'Move' &&
956
- ['mimikyu', 'mimikyutotem'].includes(target.species.id) && !target.transformed) {
993
+ if (effect?.effectType === 'Move' && ['mimikyu', 'mimikyutotem'].includes(target.species.id)) {
957
994
  this.add('-activate', target, 'ability: Disguise');
958
995
  this.effectState.busted = true;
959
996
  return 0;
@@ -962,7 +999,7 @@ export const Abilities = {
962
999
  onCriticalHit(target, source, move) {
963
1000
  if (!target)
964
1001
  return;
965
- if (!['mimikyu', 'mimikyutotem'].includes(target.species.id) || target.transformed) {
1002
+ if (!['mimikyu', 'mimikyutotem'].includes(target.species.id)) {
966
1003
  return;
967
1004
  }
968
1005
  const hitSub = target.volatiles['substitute'] && !move.flags['bypasssub'] && !(move.infiltrates && this.gen >= 6);
@@ -975,7 +1012,7 @@ export const Abilities = {
975
1012
  onEffectiveness(typeMod, target, type, move) {
976
1013
  if (!target || move.category === 'Status')
977
1014
  return;
978
- if (!['mimikyu', 'mimikyutotem'].includes(target.species.id) || target.transformed) {
1015
+ if (!['mimikyu', 'mimikyutotem'].includes(target.species.id)) {
979
1016
  return;
980
1017
  }
981
1018
  const hitSub = target.volatiles['substitute'] && !move.flags['bypasssub'] && !(move.infiltrates && this.gen >= 6);
@@ -992,8 +1029,10 @@ export const Abilities = {
992
1029
  this.damage(pokemon.baseMaxhp / 8, pokemon, pokemon, this.dex.species.get(speciesid));
993
1030
  }
994
1031
  },
995
- isBreakable: true,
996
- isPermanent: true,
1032
+ flags: {
1033
+ failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1,
1034
+ breakable: 1, notransform: 1,
1035
+ },
997
1036
  name: "Disguise",
998
1037
  rating: 3.5,
999
1038
  num: 209,
@@ -1013,6 +1052,7 @@ export const Abilities = {
1013
1052
  this.boost({ atk: 1 });
1014
1053
  }
1015
1054
  },
1055
+ flags: {},
1016
1056
  name: "Download",
1017
1057
  rating: 3.5,
1018
1058
  num: 88,
@@ -1032,6 +1072,7 @@ export const Abilities = {
1032
1072
  return this.chainModify(1.5);
1033
1073
  }
1034
1074
  },
1075
+ flags: {},
1035
1076
  name: "Dragon's Maw",
1036
1077
  rating: 3.5,
1037
1078
  num: 263,
@@ -1046,6 +1087,7 @@ export const Abilities = {
1046
1087
  }
1047
1088
  this.field.setWeather('raindance');
1048
1089
  },
1090
+ flags: {},
1049
1091
  name: "Drizzle",
1050
1092
  rating: 4,
1051
1093
  num: 2,
@@ -1060,6 +1102,7 @@ export const Abilities = {
1060
1102
  }
1061
1103
  this.field.setWeather('sunnyday');
1062
1104
  },
1105
+ flags: {},
1063
1106
  name: "Drought",
1064
1107
  rating: 4,
1065
1108
  num: 70,
@@ -1089,12 +1132,13 @@ export const Abilities = {
1089
1132
  this.damage(target.baseMaxhp / 8, target, target);
1090
1133
  }
1091
1134
  },
1092
- isBreakable: true,
1135
+ flags: { breakable: 1 },
1093
1136
  name: "Dry Skin",
1094
1137
  rating: 3,
1095
1138
  num: 87,
1096
1139
  },
1097
1140
  earlybird: {
1141
+ flags: {},
1098
1142
  name: "Early Bird",
1099
1143
  // Implemented in statuses.js
1100
1144
  rating: 1.5,
@@ -1109,7 +1153,7 @@ export const Abilities = {
1109
1153
  return null;
1110
1154
  }
1111
1155
  },
1112
- isBreakable: true,
1156
+ flags: { breakable: 1 },
1113
1157
  name: "Earth Eater",
1114
1158
  rating: 3.5,
1115
1159
  num: 297,
@@ -1129,6 +1173,7 @@ export const Abilities = {
1129
1173
  }
1130
1174
  }
1131
1175
  },
1176
+ flags: {},
1132
1177
  name: "Effect Spore",
1133
1178
  rating: 2,
1134
1179
  num: 27,
@@ -1137,6 +1182,7 @@ export const Abilities = {
1137
1182
  onStart(source) {
1138
1183
  this.field.setTerrain('electricterrain');
1139
1184
  },
1185
+ flags: {},
1140
1186
  name: "Electric Surge",
1141
1187
  rating: 4,
1142
1188
  num: 226,
@@ -1146,13 +1192,14 @@ export const Abilities = {
1146
1192
  onDamagingHit(damage, target, source, move) {
1147
1193
  target.addVolatile('charge');
1148
1194
  },
1195
+ flags: {},
1149
1196
  name: "Electromorphosis",
1150
1197
  rating: 3,
1151
1198
  num: 280,
1152
1199
  },
1153
1200
  embodyaspectcornerstone: {
1154
1201
  onStart(pokemon) {
1155
- if (pokemon.baseSpecies.name === 'Ogerpon-Cornerstone-Tera' && !pokemon.transformed && !this.effectState.embodied) {
1202
+ if (pokemon.baseSpecies.name === 'Ogerpon-Cornerstone-Tera' && !this.effectState.embodied) {
1156
1203
  this.effectState.embodied = true;
1157
1204
  this.boost({ def: 1 }, pokemon);
1158
1205
  }
@@ -1160,13 +1207,14 @@ export const Abilities = {
1160
1207
  onSwitchIn() {
1161
1208
  delete this.effectState.embodied;
1162
1209
  },
1210
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, notransform: 1 },
1163
1211
  name: "Embody Aspect (Cornerstone)",
1164
1212
  rating: 3.5,
1165
1213
  num: 304,
1166
1214
  },
1167
1215
  embodyaspecthearthflame: {
1168
1216
  onStart(pokemon) {
1169
- if (pokemon.baseSpecies.name === 'Ogerpon-Hearthflame-Tera' && !pokemon.transformed && !this.effectState.embodied) {
1217
+ if (pokemon.baseSpecies.name === 'Ogerpon-Hearthflame-Tera' && !this.effectState.embodied) {
1170
1218
  this.effectState.embodied = true;
1171
1219
  this.boost({ atk: 1 }, pokemon);
1172
1220
  }
@@ -1174,13 +1222,14 @@ export const Abilities = {
1174
1222
  onSwitchIn() {
1175
1223
  delete this.effectState.embodied;
1176
1224
  },
1225
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, notransform: 1 },
1177
1226
  name: "Embody Aspect (Hearthflame)",
1178
1227
  rating: 3.5,
1179
1228
  num: 303,
1180
1229
  },
1181
1230
  embodyaspectteal: {
1182
1231
  onStart(pokemon) {
1183
- if (pokemon.baseSpecies.name === 'Ogerpon-Teal-Tera' && !pokemon.transformed && !this.effectState.embodied) {
1232
+ if (pokemon.baseSpecies.name === 'Ogerpon-Teal-Tera' && !this.effectState.embodied) {
1184
1233
  this.effectState.embodied = true;
1185
1234
  this.boost({ spe: 1 }, pokemon);
1186
1235
  }
@@ -1188,13 +1237,14 @@ export const Abilities = {
1188
1237
  onSwitchIn() {
1189
1238
  delete this.effectState.embodied;
1190
1239
  },
1240
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, notransform: 1 },
1191
1241
  name: "Embody Aspect (Teal)",
1192
1242
  rating: 3.5,
1193
1243
  num: 301,
1194
1244
  },
1195
1245
  embodyaspectwellspring: {
1196
1246
  onStart(pokemon) {
1197
- if (pokemon.baseSpecies.name === 'Ogerpon-Wellspring-Tera' && !pokemon.transformed && !this.effectState.embodied) {
1247
+ if (pokemon.baseSpecies.name === 'Ogerpon-Wellspring-Tera' && !this.effectState.embodied) {
1198
1248
  this.effectState.embodied = true;
1199
1249
  this.boost({ spd: 1 }, pokemon);
1200
1250
  }
@@ -1202,6 +1252,7 @@ export const Abilities = {
1202
1252
  onSwitchIn() {
1203
1253
  delete this.effectState.embodied;
1204
1254
  },
1255
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, notransform: 1 },
1205
1256
  name: "Embody Aspect (Wellspring)",
1206
1257
  rating: 3.5,
1207
1258
  num: 302,
@@ -1218,6 +1269,7 @@ export const Abilities = {
1218
1269
  target.switchFlag = true;
1219
1270
  this.add('-activate', target, 'ability: Emergency Exit');
1220
1271
  },
1272
+ flags: {},
1221
1273
  name: "Emergency Exit",
1222
1274
  rating: 1,
1223
1275
  num: 194,
@@ -1238,6 +1290,7 @@ export const Abilities = {
1238
1290
  return;
1239
1291
  return this.chainModify([move.hasAuraBreak ? 3072 : 5448, 4096]);
1240
1292
  },
1293
+ flags: {},
1241
1294
  name: "Fairy Aura",
1242
1295
  rating: 3,
1243
1296
  num: 187,
@@ -1249,7 +1302,7 @@ export const Abilities = {
1249
1302
  return this.chainModify(0.75);
1250
1303
  }
1251
1304
  },
1252
- isBreakable: true,
1305
+ flags: { breakable: 1 },
1253
1306
  name: "Filter",
1254
1307
  rating: 3,
1255
1308
  num: 111,
@@ -1262,6 +1315,7 @@ export const Abilities = {
1262
1315
  }
1263
1316
  }
1264
1317
  },
1318
+ flags: {},
1265
1319
  name: "Flame Body",
1266
1320
  rating: 2,
1267
1321
  num: 49,
@@ -1273,6 +1327,7 @@ export const Abilities = {
1273
1327
  return this.chainModify(1.5);
1274
1328
  }
1275
1329
  },
1330
+ flags: {},
1276
1331
  name: "Flare Boost",
1277
1332
  rating: 2,
1278
1333
  num: 138,
@@ -1313,7 +1368,7 @@ export const Abilities = {
1313
1368
  this.add('-end', target, 'ability: Flash Fire', '[silent]');
1314
1369
  },
1315
1370
  },
1316
- isBreakable: true,
1371
+ flags: { breakable: 1 },
1317
1372
  name: "Flash Fire",
1318
1373
  rating: 3.5,
1319
1374
  num: 18,
@@ -1354,7 +1409,7 @@ export const Abilities = {
1354
1409
  return this.chainModify(1.5);
1355
1410
  }
1356
1411
  },
1357
- isBreakable: true,
1412
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, breakable: 1 },
1358
1413
  name: "Flower Gift",
1359
1414
  rating: 1,
1360
1415
  num: 122,
@@ -1394,7 +1449,7 @@ export const Abilities = {
1394
1449
  return null;
1395
1450
  }
1396
1451
  },
1397
- isBreakable: true,
1452
+ flags: { breakable: 1 },
1398
1453
  name: "Flower Veil",
1399
1454
  rating: 0,
1400
1455
  num: 166,
@@ -1408,7 +1463,7 @@ export const Abilities = {
1408
1463
  mod /= 2;
1409
1464
  return this.chainModify(mod);
1410
1465
  },
1411
- isBreakable: true,
1466
+ flags: { breakable: 1 },
1412
1467
  name: "Fluffy",
1413
1468
  rating: 3.5,
1414
1469
  num: 218,
@@ -1446,6 +1501,7 @@ export const Abilities = {
1446
1501
  pokemon.formeChange(forme, this.effect, false, '[msg]');
1447
1502
  }
1448
1503
  },
1504
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1 },
1449
1505
  name: "Forecast",
1450
1506
  rating: 2,
1451
1507
  num: 59,
@@ -1480,19 +1536,20 @@ export const Abilities = {
1480
1536
  const [warnMoveName, warnTarget] = this.sample(warnMoves);
1481
1537
  this.add('-activate', pokemon, 'ability: Forewarn', warnMoveName, '[of] ' + warnTarget);
1482
1538
  },
1539
+ flags: {},
1483
1540
  name: "Forewarn",
1484
1541
  rating: 0.5,
1485
1542
  num: 108,
1486
1543
  },
1487
1544
  friendguard: {
1488
- name: "Friend Guard",
1489
1545
  onAnyModifyDamage(damage, source, target, move) {
1490
1546
  if (target !== this.effectState.target && target.isAlly(this.effectState.target)) {
1491
1547
  this.debug('Friend Guard weaken');
1492
1548
  return this.chainModify(0.75);
1493
1549
  }
1494
1550
  },
1495
- isBreakable: true,
1551
+ flags: { breakable: 1 },
1552
+ name: "Friend Guard",
1496
1553
  rating: 0,
1497
1554
  num: 132,
1498
1555
  },
@@ -1504,6 +1561,7 @@ export const Abilities = {
1504
1561
  }
1505
1562
  }
1506
1563
  },
1564
+ flags: {},
1507
1565
  name: "Frisk",
1508
1566
  rating: 1.5,
1509
1567
  num: 119,
@@ -1524,6 +1582,7 @@ export const Abilities = {
1524
1582
  this.add("-fail", target, "unboost", "[from] ability: Full Metal Body", "[of] " + target);
1525
1583
  }
1526
1584
  },
1585
+ flags: {},
1527
1586
  name: "Full Metal Body",
1528
1587
  rating: 2,
1529
1588
  num: 230,
@@ -1533,7 +1592,7 @@ export const Abilities = {
1533
1592
  onModifyDef(def) {
1534
1593
  return this.chainModify(2);
1535
1594
  },
1536
- isBreakable: true,
1595
+ flags: { breakable: 1 },
1537
1596
  name: "Fur Coat",
1538
1597
  rating: 4,
1539
1598
  num: 169,
@@ -1543,6 +1602,7 @@ export const Abilities = {
1543
1602
  if (move?.type === 'Flying' && pokemon.hp === pokemon.maxhp)
1544
1603
  return priority + 1;
1545
1604
  },
1605
+ flags: {},
1546
1606
  name: "Gale Wings",
1547
1607
  rating: 1.5,
1548
1608
  num: 177,
@@ -1564,20 +1624,22 @@ export const Abilities = {
1564
1624
  if (move.typeChangerBoosted === this.effect)
1565
1625
  return this.chainModify([4915, 4096]);
1566
1626
  },
1627
+ flags: {},
1567
1628
  name: "Galvanize",
1568
1629
  rating: 4,
1569
1630
  num: 206,
1570
1631
  },
1571
1632
  gluttony: {
1572
- name: "Gluttony",
1573
- rating: 1.5,
1574
- num: 82,
1575
1633
  onStart(pokemon) {
1576
1634
  pokemon.abilityState.gluttony = true;
1577
1635
  },
1578
1636
  onDamage(item, pokemon) {
1579
1637
  pokemon.abilityState.gluttony = true;
1580
1638
  },
1639
+ flags: {},
1640
+ name: "Gluttony",
1641
+ rating: 1.5,
1642
+ num: 82,
1581
1643
  },
1582
1644
  goodasgold: {
1583
1645
  onTryHit(target, source, move) {
@@ -1586,7 +1648,7 @@ export const Abilities = {
1586
1648
  return null;
1587
1649
  }
1588
1650
  },
1589
- isBreakable: true,
1651
+ flags: { breakable: 1 },
1590
1652
  name: "Good as Gold",
1591
1653
  rating: 5,
1592
1654
  num: 283,
@@ -1598,6 +1660,7 @@ export const Abilities = {
1598
1660
  this.boost({ spe: -1 }, source, target, null, true);
1599
1661
  }
1600
1662
  },
1663
+ flags: {},
1601
1664
  name: "Gooey",
1602
1665
  rating: 2,
1603
1666
  num: 183,
@@ -1645,6 +1708,7 @@ export const Abilities = {
1645
1708
  onEnd(pokemon) {
1646
1709
  pokemon.abilityState.choiceLock = "";
1647
1710
  },
1711
+ flags: {},
1648
1712
  name: "Gorilla Tactics",
1649
1713
  rating: 4.5,
1650
1714
  num: 255,
@@ -1655,7 +1719,7 @@ export const Abilities = {
1655
1719
  if (this.field.isTerrain('grassyterrain'))
1656
1720
  return this.chainModify(1.5);
1657
1721
  },
1658
- isBreakable: true,
1722
+ flags: { breakable: 1 },
1659
1723
  name: "Grass Pelt",
1660
1724
  rating: 0.5,
1661
1725
  num: 179,
@@ -1664,6 +1728,7 @@ export const Abilities = {
1664
1728
  onStart(source) {
1665
1729
  this.field.setTerrain('grassyterrain');
1666
1730
  },
1731
+ flags: {},
1667
1732
  name: "Grassy Surge",
1668
1733
  rating: 4,
1669
1734
  num: 229,
@@ -1674,6 +1739,7 @@ export const Abilities = {
1674
1739
  this.boost({ spa: length }, source);
1675
1740
  }
1676
1741
  },
1742
+ flags: {},
1677
1743
  name: "Grim Neigh",
1678
1744
  rating: 3,
1679
1745
  num: 265,
@@ -1690,14 +1756,14 @@ export const Abilities = {
1690
1756
  this.boost({ atk: 1 }, target, target, null, false, true);
1691
1757
  }
1692
1758
  },
1693
- isBreakable: true,
1759
+ flags: { breakable: 1 },
1694
1760
  name: "Guard Dog",
1695
1761
  rating: 2,
1696
1762
  num: 275,
1697
1763
  },
1698
1764
  gulpmissile: {
1699
1765
  onDamagingHit(damage, target, source, move) {
1700
- if (!source.hp || !source.isActive || target.transformed || target.isSemiInvulnerable())
1766
+ if (!source.hp || !source.isActive || target.isSemiInvulnerable())
1701
1767
  return;
1702
1768
  if (['cramorantgulping', 'cramorantgorging'].includes(target.species.id)) {
1703
1769
  this.damage(source.baseMaxhp / 4, source, target);
@@ -1712,13 +1778,12 @@ export const Abilities = {
1712
1778
  },
1713
1779
  // The Dive part of this mechanic is implemented in Dive's `onTryMove` in moves.ts
1714
1780
  onSourceTryPrimaryHit(target, source, effect) {
1715
- if (effect && effect.id === 'surf' && source.hasAbility('gulpmissile') &&
1716
- source.species.name === 'Cramorant' && !source.transformed) {
1781
+ if (effect?.id === 'surf' && source.hasAbility('gulpmissile') && source.species.name === 'Cramorant') {
1717
1782
  const forme = source.hp <= source.maxhp / 2 ? 'cramorantgorging' : 'cramorantgulping';
1718
1783
  source.formeChange(forme, effect);
1719
1784
  }
1720
1785
  },
1721
- isPermanent: true,
1786
+ flags: { cantsuppress: 1, notransform: 1 },
1722
1787
  name: "Gulp Missile",
1723
1788
  rating: 2.5,
1724
1789
  num: 241,
@@ -1730,6 +1795,7 @@ export const Abilities = {
1730
1795
  return this.chainModify(1.5);
1731
1796
  }
1732
1797
  },
1798
+ flags: {},
1733
1799
  name: "Guts",
1734
1800
  rating: 3.5,
1735
1801
  num: 62,
@@ -1747,12 +1813,12 @@ export const Abilities = {
1747
1813
  return this.chainModify([5461, 4096]);
1748
1814
  }
1749
1815
  },
1816
+ flags: {},
1750
1817
  name: "Hadron Engine",
1751
1818
  rating: 4.5,
1752
1819
  num: 289,
1753
1820
  },
1754
1821
  harvest: {
1755
- name: "Harvest",
1756
1822
  onResidualOrder: 28,
1757
1823
  onResidualSubOrder: 2,
1758
1824
  onResidual(pokemon) {
@@ -1764,11 +1830,12 @@ export const Abilities = {
1764
1830
  }
1765
1831
  }
1766
1832
  },
1833
+ flags: {},
1834
+ name: "Harvest",
1767
1835
  rating: 2.5,
1768
1836
  num: 139,
1769
1837
  },
1770
1838
  healer: {
1771
- name: "Healer",
1772
1839
  onResidualOrder: 5,
1773
1840
  onResidualSubOrder: 3,
1774
1841
  onResidual(pokemon) {
@@ -1779,6 +1846,8 @@ export const Abilities = {
1779
1846
  }
1780
1847
  }
1781
1848
  },
1849
+ flags: {},
1850
+ name: "Healer",
1782
1851
  rating: 0,
1783
1852
  num: 131,
1784
1853
  },
@@ -1802,7 +1871,7 @@ export const Abilities = {
1802
1871
  return damage / 2;
1803
1872
  }
1804
1873
  },
1805
- isBreakable: true,
1874
+ flags: { breakable: 1 },
1806
1875
  name: "Heatproof",
1807
1876
  rating: 2,
1808
1877
  num: 85,
@@ -1812,12 +1881,13 @@ export const Abilities = {
1812
1881
  onModifyWeight(weighthg) {
1813
1882
  return weighthg * 2;
1814
1883
  },
1815
- isBreakable: true,
1884
+ flags: { breakable: 1 },
1816
1885
  name: "Heavy Metal",
1817
1886
  rating: 0,
1818
1887
  num: 134,
1819
1888
  },
1820
1889
  honeygather: {
1890
+ flags: {},
1821
1891
  name: "Honey Gather",
1822
1892
  rating: 0,
1823
1893
  num: 118,
@@ -1828,6 +1898,7 @@ export const Abilities = {
1828
1898
  this.heal(ally.baseMaxhp / 4, ally, pokemon);
1829
1899
  }
1830
1900
  },
1901
+ flags: {},
1831
1902
  name: "Hospitality",
1832
1903
  rating: 0,
1833
1904
  num: 299,
@@ -1837,6 +1908,7 @@ export const Abilities = {
1837
1908
  onModifyAtk(atk) {
1838
1909
  return this.chainModify(2);
1839
1910
  },
1911
+ flags: {},
1840
1912
  name: "Huge Power",
1841
1913
  rating: 5,
1842
1914
  num: 37,
@@ -1844,11 +1916,12 @@ export const Abilities = {
1844
1916
  hungerswitch: {
1845
1917
  onResidualOrder: 29,
1846
1918
  onResidual(pokemon) {
1847
- if (pokemon.species.baseSpecies !== 'Morpeko' || pokemon.transformed || pokemon.terastallized)
1919
+ if (pokemon.species.baseSpecies !== 'Morpeko' || pokemon.terastallized)
1848
1920
  return;
1849
1921
  const targetForme = pokemon.species.name === 'Morpeko' ? 'Morpeko-Hangry' : 'Morpeko';
1850
1922
  pokemon.formeChange(targetForme);
1851
1923
  },
1924
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, notransform: 1 },
1852
1925
  name: "Hunger Switch",
1853
1926
  rating: 1,
1854
1927
  num: 258,
@@ -1865,6 +1938,7 @@ export const Abilities = {
1865
1938
  return this.chainModify([3277, 4096]);
1866
1939
  }
1867
1940
  },
1941
+ flags: {},
1868
1942
  name: "Hustle",
1869
1943
  rating: 3.5,
1870
1944
  num: 55,
@@ -1879,6 +1953,7 @@ export const Abilities = {
1879
1953
  pokemon.cureStatus();
1880
1954
  }
1881
1955
  },
1956
+ flags: {},
1882
1957
  name: "Hydration",
1883
1958
  rating: 1.5,
1884
1959
  num: 93,
@@ -1894,7 +1969,7 @@ export const Abilities = {
1894
1969
  }
1895
1970
  }
1896
1971
  },
1897
- isBreakable: true,
1972
+ flags: { breakable: 1 },
1898
1973
  name: "Hyper Cutter",
1899
1974
  rating: 1.5,
1900
1975
  num: 52,
@@ -1909,14 +1984,14 @@ export const Abilities = {
1909
1984
  if (type === 'hail')
1910
1985
  return false;
1911
1986
  },
1987
+ flags: {},
1912
1988
  name: "Ice Body",
1913
1989
  rating: 1,
1914
1990
  num: 115,
1915
1991
  },
1916
1992
  iceface: {
1917
1993
  onStart(pokemon) {
1918
- if (this.field.isWeather(['hail', 'snow']) &&
1919
- pokemon.species.id === 'eiscuenoice' && !pokemon.transformed) {
1994
+ if (this.field.isWeather(['hail', 'snow']) && pokemon.species.id === 'eiscuenoice') {
1920
1995
  this.add('-activate', pokemon, 'ability: Ice Face');
1921
1996
  this.effectState.busted = false;
1922
1997
  pokemon.formeChange('Eiscue', this.effect, true);
@@ -1924,8 +1999,7 @@ export const Abilities = {
1924
1999
  },
1925
2000
  onDamagePriority: 1,
1926
2001
  onDamage(damage, target, source, effect) {
1927
- if (effect && effect.effectType === 'Move' && effect.category === 'Physical' &&
1928
- target.species.id === 'eiscue' && !target.transformed) {
2002
+ if (effect?.effectType === 'Move' && effect.category === 'Physical' && target.species.id === 'eiscue') {
1929
2003
  this.add('-activate', target, 'ability: Ice Face');
1930
2004
  this.effectState.busted = true;
1931
2005
  return 0;
@@ -1934,7 +2008,7 @@ export const Abilities = {
1934
2008
  onCriticalHit(target, type, move) {
1935
2009
  if (!target)
1936
2010
  return;
1937
- if (move.category !== 'Physical' || target.species.id !== 'eiscue' || target.transformed)
2011
+ if (move.category !== 'Physical' || target.species.id !== 'eiscue')
1938
2012
  return;
1939
2013
  if (target.volatiles['substitute'] && !(move.flags['bypasssub'] || move.infiltrates))
1940
2014
  return;
@@ -1945,7 +2019,7 @@ export const Abilities = {
1945
2019
  onEffectiveness(typeMod, target, type, move) {
1946
2020
  if (!target)
1947
2021
  return;
1948
- if (move.category !== 'Physical' || target.species.id !== 'eiscue' || target.transformed)
2022
+ if (move.category !== 'Physical' || target.species.id !== 'eiscue')
1949
2023
  return;
1950
2024
  const hitSub = target.volatiles['substitute'] && !move.flags['bypasssub'] && !(move.infiltrates && this.gen >= 6);
1951
2025
  if (hitSub)
@@ -1965,15 +2039,16 @@ export const Abilities = {
1965
2039
  return;
1966
2040
  if (!pokemon.hp)
1967
2041
  return;
1968
- if (this.field.isWeather(['hail', 'snow']) &&
1969
- pokemon.species.id === 'eiscuenoice' && !pokemon.transformed) {
2042
+ if (this.field.isWeather(['hail', 'snow']) && pokemon.species.id === 'eiscuenoice') {
1970
2043
  this.add('-activate', pokemon, 'ability: Ice Face');
1971
2044
  this.effectState.busted = false;
1972
2045
  pokemon.formeChange('Eiscue', this.effect, true);
1973
2046
  }
1974
2047
  },
1975
- isBreakable: true,
1976
- isPermanent: true,
2048
+ flags: {
2049
+ failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1,
2050
+ breakable: 1, notransform: 1,
2051
+ },
1977
2052
  name: "Ice Face",
1978
2053
  rating: 3,
1979
2054
  num: 248,
@@ -1984,7 +2059,7 @@ export const Abilities = {
1984
2059
  return this.chainModify(0.5);
1985
2060
  }
1986
2061
  },
1987
- isBreakable: true,
2062
+ flags: { breakable: 1 },
1988
2063
  name: "Ice Scales",
1989
2064
  rating: 4,
1990
2065
  num: 246,
@@ -2003,7 +2078,7 @@ export const Abilities = {
2003
2078
  onModifyMove(move) {
2004
2079
  move.ignoreEvasion = true;
2005
2080
  },
2006
- isBreakable: true,
2081
+ flags: { breakable: 1 },
2007
2082
  name: "Illuminate",
2008
2083
  rating: 0.5,
2009
2084
  num: 35,
@@ -2045,6 +2120,7 @@ export const Abilities = {
2045
2120
  onFaint(pokemon) {
2046
2121
  pokemon.illusion = null;
2047
2122
  },
2123
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1 },
2048
2124
  name: "Illusion",
2049
2125
  rating: 4.5,
2050
2126
  num: 149,
@@ -2064,7 +2140,7 @@ export const Abilities = {
2064
2140
  }
2065
2141
  return false;
2066
2142
  },
2067
- isBreakable: true,
2143
+ flags: { breakable: 1 },
2068
2144
  name: "Immunity",
2069
2145
  rating: 2,
2070
2146
  num: 17,
@@ -2086,6 +2162,7 @@ export const Abilities = {
2086
2162
  }
2087
2163
  this.effectState.switchingIn = false;
2088
2164
  },
2165
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1 },
2089
2166
  name: "Imposter",
2090
2167
  rating: 5,
2091
2168
  num: 150,
@@ -2094,18 +2171,20 @@ export const Abilities = {
2094
2171
  onModifyMove(move) {
2095
2172
  move.infiltrates = true;
2096
2173
  },
2174
+ flags: {},
2097
2175
  name: "Infiltrator",
2098
2176
  rating: 2.5,
2099
2177
  num: 151,
2100
2178
  },
2101
2179
  innardsout: {
2102
- name: "Innards Out",
2103
2180
  onDamagingHitOrder: 1,
2104
2181
  onDamagingHit(damage, target, source, move) {
2105
2182
  if (!target.hp) {
2106
2183
  this.damage(target.getUndynamaxedHP(damage), source, target);
2107
2184
  }
2108
2185
  },
2186
+ flags: {},
2187
+ name: "Innards Out",
2109
2188
  rating: 4,
2110
2189
  num: 215,
2111
2190
  },
@@ -2120,7 +2199,7 @@ export const Abilities = {
2120
2199
  this.add('-fail', target, 'unboost', 'Attack', '[from] ability: Inner Focus', '[of] ' + target);
2121
2200
  }
2122
2201
  },
2123
- isBreakable: true,
2202
+ flags: { breakable: 1 },
2124
2203
  name: "Inner Focus",
2125
2204
  rating: 1,
2126
2205
  num: 39,
@@ -2146,7 +2225,7 @@ export const Abilities = {
2146
2225
  return null;
2147
2226
  }
2148
2227
  },
2149
- isBreakable: true,
2228
+ flags: { breakable: 1 },
2150
2229
  name: "Insomnia",
2151
2230
  rating: 1.5,
2152
2231
  num: 15,
@@ -2167,6 +2246,7 @@ export const Abilities = {
2167
2246
  }
2168
2247
  }
2169
2248
  },
2249
+ flags: {},
2170
2250
  name: "Intimidate",
2171
2251
  rating: 3.5,
2172
2252
  num: 22,
@@ -2178,6 +2258,7 @@ export const Abilities = {
2178
2258
  pokemon.swordBoost = true;
2179
2259
  this.boost({ atk: 1 }, pokemon);
2180
2260
  },
2261
+ flags: {},
2181
2262
  name: "Intrepid Sword",
2182
2263
  rating: 4,
2183
2264
  num: 234,
@@ -2189,6 +2270,7 @@ export const Abilities = {
2189
2270
  this.damage(source.baseMaxhp / 8, source, target);
2190
2271
  }
2191
2272
  },
2273
+ flags: {},
2192
2274
  name: "Iron Barbs",
2193
2275
  rating: 2.5,
2194
2276
  num: 160,
@@ -2201,6 +2283,7 @@ export const Abilities = {
2201
2283
  return this.chainModify([4915, 4096]);
2202
2284
  }
2203
2285
  },
2286
+ flags: {},
2204
2287
  name: "Iron Fist",
2205
2288
  rating: 3,
2206
2289
  num: 89,
@@ -2211,6 +2294,7 @@ export const Abilities = {
2211
2294
  this.boost({ atk: 1 });
2212
2295
  }
2213
2296
  },
2297
+ flags: {},
2214
2298
  name: "Justified",
2215
2299
  rating: 2.5,
2216
2300
  num: 154,
@@ -2229,7 +2313,7 @@ export const Abilities = {
2229
2313
  onModifyMove(move) {
2230
2314
  move.ignoreEvasion = true;
2231
2315
  },
2232
- isBreakable: true,
2316
+ flags: { breakable: 1 },
2233
2317
  name: "Keen Eye",
2234
2318
  rating: 0.5,
2235
2319
  num: 51,
@@ -2239,6 +2323,7 @@ export const Abilities = {
2239
2323
  onStart(pokemon) {
2240
2324
  this.singleEvent('End', pokemon.getItem(), pokemon.itemState, pokemon);
2241
2325
  },
2326
+ flags: {},
2242
2327
  name: "Klutz",
2243
2328
  rating: -1,
2244
2329
  num: 103,
@@ -2258,14 +2343,14 @@ export const Abilities = {
2258
2343
  return null;
2259
2344
  }
2260
2345
  },
2261
- isBreakable: true,
2346
+ flags: { breakable: 1 },
2262
2347
  name: "Leaf Guard",
2263
2348
  rating: 0.5,
2264
2349
  num: 102,
2265
2350
  },
2266
2351
  levitate: {
2267
2352
  // airborneness implemented in sim/pokemon.js:Pokemon#isGrounded
2268
- isBreakable: true,
2353
+ flags: { breakable: 1 },
2269
2354
  name: "Levitate",
2270
2355
  rating: 3.5,
2271
2356
  num: 26,
@@ -2287,6 +2372,7 @@ export const Abilities = {
2287
2372
  onSwitchIn() {
2288
2373
  delete this.effectState.libero;
2289
2374
  },
2375
+ flags: {},
2290
2376
  name: "Libero",
2291
2377
  rating: 4,
2292
2378
  num: 236,
@@ -2295,7 +2381,7 @@ export const Abilities = {
2295
2381
  onModifyWeight(weighthg) {
2296
2382
  return this.trunc(weighthg / 2);
2297
2383
  },
2298
- isBreakable: true,
2384
+ flags: { breakable: 1 },
2299
2385
  name: "Light Metal",
2300
2386
  rating: 1,
2301
2387
  num: 135,
@@ -2322,7 +2408,7 @@ export const Abilities = {
2322
2408
  return this.effectState.target;
2323
2409
  }
2324
2410
  },
2325
- isBreakable: true,
2411
+ flags: { breakable: 1 },
2326
2412
  name: "Lightning Rod",
2327
2413
  rating: 3,
2328
2414
  num: 31,
@@ -2342,7 +2428,7 @@ export const Abilities = {
2342
2428
  }
2343
2429
  return false;
2344
2430
  },
2345
- isBreakable: true,
2431
+ flags: { breakable: 1 },
2346
2432
  name: "Limber",
2347
2433
  rating: 2,
2348
2434
  num: 7,
@@ -2350,7 +2436,7 @@ export const Abilities = {
2350
2436
  lingeringaroma: {
2351
2437
  onDamagingHit(damage, target, source, move) {
2352
2438
  const sourceAbility = source.getAbility();
2353
- if (sourceAbility.isPermanent || sourceAbility.id === 'lingeringaroma') {
2439
+ if (sourceAbility.flags['cantsuppress'] || sourceAbility.id === 'lingeringaroma') {
2354
2440
  return;
2355
2441
  }
2356
2442
  if (this.checkMoveMakesContact(move, source, target, !source.isAlly(target))) {
@@ -2360,6 +2446,7 @@ export const Abilities = {
2360
2446
  }
2361
2447
  }
2362
2448
  },
2449
+ flags: {},
2363
2450
  name: "Lingering Aroma",
2364
2451
  rating: 2,
2365
2452
  num: 268,
@@ -2373,6 +2460,7 @@ export const Abilities = {
2373
2460
  return 0;
2374
2461
  }
2375
2462
  },
2463
+ flags: {},
2376
2464
  name: "Liquid Ooze",
2377
2465
  rating: 2.5,
2378
2466
  num: 64,
@@ -2384,6 +2472,7 @@ export const Abilities = {
2384
2472
  move.type = 'Water';
2385
2473
  }
2386
2474
  },
2475
+ flags: {},
2387
2476
  name: "Liquid Voice",
2388
2477
  rating: 1.5,
2389
2478
  num: 204,
@@ -2392,12 +2481,12 @@ export const Abilities = {
2392
2481
  onModifyMove(move) {
2393
2482
  delete move.flags['contact'];
2394
2483
  },
2484
+ flags: {},
2395
2485
  name: "Long Reach",
2396
2486
  rating: 1,
2397
2487
  num: 203,
2398
2488
  },
2399
2489
  magicbounce: {
2400
- name: "Magic Bounce",
2401
2490
  onTryHitPriority: 1,
2402
2491
  onTryHit(target, source, move) {
2403
2492
  if (target === source || move.hasBounced || !move.flags['reflectable']) {
@@ -2422,7 +2511,8 @@ export const Abilities = {
2422
2511
  condition: {
2423
2512
  duration: 1,
2424
2513
  },
2425
- isBreakable: true,
2514
+ flags: { breakable: 1 },
2515
+ name: "Magic Bounce",
2426
2516
  rating: 4,
2427
2517
  num: 156,
2428
2518
  },
@@ -2434,6 +2524,7 @@ export const Abilities = {
2434
2524
  return false;
2435
2525
  }
2436
2526
  },
2527
+ flags: {},
2437
2528
  name: "Magic Guard",
2438
2529
  rating: 4,
2439
2530
  num: 98,
@@ -2455,6 +2546,7 @@ export const Abilities = {
2455
2546
  this.add('-item', source, yourItem, '[from] ability: Magician', '[of] ' + target);
2456
2547
  }
2457
2548
  },
2549
+ flags: {},
2458
2550
  name: "Magician",
2459
2551
  rating: 1,
2460
2552
  num: 170,
@@ -2470,7 +2562,7 @@ export const Abilities = {
2470
2562
  if (type === 'frz')
2471
2563
  return false;
2472
2564
  },
2473
- isBreakable: true,
2565
+ flags: { breakable: 1 },
2474
2566
  name: "Magma Armor",
2475
2567
  rating: 0.5,
2476
2568
  num: 40,
@@ -2490,6 +2582,7 @@ export const Abilities = {
2490
2582
  pokemon.maybeTrapped = true;
2491
2583
  }
2492
2584
  },
2585
+ flags: {},
2493
2586
  name: "Magnet Pull",
2494
2587
  rating: 4,
2495
2588
  num: 42,
@@ -2501,7 +2594,7 @@ export const Abilities = {
2501
2594
  return this.chainModify(1.5);
2502
2595
  }
2503
2596
  },
2504
- isBreakable: true,
2597
+ flags: { breakable: 1 },
2505
2598
  name: "Marvel Scale",
2506
2599
  rating: 2.5,
2507
2600
  num: 63,
@@ -2513,6 +2606,7 @@ export const Abilities = {
2513
2606
  return this.chainModify(1.5);
2514
2607
  }
2515
2608
  },
2609
+ flags: {},
2516
2610
  name: "Mega Launcher",
2517
2611
  rating: 3,
2518
2612
  num: 178,
@@ -2522,6 +2616,7 @@ export const Abilities = {
2522
2616
  if (target && ['psn', 'tox'].includes(target.status))
2523
2617
  return 5;
2524
2618
  },
2619
+ flags: {},
2525
2620
  name: "Merciless",
2526
2621
  rating: 1.5,
2527
2622
  num: 196,
@@ -2561,6 +2656,7 @@ export const Abilities = {
2561
2656
  this.add('-end', pokemon, 'typechange', '[silent]');
2562
2657
  }
2563
2658
  },
2659
+ flags: {},
2564
2660
  name: "Mimicry",
2565
2661
  rating: 0,
2566
2662
  num: 250,
@@ -2586,6 +2682,7 @@ export const Abilities = {
2586
2682
  move.ignoreImmunity['Normal'] = true;
2587
2683
  }
2588
2684
  },
2685
+ flags: { breakable: 1 },
2589
2686
  name: "Mind's Eye",
2590
2687
  rating: 0,
2591
2688
  num: 300,
@@ -2599,6 +2696,7 @@ export const Abilities = {
2599
2696
  }
2600
2697
  }
2601
2698
  },
2699
+ flags: {},
2602
2700
  name: "Minus",
2603
2701
  rating: 0,
2604
2702
  num: 58,
@@ -2623,7 +2721,7 @@ export const Abilities = {
2623
2721
  }
2624
2722
  }
2625
2723
  },
2626
- isBreakable: true,
2724
+ flags: { breakable: 1 },
2627
2725
  name: "Mirror Armor",
2628
2726
  rating: 2,
2629
2727
  num: 240,
@@ -2632,6 +2730,7 @@ export const Abilities = {
2632
2730
  onStart(source) {
2633
2731
  this.field.setTerrain('mistyterrain');
2634
2732
  },
2733
+ flags: {},
2635
2734
  name: "Misty Surge",
2636
2735
  rating: 3.5,
2637
2736
  num: 228,
@@ -2643,6 +2742,7 @@ export const Abilities = {
2643
2742
  onModifyMove(move) {
2644
2743
  move.ignoreAbility = true;
2645
2744
  },
2745
+ flags: {},
2646
2746
  name: "Mold Breaker",
2647
2747
  rating: 3,
2648
2748
  num: 104,
@@ -2678,6 +2778,7 @@ export const Abilities = {
2678
2778
  boost[randomStat] = -1;
2679
2779
  this.boost(boost, pokemon, pokemon);
2680
2780
  },
2781
+ flags: {},
2681
2782
  name: "Moody",
2682
2783
  rating: 5,
2683
2784
  num: 141,
@@ -2691,7 +2792,7 @@ export const Abilities = {
2691
2792
  return null;
2692
2793
  }
2693
2794
  },
2694
- isBreakable: true,
2795
+ flags: { breakable: 1 },
2695
2796
  name: "Motor Drive",
2696
2797
  rating: 3,
2697
2798
  num: 78,
@@ -2702,6 +2803,7 @@ export const Abilities = {
2702
2803
  this.boost({ atk: length }, source);
2703
2804
  }
2704
2805
  },
2806
+ flags: {},
2705
2807
  name: "Moxie",
2706
2808
  rating: 3,
2707
2809
  num: 153,
@@ -2713,23 +2815,22 @@ export const Abilities = {
2713
2815
  return this.chainModify(0.5);
2714
2816
  }
2715
2817
  },
2716
- isBreakable: true,
2818
+ flags: { breakable: 1 },
2717
2819
  name: "Multiscale",
2718
2820
  rating: 3.5,
2719
2821
  num: 136,
2720
2822
  },
2721
2823
  multitype: {
2722
2824
  // Multitype's type-changing itself is implemented in statuses.js
2723
- isPermanent: true,
2825
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1 },
2724
2826
  name: "Multitype",
2725
2827
  rating: 4,
2726
2828
  num: 121,
2727
2829
  },
2728
2830
  mummy: {
2729
- name: "Mummy",
2730
2831
  onDamagingHit(damage, target, source, move) {
2731
2832
  const sourceAbility = source.getAbility();
2732
- if (sourceAbility.isPermanent || sourceAbility.id === 'mummy') {
2833
+ if (sourceAbility.flags['cantsuppress'] || sourceAbility.id === 'mummy') {
2733
2834
  return;
2734
2835
  }
2735
2836
  if (this.checkMoveMakesContact(move, source, target, !source.isAlly(target))) {
@@ -2739,6 +2840,8 @@ export const Abilities = {
2739
2840
  }
2740
2841
  }
2741
2842
  },
2843
+ flags: {},
2844
+ name: "Mummy",
2742
2845
  rating: 2,
2743
2846
  num: 152,
2744
2847
  },
@@ -2754,6 +2857,7 @@ export const Abilities = {
2754
2857
  move.ignoreAbility = true;
2755
2858
  }
2756
2859
  },
2860
+ flags: {},
2757
2861
  name: "Mycelium Might",
2758
2862
  rating: 2,
2759
2863
  num: 298,
@@ -2836,6 +2940,7 @@ export const Abilities = {
2836
2940
  if (!pokemon.showCure)
2837
2941
  pokemon.showCure = undefined;
2838
2942
  },
2943
+ flags: {},
2839
2944
  name: "Natural Cure",
2840
2945
  rating: 2.5,
2841
2946
  num: 30,
@@ -2846,6 +2951,7 @@ export const Abilities = {
2846
2951
  return this.chainModify([5120, 4096]);
2847
2952
  }
2848
2953
  },
2954
+ flags: {},
2849
2955
  name: "Neuroforce",
2850
2956
  rating: 2.5,
2851
2957
  num: 233,
@@ -2853,8 +2959,6 @@ export const Abilities = {
2853
2959
  neutralizinggas: {
2854
2960
  // Ability suppression implemented in sim/pokemon.ts:Pokemon#ignoringAbility
2855
2961
  onPreStart(pokemon) {
2856
- if (pokemon.transformed)
2857
- return;
2858
2962
  this.add('-ability', pokemon, 'Neutralizing Gas');
2859
2963
  pokemon.abilityState.ending = false;
2860
2964
  const strongWeathers = ['desolateland', 'primordialsea', 'deltastream'];
@@ -2900,7 +3004,7 @@ export const Abilities = {
2900
3004
  this.speedSort(sortedActive);
2901
3005
  for (const pokemon of sortedActive) {
2902
3006
  if (pokemon !== source) {
2903
- if (pokemon.getAbility().isPermanent)
3007
+ if (pokemon.getAbility().flags['cantsuppress'])
2904
3008
  continue; // does not interact with e.g Ice Face, Zen Mode
2905
3009
  if (pokemon.hasItem('abilityshield'))
2906
3010
  continue; // don't restart abilities that weren't suppressed
@@ -2912,6 +3016,7 @@ export const Abilities = {
2912
3016
  }
2913
3017
  }
2914
3018
  },
3019
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, notransform: 1 },
2915
3020
  name: "Neutralizing Gas",
2916
3021
  rating: 3.5,
2917
3022
  num: 256,
@@ -2928,6 +3033,7 @@ export const Abilities = {
2928
3033
  }
2929
3034
  return accuracy;
2930
3035
  },
3036
+ flags: {},
2931
3037
  name: "No Guard",
2932
3038
  rating: 4,
2933
3039
  num: 99,
@@ -2950,6 +3056,7 @@ export const Abilities = {
2950
3056
  if (move.typeChangerBoosted === this.effect)
2951
3057
  return this.chainModify([4915, 4096]);
2952
3058
  },
3059
+ flags: {},
2953
3060
  name: "Normalize",
2954
3061
  rating: 0,
2955
3062
  num: 96,
@@ -2983,7 +3090,7 @@ export const Abilities = {
2983
3090
  this.add('-fail', target, 'unboost', 'Attack', '[from] ability: Oblivious', '[of] ' + target);
2984
3091
  }
2985
3092
  },
2986
- isBreakable: true,
3093
+ flags: { breakable: 1 },
2987
3094
  name: "Oblivious",
2988
3095
  rating: 1.5,
2989
3096
  num: 12,
@@ -3004,6 +3111,7 @@ export const Abilities = {
3004
3111
  return;
3005
3112
  this.boost(positiveBoosts, pokemon);
3006
3113
  },
3114
+ flags: {},
3007
3115
  name: "Opportunist",
3008
3116
  rating: 3,
3009
3117
  num: 290,
@@ -3024,6 +3132,7 @@ export const Abilities = {
3024
3132
  return this.chainModify([5461, 4096]);
3025
3133
  }
3026
3134
  },
3135
+ flags: {},
3027
3136
  name: "Orichalcum Pulse",
3028
3137
  rating: 4.5,
3029
3138
  num: 288,
@@ -3040,7 +3149,7 @@ export const Abilities = {
3040
3149
  return null;
3041
3150
  }
3042
3151
  },
3043
- isBreakable: true,
3152
+ flags: { breakable: 1 },
3044
3153
  name: "Overcoat",
3045
3154
  rating: 2,
3046
3155
  num: 142,
@@ -3060,6 +3169,7 @@ export const Abilities = {
3060
3169
  return this.chainModify(1.5);
3061
3170
  }
3062
3171
  },
3172
+ flags: {},
3063
3173
  name: "Overgrow",
3064
3174
  rating: 2,
3065
3175
  num: 65,
@@ -3086,7 +3196,7 @@ export const Abilities = {
3086
3196
  this.add('-fail', target, 'unboost', 'Attack', '[from] ability: Own Tempo', '[of] ' + target);
3087
3197
  }
3088
3198
  },
3089
- isBreakable: true,
3199
+ flags: { breakable: 1 },
3090
3200
  name: "Own Tempo",
3091
3201
  rating: 1.5,
3092
3202
  num: 20,
@@ -3106,6 +3216,7 @@ export const Abilities = {
3106
3216
  return secondaries.filter(effect => effect.volatileStatus === 'flinch');
3107
3217
  }
3108
3218
  },
3219
+ flags: {},
3109
3220
  name: "Parental Bond",
3110
3221
  rating: 4.5,
3111
3222
  num: 185,
@@ -3148,7 +3259,7 @@ export const Abilities = {
3148
3259
  }
3149
3260
  return false;
3150
3261
  },
3151
- isBreakable: true,
3262
+ flags: { breakable: 1 },
3152
3263
  name: "Pastel Veil",
3153
3264
  rating: 2,
3154
3265
  num: 257,
@@ -3168,6 +3279,7 @@ export const Abilities = {
3168
3279
  pokemon.addVolatile('perishsong');
3169
3280
  }
3170
3281
  },
3282
+ flags: {},
3171
3283
  name: "Perish Body",
3172
3284
  rating: 1,
3173
3285
  num: 253,
@@ -3190,6 +3302,7 @@ export const Abilities = {
3190
3302
  this.add('-item', target, yourItem, '[from] ability: Pickpocket', '[of] ' + source);
3191
3303
  }
3192
3304
  },
3305
+ flags: {},
3193
3306
  name: "Pickpocket",
3194
3307
  rating: 1,
3195
3308
  num: 124,
@@ -3209,6 +3322,7 @@ export const Abilities = {
3209
3322
  this.add('-item', pokemon, this.dex.items.get(item), '[from] ability: Pickup');
3210
3323
  pokemon.setItem(item);
3211
3324
  },
3325
+ flags: {},
3212
3326
  name: "Pickup",
3213
3327
  rating: 0.5,
3214
3328
  num: 53,
@@ -3230,6 +3344,7 @@ export const Abilities = {
3230
3344
  if (move.typeChangerBoosted === this.effect)
3231
3345
  return this.chainModify([4915, 4096]);
3232
3346
  },
3347
+ flags: {},
3233
3348
  name: "Pixilate",
3234
3349
  rating: 4,
3235
3350
  num: 182,
@@ -3243,6 +3358,7 @@ export const Abilities = {
3243
3358
  }
3244
3359
  }
3245
3360
  },
3361
+ flags: {},
3246
3362
  name: "Plus",
3247
3363
  rating: 0,
3248
3364
  num: 57,
@@ -3255,6 +3371,7 @@ export const Abilities = {
3255
3371
  return false;
3256
3372
  }
3257
3373
  },
3374
+ flags: {},
3258
3375
  name: "Poison Heal",
3259
3376
  rating: 4,
3260
3377
  num: 90,
@@ -3267,6 +3384,7 @@ export const Abilities = {
3267
3384
  }
3268
3385
  }
3269
3386
  },
3387
+ flags: {},
3270
3388
  name: "Poison Point",
3271
3389
  rating: 1.5,
3272
3390
  num: 38,
@@ -3279,6 +3397,7 @@ export const Abilities = {
3279
3397
  target.addVolatile('confusion');
3280
3398
  }
3281
3399
  },
3400
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1 },
3282
3401
  name: "Poison Puppeteer",
3283
3402
  rating: 3,
3284
3403
  num: 310,
@@ -3294,6 +3413,7 @@ export const Abilities = {
3294
3413
  }
3295
3414
  }
3296
3415
  },
3416
+ flags: {},
3297
3417
  name: "Poison Touch",
3298
3418
  rating: 2,
3299
3419
  num: 143,
@@ -3313,7 +3433,7 @@ export const Abilities = {
3313
3433
  pokemon.maxhp = newMaxHP;
3314
3434
  this.add('-heal', pokemon, pokemon.getHealth, '[silent]');
3315
3435
  },
3316
- isPermanent: true,
3436
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1 },
3317
3437
  name: "Power Construct",
3318
3438
  rating: 5,
3319
3439
  num: 211,
@@ -3323,15 +3443,13 @@ export const Abilities = {
3323
3443
  if (!this.effectState.target.hp)
3324
3444
  return;
3325
3445
  const ability = target.getAbility();
3326
- const additionalBannedAbilities = [
3327
- 'noability', 'commander', 'flowergift', 'forecast', 'hungerswitch', 'illusion', 'imposter', 'neutralizinggas', 'powerofalchemy', 'receiver', 'trace', 'wonderguard',
3328
- ];
3329
- if (target.getAbility().isPermanent || additionalBannedAbilities.includes(target.ability))
3446
+ if (ability.flags['noreceiver'] || ability.id === 'noability')
3330
3447
  return;
3331
3448
  if (this.effectState.target.setAbility(ability)) {
3332
3449
  this.add('-ability', this.effectState.target, ability, '[from] ability: Power of Alchemy', '[of] ' + target);
3333
3450
  }
3334
3451
  },
3452
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1 },
3335
3453
  name: "Power of Alchemy",
3336
3454
  rating: 0,
3337
3455
  num: 223,
@@ -3344,6 +3462,7 @@ export const Abilities = {
3344
3462
  return this.chainModify([5325, 4096]);
3345
3463
  }
3346
3464
  },
3465
+ flags: {},
3347
3466
  name: "Power Spot",
3348
3467
  rating: 0,
3349
3468
  num: 249,
@@ -3355,6 +3474,7 @@ export const Abilities = {
3355
3474
  return priority + 1;
3356
3475
  }
3357
3476
  },
3477
+ flags: {},
3358
3478
  name: "Prankster",
3359
3479
  rating: 4,
3360
3480
  num: 158,
@@ -3368,6 +3488,7 @@ export const Abilities = {
3368
3488
  return;
3369
3489
  return 1;
3370
3490
  },
3491
+ flags: {},
3371
3492
  name: "Pressure",
3372
3493
  rating: 2.5,
3373
3494
  num: 46,
@@ -3394,6 +3515,7 @@ export const Abilities = {
3394
3515
  }
3395
3516
  this.field.clearWeather();
3396
3517
  },
3518
+ flags: {},
3397
3519
  name: "Primordial Sea",
3398
3520
  rating: 4.5,
3399
3521
  num: 189,
@@ -3405,6 +3527,7 @@ export const Abilities = {
3405
3527
  return this.chainModify(0.75);
3406
3528
  }
3407
3529
  },
3530
+ flags: {},
3408
3531
  name: "Prism Armor",
3409
3532
  rating: 3,
3410
3533
  num: 232,
@@ -3415,6 +3538,7 @@ export const Abilities = {
3415
3538
  // most of the implementation is in Battle#getTarget
3416
3539
  move.tracksTarget = move.target !== 'scripted';
3417
3540
  },
3541
+ flags: {},
3418
3542
  name: "Propeller Tail",
3419
3543
  rating: 0,
3420
3544
  num: 239,
@@ -3436,6 +3560,7 @@ export const Abilities = {
3436
3560
  onSwitchIn(pokemon) {
3437
3561
  delete this.effectState.protean;
3438
3562
  },
3563
+ flags: {},
3439
3564
  name: "Protean",
3440
3565
  rating: 4,
3441
3566
  num: 168,
@@ -3445,8 +3570,6 @@ export const Abilities = {
3445
3570
  this.singleEvent('WeatherChange', this.effect, this.effectState, pokemon);
3446
3571
  },
3447
3572
  onWeatherChange(pokemon) {
3448
- if (pokemon.transformed)
3449
- return;
3450
3573
  // Protosynthesis is not affected by Utility Umbrella
3451
3574
  if (this.field.isWeather('sunnyday')) {
3452
3575
  pokemon.addVolatile('protosynthesis');
@@ -3510,6 +3633,7 @@ export const Abilities = {
3510
3633
  this.add('-end', pokemon, 'Protosynthesis');
3511
3634
  },
3512
3635
  },
3636
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, notransform: 1 },
3513
3637
  name: "Protosynthesis",
3514
3638
  rating: 3,
3515
3639
  num: 281,
@@ -3518,6 +3642,7 @@ export const Abilities = {
3518
3642
  onStart(source) {
3519
3643
  this.field.setTerrain('psychicterrain');
3520
3644
  },
3645
+ flags: {},
3521
3646
  name: "Psychic Surge",
3522
3647
  rating: 4,
3523
3648
  num: 227,
@@ -3536,7 +3661,7 @@ export const Abilities = {
3536
3661
  return this.chainModify(0.5);
3537
3662
  }
3538
3663
  },
3539
- isBreakable: true,
3664
+ flags: { breakable: 1 },
3540
3665
  name: "Punk Rock",
3541
3666
  rating: 3.5,
3542
3667
  num: 244,
@@ -3546,6 +3671,7 @@ export const Abilities = {
3546
3671
  onModifyAtk(atk) {
3547
3672
  return this.chainModify(2);
3548
3673
  },
3674
+ flags: {},
3549
3675
  name: "Pure Power",
3550
3676
  rating: 5,
3551
3677
  num: 74,
@@ -3577,7 +3703,7 @@ export const Abilities = {
3577
3703
  return this.chainModify(0.5);
3578
3704
  }
3579
3705
  },
3580
- isBreakable: true,
3706
+ flags: { breakable: 1 },
3581
3707
  name: "Purifying Salt",
3582
3708
  rating: 4,
3583
3709
  num: 272,
@@ -3587,8 +3713,6 @@ export const Abilities = {
3587
3713
  this.singleEvent('TerrainChange', this.effect, this.effectState, pokemon);
3588
3714
  },
3589
3715
  onTerrainChange(pokemon) {
3590
- if (pokemon.transformed)
3591
- return;
3592
3716
  if (this.field.isTerrain('electricterrain')) {
3593
3717
  pokemon.addVolatile('quarkdrive');
3594
3718
  }
@@ -3651,6 +3775,7 @@ export const Abilities = {
3651
3775
  this.add('-end', pokemon, 'Quark Drive');
3652
3776
  },
3653
3777
  },
3778
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, notransform: 1 },
3654
3779
  name: "Quark Drive",
3655
3780
  rating: 3,
3656
3781
  num: 282,
@@ -3668,7 +3793,7 @@ export const Abilities = {
3668
3793
  return false;
3669
3794
  }
3670
3795
  },
3671
- isBreakable: true,
3796
+ flags: { breakable: 1 },
3672
3797
  name: "Queenly Majesty",
3673
3798
  rating: 2.5,
3674
3799
  num: 214,
@@ -3681,6 +3806,7 @@ export const Abilities = {
3681
3806
  return 0.1;
3682
3807
  }
3683
3808
  },
3809
+ flags: {},
3684
3810
  name: "Quick Draw",
3685
3811
  rating: 2.5,
3686
3812
  num: 259,
@@ -3691,6 +3817,7 @@ export const Abilities = {
3691
3817
  return this.chainModify(1.5);
3692
3818
  }
3693
3819
  },
3820
+ flags: {},
3694
3821
  name: "Quick Feet",
3695
3822
  rating: 2.5,
3696
3823
  num: 95,
@@ -3703,6 +3830,7 @@ export const Abilities = {
3703
3830
  this.heal(target.baseMaxhp / 16);
3704
3831
  }
3705
3832
  },
3833
+ flags: {},
3706
3834
  name: "Rain Dish",
3707
3835
  rating: 1.5,
3708
3836
  num: 44,
@@ -3718,6 +3846,7 @@ export const Abilities = {
3718
3846
  this.boost({ spe: 1 });
3719
3847
  }
3720
3848
  },
3849
+ flags: {},
3721
3850
  name: "Rattled",
3722
3851
  rating: 1,
3723
3852
  num: 155,
@@ -3727,15 +3856,13 @@ export const Abilities = {
3727
3856
  if (!this.effectState.target.hp)
3728
3857
  return;
3729
3858
  const ability = target.getAbility();
3730
- const additionalBannedAbilities = [
3731
- 'noability', 'commander', 'flowergift', 'forecast', 'hungerswitch', 'illusion', 'imposter', 'neutralizinggas', 'powerofalchemy', 'receiver', 'trace', 'wonderguard',
3732
- ];
3733
- if (target.getAbility().isPermanent || additionalBannedAbilities.includes(target.ability))
3859
+ if (ability.flags['noreceiver'] || ability.id === 'noability')
3734
3860
  return;
3735
3861
  if (this.effectState.target.setAbility(ability)) {
3736
3862
  this.add('-ability', this.effectState.target, ability, '[from] ability: Receiver', '[of] ' + target);
3737
3863
  }
3738
3864
  },
3865
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1 },
3739
3866
  name: "Receiver",
3740
3867
  rating: 0,
3741
3868
  num: 222,
@@ -3748,6 +3875,7 @@ export const Abilities = {
3748
3875
  return this.chainModify([4915, 4096]);
3749
3876
  }
3750
3877
  },
3878
+ flags: {},
3751
3879
  name: "Reckless",
3752
3880
  rating: 3,
3753
3881
  num: 120,
@@ -3769,6 +3897,7 @@ export const Abilities = {
3769
3897
  if (move.typeChangerBoosted === this.effect)
3770
3898
  return this.chainModify([4915, 4096]);
3771
3899
  },
3900
+ flags: {},
3772
3901
  name: "Refrigerate",
3773
3902
  rating: 4,
3774
3903
  num: 174,
@@ -3777,6 +3906,7 @@ export const Abilities = {
3777
3906
  onSwitchOut(pokemon) {
3778
3907
  pokemon.heal(pokemon.baseMaxhp / 3);
3779
3908
  },
3909
+ flags: {},
3780
3910
  name: "Regenerator",
3781
3911
  rating: 4.5,
3782
3912
  num: 144,
@@ -3817,6 +3947,7 @@ export const Abilities = {
3817
3947
  // Record if the pokemon ate a berry to resist the attack
3818
3948
  pokemon.abilityState.berryWeaken = weakenBerries.includes(item.name);
3819
3949
  },
3950
+ flags: {},
3820
3951
  name: "Ripen",
3821
3952
  rating: 2,
3822
3953
  num: 247,
@@ -3835,13 +3966,14 @@ export const Abilities = {
3835
3966
  }
3836
3967
  }
3837
3968
  },
3969
+ flags: {},
3838
3970
  name: "Rivalry",
3839
3971
  rating: 0,
3840
3972
  num: 79,
3841
3973
  },
3842
3974
  rkssystem: {
3843
3975
  // RKS System's type-changing itself is implemented in statuses.js
3844
- isPermanent: true,
3976
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1 },
3845
3977
  name: "RKS System",
3846
3978
  rating: 4,
3847
3979
  num: 225,
@@ -3855,6 +3987,7 @@ export const Abilities = {
3855
3987
  return null;
3856
3988
  }
3857
3989
  },
3990
+ flags: {},
3858
3991
  name: "Rock Head",
3859
3992
  rating: 3,
3860
3993
  num: 69,
@@ -3874,6 +4007,7 @@ export const Abilities = {
3874
4007
  return this.chainModify(1.5);
3875
4008
  }
3876
4009
  },
4010
+ flags: {},
3877
4011
  name: "Rocky Payload",
3878
4012
  rating: 3.5,
3879
4013
  num: 276,
@@ -3885,11 +4019,13 @@ export const Abilities = {
3885
4019
  this.damage(source.baseMaxhp / 8, source, target);
3886
4020
  }
3887
4021
  },
4022
+ flags: {},
3888
4023
  name: "Rough Skin",
3889
4024
  rating: 2.5,
3890
4025
  num: 24,
3891
4026
  },
3892
4027
  runaway: {
4028
+ flags: {},
3893
4029
  name: "Run Away",
3894
4030
  rating: 0,
3895
4031
  num: 50,
@@ -3908,6 +4044,7 @@ export const Abilities = {
3908
4044
  if (type === 'sandstorm')
3909
4045
  return false;
3910
4046
  },
4047
+ flags: {},
3911
4048
  name: "Sand Force",
3912
4049
  rating: 2,
3913
4050
  num: 159,
@@ -3922,6 +4059,7 @@ export const Abilities = {
3922
4059
  if (type === 'sandstorm')
3923
4060
  return false;
3924
4061
  },
4062
+ flags: {},
3925
4063
  name: "Sand Rush",
3926
4064
  rating: 3,
3927
4065
  num: 146,
@@ -3930,6 +4068,7 @@ export const Abilities = {
3930
4068
  onDamagingHit(damage, target, source, move) {
3931
4069
  this.field.setWeather('sandstorm');
3932
4070
  },
4071
+ flags: {},
3933
4072
  name: "Sand Spit",
3934
4073
  rating: 1,
3935
4074
  num: 245,
@@ -3938,6 +4077,7 @@ export const Abilities = {
3938
4077
  onStart(source) {
3939
4078
  this.field.setWeather('sandstorm');
3940
4079
  },
4080
+ flags: {},
3941
4081
  name: "Sand Stream",
3942
4082
  rating: 4,
3943
4083
  num: 45,
@@ -3956,7 +4096,7 @@ export const Abilities = {
3956
4096
  return this.chainModify([3277, 4096]);
3957
4097
  }
3958
4098
  },
3959
- isBreakable: true,
4099
+ flags: { breakable: 1 },
3960
4100
  name: "Sand Veil",
3961
4101
  rating: 1.5,
3962
4102
  num: 8,
@@ -3978,7 +4118,7 @@ export const Abilities = {
3978
4118
  this.boost({ atk: 1 }, this.effectState.target);
3979
4119
  }
3980
4120
  },
3981
- isBreakable: true,
4121
+ flags: { breakable: 1 },
3982
4122
  name: "Sap Sipper",
3983
4123
  rating: 3,
3984
4124
  num: 157,
@@ -4014,7 +4154,7 @@ export const Abilities = {
4014
4154
  }
4015
4155
  }
4016
4156
  },
4017
- isPermanent: true,
4157
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1 },
4018
4158
  name: "Schooling",
4019
4159
  rating: 3,
4020
4160
  num: 208,
@@ -4035,6 +4175,7 @@ export const Abilities = {
4035
4175
  this.add('-fail', target, 'unboost', 'Attack', '[from] ability: Scrappy', '[of] ' + target);
4036
4176
  }
4037
4177
  },
4178
+ flags: {},
4038
4179
  name: "Scrappy",
4039
4180
  rating: 3,
4040
4181
  num: 113,
@@ -4054,6 +4195,7 @@ export const Abilities = {
4054
4195
  }
4055
4196
  }
4056
4197
  },
4198
+ flags: {},
4057
4199
  name: "Screen Cleaner",
4058
4200
  rating: 2,
4059
4201
  num: 251,
@@ -4062,6 +4204,7 @@ export const Abilities = {
4062
4204
  onDamagingHit(damage, target, source, move) {
4063
4205
  this.field.setTerrain('grassyterrain');
4064
4206
  },
4207
+ flags: {},
4065
4208
  name: "Seed Sower",
4066
4209
  rating: 2.5,
4067
4210
  num: 269,
@@ -4079,6 +4222,7 @@ export const Abilities = {
4079
4222
  if (move.self?.chance)
4080
4223
  move.self.chance *= 2;
4081
4224
  },
4225
+ flags: {},
4082
4226
  name: "Serene Grace",
4083
4227
  rating: 3.5,
4084
4228
  num: 32,
@@ -4090,6 +4234,7 @@ export const Abilities = {
4090
4234
  return this.chainModify(0.5);
4091
4235
  }
4092
4236
  },
4237
+ flags: {},
4093
4238
  name: "Shadow Shield",
4094
4239
  rating: 3.5,
4095
4240
  num: 231,
@@ -4109,6 +4254,7 @@ export const Abilities = {
4109
4254
  pokemon.maybeTrapped = true;
4110
4255
  }
4111
4256
  },
4257
+ flags: {},
4112
4258
  name: "Shadow Tag",
4113
4259
  rating: 5,
4114
4260
  num: 23,
@@ -4121,6 +4267,7 @@ export const Abilities = {
4121
4267
  return this.chainModify(1.5);
4122
4268
  }
4123
4269
  },
4270
+ flags: {},
4124
4271
  name: "Sharpness",
4125
4272
  rating: 3.5,
4126
4273
  num: 292,
@@ -4135,6 +4282,7 @@ export const Abilities = {
4135
4282
  pokemon.cureStatus();
4136
4283
  }
4137
4284
  },
4285
+ flags: {},
4138
4286
  name: "Shed Skin",
4139
4287
  rating: 3,
4140
4288
  num: 61,
@@ -4156,13 +4304,14 @@ export const Abilities = {
4156
4304
  if (move.hasSheerForce)
4157
4305
  return this.chainModify([5325, 4096]);
4158
4306
  },
4307
+ flags: {},
4159
4308
  name: "Sheer Force",
4160
4309
  rating: 3.5,
4161
4310
  num: 125,
4162
4311
  },
4163
4312
  shellarmor: {
4164
4313
  onCriticalHit: false,
4165
- isBreakable: true,
4314
+ flags: { breakable: 1 },
4166
4315
  name: "Shell Armor",
4167
4316
  rating: 1,
4168
4317
  num: 75,
@@ -4172,7 +4321,7 @@ export const Abilities = {
4172
4321
  this.debug('Shield Dust prevent secondary');
4173
4322
  return secondaries.filter(effect => !!(effect.self || effect.dustproof));
4174
4323
  },
4175
- isBreakable: true,
4324
+ flags: { breakable: 1 },
4176
4325
  name: "Shield Dust",
4177
4326
  rating: 2,
4178
4327
  num: 19,
@@ -4223,7 +4372,7 @@ export const Abilities = {
4223
4372
  this.add('-immune', target, '[from] ability: Shields Down');
4224
4373
  return null;
4225
4374
  },
4226
- isPermanent: true,
4375
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1 },
4227
4376
  name: "Shields Down",
4228
4377
  rating: 3,
4229
4378
  num: 197,
@@ -4237,7 +4386,7 @@ export const Abilities = {
4237
4386
  boost[i] *= 2;
4238
4387
  }
4239
4388
  },
4240
- isBreakable: true,
4389
+ flags: { breakable: 1 },
4241
4390
  name: "Simple",
4242
4391
  rating: 4,
4243
4392
  num: 86,
@@ -4251,6 +4400,7 @@ export const Abilities = {
4251
4400
  delete move.multiaccuracy;
4252
4401
  }
4253
4402
  },
4403
+ flags: {},
4254
4404
  name: "Skill Link",
4255
4405
  rating: 3,
4256
4406
  num: 92,
@@ -4281,6 +4431,7 @@ export const Abilities = {
4281
4431
  this.add('-end', target, 'Slow Start');
4282
4432
  },
4283
4433
  },
4434
+ flags: {},
4284
4435
  name: "Slow Start",
4285
4436
  rating: -1,
4286
4437
  num: 112,
@@ -4291,6 +4442,7 @@ export const Abilities = {
4291
4442
  return this.chainModify(2);
4292
4443
  }
4293
4444
  },
4445
+ flags: {},
4294
4446
  name: "Slush Rush",
4295
4447
  rating: 3,
4296
4448
  num: 202,
@@ -4302,6 +4454,7 @@ export const Abilities = {
4302
4454
  return this.chainModify(1.5);
4303
4455
  }
4304
4456
  },
4457
+ flags: {},
4305
4458
  name: "Sniper",
4306
4459
  rating: 2,
4307
4460
  num: 97,
@@ -4320,7 +4473,7 @@ export const Abilities = {
4320
4473
  return this.chainModify([3277, 4096]);
4321
4474
  }
4322
4475
  },
4323
- isBreakable: true,
4476
+ flags: { breakable: 1 },
4324
4477
  name: "Snow Cloak",
4325
4478
  rating: 1.5,
4326
4479
  num: 81,
@@ -4329,6 +4482,7 @@ export const Abilities = {
4329
4482
  onStart(source) {
4330
4483
  this.field.setWeather('snow');
4331
4484
  },
4485
+ flags: {},
4332
4486
  name: "Snow Warning",
4333
4487
  rating: 4,
4334
4488
  num: 117,
@@ -4347,6 +4501,7 @@ export const Abilities = {
4347
4501
  this.damage(target.baseMaxhp / 8, target, target);
4348
4502
  }
4349
4503
  },
4504
+ flags: {},
4350
4505
  name: "Solar Power",
4351
4506
  rating: 2,
4352
4507
  num: 94,
@@ -4358,7 +4513,7 @@ export const Abilities = {
4358
4513
  return this.chainModify(0.75);
4359
4514
  }
4360
4515
  },
4361
- isBreakable: true,
4516
+ flags: { breakable: 1 },
4362
4517
  name: "Solid Rock",
4363
4518
  rating: 3,
4364
4519
  num: 116,
@@ -4368,6 +4523,7 @@ export const Abilities = {
4368
4523
  onAnyFaint() {
4369
4524
  this.boost({ spa: 1 }, this.effectState.target);
4370
4525
  },
4526
+ flags: {},
4371
4527
  name: "Soul-Heart",
4372
4528
  rating: 3.5,
4373
4529
  num: 220,
@@ -4384,7 +4540,7 @@ export const Abilities = {
4384
4540
  this.add('-immune', this.effectState.target, '[from] ability: Soundproof');
4385
4541
  }
4386
4542
  },
4387
- isBreakable: true,
4543
+ flags: { breakable: 1 },
4388
4544
  name: "Soundproof",
4389
4545
  rating: 2,
4390
4546
  num: 43,
@@ -4397,6 +4553,7 @@ export const Abilities = {
4397
4553
  this.boost({ spe: 1 });
4398
4554
  }
4399
4555
  },
4556
+ flags: {},
4400
4557
  name: "Speed Boost",
4401
4558
  rating: 4.5,
4402
4559
  num: 3,
@@ -4416,12 +4573,14 @@ export const Abilities = {
4416
4573
  return this.chainModify(2);
4417
4574
  }
4418
4575
  },
4576
+ flags: {},
4419
4577
  name: "Stakeout",
4420
4578
  rating: 4.5,
4421
4579
  num: 198,
4422
4580
  },
4423
4581
  stall: {
4424
4582
  onFractionalPriority: -0.1,
4583
+ flags: {},
4425
4584
  name: "Stall",
4426
4585
  rating: -1,
4427
4586
  num: 100,
@@ -4432,6 +4591,7 @@ export const Abilities = {
4432
4591
  // most of the implementation is in Battle#getTarget
4433
4592
  move.tracksTarget = move.target !== 'scripted';
4434
4593
  },
4594
+ flags: {},
4435
4595
  name: "Stalwart",
4436
4596
  rating: 0,
4437
4597
  num: 242,
@@ -4440,6 +4600,7 @@ export const Abilities = {
4440
4600
  onDamagingHit(damage, target, source, effect) {
4441
4601
  this.boost({ def: 1 });
4442
4602
  },
4603
+ flags: {},
4443
4604
  name: "Stamina",
4444
4605
  rating: 4,
4445
4606
  num: 192,
@@ -4455,7 +4616,7 @@ export const Abilities = {
4455
4616
  if (attacker.species.name !== targetForme)
4456
4617
  attacker.formeChange(targetForme);
4457
4618
  },
4458
- isPermanent: true,
4619
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1 },
4459
4620
  name: "Stance Change",
4460
4621
  rating: 4,
4461
4622
  num: 176,
@@ -4468,6 +4629,7 @@ export const Abilities = {
4468
4629
  }
4469
4630
  }
4470
4631
  },
4632
+ flags: {},
4471
4633
  name: "Static",
4472
4634
  rating: 2,
4473
4635
  num: 9,
@@ -4476,6 +4638,7 @@ export const Abilities = {
4476
4638
  onFlinch(pokemon) {
4477
4639
  this.boost({ spe: 1 });
4478
4640
  },
4641
+ flags: {},
4479
4642
  name: "Steadfast",
4480
4643
  rating: 1,
4481
4644
  num: 80,
@@ -4486,6 +4649,7 @@ export const Abilities = {
4486
4649
  this.boost({ spe: 6 });
4487
4650
  }
4488
4651
  },
4652
+ flags: {},
4489
4653
  name: "Steam Engine",
4490
4654
  rating: 2,
4491
4655
  num: 243,
@@ -4505,6 +4669,7 @@ export const Abilities = {
4505
4669
  return this.chainModify(1.5);
4506
4670
  }
4507
4671
  },
4672
+ flags: {},
4508
4673
  name: "Steelworker",
4509
4674
  rating: 3.5,
4510
4675
  num: 200,
@@ -4517,6 +4682,7 @@ export const Abilities = {
4517
4682
  return this.chainModify(1.5);
4518
4683
  }
4519
4684
  },
4685
+ flags: {},
4520
4686
  name: "Steely Spirit",
4521
4687
  rating: 3.5,
4522
4688
  num: 252,
@@ -4538,6 +4704,7 @@ export const Abilities = {
4538
4704
  });
4539
4705
  }
4540
4706
  },
4707
+ flags: {},
4541
4708
  name: "Stench",
4542
4709
  rating: 0.5,
4543
4710
  num: 1,
@@ -4553,7 +4720,7 @@ export const Abilities = {
4553
4720
  return false;
4554
4721
  }
4555
4722
  },
4556
- isBreakable: true,
4723
+ flags: { breakable: 1 },
4557
4724
  name: "Sticky Hold",
4558
4725
  rating: 1.5,
4559
4726
  num: 60,
@@ -4580,7 +4747,7 @@ export const Abilities = {
4580
4747
  return this.effectState.target;
4581
4748
  }
4582
4749
  },
4583
- isBreakable: true,
4750
+ flags: { breakable: 1 },
4584
4751
  name: "Storm Drain",
4585
4752
  rating: 3,
4586
4753
  num: 114,
@@ -4592,6 +4759,7 @@ export const Abilities = {
4592
4759
  return this.chainModify(1.5);
4593
4760
  }
4594
4761
  },
4762
+ flags: {},
4595
4763
  name: "Strong Jaw",
4596
4764
  rating: 3.5,
4597
4765
  num: 173,
@@ -4610,7 +4778,7 @@ export const Abilities = {
4610
4778
  return target.hp - 1;
4611
4779
  }
4612
4780
  },
4613
- isBreakable: true,
4781
+ flags: { breakable: 1 },
4614
4782
  name: "Sturdy",
4615
4783
  rating: 3,
4616
4784
  num: 5,
@@ -4621,7 +4789,7 @@ export const Abilities = {
4621
4789
  this.add('-activate', pokemon, 'ability: Suction Cups');
4622
4790
  return null;
4623
4791
  },
4624
- isBreakable: true,
4792
+ flags: { breakable: 1 },
4625
4793
  name: "Suction Cups",
4626
4794
  rating: 1,
4627
4795
  num: 21,
@@ -4630,6 +4798,7 @@ export const Abilities = {
4630
4798
  onModifyCritRatio(critRatio) {
4631
4799
  return critRatio + 1;
4632
4800
  },
4801
+ flags: {},
4633
4802
  name: "Super Luck",
4634
4803
  rating: 1.5,
4635
4804
  num: 105,
@@ -4654,6 +4823,7 @@ export const Abilities = {
4654
4823
  }
4655
4824
  }
4656
4825
  },
4826
+ flags: {},
4657
4827
  name: "Supersweet Syrup",
4658
4828
  rating: 1.5,
4659
4829
  num: 306,
@@ -4678,6 +4848,7 @@ export const Abilities = {
4678
4848
  return this.chainModify([powMod[this.effectState.fallen], 4096]);
4679
4849
  }
4680
4850
  },
4851
+ flags: {},
4681
4852
  name: "Supreme Overlord",
4682
4853
  rating: 4,
4683
4854
  num: 293,
@@ -4688,6 +4859,7 @@ export const Abilities = {
4688
4859
  return this.chainModify(2);
4689
4860
  }
4690
4861
  },
4862
+ flags: {},
4691
4863
  name: "Surge Surfer",
4692
4864
  rating: 3,
4693
4865
  num: 207,
@@ -4707,12 +4879,12 @@ export const Abilities = {
4707
4879
  return this.chainModify(1.5);
4708
4880
  }
4709
4881
  },
4882
+ flags: {},
4710
4883
  name: "Swarm",
4711
4884
  rating: 2,
4712
4885
  num: 68,
4713
4886
  },
4714
4887
  sweetveil: {
4715
- name: "Sweet Veil",
4716
4888
  onAllySetStatus(status, target, source, effect) {
4717
4889
  if (status.id === 'slp') {
4718
4890
  this.debug('Sweet Veil interrupts sleep');
@@ -4729,7 +4901,8 @@ export const Abilities = {
4729
4901
  return null;
4730
4902
  }
4731
4903
  },
4732
- isBreakable: true,
4904
+ flags: { breakable: 1 },
4905
+ name: "Sweet Veil",
4733
4906
  rating: 2,
4734
4907
  num: 175,
4735
4908
  },
@@ -4739,6 +4912,7 @@ export const Abilities = {
4739
4912
  return this.chainModify(2);
4740
4913
  }
4741
4914
  },
4915
+ flags: {},
4742
4916
  name: "Swift Swim",
4743
4917
  rating: 3,
4744
4918
  num: 33,
@@ -4758,6 +4932,7 @@ export const Abilities = {
4758
4932
  }
4759
4933
  this.add('-activate', source, 'ability: Symbiosis', myItem, '[of] ' + pokemon);
4760
4934
  },
4935
+ flags: {},
4761
4936
  name: "Symbiosis",
4762
4937
  rating: 0,
4763
4938
  num: 180,
@@ -4775,6 +4950,7 @@ export const Abilities = {
4775
4950
  // and show messages when activating against it.
4776
4951
  source.trySetStatus(status, target, { status: status.id, id: 'synchronize' });
4777
4952
  },
4953
+ flags: {},
4778
4954
  name: "Synchronize",
4779
4955
  rating: 2,
4780
4956
  num: 28,
@@ -4796,6 +4972,7 @@ export const Abilities = {
4796
4972
  this.debug('Sword of Ruin Def drop');
4797
4973
  return this.chainModify(0.75);
4798
4974
  },
4975
+ flags: {},
4799
4976
  name: "Sword of Ruin",
4800
4977
  rating: 4.5,
4801
4978
  num: 285,
@@ -4817,6 +4994,7 @@ export const Abilities = {
4817
4994
  this.debug('Tablets of Ruin Atk drop');
4818
4995
  return this.chainModify(0.75);
4819
4996
  },
4997
+ flags: {},
4820
4998
  name: "Tablets of Ruin",
4821
4999
  rating: 4.5,
4822
5000
  num: 284,
@@ -4831,7 +5009,7 @@ export const Abilities = {
4831
5009
  return this.chainModify(0.5);
4832
5010
  }
4833
5011
  },
4834
- isBreakable: true,
5012
+ flags: { breakable: 1 },
4835
5013
  name: "Tangled Feet",
4836
5014
  rating: 1,
4837
5015
  num: 77,
@@ -4843,6 +5021,7 @@ export const Abilities = {
4843
5021
  this.boost({ spe: -1 }, source, target, null, true);
4844
5022
  }
4845
5023
  },
5024
+ flags: {},
4846
5025
  name: "Tangling Hair",
4847
5026
  rating: 2,
4848
5027
  num: 221,
@@ -4857,6 +5036,7 @@ export const Abilities = {
4857
5036
  return this.chainModify(1.5);
4858
5037
  }
4859
5038
  },
5039
+ flags: {},
4860
5040
  name: "Technician",
4861
5041
  rating: 3.5,
4862
5042
  num: 101,
@@ -4868,7 +5048,7 @@ export const Abilities = {
4868
5048
  return null;
4869
5049
  }
4870
5050
  },
4871
- isBreakable: true,
5051
+ flags: { breakable: 1 },
4872
5052
  name: "Telepathy",
4873
5053
  rating: 0,
4874
5054
  num: 140,
@@ -4883,13 +5063,14 @@ export const Abilities = {
4883
5063
  this.field.clearTerrain();
4884
5064
  }
4885
5065
  },
5066
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1 },
4886
5067
  name: "Teraform Zero",
4887
5068
  rating: 3,
4888
5069
  num: 309,
4889
5070
  },
4890
5071
  terashell: {
4891
5072
  onEffectiveness(typeMod, target, type, move) {
4892
- if (!target || target.species.name !== 'Terapagos-Terastal')
5073
+ if (!target || target.baseSpecies.name !== 'Terapagos-Terastal')
4893
5074
  return;
4894
5075
  if (this.effectState.resisted)
4895
5076
  return -1; // all hits of multi-hit move should be not very effective
@@ -4906,21 +5087,21 @@ export const Abilities = {
4906
5087
  onAnyAfterMove() {
4907
5088
  this.effectState.resisted = false;
4908
5089
  },
4909
- isBreakable: true,
5090
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, breakable: 1 },
4910
5091
  name: "Tera Shell",
4911
5092
  rating: 3.5,
4912
5093
  num: 308,
4913
5094
  },
4914
5095
  terashift: {
4915
5096
  onPreStart(pokemon) {
4916
- if (pokemon.baseSpecies.baseSpecies !== 'Terapagos' || pokemon.transformed)
5097
+ if (pokemon.baseSpecies.baseSpecies !== 'Terapagos')
4917
5098
  return;
4918
5099
  if (pokemon.species.forme !== 'Terastal') {
4919
5100
  this.add('-activate', pokemon, 'ability: Tera Shift');
4920
5101
  pokemon.formeChange('Terapagos-Terastal', this.effect, true);
4921
5102
  }
4922
5103
  },
4923
- isPermanent: true,
5104
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1, notransform: 1 },
4924
5105
  name: "Tera Shift",
4925
5106
  rating: 3,
4926
5107
  num: 307,
@@ -4932,6 +5113,7 @@ export const Abilities = {
4932
5113
  onModifyMove(move) {
4933
5114
  move.ignoreAbility = true;
4934
5115
  },
5116
+ flags: {},
4935
5117
  name: "Teravolt",
4936
5118
  rating: 3,
4937
5119
  num: 164,
@@ -4956,6 +5138,7 @@ export const Abilities = {
4956
5138
  }
4957
5139
  return false;
4958
5140
  },
5141
+ flags: { breakable: 1 },
4959
5142
  name: "Thermal Exchange",
4960
5143
  rating: 2.5,
4961
5144
  num: 270,
@@ -4975,7 +5158,7 @@ export const Abilities = {
4975
5158
  return this.chainModify(0.5);
4976
5159
  }
4977
5160
  },
4978
- isBreakable: true,
5161
+ flags: { breakable: 1 },
4979
5162
  name: "Thick Fat",
4980
5163
  rating: 3.5,
4981
5164
  num: 47,
@@ -4987,6 +5170,7 @@ export const Abilities = {
4987
5170
  return this.chainModify(2);
4988
5171
  }
4989
5172
  },
5173
+ flags: {},
4990
5174
  name: "Tinted Lens",
4991
5175
  rating: 4,
4992
5176
  num: 110,
@@ -5006,6 +5190,7 @@ export const Abilities = {
5006
5190
  return this.chainModify(1.5);
5007
5191
  }
5008
5192
  },
5193
+ flags: {},
5009
5194
  name: "Torrent",
5010
5195
  rating: 2,
5011
5196
  num: 67,
@@ -5017,6 +5202,7 @@ export const Abilities = {
5017
5202
  return this.chainModify([5325, 4096]);
5018
5203
  }
5019
5204
  },
5205
+ flags: {},
5020
5206
  name: "Tough Claws",
5021
5207
  rating: 3.5,
5022
5208
  num: 181,
@@ -5028,6 +5214,7 @@ export const Abilities = {
5028
5214
  return this.chainModify(1.5);
5029
5215
  }
5030
5216
  },
5217
+ flags: {},
5031
5218
  name: "Toxic Boost",
5032
5219
  rating: 3,
5033
5220
  num: 137,
@@ -5041,6 +5228,7 @@ export const Abilities = {
5041
5228
  target.trySetStatus('tox', source);
5042
5229
  }
5043
5230
  },
5231
+ flags: {},
5044
5232
  name: "Toxic Chain",
5045
5233
  rating: 4.5,
5046
5234
  num: 305,
@@ -5054,6 +5242,7 @@ export const Abilities = {
5054
5242
  side.addSideCondition('toxicspikes', target);
5055
5243
  }
5056
5244
  },
5245
+ flags: {},
5057
5246
  name: "Toxic Debris",
5058
5247
  rating: 3.5,
5059
5248
  num: 295,
@@ -5074,11 +5263,7 @@ export const Abilities = {
5074
5263
  onUpdate(pokemon) {
5075
5264
  if (!pokemon.isStarted || this.effectState.gaveUp)
5076
5265
  return;
5077
- const additionalBannedAbilities = [
5078
- // Zen Mode included here for compatability with Gen 5-6
5079
- 'noability', 'commander', 'flowergift', 'forecast', 'hungerswitch', 'illusion', 'imposter', 'neutralizinggas', 'powerofalchemy', 'receiver', 'trace', 'zenmode',
5080
- ];
5081
- const possibleTargets = pokemon.adjacentFoes().filter(target => (!target.getAbility().isPermanent && !additionalBannedAbilities.includes(target.ability)));
5266
+ const possibleTargets = pokemon.adjacentFoes().filter(target => !target.getAbility().flags['notrace'] && target.ability !== 'noability');
5082
5267
  if (!possibleTargets.length)
5083
5268
  return;
5084
5269
  const target = this.sample(possibleTargets);
@@ -5087,6 +5272,7 @@ export const Abilities = {
5087
5272
  this.add('-ability', pokemon, ability, '[from] ability: Trace', '[of] ' + target);
5088
5273
  }
5089
5274
  },
5275
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1 },
5090
5276
  name: "Trace",
5091
5277
  rating: 2.5,
5092
5278
  num: 36,
@@ -5106,6 +5292,7 @@ export const Abilities = {
5106
5292
  return this.chainModify([5325, 4096]);
5107
5293
  }
5108
5294
  },
5295
+ flags: {},
5109
5296
  name: "Transistor",
5110
5297
  rating: 3.5,
5111
5298
  num: 262,
@@ -5115,6 +5302,7 @@ export const Abilities = {
5115
5302
  if (move?.flags['heal'])
5116
5303
  return priority + 3;
5117
5304
  },
5305
+ flags: {},
5118
5306
  name: "Triage",
5119
5307
  rating: 3.5,
5120
5308
  num: 205,
@@ -5135,6 +5323,7 @@ export const Abilities = {
5135
5323
  pokemon.addVolatile('truant');
5136
5324
  },
5137
5325
  condition: {},
5326
+ flags: {},
5138
5327
  name: "Truant",
5139
5328
  rating: -1,
5140
5329
  num: 54,
@@ -5146,12 +5335,12 @@ export const Abilities = {
5146
5335
  onModifyMove(move) {
5147
5336
  move.ignoreAbility = true;
5148
5337
  },
5338
+ flags: {},
5149
5339
  name: "Turboblaze",
5150
5340
  rating: 3,
5151
5341
  num: 163,
5152
5342
  },
5153
5343
  unaware: {
5154
- name: "Unaware",
5155
5344
  onAnyModifyBoost(boosts, pokemon) {
5156
5345
  const unawareUser = this.effectState.target;
5157
5346
  if (unawareUser === pokemon)
@@ -5168,7 +5357,8 @@ export const Abilities = {
5168
5357
  boosts['accuracy'] = 0;
5169
5358
  }
5170
5359
  },
5171
- isBreakable: true,
5360
+ flags: { breakable: 1 },
5361
+ name: "Unaware",
5172
5362
  rating: 4,
5173
5363
  num: 109,
5174
5364
  },
@@ -5191,6 +5381,7 @@ export const Abilities = {
5191
5381
  }
5192
5382
  },
5193
5383
  },
5384
+ flags: {},
5194
5385
  name: "Unburden",
5195
5386
  rating: 3.5,
5196
5387
  num: 84,
@@ -5212,6 +5403,7 @@ export const Abilities = {
5212
5403
  onFoeTryEatItem() {
5213
5404
  return !this.effectState.unnerved;
5214
5405
  },
5406
+ flags: {},
5215
5407
  name: "Unnerve",
5216
5408
  rating: 1,
5217
5409
  num: 127,
@@ -5221,6 +5413,7 @@ export const Abilities = {
5221
5413
  if (move.flags['contact'])
5222
5414
  delete move.flags['protect'];
5223
5415
  },
5416
+ flags: {},
5224
5417
  name: "Unseen Fist",
5225
5418
  rating: 2,
5226
5419
  num: 260,
@@ -5242,6 +5435,7 @@ export const Abilities = {
5242
5435
  this.debug('Vessel of Ruin SpA drop');
5243
5436
  return this.chainModify(0.75);
5244
5437
  },
5438
+ flags: {},
5245
5439
  name: "Vessel of Ruin",
5246
5440
  rating: 4.5,
5247
5441
  num: 284,
@@ -5253,6 +5447,7 @@ export const Abilities = {
5253
5447
  return this.chainModify([4506, 4096]);
5254
5448
  }
5255
5449
  },
5450
+ flags: {},
5256
5451
  name: "Victory Star",
5257
5452
  rating: 2,
5258
5453
  num: 162,
@@ -5278,7 +5473,7 @@ export const Abilities = {
5278
5473
  return null;
5279
5474
  }
5280
5475
  },
5281
- isBreakable: true,
5476
+ flags: { breakable: 1 },
5282
5477
  name: "Vital Spirit",
5283
5478
  rating: 1.5,
5284
5479
  num: 72,
@@ -5292,18 +5487,15 @@ export const Abilities = {
5292
5487
  return null;
5293
5488
  }
5294
5489
  },
5295
- isBreakable: true,
5490
+ flags: { breakable: 1 },
5296
5491
  name: "Volt Absorb",
5297
5492
  rating: 3.5,
5298
5493
  num: 10,
5299
5494
  },
5300
5495
  wanderingspirit: {
5301
5496
  onDamagingHit(damage, target, source, move) {
5302
- const additionalBannedAbilities = ['commander', 'hungerswitch', 'illusion', 'neutralizinggas', 'wonderguard'];
5303
- if (source.getAbility().isPermanent || additionalBannedAbilities.includes(source.ability) ||
5304
- target.volatiles['dynamax']) {
5497
+ if (source.getAbility().flags['failskillswap'] || target.volatiles['dynamax'])
5305
5498
  return;
5306
- }
5307
5499
  if (this.checkMoveMakesContact(move, source, target)) {
5308
5500
  const targetCanBeSet = this.runEvent('SetAbility', target, source, this.effect, source.ability);
5309
5501
  if (!targetCanBeSet)
@@ -5320,6 +5512,7 @@ export const Abilities = {
5320
5512
  target.setAbility(sourceAbility);
5321
5513
  }
5322
5514
  },
5515
+ flags: {},
5323
5516
  name: "Wandering Spirit",
5324
5517
  rating: 2.5,
5325
5518
  num: 254,
@@ -5333,7 +5526,7 @@ export const Abilities = {
5333
5526
  return null;
5334
5527
  }
5335
5528
  },
5336
- isBreakable: true,
5529
+ flags: { breakable: 1 },
5337
5530
  name: "Water Absorb",
5338
5531
  rating: 3.5,
5339
5532
  num: 11,
@@ -5375,7 +5568,7 @@ export const Abilities = {
5375
5568
  }
5376
5569
  return false;
5377
5570
  },
5378
- isBreakable: true,
5571
+ flags: { breakable: 1 },
5379
5572
  name: "Water Bubble",
5380
5573
  rating: 4.5,
5381
5574
  num: 199,
@@ -5386,6 +5579,7 @@ export const Abilities = {
5386
5579
  this.boost({ def: 2 });
5387
5580
  }
5388
5581
  },
5582
+ flags: {},
5389
5583
  name: "Water Compaction",
5390
5584
  rating: 1.5,
5391
5585
  num: 195,
@@ -5405,7 +5599,7 @@ export const Abilities = {
5405
5599
  }
5406
5600
  return false;
5407
5601
  },
5408
- isBreakable: true,
5602
+ flags: { breakable: 1 },
5409
5603
  name: "Water Veil",
5410
5604
  rating: 2,
5411
5605
  num: 41,
@@ -5416,6 +5610,7 @@ export const Abilities = {
5416
5610
  this.boost({ def: -1, spe: 2 }, target, target);
5417
5611
  }
5418
5612
  },
5613
+ flags: {},
5419
5614
  name: "Weak Armor",
5420
5615
  rating: 1,
5421
5616
  num: 133,
@@ -5429,7 +5624,7 @@ export const Abilities = {
5429
5624
  return null;
5430
5625
  }
5431
5626
  },
5432
- isBreakable: true,
5627
+ flags: { breakable: 1 },
5433
5628
  name: "Well-Baked Body",
5434
5629
  rating: 3.5,
5435
5630
  num: 273,
@@ -5450,7 +5645,7 @@ export const Abilities = {
5450
5645
  this.add("-fail", target, "unboost", "[from] ability: White Smoke", "[of] " + target);
5451
5646
  }
5452
5647
  },
5453
- isBreakable: true,
5648
+ flags: { breakable: 1 },
5454
5649
  name: "White Smoke",
5455
5650
  rating: 2,
5456
5651
  num: 73,
@@ -5467,6 +5662,7 @@ export const Abilities = {
5467
5662
  target.switchFlag = true;
5468
5663
  this.add('-activate', target, 'ability: Wimp Out');
5469
5664
  },
5665
+ flags: {},
5470
5666
  name: "Wimp Out",
5471
5667
  rating: 1,
5472
5668
  num: 193,
@@ -5484,6 +5680,7 @@ export const Abilities = {
5484
5680
  pokemon.addVolatile('charge');
5485
5681
  }
5486
5682
  },
5683
+ flags: {},
5487
5684
  name: "Wind Power",
5488
5685
  rating: 1,
5489
5686
  num: 277,
@@ -5508,7 +5705,7 @@ export const Abilities = {
5508
5705
  this.boost({ atk: 1 }, pokemon, pokemon);
5509
5706
  }
5510
5707
  },
5511
- isBreakable: true,
5708
+ flags: { breakable: 1 },
5512
5709
  name: "Wind Rider",
5513
5710
  rating: 3.5,
5514
5711
  // We do not want Brambleghast to get Infiltrator in Randbats
@@ -5531,7 +5728,7 @@ export const Abilities = {
5531
5728
  return null;
5532
5729
  }
5533
5730
  },
5534
- isBreakable: true,
5731
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, failskillswap: 1, breakable: 1 },
5535
5732
  name: "Wonder Guard",
5536
5733
  rating: 5,
5537
5734
  num: 25,
@@ -5544,7 +5741,7 @@ export const Abilities = {
5544
5741
  return 50;
5545
5742
  }
5546
5743
  },
5547
- isBreakable: true,
5744
+ flags: { breakable: 1 },
5548
5745
  name: "Wonder Skin",
5549
5746
  rating: 2,
5550
5747
  num: 147,
@@ -5589,14 +5786,14 @@ export const Abilities = {
5589
5786
  }
5590
5787
  },
5591
5788
  },
5592
- isPermanent: true,
5789
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1 },
5593
5790
  name: "Zen Mode",
5594
5791
  rating: 0,
5595
5792
  num: 161,
5596
5793
  },
5597
5794
  zerotohero: {
5598
5795
  onSwitchOut(pokemon) {
5599
- if (pokemon.baseSpecies.baseSpecies !== 'Palafin' || pokemon.transformed)
5796
+ if (pokemon.baseSpecies.baseSpecies !== 'Palafin')
5600
5797
  return;
5601
5798
  if (pokemon.species.forme !== 'Hero') {
5602
5799
  pokemon.formeChange('Palafin-Hero', this.effect, true);
@@ -5609,14 +5806,14 @@ export const Abilities = {
5609
5806
  if (!this.effectState.switchingIn)
5610
5807
  return;
5611
5808
  this.effectState.switchingIn = false;
5612
- if (pokemon.baseSpecies.baseSpecies !== 'Palafin' || pokemon.transformed)
5809
+ if (pokemon.baseSpecies.baseSpecies !== 'Palafin')
5613
5810
  return;
5614
5811
  if (!this.effectState.heroMessageDisplayed && pokemon.species.forme === 'Hero') {
5615
5812
  this.add('-activate', pokemon, 'ability: Zero to Hero');
5616
5813
  this.effectState.heroMessageDisplayed = true;
5617
5814
  }
5618
5815
  },
5619
- isPermanent: true,
5816
+ flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1, notransform: 1 },
5620
5817
  name: "Zero to Hero",
5621
5818
  rating: 5,
5622
5819
  num: 278,
@@ -5635,14 +5832,13 @@ export const Abilities = {
5635
5832
  }
5636
5833
  },
5637
5834
  isNonstandard: "CAP",
5638
- isBreakable: true,
5835
+ flags: { breakable: 1 },
5639
5836
  name: "Mountaineer",
5640
5837
  rating: 3,
5641
5838
  num: -2,
5642
5839
  },
5643
5840
  rebound: {
5644
5841
  isNonstandard: "CAP",
5645
- name: "Rebound",
5646
5842
  onTryHitPriority: 1,
5647
5843
  onTryHit(target, source, move) {
5648
5844
  if (this.effectState.target.activeTurns)
@@ -5669,14 +5865,16 @@ export const Abilities = {
5669
5865
  condition: {
5670
5866
  duration: 1,
5671
5867
  },
5672
- isBreakable: true,
5868
+ flags: { breakable: 1 },
5869
+ name: "Rebound",
5673
5870
  rating: 3,
5674
5871
  num: -3,
5675
5872
  },
5676
5873
  persistent: {
5677
5874
  isNonstandard: "CAP",
5678
- name: "Persistent",
5679
5875
  // implemented in the corresponding move
5876
+ flags: {},
5877
+ name: "Persistent",
5680
5878
  rating: 3,
5681
5879
  num: -4,
5682
5880
  },