@pkmn/sim 0.5.20 → 0.5.23

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 (102) hide show
  1. package/build/config/formats.js +149 -126
  2. package/build/config/formats.js.map +1 -1
  3. package/build/data/abilities.js +1 -3
  4. package/build/data/abilities.js.map +1 -1
  5. package/build/data/aliases.js +4 -4
  6. package/build/data/aliases.js.map +1 -1
  7. package/build/data/conditions.js +5 -2
  8. package/build/data/conditions.js.map +1 -1
  9. package/build/data/formats-data.js +20 -17
  10. package/build/data/formats-data.js.map +1 -1
  11. package/build/data/learnsets.js +29 -0
  12. package/build/data/learnsets.js.map +1 -1
  13. package/build/data/mods/gen1/conditions.js +7 -0
  14. package/build/data/mods/gen1/conditions.js.map +1 -1
  15. package/build/data/mods/gen1/formats-data.js +2 -2
  16. package/build/data/mods/gen1/formats-data.js.map +1 -1
  17. package/build/data/mods/gen1/moves.js +2 -3
  18. package/build/data/mods/gen1/moves.js.map +1 -1
  19. package/build/data/mods/gen1/scripts.js +4 -2
  20. package/build/data/mods/gen1/scripts.js.map +1 -1
  21. package/build/data/mods/gen2/conditions.js +3 -0
  22. package/build/data/mods/gen2/conditions.js.map +1 -1
  23. package/build/data/mods/gen2/learnsets.js +2 -2
  24. package/build/data/mods/gen2/learnsets.js.map +1 -1
  25. package/build/data/mods/gen2/scripts.js +16 -0
  26. package/build/data/mods/gen2/scripts.js.map +1 -1
  27. package/build/data/mods/gen3/conditions.js +3 -0
  28. package/build/data/mods/gen3/conditions.js.map +1 -1
  29. package/build/data/mods/gen3/formats-data.js +3 -3
  30. package/build/data/mods/gen3/formats-data.js.map +1 -1
  31. package/build/data/mods/gen4/abilities.js +1 -1
  32. package/build/data/mods/gen4/abilities.js.map +1 -1
  33. package/build/data/mods/gen4/conditions.js +3 -0
  34. package/build/data/mods/gen4/conditions.js.map +1 -1
  35. package/build/data/mods/gen4/formats-data.js +1 -1
  36. package/build/data/mods/gen4/formats-data.js.map +1 -1
  37. package/build/data/mods/gen4/moves.js +9 -2
  38. package/build/data/mods/gen4/moves.js.map +1 -1
  39. package/build/data/mods/gen5/moves.js +4 -7
  40. package/build/data/mods/gen5/moves.js.map +1 -1
  41. package/build/data/mods/gen5/pokedex.js +24 -0
  42. package/build/data/mods/gen5/pokedex.js.map +1 -1
  43. package/build/data/mods/gen6/formats-data.js +65 -65
  44. package/build/data/mods/gen6/formats-data.js.map +1 -1
  45. package/build/data/mods/gen6/learnsets.js +0 -75
  46. package/build/data/mods/gen6/learnsets.js.map +1 -1
  47. package/build/data/mods/gen7/abilities.js +8 -0
  48. package/build/data/mods/gen7/abilities.js.map +1 -1
  49. package/build/data/mods/gen7/moves.js +2 -2
  50. package/build/data/mods/gen7/moves.js.map +1 -1
  51. package/build/data/moves.js +8 -3
  52. package/build/data/moves.js.map +1 -1
  53. package/build/data/pokedex.js +12 -0
  54. package/build/data/pokedex.js.map +1 -1
  55. package/build/data/rulesets.js +175 -0
  56. package/build/data/rulesets.js.map +1 -1
  57. package/build/data/tags.js +2 -2
  58. package/build/data/tags.js.map +1 -1
  59. package/build/sim/battle-stream.js +3 -0
  60. package/build/sim/battle-stream.js.map +1 -1
  61. package/build/sim/exported-global-types.d.ts +2 -0
  62. package/build/sim/global-types.d.ts +2 -0
  63. package/build/sim/pokemon.d.ts +1 -0
  64. package/build/sim/pokemon.js +9 -2
  65. package/build/sim/pokemon.js.map +1 -1
  66. package/build/sim/side.js +21 -0
  67. package/build/sim/side.js.map +1 -1
  68. package/config/formats.ts +152 -130
  69. package/data/abilities.ts +1 -3
  70. package/data/aliases.ts +4 -4
  71. package/data/conditions.ts +6 -2
  72. package/data/formats-data.ts +20 -17
  73. package/data/learnsets.ts +29 -0
  74. package/data/mods/gen1/conditions.ts +8 -0
  75. package/data/mods/gen1/formats-data.ts +2 -2
  76. package/data/mods/gen1/moves.ts +3 -2
  77. package/data/mods/gen1/scripts.ts +3 -2
  78. package/data/mods/gen2/conditions.ts +4 -0
  79. package/data/mods/gen2/learnsets.ts +2 -2
  80. package/data/mods/gen2/scripts.ts +16 -0
  81. package/data/mods/gen3/conditions.ts +4 -0
  82. package/data/mods/gen3/formats-data.ts +3 -3
  83. package/data/mods/gen4/abilities.ts +1 -1
  84. package/data/mods/gen4/conditions.ts +4 -0
  85. package/data/mods/gen4/formats-data.ts +1 -1
  86. package/data/mods/gen4/moves.ts +9 -2
  87. package/data/mods/gen5/moves.ts +4 -7
  88. package/data/mods/gen5/pokedex.ts +24 -0
  89. package/data/mods/gen6/formats-data.ts +65 -65
  90. package/data/mods/gen6/learnsets.ts +0 -75
  91. package/data/mods/gen7/abilities.ts +8 -0
  92. package/data/mods/gen7/moves.ts +2 -2
  93. package/data/moves.ts +8 -3
  94. package/data/pokedex.ts +12 -0
  95. package/data/rulesets.ts +155 -0
  96. package/data/tags.ts +2 -2
  97. package/package.json +2 -2
  98. package/sim/battle-stream.ts +3 -0
  99. package/sim/exported-global-types.ts +2 -0
  100. package/sim/global-types.ts +2 -0
  101. package/sim/pokemon.ts +9 -2
  102. package/sim/side.ts +20 -0
