@pkmn/sim 0.5.16 → 0.5.19

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/config/formats.js +97 -114
  2. package/build/config/formats.js.map +1 -1
  3. package/build/data/aliases.js +2 -2
  4. package/build/data/aliases.js.map +1 -1
  5. package/build/data/items.js +1 -3
  6. package/build/data/items.js.map +1 -1
  7. package/build/data/learnsets.js +50 -11
  8. package/build/data/learnsets.js.map +1 -1
  9. package/build/data/mods/gen1/formats-data.js +1 -1
  10. package/build/data/mods/gen1/formats-data.js.map +1 -1
  11. package/build/data/mods/gen1/moves.js +3 -10
  12. package/build/data/mods/gen1/moves.js.map +1 -1
  13. package/build/data/mods/gen3/moves.js +0 -7
  14. package/build/data/mods/gen3/moves.js.map +1 -1
  15. package/build/data/mods/gen3/scripts.js +2 -2
  16. package/build/data/mods/gen3/scripts.js.map +1 -1
  17. package/build/data/mods/gen4/moves.js +1 -1
  18. package/build/data/mods/gen4/moves.js.map +1 -1
  19. package/build/data/mods/gen4/rulesets.js +2 -1
  20. package/build/data/mods/gen4/rulesets.js.map +1 -1
  21. package/build/data/mods/gen5/rulesets.js +2 -1
  22. package/build/data/mods/gen5/rulesets.js.map +1 -1
  23. package/build/data/mods/gen7/formats-data.js +5 -5
  24. package/build/data/mods/gen7/formats-data.js.map +1 -1
  25. package/build/data/mods/gen7/rulesets.js +2 -1
  26. package/build/data/mods/gen7/rulesets.js.map +1 -1
  27. package/build/data/moves.js +57 -78
  28. package/build/data/moves.js.map +1 -1
  29. package/build/data/pokedex.js +10 -3
  30. package/build/data/pokedex.js.map +1 -1
  31. package/build/data/rulesets.js +3 -4
  32. package/build/data/rulesets.js.map +1 -1
  33. package/build/data/text/items.js +1 -0
  34. package/build/data/text/items.js.map +1 -1
  35. package/build/data/text/moves.js +5 -3
  36. package/build/data/text/moves.js.map +1 -1
  37. package/build/sim/battle-actions.js +9 -1
  38. package/build/sim/battle-actions.js.map +1 -1
  39. package/build/sim/battle.js +39 -1
  40. package/build/sim/battle.js.map +1 -1
  41. package/build/sim/dex-conditions.d.ts +1 -0
  42. package/build/sim/dex-conditions.js.map +1 -1
  43. package/build/sim/exported-global-types.d.ts +1 -0
  44. package/build/sim/global-types.d.ts +1 -0
  45. package/build/sim/state.d.ts +1 -1
  46. package/build/sim/state.js +6 -6
  47. package/build/sim/state.js.map +1 -1
  48. package/build/sim/team-validator.js +15 -4
  49. package/build/sim/team-validator.js.map +1 -1
  50. package/build/sim/teams.d.ts +2 -2
  51. package/build/sim/tools/exhaustive-runner.d.ts +9 -0
  52. package/build/sim/tools/exhaustive-runner.js +18 -7
  53. package/build/sim/tools/exhaustive-runner.js.map +1 -1
  54. package/config/formats.ts +100 -117
  55. package/data/aliases.ts +2 -2
  56. package/data/items.ts +1 -3
  57. package/data/learnsets.ts +50 -11
  58. package/data/mods/gen1/formats-data.ts +1 -1
  59. package/data/mods/gen1/moves.ts +3 -10
  60. package/data/mods/gen3/moves.ts +0 -7
  61. package/data/mods/gen3/scripts.ts +3 -3
  62. package/data/mods/gen4/moves.ts +1 -1
  63. package/data/mods/gen4/rulesets.ts +2 -1
  64. package/data/mods/gen5/rulesets.ts +2 -1
  65. package/data/mods/gen7/formats-data.ts +5 -5
  66. package/data/mods/gen7/rulesets.ts +2 -1
  67. package/data/moves.ts +57 -69
  68. package/data/pokedex.ts +10 -3
  69. package/data/rulesets.ts +3 -6
  70. package/data/text/items.ts +2 -0
  71. package/data/text/moves.ts +6 -3
  72. package/package.json +1 -1
  73. package/sim/battle-actions.ts +13 -1
  74. package/sim/battle.ts +38 -1
  75. package/sim/dex-conditions.ts +1 -0
  76. package/sim/exported-global-types.ts +3 -0
  77. package/sim/global-types.ts +3 -0
  78. package/sim/team-validator.ts +16 -4
  79. package/sim/tools/exhaustive-runner.ts +30 -11
