@pkmn/sim 0.7.16 → 0.7.18

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 (151) hide show
  1. package/build/cjs/config/formats.js +65 -107
  2. package/build/cjs/config/formats.js.map +1 -1
  3. package/build/cjs/data/abilities.js +72 -75
  4. package/build/cjs/data/abilities.js.map +1 -1
  5. package/build/cjs/data/aliases.js +3 -0
  6. package/build/cjs/data/aliases.js.map +1 -1
  7. package/build/cjs/data/formats-data.js +7 -7
  8. package/build/cjs/data/formats-data.js.map +1 -1
  9. package/build/cjs/data/items.js +23 -25
  10. package/build/cjs/data/items.js.map +1 -1
  11. package/build/cjs/data/learnsets.js +3 -3
  12. package/build/cjs/data/learnsets.js.map +1 -1
  13. package/build/cjs/data/legality.js +338 -0
  14. package/build/cjs/data/legality.js.map +1 -1
  15. package/build/cjs/data/mods/gen1/conditions.js +15 -13
  16. package/build/cjs/data/mods/gen1/conditions.js.map +1 -1
  17. package/build/cjs/data/mods/gen1/moves.js +10 -2
  18. package/build/cjs/data/mods/gen1/moves.js.map +1 -1
  19. package/build/cjs/data/mods/gen1/scripts.js +40 -14
  20. package/build/cjs/data/mods/gen1/scripts.js.map +1 -1
  21. package/build/cjs/data/mods/gen2/formats-data.js +2 -2
  22. package/build/cjs/data/mods/gen2/formats-data.js.map +1 -1
  23. package/build/cjs/data/mods/gen2/moves.js +1 -1
  24. package/build/cjs/data/mods/gen2/moves.js.map +1 -1
  25. package/build/cjs/data/mods/gen4/moves.js +1 -1
  26. package/build/cjs/data/mods/gen4/moves.js.map +1 -1
  27. package/build/cjs/data/mods/gen5/formats-data.js +2 -2
  28. package/build/cjs/data/mods/gen5/formats-data.js.map +1 -1
  29. package/build/cjs/data/mods/gen6/formats-data.js +6 -6
  30. package/build/cjs/data/mods/gen6/formats-data.js.map +1 -1
  31. package/build/cjs/data/mods/gen7/abilities.js +4 -4
  32. package/build/cjs/data/mods/gen7/abilities.js.map +1 -1
  33. package/build/cjs/data/mods/gen7/formats-data.js +1 -1
  34. package/build/cjs/data/mods/gen7/formats-data.js.map +1 -1
  35. package/build/cjs/data/mods/gen8/moves.js +24 -0
  36. package/build/cjs/data/mods/gen8/moves.js.map +1 -1
  37. package/build/cjs/data/moves.js +12 -18
  38. package/build/cjs/data/moves.js.map +1 -1
  39. package/build/cjs/data/pokedex.js +26 -26
  40. package/build/cjs/data/pokedex.js.map +1 -1
  41. package/build/cjs/data/rulesets.js +0 -28
  42. package/build/cjs/data/rulesets.js.map +1 -1
  43. package/build/cjs/data/text/abilities.js +5 -5
  44. package/build/cjs/data/text/abilities.js.map +1 -1
  45. package/build/cjs/data/text/default.js +1 -1
  46. package/build/cjs/data/text/default.js.map +1 -1
  47. package/build/cjs/data/text/moves.js +79 -30
  48. package/build/cjs/data/text/moves.js.map +1 -1
  49. package/build/cjs/sim/battle-actions.js +5 -0
  50. package/build/cjs/sim/battle-actions.js.map +1 -1
  51. package/build/cjs/sim/battle.js +9 -2
  52. package/build/cjs/sim/battle.js.map +1 -1
  53. package/build/cjs/sim/dex-conditions.js.map +1 -1
  54. package/build/cjs/sim/dex.js +0 -1
  55. package/build/cjs/sim/dex.js.map +1 -1
  56. package/build/cjs/sim/pokemon.js +16 -9
  57. package/build/cjs/sim/pokemon.js.map +1 -1
  58. package/build/cjs/sim/team-validator.js +1 -1
  59. package/build/cjs/sim/team-validator.js.map +1 -1
  60. package/build/esm/config/formats.mjs +65 -107
  61. package/build/esm/config/formats.mjs.map +1 -1
  62. package/build/esm/data/abilities.mjs +72 -75
  63. package/build/esm/data/abilities.mjs.map +1 -1
  64. package/build/esm/data/aliases.mjs +3 -0
  65. package/build/esm/data/aliases.mjs.map +1 -1
  66. package/build/esm/data/formats-data.mjs +7 -7
  67. package/build/esm/data/formats-data.mjs.map +1 -1
  68. package/build/esm/data/index.mjs +11 -11
  69. package/build/esm/data/items.mjs +23 -25
  70. package/build/esm/data/items.mjs.map +1 -1
  71. package/build/esm/data/learnsets.mjs +3 -3
  72. package/build/esm/data/learnsets.mjs.map +1 -1
  73. package/build/esm/data/legality.mjs +338 -0
  74. package/build/esm/data/legality.mjs.map +1 -1
  75. package/build/esm/data/mods/gen1/conditions.mjs +15 -13
  76. package/build/esm/data/mods/gen1/conditions.mjs.map +1 -1
  77. package/build/esm/data/mods/gen1/index.mjs +7 -7
  78. package/build/esm/data/mods/gen1/moves.mjs +10 -2
  79. package/build/esm/data/mods/gen1/moves.mjs.map +1 -1
  80. package/build/esm/data/mods/gen1/scripts.mjs +40 -14
  81. package/build/esm/data/mods/gen1/scripts.mjs.map +1 -1
  82. package/build/esm/data/mods/gen2/formats-data.mjs +2 -2
  83. package/build/esm/data/mods/gen2/formats-data.mjs.map +1 -1
  84. package/build/esm/data/mods/gen2/index.mjs +8 -8
  85. package/build/esm/data/mods/gen2/moves.mjs +1 -1
  86. package/build/esm/data/mods/gen2/moves.mjs.map +1 -1
  87. package/build/esm/data/mods/gen3/index.mjs +7 -7
  88. package/build/esm/data/mods/gen4/index.mjs +8 -8
  89. package/build/esm/data/mods/gen4/moves.mjs +1 -1
  90. package/build/esm/data/mods/gen4/moves.mjs.map +1 -1
  91. package/build/esm/data/mods/gen5/formats-data.mjs +2 -2
  92. package/build/esm/data/mods/gen5/formats-data.mjs.map +1 -1
  93. package/build/esm/data/mods/gen5/index.mjs +9 -9
  94. package/build/esm/data/mods/gen6/formats-data.mjs +6 -6
  95. package/build/esm/data/mods/gen6/formats-data.mjs.map +1 -1
  96. package/build/esm/data/mods/gen6/index.mjs +8 -8
  97. package/build/esm/data/mods/gen7/abilities.mjs +4 -4
  98. package/build/esm/data/mods/gen7/abilities.mjs.map +1 -1
  99. package/build/esm/data/mods/gen7/formats-data.mjs +1 -1
  100. package/build/esm/data/mods/gen7/formats-data.mjs.map +1 -1
  101. package/build/esm/data/mods/gen7/index.mjs +7 -7
  102. package/build/esm/data/mods/gen8/index.mjs +7 -7
  103. package/build/esm/data/mods/gen8/moves.mjs +24 -0
  104. package/build/esm/data/mods/gen8/moves.mjs.map +1 -1
  105. package/build/esm/data/moves.mjs +12 -18
  106. package/build/esm/data/moves.mjs.map +1 -1
  107. package/build/esm/data/pokedex.mjs +26 -26
  108. package/build/esm/data/pokedex.mjs.map +1 -1
  109. package/build/esm/data/rulesets.mjs +0 -28
  110. package/build/esm/data/rulesets.mjs.map +1 -1
  111. package/build/esm/data/text/abilities.mjs +5 -5
  112. package/build/esm/data/text/abilities.mjs.map +1 -1
  113. package/build/esm/data/text/default.mjs +1 -1
  114. package/build/esm/data/text/default.mjs.map +1 -1
  115. package/build/esm/data/text/moves.mjs +79 -30
  116. package/build/esm/data/text/moves.mjs.map +1 -1
  117. package/build/esm/lib/index.mjs +2 -2
  118. package/build/esm/sim/battle-actions.mjs +6 -1
  119. package/build/esm/sim/battle-actions.mjs.map +1 -1
  120. package/build/esm/sim/battle-stream.mjs +3 -3
  121. package/build/esm/sim/battle.mjs +19 -12
  122. package/build/esm/sim/battle.mjs.map +1 -1
  123. package/build/esm/sim/dex-abilities.mjs +1 -1
  124. package/build/esm/sim/dex-conditions.mjs +1 -1
  125. package/build/esm/sim/dex-conditions.mjs.map +1 -1
  126. package/build/esm/sim/dex-data.mjs +1 -1
  127. package/build/esm/sim/dex-formats.mjs +4 -4
  128. package/build/esm/sim/dex-items.mjs +1 -1
  129. package/build/esm/sim/dex-moves.mjs +2 -2
  130. package/build/esm/sim/dex-species.mjs +1 -1
  131. package/build/esm/sim/dex.mjs +30 -31
  132. package/build/esm/sim/dex.mjs.map +1 -1
  133. package/build/esm/sim/field.mjs +2 -2
  134. package/build/esm/sim/index.mjs +13 -13
  135. package/build/esm/sim/pokemon.mjs +18 -11
  136. package/build/esm/sim/pokemon.mjs.map +1 -1
  137. package/build/esm/sim/side.mjs +4 -4
  138. package/build/esm/sim/state.mjs +6 -6
  139. package/build/esm/sim/team-validator.mjs +6 -6
  140. package/build/esm/sim/team-validator.mjs.map +1 -1
  141. package/build/esm/sim/teams.mjs +1 -1
  142. package/build/esm/sim/tools/exhaustive-runner.mjs +4 -4
  143. package/build/esm/sim/tools/index.mjs +2 -2
  144. package/build/esm/sim/tools/random-player-ai.mjs +2 -2
  145. package/build/esm/sim/tools/runner.mjs +6 -6
  146. package/build/types/sim/battle.d.ts +2 -0
  147. package/build/types/sim/dex-conditions.d.ts +7 -6
  148. package/build/types/sim/exported-global-types.d.ts +2 -1
  149. package/build/types/sim/global-types.d.ts +2 -1
  150. package/build/types/sim/pokemon.d.ts +1 -0
  151. package/package.json +1 -1