@@ -172,79 +172,4 @@ export const Learnsets: {[k: string]: ModdedLearnsetData} = {
172
172
  zenheadbutt: ["7T", "5T"],
173
173
  },
174
174
  },
175
- crucibelle: {
176
- inherit: true,
177
- learnset: {
178
- acidarmor: ["7L32", "6L32"],
179
- astonish: ["7L1", "6L1"],
180
- attract: ["7M", "6M"],
181
- block: ["6T"],
182
- coil: ["7E", "6E"],
183
- confuseray: ["7L16", "6L16"],
184
- confusion: ["7L14", "6L14"],
185
- defensecurl: ["7E", "6E"],
186
- doubleteam: ["7M", "6M"],
187
- embargo: ["7M", "6M"],
188
- endure: ["7L1", "6L1"],
189
- explosion: ["7M", "7L60", "6M", "6L60"],
190
- facade: ["7M", "6M"],
191
- faketears: ["7L10", "6L10"],
192
- frustration: ["7M", "6M"],
193
- gigaimpact: ["7M", "6M"],
194
- grassknot: ["7M", "6M"],
195
- gravity: ["6T"],
196
- gunkshot: ["7L56", "6T", "6L56"],
197
- headsmash: ["6L1"],
198
- helpinghand: ["6T"],
199
- hex: ["7L44", "6L44"],
200
- hiddenpower: ["7M", "6M"],
201
- hyperbeam: ["7M", "6M"],
202
- infestation: ["7M", "6M"],
203
- ironhead: ["6T"],
204
- lowkick: ["6T"],
205
- magicroom: ["6T"],
206
- payback: ["7M", "6M"],
207
- poisonjab: ["7M", "6M"],
208
- protect: ["7M", "7L1", "6M", "6L1"],
209
- psybeam: ["7L40", "6L40"],
210
- psychic: ["7M", "6M"],
211
- reflect: ["7M", "7L25", "6M", "6L25"],
212
- rest: ["7M", "6M"],
213
- return: ["7M", "6M"],
214
- rockblast: ["7L52", "6L52"],
215
- rockpolish: ["7M", "6M"],
216
- rockslide: ["7M", "7L36", "6M", "6L36"],
217
- rocksmash: ["7M", "6M"],
218
- rockthrow: ["7L5", "6L5"],
219
- rocktomb: ["7M", "6M"],
220
- rollout: ["7E", "6E"],
221
- round: ["7M", "6M"],
222
- safeguard: ["7M", "6M"],
223
- sandstorm: ["7M", "6M"],
224
- secretpower: ["7M"],
225
- shadowball: ["7M", "6M"],
226
- skillswap: ["6T"],
227
- sleeptalk: ["7M", "6M"],
228
- sludge: ["7L28", "6L28"],
229
- sludgebomb: ["7M", "6M"],
230
- sludgewave: ["7M", "6M"],
231
- smackdown: ["7M", "7L23", "6M", "6L23"],
232
- snatch: ["6T"],
233
- snore: ["6T"],
234
- stealthrock: ["6T"],
235
- stoneedge: ["7M", "6M"],
236
- substitute: ["7M", "6M"],
237
- swagger: ["7M", "6M"],
238
- torment: ["7M", "7L48", "6M", "6L48"],
239
- toxic: ["7M", "7L7", "6M", "6L7"],
240
- toxicspikes: ["7L19", "6L19"],
241
- trick: ["6T"],
242
- uturn: ["7M", "6M"],
243
- venoshock: ["7M", "6M"],
244
- withdraw: ["7L1", "6L1"],
245
- wonderroom: ["6T"],
246
- woodhammer: ["7E", "6E"],
247
- zenheadbutt: ["6T"],
248
- },
249
- },
250
175
  };
