@pkmn/sim 0.6.2 → 0.6.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.
- package/build/config/formats.js +93 -72
- package/build/config/formats.js.map +1 -1
- package/build/data/mods/gen1/scripts.js +72 -38
- package/build/data/mods/gen1/scripts.js.map +1 -1
- package/build/data/mods/gen2/scripts.js +1 -1
- package/build/data/rulesets.js +58 -0
- package/build/data/rulesets.js.map +1 -1
- package/build/sim/battle.js +8 -4
- package/build/sim/battle.js.map +1 -1
- package/config/formats.ts +96 -69
- package/data/mods/gen1/scripts.ts +71 -37
- package/data/mods/gen2/scripts.ts +1 -1
- package/data/rulesets.ts +59 -0
- package/package.json +1 -1
- package/sim/battle.ts +6 -4
package/build/config/formats.js
CHANGED
|
@@ -637,7 +637,7 @@ exports.Formats = [
|
|
|
637
637
|
'Yveltal', 'Zacian', 'Zacian-Crowned', 'Zamazenta-Base', 'Zekrom', 'Zeraora', 'Zygarde-Base', 'Arena Trap', 'Comatose', 'Contrary', 'Fluffy',
|
|
638
638
|
'Fur Coat', 'Gorilla Tactics', 'Huge Power', 'Ice Scales', 'Illusion', 'Imposter', 'Innards Out', 'Intrepid Sword', 'Libero', 'Magic Bounce',
|
|
639
639
|
'Magnet Pull', 'Moody', 'Neutralizing Gas', 'Parental Bond', 'Poison Heal', 'Protean', 'Pure Power', 'Shadow Tag', 'Simple', 'Stakeout',
|
|
640
|
-
'Speed Boost', 'Unburden', 'Water Bubble', 'Wonder Guard', 'King\'s Rock', 'Baton Pass',
|
|
640
|
+
'Speed Boost', 'Unburden', 'Water Bubble', 'Wonder Guard', 'King\'s Rock', 'Baton Pass', 'Electrify',
|
|
641
641
|
],
|
|
642
642
|
},
|
|
643
643
|
{
|
|
@@ -754,70 +754,12 @@ exports.Formats = [
|
|
|
754
754
|
`• <a href="https://www.smogon.com/forums/threads/3660461/">Godly Gift</a>`,
|
|
755
755
|
],
|
|
756
756
|
mod: 'gen8',
|
|
757
|
-
ruleset: ['Standard OMs', 'Sleep Moves Clause'],
|
|
757
|
+
ruleset: ['Standard OMs', 'Sleep Moves Clause', 'Godly Gift Mod'],
|
|
758
758
|
banlist: [
|
|
759
759
|
'Blissey', 'Calyrex-Shadow', 'Chansey', 'Crawdaunt', 'Dragapult', 'Eternatus', 'Hawlucha', 'Kyogre', 'Marowak-Alola', 'Melmetal',
|
|
760
|
-
'Nidoking', 'Nidoqueen', 'Pikachu', 'Toxapex', 'Xerneas', 'Zacian', 'Zacian-Crowned', '
|
|
761
|
-
'
|
|
762
|
-
'Quick Claw', 'Baton Pass',
|
|
760
|
+
'Nidoking', 'Nidoqueen', 'Pikachu', 'Toxapex', 'Xerneas', 'Zacian', 'Zacian-Crowned', 'Arena Trap', 'Huge Power', 'Moody',
|
|
761
|
+
'Pure Power', 'Shadow Tag', 'Swift Swim', 'Bright Powder', 'Focus Band', 'King\'s Rock', 'Lax Incense', 'Quick Claw', 'Baton Pass',
|
|
763
762
|
],
|
|
764
|
-
onValidateTeam(team) {
|
|
765
|
-
const gods = new Set();
|
|
766
|
-
for (const set of team) {
|
|
767
|
-
let species = this.dex.species.get(set.species);
|
|
768
|
-
if (typeof species.battleOnly === 'string')
|
|
769
|
-
species = this.dex.species.get(species.battleOnly);
|
|
770
|
-
if (set.item && this.dex.items.get(set.item).megaStone) {
|
|
771
|
-
const item = this.dex.items.get(set.item);
|
|
772
|
-
if (item.megaEvolves === species.baseSpecies) {
|
|
773
|
-
species = this.dex.species.get(item.megaStone);
|
|
774
|
-
}
|
|
775
|
-
}
|
|
776
|
-
if (this.ruleTable.has('standardnatdex')) {
|
|
777
|
-
const format = this.dex.formats.getRuleTable(this.dex.formats.get('gen8nationaldex'));
|
|
778
|
-
if (format.isBannedSpecies(species))
|
|
779
|
-
gods.add(species.name);
|
|
780
|
-
}
|
|
781
|
-
else {
|
|
782
|
-
if (['ag', 'uber'].includes(this.toID(species.tier)) || this.toID(set.ability) === 'powerconstruct') {
|
|
783
|
-
gods.add(species.name);
|
|
784
|
-
}
|
|
785
|
-
}
|
|
786
|
-
}
|
|
787
|
-
if (gods.size > 1) {
|
|
788
|
-
return [`You have too many Gods.`, `(${Array.from(gods).join(', ')} are Gods.)`];
|
|
789
|
-
}
|
|
790
|
-
},
|
|
791
|
-
onModifySpeciesPriority: 3,
|
|
792
|
-
onModifySpecies(species, target, source) {
|
|
793
|
-
if (source || !target?.side)
|
|
794
|
-
return;
|
|
795
|
-
const god = target.side.team.find(set => {
|
|
796
|
-
let godSpecies = this.dex.species.get(set.species);
|
|
797
|
-
const isNatDex = this.format.ruleTable?.has('standardnatdex');
|
|
798
|
-
const validator = this.dex.formats.getRuleTable(this.dex.formats.get(`gen${isNatDex && this.gen < 8 ? 8 : this.gen}${isNatDex ? 'nationaldex' : 'ou'}`));
|
|
799
|
-
if (this.toID(set.ability) === 'powerconstruct') {
|
|
800
|
-
return true;
|
|
801
|
-
}
|
|
802
|
-
if (set.item) {
|
|
803
|
-
const item = this.dex.items.get(set.item);
|
|
804
|
-
if (item.megaEvolves === set.species)
|
|
805
|
-
godSpecies = this.dex.species.get(item.megaStone);
|
|
806
|
-
}
|
|
807
|
-
const isBanned = validator.isBannedSpecies(godSpecies);
|
|
808
|
-
return isBanned;
|
|
809
|
-
}) || target.side.team[0];
|
|
810
|
-
const stat = Dex.stats.ids()[target.side.team.indexOf(target.set)];
|
|
811
|
-
const newSpecies = this.dex.deepClone(species);
|
|
812
|
-
let godSpecies = this.dex.species.get(god.species);
|
|
813
|
-
if (typeof godSpecies.battleOnly === 'string') {
|
|
814
|
-
godSpecies = this.dex.species.get(godSpecies.battleOnly);
|
|
815
|
-
}
|
|
816
|
-
newSpecies.bst -= newSpecies.baseStats[stat];
|
|
817
|
-
newSpecies.baseStats[stat] = godSpecies.baseStats[stat];
|
|
818
|
-
newSpecies.bst += newSpecies.baseStats[stat];
|
|
819
|
-
return newSpecies;
|
|
820
|
-
},
|
|
821
763
|
},
|
|
822
764
|
{
|
|
823
765
|
name: "[Gen 8] Free-For-All",
|
|
@@ -1630,9 +1572,9 @@ exports.Formats = [
|
|
|
1630
1572
|
'Calyrex-Ice', 'Calyrex-Shadow', 'Dialga', 'Eternatus', 'Giratina', 'Giratina-Origin', 'Groudon', 'Ho-Oh',
|
|
1631
1573
|
'Jirachi', 'Kyogre', 'Kyurem-White', 'Lugia', 'Lunala', 'Magearna', 'Marshadow', 'Melmetal', 'Mewtwo',
|
|
1632
1574
|
'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane', 'Palkia', 'Rayquaza', 'Reshiram', 'Solgaleo', 'Urshifu-Base',
|
|
1633
|
-
'Xerneas', 'Yveltal', 'Zacian', 'Zacian-Crowned', 'Zamazenta', 'Zamazenta-Crowned', 'Zekrom', '
|
|
1634
|
-
'
|
|
1635
|
-
'Shell Smash', 'Swagger',
|
|
1575
|
+
'Xerneas', 'Yveltal', 'Zacian', 'Zacian-Crowned', 'Zamazenta', 'Zamazenta-Crowned', 'Zekrom', 'Contrary',
|
|
1576
|
+
'Emergency Exit', 'Huge Power', 'Moody', 'Power Construct', 'Serene Grace', 'Shadow Tag', 'Wimp Out',
|
|
1577
|
+
'Wonder Guard', 'Ally Switch', 'Bolt Beak', 'Fishious Rend', 'Shell Smash', 'Swagger',
|
|
1636
1578
|
],
|
|
1637
1579
|
onBeforeSwitchIn(pokemon) {
|
|
1638
1580
|
pokemon.m.curMoves = this.dex.deepClone(pokemon.moves);
|
|
@@ -2128,11 +2070,90 @@ exports.Formats = [
|
|
|
2128
2070
|
column: 2,
|
|
2129
2071
|
},
|
|
2130
2072
|
{
|
|
2131
|
-
name: "[Gen
|
|
2132
|
-
|
|
2073
|
+
name: "[Gen 4] Shared Power Random Battle",
|
|
2074
|
+
desc: `[Gen 4] Random Battle with aspects of [Gen 8] Shared Power`,
|
|
2075
|
+
mod: 'gen4',
|
|
2133
2076
|
team: 'random',
|
|
2134
|
-
ruleset: ['[Gen
|
|
2135
|
-
|
|
2077
|
+
ruleset: ['[Gen 4] Random Battle', 'Team Preview'],
|
|
2078
|
+
getSharedPower(pokemon) {
|
|
2079
|
+
const sharedPower = new Set();
|
|
2080
|
+
for (const ally of pokemon.side.pokemon) {
|
|
2081
|
+
if (ally.previouslySwitchedIn > 0) {
|
|
2082
|
+
if (pokemon.battle.dex.currentMod !== 'sharedpower' && ['trace', 'mirrorarmor'].includes(ally.baseAbility)) {
|
|
2083
|
+
sharedPower.add('noability');
|
|
2084
|
+
continue;
|
|
2085
|
+
}
|
|
2086
|
+
sharedPower.add(ally.baseAbility);
|
|
2087
|
+
}
|
|
2088
|
+
}
|
|
2089
|
+
sharedPower.delete(pokemon.baseAbility);
|
|
2090
|
+
return sharedPower;
|
|
2091
|
+
},
|
|
2092
|
+
onBeforeSwitchIn(pokemon) {
|
|
2093
|
+
let format = this.format;
|
|
2094
|
+
if (!format.getSharedPower)
|
|
2095
|
+
format = this.dex.formats.get('gen8sharedpower');
|
|
2096
|
+
for (const ability of format.getSharedPower(pokemon)) {
|
|
2097
|
+
const effect = 'ability:' + ability;
|
|
2098
|
+
pokemon.volatiles[effect] = { id: this.toID(effect), target: pokemon };
|
|
2099
|
+
if (!pokemon.m.abils)
|
|
2100
|
+
pokemon.m.abils = [];
|
|
2101
|
+
if (!pokemon.m.abils.includes(effect))
|
|
2102
|
+
pokemon.m.abils.push(effect);
|
|
2103
|
+
}
|
|
2104
|
+
},
|
|
2105
|
+
onSwitchInPriority: 2,
|
|
2106
|
+
onSwitchIn(pokemon) {
|
|
2107
|
+
let format = this.format;
|
|
2108
|
+
if (!format.getSharedPower)
|
|
2109
|
+
format = this.dex.formats.get('gen8sharedpower');
|
|
2110
|
+
for (const ability of format.getSharedPower(pokemon)) {
|
|
2111
|
+
if (ability === 'noability') {
|
|
2112
|
+
this.hint(`Mirror Armor and Trace break in Shared Power formats that don't use Shared Power as a base, so they get removed from non-base users.`);
|
|
2113
|
+
}
|
|
2114
|
+
const effect = 'ability:' + ability;
|
|
2115
|
+
delete pokemon.volatiles[effect];
|
|
2116
|
+
pokemon.addVolatile(effect);
|
|
2117
|
+
}
|
|
2118
|
+
},
|
|
2119
|
+
field: {
|
|
2120
|
+
suppressingWeather() {
|
|
2121
|
+
for (const pokemon of this.battle.getAllActive()) {
|
|
2122
|
+
const innates = Object.keys(pokemon.volatiles).filter(x => x.startsWith('ability:'));
|
|
2123
|
+
if (pokemon && !pokemon.ignoringAbility() &&
|
|
2124
|
+
(pokemon.getAbility().suppressWeather || innates.some(x => (this.battle.dex.abilities.get(x.replace('ability:', '')).suppressWeather)))) {
|
|
2125
|
+
return true;
|
|
2126
|
+
}
|
|
2127
|
+
}
|
|
2128
|
+
return false;
|
|
2129
|
+
},
|
|
2130
|
+
},
|
|
2131
|
+
pokemon: {
|
|
2132
|
+
hasAbility(ability) {
|
|
2133
|
+
if (this.ignoringAbility())
|
|
2134
|
+
return false;
|
|
2135
|
+
if (Array.isArray(ability))
|
|
2136
|
+
return ability.some(abil => this.hasAbility(abil));
|
|
2137
|
+
const abilityid = this.battle.toID(ability);
|
|
2138
|
+
return this.ability === abilityid || !!this.volatiles['ability:' + abilityid];
|
|
2139
|
+
},
|
|
2140
|
+
ignoringAbility() {
|
|
2141
|
+
// Check if any active pokemon have the ability Neutralizing Gas
|
|
2142
|
+
let neutralizinggas = false;
|
|
2143
|
+
for (const pokemon of this.battle.getAllActive()) {
|
|
2144
|
+
// can't use hasAbility because it would lead to infinite recursion
|
|
2145
|
+
if ((pokemon.ability === 'neutralizinggas' || pokemon.m.abils?.includes('ability:neutralizinggas')) &&
|
|
2146
|
+
!pokemon.volatiles['gastroacid'] && !pokemon.abilityState.ending) {
|
|
2147
|
+
neutralizinggas = true;
|
|
2148
|
+
break;
|
|
2149
|
+
}
|
|
2150
|
+
}
|
|
2151
|
+
return !!((this.battle.gen >= 5 && !this.isActive) ||
|
|
2152
|
+
((this.volatiles['gastroacid'] ||
|
|
2153
|
+
(neutralizinggas && (this.ability !== 'neutralizinggas' ||
|
|
2154
|
+
this.m.abils?.includes('ability:neutralizinggas')))) && !this.getAbility().isPermanent));
|
|
2155
|
+
},
|
|
2156
|
+
},
|
|
2136
2157
|
},
|
|
2137
2158
|
// Randomized Metas
|
|
2138
2159
|
///////////////////////////////////////////////////////////////////
|
|
@@ -2477,9 +2498,9 @@ exports.Formats = [
|
|
|
2477
2498
|
mod: 'gen3',
|
|
2478
2499
|
// searchShow: false,
|
|
2479
2500
|
gameType: 'doubles',
|
|
2480
|
-
ruleset: ['Standard', '!
|
|
2481
|
-
banlist: ['Uber'],
|
|
2482
|
-
unbanlist: ['Deoxys-
|
|
2501
|
+
ruleset: ['Standard', '!Switch Priority Clause Mod'],
|
|
2502
|
+
banlist: ['Uber', 'Soul Dew', 'Swagger'],
|
|
2503
|
+
unbanlist: ['Deoxys-Defense', 'Latias', 'Wobbuffet', 'Wynaut'],
|
|
2483
2504
|
},
|
|
2484
2505
|
{
|
|
2485
2506
|
name: "[Gen 3] UU",
|