From ebf13740f4e45f3d4e9eee3a6004fd3304579c9e Mon Sep 17 00:00:00 2001 From: Kris Johnson <11083252+KrisXV@users.noreply.github.com> Date: Thu, 1 Apr 2021 19:42:32 -0600 Subject: [PATCH] Shared Power: Fix Trace and Mirror Armor --- config/formats.ts | 28 ++++++------------ data/mods/pokebilities/scripts.ts | 3 +- data/mods/sharedpower/abilities.ts | 46 ++++++++++++++++++++++++++++++ data/mods/sharedpower/scripts.ts | 23 +++++++++++++++ 4 files changed, 79 insertions(+), 21 deletions(-) create mode 100644 data/mods/sharedpower/abilities.ts create mode 100644 data/mods/sharedpower/scripts.ts 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]; + }, + }, +};