diff --git a/config/formats.ts b/config/formats.ts index 8cdeb09788..141824e3ee 100644 --- a/config/formats.ts +++ b/config/formats.ts @@ -697,35 +697,16 @@ export const Formats: FormatList = [ column: 2, }, { - name: "[Gen 8] Camomons", - desc: `Pokémon change type to match their first two moves.`, - threads: [ - `• Camomons`, - ], - - mod: 'gen8', - searchShow: false, - ruleset: ['Standard OMs', 'Camomons Mod', 'Sleep Clause Mod'], - banlist: [ - 'Calyrex-Ice', 'Calyrex-Shadow', 'Darmanitan-Galar', 'Dialga', 'Dracovish', 'Dragonite', 'Eternatus', 'Genesect', 'Giratina', 'Giratina-Origin', - 'Groudon', 'Ho-Oh', 'Hydreigon', 'Kartana', 'Kyogre', 'Kyurem', 'Kyurem-Black', 'Kyurem-White', 'Landorus-Base', 'Lugia', 'Lunala', 'Marshadow', - 'Mew', 'Mewtwo', 'Naganadel', 'Necrozma-Dawn-Wings', 'Necrozma-Dusk-Mane', 'Palkia', 'Pheromosa', 'Rayquaza', 'Reshiram', 'Shedinja', 'Solgaleo', - 'Spectrier', 'Tornadus-Therian', 'Volcarona', 'Xerneas', 'Yveltal', 'Zacian', 'Zacian-Crowned', 'Zamazenta', 'Zamazenta-Crowned', 'Zekrom', 'Zeraora', - 'Zygarde-Base', 'Arena Trap', 'Moody', 'Power Construct', 'Shadow Tag', 'Baton Pass', 'Calm Mind', - ], - }, - { - name: "[Gen 8] Cross Evolution", + name: "[Gen 9] Cross Evolution", desc: `Give a Pokémon a Pokémon name of the next evolution stage as a nickname to inherit stat changes, typing, abilities, and up to 2 moves from the next stage Pokémon.`, threads: [ - `• Cross Evolution`, + `• Cross Evolution`, ], - mod: 'gen8', + mod: 'gen9', searchShow: false, - ruleset: ['Standard OMs', 'Ability Clause = 2', 'Sleep Clause Mod'], - banlist: ['Corsola-Galar', 'Sneasel', 'Type: Null', 'Arena Trap', 'Ice Scales', 'Moody', 'King\'s Rock', 'Baton Pass'], - restricted: ['Chansey', 'Lunala', 'Shedinja', 'Solgaleo', 'Gorilla Tactics', 'Huge Power', 'Pure Power', 'Shadow Tag'], + ruleset: ['Standard OMs', 'Ability Clause = 2', 'Sleep Moves Clause', 'Min Source Gen = 9'], + banlist: ['Arena Trap', 'Huge Power', 'Pure Power', 'Shadow Tag', 'Moody', 'King\'s Rock', 'Baton Pass'], onValidateTeam(team) { const names = new Set(); for (const set of team) { @@ -763,7 +744,7 @@ export const Formats: FormatList = [ }, validateSet(set, teamHas) { const crossSpecies = this.dex.species.get(set.name); - let problems = this.dex.formats.get('Pokemon').onChangeSet?.call(this, set, this.format) || null; + let problems = this.dex.formats.get('Obtainable Misc').onChangeSet?.call(this, set, this.format) || null; if (Array.isArray(problems) && problems.length) return problems; const crossNonstandard = (!this.ruleTable.has('standardnatdex') && crossSpecies.isNonstandard === 'Past') || crossSpecies.isNonstandard === 'Future'; @@ -776,7 +757,8 @@ export const Formats: FormatList = [ const isCap = !this.ruleTable.has('+pokemontag:cap') && species.isNonstandard === 'CAP'; if (!species.exists || nonstandard || isCap || species === crossSpecies) return this.validateSet(set, teamHas); if (!species.nfe) return [`${species.name} cannot cross evolve because it doesn't evolve.`]; - const crossIsUnreleased = (crossSpecies.tier === "Unreleased" && crossSpecies.isNonstandard === "Unobtainable"); + const crossIsUnreleased = (crossSpecies.tier === "Unreleased" && crossSpecies.isNonstandard === "Unobtainable" && + !this.ruleTable.has('+unobtainable')); if (crossSpecies.battleOnly || crossIsUnreleased || !crossSpecies.prevo) { return [`${species.name} cannot cross evolve into ${crossSpecies.name} because it isn't an evolution.`]; } @@ -818,7 +800,8 @@ export const Formats: FormatList = [ const crossSpecies = this.dex.species.get(target.set.name); if (!crossSpecies.exists) return; if (species.battleOnly || !species.nfe) return; - const crossIsUnreleased = (crossSpecies.tier === "Unreleased" && crossSpecies.isNonstandard === "Unobtainable"); + const crossIsUnreleased = (crossSpecies.tier === "Unreleased" && crossSpecies.isNonstandard === "Unobtainable" && + !this.ruleTable.has('+unobtainable')); if (crossSpecies.battleOnly || crossIsUnreleased || !crossSpecies.prevo) return; const crossPrevoSpecies = this.dex.species.get(crossSpecies.prevo); if (!crossPrevoSpecies.prevo !== !species.prevo) return; @@ -851,6 +834,74 @@ export const Formats: FormatList = [ } }, }, + { + name: "[Gen 9] Partners in Crime", + desc: `Doubles-based metagame where both active ally Pokémon share abilities and moves.`, + threads: [ + `• Partners in Crime`, + ], + + mod: 'partnersincrime', + gameType: 'doubles', + searchShow: false, + ruleset: ['Standard Doubles', 'Dynamax Clause'], + banlist: ['Koraidon', 'Miraidon', 'Huge Power', 'Moody', 'Pure Power', 'Shadow Tag', 'Ally Switch', 'Swagger'], + onBeforeSwitchIn(pokemon) { + if (!pokemon.m.trackPP) pokemon.m.trackPP = new Map(); + pokemon.m.curMoves = this.dex.deepClone(pokemon.moves); + }, + onSwitchInPriority: 2, + onSwitchIn(pokemon) { + let ngas = false; + for (const poke of this.getAllActive()) { + if (this.toID(poke.ability) === ('neutralizinggas' as ID)) { + ngas = true; + break; + } + } + const BAD_ABILITIES = ['trace', 'imposter', 'neutralizinggas', 'illusion', 'wanderingspirit']; + const ally = pokemon.side.active.find(mon => mon && mon !== pokemon && !mon.fainted); + if (ally && ally.ability !== pokemon.ability) { + if (!pokemon.m.innate && !BAD_ABILITIES.includes(this.toID(ally.ability))) { + pokemon.m.innate = 'ability:' + ally.ability; + if (!ngas || ally.getAbility().isPermanent || pokemon.hasItem('Ability Shield')) { + pokemon.volatiles[pokemon.m.innate] = {id: pokemon.m.innate, target: pokemon}; + pokemon.m.startVolatile = true; + } + } + if (!ally.m.innate && !BAD_ABILITIES.includes(this.toID(pokemon.ability))) { + ally.m.innate = 'ability:' + pokemon.ability; + if (!ngas || pokemon.getAbility().isPermanent || ally.hasItem('Ability Shield')) { + ally.volatiles[ally.m.innate] = {id: ally.m.innate, target: ally}; + ally.m.startVolatile = true; + } + } + } + }, + // Starting innate abilities in scripts#actions + onSwitchOut(pokemon) { + if (pokemon.m.innate) { + pokemon.removeVolatile(pokemon.m.innate); + delete pokemon.m.innate; + } + const ally = pokemon.side.active.find(mon => mon && mon !== pokemon && !mon.fainted); + if (ally && ally.m.innate) { + ally.removeVolatile(ally.m.innate); + delete ally.m.innate; + } + }, + onFaint(pokemon) { + if (pokemon.m.innate) { + pokemon.removeVolatile(pokemon.m.innate); + delete pokemon.m.innate; + } + const ally = pokemon.side.active.find(mon => mon && mon !== pokemon && !mon.fainted); + if (ally && ally.m.innate) { + ally.removeVolatile(ally.m.innate); + delete ally.m.innate; + } + }, + }, { name: "[Gen 8] Inheritance", desc: `Pokémon may use the ability and moves of another, as long as they forfeit their own learnset.`, @@ -1314,74 +1365,6 @@ export const Formats: FormatList = [ }, }, }, - { - name: "[Gen 9] Partners in Crime", - desc: `Doubles-based metagame where both active ally Pokémon share abilities and moves.`, - threads: [ - `• Partners in Crime`, - ], - - mod: 'partnersincrime', - gameType: 'doubles', - searchShow: false, - ruleset: ['Standard Doubles', 'Dynamax Clause'], - banlist: ['Koraidon', 'Miraidon', 'Huge Power', 'Moody', 'Pure Power', 'Shadow Tag', 'Ally Switch', 'Swagger'], - onBeforeSwitchIn(pokemon) { - if (!pokemon.m.trackPP) pokemon.m.trackPP = new Map(); - pokemon.m.curMoves = this.dex.deepClone(pokemon.moves); - }, - onSwitchInPriority: 2, - onSwitchIn(pokemon) { - let ngas = false; - for (const poke of this.getAllActive()) { - if (this.toID(poke.ability) === ('neutralizinggas' as ID)) { - ngas = true; - break; - } - } - const BAD_ABILITIES = ['trace', 'imposter', 'neutralizinggas', 'illusion', 'wanderingspirit']; - const ally = pokemon.side.active.find(mon => mon && mon !== pokemon && !mon.fainted); - if (ally && ally.ability !== pokemon.ability) { - if (!pokemon.m.innate && !BAD_ABILITIES.includes(this.toID(ally.ability))) { - pokemon.m.innate = 'ability:' + ally.ability; - if (!ngas || ally.getAbility().isPermanent || pokemon.hasItem('Ability Shield')) { - pokemon.volatiles[pokemon.m.innate] = {id: pokemon.m.innate, target: pokemon}; - pokemon.m.startVolatile = true; - } - } - if (!ally.m.innate && !BAD_ABILITIES.includes(this.toID(pokemon.ability))) { - ally.m.innate = 'ability:' + pokemon.ability; - if (!ngas || pokemon.getAbility().isPermanent || ally.hasItem('Ability Shield')) { - ally.volatiles[ally.m.innate] = {id: ally.m.innate, target: ally}; - ally.m.startVolatile = true; - } - } - } - }, - // Starting innate abilities in scripts#actions - onSwitchOut(pokemon) { - if (pokemon.m.innate) { - pokemon.removeVolatile(pokemon.m.innate); - delete pokemon.m.innate; - } - const ally = pokemon.side.active.find(mon => mon && mon !== pokemon && !mon.fainted); - if (ally && ally.m.innate) { - ally.removeVolatile(ally.m.innate); - delete ally.m.innate; - } - }, - onFaint(pokemon) { - if (pokemon.m.innate) { - pokemon.removeVolatile(pokemon.m.innate); - delete pokemon.m.innate; - } - const ally = pokemon.side.active.find(mon => mon && mon !== pokemon && !mon.fainted); - if (ally && ally.m.innate) { - ally.removeVolatile(ally.m.innate); - delete ally.m.innate; - } - }, - }, { name: "[Gen 8] Pokebilities", desc: `Pokémon have all of their released abilities simultaneously.`,