@pkmn/sim 0.4.25 → 0.5.3

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 (59) hide show
  1. package/build/config/formats.js +272 -204
  2. package/build/config/formats.js.map +1 -1
  3. package/build/data/abilities.js +5 -1
  4. package/build/data/abilities.js.map +1 -1
  5. package/build/data/formats-data.js +48 -41
  6. package/build/data/formats-data.js.map +1 -1
  7. package/build/data/items.js +26 -2
  8. package/build/data/items.js.map +1 -1
  9. package/build/data/learnsets.js +35 -1
  10. package/build/data/learnsets.js.map +1 -1
  11. package/build/data/mods/gen1/scripts.js +12 -0
  12. package/build/data/mods/gen1/scripts.js.map +1 -1
  13. package/build/data/mods/gen2/formats-data.js +2 -2
  14. package/build/data/mods/gen2/formats-data.js.map +1 -1
  15. package/build/data/mods/gen3/formats-data.js +1 -1
  16. package/build/data/mods/gen3/formats-data.js.map +1 -1
  17. package/build/data/moves.js +9 -13
  18. package/build/data/moves.js.map +1 -1
  19. package/build/data/pokedex.js +33 -0
  20. package/build/data/pokedex.js.map +1 -1
  21. package/build/data/rulesets.js +39 -5
  22. package/build/data/rulesets.js.map +1 -1
  23. package/build/data/text/items.js +4 -0
  24. package/build/data/text/items.js.map +1 -1
  25. package/build/data/text/moves.js +1 -1
  26. package/build/data/text/moves.js.map +1 -1
  27. package/build/sim/battle-actions.js +8 -3
  28. package/build/sim/battle-actions.js.map +1 -1
  29. package/build/sim/dex-formats.js +1 -1
  30. package/build/sim/dex-formats.js.map +1 -1
  31. package/build/sim/dex-species.js +4 -3
  32. package/build/sim/dex-species.js.map +1 -1
  33. package/build/sim/exported-global-types.d.ts +1 -0
  34. package/build/sim/global-types.d.ts +1 -0
  35. package/build/sim/pokemon.js +1 -1
  36. package/build/sim/pokemon.js.map +1 -1
  37. package/build/sim/team-validator.js +3 -0
  38. package/build/sim/team-validator.js.map +1 -1
  39. package/config/formats.ts +276 -205
  40. package/data/abilities.ts +3 -1
  41. package/data/formats-data.ts +48 -41
  42. package/data/items.ts +26 -2
  43. package/data/learnsets.ts +35 -1
  44. package/data/mods/gen1/scripts.ts +11 -0
  45. package/data/mods/gen2/formats-data.ts +2 -2
  46. package/data/mods/gen3/formats-data.ts +1 -1
  47. package/data/moves.ts +9 -13
  48. package/data/pokedex.ts +33 -0
  49. package/data/rulesets.ts +35 -6
  50. package/data/text/items.ts +4 -0
  51. package/data/text/moves.ts +1 -1
  52. package/package.json +1 -1
  53. package/sim/battle-actions.ts +8 -3
  54. package/sim/dex-formats.ts +1 -1
  55. package/sim/dex-species.ts +4 -3
  56. package/sim/exported-global-types.ts +1 -0
  57. package/sim/global-types.ts +1 -0
  58. package/sim/pokemon.ts +1 -1
  59. package/sim/team-validator.ts +3 -0
package/data/rulesets.ts CHANGED
@@ -1,4 +1,4 @@
1
- // Note: These are the rules that formats use
1
+ // Note: These are the rules that formats use
2
2
 
3
3
  import {Utils} from "../lib";
4
4
 
@@ -791,13 +791,42 @@ export const Rulesets: {[k: string]: FormatData} = {
791
791
  ];
792
792
  },
793
793
  },