@@ -140,23 +140,23 @@ exports.Abilities = {
140
140
  if (effect.effectType === "Move" &&
141
141
  !effect.multihit &&
142
142
  (!effect.negateSecondary && !(effect.hasSheerForce && source.hasAbility('sheerforce')))) {
143
- target.abilityState.checkedAngerShell = false;
143
+ this.effectState.checkedAngerShell = false;
144
144
  }
145
145
  else {
146
- target.abilityState.checkedAngerShell = true;
146
+ this.effectState.checkedAngerShell = true;
147
147
  }
148
148
  },
149
- onTryEatItem(item, pokemon) {
149
+ onTryEatItem(item) {
150
150
  const healingItems = [
151
151
  'aguavberry', 'enigmaberry', 'figyberry', 'iapapaberry', 'magoberry', 'sitrusberry', 'wikiberry', 'oranberry', 'berryjuice',
152
152
  ];
153
153
  if (healingItems.includes(item.id)) {
154
- return pokemon.abilityState.checkedAngerShell;
154
+ return this.effectState.checkedAngerShell;
155
155
  }
156
156
  return true;
157
157
  },
158
158
  onAfterMoveSecondary(target, source, move) {
159
- target.abilityState.checkedAngerShell = true;
159
+ this.effectState.checkedAngerShell = true;
160
160
  if (!source || source === target || !target.hp || !move.totalDamage)
161
161
  return;
162
162
  const lastAttackedBy = target.getLastAttackedBy();
@@ -164,7 +164,7 @@ exports.Abilities = {
164
164
  return;
165
165
  const damage = move.multihit ? move.totalDamage : lastAttackedBy.damage;
166
166
  if (target.hp <= target.maxhp / 2 && target.hp + damage > target.maxhp / 2) {
167
- this.boost({ atk: 1, spa: 1, spe: 1, def: -1, spd: -1 });
167
+ this.boost({ atk: 1, spa: 1, spe: 1, def: -1, spd: -1 }, target, target);
168
168
  }
169
169
  },
170
170
  name: "Anger Shell",
@@ -370,11 +370,11 @@ exports.Abilities = {
370
370
  },
371
371
  onAnyModifySpD(spd, target, source, move) {
372
372
  const abilityHolder = this.effectState.target;
373
- if (abilityHolder === target)
373
+ if (target.hasAbility('Beads of Ruin'))
374
374
  return;
375
375
  if (!move.ruinedSpD?.hasAbility('Beads of Ruin'))
376
376
  move.ruinedSpD = abilityHolder;
377
- if (move.ruinedSpD !== abilityHolder && move.ruinedSpD !== target)
377
+ if (move.ruinedSpD !== abilityHolder)
378
378
  return;
379
379
  this.debug('Beads of Ruin SpD drop');
380
380
  return this.chainModify(0.75);
@@ -399,23 +399,23 @@ exports.Abilities = {
399
399
  if (effect.effectType === "Move" &&
400
400
  !effect.multihit &&
401
401
  (!effect.negateSecondary && !(effect.hasSheerForce && source.hasAbility('sheerforce')))) {
402
- target.abilityState.checkedBerserk = false;
402
+ this.effectState.checkedBerserk = false;
403
403
  }
404
404
  else {
405
- target.abilityState.checkedBerserk = true;
405
+ this.effectState.checkedBerserk = true;
406
406
  }
407
407
  },
408
- onTryEatItem(item, pokemon) {
408
+ onTryEatItem(item) {
409
409
  const healingItems = [
410
410
  'aguavberry', 'enigmaberry', 'figyberry', 'iapapaberry', 'magoberry', 'sitrusberry', 'wikiberry', 'oranberry', 'berryjuice',
411
411
  ];
412
412
  if (healingItems.includes(item.id)) {
413
- return pokemon.abilityState.checkedBerserk;
413
+ return this.effectState.checkedBerserk;
414
414
  }
415
415
  return true;
416
416
  },
417
417
  onAfterMoveSecondary(target, source, move) {
418
- target.abilityState.checkedBerserk = true;
418
+ this.effectState.checkedBerserk = true;
419
419
  if (!source || source === target || !target.hp || !move.totalDamage)
420
420
  return;
421
421
  const lastAttackedBy = target.getLastAttackedBy();
@@ -423,7 +423,7 @@ exports.Abilities = {
423
423
  return;
424
424
  const damage = move.multihit ? move.totalDamage : lastAttackedBy.damage;
425
425
  if (target.hp <= target.maxhp / 2 && target.hp + damage > target.maxhp / 2) {
426
- this.boost({ spa: 1 });
426
+ this.boost({ spa: 1 }, target, target);
427
427
  }
428
428
  },
429
429
  name: "Berserk",
@@ -431,7 +431,7 @@ exports.Abilities = {
431
431
  num: 201,
432
432
  },
433
433
  bigpecks: {
434
- onBoost(boost, target, source, effect) {
434
+ onTryBoost(boost, target, source, effect) {
435
435
  if (source && target === source)
436
436
  return;
437
437
  if (boost.def && boost.def < 0) {
@@ -506,7 +506,7 @@ exports.Abilities = {
506
506
  num: 34,
507
507
  },
508
508
  clearbody: {
509
- onBoost(boost, target, source, effect) {
509
+ onTryBoost(boost, target, source, effect) {
510
510
  if (source && target === source)
511
511
  return;
512
512
  let showMsg = false;
@@ -652,7 +652,7 @@ exports.Abilities = {
652
652
  num: 14,
653
653
  },
654
654
  contrary: {
655
- onBoost(boost, target, source, effect) {
655
+ onChangeBoost(boost, target, source, effect) {
656
656
  if (effect && effect.id === 'zpower')
657
657
  return;
658
658
  let i;
@@ -1096,6 +1096,12 @@ exports.Abilities = {
1096
1096
  rating: 3,
1097
1097
  num: 87,
1098
1098
  },
1099
+ earlybird: {
1100
+ name: "Early Bird",
1101
+ // Implemented in statuses.js
1102
+ rating: 1.5,
1103
+ num: 48,
1104
+ },
1099
1105
  eartheater: {
1100
1106
  onTryHit(target, source, move) {
1101
1107
  if (target !== source && move.type === 'Ground') {
@@ -1110,12 +1116,6 @@ exports.Abilities = {
1110
1116
  rating: 3.5,
1111
1117
  num: 297,
1112
1118
  },
1113
- earlybird: {
1114
- name: "Early Bird",
1115
- // Implemented in statuses.js
1116
- rating: 1.5,
1117
- num: 48,
1118
- },
1119
1119
  effectspore: {
1120
1120
  onDamagingHit(damage, target, source, move) {
1121
1121
  if (this.checkMoveMakesContact(move, source, target) && !source.status && source.runStatusImmunity('powder')) {
@@ -1306,7 +1306,7 @@ exports.Abilities = {
1306
1306
  num: 122,
1307
1307
  },
1308
1308
  flowerveil: {
1309
- onAllyBoost(boost, target, source, effect) {
1309
+ onAllyTryBoost(boost, target, source, effect) {
1310
1310
  if ((source && target === source) || !target.hasType('Grass'))
1311
1311
  return;
1312
1312
  let showMsg = false;
@@ -1325,7 +1325,7 @@ exports.Abilities = {
1325
1325
  onAllySetStatus(status, target, source, effect) {
1326
1326
  if (target.hasType('Grass') && source && target !== source && effect && effect.id !== 'yawn') {
1327
1327
  this.debug('interrupting setStatus with Flower Veil');
1328
- if (effect.id === 'synchronize' || (effect.effectType === 'Move' && !effect.secondaries)) {
1328
+ if (effect.name === 'Synchronize' || (effect.effectType === 'Move' && !effect.secondaries)) {
1329
1329
  const effectHolder = this.effectState.target;
1330
1330
  this.add('-block', target, 'ability: Flower Veil', '[of] ' + effectHolder);
1331
1331
  }
@@ -1455,7 +1455,7 @@ exports.Abilities = {
1455
1455
  num: 119,
1456
1456
  },
1457
1457
  fullmetalbody: {
1458
- onBoost(boost, target, source, effect) {
1458
+ onTryBoost(boost, target, source, effect) {
1459
1459
  if (source && target === source)
1460
1460
  return;
1461
1461
  let showMsg = false;
@@ -1630,8 +1630,8 @@ exports.Abilities = {
1630
1630
  this.add('-activate', pokemon, 'ability: Guard Dog');
1631
1631
  return null;
1632
1632
  },
1633
- onBoost(boost, target, source, effect) {
1634
- if (effect.name === 'Intimidate') {
1633
+ onTryBoost(boost, target, source, effect) {
1634
+ if (effect.name === 'Intimidate' && boost.atk) {
1635
1635
  delete boost.atk;
1636
1636
  this.boost({ atk: 1 }, target, target, null, false, true);
1637
1637
  }
@@ -1819,7 +1819,7 @@ exports.Abilities = {
1819
1819
  num: 93,
1820
1820
  },
1821
1821
  hypercutter: {
1822
- onBoost(boost, target, source, effect) {
1822
+ onTryBoost(boost, target, source, effect) {
1823
1823
  if (source && target === source)
1824
1824
  return;
1825
1825
  if (boost.atk && boost.atk < 0) {
@@ -2028,8 +2028,8 @@ exports.Abilities = {
2028
2028
  if (status.id === 'flinch')
2029
2029
  return null;
2030
2030
  },
2031
- onBoost(boost, target, source, effect) {
2032
- if (effect.name === 'Intimidate') {
2031
+ onTryBoost(boost, target, source, effect) {
2032
+ if (effect.name === 'Intimidate' && boost.atk) {
2033
2033
  delete boost.atk;
2034
2034
  this.add('-fail', target, 'unboost', 'Attack', '[from] ability: Inner Focus', '[of] ' + target);
2035
2035
  }
@@ -2125,7 +2125,7 @@ exports.Abilities = {
2125
2125
  num: 154,
2126
2126
  },
2127
2127
  keeneye: {
2128
- onBoost(boost, target, source, effect) {
2128
+ onTryBoost(boost, target, source, effect) {
2129
2129
  if (source && target === source)
2130
2130
  return;
2131
2131
  if (boost.accuracy && boost.accuracy < 0) {
@@ -2236,23 +2236,6 @@ exports.Abilities = {
2236
2236
  rating: 3,
2237
2237
  num: 31,
2238
2238
  },
2239
- lingeringaroma: {
2240
- onDamagingHit(damage, target, source, move) {
2241
- const sourceAbility = source.getAbility();
2242
- if (sourceAbility.isPermanent || sourceAbility.id === 'lingeringaroma') {
2243
- return;
2244
- }
2245
- if (this.checkMoveMakesContact(move, source, target, !source.isAlly(target))) {
2246
- const oldAbility = source.setAbility('lingeringaroma', target);
2247
- if (oldAbility) {
2248
- this.add('-activate', target, 'ability: Lingering Aroma', this.dex.abilities.get(oldAbility).name, '[of] ' + source);
2249
- }
2250
- }
2251
- },
2252
- name: "Lingering Aroma",
2253
- rating: 2,
2254
- num: 268,
2255
- },
2256
2239
  limber: {
2257
2240
  onUpdate(pokemon) {
2258
2241
  if (pokemon.status === 'par') {
@@ -2273,6 +2256,23 @@ exports.Abilities = {
2273
2256
  rating: 2,
2274
2257
  num: 7,
2275
2258
  },
2259
+ lingeringaroma: {
2260
+ onDamagingHit(damage, target, source, move) {
2261
+ const sourceAbility = source.getAbility();
2262
+ if (sourceAbility.isPermanent || sourceAbility.id === 'lingeringaroma') {
2263
+ return;
2264
+ }
2265
+ if (this.checkMoveMakesContact(move, source, target, !source.isAlly(target))) {
2266
+ const oldAbility = source.setAbility('lingeringaroma', target);
2267
+ if (oldAbility) {
2268
+ this.add('-activate', target, 'ability: Lingering Aroma', this.dex.abilities.get(oldAbility).name, '[of] ' + source);
2269
+ }
2270
+ }
2271
+ },
2272
+ name: "Lingering Aroma",
2273
+ rating: 2,
2274
+ num: 268,
2275
+ },
2276
2276
  liquidooze: {
2277
2277
  onSourceTryHeal(damage, target, source, effect) {
2278
2278
  this.debug("Heal is occurring: " + target + " <- " + source + " :: " + effect.id);
@@ -2488,7 +2488,7 @@ exports.Abilities = {
2488
2488
  num: 58,
2489
2489
  },
2490
2490
  mirrorarmor: {
2491
- onBoost(boost, target, source, effect) {
2491
+ onTryBoost(boost, target, source, effect) {
2492
2492
  // Don't bounce self stat changes, or boosts that have already bounced
2493
2493
  if (target === source || !boost || effect.name === 'Mirror Armor')
2494
2494
  return;
@@ -2853,8 +2853,8 @@ exports.Abilities = {
2853
2853
  return null;
2854
2854
  }
2855
2855
  },
2856
- onBoost(boost, target, source, effect) {
2857
- if (effect.name === 'Intimidate') {
2856
+ onTryBoost(boost, target, source, effect) {
2857
+ if (effect.name === 'Intimidate' && boost.atk) {
2858
2858
  delete boost.atk;
2859
2859
  this.add('-fail', target, 'unboost', 'Attack', '[from] ability: Oblivious', '[of] ' + target);
2860
2860
  }
@@ -2866,7 +2866,7 @@ exports.Abilities = {
2866
2866
  },
2867
2867
  opportunist: {
2868
2868
  onFoeAfterBoost(boost, target, source, effect) {
2869
- if (effect?.fullname?.endsWith('Opportunist') || effect?.fullname?.endsWith('Mirror Herb'))
2869
+ if (effect?.name === 'Opportunist' || effect?.name === 'Mirror Herb')
2870
2870
  return;
2871
2871
  const pokemon = this.effectState.target;
2872
2872
  const positiveBoosts = {};
@@ -2961,8 +2961,8 @@ exports.Abilities = {
2961
2961
  this.add('-immune', target, 'confusion', '[from] ability: Own Tempo');
2962
2962
  }
2963
2963
  },
2964
- onBoost(boost, target, source, effect) {
2965
- if (effect.name === 'Intimidate') {
2964
+ onTryBoost(boost, target, source, effect) {
2965
+ if (effect.name === 'Intimidate' && boost.atk) {
2966
2966
  delete boost.atk;
2967
2967
  this.add('-fail', target, 'unboost', 'Attack', '[from] ability: Own Tempo', '[of] ' + target);
2968
2968
  }
@@ -3591,7 +3591,7 @@ exports.Abilities = {
3591
3591
  }
3592
3592
  },
3593
3593
  onAfterBoost(boost, target, source, effect) {
3594
- if (effect && effect.id === 'intimidate') {
3594
+ if (effect?.name === 'Intimidate') {
3595
3595
  this.boost({ spe: 1 });
3596
3596
  }
3597
3597
  },
@@ -3668,7 +3668,7 @@ exports.Abilities = {
3668
3668
  if (effect.isBerry)
3669
3669
  return this.chainModify(2);
3670
3670
  },
3671
- onBoost(boost, target, source, effect) {
3671
+ onChangeBoost(boost, target, source, effect) {
3672
3672
  if (effect && effect.isBerry) {
3673
3673
  let b;
3674
3674
  for (b in boost) {
@@ -3906,8 +3906,8 @@ exports.Abilities = {
3906
3906
  move.ignoreImmunity['Normal'] = true;
3907
3907
  }
3908
3908
  },
3909
- onBoost(boost, target, source, effect) {
3910
- if (effect.name === 'Intimidate') {
3909
+ onTryBoost(boost, target, source, effect) {
3910
+ if (effect.name === 'Intimidate' && boost.atk) {
3911
3911
  delete boost.atk;
3912
3912
  this.add('-fail', target, 'unboost', 'Attack', '[from] ability: Scrappy', '[of] ' + target);
3913
3913
  }
@@ -4106,7 +4106,7 @@ exports.Abilities = {
4106
4106
  num: 197,
4107
4107
  },
4108
4108
  simple: {
4109
- onBoost(boost, target, source, effect) {
4109
+ onChangeBoost(boost, target, source, effect) {
4110
4110
  if (effect && effect.id === 'zpower')
4111
4111
  return;
4112
4112
  let i;
@@ -4640,14 +4640,13 @@ exports.Abilities = {
4640
4640
  },
4641
4641
  onAnyModifyDef(def, target, source, move) {
4642
4642
  const abilityHolder = this.effectState.target;
4643
- if (abilityHolder === target)
4643
+ if (target.hasAbility('Sword of Ruin'))
4644
4644
  return;
4645
4645
  if (!move.ruinedDef?.hasAbility('Sword of Ruin'))
4646
4646
  move.ruinedDef = abilityHolder;
4647
- if (move.ruinedDef !== abilityHolder && move.ruinedDef !== target)
4647
+ if (move.ruinedDef !== abilityHolder)
4648
4648
  return;
4649
4649
  this.debug('Sword of Ruin Def drop');
4650
- // TODO Placeholder
4651
4650
  return this.chainModify(0.75);
4652
4651
  },
4653
4652
  name: "Sword of Ruin",
@@ -4662,14 +4661,13 @@ exports.Abilities = {
4662
4661
  },
4663
4662
  onAnyModifyAtk(atk, source, target, move) {
4664
4663
  const abilityHolder = this.effectState.target;
4665
- if (abilityHolder === source)
4664
+ if (source.hasAbility('Tablets of Ruin'))
4666
4665
  return;
4667
4666
  if (!move.ruinedAtk)
4668
4667
  move.ruinedAtk = abilityHolder;
4669
4668
  if (move.ruinedAtk !== abilityHolder)
4670
4669
  return;
4671
4670
  this.debug('Tablets of Ruin Atk drop');
4672
- // TODO Placeholder
4673
4671
  return this.chainModify(0.75);
4674
4672
  },
4675
4673
  name: "Tablets of Ruin",
@@ -5017,14 +5015,13 @@ exports.Abilities = {
5017
5015
  },
5018
5016
  onAnyModifySpA(spa, source, target, move) {
5019
5017
  const abilityHolder = this.effectState.target;
5020
- if (abilityHolder === source)
5018
+ if (source.hasAbility('Vessel of Ruin'))
5021
5019
  return;
5022
5020
  if (!move.ruinedSpA)
5023
5021
  move.ruinedSpA = abilityHolder;
5024
5022
  if (move.ruinedSpA !== abilityHolder)
5025
5023
  return;
5026
5024
  this.debug('Vessel of Ruin SpA drop');
5027
- // TODO Placeholder
5028
5025
  return this.chainModify(0.75);
5029
5026
  },
5030
5027
  name: "Vessel of Ruin",
@@ -5214,7 +5211,7 @@ exports.Abilities = {
5214
5211
  num: 273,
5215
5212
  },
5216
5213
  whitesmoke: {
5217
- onBoost(boost, target, source, effect) {
5214
+ onTryBoost(boost, target, source, effect) {
5218
5215
  if (source && target === source)
5219
5216
  return;
5220
5217
  let showMsg = false;
@@ -5374,20 +5371,20 @@ exports.Abilities = {
5374
5371
  },
5375
5372
  zerotohero: {
5376
5373
  onSwitchOut(pokemon) {
5377
- if (pokemon.baseSpecies.baseSpecies !== 'Palafin')
5374
+ if (pokemon.baseSpecies.baseSpecies !== 'Palafin' || pokemon.transformed)
5378
5375
  return;
5379
5376
  if (pokemon.species.forme !== 'Hero') {
5380
- pokemon.formeChange('Palafin-Hero', this.effect, true, '[silent]');
5377
+ pokemon.formeChange('Palafin-Hero', this.effect, true);
5378
+ this.effectState.sendHeroMessage = true;
5381
5379
  }
5382
5380
  },
5383
- onSwitchIn(pokemon) {
5384
- if (pokemon.baseSpecies.baseSpecies !== 'Palafin' || pokemon.species.forme !== 'Hero')
5385
- return;
5386
- if (!this.effectState.heroMessageDisplayed) {
5381
+ onStart(pokemon) {
5382
+ if (this.effectState.sendHeroMessage) {
5387
5383
  this.add('-activate', pokemon, 'ability: Zero to Hero');
5388
- this.effectState.heroMessageDisplayed = true;
5384
+ this.effectState.sendHeroMessage = false;
5389
5385
  }
5390
5386
  },
5387
+ isPermanent: true,
5391
5388
  name: "Zero to Hero",
5392
5389
  rating: 5,
5393
5390
  num: 278,