@@ -8,6 +8,14 @@ export const Abilities: {[k: string]: ModdedAbilityData} = {
8
8
  }
9
9
  },
10
10
  },
11
+ darkaura: {
12
+ inherit: true,
13
+ isBreakable: true,
14
+ },
15
+ fairyaura: {
16
+ inherit: true,
17
+ isBreakable: true,
18
+ },
11
19
  innerfocus: {
12
20
  inherit: true,
13
21
  rating: 1,
@@ -381,7 +381,7 @@ export const Moves: {[k: string]: ModdedMoveData} = {
381
381
  onSwitchIn(target) {
382
382
  if (!target.fainted) {
383
383
  target.heal(target.maxhp);
384
- target.setStatus('');
384
+ target.clearStatus();
385
385
  this.add('-heal', target, target.getHealth, '[from] move: Healing Wish');
386
386
  target.side.removeSlotCondition(target, 'healingwish');
387
387
  }
@@ -608,7 +608,7 @@ export const Moves: {[k: string]: ModdedMoveData} = {
608
608
  onSwitchIn(target) {
609
609
  if (!target.fainted) {
610
610
  target.heal(target.maxhp);
611
- target.setStatus('');
611
+ target.clearStatus();
612
612
  for (const moveSlot of target.moveSlots) {
613
613
  moveSlot.pp = moveSlot.maxpp;
614
614
  }
package/data/moves.ts CHANGED
@@ -7828,7 +7828,7 @@ export const Moves: {[moveid: string]: MoveData} = {
7828
7828
  onSwap(target) {
7829
7829
  if (!target.fainted && (target.hp < target.maxhp || target.status)) {
7830
7830
  target.heal(target.maxhp);
7831
- target.setStatus('');
7831
+ target.clearStatus();
7832
7832
  this.add('-heal', target, target.getHealth, '[from] move: Healing Wish');
7833
7833
  target.side.removeSlotCondition(target, 'healingwish');
7834
7834
  }
@@ -9081,7 +9081,12 @@ export const Moves: {[moveid: string]: MoveData} = {
9081
9081
  return false;
9082
9082
  }
9083
9083
  this.add('-singleturn', target, 'move: Instruct', '[of] ' + source);
9084
- this.actions.runMove(target.lastMove.id, target, target.lastMoveTargetLoc!);
9084
+ this.queue.prioritizeAction(this.queue.resolveAction({
9085
+ choice: 'move',
9086
+ pokemon: target,
9087
+ moveid: target.lastMove.id,
9088
+ targetLoc: target.lastMoveTargetLoc!,
9089
+ })[0] as MoveAction);
9085
9090
  },
9086
9091
  secondary: null,
9087
9092
  target: "normal",
@@ -9929,7 +9934,7 @@ export const Moves: {[moveid: string]: MoveData} = {
9929
9934
  )
9930
9935
  ) {
9931
9936
  target.heal(target.maxhp);
9932
- target.setStatus('');
9937
+ target.clearStatus();
9933
9938
  for (const moveSlot of target.moveSlots) {
9934
9939
  moveSlot.pp = moveSlot.maxpp;
9935
9940
  }
package/data/pokedex.ts CHANGED
@@ -17419,6 +17419,18 @@ export const Pokedex: {[speciesid: string]: SpeciesData} = {
17419
17419
  changesFrom: "Venomicon",
17420
17420
  gen: 8,
17421
17421
  },
17422
+ saharaja: {
17423
+ num: -68,
17424
+ name: "Saharaja",
17425
+ types: ["Ground"],
17426
+ baseStats: {hp: 70, atk: 120, def: 105, spa: 65, spd: 130, spe: 90},
17427
+ abilities: {0: "Water Absorb", 1: "Serene Grace"},
17428
+ heightm: 2.3,
17429
+ weightkg: 303.9,
17430
+ color: "White",
17431
+ eggGroups: ["Undiscovered"],
17432
+ gen: 8,
17433
+ },
17422
17434
  // NOTE: PokeStar "formes" are not actually formes and thus do not have a formeOrder
17423
17435
  pokestarsmeargle: {
17424
17436
  num: -5000,
package/data/rulesets.ts CHANGED
@@ -399,6 +399,29 @@ export const Rulesets: {[k: string]: FormatData} = {
399
399
  }
400
400
  },
401
401
  },
402
+ forceselect: {
403
+ effectType: 'ValidatorRule',
404
+ name: 'Force Select',
405
+ desc: `Forces a Pokemon to be on the team and selected at Team Preview. Usage: Force Select = [Pokemon], e.g. "Force Select = Magikarp"`,
406
+ hasValue: true,
407
+ onValidateRule(value) {
408
+ if (!this.dex.species.get(value).exists) throw new Error(`Misspelled Pokemon "${value}"`);
409
+ },
410
+ onValidateTeam(team) {
411
+ let hasSelection = false;
412
+ const species = this.dex.species.get(this.ruleTable.valueRules.get('forceselect'));
413
+ for (const set of team) {
414
+ if (species.name === set.species) {
415
+ hasSelection = true;
416
+ break;
417
+ }
418
+ }
419
+ if (!hasSelection) {
420
+ return [`Your team must contain ${species.name}.`];
421
+ }
422
+ },
423
+ // hardcoded in sim/side
424
+ },
402
425
  evlimits: {
403
426
  effectType: 'ValidatorRule',
404
427
  name: 'EV Limits',
@@ -1262,6 +1285,19 @@ export const Rulesets: {[k: string]: FormatData} = {
1262
1285
  }
1263
1286
  },
1264
1287
  },
1288
+ gemsclause: {
1289
+ effectType: 'ValidatorRule',
1290
+ name: 'Gems Clause',
1291
+ desc: "Bans all Gems",
1292
+ onValidateSet(set) {
1293
+ if (!set.item) return;
1294
+ const item = this.dex.items.get(set.item);
1295
+ if (item.isGem) {
1296
+ if (this.ruleTable.has(`+item:${item.id}`)) return;
1297
+ return [`${item.name} is banned due to Gems Clause.`];
1298
+ }
1299
+ },
1300
+ },
1265
1301
  'sketchgen8moves': {
1266
1302
  effectType: 'ValidatorRule',
1267
1303
  name: 'Sketch Gen 8 Moves',
@@ -1585,6 +1621,12 @@ export const Rulesets: {[k: string]: FormatData} = {
1585
1621
  desc: "Prevents Pok\u00e9mon from having moves that would only be obtainable in Pok\u00e9mon Crystal.",
1586
1622
  // Implemented in mods/gen2/rulesets.ts
1587
1623
  },
1624
+ aptclause: {
1625
+ effectType: 'ValidatorRule',
1626
+ name: 'APT Clause',
1627
+ desc: "Bans the combination of Agility and partial trapping moves like Wrap.",
1628
+ banlist: ['Agility + Wrap', 'Agility + Fire Spin', 'Agility + Bind', 'Agility + Clamp'],
1629
+ },
1588
1630
  nintendocup1997movelegality: {
1589
1631
  effectType: 'ValidatorRule',
1590
1632
  name: "Nintendo Cup 1997 Move Legality",
@@ -1824,4 +1866,117 @@ export const Rulesets: {[k: string]: FormatData} = {
1824
1866
  }
1825
1867
  },
1826
1868
  },
1869
+ reevolutionmod: {
1870
+ effectType: "Rule",
1871
+ name: "Re-Evolution Mod",
1872
+ desc: "Pok&eacute;mon gain the stat changes they would gain from evolving again.",
1873
+ ruleset: ['Overflow Stat Mod'],
1874
+ onBegin() {
1875
+ this.add('rule', 'Re-Evolution Mod: Pok\u00e9mon gain the boosts they would gain from evolving again');
1876
+ },
1877
+ onModifySpecies(species, target) {
1878
+ const newSpecies = this.dex.deepClone(species);
1879
+ if (!newSpecies.prevo) return;
1880
+ const prevoSpecies = this.dex.species.get(newSpecies.prevo);
1881
+ let statid: StatID;
1882
+ newSpecies.bst = 0;
1883
+ for (statid in prevoSpecies.baseStats) {
1884
+ const change = newSpecies.baseStats[statid] - prevoSpecies.baseStats[statid];
1885
+ newSpecies.baseStats[statid] = this.clampIntRange(newSpecies.baseStats[statid] + change, 1, 255);
1886
+ newSpecies.bst += newSpecies.baseStats[statid];
1887
+ }
1888
+ return newSpecies;
1889
+ },
1890
+ },
1891
+ brokenrecordmod: {
1892
+ effectType: "Rule",
1893
+ name: "Broken Record Mod",
1894
+ desc: `Pok&eacute;mon can hold a TR to use that move in battle.`,
1895
+ onValidateSet(set) {
1896
+ if (!set.item) return;
1897
+ const item = this.dex.items.get(set.item);
1898
+ if (!/^tr\d\d/i.test(item.name)) return;
1899
+ const moveName = item.desc.split('move ')[1].split('.')[0];
1900
+ if (set.moves.map(this.toID).includes(this.toID(moveName))) {
1901
+ return [
1902
+ `${set.species} can't run ${item.name} (${moveName}) as its item because it already has that move in its moveset.`,
1903
+ ];
1904
+ }
1905
+ },
1906
+ onValidateTeam(team) {
1907
+ const trs = new Set<string>();
1908
+ for (const set of team) {
1909
+ if (!set.item) continue;
1910
+ const item = this.dex.items.get(set.item).name;
1911
+ if (!/^tr\d\d/i.test(item)) continue;
1912
+ if (trs.has(item)) {
1913
+ return [`Your team already has a Pok\u00e9mon with ${item}.`];
1914
+ }
1915
+ trs.add(item);
1916
+ }
1917
+ },
1918
+ onTakeItem(item) {
1919
+ return !/^tr\d\d/i.test(item.name);
1920
+ },
1921
+ onModifyMove(move) {
1922
+ if (move.id === 'knockoff') {
1923
+ move.onBasePower = function (basePower, source, target, m) {
1924
+ const item = target.getItem();
1925
+ if (!this.singleEvent('TakeItem', item, target.itemState, target, target, m, item)) return;
1926
+ // Very hardcode but I'd prefer to not make a mod for one damage calculation change
1927
+ if (item.id && !/^tr\d\d/i.test(item.id)) {
1928
+ return this.chainModify(1.5);
1929
+ }
1930
+ };
1931
+ } else if (move.id === 'fling') {
1932
+ move.onPrepareHit = function (target, source, m) {
1933
+ if (source.ignoringItem()) return false;
1934
+ const item = source.getItem();
1935
+ if (!this.singleEvent('TakeItem', item, source.itemState, source, source, m, item)) return false;
1936
+ if (!item.fling) return false;
1937
+ if (/^tr\d\d/i.test(item.id)) return false;
1938
+ m.basePower = item.fling.basePower;
1939
+ if (item.isBerry) {
1940
+ m.onHit = function (foe) {
1941
+ if (this.singleEvent('Eat', item, null, foe, null, null)) {
1942
+ this.runEvent('EatItem', foe, null, null, item);
1943
+ if (item.id === 'leppaberry') foe.staleness = 'external';
1944
+ }
1945
+ if (item.onEat) foe.ateBerry = true;
1946
+ };
1947
+ } else if (item.fling.effect) {
1948
+ m.onHit = item.fling.effect;
1949
+ } else {
1950
+ if (!m.secondaries) m.secondaries = [];
1951
+ if (item.fling.status) {
1952
+ m.secondaries.push({status: item.fling.status});
1953
+ } else if (item.fling.volatileStatus) {
1954
+ m.secondaries.push({volatileStatus: item.fling.volatileStatus});
1955
+ }
1956
+ }
1957
+ source.addVolatile('fling');
1958
+ };
1959
+ }
1960
+ },
1961
+ onBegin() {
1962
+ for (const pokemon of this.getAllPokemon()) {
1963
+ const item = pokemon.getItem();
1964
+ if (/^tr\d\d/i.test(item.name)) {
1965
+ const move = this.dex.moves.get(item.desc.split('move ')[1].split('.')[0]);
1966
+ pokemon.moveSlots = (pokemon as any).baseMoveSlots = [
1967
+ ...pokemon.baseMoveSlots, {
1968
+ id: move.id,
1969
+ move: move.name,
1970
+ pp: move.pp * 8 / 5,
1971
+ maxpp: move.pp * 8 / 5,
1972
+ target: move.target,
1973
+ disabled: false,
1974
+ disabledSource: '',
1975
+ used: false,
1976
+ },
1977
+ ];
1978
+ }
1979
+ }
1980
+ },
1981
+ },
1827
1982
  };
package/data/tags.ts CHANGED
@@ -199,8 +199,8 @@ export const Tags: {[id: string]: TagData} = {
199
199
  speciesFilter: species => [
200
200
  'Aerodactyl-Mega', 'Alakazam', 'Blacephalon', 'Blaziken', 'Diancie-Mega', 'Gallade-Mega', 'Gardevoir-Mega', 'Gengar', 'Gyarados',
201
201
  'Gyarados-Mega', 'Hawlucha', 'Heracross-Mega', 'Hoopa-Unbound', 'Hydreigon', 'Jirachi', 'Latias', 'Latias-Mega', 'Latios',
202
- 'Latios-Mega', 'Manaphy', 'Medicham-Mega', 'Melmetal', 'Mew', 'Pinsir-Mega', 'Sableye-Mega', 'Slowbro-Mega', 'Slowking-Galar',
203
- 'Thundurus', 'Thundurus-Therian', 'Venusaur-Mega', 'Xurkitree', 'Zapdos-Galar',
202
+ 'Latios-Mega', 'Manaphy', 'Medicham-Mega', 'Melmetal', 'Mew', 'Moltres-Galar', 'Pinsir-Mega', 'Sableye-Mega', 'Slowbro-Mega',
203
+ 'Slowking-Galar', 'Thundurus', 'Venusaur-Mega', 'Xurkitree', 'Zapdos-Galar',
204
204
  ].includes(species.name),
205
205
  },
206
206
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pkmn/sim",
3
- "version": "0.5.20",
3
+ "version": "0.5.23",
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",
@@ -27,7 +27,7 @@
27
27
  "sim"
28
28
  ],
29
29
  "dependencies": {
30
- "@pkmn/sets": "^3.0.0",
30
+ "@pkmn/sets": "^3.1.0",
31
31
  "@pkmn/streams": "^1.0.0"
32
32
  },
33
33
  "devDependencies": {
@@ -211,6 +211,9 @@ export class BattleStream extends Streams.ObjectReadWriteStream<string> {
211
211
  case 'requestlog':
212
212
  this.push(`requesteddata\n${this.battle!.inputLog.join('\n')}`);
213
213
  break;
214
+ case 'requestexport':
215
+ this.push(`requesteddata\n${this.battle!.prngSeed}\n${this.battle!.inputLog.join('\n')}`);
216
+ break;
214
217
  case 'requestteam':
215
218
  message = message.trim();
216
219
  const slotNum = parseInt(message.slice(1)) - 1;
@@ -515,6 +515,7 @@ export namespace RandomTeamsTypes {
515
515
  shiny: boolean;
516
516
  nature?: string;
517
517
  happiness?: number;
518
+ dynamaxLevel?: number;
518
519
  gigantamax?: boolean;
519
520
  }
520
521
  export interface RandomFactorySet {
@@ -530,6 +531,7 @@ export namespace RandomTeamsTypes {
530
531
  ivs: SparseStatsTable;
531
532
  nature: string;
532
533
  moves: string[];
534
+ dynamaxLevel?: number;
533
535
  gigantamax?: boolean;
534
536
  }
535
537
  }
@@ -515,6 +515,7 @@ namespace RandomTeamsTypes {
515
515
  shiny: boolean;
516
516
  nature?: string;
517
517
  happiness?: number;
518
+ dynamaxLevel?: number;
518
519
  gigantamax?: boolean;
519
520
  }
520
521
  export interface RandomFactorySet {
@@ -530,6 +531,7 @@ namespace RandomTeamsTypes {
530
531
  ivs: SparseStatsTable;
531
532
  nature: string;
532
533
  moves: string[];
534
+ dynamaxLevel?: number;
533
535
  gigantamax?: boolean;
534
536
  }
535
537
  }
package/sim/pokemon.ts CHANGED
@@ -77,6 +77,7 @@ export class Pokemon {
77
77
  readonly gender: GenderName;
78
78
  readonly happiness: number;
79
79
  readonly pokeball: string;
80
+ readonly dynamaxLevel: number;
80
81
  readonly gigantamax: boolean;
81
82
 
82
83
  /** Transform keeps the original pre-transformed Hidden Power in Gen 2-4. */
@@ -326,6 +327,7 @@ export class Pokemon {
326
327
  if (this.gender === 'N') this.gender = '';
327
328
  this.happiness = typeof set.happiness === 'number' ? this.battle.clampIntRange(set.happiness, 0, 255) : 255;
328
329
  this.pokeball = this.set.pokeball || 'pokeball';
330
+ this.dynamaxLevel = typeof set.dynamaxLevel === 'number' ? this.battle.clampIntRange(set.dynamaxLevel, 0, 10) : 10;
329
331
  this.gigantamax = this.set.gigantamax || false;
330
332
 
331
333
  this.baseMoveSlots = [];
@@ -1522,7 +1524,7 @@ export class Pokemon {
1522
1524
  cureStatus(silent = false) {
1523
1525
  if (!this.hp || !this.status) return false;
1524
1526
  this.battle.add('-curestatus', this, this.status, silent ? '[silent]' : '[msg]');
1525
- if (this.status === 'slp' && !this.hasAbility('comatose') && this.removeVolatile('nightmare')) {
1527
+ if (this.status === 'slp' && this.removeVolatile('nightmare')) {
1526
1528
  this.battle.add('-end', this, 'Nightmare', '[silent]');
1527
1529
  }
1528
1530
  this.setStatus('');
@@ -1599,7 +1601,12 @@ export class Pokemon {
1599
1601
  * Unlike cureStatus, does not give cure message
1600
1602
  */
1601
1603
  clearStatus() {
1602
- return this.setStatus('');
1604
+ if (!this.hp || !this.status) return false;
1605
+ if (this.status === 'slp' && this.removeVolatile('nightmare')) {
1606
+ this.battle.add('-end', this, 'Nightmare', '[silent]');
1607
+ }
1608
+ this.setStatus('');
1609
+ return true;
1603
1610
  }
1604
1611
 
1605
1612
  getStatus() {
package/sim/side.ts CHANGED
@@ -796,6 +796,26 @@ export class Side {
796
796
  }
797
797
  }
798
798
  }
799
+ if (ruleTable.valueRules.has('forceselect')) {
800
+ const species = this.battle.dex.species.get(ruleTable.valueRules.get('forceselect'));
801
+ if (!data) {
802
+ // autoChoose
803
+ positions = [...this.pokemon.keys()].filter(pos => this.pokemon[pos].species.name === species.name)
804
+ .concat([...this.pokemon.keys()].filter(pos => this.pokemon[pos].species.name !== species.name))
805
+ .slice(0, pickedTeamSize);
806
+ } else {
807
+ let hasSelection = false;
808
+ for (const pos of positions) {
809
+ if (this.pokemon[pos].species.name === species.name) {
810
+ hasSelection = true;
811
+ break;
812
+ }
813
+ }
814
+ if (!hasSelection) {
815
+ return this.emitChoiceError(`You must bring ${species.name} to the battle.`);
816
+ }
817
+ }
818
+ }
799
819
  for (const [index, pos] of positions.entries()) {
800
820
  this.choice.switchIns.add(pos);
801
821
  this.choice.actions.push({