@@ -38,7 +38,7 @@ export const Moves: {[k: string]: ModdedMoveData} = {
38
38
  condition: {
39
39
  duration: 2,
40
40
  durationCallback(target, source, effect) {
41
- return this.random(3, 4);
41
+ return this.random(3, 5);
42
42
  },
43
43
  onStart(pokemon) {
44
44
  this.effectState.totalDamage = 0;
@@ -425,17 +425,13 @@ export const Moves: {[k: string]: ModdedMoveData} = {
425
425
  highjumpkick: {
426
426
  inherit: true,
427
427
  onMoveFail(target, source, move) {
428
- if (!target.types.includes('Ghost')) {
429
- this.directDamage(1, source, target);
430
- }
428
+ this.directDamage(1, source, target);
431
429
  },
432
430
  },
433
431
  jumpkick: {
434
432
  inherit: true,
435
433
  onMoveFail(target, source, move) {
436
- if (!target.types.includes('Ghost')) {
437
- this.directDamage(1, source, target);
438
- }
434
+ this.directDamage(1, source, target);
439
435
  },
440
436
  },
441
437
  karatechop: {
@@ -500,9 +496,6 @@ export const Moves: {[k: string]: ModdedMoveData} = {
500
496
  metronome: {
501
497
  inherit: true,
502
498
  noMetronome: ["Metronome", "Struggle"],
503
- secondary: null,
504
- target: "self",
505
- type: "Normal",
506
499
  },
507
500
  mimic: {
508
501
  inherit: true,
@@ -546,13 +546,6 @@ export const Moves: {[k: string]: ModdedMoveData} = {
546
546
  },
547
547
  sleeptalk: {
548
548
  inherit: true,
549
- beforeMoveCallback(pokemon) {
550
- if (pokemon.volatiles['choicelock'] || pokemon.volatiles['encore']) {
551
- this.addMove('move', pokemon, 'Sleep Talk');
552
- this.add('-fail', pokemon);
553
- return true;
554
- }
555
- },
556
549
  onHit(pokemon) {
557
550
  const moves = [];
558
551
  for (const moveSlot of pokemon.moveSlots) {
@@ -69,9 +69,6 @@ export const Scripts: ModdedBattleScriptsData = {
69
69
  // Mod 2 (Damage is floored after all multipliers are in)
70
70
  baseDamage = Math.floor(this.battle.runEvent('ModifyDamagePhase2', pokemon, target, move, baseDamage));
71
71
 
72
- // this is not a modifier
73
- baseDamage = this.battle.randomizer(baseDamage);
74
-
75
72
  // STAB
76
73
  if (move.forceSTAB || type !== '???' && pokemon.hasType(type)) {
77
74
  // The "???" type never gets STAB
@@ -104,6 +101,9 @@ export const Scripts: ModdedBattleScriptsData = {
104
101
  // Final modifier.
105
102
  baseDamage = this.battle.runEvent('ModifyDamage', pokemon, target, move, baseDamage);
106
103
 
104
+ // this is not a modifier
105
+ baseDamage = this.battle.randomizer(baseDamage);
106
+
107
107
  if (!Math.floor(baseDamage)) {
108
108
  return 1;
109
109
  }
@@ -1650,7 +1650,7 @@ export const Moves: {[k: string]: ModdedMoveData} = {
1650
1650
  this.add('-sidestart', side, 'move: Toxic Spikes');
1651
1651
  this.effectState.layers++;
1652
1652
  },
1653
- onSwitchIn(pokemon) {
1653
+ onEntryHazard(pokemon) {
1654
1654
  if (!pokemon.isGrounded()) return;
1655
1655
  if (pokemon.hasType('Poison')) {
1656
1656
  this.add('-sideend', pokemon.side, 'move: Toxic Spikes', '[of] ' + pokemon);
@@ -13,7 +13,8 @@ export const Rulesets: {[k: string]: ModdedFormatData} = {
13
13
  this.add('clearpoke');
14
14
  for (const pokemon of this.getAllPokemon()) {
15
15
  const details = pokemon.details.replace(', shiny', '')
16
- .replace(/(Arceus|Gourgeist|Genesect|Pumpkaboo|Silvally|Zacian|Zamazenta|Urshifu)(-[a-zA-Z?-]+)?/g, '$1-*');
16
+ .replace(/(Arceus|Gourgeist|Pumpkaboo|Xerneas|Silvally|Urshifu)(-[a-zA-Z?-]+)?/g, '$1-*')
17
+ .replace(/(Zacian|Zamazenta)(?!-Crowned)/g, '$1-*'); // Hacked-in Crowned formes will be revealed
17
18
  this.add('poke', pokemon.side.id, details, pokemon.item ? 'item' : '');
18
19
  }
19
20
  this.makeRequest('teampreview');
@@ -19,7 +19,8 @@ export const Rulesets: {[k: string]: ModdedFormatData} = {
19
19
  this.add('clearpoke');
20
20
  for (const pokemon of this.getAllPokemon()) {
21
21
  const details = pokemon.details.replace(', shiny', '')
22
- .replace(/(Arceus|Gourgeist|Genesect|Pumpkaboo|Silvally|Zacian|Zamazenta|Urshifu)(-[a-zA-Z?-]+)?/g, '$1-*');
22
+ .replace(/(Arceus|Gourgeist|Pumpkaboo|Xerneas|Silvally|Urshifu)(-[a-zA-Z?-]+)?/g, '$1-*')
23
+ .replace(/(Zacian|Zamazenta)(?!-Crowned)/g, '$1-*'); // Hacked-in Crowned formes will be revealed
23
24
  const item = pokemon.item.includes('mail') ? 'mail' : pokemon.item ? 'item' : '';
24
25
  this.add('poke', pokemon.side.id, details, item);
25
26
  }
@@ -2284,7 +2284,7 @@ export const FormatsData: {[k: string]: ModdedSpeciesFormatsData} = {
2284
2284
  doublesTier: "DUber",
2285
2285
  },
2286
2286
  rayquaza: {
2287
- randomBattleMoves: ["dracometeor", "dragondance", "earthquake", "extremespeed", "outrage", "vcreate"],
2287
+ randomBattleMoves: ["dracometeor", "dragonascent", "dragondance", "earthquake", "extremespeed", "outrage", "vcreate"],
2288
2288
  randomDoubleBattleMoves: ["dracometeor", "dragonclaw", "dragondance", "earthquake", "extremespeed", "protect", "tailwind", "vcreate"],
2289
2289
  tier: "Uber",
2290
2290
  doublesTier: "DUber",
@@ -3046,7 +3046,7 @@ export const FormatsData: {[k: string]: ModdedSpeciesFormatsData} = {
3046
3046
  doublesTier: "(DUU)",
3047
3047
  },
3048
3048
  sawk: {
3049
- randomBattleMoves: ["bulkup", "closecombat", "earthquake", "icepunch", "knockoff", "poisonjab"],
3049
+ randomBattleMoves: ["bulkup", "closecombat", "earthquake", "icepunch", "knockoff", "poisonjab", "stoneedge"],
3050
3050
  randomDoubleBattleMoves: ["closecombat", "icepunch", "knockoff", "protect", "rockslide"],
3051
3051
  tier: "PUBL",
3052
3052
  doublesTier: "(DUU)",
@@ -3362,7 +3362,7 @@ export const FormatsData: {[k: string]: ModdedSpeciesFormatsData} = {
3362
3362
  tier: "NFE",
3363
3363
  },
3364
3364
  chandelure: {
3365
- randomBattleMoves: ["calmmind", "energyball", "fireblast", "hiddenpowerground", "painsplit", "shadowball", "substitute", "trick"],
3365
+ randomBattleMoves: ["calmmind", "energyball", "fireblast", "hiddenpowerground", "shadowball", "substitute", "trick"],
3366
3366
  randomDoubleBattleMoves: ["energyball", "heatwave", "overheat", "protect", "shadowball", "trick"],
3367
3367
  tier: "UU",
3368
3368
  doublesTier: "DUU",
@@ -3485,7 +3485,7 @@ export const FormatsData: {[k: string]: ModdedSpeciesFormatsData} = {
3485
3485
  tier: "NFE",
3486
3486
  },
3487
3487
  hydreigon: {
3488
- randomBattleMoves: ["darkpulse", "dracometeor", "dragonpulse", "earthpower", "fireblast", "flashcannon", "roost", "superpower", "uturn"],
3488
+ randomBattleMoves: ["darkpulse", "dracometeor", "earthpower", "fireblast", "flashcannon", "roost", "superpower", "uturn"],
3489
3489
  randomDoubleBattleMoves: ["darkpulse", "dracometeor", "fireblast", "flashcannon", "protect", "tailwind", "uturn"],
3490
3490
  tier: "UU",
3491
3491
  doublesTier: "DUU",
@@ -3904,7 +3904,7 @@ export const FormatsData: {[k: string]: ModdedSpeciesFormatsData} = {
3904
3904
  tier: "NFE",
3905
3905
  },
3906
3906
  goodra: {
3907
- randomBattleMoves: ["dracometeor", "dragonpulse", "dragontail", "earthquake", "fireblast", "sludgebomb", "thunderbolt"],
3907
+ randomBattleMoves: ["dracometeor", "dragontail", "earthquake", "fireblast", "sludgebomb", "thunderbolt"],
3908
3908
  randomDoubleBattleMoves: ["dracometeor", "dragonpulse", "fireblast", "muddywater", "powerwhip", "protect", "thunderbolt"],
3909
3909
  tier: "RU",
3910
3910
  doublesTier: "(DUU)",
@@ -36,7 +36,8 @@ export const Rulesets: {[k: string]: ModdedFormatData} = {
36
36
  this.add('clearpoke');
37
37
  for (const pokemon of this.getAllPokemon()) {
38
38
  const details = pokemon.details.replace(', shiny', '')
39
- .replace(/(Arceus|Gourgeist|Genesect|Pumpkaboo|Silvally|Zacian|Zamazenta|Urshifu)(-[a-zA-Z?-]+)?/g, '$1-*');
39
+ .replace(/(Arceus|Gourgeist|Pumpkaboo|Xerneas|Silvally|Urshifu)(-[a-zA-Z?-]+)?/g, '$1-*')
40
+ .replace(/(Zacian|Zamazenta)(?!-Crowned)/g, '$1-*'); // Hacked-in Crowned formes will be revealed
40
41
  this.add('poke', pokemon.side.id, details, pokemon.item ? 'item' : '');
41
42
  }
42
43
  this.makeRequest('teampreview');
package/data/moves.ts CHANGED
@@ -2689,53 +2689,50 @@ export const Moves: {[moveid: string]: MoveData} = {
2689
2689
  const offset = this.random(3) + 1;
2690
2690
  // the list of all sides in counterclockwise order
2691
2691
  const sides = [this.sides[0], this.sides[2]!, this.sides[1], this.sides[3]!];
2692
- for (const id of sideConditions) {
2693
- const effectName = this.dex.conditions.get(id).name;
2694
- const rotatedSides = [];
2695
- let someCondition = false;
2696
- for (let i = 0; i < 4; i++) {
2697
- const sourceSide = sides[i];
2698
- const targetSide = sides[(i + offset) % 4]; // the next side in rotation
2699
- rotatedSides.push(targetSide.sideConditions[id]);
2700
- if (sourceSide.sideConditions[id]) {
2701
- this.add('-sideend', sourceSide, effectName, '[silent]');
2702
- someCondition = true;
2703
- }
2692
+ const temp: {[k: number]: typeof source.side.sideConditions} = {0: {}, 1: {}, 2: {}, 3: {}};
2693
+ for (const side of sides) {
2694
+ for (const id in side.sideConditions) {
2695
+ if (!sideConditions.includes(id)) continue;
2696
+ temp[side.n][id] = side.sideConditions[id];
2697
+ delete side.sideConditions[id];
2698
+ const effectName = this.dex.conditions.get(id).name;
2699
+ this.add('-sideend', side, effectName, '[silent]');
2700
+ success = true;
2704
2701
  }
2705
- if (!someCondition) continue;
2706
- [
2707
- sides[0].sideConditions[id], sides[1].sideConditions[id],
2708
- sides[2]!.sideConditions[id], sides[3]!.sideConditions[id],
2709
- ] = [...rotatedSides];
2710
- for (const side of sides) {
2711
- if (side.sideConditions[id]) {
2712
- let layers = side.sideConditions[id].layers || 1;
2713
- for (; layers > 0; layers--) this.add('-sidestart', side, effectName, '[silent]');
2714
- } else {
2715
- delete side.sideConditions[id];
2716
- }
2702
+ }
2703
+ for (let i = 0; i < 4; i++) {
2704
+ const sourceSideConditions = temp[sides[i].n];
2705
+ const targetSide = sides[(i + offset) % 4]; // the next side in rotation
2706
+ for (const id in sourceSideConditions) {
2707
+ targetSide.sideConditions[id] = sourceSideConditions[id];
2708
+ const effectName = this.dex.conditions.get(id).name;
2709
+ let layers = sourceSideConditions[id].layers || 1;
2710
+ for (; layers > 0; layers--) this.add('-sidestart', targetSide, effectName, '[silent]');
2717
2711
  }
2718
- success = true;
2719
2712
  }
2720
2713
  } else {
2721
- const sourceSide = source.side;
2722
- const targetSide = source.side.foe;
2723
- for (const id of sideConditions) {
2724
- if (sourceSide.sideConditions[id] && targetSide.sideConditions[id]) {
2725
- [sourceSide.sideConditions[id], targetSide.sideConditions[id]] = [
2726
- targetSide.sideConditions[id], sourceSide.sideConditions[id],
2727
- ];
2728
- } else if (sourceSide.sideConditions[id] && !targetSide.sideConditions[id]) {
2729
- targetSide.sideConditions[id] = sourceSide.sideConditions[id];
2730
- delete sourceSide.sideConditions[id];
2731
- } else if (targetSide.sideConditions[id] && !sourceSide.sideConditions[id]) {
2732
- sourceSide.sideConditions[id] = targetSide.sideConditions[id];
2733
- delete targetSide.sideConditions[id];
2734
- } else {
2735
- continue;
2736
- }
2714
+ const sourceSideConditions = source.side.sideConditions;
2715
+ const targetSideConditions = source.side.foe.sideConditions;
2716
+ const sourceTemp: typeof sourceSideConditions = {};
2717
+ const targetTemp: typeof targetSideConditions = {};
2718
+ for (const id in sourceSideConditions) {
2719
+ if (!sideConditions.includes(id)) continue;
2720
+ sourceTemp[id] = sourceSideConditions[id];
2721
+ delete sourceSideConditions[id];
2722
+ success = true;
2723
+ }
2724
+ for (const id in targetSideConditions) {
2725
+ if (!sideConditions.includes(id)) continue;
2726
+ targetTemp[id] = targetSideConditions[id];
2727
+ delete targetSideConditions[id];
2737
2728
  success = true;
2738
2729
  }
2730
+ for (const id in sourceTemp) {
2731
+ targetSideConditions[id] = sourceTemp[id];
2732
+ }
2733
+ for (const id in targetTemp) {
2734
+ sourceSideConditions[id] = targetTemp[id];
2735
+ }
2739
2736
  this.add('-swapsideconditions');
2740
2737
  }
2741
2738
  if (!success) return false;
@@ -6719,7 +6716,7 @@ export const Moves: {[moveid: string]: MoveData} = {
6719
6716
  onSideStart(side) {
6720
6717
  this.add('-sidestart', side, 'move: G-Max Steelsurge');
6721
6718
  },
6722
- onSwitchIn(pokemon) {
6719
+ onEntryHazard(pokemon) {
6723
6720
  if (pokemon.hasItem('heavydutyboots')) return;
6724
6721
  // Ice Face and Disguise correctly get typed damage from Stealth Rock
6725
6722
  // because Stealth Rock bypasses Substitute.
@@ -7818,9 +7815,8 @@ export const Moves: {[moveid: string]: MoveData} = {
7818
7815
  pp: 10,
7819
7816
  priority: 0,
7820
7817
  flags: {snatch: 1, heal: 1},
7821
- onHit(target, source, move) {
7818
+ onTryHit(source) {
7822
7819
  if (!this.canSwitch(source.side)) {
7823
- delete move.selfdestruct;
7824
7820
  this.attrLastMove('[still]');
7825
7821
  this.add('-fail', source);
7826
7822
  return this.NOT_FAIL;
@@ -9914,9 +9910,8 @@ export const Moves: {[moveid: string]: MoveData} = {
9914
9910
  pp: 10,
9915
9911
  priority: 0,
9916
9912
  flags: {snatch: 1, heal: 1, dance: 1},
9917
- onHit(target, source, move) {
9913
+ onTryHit(source) {
9918
9914
  if (!this.canSwitch(source.side)) {
9919
- delete move.selfdestruct;
9920
9915
  this.attrLastMove('[still]');
9921
9916
  this.add('-fail', source);
9922
9917
  return this.NOT_FAIL;
@@ -11062,26 +11057,21 @@ export const Moves: {[moveid: string]: MoveData} = {
11062
11057
  priority: 0,
11063
11058
  flags: {},
11064
11059
  noMetronome: [
11065
- "After You", "Apple Acid", "Assist", "Astral Barrage", "Aura Wheel", "Baneful Bunker", "Beak Blast", "Behemoth Bash", "Behemoth Blade", "Belch", "Bestow", "Body Press", "Branch Poke", "Breaking Swipe", "Celebrate", "Chatter", "Clangorous Soul", "Copycat", "Counter", "Covet", "Crafty Shield", "Decorate", "Destiny Bond", "Detect", "Diamond Storm", "Double Iron Bash", "Dragon Ascent", "Dragon Energy", "Drum Beating", "Dynamax Cannon", "Endure", "Eternabeam", "False Surrender", "Feint", "Fiery Wrath", "Fleur Cannon", "Focus Punch", "Follow Me", "Freeze Shock", "Freezing Glare", "Glacial Lance", "Grav Apple", "Helping Hand", "Hold Hands", "Hyperspace Fury", "Hyperspace Hole", "Ice Burn", "Instruct", "Jungle Healing", "King's Shield", "Life Dew", "Light of Ruin", "Mat Block", "Me First", "Meteor Assault", "Metronome", "Mimic", "Mind Blown", "Mirror Coat", "Mirror Move", "Moongeist Beam", "Nature Power", "Nature's Madness", "Obstruct", "Origin Pulse", "Overdrive", "Photon Geyser", "Plasma Fists", "Precipice Blades", "Protect", "Pyro Ball", "Quash", "Quick Guard", "Rage Powder", "Relic Song", "Secret Sword", "Shell Trap", "Sketch", "Sleep Talk", "Snap Trap", "Snarl", "Snatch", "Snore", "Spectral Thief", "Spiky Shield", "Spirit Break", "Spotlight", "Steam Eruption", "Steel Beam", "Strange Steam", "Struggle", "Sunsteel Strike", "Surging Strikes", "Switcheroo", "Techno Blast", "Thief", "Thousand Arrows", "Thousand Waves", "Thunder Cage", "Thunderous Kick", "Transform", "Trick", "V-create", "Wicked Blow", "Wide Guard",
11060
+ "After You", "Apple Acid", "Assist", "Astral Barrage", "Aura Wheel", "Baneful Bunker", "Beak Blast", "Behemoth Bash", "Behemoth Blade", "Belch", "Bestow", "Body Press", "Branch Poke", "Breaking Swipe", "Celebrate", "Chatter", "Clangorous Soul", "Copycat", "Counter", "Covet", "Crafty Shield", "Decorate", "Destiny Bond", "Detect", "Diamond Storm", "Double Iron Bash", "Dragon Ascent", "Dragon Energy", "Dragon Hammer", "Drum Beating", "Dynamax Cannon", "Endure", "Eternabeam", "False Surrender", "Feint", "Fiery Wrath", "Fleur Cannon", "Focus Punch", "Follow Me", "Freeze Shock", "Freezing Glare", "Glacial Lance", "Grav Apple", "Helping Hand", "Hold Hands", "Hyperspace Fury", "Hyperspace Hole", "Ice Burn", "Instruct", "Jungle Healing", "King's Shield", "Life Dew", "Light of Ruin", "Mat Block", "Me First", "Meteor Assault", "Metronome", "Mimic", "Mind Blown", "Mirror Coat", "Mirror Move", "Moongeist Beam", "Nature Power", "Nature's Madness", "Obstruct", "Origin Pulse", "Overdrive", "Photon Geyser", "Plasma Fists", "Precipice Blades", "Protect", "Pyro Ball", "Quash", "Quick Guard", "Rage Powder", "Relic Song", "Secret Sword", "Shell Trap", "Sketch", "Sleep Talk", "Snap Trap", "Snarl", "Snatch", "Snore", "Spectral Thief", "Spiky Shield", "Spirit Break", "Spotlight", "Steam Eruption", "Steel Beam", "Strange Steam", "Struggle", "Sunsteel Strike", "Surging Strikes", "Switcheroo", "Techno Blast", "Thief", "Thousand Arrows", "Thousand Waves", "Thunder Cage", "Thunderous Kick", "Transform", "Trick", "V-create", "Wicked Blow", "Wide Guard",
11066
11061
  ],
11067
11062
  onHit(target, source, effect) {
11068
- const moves: MoveData[] = [];
11069
- for (const id in Moves) {
11070
- const move = Moves[id];
11071
- if (move.realMove) continue;
11072
- if (move.isZ || move.isMax || move.isNonstandard) continue;
11073
- if (effect.noMetronome!.includes(move.name)) continue;
11074
- if (this.dex.moves.get(id).gen > this.gen) continue;
11075
- moves.push(move);
11076
- }
11063
+ const moves = this.dex.moves.all().filter(move => (
11064
+ (![2, 4].includes(this.gen) || !source.moves.includes(move.id)) &&
11065
+ !move.realMove && !move.isZ && !move.isMax &&
11066
+ (!move.isNonstandard || move.isNonstandard === 'Unobtainable') &&
11067
+ !effect.noMetronome!.includes(move.name)
11068
+ ));
11077
11069
  let randomMove = '';
11078
11070
  if (moves.length) {
11079
- moves.sort((a, b) => a.num! - b.num!);
11080
- randomMove = this.sample(moves).name;
11081
- }
11082
- if (!randomMove) {
11083
- return false;
11071
+ moves.sort((a, b) => a.num - b.num);
11072
+ randomMove = this.sample(moves).id;
11084
11073
  }
11074
+ if (!randomMove) return false;
11085
11075
  this.actions.useMove(randomMove, target);
11086
11076
  },
11087
11077
  secondary: null,
@@ -16411,9 +16401,8 @@ export const Moves: {[moveid: string]: MoveData} = {
16411
16401
  this.add('-sidestart', side, 'Spikes');
16412
16402
  this.effectState.layers++;
16413
16403
  },
16414
- onSwitchIn(pokemon) {
16415
- if (!pokemon.isGrounded()) return;
16416
- if (pokemon.hasItem('heavydutyboots')) return;
16404
+ onEntryHazard(pokemon) {
16405
+ if (!pokemon.isGrounded() || pokemon.hasItem('heavydutyboots')) return;
16417
16406
  const damageAmounts = [0, 3, 4, 6]; // 1/8, 1/6, 1/4
16418
16407
  this.damage(damageAmounts[this.effectState.layers] * pokemon.maxhp / 24);
16419
16408
  },
@@ -16696,7 +16685,7 @@ export const Moves: {[moveid: string]: MoveData} = {
16696
16685
  onSideStart(side) {
16697
16686
  this.add('-sidestart', side, 'move: Stealth Rock');
16698
16687
  },
16699
- onSwitchIn(pokemon) {
16688
+ onEntryHazard(pokemon) {
16700
16689
  if (pokemon.hasItem('heavydutyboots')) return;
16701
16690
  const typeMod = this.clampIntRange(pokemon.runEffectiveness(this.dex.getActiveMove('stealthrock')), -6, 6);
16702
16691
  this.damage(pokemon.maxhp * Math.pow(2, typeMod) / 8);
@@ -16820,9 +16809,8 @@ export const Moves: {[moveid: string]: MoveData} = {
16820
16809
  onSideStart(side) {
16821
16810
  this.add('-sidestart', side, 'move: Sticky Web');
16822
16811
  },
16823
- onSwitchIn(pokemon) {
16824
- if (!pokemon.isGrounded()) return;
16825
- if (pokemon.hasItem('heavydutyboots')) return;
16812
+ onEntryHazard(pokemon) {
16813
+ if (!pokemon.isGrounded() || pokemon.hasItem('heavydutyboots')) return;
16826
16814
  this.add('-activate', pokemon, 'move: Sticky Web');
16827
16815
  this.boost({spe: -1}, pokemon, this.effectState.source, this.dex.getActiveMove('stickyweb'));
16828
16816
  },
@@ -18426,7 +18414,7 @@ export const Moves: {[moveid: string]: MoveData} = {
18426
18414
  this.add('-sidestart', side, 'move: Toxic Spikes');
18427
18415
  this.effectState.layers++;
18428
18416
  },
18429
- onSwitchIn(pokemon) {
18417
+ onEntryHazard(pokemon) {
18430
18418
  if (!pokemon.isGrounded()) return;
18431
18419
  if (pokemon.hasType('Poison')) {
18432
18420
  this.add('-sideend', pokemon.side, 'move: Toxic Spikes', '[of] ' + pokemon);
package/data/pokedex.ts CHANGED
@@ -459,6 +459,7 @@ export const Pokedex: {[speciesid: string]: SpeciesData} = {
459
459
  color: "Black",
460
460
  prevo: "Rattata-Alola",
461
461
  evoLevel: 20,
462
+ evoCondition: "at night",
462
463
  eggGroups: ["Field"],
463
464
  },
464
465
  raticatealolatotem: {
@@ -2391,6 +2392,7 @@ export const Pokedex: {[speciesid: string]: SpeciesData} = {
2391
2392
  color: "Purple",
2392
2393
  prevo: "Cubone",
2393
2394
  evoLevel: 28,
2395
+ evoCondition: "at night",
2394
2396
  eggGroups: ["Monster"],
2395
2397
  },
2396
2398
  marowakalolatotem: {
@@ -8096,6 +8098,7 @@ export const Pokedex: {[speciesid: string]: SpeciesData} = {
8096
8098
  prevo: "Sneasel",
8097
8099
  evoType: "levelHold",
8098
8100
  evoItem: "Razor Claw",
8101
+ evoCondition: "at night",
8099
8102
  eggGroups: ["Field"],
8100
8103
  },
8101
8104
  magnezone: {
@@ -12224,6 +12227,7 @@ export const Pokedex: {[speciesid: string]: SpeciesData} = {
12224
12227
  color: "Red",
12225
12228
  prevo: "Tyrunt",
12226
12229
  evoLevel: 39,
12230
+ evoCondition: "during the day",
12227
12231
  eggGroups: ["Monster", "Dragon"],
12228
12232
  },
12229
12233
  amaura: {
@@ -12251,6 +12255,7 @@ export const Pokedex: {[speciesid: string]: SpeciesData} = {
12251
12255
  color: "Blue",
12252
12256
  prevo: "Amaura",
12253
12257
  evoLevel: 39,
12258
+ evoCondition: "at night",
12254
12259
  eggGroups: ["Monster"],
12255
12260
  },
12256
12261
  sylveon: {
@@ -12970,6 +12975,7 @@ export const Pokedex: {[speciesid: string]: SpeciesData} = {
12970
12975
  color: "Brown",
12971
12976
  prevo: "Yungoos",
12972
12977
  evoLevel: 20,
12978
+ evoCondition: "during the day",
12973
12979
  eggGroups: ["Field"],
12974
12980
  otherFormes: ["Gumshoos-Totem"],
12975
12981
  formeOrder: ["Gumshoos", "Gumshoos-Totem"],
@@ -13212,7 +13218,7 @@ export const Pokedex: {[speciesid: string]: SpeciesData} = {
13212
13218
  color: "Red",
13213
13219
  prevo: "Rockruff",
13214
13220
  evoLevel: 25,
13215
- evoCondition: "during the night",
13221
+ evoCondition: "at night",
13216
13222
  eggGroups: ["Field"],
13217
13223
  },
13218
13224
  lycanrocdusk: {
@@ -16034,7 +16040,7 @@ export const Pokedex: {[speciesid: string]: SpeciesData} = {
16034
16040
  color: "Blue",
16035
16041
  eggGroups: ["Undiscovered"],
16036
16042
  requiredItem: "Rusted Sword",
16037
- changesFrom: "Zacian",
16043
+ battleOnly: "Zacian",
16038
16044
  cannotDynamax: true,
16039
16045
  },
16040
16046
  zamazenta: {
@@ -16068,7 +16074,7 @@ export const Pokedex: {[speciesid: string]: SpeciesData} = {
16068
16074
  color: "Red",
16069
16075
  eggGroups: ["Undiscovered"],
16070
16076
  requiredItem: "Rusted Shield",
16071
- changesFrom: "Zamazenta",
16077
+ battleOnly: "Zamazenta",
16072
16078
  cannotDynamax: true,
16073
16079
  },
16074
16080
  eternatus: {
@@ -16400,6 +16406,7 @@ export const Pokedex: {[speciesid: string]: SpeciesData} = {
16400
16406
  prevo: "Sneasel-Hisui",
16401
16407
  evoType: "useItem",
16402
16408
  evoItem: "Razor Claw",
16409
+ evoCondition: "during the day",
16403
16410
  eggGroups: ["Field"],
16404
16411
  },
16405
16412
  overqwil: {
package/data/rulesets.ts CHANGED
@@ -446,7 +446,8 @@ export const Rulesets: {[k: string]: FormatData} = {
446
446
  this.add('clearpoke');
447
447
  for (const pokemon of this.getAllPokemon()) {
448
448
  const details = pokemon.details.replace(', shiny', '')
449
- .replace(/(Arceus|Gourgeist|Pumpkaboo|Xerneas|Silvally|Zacian|Zamazenta|Urshifu)(-[a-zA-Z?-]+)?/g, '$1-*');
449
+ .replace(/(Arceus|Gourgeist|Pumpkaboo|Xerneas|Silvally|Urshifu)(-[a-zA-Z?-]+)?/g, '$1-*')
450
+ .replace(/(Zacian|Zamazenta)(?!-Crowned)/g, '$1-*'); // Hacked-in Crowned formes will be revealed
450
451
  this.add('poke', pokemon.side.id, details, '');
451
452
  }
452
453
  this.makeRequest('teampreview');
@@ -1146,11 +1147,7 @@ export const Rulesets: {[k: string]: FormatData} = {
1146
1147
  if (prevo.evos.includes(formeName)) continue;
1147
1148
  }
1148
1149
  const forme = dex.species.get(formeName);
1149
- if (
1150
- forme.changesFrom === originalForme.name && !forme.battleOnly &&
1151
- // Temporary workaround
1152
- forme.forme !== 'Crowned'
1153
- ) {
1150
+ if (forme.changesFrom === originalForme.name && !forme.battleOnly) {
1154
1151
  speciesTypes.push(...forme.types);
1155
1152
  }
1156
1153
  }
@@ -429,6 +429,8 @@ export const ItemsText: {[k: string]: ItemText} = {
429
429
  ejectpack: {
430
430
  name: "Eject Pack",
431
431
  desc: "If the holder's stat stages are lowered, it switches to a chosen ally. Single use.",
432
+
433
+ end: " [POKEMON] is switched out by the Eject Pack!",
432
434
  },
433
435
  electirizer: {
434
436
  name: "Electirizer",
@@ -1934,6 +1934,8 @@ export const MovesText: {[k: string]: MoveText} = {
1934
1934
  name: "Flip Turn",
1935
1935
  desc: "If this move is successful and the user has not fainted, the user switches out even if it is trapped and is replaced immediately by a selected party member. The user does not switch out if there are no unfainted party members, or if the target switched out using an Eject Button or through the effect of the Emergency Exit or Wimp Out Abilities.",
1936
1936
  shortDesc: "User switches out after damaging the target.",
1937
+
1938
+ switchOut: "#uturn",
1937
1939
  },
1938
1940
  floatyfall: {
1939
1941
  name: "Floaty Fall",
@@ -3695,7 +3697,7 @@ export const MovesText: {[k: string]: MoveText} = {
3695
3697
  },
3696
3698
  metronome: {
3697
3699
  name: "Metronome",
3698
- desc: "A random move is selected for use, other than After You, Apple Acid, Assist, Astral Barrage, Aura Wheel, Baneful Bunker, Beak Blast, Behemoth Bash, Behemoth Blade, Belch, Bestow, Body Press, Branch Poke, Breaking Swipe, Celebrate, Chatter, Clangorous Soul, Copycat, Counter, Covet, Crafty Shield, Decorate, Destiny Bond, Detect, Diamond Storm, Double Iron Bash, Dragon Ascent, Dragon Energy, Drum Beating, Dynamax Cannon, Endure, Eternabeam, False Surrender, Feint, Fiery Wrath, Fleur Cannon, Focus Punch, Follow Me, Freeze Shock, Freezing Glare, Glacial Lance, Grav Apple, Helping Hand, Hold Hands, Hyperspace Fury, Hyperspace Hole, Ice Burn, Instruct, Jungle Healing, King's Shield, Life Dew, Light of Ruin, Mat Block, Me First, Meteor Assault, Metronome, Mimic, Mind Blown, Mirror Coat, Mirror Move, Moongeist Beam, Nature Power, Nature's Madness, Obstruct, Origin Pulse, Overdrive, Photon Geyser, Plasma Fists, Precipice Blades, Protect, Pyro Ball, Quash, Quick Guard, Rage Powder, Relic Song, Secret Sword, Shell Trap, Sketch, Sleep Talk, Snap Trap, Snarl, Snatch, Snore, Spectral Thief, Spiky Shield, Spirit Break, Spotlight, Steam Eruption, Steel Beam, Strange Steam, Struggle, Sunsteel Strike, Surging Strikes, Switcheroo, Techno Blast, Thief, Thousand Arrows, Thousand Waves, Thunder Cage, Thunderous Kick, Transform, Trick, V-create, Wicked Blow, or Wide Guard.",
3700
+ desc: "A random move is selected for use, other than After You, Apple Acid, Assist, Astral Barrage, Aura Wheel, Baneful Bunker, Beak Blast, Behemoth Bash, Behemoth Blade, Belch, Bestow, Body Press, Branch Poke, Breaking Swipe, Celebrate, Chatter, Clangorous Soul, Copycat, Counter, Covet, Crafty Shield, Decorate, Destiny Bond, Detect, Diamond Storm, Double Iron Bash, Dragon Ascent, Dragon Energy, Dragon Hammer, Drum Beating, Dynamax Cannon, Endure, Eternabeam, False Surrender, Feint, Fiery Wrath, Fleur Cannon, Focus Punch, Follow Me, Freeze Shock, Freezing Glare, Glacial Lance, Grav Apple, Helping Hand, Hold Hands, Hyperspace Fury, Hyperspace Hole, Ice Burn, Instruct, Jungle Healing, King's Shield, Life Dew, Light of Ruin, Mat Block, Me First, Meteor Assault, Metronome, Mimic, Mind Blown, Mirror Coat, Mirror Move, Moongeist Beam, Nature Power, Nature's Madness, Obstruct, Origin Pulse, Overdrive, Photon Geyser, Plasma Fists, Precipice Blades, Protect, Pyro Ball, Quash, Quick Guard, Rage Powder, Relic Song, Secret Sword, Shell Trap, Sketch, Sleep Talk, Snap Trap, Snarl, Snatch, Snore, Spectral Thief, Spiky Shield, Spirit Break, Spotlight, Steam Eruption, Steel Beam, Strange Steam, Struggle, Sunsteel Strike, Surging Strikes, Switcheroo, Techno Blast, Thief, Thousand Arrows, Thousand Waves, Thunder Cage, Thunderous Kick, Transform, Trick, V-create, Wicked Blow, or Wide Guard.",
3699
3701
  shortDesc: "Picks a random move.",
3700
3702
  gen7: {
3701
3703
  desc: "A random move is selected for use, other than After You, Assist, Baneful Bunker, Beak Blast, Belch, Bestow, Celebrate, Chatter, Copycat, Counter, Covet, Crafty Shield, Destiny Bond, Detect, Diamond Storm, Dragon Ascent, Endure, Feint, Fleur Cannon, Focus Punch, Follow Me, Freeze Shock, Helping Hand, Hold Hands, Hyperspace Fury, Hyperspace Hole, Ice Burn, Instruct, King's Shield, Light of Ruin, Mat Block, Me First, Metronome, Mimic, Mind Blown, Mirror Coat, Mirror Move, Nature Power, Origin Pulse, Photon Geyser, Plasma Fists, Precipice Blades, Protect, Quash, Quick Guard, Rage Powder, Relic Song, Secret Sword, Shell Trap, Sketch, Sleep Talk, Snarl, Snatch, Snore, Spectral Thief, Spiky Shield, Spotlight, Steam Eruption, Struggle, Switcheroo, Techno Blast, Thief, Thousand Arrows, Thousand Waves, Transform, Trick, V-create, or Wide Guard.",
@@ -3707,13 +3709,13 @@ export const MovesText: {[k: string]: MoveText} = {
3707
3709
  desc: "A random move is selected for use, other than After You, Assist, Bestow, Chatter, Copycat, Counter, Covet, Destiny Bond, Detect, Endure, Feint, Focus Punch, Follow Me, Freeze Shock, Helping Hand, Ice Burn, Me First, Metronome, Mimic, Mirror Coat, Mirror Move, Nature Power, Protect, Quash, Quick Guard, Rage Powder, Relic Song, Secret Sword, Sketch, Sleep Talk, Snarl, Snatch, Snore, Struggle, Switcheroo, Techno Blast, Thief, Transform, Trick, V-create, or Wide Guard.",
3708
3710
  },
3709
3711
  gen4: {
3710
- desc: "A random move is selected for use, other than Assist, Chatter, Copycat, Counter, Covet, Destiny Bond, Detect, Endure, Feint, Focus Punch, Follow Me, Helping Hand, Me First, Metronome, Mimic, Mirror Coat, Mirror Move, Protect, Sketch, Sleep Talk, Snatch, Struggle, Switcheroo, Thief, or Trick.",
3712
+ desc: "A random move is selected for use, other than Assist, Chatter, Copycat, Counter, Covet, Destiny Bond, Detect, Endure, Feint, Focus Punch, Follow Me, Helping Hand, Me First, Metronome, Mimic, Mirror Coat, Mirror Move, Protect, Sketch, Sleep Talk, Snatch, Struggle, Switcheroo, Thief, Trick, or any move the user already knows.",
3711
3713
  },
3712
3714
  gen3: {
3713
3715
  desc: "A random move is selected for use, other than Counter, Covet, Destiny Bond, Detect, Endure, Focus Punch, Follow Me, Helping Hand, Metronome, Mimic, Mirror Coat, Protect, Sketch, Sleep Talk, Snatch, Struggle, Thief, or Trick.",
3714
3716
  },
3715
3717
  gen2: {
3716
- desc: "A random move is selected for use, other than Counter, Destiny Bond, Detect, Endure, Metronome, Mimic, Mirror Coat, Protect, Sketch, Sleep Talk, Struggle, or Thief.",
3718
+ desc: "A random move is selected for use, other than Counter, Destiny Bond, Detect, Endure, Metronome, Mimic, Mirror Coat, Protect, Sketch, Sleep Talk, Struggle, Thief, or any move the user already knows.",
3717
3719
  },
3718
3720
  gen1: {
3719
3721
  desc: "A random move is selected for use, other than Metronome or Struggle.",
@@ -4167,6 +4169,7 @@ export const MovesText: {[k: string]: MoveText} = {
4167
4169
  },
4168
4170
 
4169
4171
  heal: "#memento",
4172
+ switchOut: "#uturn",
4170
4173
  },
4171
4174
  payback: {
4172
4175
  name: "Payback",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pkmn/sim",
3
- "version": "0.5.16",
3
+ "version": "0.5.19",
4
4
  "description": "An automatically generated extraction of just the simulator portion of Pokémon Showdown",
5
5
  "homepage": "https://psim.us",
6
6
  "main": "build/sim/index.js",
@@ -133,6 +133,8 @@ export class BattleActions {
133
133
  oldActive.isActive = false;
134
134
  oldActive.isStarted = false;
135
135
  oldActive.usedItemThisTurn = false;
136
+ oldActive.statsRaisedThisTurn = false;
137
+ oldActive.statsLoweredThisTurn = false;
136
138
  oldActive.position = pokemon.position;
137
139
  pokemon.position = pos;
138
140
  side.pokemon[pokemon.position] = pokemon;
@@ -178,7 +180,17 @@ export class BattleActions {
178
180
  }
179
181
  runSwitch(pokemon: Pokemon) {
180
182
  this.battle.runEvent('Swap', pokemon);
181
- this.battle.runEvent('SwitchIn', pokemon);
183
+
184
+ if (this.battle.gen >= 5) {
185
+ this.battle.runEvent('SwitchIn', pokemon);
186
+ }
187
+
188
+ this.battle.runEvent('EntryHazard', pokemon);
189
+
190
+ if (this.battle.gen <= 4) {
191
+ this.battle.runEvent('SwitchIn', pokemon);
192
+ }
193
+
182
194
  if (this.battle.gen <= 2 && !pokemon.side.faintedThisTurn && pokemon.draggedIn !== this.battle.turn) {
183
195
  this.battle.runEvent('AfterSwitchInSelf', pokemon);
184
196
  }
package/sim/battle.ts CHANGED
@@ -711,7 +711,7 @@ export class Battle {
711
711
  }
712
712
  }
713
713
 
714
- if (eventid === 'Invulnerability' || eventid === 'TryHit' || eventid === 'DamagingHit') {
714
+ if (['Invulnerability', 'TryHit', 'DamagingHit', 'EntryHazard'].includes(eventid)) {
715
715
  handlers.sort(Battle.compareLeftToRightOrder);
716
716
  } else if (fastExit) {
717
717
  handlers.sort(Battle.compareRedirectOrder);
@@ -2413,6 +2413,43 @@ export class Battle {
2413
2413
 
2414
2414
  this.add('start');
2415
2415
 
2416
+ // Change Zacian/Zamazenta into their Crowned formes
2417
+ for (const pokemon of this.getAllPokemon()) {
2418
+ let rawSpecies: Species | null = null;
2419
+ if (pokemon.species.id === 'zacian' && pokemon.item === 'rustedsword') {
2420
+ rawSpecies = this.dex.species.get('Zacian-Crowned');
2421
+ } else if (pokemon.species.id === 'zamazenta' && pokemon.item === 'rustedshield') {
2422
+ rawSpecies = this.dex.species.get('Zamazenta-Crowned');
2423
+ }
2424
+ if (!rawSpecies) continue;
2425
+ const species = pokemon.setSpecies(rawSpecies);
2426
+ if (!species) continue;
2427
+ pokemon.baseSpecies = rawSpecies;
2428
+ pokemon.details = species.name + (pokemon.level === 100 ? '' : ', L' + pokemon.level) +
2429
+ (pokemon.gender === '' ? '' : ', ' + pokemon.gender) + (pokemon.set.shiny ? ', shiny' : '');
2430
+ pokemon.setAbility(species.abilities['0'], null, true);
2431
+ pokemon.baseAbility = pokemon.ability;
2432
+
2433
+ const behemothMove: {[k: string]: string} = {
2434
+ 'Zacian-Crowned': 'behemothblade', 'Zamazenta-Crowned': 'behemothbash',
2435
+ };
2436
+ const ironHead = pokemon.baseMoves.indexOf('ironhead');
2437
+ if (ironHead >= 0) {
2438
+ const move = this.dex.moves.get(behemothMove[rawSpecies.name]);
2439
+ pokemon.baseMoveSlots[ironHead] = {
2440
+ move: move.name,
2441
+ id: move.id,
2442
+ pp: (move.noPPBoosts || move.isZ) ? move.pp : move.pp * 8 / 5,
2443
+ maxpp: (move.noPPBoosts || move.isZ) ? move.pp : move.pp * 8 / 5,
2444
+ target: move.target,
2445
+ disabled: false,
2446
+ disabledSource: '',
2447
+ used: false,
2448
+ };
2449
+ pokemon.moveSlots = pokemon.baseMoveSlots.slice();
2450
+ }
2451
+ }
2452
+
2416
2453
  if (this.format.onBattleStart) this.format.onBattleStart.call(this);
2417
2454
  for (const rule of this.ruleTable.keys()) {
2418
2455
  if ('+*-!'.includes(rule.charAt(0))) continue;
@@ -53,6 +53,7 @@ export interface EventMethods {
53
53
  onDragOut?: (this: Battle, pokemon: Pokemon, source?: Pokemon, move?: ActiveMove) => void;
54
54
  onEatItem?: (this: Battle, item: Item, pokemon: Pokemon) => void;
55
55
  onEffectiveness?: MoveEventMethods['onEffectiveness'];
56
+ onEntryHazard?: (this: Battle, pokemon: Pokemon) => void;
56
57
  onFaint?: CommonHandlers['VoidEffect'];
57
58
  onFlinch?: ((this: Battle, pokemon: Pokemon) => boolean | void) | boolean;
58
59
  onFractionalPriority?: CommonHandlers['ModifierSourceMove'] | -0.1;