794
- "3batonpassclause": {
794
+ oneboostpasserclause: {
795
795
  effectType: 'ValidatorRule',
796
- name: '3 Baton Pass Clause',
797
- desc: "Stops teams from having more than three Pokémon with Baton Pass",
798
- banlist: ["Baton Pass > 3"],
796
+ name: 'One Boost Passer Clause',
797
+ desc: "Stops teams from having a Pokémon with Baton Pass that has multiple ways to boost its stats, and no more than one Baton Passer may be able to boost its stats",
799
798
  onBegin() {
800
- this.add('rule', '3 Baton Pass Clause: Limit three Baton Passers');
799
+ this.add('rule', 'One Boost Passer Clause: Limit one Baton Passer that has a way to boost its stats');
800
+ },
801
+ onValidateTeam(team) {
802
+ const boostingEffects = [
803
+ 'acidarmor', 'agility', 'amnesia', 'apicotberry', 'barrier', 'bellydrum', 'bulkup', 'calmmind', 'cosmicpower', 'curse',
804
+ 'defensecurl', 'dragondance', 'ganlonberry', 'growth', 'harden', 'howl', 'irondefense', 'liechiberry', 'meditate',
805
+ 'petayaberry', 'salacberry', 'sharpen', 'speedboost', 'starfberry', 'swordsdance', 'tailglow', 'withdraw',
806
+ ];
807
+ let passers = 0;
808
+ for (const set of team) {
809
+ if (!set.moves.includes('Baton Pass')) continue;
810
+ let passableBoosts = 0;
811
+ const item = this.toID(set.item);
812
+ const ability = this.toID(set.ability);
813
+ for (const move of set.moves) {
814
+ if (boostingEffects.includes(this.toID(move))) passableBoosts++;
815
+ }
816
+ if (boostingEffects.includes(item)) passableBoosts++;
817
+ if (boostingEffects.includes(ability)) passableBoosts++;
818
+ if (passableBoosts === 1) passers++;
819
+ if (passableBoosts > 1) {
820
+ return [
821
+ `${set.name || set.species} has Baton Pass and multiple ways to boost its stats, which is banned by One Boost Passer Clause.`,
822
+ ];
823
+ }
824
+ if (passers > 1) {
825
+ return [
826
+ `Multiple Pokemon have Baton Pass and a way to boost their stats, which is banned by One Boost Passer Clause.`,
827
+ ];
828
+ }
829
+ }
801
830
  },
802
831
  },
803
832
  cfzclause: {
@@ -2336,4 +2336,8 @@ export const ItemsText: {[k: string]: ItemText} = {
2336
2336
  name: "Crucibellite",
2337
2337
  desc: "If held by a Crucibelle, this item allows it to Mega Evolve in battle.",
2338
2338
  },
2339
+ vilevial: {
2340
+ name: "Vile Vial",
2341
+ desc: "If held by a Venomicon, its Poison- and Flying-type attacks have 1.2x power.",
2342
+ },
2339
2343
  };
@@ -3729,7 +3729,7 @@ export const MovesText: {[k: string]: MoveText} = {
3729
3729
  },
3730
3730
  mimic: {
3731
3731
  name: "Mimic",
3732
- desc: "While the user remains active, this move is replaced by the last move used by the target. The copied move has the maximum PP for that move. Fails if the target has not made a move, if the user has Transformed, if the user already knows the move, or if the move is Chatter, Dynamax Cannon, Mimic, Sketch, Struggle, Transform, or any Z-Move.",
3732
+ desc: "While the user remains active, this move is replaced by the last move used by the target. The copied move has the maximum PP for that move. Fails if the target has not made a move, if the user has Transformed, if the user already knows the move, or if the move is Behemoth Bash, Behemoth Blade, Chatter, Dynamax Cannon, Mimic, Sketch, Struggle, Transform, or any Z-Move.",
3733
3733
  shortDesc: "The last move the target used replaces this one.",
3734
3734
  gen6: {
3735
3735
  desc: "While the user remains active, this move is replaced by the last move used by the target. The copied move has the maximum PP for that move. Fails if the target has not made a move, if the user has Transformed, if the user already knows the move, or if the move is Chatter, Mimic, Sketch, Struggle, or Transform.",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pkmn/sim",
3
- "version": "0.4.25",
3
+ "version": "0.5.3",
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",
@@ -438,7 +438,8 @@ export class BattleActions {
438
438
  target = targets[targets.length - 1]; // in case of redirection
439
439
  }
440
440
 
441
- if (!sourceEffect || sourceEffect.id === 'pursuit') {
441
+ const callerMoveForPressure = sourceEffect && (sourceEffect as ActiveMove).pp ? sourceEffect as ActiveMove : null;
442
+ if (!sourceEffect || callerMoveForPressure || sourceEffect.id === 'pursuit') {
442
443
  let extraPP = 0;
443
444
  for (const source of pressureTargets) {
444
445
  const ppDrop = this.battle.runEvent('DeductPP', source, pokemon, move);
@@ -447,7 +448,7 @@ export class BattleActions {
447
448
  }
448
449
  }
449
450
  if (extraPP > 0) {
450
- pokemon.deductPP(moveOrMoveName, extraPP);
451
+ pokemon.deductPP(callerMoveForPressure || moveOrMoveName, extraPP);
451
452
  }
452
453
  }
453
454
 
@@ -1447,7 +1448,7 @@ export class BattleActions {
1447
1448
  this.battle.heal(pokemon.maxhp, pokemon, pokemon, zPower);
1448
1449
  break;
1449
1450
  case 'healreplacement':
1450
- move.self = {slotCondition: 'healreplacement'};
1451
+ pokemon.side.addSlotCondition(pokemon, 'healreplacement', pokemon, move);
1451
1452
  break;
1452
1453
  case 'clearnegativeboost':
1453
1454
  const boosts: SparseBoostsTable = {};
@@ -1575,6 +1576,10 @@ export class BattleActions {
1575
1576
 
1576
1577
  if (!basePower) return 0;
1577
1578
  basePower = this.battle.clampIntRange(basePower, 1);
1579
+ // Hacked Max Moves have 0 base power, even if you Dynamax
1580
+ if ((!source.volatiles['dynamax'] && move.isMax) || (move.isMax && this.dex.moves.get(move.baseMove).isMax)) {
1581
+ basePower = 0;
1582
+ }
1578
1583
 
1579
1584
  const level = source.level;
1580
1585
 
@@ -883,7 +883,7 @@ export class DexFormats {
883
883
  if (table.hasOwnProperty(id)) {
884
884
  if (matchType === 'pokemon') {
885
885
  const species: Species = table[id] as Species;
886
- if (species.otherFormes && ruleid !== species.id + toID(species.baseForme)) {
886
+ if ((species.otherFormes || species.cosmeticFormes) && ruleid !== species.id + toID(species.baseForme)) {
887
887
  matches.push('basepokemon:' + id);
888
888
  continue;
889
889
  }
@@ -485,9 +485,10 @@ export class DexSpecies {
485
485
  if (!isLetsGo) species.isNonstandard = 'Past';
486
486
  }
487
487
  if (this.dex.currentMod === 'gen8bdsp' &&
488
- (!species.isNonstandard || species.isNonstandard === "Gigantamax")) {
489
- if (species.gen > 4 || species.num < 1 || species.id === 'pichuspikyeared') {
490
- species.isNonstandard = 'Past';
488
+ (!species.isNonstandard || ["Gigantamax", "CAP"].includes(species.isNonstandard))) {
489
+ if (species.gen > 4 || (species.num < 1 && species.isNonstandard !== 'CAP') ||
490
+ species.id === 'pichuspikyeared') {
491
+ species.isNonstandard = 'Future';
491
492
  species.tier = species.doublesTier = 'Illegal';
492
493
  }
493
494
  }
@@ -309,6 +309,7 @@ export interface ModdedBattlePokemon {
309
309
  inherit?: true;
310
310
  lostItemForDelibird?: Item | null;
311
311
  boostBy?: (this: Pokemon, boost: SparseBoostsTable) => boolean | number;
312
+ clearBoosts?: (this: Pokemon) => void;
312
313
  calculateStat?: (this: Pokemon, statName: StatIDExceptHP, boost: number, modifier?: number) => number;
313
314
  cureStatus?: (this: Pokemon, silent?: boolean) => boolean;
314
315
  getAbility?: (this: Pokemon) => Ability;
@@ -309,6 +309,7 @@ interface ModdedBattlePokemon {
309
309
  inherit?: true;
310
310
  lostItemForDelibird?: Item | null;
311
311
  boostBy?: (this: Pokemon, boost: SparseBoostsTable) => boolean | number;
312
+ clearBoosts?: (this: Pokemon) => void;
312
313
  calculateStat?: (this: Pokemon, statName: StatIDExceptHP, boost: number, modifier?: number) => number;
313
314
  cureStatus?: (this: Pokemon, silent?: boolean) => boolean;
314
315
  getAbility?: (this: Pokemon) => Ability;
package/sim/pokemon.ts CHANGED
@@ -794,7 +794,7 @@ export class Pokemon {
794
794
  for (const pokemon of this.battle.getAllActive()) {
795
795
  // can't use hasAbility because it would lead to infinite recursion
796
796
  if (pokemon.ability === ('neutralizinggas' as ID) && !pokemon.volatiles['gastroacid'] &&
797
- !pokemon.abilityState.ending) {
797
+ !pokemon.transformed && !pokemon.abilityState.ending) {
798
798
  neutralizinggas = true;
799
799
  break;
800
800
  }
@@ -540,6 +540,9 @@ export class TeamValidator {
540
540
  problem = this.checkItem(set, item, setHas);
541
541
  if (problem) problems.push(problem);
542
542
  if (ruleTable.has('obtainablemisc')) {
543
+ if (dex.gen === 4 && item.id === 'griseousorb' && species.num !== 487) {
544
+ problems.push(`${set.name} cannot hold the Griseous Orb.`, `(In Gen 4, only Giratina could hold the Griseous Orb).`);
545
+ }
543
546
  if (dex.gen <= 1) {
544
547
  if (item.id) {
545
548
  // no items allowed