diff --git a/config/formats.ts b/config/formats.ts
index 3a78b6f03f..da76690b1b 100644
--- a/config/formats.ts
+++ b/config/formats.ts
@@ -1392,7 +1392,7 @@ export const Formats: FormatList = [
`• Shared Power`,
],
- mod: 'gen8',
+ mod: 'sharedpower',
searchShow: false,
ruleset: ['Standard', 'Dynamax Clause'],
banlist: [
@@ -1412,7 +1412,10 @@ export const Formats: FormatList = [
const sharedPower = new Set();
for (const ally of pokemon.side.pokemon) {
if (ally.previouslySwitchedIn > 0) {
- if (['mirrorarmor', 'trace'].includes(ally.baseAbility)) continue;
+ if (pokemon.battle.dex.currentMod !== 'sharedpower' && ['trace', 'mirrorarmor'].includes(ally.baseAbility)) {
+ sharedPower.add('noability');
+ continue;
+ }
sharedPower.add(ally.baseAbility);
}
}
@@ -1432,29 +1435,14 @@ export const Formats: FormatList = [
let format = this.format;
if (!format.getSharedPower) format = this.dex.getFormat('gen8sharedpower');
for (const ability of format.getSharedPower!(pokemon)) {
+ if (ability === 'noability') {
+ 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.`);
+ }
const effect = 'ability:' + ability;
delete pokemon.volatiles[effect];
pokemon.addVolatile(effect);
}
},
- field: {
- suppressingWeather() {
- for (const pokemon of this.battle.getAllActive()) {
- if (pokemon && !pokemon.ignoringAbility() && pokemon.hasAbility('Cloud Nine')) {
- return true;
- }
- }
- return false;
- },
- },
- pokemon: {
- hasAbility(ability) {
- if (this.ignoringAbility()) return false;
- if (Array.isArray(ability)) return ability.some(abil => this.hasAbility(abil));
- const abilityid = this.battle.toID(ability);
- return this.ability === abilityid || !!this.volatiles['ability:' + abilityid];
- },
- },
},
{
name: "[Gen 8] The Loser's Game",
diff --git a/data/mods/pokebilities/scripts.ts b/data/mods/pokebilities/scripts.ts
index 9cd1ed26f5..ad85cf891d 100644
--- a/data/mods/pokebilities/scripts.ts
+++ b/data/mods/pokebilities/scripts.ts
@@ -1,10 +1,11 @@
export const Scripts: ModdedBattleScriptsData = {
+ gen: 8,
field: {
suppressingWeather() {
for (const pokemon of this.battle.getAllActive()) {
if (pokemon && !pokemon.fainted && !pokemon.ignoringAbility() &&
(pokemon.getAbility().suppressWeather ||
- pokemon.m.innates?.some((k: string) => pokemon.volatiles['ability:' + k]?.suppressWeather))) {
+ pokemon.m.innates?.some((k: string) => this.battle.dex.getAbility(k).suppressWeather))) {
return true;
}
}
diff --git a/data/mods/sharedpower/abilities.ts b/data/mods/sharedpower/abilities.ts
new file mode 100644
index 0000000000..423e9ef1b7
--- /dev/null
+++ b/data/mods/sharedpower/abilities.ts
@@ -0,0 +1,46 @@
+export const Abilities: {[k: string]: ModdedAbilityData} = {
+ mirrorarmor: {
+ inherit: true,
+ onBoost(boost, target, source, effect) {
+ // Don't bounce self stat changes, or boosts that have already bounced
+ if (target === source || !boost || effect.id === 'mirrorarmor' || effect.id === 'ability:mirrorarmor') return;
+ let b: BoostName;
+ for (b in boost) {
+ if (boost[b]! < 0) {
+ if (target.boosts[b] === -6) continue;
+ const negativeBoost: SparseBoostsTable = {};
+ negativeBoost[b] = boost[b];
+ delete boost[b];
+ this.add('-ability', target, 'Mirror Armor');
+ this.boost(negativeBoost, source, target, null, true);
+ }
+ }
+ },
+ },
+ trace: {
+ inherit: true,
+ onUpdate(pokemon) {
+ if (!pokemon.isStarted || this.effectData.gaveUp) return;
+ const isAbility = pokemon.ability === 'trace';
+
+ const additionalBannedAbilities = [
+ // Zen Mode included here for compatability with Gen 5-6
+ 'noability', 'flowergift', 'forecast', 'hungerswitch', 'illusion', 'imposter', 'neutralizinggas', 'powerofalchemy', 'receiver', 'trace', 'zenmode',
+ ];
+ const possibleTargets = pokemon.adjacentFoes().filter(target => (
+ !target.getAbility().isPermanent && !additionalBannedAbilities.includes(target.ability)
+ ));
+ if (!possibleTargets.length) return;
+
+ const target = this.sample(possibleTargets);
+ const ability = target.getAbility();
+ this.add('-ability', pokemon, ability, '[from] ability: Trace', '[of] ' + target);
+ if (isAbility) {
+ pokemon.setAbility(ability);
+ } else {
+ pokemon.removeVolatile('ability:trace');
+ pokemon.addVolatile('ability:' + ability.id, pokemon);
+ }
+ },
+ },
+};
diff --git a/data/mods/sharedpower/scripts.ts b/data/mods/sharedpower/scripts.ts
new file mode 100644
index 0000000000..fe9a0656ca
--- /dev/null
+++ b/data/mods/sharedpower/scripts.ts
@@ -0,0 +1,23 @@
+export const Scripts: ModdedBattleScriptsData = {
+ gen: 8,
+ field: {
+ suppressingWeather() {
+ for (const pokemon of this.battle.getAllActive()) {
+ const innates = Object.keys(pokemon.volatiles).filter(x => x.startsWith('ability:'));
+ if (pokemon && !pokemon.ignoringAbility() &&
+ (pokemon.getAbility().suppressWeather || innates.some(x => this.battle.dex.getAbility(x).suppressWeather))) {
+ return true;
+ }
+ }
+ return false;
+ },
+ },
+ pokemon: {
+ hasAbility(ability) {
+ if (this.ignoringAbility()) return false;
+ if (Array.isArray(ability)) return ability.some(abil => this.hasAbility(abil));
+ const abilityid = this.battle.toID(ability);
+ return this.ability === abilityid || !!this.volatiles['ability:' + abilityid];
+ },
+ },
+};