@pkmn/sim 0.9.26 → 0.9.28
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.
- package/build/cjs/config/formats.js +79 -86
- package/build/cjs/config/formats.js.map +1 -1
- package/build/cjs/data/abilities.js +100 -116
- package/build/cjs/data/abilities.js.map +1 -1
- package/build/cjs/data/aliases.js +3 -2
- package/build/cjs/data/aliases.js.map +1 -1
- package/build/cjs/data/conditions.js +3 -3
- package/build/cjs/data/conditions.js.map +1 -1
- package/build/cjs/data/formats-data.js +12 -12
- package/build/cjs/data/formats-data.js.map +1 -1
- package/build/cjs/data/items.js +55 -25
- package/build/cjs/data/items.js.map +1 -1
- package/build/cjs/data/legality.js +275 -23
- package/build/cjs/data/legality.js.map +1 -1
- package/build/cjs/data/mods/gen1/moves.js.map +1 -1
- package/build/cjs/data/mods/gen1/scripts.js +2 -0
- package/build/cjs/data/mods/gen1/scripts.js.map +1 -1
- package/build/cjs/data/mods/gen2/moves.js +1 -1
- package/build/cjs/data/mods/gen2/moves.js.map +1 -1
- package/build/cjs/data/mods/gen3/abilities.js +0 -2
- package/build/cjs/data/mods/gen3/abilities.js.map +1 -1
- package/build/cjs/data/mods/gen3/moves.js.map +1 -1
- package/build/cjs/data/mods/gen4/abilities.js +1 -1
- package/build/cjs/data/mods/gen4/abilities.js.map +1 -1
- package/build/cjs/data/mods/gen4/formats-data.js +1 -1
- package/build/cjs/data/mods/gen4/formats-data.js.map +1 -1
- package/build/cjs/data/mods/gen4/moves.js +88 -0
- package/build/cjs/data/mods/gen4/moves.js.map +1 -1
- package/build/cjs/data/mods/gen4/scripts.js +26 -0
- package/build/cjs/data/mods/gen4/scripts.js.map +1 -1
- package/build/cjs/data/mods/gen5/conditions.js +1 -2
- package/build/cjs/data/mods/gen5/conditions.js.map +1 -1
- package/build/cjs/data/mods/gen5/formats-data.js +2 -2
- package/build/cjs/data/mods/gen5/formats-data.js.map +1 -1
- package/build/cjs/data/mods/gen6/moves.js.map +1 -1
- package/build/cjs/data/mods/gen8/abilities.js +0 -2
- package/build/cjs/data/mods/gen8/abilities.js.map +1 -1
- package/build/cjs/data/mods/gen8/moves.js +1 -1
- package/build/cjs/data/mods/gen8/moves.js.map +1 -1
- package/build/cjs/data/moves.js +22 -18
- package/build/cjs/data/moves.js.map +1 -1
- package/build/cjs/data/pokemongo.js +1 -1
- package/build/cjs/data/text/moves.js +1 -1
- package/build/cjs/data/text/moves.js.map +1 -1
- package/build/cjs/lib/utils.d.ts +8 -0
- package/build/cjs/lib/utils.js +21 -2
- package/build/cjs/lib/utils.js.map +1 -1
- package/build/cjs/sim/battle-actions.js +30 -39
- package/build/cjs/sim/battle-actions.js.map +1 -1
- package/build/cjs/sim/battle-queue.d.ts +1 -1
- package/build/cjs/sim/battle-queue.js +0 -2
- package/build/cjs/sim/battle-queue.js.map +1 -1
- package/build/cjs/sim/battle-stream.js +2 -3
- package/build/cjs/sim/battle-stream.js.map +1 -1
- package/build/cjs/sim/battle.d.ts +13 -7
- package/build/cjs/sim/battle.js +197 -70
- package/build/cjs/sim/battle.js.map +1 -1
- package/build/cjs/sim/dex-abilities.d.ts +0 -1
- package/build/cjs/sim/dex-abilities.js +2 -2
- package/build/cjs/sim/dex-abilities.js.map +1 -1
- package/build/cjs/sim/dex-conditions.d.ts +11 -3
- package/build/cjs/sim/dex-conditions.js +2 -2
- package/build/cjs/sim/dex-conditions.js.map +1 -1
- package/build/cjs/sim/dex-data.js +7 -7
- package/build/cjs/sim/dex-data.js.map +1 -1
- package/build/cjs/sim/dex-formats.d.ts +2 -1
- package/build/cjs/sim/dex-formats.js.map +1 -1
- package/build/cjs/sim/dex-items.d.ts +3 -1
- package/build/cjs/sim/dex-items.js +3 -2
- package/build/cjs/sim/dex-items.js.map +1 -1
- package/build/cjs/sim/dex-moves.js +4 -4
- package/build/cjs/sim/dex-moves.js.map +1 -1
- package/build/cjs/sim/exported-global-types.d.ts +6 -0
- package/build/cjs/sim/field.js +9 -9
- package/build/cjs/sim/field.js.map +1 -1
- package/build/cjs/sim/global-types.d.ts +6 -0
- package/build/cjs/sim/pokemon.d.ts +8 -4
- package/build/cjs/sim/pokemon.js +62 -47
- package/build/cjs/sim/pokemon.js.map +1 -1
- package/build/cjs/sim/prng.d.ts +57 -18
- package/build/cjs/sim/prng.js +171 -38
- package/build/cjs/sim/prng.js.map +1 -1
- package/build/cjs/sim/side.js +9 -6
- package/build/cjs/sim/side.js.map +1 -1
- package/build/cjs/sim/state.js +1 -1
- package/build/cjs/sim/state.js.map +1 -1
- package/build/cjs/sim/team-validator.js +16 -17
- package/build/cjs/sim/team-validator.js.map +1 -1
- package/build/cjs/sim/tools/exhaustive-runner.js +11 -12
- package/build/cjs/sim/tools/exhaustive-runner.js.map +1 -1
- package/build/cjs/sim/tools/random-player-ai.js +5 -5
- package/build/cjs/sim/tools/random-player-ai.js.map +1 -1
- package/build/cjs/sim/tools/runner.js +7 -8
- package/build/cjs/sim/tools/runner.js.map +1 -1
- package/build/esm/config/formats.mjs +79 -86
- package/build/esm/config/formats.mjs.map +1 -1
- package/build/esm/data/abilities.mjs +100 -116
- package/build/esm/data/abilities.mjs.map +1 -1
- package/build/esm/data/aliases.mjs +3 -2
- package/build/esm/data/aliases.mjs.map +1 -1
- package/build/esm/data/conditions.mjs +3 -3
- package/build/esm/data/conditions.mjs.map +1 -1
- package/build/esm/data/formats-data.mjs +12 -12
- package/build/esm/data/formats-data.mjs.map +1 -1
- package/build/esm/data/items.mjs +55 -25
- package/build/esm/data/items.mjs.map +1 -1
- package/build/esm/data/legality.mjs +275 -23
- package/build/esm/data/legality.mjs.map +1 -1
- package/build/esm/data/mods/gen1/moves.mjs.map +1 -1
- package/build/esm/data/mods/gen1/scripts.mjs +2 -0
- package/build/esm/data/mods/gen1/scripts.mjs.map +1 -1
- package/build/esm/data/mods/gen2/moves.mjs +1 -1
- package/build/esm/data/mods/gen2/moves.mjs.map +1 -1
- package/build/esm/data/mods/gen3/abilities.mjs +0 -2
- package/build/esm/data/mods/gen3/abilities.mjs.map +1 -1
- package/build/esm/data/mods/gen3/moves.mjs.map +1 -1
- package/build/esm/data/mods/gen4/abilities.mjs +1 -1
- package/build/esm/data/mods/gen4/abilities.mjs.map +1 -1
- package/build/esm/data/mods/gen4/formats-data.mjs +1 -1
- package/build/esm/data/mods/gen4/formats-data.mjs.map +1 -1
- package/build/esm/data/mods/gen4/moves.mjs +88 -0
- package/build/esm/data/mods/gen4/moves.mjs.map +1 -1
- package/build/esm/data/mods/gen4/scripts.mjs +26 -0
- package/build/esm/data/mods/gen4/scripts.mjs.map +1 -1
- package/build/esm/data/mods/gen5/conditions.mjs +1 -2
- package/build/esm/data/mods/gen5/conditions.mjs.map +1 -1
- package/build/esm/data/mods/gen5/formats-data.mjs +2 -2
- package/build/esm/data/mods/gen5/formats-data.mjs.map +1 -1
- package/build/esm/data/mods/gen6/moves.mjs.map +1 -1
- package/build/esm/data/mods/gen8/abilities.mjs +0 -2
- package/build/esm/data/mods/gen8/abilities.mjs.map +1 -1
- package/build/esm/data/mods/gen8/moves.mjs +1 -1
- package/build/esm/data/mods/gen8/moves.mjs.map +1 -1
- package/build/esm/data/moves.mjs +22 -18
- package/build/esm/data/moves.mjs.map +1 -1
- package/build/esm/data/pokemongo.mjs +1 -1
- package/build/esm/data/text/moves.mjs +1 -1
- package/build/esm/data/text/moves.mjs.map +1 -1
- package/build/esm/lib/utils.d.mts +8 -0
- package/build/esm/lib/utils.mjs +18 -2
- package/build/esm/lib/utils.mjs.map +1 -1
- package/build/esm/sim/battle-actions.mjs +30 -39
- package/build/esm/sim/battle-actions.mjs.map +1 -1
- package/build/esm/sim/battle-queue.d.mts +1 -1
- package/build/esm/sim/battle-queue.mjs +0 -2
- package/build/esm/sim/battle-queue.mjs.map +1 -1
- package/build/esm/sim/battle-stream.mjs +2 -3
- package/build/esm/sim/battle-stream.mjs.map +1 -1
- package/build/esm/sim/battle.d.mts +13 -7
- package/build/esm/sim/battle.mjs +196 -69
- package/build/esm/sim/battle.mjs.map +1 -1
- package/build/esm/sim/dex-abilities.d.mts +0 -1
- package/build/esm/sim/dex-abilities.mjs +1 -1
- package/build/esm/sim/dex-abilities.mjs.map +1 -1
- package/build/esm/sim/dex-conditions.d.mts +11 -3
- package/build/esm/sim/dex-conditions.mjs +1 -1
- package/build/esm/sim/dex-conditions.mjs.map +1 -1
- package/build/esm/sim/dex-data.mjs +1 -1
- package/build/esm/sim/dex-data.mjs.map +1 -1
- package/build/esm/sim/dex-formats.d.mts +2 -1
- package/build/esm/sim/dex-formats.mjs.map +1 -1
- package/build/esm/sim/dex-items.d.mts +3 -1
- package/build/esm/sim/dex-items.mjs +2 -1
- package/build/esm/sim/dex-items.mjs.map +1 -1
- package/build/esm/sim/dex-moves.mjs +1 -1
- package/build/esm/sim/dex-moves.mjs.map +1 -1
- package/build/esm/sim/exported-global-types.d.mts +6 -0
- package/build/esm/sim/field.mjs +9 -9
- package/build/esm/sim/field.mjs.map +1 -1
- package/build/esm/sim/global-types.d.mts +6 -0
- package/build/esm/sim/pokemon.d.mts +8 -4
- package/build/esm/sim/pokemon.mjs +62 -47
- package/build/esm/sim/pokemon.mjs.map +1 -1
- package/build/esm/sim/prng.d.mts +57 -18
- package/build/esm/sim/prng.mjs +134 -36
- package/build/esm/sim/prng.mjs.map +1 -1
- package/build/esm/sim/side.mjs +8 -5
- package/build/esm/sim/side.mjs.map +1 -1
- package/build/esm/sim/state.mjs +1 -1
- package/build/esm/sim/state.mjs.map +1 -1
- package/build/esm/sim/team-validator.mjs +10 -11
- package/build/esm/sim/team-validator.mjs.map +1 -1
- package/build/esm/sim/tools/exhaustive-runner.mjs +11 -12
- package/build/esm/sim/tools/exhaustive-runner.mjs.map +1 -1
- package/build/esm/sim/tools/random-player-ai.mjs +5 -5
- package/build/esm/sim/tools/random-player-ai.mjs.map +1 -1
- package/build/esm/sim/tools/runner.mjs +7 -8
- package/build/esm/sim/tools/runner.mjs.map +1 -1
- package/package.json +3 -2
|
@@ -89,15 +89,12 @@ export const Abilities = {
|
|
|
89
89
|
},
|
|
90
90
|
airlock: {
|
|
91
91
|
onSwitchIn(pokemon) {
|
|
92
|
-
|
|
92
|
+
// Air Lock does not activate when Skill Swapped or when Neutralizing Gas leaves the field
|
|
93
|
+
this.add('-ability', pokemon, 'Air Lock');
|
|
94
|
+
this.effect.onStart.call(this, pokemon);
|
|
93
95
|
},
|
|
94
96
|
onStart(pokemon) {
|
|
95
|
-
// Air Lock does not activate when Skill Swapped or when Neutralizing Gas leaves the field
|
|
96
97
|
pokemon.abilityState.ending = false; // Clear the ending flag
|
|
97
|
-
if (this.effectState.switchingIn) {
|
|
98
|
-
this.add('-ability', pokemon, 'Air Lock');
|
|
99
|
-
this.effectState.switchingIn = false;
|
|
100
|
-
}
|
|
101
98
|
this.eachEvent('WeatherChange', this.effect);
|
|
102
99
|
},
|
|
103
100
|
onEnd(pokemon) {
|
|
@@ -259,11 +256,7 @@ export const Abilities = {
|
|
|
259
256
|
num: 165,
|
|
260
257
|
},
|
|
261
258
|
asoneglastrier: {
|
|
262
|
-
|
|
263
|
-
this.add('-ability', pokemon, 'As One');
|
|
264
|
-
this.add('-ability', pokemon, 'Unnerve');
|
|
265
|
-
this.effectState.unnerved = true;
|
|
266
|
-
},
|
|
259
|
+
onSwitchInPriority: 1,
|
|
267
260
|
onStart(pokemon) {
|
|
268
261
|
if (this.effectState.unnerved)
|
|
269
262
|
return;
|
|
@@ -288,11 +281,7 @@ export const Abilities = {
|
|
|
288
281
|
num: 266,
|
|
289
282
|
},
|
|
290
283
|
asonespectrier: {
|
|
291
|
-
|
|
292
|
-
this.add('-ability', pokemon, 'As One');
|
|
293
|
-
this.add('-ability', pokemon, 'Unnerve');
|
|
294
|
-
this.effectState.unnerved = true;
|
|
295
|
-
},
|
|
284
|
+
onSwitchInPriority: 1,
|
|
296
285
|
onStart(pokemon) {
|
|
297
286
|
if (this.effectState.unnerved)
|
|
298
287
|
return;
|
|
@@ -565,15 +554,12 @@ export const Abilities = {
|
|
|
565
554
|
},
|
|
566
555
|
cloudnine: {
|
|
567
556
|
onSwitchIn(pokemon) {
|
|
568
|
-
|
|
557
|
+
// Cloud Nine does not activate when Skill Swapped or when Neutralizing Gas leaves the field
|
|
558
|
+
this.add('-ability', pokemon, 'Cloud Nine');
|
|
559
|
+
this.effect.onStart.call(this, pokemon);
|
|
569
560
|
},
|
|
570
561
|
onStart(pokemon) {
|
|
571
|
-
// Cloud Nine does not activate when Skill Swapped or when Neutralizing Gas leaves the field
|
|
572
562
|
pokemon.abilityState.ending = false; // Clear the ending flag
|
|
573
|
-
if (this.effectState.switchingIn) {
|
|
574
|
-
this.add('-ability', pokemon, 'Cloud Nine');
|
|
575
|
-
this.effectState.switchingIn = false;
|
|
576
|
-
}
|
|
577
563
|
this.eachEvent('WeatherChange', this.effect);
|
|
578
564
|
},
|
|
579
565
|
onEnd(pokemon) {
|
|
@@ -627,10 +613,22 @@ export const Abilities = {
|
|
|
627
613
|
num: 213,
|
|
628
614
|
},
|
|
629
615
|
commander: {
|
|
616
|
+
onAnySwitchInPriority: -2,
|
|
617
|
+
onAnySwitchIn() {
|
|
618
|
+
this.effect.onUpdate.call(this, this.effectState.target);
|
|
619
|
+
},
|
|
620
|
+
onStart(pokemon) {
|
|
621
|
+
this.effect.onUpdate.call(this, pokemon);
|
|
622
|
+
},
|
|
630
623
|
onUpdate(pokemon) {
|
|
631
624
|
if (this.gameType !== 'doubles')
|
|
632
625
|
return;
|
|
626
|
+
// don't run between when a Pokemon switches in and the resulting onSwitchIn event
|
|
627
|
+
if (this.queue.peek()?.choice === 'runSwitch')
|
|
628
|
+
return;
|
|
633
629
|
const ally = pokemon.allies()[0];
|
|
630
|
+
if (pokemon.switchFlag || ally?.switchFlag)
|
|
631
|
+
return;
|
|
634
632
|
if (!ally || pokemon.baseSpecies.baseSpecies !== 'Tatsugiri' || ally.baseSpecies.baseSpecies !== 'Dondozo') {
|
|
635
633
|
// Handle any edge cases
|
|
636
634
|
if (pokemon.getVolatile('commanding'))
|
|
@@ -716,6 +714,7 @@ export const Abilities = {
|
|
|
716
714
|
num: 212,
|
|
717
715
|
},
|
|
718
716
|
costar: {
|
|
717
|
+
onSwitchInPriority: -2,
|
|
719
718
|
onStart(pokemon) {
|
|
720
719
|
const ally = pokemon.allies()[0];
|
|
721
720
|
if (!ally)
|
|
@@ -1098,12 +1097,8 @@ export const Abilities = {
|
|
|
1098
1097
|
},
|
|
1099
1098
|
drizzle: {
|
|
1100
1099
|
onStart(source) {
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
return;
|
|
1104
|
-
if (action.choice !== 'runSwitch' && action.choice !== 'runPrimal')
|
|
1105
|
-
break;
|
|
1106
|
-
}
|
|
1100
|
+
if (source.species.id === 'kyogre' && source.item === 'blueorb')
|
|
1101
|
+
return;
|
|
1107
1102
|
this.field.setWeather('raindance');
|
|
1108
1103
|
},
|
|
1109
1104
|
flags: {},
|
|
@@ -1113,12 +1108,8 @@ export const Abilities = {
|
|
|
1113
1108
|
},
|
|
1114
1109
|
drought: {
|
|
1115
1110
|
onStart(source) {
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
return;
|
|
1119
|
-
if (action.choice !== 'runSwitch' && action.choice !== 'runPrimal')
|
|
1120
|
-
break;
|
|
1121
|
-
}
|
|
1111
|
+
if (source.species.id === 'groudon' && source.item === 'redorb')
|
|
1112
|
+
return;
|
|
1122
1113
|
this.field.setWeather('sunnyday');
|
|
1123
1114
|
},
|
|
1124
1115
|
flags: {},
|
|
@@ -1218,14 +1209,12 @@ export const Abilities = {
|
|
|
1218
1209
|
},
|
|
1219
1210
|
embodyaspectcornerstone: {
|
|
1220
1211
|
onStart(pokemon) {
|
|
1221
|
-
if (pokemon.baseSpecies.name === 'Ogerpon-Cornerstone-Tera' &&
|
|
1222
|
-
this.effectState.embodied
|
|
1212
|
+
if (pokemon.baseSpecies.name === 'Ogerpon-Cornerstone-Tera' &&
|
|
1213
|
+
this.effectState.embodied !== pokemon.previouslySwitchedIn) {
|
|
1214
|
+
this.effectState.embodied = pokemon.previouslySwitchedIn;
|
|
1223
1215
|
this.boost({ def: 1 }, pokemon);
|
|
1224
1216
|
}
|
|
1225
1217
|
},
|
|
1226
|
-
onSwitchIn() {
|
|
1227
|
-
delete this.effectState.embodied;
|
|
1228
|
-
},
|
|
1229
1218
|
flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, notransform: 1 },
|
|
1230
1219
|
name: "Embody Aspect (Cornerstone)",
|
|
1231
1220
|
rating: 3.5,
|
|
@@ -1233,14 +1222,12 @@ export const Abilities = {
|
|
|
1233
1222
|
},
|
|
1234
1223
|
embodyaspecthearthflame: {
|
|
1235
1224
|
onStart(pokemon) {
|
|
1236
|
-
if (pokemon.baseSpecies.name === 'Ogerpon-Hearthflame-Tera' &&
|
|
1237
|
-
this.effectState.embodied
|
|
1225
|
+
if (pokemon.baseSpecies.name === 'Ogerpon-Hearthflame-Tera' &&
|
|
1226
|
+
this.effectState.embodied !== pokemon.previouslySwitchedIn) {
|
|
1227
|
+
this.effectState.embodied = pokemon.previouslySwitchedIn;
|
|
1238
1228
|
this.boost({ atk: 1 }, pokemon);
|
|
1239
1229
|
}
|
|
1240
1230
|
},
|
|
1241
|
-
onSwitchIn() {
|
|
1242
|
-
delete this.effectState.embodied;
|
|
1243
|
-
},
|
|
1244
1231
|
flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, notransform: 1 },
|
|
1245
1232
|
name: "Embody Aspect (Hearthflame)",
|
|
1246
1233
|
rating: 3.5,
|
|
@@ -1248,14 +1235,12 @@ export const Abilities = {
|
|
|
1248
1235
|
},
|
|
1249
1236
|
embodyaspectteal: {
|
|
1250
1237
|
onStart(pokemon) {
|
|
1251
|
-
if (pokemon.baseSpecies.name === 'Ogerpon-Teal-Tera' &&
|
|
1252
|
-
this.effectState.embodied
|
|
1238
|
+
if (pokemon.baseSpecies.name === 'Ogerpon-Teal-Tera' &&
|
|
1239
|
+
this.effectState.embodied !== pokemon.previouslySwitchedIn) {
|
|
1240
|
+
this.effectState.embodied = pokemon.previouslySwitchedIn;
|
|
1253
1241
|
this.boost({ spe: 1 }, pokemon);
|
|
1254
1242
|
}
|
|
1255
1243
|
},
|
|
1256
|
-
onSwitchIn() {
|
|
1257
|
-
delete this.effectState.embodied;
|
|
1258
|
-
},
|
|
1259
1244
|
flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, notransform: 1 },
|
|
1260
1245
|
name: "Embody Aspect (Teal)",
|
|
1261
1246
|
rating: 3.5,
|
|
@@ -1263,14 +1248,12 @@ export const Abilities = {
|
|
|
1263
1248
|
},
|
|
1264
1249
|
embodyaspectwellspring: {
|
|
1265
1250
|
onStart(pokemon) {
|
|
1266
|
-
if (pokemon.baseSpecies.name === 'Ogerpon-Wellspring-Tera' &&
|
|
1267
|
-
this.effectState.embodied
|
|
1251
|
+
if (pokemon.baseSpecies.name === 'Ogerpon-Wellspring-Tera' &&
|
|
1252
|
+
this.effectState.embodied !== pokemon.previouslySwitchedIn) {
|
|
1253
|
+
this.effectState.embodied = pokemon.previouslySwitchedIn;
|
|
1268
1254
|
this.boost({ spd: 1 }, pokemon);
|
|
1269
1255
|
}
|
|
1270
1256
|
},
|
|
1271
|
-
onSwitchIn() {
|
|
1272
|
-
delete this.effectState.embodied;
|
|
1273
|
-
},
|
|
1274
1257
|
flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, notransform: 1 },
|
|
1275
1258
|
name: "Embody Aspect (Wellspring)",
|
|
1276
1259
|
rating: 3.5,
|
|
@@ -1393,6 +1376,7 @@ export const Abilities = {
|
|
|
1393
1376
|
num: 18,
|
|
1394
1377
|
},
|
|
1395
1378
|
flowergift: {
|
|
1379
|
+
onSwitchInPriority: -2,
|
|
1396
1380
|
onStart(pokemon) {
|
|
1397
1381
|
this.singleEvent('WeatherChange', this.effect, this.effectState, pokemon);
|
|
1398
1382
|
},
|
|
@@ -1488,6 +1472,7 @@ export const Abilities = {
|
|
|
1488
1472
|
num: 218,
|
|
1489
1473
|
},
|
|
1490
1474
|
forecast: {
|
|
1475
|
+
onSwitchInPriority: -2,
|
|
1491
1476
|
onStart(pokemon) {
|
|
1492
1477
|
this.singleEvent('WeatherChange', this.effect, this.effectState, pokemon);
|
|
1493
1478
|
},
|
|
@@ -1913,6 +1898,7 @@ export const Abilities = {
|
|
|
1913
1898
|
num: 118,
|
|
1914
1899
|
},
|
|
1915
1900
|
hospitality: {
|
|
1901
|
+
onSwitchInPriority: -2,
|
|
1916
1902
|
onStart(pokemon) {
|
|
1917
1903
|
for (const ally of pokemon.adjacentAllies()) {
|
|
1918
1904
|
this.heal(ally.baseMaxhp / 4, ally, pokemon);
|
|
@@ -2010,6 +1996,7 @@ export const Abilities = {
|
|
|
2010
1996
|
num: 115,
|
|
2011
1997
|
},
|
|
2012
1998
|
iceface: {
|
|
1999
|
+
onSwitchInPriority: -2,
|
|
2013
2000
|
onStart(pokemon) {
|
|
2014
2001
|
if (this.field.isWeather(['hail', 'snow']) && pokemon.species.id === 'eiscuenoice') {
|
|
2015
2002
|
this.add('-activate', pokemon, 'ability: Ice Face');
|
|
@@ -2128,8 +2115,7 @@ export const Abilities = {
|
|
|
2128
2115
|
if (pokemon.illusion) {
|
|
2129
2116
|
this.debug('illusion cleared');
|
|
2130
2117
|
pokemon.illusion = null;
|
|
2131
|
-
const details = pokemon.
|
|
2132
|
-
(pokemon.gender === '' ? '' : ', ' + pokemon.gender) + (pokemon.set.shiny ? ', shiny' : '');
|
|
2118
|
+
const details = pokemon.getUpdatedDetails();
|
|
2133
2119
|
this.add('replace', pokemon, details);
|
|
2134
2120
|
this.add('-end', pokemon, 'Illusion');
|
|
2135
2121
|
if (this.ruleTable.has('illusionlevelmod')) {
|
|
@@ -2167,20 +2153,14 @@ export const Abilities = {
|
|
|
2167
2153
|
},
|
|
2168
2154
|
imposter: {
|
|
2169
2155
|
onSwitchIn(pokemon) {
|
|
2170
|
-
this.effectState.switchingIn = true;
|
|
2171
|
-
},
|
|
2172
|
-
onStart(pokemon) {
|
|
2173
2156
|
// Imposter does not activate when Skill Swapped or when Neutralizing Gas leaves the field
|
|
2174
|
-
|
|
2175
|
-
return;
|
|
2176
|
-
// copies across in doubles/triples
|
|
2157
|
+
// Imposter copies across in doubles/triples
|
|
2177
2158
|
// (also copies across in multibattle and diagonally in free-for-all,
|
|
2178
2159
|
// but side.foe already takes care of those)
|
|
2179
2160
|
const target = pokemon.side.foe.active[pokemon.side.foe.active.length - 1 - pokemon.position];
|
|
2180
2161
|
if (target) {
|
|
2181
2162
|
pokemon.transformInto(target, this.dex.abilities.get('imposter'));
|
|
2182
2163
|
}
|
|
2183
|
-
this.effectState.switchingIn = false;
|
|
2184
2164
|
},
|
|
2185
2165
|
flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1 },
|
|
2186
2166
|
name: "Imposter",
|
|
@@ -2339,6 +2319,9 @@ export const Abilities = {
|
|
|
2339
2319
|
num: 51,
|
|
2340
2320
|
},
|
|
2341
2321
|
klutz: {
|
|
2322
|
+
// Klutz isn't technically active immediately in-game, but it activates early enough to beat all items
|
|
2323
|
+
// we should keep an eye out in future gens for items that activate on switch-in before Unnerve
|
|
2324
|
+
onSwitchInPriority: 1,
|
|
2342
2325
|
// Item suppression implemented in Pokemon.ignoringItem() within sim/pokemon.js
|
|
2343
2326
|
onStart(pokemon) {
|
|
2344
2327
|
this.singleEvent('End', pokemon.getItem(), pokemon.itemState, pokemon);
|
|
@@ -2377,7 +2360,7 @@ export const Abilities = {
|
|
|
2377
2360
|
},
|
|
2378
2361
|
libero: {
|
|
2379
2362
|
onPrepareHit(source, target, move) {
|
|
2380
|
-
if (this.effectState.libero)
|
|
2363
|
+
if (this.effectState.libero === source.previouslySwitchedIn)
|
|
2381
2364
|
return;
|
|
2382
2365
|
if (move.hasBounced || move.flags['futuremove'] || move.sourceEffect === 'snatch' || move.callsMove)
|
|
2383
2366
|
return;
|
|
@@ -2385,13 +2368,10 @@ export const Abilities = {
|
|
|
2385
2368
|
if (type && type !== '???' && source.getTypes().join() !== type) {
|
|
2386
2369
|
if (!source.setType(type))
|
|
2387
2370
|
return;
|
|
2388
|
-
this.effectState.libero =
|
|
2371
|
+
this.effectState.libero = source.previouslySwitchedIn;
|
|
2389
2372
|
this.add('-start', source, 'typechange', type, '[from] ability: Libero');
|
|
2390
2373
|
}
|
|
2391
2374
|
},
|
|
2392
|
-
onSwitchIn() {
|
|
2393
|
-
delete this.effectState.libero;
|
|
2394
|
-
},
|
|
2395
2375
|
flags: {},
|
|
2396
2376
|
name: "Libero",
|
|
2397
2377
|
rating: 4,
|
|
@@ -2642,6 +2622,7 @@ export const Abilities = {
|
|
|
2642
2622
|
num: 196,
|
|
2643
2623
|
},
|
|
2644
2624
|
mimicry: {
|
|
2625
|
+
onSwitchInPriority: -1,
|
|
2645
2626
|
onStart(pokemon) {
|
|
2646
2627
|
this.singleEvent('TerrainChange', this.effect, this.effectState, pokemon);
|
|
2647
2628
|
},
|
|
@@ -2978,7 +2959,8 @@ export const Abilities = {
|
|
|
2978
2959
|
},
|
|
2979
2960
|
neutralizinggas: {
|
|
2980
2961
|
// Ability suppression implemented in sim/pokemon.ts:Pokemon#ignoringAbility
|
|
2981
|
-
|
|
2962
|
+
onSwitchInPriority: 2,
|
|
2963
|
+
onSwitchIn(pokemon) {
|
|
2982
2964
|
this.add('-ability', pokemon, 'Neutralizing Gas');
|
|
2983
2965
|
pokemon.abilityState.ending = false;
|
|
2984
2966
|
const strongWeathers = ['desolateland', 'primordialsea', 'deltastream'];
|
|
@@ -3119,17 +3101,38 @@ export const Abilities = {
|
|
|
3119
3101
|
onFoeAfterBoost(boost, target, source, effect) {
|
|
3120
3102
|
if (effect?.name === 'Opportunist' || effect?.name === 'Mirror Herb')
|
|
3121
3103
|
return;
|
|
3122
|
-
|
|
3123
|
-
|
|
3104
|
+
if (!this.effectState.boosts)
|
|
3105
|
+
this.effectState.boosts = {};
|
|
3106
|
+
const boostPlus = this.effectState.boosts;
|
|
3124
3107
|
let i;
|
|
3125
3108
|
for (i in boost) {
|
|
3126
3109
|
if (boost[i] > 0) {
|
|
3127
|
-
|
|
3110
|
+
boostPlus[i] = (boostPlus[i] || 0) + boost[i];
|
|
3128
3111
|
}
|
|
3129
3112
|
}
|
|
3130
|
-
|
|
3113
|
+
},
|
|
3114
|
+
onAnySwitchInPriority: -3,
|
|
3115
|
+
onAnySwitchIn() {
|
|
3116
|
+
if (!this.effectState.boosts)
|
|
3131
3117
|
return;
|
|
3132
|
-
this.boost(
|
|
3118
|
+
this.boost(this.effectState.boosts, this.effectState.target);
|
|
3119
|
+
delete this.effectState.boosts;
|
|
3120
|
+
},
|
|
3121
|
+
onAnyAfterMove() {
|
|
3122
|
+
if (!this.effectState.boosts)
|
|
3123
|
+
return;
|
|
3124
|
+
this.boost(this.effectState.boosts, this.effectState.target);
|
|
3125
|
+
delete this.effectState.boosts;
|
|
3126
|
+
},
|
|
3127
|
+
onResidualOrder: 29,
|
|
3128
|
+
onResidual(pokemon) {
|
|
3129
|
+
if (!this.effectState.boosts)
|
|
3130
|
+
return;
|
|
3131
|
+
this.boost(this.effectState.boosts, this.effectState.target);
|
|
3132
|
+
delete this.effectState.boosts;
|
|
3133
|
+
},
|
|
3134
|
+
onEnd() {
|
|
3135
|
+
delete this.effectState.boosts;
|
|
3133
3136
|
},
|
|
3134
3137
|
flags: {},
|
|
3135
3138
|
name: "Opportunist",
|
|
@@ -3256,11 +3259,8 @@ export const Abilities = {
|
|
|
3256
3259
|
pokemon.cureStatus();
|
|
3257
3260
|
}
|
|
3258
3261
|
},
|
|
3259
|
-
|
|
3260
|
-
|
|
3261
|
-
this.add('-activate', this.effectState.target, 'ability: Pastel Veil');
|
|
3262
|
-
pokemon.cureStatus();
|
|
3263
|
-
}
|
|
3262
|
+
onAnySwitchIn() {
|
|
3263
|
+
this.effect.onStart.call(this, this.effectState.target);
|
|
3264
3264
|
},
|
|
3265
3265
|
onSetStatus(status, target, source, effect) {
|
|
3266
3266
|
if (!['psn', 'tox'].includes(status.id))
|
|
@@ -3567,7 +3567,7 @@ export const Abilities = {
|
|
|
3567
3567
|
},
|
|
3568
3568
|
protean: {
|
|
3569
3569
|
onPrepareHit(source, target, move) {
|
|
3570
|
-
if (this.effectState.protean)
|
|
3570
|
+
if (this.effectState.protean === source.previouslySwitchedIn)
|
|
3571
3571
|
return;
|
|
3572
3572
|
if (move.hasBounced || move.flags['futuremove'] || move.sourceEffect === 'snatch' || move.callsMove)
|
|
3573
3573
|
return;
|
|
@@ -3575,19 +3575,17 @@ export const Abilities = {
|
|
|
3575
3575
|
if (type && type !== '???' && source.getTypes().join() !== type) {
|
|
3576
3576
|
if (!source.setType(type))
|
|
3577
3577
|
return;
|
|
3578
|
-
this.effectState.protean =
|
|
3578
|
+
this.effectState.protean = source.previouslySwitchedIn;
|
|
3579
3579
|
this.add('-start', source, 'typechange', type, '[from] ability: Protean');
|
|
3580
3580
|
}
|
|
3581
3581
|
},
|
|
3582
|
-
onSwitchIn(pokemon) {
|
|
3583
|
-
delete this.effectState.protean;
|
|
3584
|
-
},
|
|
3585
3582
|
flags: {},
|
|
3586
3583
|
name: "Protean",
|
|
3587
3584
|
rating: 4,
|
|
3588
3585
|
num: 168,
|
|
3589
3586
|
},
|
|
3590
3587
|
protosynthesis: {
|
|
3588
|
+
onSwitchInPriority: -2,
|
|
3591
3589
|
onStart(pokemon) {
|
|
3592
3590
|
this.singleEvent('WeatherChange', this.effect, this.effectState, pokemon);
|
|
3593
3591
|
},
|
|
@@ -3596,8 +3594,7 @@ export const Abilities = {
|
|
|
3596
3594
|
if (this.field.isWeather('sunnyday')) {
|
|
3597
3595
|
pokemon.addVolatile('protosynthesis');
|
|
3598
3596
|
}
|
|
3599
|
-
else if (!pokemon.volatiles['protosynthesis']?.fromBooster && this.field.
|
|
3600
|
-
// Protosynthesis will not deactivite if Sun is suppressed, hence the direct ID check (isWeather respects supression)
|
|
3597
|
+
else if (!pokemon.volatiles['protosynthesis']?.fromBooster && !this.field.isWeather('sunnyday')) {
|
|
3601
3598
|
pokemon.removeVolatile('protosynthesis');
|
|
3602
3599
|
}
|
|
3603
3600
|
},
|
|
@@ -3732,6 +3729,7 @@ export const Abilities = {
|
|
|
3732
3729
|
num: 272,
|
|
3733
3730
|
},
|
|
3734
3731
|
quarkdrive: {
|
|
3732
|
+
onSwitchInPriority: -2,
|
|
3735
3733
|
onStart(pokemon) {
|
|
3736
3734
|
this.singleEvent('TerrainChange', this.effect, this.effectState, pokemon);
|
|
3737
3735
|
},
|
|
@@ -4147,6 +4145,7 @@ export const Abilities = {
|
|
|
4147
4145
|
num: 157,
|
|
4148
4146
|
},
|
|
4149
4147
|
schooling: {
|
|
4148
|
+
onSwitchInPriority: -1,
|
|
4150
4149
|
onStart(pokemon) {
|
|
4151
4150
|
if (pokemon.baseSpecies.baseSpecies !== 'Wishiwashi' || pokemon.level < 20 || pokemon.transformed)
|
|
4152
4151
|
return;
|
|
@@ -4350,6 +4349,7 @@ export const Abilities = {
|
|
|
4350
4349
|
num: 19,
|
|
4351
4350
|
},
|
|
4352
4351
|
shieldsdown: {
|
|
4352
|
+
onSwitchInPriority: -1,
|
|
4353
4353
|
onStart(pokemon) {
|
|
4354
4354
|
if (pokemon.baseSpecies.baseSpecies !== 'Minior' || pokemon.transformed)
|
|
4355
4355
|
return;
|
|
@@ -5092,21 +5092,7 @@ export const Abilities = {
|
|
|
5092
5092
|
num: 309,
|
|
5093
5093
|
},
|
|
5094
5094
|
terashell: {
|
|
5095
|
-
|
|
5096
|
-
if (!target || target.species.name !== 'Terapagos-Terastal')
|
|
5097
|
-
return;
|
|
5098
|
-
if (this.effectState.resisted)
|
|
5099
|
-
return -1; // all hits of multi-hit move should be not very effective
|
|
5100
|
-
if (move.category === 'Status' || move.id === 'struggle')
|
|
5101
|
-
return;
|
|
5102
|
-
if (!target.runImmunity(move.type))
|
|
5103
|
-
return; // immunity has priority
|
|
5104
|
-
if (target.hp < target.maxhp)
|
|
5105
|
-
return;
|
|
5106
|
-
this.add('-activate', target, 'ability: Tera Shell');
|
|
5107
|
-
this.effectState.resisted = true;
|
|
5108
|
-
return -1;
|
|
5109
|
-
},
|
|
5095
|
+
// effectiveness implemented in sim/pokemon.ts:Pokemon#runEffectiveness
|
|
5110
5096
|
onAnyAfterMove() {
|
|
5111
5097
|
this.effectState.resisted = false;
|
|
5112
5098
|
},
|
|
@@ -5116,12 +5102,14 @@ export const Abilities = {
|
|
|
5116
5102
|
num: 308,
|
|
5117
5103
|
},
|
|
5118
5104
|
terashift: {
|
|
5119
|
-
|
|
5105
|
+
onSwitchInPriority: 2,
|
|
5106
|
+
onSwitchIn(pokemon) {
|
|
5120
5107
|
if (pokemon.baseSpecies.baseSpecies !== 'Terapagos')
|
|
5121
5108
|
return;
|
|
5122
5109
|
if (pokemon.species.forme !== 'Terastal') {
|
|
5123
5110
|
this.add('-activate', pokemon, 'ability: Tera Shift');
|
|
5124
5111
|
pokemon.formeChange('Terapagos-Terastal', this.effect, true);
|
|
5112
|
+
pokemon.regressionForme = false;
|
|
5125
5113
|
pokemon.baseMaxhp = Math.floor(Math.floor(2 * pokemon.species.baseStats['hp'] + pokemon.set.ivs['hp'] + Math.floor(pokemon.set.evs['hp'] / 4) + 100) * pokemon.level / 100 + 10);
|
|
5126
5114
|
const newMaxHP = pokemon.baseMaxhp;
|
|
5127
5115
|
pokemon.hp = newMaxHP - (pokemon.maxhp - pokemon.hp);
|
|
@@ -5277,19 +5265,23 @@ export const Abilities = {
|
|
|
5277
5265
|
},
|
|
5278
5266
|
trace: {
|
|
5279
5267
|
onStart(pokemon) {
|
|
5268
|
+
this.effectState.seek = true;
|
|
5280
5269
|
// n.b. only affects Hackmons
|
|
5281
5270
|
// interaction with No Ability is complicated: https://www.smogon.com/forums/threads/pokemon-sun-moon-battle-mechanics-research.3586701/page-76#post-7790209
|
|
5282
5271
|
if (pokemon.adjacentFoes().some(foeActive => foeActive.ability === 'noability')) {
|
|
5283
|
-
this.effectState.
|
|
5272
|
+
this.effectState.seek = false;
|
|
5284
5273
|
}
|
|
5285
5274
|
// interaction with Ability Shield is similar to No Ability
|
|
5286
5275
|
if (pokemon.hasItem('Ability Shield')) {
|
|
5287
5276
|
this.add('-block', pokemon, 'item: Ability Shield');
|
|
5288
|
-
this.effectState.
|
|
5277
|
+
this.effectState.seek = false;
|
|
5278
|
+
}
|
|
5279
|
+
if (this.effectState.seek) {
|
|
5280
|
+
this.singleEvent('Update', this.effect, this.effectState, pokemon);
|
|
5289
5281
|
}
|
|
5290
5282
|
},
|
|
5291
5283
|
onUpdate(pokemon) {
|
|
5292
|
-
if (!
|
|
5284
|
+
if (!this.effectState.seek)
|
|
5293
5285
|
return;
|
|
5294
5286
|
const possibleTargets = pokemon.adjacentFoes().filter(target => !target.getAbility().flags['notrace'] && target.ability !== 'noability');
|
|
5295
5287
|
if (!possibleTargets.length)
|
|
@@ -5415,10 +5407,7 @@ export const Abilities = {
|
|
|
5415
5407
|
num: 84,
|
|
5416
5408
|
},
|
|
5417
5409
|
unnerve: {
|
|
5418
|
-
|
|
5419
|
-
this.add('-ability', pokemon, 'Unnerve');
|
|
5420
|
-
this.effectState.unnerved = true;
|
|
5421
|
-
},
|
|
5410
|
+
onSwitchInPriority: 1,
|
|
5422
5411
|
onStart(pokemon) {
|
|
5423
5412
|
if (this.effectState.unnerved)
|
|
5424
5413
|
return;
|
|
@@ -5825,15 +5814,10 @@ export const Abilities = {
|
|
|
5825
5814
|
return;
|
|
5826
5815
|
if (pokemon.species.forme !== 'Hero') {
|
|
5827
5816
|
pokemon.formeChange('Palafin-Hero', this.effect, true);
|
|
5817
|
+
pokemon.regressionForme = false;
|
|
5828
5818
|
}
|
|
5829
5819
|
},
|
|
5830
|
-
onSwitchIn() {
|
|
5831
|
-
this.effectState.switchingIn = true;
|
|
5832
|
-
},
|
|
5833
|
-
onStart(pokemon) {
|
|
5834
|
-
if (!this.effectState.switchingIn)
|
|
5835
|
-
return;
|
|
5836
|
-
this.effectState.switchingIn = false;
|
|
5820
|
+
onSwitchIn(pokemon) {
|
|
5837
5821
|
if (pokemon.baseSpecies.baseSpecies !== 'Palafin')
|
|
5838
5822
|
return;
|
|
5839
5823
|
if (!this.effectState.heroMessageDisplayed && pokemon.species.forme === 'Hero') {
|