Merge remote-tracking branch 'upstream/master' into dancer

This commit is contained in:
André Bastos Dias 2026-03-02 12:24:38 +00:00
commit f131aa52d6
145 changed files with 25798 additions and 30212 deletions

View File

@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2011-2024 Guangcong Luo and other contributors http://pokemonshowdown.com/
Copyright (c) 2011-2026 Guangcong Luo and other contributors http://pokemonshowdown.com/
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in

View File

@ -25,6 +25,15 @@ exports.bindaddress = '0.0.0.0';
*/
exports.wsdeflate = null;
/**
* lazysockets - disables eager initialization of network services
* Turn this on if you'd prefer to manually connect Showdown to the network,
* or you intend to run it offline.
*
* @type {boolean}
*/
exports.lazysockets = false;
/*
// example:
exports.wsdeflate = {

File diff suppressed because it is too large Load Diff

View File

@ -2050,7 +2050,7 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
}
},
onEnd(pokemon) {
if (pokemon.illusion) {
if (pokemon.illusion && !pokemon.beingCalledBack) {
this.debug('illusion cleared');
pokemon.illusion = null;
const details = pokemon.getUpdatedDetails();
@ -2366,10 +2366,7 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
return;
}
if (this.checkMoveMakesContact(move, source, target, !source.isAlly(target))) {
const oldAbility = source.setAbility('lingeringaroma', target);
if (oldAbility) {
this.add('-activate', target, 'ability: Lingering Aroma', this.dex.abilities.get(oldAbility).name, `[of] ${source}`);
}
source.setAbility('lingeringaroma', target);
}
},
flags: {},
@ -2747,10 +2744,7 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
return;
}
if (this.checkMoveMakesContact(move, source, target, !source.isAlly(target))) {
const oldAbility = source.setAbility('mummy', target);
if (oldAbility) {
this.add('-activate', target, 'ability: Mummy', this.dex.abilities.get(oldAbility).name, `[of] ${source}`);
}
source.setAbility('mummy', target);
}
},
flags: {},
@ -4288,6 +4282,10 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
return this.chainModify(0.5);
}
},
onEnd(pokemon) {
if (pokemon.beingCalledBack) return;
this.add('-end', pokemon, 'Slow Start', '[silent]');
},
flags: {},
name: "Slow Start",
rating: -1,
@ -5299,20 +5297,7 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
},
wanderingspirit: {
onDamagingHit(damage, target, source, move) {
if (source.getAbility().flags['failskillswap'] || target.volatiles['dynamax']) return;
if (this.checkMoveMakesContact(move, source, target)) {
const targetCanBeSet = this.runEvent('SetAbility', target, source, this.effect, source.ability);
if (!targetCanBeSet) return targetCanBeSet;
const sourceAbility = source.setAbility('wanderingspirit', target);
if (!sourceAbility) return;
if (target.isAlly(source)) {
this.add('-activate', target, 'Skill Swap', '', '', `[of] ${source}`);
} else {
this.add('-activate', target, 'ability: Wandering Spirit', this.dex.abilities.get(sourceAbility).name, 'Wandering Spirit', `[of] ${source}`);
}
target.setAbility(sourceAbility);
}
if (this.checkMoveMakesContact(move, source, target)) this.skillSwap(source, target);
},
flags: {},
name: "Wandering Spirit",

View File

@ -91,8 +91,10 @@ export const Aliases: import('../sim/dex').AliasesTable = {
zaou: "[Gen 9] Legends Z-A OU",
legendsou: "[Gen 9] Legends Z-A OU",
plzaou: "[Gen 9] Legends Z-A OU",
omotm: "[Gen 9] Pokebilities",
lcotm: "[Gen 9] Tera Override",
omotm: "[Gen 9] Linked",
lcotm: "[Gen 9] 350 Cup",
ommotm: "[Gen 9] Pokebilities AAA",
ommspotlight: "[Gen 9] Pokebilities AAA",
// mega evos --- 1st ordered alphabetically by species, 2nd by alias
megasnow: "Abomasnow-Mega",

View File

@ -879,6 +879,65 @@ export const Conditions: import('../sim/dex-conditions').ConditionDataTable = {
return [type];
},
},
zacian: {
name: 'Zacian',
onBattleStart(pokemon) {
if (pokemon.item !== 'rustedsword') return;
const rawSpecies = this.dex.species.get('Zacian-Crowned');
const species = pokemon.setSpecies(rawSpecies);
if (!species) return;
pokemon.baseSpecies = rawSpecies;
pokemon.details = pokemon.getUpdatedDetails();
pokemon.setAbility(species.abilities['0'], null, null, true);
pokemon.baseAbility = pokemon.ability;
const ironHeadIndex = pokemon.baseMoves.indexOf('ironhead');
if (ironHeadIndex >= 0) {
const move = this.dex.moves.get('behemothblade');
pokemon.baseMoveSlots[ironHeadIndex] = {
move: move.name,
id: move.id,
pp: move.noPPBoosts ? move.pp : move.pp * 8 / 5,
maxpp: move.noPPBoosts ? move.pp : move.pp * 8 / 5,
target: move.target,
disabled: false,
disabledSource: '',
used: false,
};
pokemon.moveSlots = pokemon.baseMoveSlots.slice();
}
},
},
zamazenta: {
name: 'Zamazenta',
onBattleStart(pokemon) {
if (pokemon.item !== 'rustedshield') return;
const rawSpecies = this.dex.species.get('Zamazenta-Crowned');
const species = pokemon.setSpecies(rawSpecies);
if (!species) return;
pokemon.baseSpecies = rawSpecies;
pokemon.details = pokemon.getUpdatedDetails();
pokemon.setAbility(species.abilities['0'], null, null, true);
pokemon.baseAbility = pokemon.ability;
const ironHeadIndex = pokemon.baseMoves.indexOf('ironhead');
if (ironHeadIndex >= 0) {
const move = this.dex.moves.get('behemothbash');
pokemon.baseMoveSlots[ironHeadIndex] = {
move: move.name,
id: move.id,
pp: move.noPPBoosts ? move.pp : move.pp * 8 / 5,
maxpp: move.noPPBoosts ? move.pp : move.pp * 8 / 5,
target: move.target,
disabled: false,
disabledSource: '',
used: false,
};
pokemon.moveSlots = pokemon.baseMoveSlots.slice();
}
},
},
rolloutstorage: {
name: 'rolloutstorage',
duration: 2,

View File

@ -496,7 +496,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
natDexTier: "RU",
},
politoed: {
tier: "NUBL",
tier: "RU",
doublesTier: "DUU",
natDexTier: "RU",
},
@ -628,7 +628,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
slowking: {
tier: "UU",
doublesTier: "(DUU)",
natDexTier: "RU",
natDexTier: "UU",
},
slowkinggalar: {
tier: "OU",
@ -646,7 +646,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
magnezone: {
tier: "RU",
doublesTier: "(DUU)",
natDexTier: "UU",
natDexTier: "RU",
},
farfetchd: {
isNonstandard: "Past",
@ -868,14 +868,14 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
tier: "LC",
},
chansey: {
tier: "RU",
tier: "NU",
doublesTier: "NFE",
natDexTier: "UU",
},
blissey: {
tier: "RU",
doublesTier: "(DUU)",
natDexTier: "RU",
natDexTier: "UU",
},
tangela: {
isNonstandard: "Past",
@ -958,7 +958,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
natDexTier: "NFE",
},
scizor: {
tier: "OU",
tier: "UU",
doublesTier: "(DUU)",
natDexTier: "UU",
},
@ -1088,7 +1088,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
natDexTier: "RU",
},
espeon: {
tier: "PU",
tier: "NU",
doublesTier: "(DUU)",
natDexTier: "RU",
},
@ -1121,7 +1121,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
natDexTier: "NFE",
},
porygonz: {
tier: "NUBL",
tier: "RU",
doublesTier: "(DUU)",
natDexTier: "UU",
},
@ -1478,7 +1478,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
tier: "NFE",
},
dudunsparce: {
tier: "PU",
tier: "NU",
doublesTier: "(DUU)",
natDexTier: "RU",
},
@ -1528,7 +1528,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
heracrossmega: {
isNonstandard: "Past",
tier: "Illegal",
natDexTier: "RUBL",
natDexTier: "UU",
},
sneasel: {
tier: "NFE",
@ -1682,7 +1682,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
natDexTier: "RU",
},
suicune: {
tier: "NUBL",
tier: "RU",
doublesTier: "(DUU)",
natDexTier: "RU",
},
@ -1693,7 +1693,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
tier: "NFE",
},
tyranitar: {
tier: "UU",
tier: "OU",
doublesTier: "DOU",
natDexTier: "UU",
},
@ -1763,7 +1763,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
swampertmega: {
isNonstandard: "Past",
tier: "Illegal",
natDexTier: "RU",
natDexTier: "UU",
},
poochyena: {
tier: "LC",
@ -1877,7 +1877,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
gardevoirmega: {
isNonstandard: "Past",
tier: "Illegal",
natDexTier: "UU",
natDexTier: "RUBL",
},
gallade: {
tier: "RU",
@ -1901,7 +1901,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
tier: "LC",
},
breloom: {
tier: "NU",
tier: "RU",
doublesTier: "(DUU)",
natDexTier: "RU",
},
@ -2096,7 +2096,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
sharpedomega: {
isNonstandard: "Past",
tier: "Illegal",
natDexTier: "RU",
natDexTier: "RUBL",
},
wailmer: {
isNonstandard: "Past",
@ -2390,7 +2390,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
salamence: {
tier: "RUBL",
doublesTier: "(DUU)",
natDexTier: "UU",
natDexTier: "RUBL",
},
salamencemega: {
isNonstandard: "Past",
@ -2510,7 +2510,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
tier: "NFE",
},
torterra: {
tier: "PUBL",
tier: "RU",
doublesTier: "(DUU)",
natDexTier: "RU",
},
@ -2534,7 +2534,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
empoleon: {
tier: "RU",
doublesTier: "(DUU)",
natDexTier: "RU",
natDexTier: "UU",
},
starly: {
tier: "LC",
@ -2638,7 +2638,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
tier: "LC",
},
floatzel: {
tier: "ZUBL",
tier: "PU",
doublesTier: "(DUU)",
natDexTier: "RU",
},
@ -2764,7 +2764,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
tier: "LC",
},
hippowdon: {
tier: "RU",
tier: "UU",
doublesTier: "DUU",
natDexTier: "UU",
},
@ -3399,7 +3399,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
tier: "NFE",
},
reuniclus: {
tier: "RU",
tier: "NU",
doublesTier: "(DUU)",
natDexTier: "RU",
},
@ -3455,7 +3455,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
amoonguss: {
tier: "PU",
doublesTier: "DOU",
natDexTier: "RU",
natDexTier: "UU",
},
frillish: {
isNonstandard: "Past",
@ -3476,7 +3476,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
tier: "LC",
},
galvantula: {
tier: "NU",
tier: "PU",
doublesTier: "(DUU)",
natDexTier: "RU",
},
@ -3593,7 +3593,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
tier: "LC",
},
mienshao: {
tier: "NUBL",
tier: "RU",
doublesTier: "(DUU)",
natDexTier: "RUBL",
},
@ -3631,7 +3631,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
tier: "NFE",
},
braviary: {
tier: "ZU",
tier: "NU",
doublesTier: "(DUU)",
natDexTier: "RU",
},
@ -3646,7 +3646,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
mandibuzz: {
tier: "UU",
doublesTier: "(DUU)",
natDexTier: "RU",
natDexTier: "UU",
},
heatmor: {
isNonstandard: "Past",
@ -3700,12 +3700,12 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
tornadustherian: {
tier: "OU",
doublesTier: "(DUU)",
natDexTier: "UUBL",
natDexTier: "OU",
},
thundurus: {
tier: "RUBL",
doublesTier: "DUU",
natDexTier: "RUBL",
natDexTier: "UU",
},
thundurustherian: {
tier: "UU",
@ -3734,7 +3734,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
},
kyurem: {
tier: "OU",
doublesTier: "DUU",
doublesTier: "DOU",
natDexTier: "OU",
},
kyuremblack: {
@ -3849,7 +3849,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
},
talonflame: {
tier: "RU",
doublesTier: "DUU",
doublesTier: "(DUU)",
natDexTier: "RU",
},
scatterbug: {
@ -4076,7 +4076,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
tier: "NFE",
},
goodra: {
tier: "PU",
tier: "NU",
doublesTier: "(DUU)",
natDexTier: "RU",
},
@ -4240,8 +4240,8 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
},
primarina: {
tier: "OU",
doublesTier: "DUU",
natDexTier: "RU",
doublesTier: "DOU",
natDexTier: "UU",
},
pikipek: {
tier: "LC",
@ -4317,7 +4317,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
tier: "NFE",
},
ribombee: {
tier: "NU",
tier: "RU",
doublesTier: "(DUU)",
natDexTier: "RU",
},
@ -4460,7 +4460,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
golisopod: {
isNonstandard: "Past",
tier: "Illegal",
natDexTier: "RU",
natDexTier: "UU",
},
golisopodmega: {
isNonstandard: "Future",
@ -4709,7 +4709,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
kartana: {
isNonstandard: "Past",
tier: "Illegal",
natDexTier: "OU",
natDexTier: "UUBL",
},
guzzlord: {
isNonstandard: "Past",
@ -4777,7 +4777,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
zeraora: {
isNonstandard: "Past",
tier: "Illegal",
natDexTier: "UU",
natDexTier: "RU",
},
zeraoramega: {
isNonstandard: "Future",
@ -4801,7 +4801,9 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
tier: "LC",
},
thwackey: {
tier: "NFE",
tier: "NU",
doublesTier: "NFE",
natDexTier: "NFE",
},
rillaboom: {
tier: "OU",
@ -5207,7 +5209,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
zamazentacrowned: {
tier: "Uber",
doublesTier: "DUber",
natDexTier: "Uber",
natDexTier: "OU",
},
eternatus: {
tier: "Uber",
@ -5281,7 +5283,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
},
enamorus: {
tier: "OU",
doublesTier: "(DUU)",
doublesTier: "DUU",
natDexTier: "RUBL",
},
enamorustherian: {
@ -5320,7 +5322,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
quaquaval: {
tier: "UUBL",
doublesTier: "(DUU)",
natDexTier: "UU",
natDexTier: "RUBL",
},
lechonk: {
tier: "LC",
@ -5349,7 +5351,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
lokix: {
tier: "UU",
doublesTier: "(DUU)",
natDexTier: "RU",
natDexTier: "UU",
},
rellor: {
tier: "LC",
@ -5554,7 +5556,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
glimmora: {
tier: "OU",
doublesTier: "DOU",
natDexTier: "UU",
natDexTier: "RU",
},
glimmoramega: {
isNonstandard: "Future",
@ -5564,7 +5566,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
tier: "LC",
},
grafaiai: {
tier: "ZU",
tier: "NU",
doublesTier: "(DUU)",
natDexTier: "RU",
},
@ -5609,7 +5611,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
natDexTier: "OU",
},
brutebonnet: {
tier: "PU",
tier: "ZU",
doublesTier: "DUU",
natDexTier: "RU",
},
@ -5771,7 +5773,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
okidogi: {
tier: "UUBL",
doublesTier: "(DUU)",
natDexTier: "RUBL",
natDexTier: "UUBL",
},
munkidori: {
tier: "NU",

File diff suppressed because it is too large Load Diff

View File

@ -32244,18 +32244,22 @@ export const Learnsets: import('../sim/dex-species').LearnsetDataTable = {
smeargle: {
learnset: {
captivate: ["5D"],
falseswipe: ["5S1"],
flamethrower: ["6S2"],
furyswipes: ["6S2"],
meanlook: ["5S1"],
odorsleuth: ["5S1"],
seismictoss: ["6S2"],
sketch: ["9L1", "7L1", "7V", "6L1", "6S2", "5L1", "5D", "4L1", "3L1", "3S0"],
doubleslap: ["3S1"],
falseswipe: ["5S2"],
flamethrower: ["6S3"],
furyswipes: ["6S3"],
irontail: ["3S1"],
meanlook: ["5S2"],
odorsleuth: ["5S2"],
seismictoss: ["6S3"],
sketch: ["9L1", "7L1", "7V", "6L1", "6S3", "5L1", "5D", "4L1", "3L1", "3S1", "3S0"],
sleeptalk: ["5D"],
spore: ["5S1"],
spore: ["5S2"],
tailwhip: ["3S1"],
},
eventData: [
{generation: 3, level: 10, gender: "M", abilities: ["owntempo"], moves: ["sketch"], pokeball: "pokeball"},
{generation: 3, level: 45, abilities: ["owntempo"], moves: ["sketch", "tailwhip", "doubleslap", "irontail"]},
{generation: 5, level: 50, gender: "F", nature: "Jolly", ivs: {atk: 31, spe: 31}, abilities: ["technician"], moves: ["falseswipe", "spore", "odorsleuth", "meanlook"], pokeball: "cherishball"},
{generation: 6, level: 40, gender: "M", nature: "Jolly", abilities: ["owntempo"], moves: ["sketch", "furyswipes", "seismictoss", "flamethrower"], pokeball: "cherishball"},
],
@ -49730,12 +49734,85 @@ export const Learnsets: import('../sim/dex-species').LearnsetDataTable = {
},
gastrodoneast: {
learnset: {
earthpower: ["9S3", "9S2", "8S1", "8S0"],
icebeam: ["9S2", "8S1", "8S0"],
icywind: ["9S3"],
protect: ["9S3", "9S2", "8S1", "8S0"],
surf: ["8S0"],
yawn: ["9S3", "9S2", "8S1"],
amnesia: ["9M", "8M"],
ancientpower: ["9L20", "8L20", "4T"],
attract: ["8M", "7M", "6M", "5M", "4M"],
blizzard: ["9M", "8M", "7M", "6M", "5M", "4M"],
block: ["7T", "6T", "5T", "4T"],
bodyslam: ["9M", "9L25", "8M", "8L25", "7L29", "6L29", "5L29", "4L29"],
brine: ["8M", "4M"],
bulldoze: ["9M", "8M", "7M", "6M", "5M"],
captivate: ["4M"],
chillingwater: ["9M"],
confide: ["7M", "6M"],
curse: ["9M"],
dig: ["9M", "8M", "6M", "5M", "4M"],
dive: ["8M", "6M", "5M", "4T"],
doubleteam: ["7M", "6M", "5M", "4M"],
earthpower: ["9M", "9L39", "9S2", "9S3", "8M", "8L39", "8S0", "8S1", "7T", "6T", "5T", "4T"],
earthquake: ["9M", "8M", "7M", "6M", "5M", "4M"],
endure: ["9M", "8M", "4M"],
facade: ["9M", "8M", "7M", "6M", "5M", "4M"],
flash: ["6M", "5M", "4M"],
frustration: ["7M", "6M", "5M", "4M"],
gigaimpact: ["9M", "8M", "7M", "6M", "5M", "4M"],
hail: ["8M", "7M", "6M", "5M", "4M"],
harden: ["9L1", "8L1", "7L1", "6L1", "5L1", "4L1"],
headbutt: ["4T"],
helpinghand: ["9M"],
hiddenpower: ["7M", "7L16", "6M", "6L16", "5M", "5L16", "4M", "4L16"],
hydropump: ["9M", "8M"],
hyperbeam: ["9M", "8M", "7M", "6M", "5M", "4M"],
icebeam: ["9M", "9S2", "8M", "8S0", "8S1", "7M", "6M", "5M", "4M"],
icywind: ["9M", "9S3", "8M", "7T", "6T", "5T", "4T"],
infestation: ["7M", "6M"],
liquidation: ["9M"],
memento: ["9L53", "8L53"],
mudbomb: ["7L11", "6L11", "5L11", "4L11"],
muddywater: ["9M", "9L33", "8M", "8L33", "7L41", "6L41", "5L41", "4L41"],
mudshot: ["9M", "8M"],
mudslap: ["9M", "9L1", "8L1", "7L1", "6L1", "5L1", "4T", "4L1"],
mudsport: ["7L1", "6L1", "5L1", "4L1"],
naturalgift: ["4M"],
painsplit: ["9M", "7T", "6T", "5T", "4T"],
protect: ["9M", "9S2", "9S3", "8M", "8S0", "8S1", "7M", "6M", "5M", "4M"],
raindance: ["9M", "9L46", "8M", "8L46", "7M", "7L22", "6M", "6L22", "5M", "5L22", "4M", "4L22"],
recover: ["9L1", "8L1", "7L54", "6L54", "5L54", "4L54"],
rest: ["9M", "8M", "7M", "6M", "5M", "4M"],
return: ["7M", "6M", "5M", "4M"],
rockblast: ["9M"],
rockslide: ["9M", "8M", "7M", "6M", "5M", "4M"],
rocksmash: ["6M", "5M", "4M"],
rocktomb: ["9M", "8M", "7M", "6M", "5M", "4M"],
round: ["8M", "7M", "6M", "5M"],
sandstorm: ["9M", "8M", "7M", "6M", "5M", "4M"],
sandtomb: ["9M", "8M"],
scald: ["8M", "7M", "6M", "5M"],
secretpower: ["6M", "4M"],
skittersmack: ["9M", "8T"],
sleeptalk: ["9M", "8M", "7M", "6M", "5T", "4M"],
sludgebomb: ["9M", "8M", "7M", "6M", "5M", "4M"],
sludgewave: ["9M", "8M", "7M", "6M", "5M"],
snore: ["8M", "7T", "6T", "5T", "4T"],
snowscape: ["9M"],
spikes: ["9M"],
stealthrock: ["9M"],
stompingtantrum: ["9M", "8M", "7T"],
stoneedge: ["9M", "8M", "7M", "6M", "5M", "4M"],
strength: ["6M", "5M", "4M"],
stringshot: ["4T"],
substitute: ["9M", "8M", "7M", "6M", "5M", "4M"],
surf: ["9M", "8M", "8S0", "7M", "6M", "5M", "4M"],
swagger: ["7M", "6M", "5M", "4M"],
takedown: ["9M"],
terablast: ["9M"],
toxic: ["7M", "6M", "5M", "4M"],
waterfall: ["9M", "8M", "7M", "6M", "5M", "4M"],
watergun: ["9L1", "8L1"],
waterpulse: ["9M", "9L15", "8L15", "7T", "7L1", "6T", "6L1", "5L1", "4M", "4L1"],
weatherball: ["9M", "8M"],
whirlpool: ["9M", "8M", "4M"],
yawn: ["9S2", "9S3", "8S1"],
},
eventData: [
{generation: 8, level: 50, gender: "F", nature: "Quiet", abilities: ["stormdrain"], ivs: {hp: 31, atk: 2, def: 31, spa: 31, spd: 31, spe: 0}, moves: ["protect", "surf", "icebeam", "earthpower"], pokeball: "cherishball"},
@ -53582,7 +53659,7 @@ export const Learnsets: import('../sim/dex-species').LearnsetDataTable = {
{generation: 6, level: 1, moves: ["tailglow", "bubble", "watersport", "heartswap"], pokeball: "cherishball"},
{generation: 6, level: 100, moves: ["tailglow", "bubble", "watersport"], pokeball: "cherishball"},
{generation: 7, level: 15, moves: ["tailglow", "waterpulse", "aquaring", "heartswap"], pokeball: "cherishball"},
{generation: 8, moves: ['tailglow', 'watergun'], pokeball: 'pokeball', source: "gen8bdsp"},
{generation: 8, level: 1, moves: ['tailglow', 'watergun'], pokeball: 'pokeball', source: "gen8bdsp"},
{generation: 8, level: 50, moves: ["waterpulse", "zenheadbutt", "moonblast", "bubble"], source: "gen8legends"},
{generation: 9, level: 50, shiny: true, nature: "Calm", ivs: {hp: 31, atk: 20, def: 31, spa: 20, spd: 31, spe: 20}, moves: ["bubblebeam", "acidarmor", "whirlpool", "waterpulse"], pokeball: "cherishball"},
],
@ -72938,10 +73015,79 @@ export const Learnsets: import('../sim/dex-species').LearnsetDataTable = {
},
pumpkaboosuper: {
learnset: {
astonish: ["6S0"],
scaryface: ["6S0"],
shadowsneak: ["6S0"],
trickortreat: ["6S0"],
allyswitch: ["8M", "7T"],
astonish: ["8L1", "7L1", "6L1", "6S0"],
attract: ["8M", "7M", "6M"],
bestow: ["7E", "6E"],
bulletseed: ["8M", "8L20", "7L26", "6L26"],
chargebeam: ["7M", "6M"],
confide: ["7M", "6M"],
confuseray: ["8L8", "7L1", "6L1"],
curse: ["8E", "7E"],
darkpulse: ["8M", "7M", "6M"],
destinybond: ["8E", "7E", "6E"],
disable: ["8E", "7E", "6E"],
doubleteam: ["7M", "6M"],
dreameater: ["7M", "6M"],
endure: ["8M"],
energyball: ["8M", "7M", "6M"],
explosion: ["7M", "6M"],
facade: ["8M", "7M", "6M"],
fireblast: ["8M", "7M", "6M"],
flamecharge: ["7M", "6M"],
flamethrower: ["8M", "7M", "6M"],
flash: ["6M"],
foulplay: ["8M", "7T", "6T"],
frustration: ["7M", "6M"],
gigadrain: ["8M", "7T", "6T"],
grassknot: ["8M", "7M", "6M"],
grassyglide: ["8T"],
gyroball: ["8M", "7M", "6M"],
hex: ["8M"],
hiddenpower: ["7M", "6M"],
imprison: ["8M"],
incinerate: ["6M"],
leechseed: ["8L16", "7L20", "6L20"],
lightscreen: ["8M", "7M", "6M"],
magiccoat: ["7T", "6T"],
mysticalfire: ["8M"],
naturepower: ["7M", "6M"],
painsplit: ["8L44", "7T", "7L42", "6T", "6L42"],
poltergeist: ["8T"],
protect: ["8M", "7M", "6M"],
psychic: ["8M", "7M", "6M"],
razorleaf: ["8L12", "7L16", "6L16"],
rest: ["8M", "7M", "6M"],
return: ["7M", "6M"],
rockslide: ["8M", "7M", "6M"],
rocksmash: ["6M"],
roleplay: ["7T", "6T"],
round: ["8M", "7M", "6M"],
safeguard: ["8M", "7M", "6M"],
scaryface: ["8M", "8L24", "7L4", "6L4", "6S0"],
secretpower: ["6M"],
seedbomb: ["8M", "8L32", "7T", "7L48", "6T", "6L48"],
shadowball: ["8M", "8L36", "7M", "7L36", "6M", "6L36"],
shadowsneak: ["8L4", "7L30", "6L30", "6S0"],
skillswap: ["8M", "7T", "6T"],
skittersmack: ["8T"],
sleeptalk: ["8M", "7M", "6M"],
sludgebomb: ["8M", "7M", "6M"],
snore: ["8M"],
solarbeam: ["8M", "7M", "6M"],
spite: ["7T", "6T"],
substitute: ["8M", "7M", "6M"],
sunnyday: ["8M", "7M", "6M"],
swagger: ["7M", "6M"],
synthesis: ["7T", "6T"],
telekinesis: ["7T"],
thief: ["8M", "7M", "6M"],
toxic: ["7M", "6M"],
trick: ["8M", "8L40", "7T", "7L1", "6T", "6L1"],
trickortreat: ["8L1", "7L23", "6L6", "6S0"],
trickroom: ["8M", "7M", "6M"],
willowisp: ["8M", "7M", "6M"],
worryseed: ["8L28", "7T", "7L11", "6T", "6L11"],
},
eventData: [
{generation: 6, level: 50, moves: ["trickortreat", "astonish", "scaryface", "shadowsneak"], pokeball: "cherishball"},
@ -73028,6 +73174,87 @@ export const Learnsets: import('../sim/dex-species').LearnsetDataTable = {
worryseed: ["8L28", "7T", "7L11", "6T", "6L11"],
},
},
gourgeistsuper: {
learnset: {
allyswitch: ["8M", "7T"],
astonish: ["8L1", "7L1", "6L1"],
attract: ["8M", "7M", "6M"],
brutalswing: ["8M"],
bulletseed: ["8M", "8L20", "7L26", "6L26"],
chargebeam: ["7M", "6M"],
confide: ["7M", "6M"],
confuseray: ["8L1", "7L1", "6L1"],
darkpulse: ["8M", "7M", "6M"],
doubleteam: ["7M", "6M"],
dreameater: ["7M", "6M"],
endure: ["8M"],
energyball: ["8M", "7M", "6M"],
explosion: ["8L1", "7M", "7L1", "6M", "6L1"],
facade: ["8M", "7M", "6M"],
fireblast: ["8M", "7M", "6M"],
flamecharge: ["7M", "6M"],
flamethrower: ["8M", "7M", "6M"],
flash: ["6M"],
focusblast: ["8M", "7M", "6M"],
foulplay: ["8M", "7T", "6T"],
frustration: ["7M", "6M"],
gigadrain: ["8M", "7T", "6T"],
gigaimpact: ["8M", "7M", "6M"],
grassknot: ["8M", "7M", "6M"],
grassyglide: ["8T"],
gyroball: ["8M", "7M", "6M"],
hex: ["8M"],
hiddenpower: ["7M", "6M"],
hyperbeam: ["8M", "7M", "6M"],
imprison: ["8M"],
incinerate: ["6M"],
leechseed: ["8L16", "7L20", "6L20"],
lightscreen: ["8M", "7M", "6M"],
magiccoat: ["7T", "6T"],
moonblast: ["8L1"],
mysticalfire: ["8M"],
nastyplot: ["8M"],
naturepower: ["7M", "6M"],
painsplit: ["8L44", "7T", "7L42", "6T", "6L42"],
phantomforce: ["8M", "8L48", "7L1", "6L1"],
poltergeist: ["8T"],
powerwhip: ["8M"],
protect: ["8M", "7M", "6M"],
psychic: ["8M", "7M", "6M"],
razorleaf: ["8L12", "7L16", "6L16"],
rest: ["8M", "7M", "6M"],
return: ["7M", "6M"],
rockslide: ["8M", "7M", "6M"],
rocksmash: ["6M"],
roleplay: ["7T", "6T"],
round: ["8M", "7M", "6M"],
safeguard: ["8M", "7M", "6M"],
scaryface: ["8M", "8L24", "7L1", "6L4"],
secretpower: ["6M"],
seedbomb: ["8M", "8L32", "7T", "7L48", "6T", "6L48"],
shadowball: ["8M", "8L36", "7M", "7L36", "6M", "6L36"],
shadowsneak: ["8L1", "7L30", "6L30"],
skillswap: ["8M", "7T", "6T"],
skittersmack: ["8T"],
sleeptalk: ["8M", "7M", "6M"],
sludgebomb: ["8M", "7M", "6M"],
snore: ["8M"],
solarbeam: ["8M", "7M", "6M"],
spite: ["7T", "6T"],
substitute: ["8M", "7M", "6M"],
sunnyday: ["8M", "7M", "6M"],
swagger: ["7M", "6M"],
synthesis: ["7T", "6T"],
telekinesis: ["7T"],
thief: ["8M", "7M", "6M"],
toxic: ["7M", "6M"],
trick: ["8M", "8L40", "7T", "7L1", "6T", "6L1"],
trickortreat: ["8L1", "7L23", "6L6"],
trickroom: ["8M", "7M", "6M"],
willowisp: ["8M", "7M", "6M"],
worryseed: ["8L28", "7T", "7L11", "6T", "6L11"],
},
},
bergmite: {
learnset: {
afteryou: ["7T", "6T"],
@ -84106,49 +84333,53 @@ export const Learnsets: import('../sim/dex-species').LearnsetDataTable = {
},
sinisteaantique: {
learnset: {
allyswitch: ["9E"],
aromatherapy: ["8S0"],
aromaticmist: ["9L6"],
astonish: ["9L1"],
batonpass: ["9M"],
allyswitch: ["9E", "8M"],
aromatherapy: ["8L30", "8S0"],
aromaticmist: ["9L6", "8L6"],
astonish: ["9L1", "8L1"],
batonpass: ["9M", "8M"],
calmmind: ["9M"],
celebrate: ["8S0"],
confuseray: ["9M"],
curse: ["9M"],
darkpulse: ["9M"],
endure: ["9M"],
facade: ["9M"],
foulplay: ["9M"],
gigadrain: ["9M", "9L36"],
hex: ["9M"],
imprison: ["9M"],
darkpulse: ["9M", "8M"],
endure: ["9M", "8M"],
facade: ["9M", "8M"],
foulplay: ["9M", "8M"],
gigadrain: ["9M", "9L36", "8M", "8L36"],
hex: ["9M", "8M"],
imprison: ["9M", "8M"],
magicalleaf: ["9M"],
megadrain: ["9L12"],
memento: ["9L54", "8S0"],
metronome: ["9M", "8S0"],
nastyplot: ["9M", "9L42"],
megadrain: ["9L12", "8L12"],
memento: ["9L54", "8L54", "8S0"],
metronome: ["9M", "8M", "8S0"],
nastyplot: ["9M", "9L42", "8M", "8L42"],
nightshade: ["9M"],
phantomforce: ["9M"],
poltergeist: ["9M"],
protect: ["9M"],
payback: ["8M"],
phantomforce: ["9M", "8M"],
poltergeist: ["9M", "8T"],
protect: ["9M", "8M", "8L18"],
psybeam: ["9M"],
psychic: ["9M"],
psyshock: ["9M"],
rest: ["9M"],
shadowball: ["9M", "9L48"],
shellsmash: ["9L60"],
psychic: ["9M", "8M"],
psyshock: ["9M", "8M"],
rest: ["9M", "8M"],
round: ["8M"],
shadowball: ["9M", "9L48", "8M", "8L48"],
shellsmash: ["9L60", "8L60"],
skillswap: ["9M"],
sleeptalk: ["9M"],
sleeptalk: ["9M", "8M"],
snore: ["8M"],
spite: ["9M"],
storedpower: ["9M"],
substitute: ["9M"],
suckerpunch: ["9L24"],
storedpower: ["9M", "8M"],
substitute: ["9M", "8M"],
suckerpunch: ["9L24", "8L24"],
sweetscent: ["9L30"],
terablast: ["9M"],
trick: ["9M"],
trick: ["9M", "8M"],
trickroom: ["9M"],
willowisp: ["9M"],
withdraw: ["9L1"],
willowisp: ["9M", "8M"],
withdraw: ["9L1", "8L1"],
wonderroom: ["8M"],
},
eventData: [
{generation: 8, level: 50, isHidden: true, moves: ["memento", "metronome", "aromatherapy", "celebrate"], pokeball: "cherishball"},
@ -84212,6 +84443,64 @@ export const Learnsets: import('../sim/dex-species').LearnsetDataTable = {
wonderroom: ["8M"],
},
},
polteageistantique: {
learnset: {
allyswitch: ["8M"],
aromatherapy: ["8L30"],
aromaticmist: ["9L1", "8L1"],
astonish: ["9L1", "8L1"],
batonpass: ["9M", "8M"],
calmmind: ["9M"],
confuseray: ["9M"],
curse: ["9M", "9L66", "8L66"],
darkpulse: ["9M", "8M"],
endure: ["9M", "8M"],
facade: ["9M", "8M"],
foulplay: ["9M", "8M"],
gigadrain: ["9M", "9L36", "8M", "8L36"],
gigaimpact: ["9M", "8M"],
hex: ["9M", "8M"],
hyperbeam: ["9M", "8M"],
imprison: ["9M", "8M"],
lightscreen: ["9M", "8M"],
magicalleaf: ["9M"],
megadrain: ["9L1", "8L1"],
memento: ["9L54", "8L54"],
metronome: ["9M", "8M"],
nastyplot: ["9M", "9L42", "8M", "8L42"],
nightshade: ["9M"],
painsplit: ["9M"],
payback: ["8M"],
phantomforce: ["9M", "8M"],
poltergeist: ["9M", "8T"],
protect: ["9M", "9L18", "8M", "8L18"],
psybeam: ["9M"],
psychic: ["9M", "8M"],
psyshock: ["9M", "8M"],
reflect: ["9M", "8M"],
rest: ["9M", "8M"],
round: ["8M"],
selfdestruct: ["8M"],
shadowball: ["9M", "9L48", "8M", "8L48"],
shellsmash: ["9L60", "8L60"],
skillswap: ["9M"],
sleeptalk: ["9M", "8M"],
snore: ["8M"],
spite: ["9M"],
storedpower: ["9M", "8M"],
strengthsap: ["9L1", "8L1"],
substitute: ["9M", "8M"],
suckerpunch: ["9L24", "8L24"],
sweetscent: ["9L30"],
teatime: ["9L0", "8L0"],
terablast: ["9M"],
trick: ["9M", "8M"],
trickroom: ["9M"],
willowisp: ["9M", "8M"],
withdraw: ["9L1", "8L1"],
wonderroom: ["8M"],
},
},
hatenna: {
learnset: {
afteryou: ["9E", "8E"],
@ -89284,7 +89573,7 @@ export const Learnsets: import('../sim/dex-species').LearnsetDataTable = {
waterpulse: ["9M"],
},
eventData: [
{generation: 9, moves: ["bodyslam", "amnesia", "icespinner", "doubleedge"]},
{generation: 9, level: 50, moves: ["bodyslam", "amnesia", "icespinner", "doubleedge"]},
],
},
frigibax: {
@ -89471,10 +89760,43 @@ export const Learnsets: import('../sim/dex-species').LearnsetDataTable = {
},
tatsugiristretchy: {
learnset: {
batonpass: ["9M", "9E"],
celebrate: ["9S0"],
dracometeor: ["9S0"],
helpinghand: ["9S0"],
muddywater: ["9S0"],
chillingwater: ["9M"],
counter: ["9E"],
dracometeor: ["9M", "9S0"],
dragoncheer: ["9M"],
dragondance: ["9M"],
dragonpulse: ["9M", "9L52"],
endure: ["9M"],
facade: ["9M"],
gigaimpact: ["9M"],
harden: ["9L6"],
helpinghand: ["9M", "9L12", "9S0"],
hydropump: ["9M"],
hyperbeam: ["9M"],
icywind: ["9M"],
lunge: ["9M"],
memento: ["9L34"],
mirrorcoat: ["9L47"],
muddywater: ["9M", "9L39", "9S0"],
nastyplot: ["9M", "9L43"],
outrage: ["9M"],
protect: ["9M"],
raindance: ["9M"],
rapidspin: ["9E"],
rest: ["9M"],
sleeptalk: ["9M"],
soak: ["9L23"],
splash: ["9L1"],
substitute: ["9M"],
surf: ["9M"],
takedown: ["9M"],
taunt: ["9M", "9L28"],
terablast: ["9M"],
watergun: ["9L1"],
waterpulse: ["9M", "9L17"],
whirlpool: ["9M"],
},
eventData: [
{generation: 9, level: 50, moves: ["dracometeor", "muddywater", "helpinghand", "celebrate"], pokeball: "cherishball"},

View File

@ -0,0 +1,206 @@
export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTable = {
magician: {
inherit: true,
onAfterMoveSecondarySelf(source, target, move) {
if (!move || source.switchFlag === true || !move.hitTargets || source.item || source.volatiles['gem'] ||
move.id === 'fling' || move.category === 'Status') return;
const hitTargets = move.hitTargets;
this.speedSort(hitTargets);
for (const pokemon of hitTargets) {
if (pokemon !== source) {
const yourItem = pokemon.takeItem(source);
if (!yourItem) continue;
if (!source.setItem(yourItem)) {
if (!this.dex.items.get(yourItem.id).exists) {
pokemon.setItem(yourItem.id);
continue;
}
pokemon.item = yourItem.id; // bypass setItem so we don't break choicelock or anything
continue;
}
this.add('-item', source, yourItem, '[from] ability: Magician', `[of] ${pokemon}`);
return;
}
}
},
},
neutralizinggas: {
inherit: true,
onSwitchIn(pokemon) {
this.add('-ability', pokemon, 'Neutralizing Gas');
pokemon.abilityState.ending = false;
const strongWeathers = ['desolateland', 'primordialsea', 'deltastream'];
for (const target of this.getAllActive()) {
if (target.hasItem('Ability Shield')) {
this.add('-block', target, 'item: Ability Shield');
continue;
}
// Can't suppress a Tatsugiri inside of Dondozo already
if (target.volatiles['commanding']) {
continue;
}
if (target.illusion) {
this.singleEvent('End', this.dex.abilities.get('Illusion'), target.abilityState, target, pokemon, 'neutralizinggas');
}
if (target.volatiles['slowstart']) {
delete target.volatiles['slowstart'];
this.add('-end', target, 'Slow Start', '[silent]');
}
if (strongWeathers.includes(target.getAbility().id)) {
this.singleEvent('End', this.dex.abilities.get(target.getAbility().id), target.abilityState, target, pokemon, 'neutralizinggas');
}
if (!this.dex.abilities.get(target.ability).exists) {
const isItem = (target.m.scrambled.items as { inSlot: string }[]).findIndex(e => e.inSlot === 'Ability');
if (isItem >= 0) {
target.removeVolatile('item:' + this.toID(target.m.scrambled.items[isItem].thing));
} else if ((target.m.scrambled.moves as { inSlot: string }[]).findIndex(e => e.inSlot === 'Ability') >= 0) {
const isMove = (target.m.scrambled.moves as { inSlot: string }[]).findIndex(e => e.inSlot === 'Ability');
const indexOfMove = target.moveSlots.findIndex(m => this.toID(target.m.scrambled.moves[isMove].thing) === m.id);
if (indexOfMove >= 0) target.moveSlots.splice(indexOfMove, 1);
}
}
}
},
onEnd(source) {
if (source.transformed) return;
for (const pokemon of this.getAllActive()) {
if (pokemon !== source && pokemon.hasAbility('Neutralizing Gas')) {
return;
}
}
this.add('-end', source, 'ability: Neutralizing Gas');
// FIXME this happens before the pokemon switches out, should be the opposite order.
// Not an easy fix since we cant use a supported event. Would need some kind of special event that
// gathers events to run after the switch and then runs them when the ability is no longer accessible.
// (If you're tackling this, do note extreme weathers have the same issue)
// Mark this pokemon's ability as ending so Pokemon#ignoringAbility skips it
if (source.abilityState.ending) return;
source.abilityState.ending = true;
const sortedActive = this.getAllActive();
this.speedSort(sortedActive);
for (const pokemon of sortedActive) {
if (pokemon !== source) {
if (pokemon.getAbility().flags['cantsuppress']) continue; // does not interact with e.g Ice Face, Zen Mode
if (pokemon.hasItem('abilityshield')) continue; // don't restart abilities that weren't suppressed
// Will be suppressed by Pokemon#ignoringAbility if needed
this.singleEvent('Start', pokemon.getAbility(), pokemon.abilityState, pokemon);
if (pokemon.ability === "gluttony") {
pokemon.abilityState.gluttony = false;
}
}
if (!this.dex.abilities.get(pokemon.ability).exists) {
const isItem = (pokemon.m.scrambled.items as { inSlot: string }[]).findIndex(e => e.inSlot === 'Ability');
if (isItem >= 0) {
pokemon.addVolatile('item:' + this.toID(pokemon.m.scrambled.items[isItem].thing));
} else if ((pokemon.m.scrambled.moves as { inSlot: string }[]).findIndex(e => e.inSlot === 'Ability') >= 0) {
const findMove = (pokemon.m.scrambled.moves as { inSlot: string }[]).findIndex(e => e.inSlot === 'Ability');
const findSlot = pokemon.baseMoveSlots.find(e => e.id === this.toID(pokemon.m.scrambled.moves[findMove].thing));
pokemon.moveSlots.push(this.dex.deepClone(findSlot));
}
}
}
},
},
pickpocket: {
inherit: true,
onAfterMoveSecondary(target, source, move) {
if (source && source !== target && move?.flags['contact']) {
if (target.item || target.switchFlag || target.forceSwitchFlag || source.switchFlag === true) {
return;
}
const yourItem = source.takeItem(target);
if (!yourItem) {
return;
}
if (!target.setItem(yourItem)) {
if (!this.dex.items.get(yourItem.id).exists) {
target.setItem(yourItem.id);
return;
}
source.item = yourItem.id;
return;
}
this.add('-enditem', source, yourItem, '[silent]', '[from] ability: Pickpocket', `[of] ${source}`);
this.add('-item', target, yourItem, '[from] ability: Pickpocket', `[of] ${source}`);
}
},
},
trace: {
inherit: true,
onStart(pokemon) {
this.effectState.seek = true;
// n.b. only affects Hackmons
// interaction with No Ability is complicated: https://www.smogon.com/forums/threads/pokemon-sun-moon-battle-mechanics-research.3586701/page-76#post-7790209
if (pokemon.adjacentFoes().some(foeActive => foeActive.ability === 'noability')) {
this.effectState.seek = false;
}
// interaction with Ability Shield is similar to No Ability
if (pokemon.hasItem('Ability Shield') && this.toID(pokemon.ability) === 'trace') {
this.add('-block', pokemon, 'item: Ability Shield');
this.effectState.seek = false;
}
if (this.effectState.seek) {
this.singleEvent('Update', this.effect, this.effectState, pokemon);
}
},
onUpdate(pokemon) {
if (!this.effectState.seek) return;
const possibleTargets = pokemon.adjacentFoes().filter(
target => !target.getAbility().flags['notrace'] && target.ability !== 'noability'
);
if (!possibleTargets.length) return;
const target = this.sample(possibleTargets);
const ability = target.getAbility();
if (this.toID(pokemon.item) === 'trace') {
this.add('-ability', pokemon, ability.name, 'Trace');
pokemon.setItem(ability.name);
return;
} else if (pokemon.volatiles['ability:trace']?.inSlot === 'Move') {
if (this.dex.abilities.get(ability.name).exists) {
pokemon.removeVolatile('ability:trace');
pokemon.m.scrambled.abilities.splice(
(pokemon.m.scrambled.abilities as { thing: string, inSlot: string }[]).findIndex(e =>
this.toID(e.thing) === 'trace' && e.inSlot === 'Move'), 1);
this.add('-ability', pokemon, ability.name, 'Trace');
pokemon.addVolatile(`ability:${ability.id}`);
pokemon.m.scrambled.abilities.push({ thing: ability.name, inSlot: 'Move' });
} else if (this.dex.items.get(ability.name).exists) {
pokemon.removeVolatile('ability:trace');
pokemon.m.scrambled.abilities.splice(
(pokemon.m.scrambled.abilities as { thing: string, inSlot: string }[]).findIndex(e =>
this.toID(e.thing) === 'trace' && e.inSlot === 'Move'), 1);
this.add('-ability', pokemon, ability.name, 'Trace');
pokemon.addVolatile(`item:${ability.id}`);
pokemon.m.scrambled.items.push({ thing: this.dex.items.get(ability.name).name, inSlot: 'Move' });
} else {
const move = this.dex.moves.get(ability.name);
if (move.exists) {
pokemon.removeVolatile('ability:trace');
pokemon.m.scrambled.abilities.splice(
(pokemon.m.scrambled.abilities as { thing: string, inSlot: string }[]).findIndex(e =>
this.toID(e.thing) === 'trace' && e.inSlot === 'Move'), 1);
this.add('-ability', pokemon, move.name, 'Trace');
const newMove = {
move: move.name,
id: move.id,
pp: move.noPPBoosts ? move.pp : move.pp * 8 / 5,
maxpp: move.noPPBoosts ? move.pp : move.pp * 8 / 5,
target: move.target,
disabled: false,
used: false,
};
pokemon.baseMoveSlots.push(newMove);
pokemon.moveSlots.push(newMove);
}
}
return;
}
pokemon.setAbility(ability, target);
},
},
};

View File

@ -0,0 +1,44 @@
export const Conditions: import('../../../sim/dex-conditions').ModdedConditionDataTable = {
choicelock: {
inherit: true,
onBeforeMove(pokemon, target, move) {
const choiceItem = pokemon.getItem().isChoice ||
Object.keys(pokemon.volatiles).some(v => (
v.startsWith('item:') && this.dex.items.get(v.split(':')[1]).isChoice
));
if (!choiceItem) {
pokemon.removeVolatile('choicelock');
return;
}
if (
!pokemon.ignoringItem() && !pokemon.volatiles['dynamax'] &&
move.id !== this.effectState.move && move.id !== 'struggle'
) {
// Fails unless the Choice item is being ignored, and no PP is lost
this.addMove('move', pokemon, move.name);
this.attrLastMove('[still]');
this.debug("Disabled by Choice item lock");
this.add('-fail', pokemon);
return false;
}
},
onDisableMove(pokemon) {
const choiceItem = pokemon.getItem().isChoice ||
Object.keys(pokemon.volatiles).some(v => (
v.startsWith('item:') && this.dex.items.get(v.split(':')[1]).isChoice
));
if (!choiceItem || !pokemon.hasMove(this.effectState.move)) {
pokemon.removeVolatile('choicelock');
return;
}
if (pokemon.ignoringItem() || pokemon.volatiles['dynamax']) {
return;
}
for (const moveSlot of pokemon.moveSlots) {
if (moveSlot.id !== this.effectState.move) {
pokemon.disableMove(moveSlot.id, false, this.effectState.sourceEffect);
}
}
},
},
};

View File

@ -0,0 +1,41 @@
export const Items: import('../../../sim/dex-items').ModdedItemDataTable = {
airballoon: {
inherit: true,
// airborneness implemented in sim/pokemon.js:Pokemon#isGrounded
onDamagingHit(damage, target, source, move) {
this.add('-enditem', target, 'Air Balloon');
if (target.item === 'airballoon') {
target.item = '';
this.clearEffectState(target.itemState);
} else {
const isBMM = target.volatiles['item:airballoon']?.inSlot;
if (isBMM) {
target.removeVolatile('item:airballoon');
target.m.scrambled.items.splice((target.m.scrambled.items as { thing: string, inSlot: string }[]).findIndex(e =>
this.toID(e.thing) === 'airballoon' && e.inSlot === isBMM), 1);
if (isBMM === 'Ability') target.setAbility('No Ability');
}
}
this.runEvent('AfterUseItem', target, null, null, this.dex.items.get('airballoon'));
},
onAfterSubDamage(damage, target, source, effect) {
this.debug('effect: ' + effect.id);
if (effect.effectType === 'Move') {
this.add('-enditem', target, 'Air Balloon');
if (target.item === 'airballoon') {
target.item = '';
this.clearEffectState(target.itemState);
} else {
const isBMM = target.volatiles['item:airballoon']?.inSlot;
if (isBMM) {
target.removeVolatile('item:airballoon');
target.m.scrambled.items.splice((target.m.scrambled.items as { thing: string, inSlot: string }[]).findIndex(e =>
this.toID(e.thing) === 'airballoon' && e.inSlot === isBMM), 1);
if (isBMM === 'Ability') target.setAbility('No Ability');
}
}
this.runEvent('AfterUseItem', target, null, null, this.dex.items.get('airballoon'));
}
},
},
};

View File

@ -0,0 +1,419 @@
export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
// Remember, everything deals with SLOTS not with properties as they are!
covet: {
inherit: true,
onAfterHit(target, source, move) {
if (source.item || source.volatiles['gem']) {
return;
}
const yourItem = target.takeItem(source);
if (!yourItem) {
return;
}
if (
!this.singleEvent('TakeItem', yourItem, target.itemState, source, target, move, yourItem) ||
!source.setItem(yourItem)
) {
if (!this.dex.items.get(yourItem.id).exists) {
target.setItem(yourItem.id);
return;
}
target.item = yourItem.id; // bypass setItem so we don't break choicelock or anything
return;
}
this.add('-item', source, yourItem, '[from] move: Covet', `[of] ${target}`);
},
},
embargo: {
inherit: true,
condition: {
duration: 5,
onStart(pokemon) {
this.add('-start', pokemon, 'Embargo');
this.singleEvent('End', pokemon.getItem(), pokemon.itemState, pokemon);
if (!this.dex.items.get(pokemon.item).exists) {
const isAbil = (pokemon.m.scrambled.abilities as { inSlot: string }[]).findIndex(e => e.inSlot === 'Item');
if (isAbil >= 0) {
pokemon.removeVolatile('ability:' + this.toID(pokemon.m.scrambled.abilities[isAbil].thing));
} else if ((pokemon.m.scrambled.moves as { inSlot: string }[]).findIndex(e => e.inSlot === 'Item') >= 0) {
const isMove = (pokemon.m.scrambled.moves as { inSlot: string }[]).findIndex(e => e.inSlot === 'Item');
const slotNo = pokemon.moveSlots.findIndex(m => this.toID(pokemon.m.scrambled.moves[isMove].thing) === m.id);
if (slotNo >= 0) pokemon.moveSlots.splice(slotNo, 1);
}
}
},
// Item suppression implemented in Pokemon.ignoringItem() within sim/pokemon.js
onResidualOrder: 21,
onEnd(pokemon) {
this.add('-end', pokemon, 'Embargo');
if (!this.dex.items.get(pokemon.item).exists) {
const isAbil = (pokemon.m.scrambled.abilities as { inSlot: string }[]).findIndex(e => e.inSlot === 'Item');
if (isAbil >= 0) {
pokemon.addVolatile('ability:' + this.toID(pokemon.m.scrambled.abilities[isAbil].thing));
} else if ((pokemon.m.scrambled.moves as { inSlot: string }[]).findIndex(e => e.inSlot === 'Item') >= 0) {
const findMove = (pokemon.m.scrambled.moves as { inSlot: string }[]).findIndex(e => e.inSlot === 'Item');
const findSlot = pokemon.baseMoveSlots.find(e => e.id === this.toID(pokemon.m.scrambled.moves[findMove].thing));
pokemon.moveSlots.push(this.dex.deepClone(findSlot));
}
}
},
},
},
magicroom: {
inherit: true,
condition: {
duration: 5,
durationCallback(source, effect) {
if (source?.hasAbility('persistent')) {
this.add('-activate', source, 'ability: Persistent', '[move] Magic Room');
return 7;
}
return 5;
},
onFieldStart(target, source) {
if (source?.hasAbility('persistent')) {
this.add('-fieldstart', 'move: Magic Room', `[of] ${source}`, '[persistent]');
} else {
this.add('-fieldstart', 'move: Magic Room', `[of] ${source}`);
}
for (const mon of this.getAllActive()) {
this.singleEvent('End', mon.getItem(), mon.itemState, mon);
if (!this.dex.items.get(mon.item).exists) {
const isAbil = (mon.m.scrambled.abilities as { inSlot: string }[]).findIndex(e => e.inSlot === 'Item');
if (isAbil >= 0) {
mon.removeVolatile('ability:' + this.toID(mon.m.scrambled.abilities[isAbil].thing));
} else if ((mon.m.scrambled.moves as { inSlot: string }[]).findIndex(e => e.inSlot === 'Item') >= 0) {
const isMove = (mon.m.scrambled.moves as { inSlot: string }[]).findIndex(e => e.inSlot === 'Item');
const slotNo = mon.moveSlots.findIndex(m => this.toID(mon.m.scrambled.moves[isMove].thing) === m.id);
if (slotNo >= 0) mon.moveSlots.splice(slotNo, 1);
}
}
}
},
onFieldRestart(target, source) {
this.field.removePseudoWeather('magicroom');
},
// Item suppression implemented in Pokemon.ignoringItem() within sim/pokemon.js
onFieldResidualOrder: 27,
onFieldResidualSubOrder: 6,
onFieldEnd() {
this.add('-fieldend', 'move: Magic Room', '[of] ' + this.effectState.source);
for (const pokemon of this.getAllActive()) {
if (!this.dex.items.get(pokemon.item).exists) {
const isAbil = (pokemon.m.scrambled.abilities as { inSlot: string }[]).findIndex(e => e.inSlot === 'Item');
if (isAbil >= 0) {
pokemon.addVolatile('ability:' + this.toID(pokemon.m.scrambled.abilities[isAbil].thing));
} else if ((pokemon.m.scrambled.moves as { inSlot: string }[]).findIndex(e => e.inSlot === 'Item') >= 0) {
const findMove = (pokemon.m.scrambled.moves as { inSlot: string }[]).findIndex(e => e.inSlot === 'Item');
const findSlot = pokemon.baseMoveSlots.find(e => e.id === this.toID(pokemon.m.scrambled.moves[findMove].thing));
pokemon.moveSlots.push(this.dex.deepClone(findSlot));
}
}
}
},
},
},
gastroacid: {
inherit: true,
condition: {
// Ability suppression implemented in Pokemon.ignoringAbility() within sim/pokemon.js
onStart(pokemon) {
this.add('-endability', pokemon);
this.singleEvent('End', pokemon.getAbility(), pokemon.abilityState, pokemon, pokemon, 'gastroacid');
if (!this.dex.abilities.get(pokemon.ability).exists) {
const isItem = (pokemon.m.scrambled.items as { inSlot: string }[]).findIndex(e => e.inSlot === 'Ability');
if (isItem >= 0) {
pokemon.removeVolatile('item:' + this.toID(pokemon.m.scrambled.items[isItem].thing));
} else if ((pokemon.m.scrambled.moves as { inSlot: string }[]).findIndex(e => e.inSlot === 'Ability') >= 0) {
const isMove = (pokemon.m.scrambled.moves as { inSlot: string }[]).findIndex(e => e.inSlot === 'Ability');
const slotNo = pokemon.moveSlots.findIndex(m => this.toID(pokemon.m.scrambled.moves[isMove].thing) === m.id);
if (slotNo >= 0) pokemon.moveSlots.splice(slotNo, 1);
}
}
},
},
},
trick: {
inherit: true,
onHit(target, source, move) {
const yourItem = target.takeItem(source);
const myItem = source.takeItem();
if (target.item || source.item || (!yourItem && !myItem)) {
if (yourItem) {
if (!this.dex.items.get(yourItem.id).exists) {
target.setItem(yourItem.id);
} else {
target.item = yourItem.id;
}
}
if (myItem) {
if (!this.dex.items.get(myItem.id).exists) {
source.setItem(myItem.id);
} else {
source.item = myItem.id;
}
}
return false;
}
if (
(myItem && !this.singleEvent('TakeItem', myItem, source.itemState, target, source, move, myItem)) ||
(yourItem && !this.singleEvent('TakeItem', yourItem, target.itemState, source, target, move, yourItem))
) {
if (yourItem) {
if (!this.dex.items.get(yourItem.id).exists) {
target.setItem(yourItem.id);
} else {
target.item = yourItem.id;
}
}
if (myItem) {
if (!this.dex.items.get(myItem.id).exists) {
source.setItem(myItem.id);
} else {
source.item = myItem.id;
}
}
return false;
}
this.add('-activate', source, 'move: Trick', `[of] ${target}`);
if (myItem) {
target.setItem(myItem);
this.add('-item', target, myItem, '[from] move: Trick');
} else {
this.add('-enditem', target, yourItem, '[silent]', '[from] move: Trick');
}
if (yourItem) {
source.setItem(yourItem);
this.add('-item', source, yourItem, '[from] move: Trick');
} else {
this.add('-enditem', source, myItem, '[silent]', '[from] move: Trick');
}
},
},
sketch: {
inherit: true,
onHit(target, source) {
const move = target.lastMove;
if (source.transformed || !move || source.moves.includes(move.id)) return false;
if (move.flags['nosketch'] || move.isZ || move.isMax) return false;
const sketchIndex = source.moves.indexOf('sketch');
if (sketchIndex < 0) return false;
if (this.toID(source.item) === 'sketch') {
source.setItem(move.name);
this.add('-activate', source, 'move: Sketch', move.name);
return;
} else if (this.toID(source.ability) === 'sketch') {
source.setAbility(move.name);
this.add('-activate', source, 'move: Sketch', move.name);
return;
}
const sketchedMove = {
move: move.name,
id: move.id,
pp: move.pp,
maxpp: move.pp,
target: move.target,
disabled: false,
used: false,
};
source.moveSlots[sketchIndex] = sketchedMove;
source.baseMoveSlots[sketchIndex] = sketchedMove;
this.add('-activate', source, 'move: Sketch', move.name);
},
},
skillswap: {
inherit: true,
onTryHit(target, source) {
const targetAbility = target.getAbility();
const sourceAbility = source.getAbility();
if (sourceAbility.flags['failskillswap'] || targetAbility.flags['failskillswap'] || target.volatiles['dynamax']) {
return false;
}
let sourceCanBeSet = this.runEvent('SetAbility', source, source, this.effect, targetAbility);
if (!this.dex.abilities.get(sourceAbility).exists && this.dex.items.get(sourceAbility.id).exists) {
sourceCanBeSet = this.runEvent('TakeItem', source, source, this.effect, this.dex.items.get(sourceAbility.id));
}
if (!sourceCanBeSet) return sourceCanBeSet;
let targetCanBeSet = this.runEvent('SetAbility', target, source, this.effect, sourceAbility);
if (!this.dex.abilities.get(targetAbility).exists && this.dex.items.get(targetAbility.id).exists) {
targetCanBeSet = this.runEvent('TakeItem', target, source, this.effect, this.dex.items.get(targetAbility.id));
}
if (!targetCanBeSet) return targetCanBeSet;
},
onHit(target, source, move) {
const targetAbility = target.getAbility();
const sourceAbility = source.getAbility();
const sourceIsBMM = !this.dex.abilities.get(sourceAbility).exists;
const targetIsBMM = !this.dex.abilities.get(targetAbility).exists;
if (target.isAlly(source)) {
this.add('-activate', source, 'move: Skill Swap', '', '', `[of] ${target}`);
} else {
this.add('-activate', source, 'move: Skill Swap', targetAbility, sourceAbility, `[of] ${target}`);
}
this.singleEvent('End', sourceAbility, source.abilityState, source);
if (sourceIsBMM) {
const isItem = (source.m.scrambled.items as { inSlot: string }[]).findIndex(e => e.inSlot === 'Ability');
if (isItem >= 0) {
source.removeVolatile('item:' + this.toID(source.m.scrambled.items[isItem].thing));
source.m.scrambled.items.splice(isItem, 1);
} else if ((source.m.scrambled.moves as { inSlot: string }[]).findIndex(e => e.inSlot === 'Ability') >= 0) {
const isMove = (source.m.scrambled.moves as { inSlot: string }[]).findIndex(e => e.inSlot === 'Ability');
source.baseMoveSlots.splice(
source.baseMoveSlots.findIndex(m => this.toID(source.m.scrambled.moves[isMove].thing) === m.id), 1);
source.moveSlots.splice(source.moveSlots.findIndex(m => this.toID(source.m.scrambled.moves[isMove].thing) === m.id), 1);
source.m.scrambled.moves.splice(isMove, 1);
}
}
this.singleEvent('End', targetAbility, target.abilityState, target);
if (targetIsBMM) {
const isItem = (target.m.scrambled.items as { inSlot: string }[]).findIndex(e => e.inSlot === 'Ability');
if (isItem >= 0) {
target.removeVolatile('item:' + this.toID(target.m.scrambled.items[isItem].thing));
target.m.scrambled.items.splice(isItem, 1);
} else if ((target.m.scrambled.moves as { inSlot: string }[]).findIndex(e => e.inSlot === 'Ability') >= 0) {
const isMove = (target.m.scrambled.moves as { inSlot: string }[]).findIndex(e => e.inSlot === 'Ability');
target.baseMoveSlots.splice(
target.baseMoveSlots.findIndex(m => this.toID(target.m.scrambled.moves[isMove].thing) === m.id), 1);
target.moveSlots.splice(target.moveSlots.findIndex(m => this.toID(target.m.scrambled.moves[isMove].thing) === m.id), 1);
target.m.scrambled.moves.splice(isMove, 1);
}
}
source.ability = source.baseAbility = targetAbility.id;
target.ability = target.baseAbility = sourceAbility.id;
source.abilityState = this.initEffectState({ id: this.toID(source.ability), target: source });
target.abilityState = this.initEffectState({ id: this.toID(target.ability), target });
source.volatileStaleness = undefined;
if (!target.isAlly(source)) target.volatileStaleness = 'external';
this.singleEvent('Start', targetAbility, source.abilityState, source);
if (targetIsBMM) {
if (this.dex.items.get(targetAbility.id).exists) {
source.m.scrambled.items.push({ thing: targetAbility.id, inSlot: 'Ability' });
const effect = 'item:' + this.toID(targetAbility.id);
source.addVolatile(effect);
source.volatiles[effect].inSlot = 'Ability';
} else {
source.m.scrambled.moves.push({ thing: targetAbility.id, inSlot: 'Ability' });
const bmmMove = Dex.moves.get(targetAbility.id);
const newMove = {
move: bmmMove.name,
id: bmmMove.id,
pp: bmmMove.noPPBoosts ? bmmMove.pp : bmmMove.pp * 8 / 5,
maxpp: bmmMove.noPPBoosts ? bmmMove.pp : bmmMove.pp * 8 / 5,
target: bmmMove.target,
disabled: false,
used: false,
};
source.baseMoveSlots.push(newMove);
source.moveSlots.push(newMove);
}
}
this.singleEvent('Start', sourceAbility, target.abilityState, target);
if (sourceIsBMM) {
if (this.dex.items.get(sourceAbility.id).exists) {
target.m.scrambled.items.push({ thing: sourceAbility.id, inSlot: 'Ability' });
const effect = 'item:' + this.toID(sourceAbility.id);
target.addVolatile(effect);
target.volatiles[effect].inSlot = 'Ability';
} else {
target.m.scrambled.moves.push({ thing: sourceAbility.id, inSlot: 'Ability' });
const bmmMove = Dex.moves.get(sourceAbility.id);
const newMove = {
move: bmmMove.name,
id: bmmMove.id,
pp: bmmMove.noPPBoosts ? bmmMove.pp : bmmMove.pp * 8 / 5,
maxpp: bmmMove.noPPBoosts ? bmmMove.pp : bmmMove.pp * 8 / 5,
target: bmmMove.target,
disabled: false,
used: false,
};
target.baseMoveSlots.push(newMove);
target.moveSlots.push(newMove);
}
}
},
},
switcheroo: {
inherit: true,
onHit(target, source, move) {
const yourItem = target.takeItem(source);
const myItem = source.takeItem();
if (target.item || source.item || (!yourItem && !myItem)) {
if (yourItem) {
if (!this.dex.items.get(yourItem.id).exists) {
target.setItem(yourItem.id);
} else {
target.item = yourItem.id;
}
}
if (myItem) {
if (!this.dex.items.get(myItem.id).exists) {
source.setItem(myItem.id);
} else {
source.item = myItem.id;
}
}
return false;
}
if (
(myItem && !this.singleEvent('TakeItem', myItem, source.itemState, target, source, move, myItem)) ||
(yourItem && !this.singleEvent('TakeItem', yourItem, target.itemState, source, target, move, yourItem))
) {
if (yourItem) {
if (!this.dex.items.get(yourItem.id).exists) {
target.setItem(yourItem.id);
} else {
target.item = yourItem.id;
}
}
if (myItem) {
if (!this.dex.items.get(myItem.id).exists) {
source.setItem(myItem.id);
} else {
source.item = myItem.id;
}
}
return false;
}
this.add('-activate', source, 'move: Trick', `[of] ${target}`);
if (myItem) {
target.setItem(myItem);
this.add('-item', target, myItem, '[from] move: Switcheroo');
} else {
this.add('-enditem', target, yourItem, '[silent]', '[from] move: Switcheroo');
}
if (yourItem) {
source.setItem(yourItem);
this.add('-item', source, yourItem, '[from] move: Switcheroo');
} else {
this.add('-enditem', source, myItem, '[silent]', '[from] move: Switcheroo');
}
},
},
thief: {
inherit: true,
onAfterHit(target, source, move) {
if (source.item || source.volatiles['gem']) {
return;
}
const yourItem = target.takeItem(source);
if (!yourItem) {
return;
}
if (!this.singleEvent('TakeItem', yourItem, target.itemState, source, target, move, yourItem) ||
!source.setItem(yourItem)) {
if (!this.dex.items.get(yourItem.id).exists) {
target.setItem(yourItem.id);
return;
}
target.item = yourItem.id; // bypass setItem so we don't break choicelock or anything
return;
}
this.add('-enditem', target, yourItem, '[silent]', '[from] move: Thief', `[of] ${source}`);
this.add('-item', source, yourItem, '[from] move: Thief', `[of] ${target}`);
},
},
};

View File

@ -0,0 +1,584 @@
import { RESTORATIVE_BERRIES } from "../../../sim/pokemon";
export const Scripts: ModdedBattleScriptsData = {
pokemon: {
isGrounded(negateImmunity) {
if ('gravity' in this.battle.field.pseudoWeather) return true;
if ('ingrain' in this.volatiles && this.battle.gen >= 4) return true;
if ('smackdown' in this.volatiles) return true;
const item = (this.ignoringItem() ? '' : this.item);
if (item === 'ironball' || (this.volatiles['item:ironball'] && !this.ignoringItem())) return true;
// If a Fire/Flying type uses Burn Up and Roost, it becomes ???/Flying-type, but it's still grounded.
if (!negateImmunity && this.hasType('Flying') && !(this.hasType('???') && 'roost' in this.volatiles)) return false;
if (this.hasAbility('levitate') && !this.battle.suppressingAbility(this)) return null;
if ('magnetrise' in this.volatiles) return false;
if ('telekinesis' in this.volatiles) return false;
if (item === 'airballoon' || (this.volatiles['item:airballoon'] && !this.ignoringItem())) return false;
return true;
},
getAbility() {
const ability = this.battle.dex.abilities.getByID(this.ability);
if (ability.exists) return ability;
let abil = this.battle.dex.items.getByID(this.ability) as Item | Move;
if (!abil.exists) abil = this.battle.dex.moves.getByID(this.ability);
return {
id: this.ability,
name: abil.name || this.ability,
flags: {},
effectType: "Ability",
toString() {
return abil.name || this.id;
},
} as Ability;
},
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];
},
ignoringAbility() {
// Check if any active pokemon have the ability Neutralizing Gas
let neutralizinggas = false;
for (const pokemon of this.battle.getAllActive()) {
// can't use hasAbility because it would lead to infinite recursion
if (
(pokemon.ability === ('neutralizinggas' as ID) ||
(pokemon.m.scrambled.abilities as { thing: string }[]).some(
abils => this.battle.toID(abils.thing) === 'neutralizinggas')) &&
!pokemon.volatiles['gastroacid'] && !pokemon.abilityState.ending
) {
neutralizinggas = true;
break;
}
}
return !!(
(this.battle.gen >= 5 && !this.isActive) ||
((this.volatiles['gastroacid'] ||
(neutralizinggas && (this.ability !== ('neutralizinggas' as ID) ||
(this.m.scrambled.abilities as { thing: string }[]).some(abils => this.battle.toID(abils.thing) === 'neutralizinggas'))
)) && !this.getAbility().flags['cantsuppress']
)
);
},
setAbility(ability, source, sourceEffect, isFromFormeChange = false, isTransform = false) {
const allThings = new Set([
...(this.m.scrambled.abilities as { thing: string }[]).map(e => e.thing),
...(this.m.scrambled.items as { thing: string }[]).map(e => e.thing),
...(this.m.scrambled.moves as { thing: string }[]).map(e => e.thing),
this.ability, ...this.moveSlots.map(e => e.move), this.item,
].map(this.battle.toID));
let isBMMAbil = false;
let isOldBMMAbil = false;
if (!this.hp) return false;
if (typeof ability === 'string') {
if (this.battle.dex.abilities.get(ability).exists) {
ability = this.battle.dex.abilities.get(ability);
} else {
const abilString = ability;
let abil = this.battle.dex.items.get(abilString) as Item | Move;
if (!abil.exists) abil = this.battle.dex.moves.get(abilString);
ability = {
id: abil.id || abilString,
name: abil.name || abilString,
flags: {},
effectType: "Ability",
toString() {
return abil.name || abilString;
},
} as Ability;
}
}
if (ability.name.length && !this.battle.dex.abilities.get(ability).exists) isBMMAbil = true;
if (!sourceEffect && this.battle.effect) sourceEffect = this.battle.effect;
let oldAbility;
if (this.battle.dex.abilities.get(this.ability).exists) {
oldAbility = this.battle.dex.abilities.get(this.ability);
} else {
let abil = this.battle.dex.items.getByID(this.ability) as Item | Move;
if (!abil.exists) {
abil = this.battle.dex.moves.getByID(this.ability);
} else {
if (!this.battle.runEvent('TakeItem', this, source, null, abil as Item)) return false;
}
oldAbility = {
id: this.ability,
name: abil.name || this.ability,
flags: {},
effectType: "Ability",
toString() {
return abil.name || this.id;
},
} as Ability;
isOldBMMAbil = true;
}
if (allThings.has(ability.id)) return false;
if (!isFromFormeChange) {
if (ability.flags['cantsuppress'] || this.getAbility().flags['cantsuppress']) return false;
}
if (!isFromFormeChange && !isTransform) {
const setAbilityEvent: boolean | null = this.battle.runEvent('SetAbility', this, source, sourceEffect, ability);
if (!setAbilityEvent) return setAbilityEvent;
}
this.battle.singleEvent('End', oldAbility, this.abilityState, this, source);
if (isOldBMMAbil) {
const isItem = (this.m.scrambled.items as { inSlot: string }[]).findIndex(e => e.inSlot === 'Ability');
if (isItem >= 0) {
this.removeVolatile('item:' + this.battle.toID(this.m.scrambled.items[isItem].thing));
this.m.scrambled.items.splice(isItem, 1);
} else if ((this.m.scrambled.moves as { inSlot: string }[]).findIndex(e => e.inSlot === 'Ability') >= 0) {
const isMove = (this.m.scrambled.moves as { inSlot: string }[]).findIndex(e => e.inSlot === 'Ability');
if (!isTransform) {
let indexOfMove = this.baseMoveSlots.findIndex(m => this.battle.toID(this.m.scrambled.moves[isMove].thing) === m.id);
if (indexOfMove >= 0) this.baseMoveSlots.splice(indexOfMove, 1);
if (oldAbility.id !== 'mimic') {
indexOfMove = this.moveSlots.findIndex(m => this.battle.toID(this.m.scrambled.moves[isMove].thing) === m.id);
}
if (indexOfMove >= 0) this.moveSlots.splice(indexOfMove, 1);
}
this.m.scrambled.moves.splice(isMove, 1);
}
}
this.ability = ability.id;
// ability changes are permanent in BioMechMons
if (!isTransform && !this.transformed) this.baseAbility = ability.id;
this.abilityState = this.battle.initEffectState({ id: ability.id, target: this });
if (sourceEffect && !isFromFormeChange && !isTransform) {
if (source) {
this.battle.add('-ability', this, ability.name, oldAbility.name, `[from] ${sourceEffect.fullname}`, `[of] ${source}`);
} else {
this.battle.add('-ability', this, ability.name, oldAbility.name, `[from] ${sourceEffect.fullname}`);
}
}
if (ability.id && this.battle.gen > 3 &&
(!isTransform || oldAbility.id !== ability.id || this.battle.gen <= 4)) {
this.battle.singleEvent('Start', ability, this.abilityState, this, source);
}
if (isBMMAbil) {
if (this.battle.dex.items.get(ability.id).exists) {
this.m.scrambled.items.push({ thing: ability.id, inSlot: 'Ability' });
const effect = 'item:' + this.battle.toID(ability.id);
this.addVolatile(effect);
this.volatiles[effect].inSlot = 'Ability';
} else {
this.m.scrambled.moves.push({ thing: ability.id, inSlot: 'Ability' });
const move = Dex.moves.get(ability.id);
const newMove = {
move: move.name,
id: move.id,
pp: move.noPPBoosts ? move.pp : move.pp * 8 / 5,
maxpp: move.noPPBoosts ? move.pp : move.pp * 8 / 5,
target: move.target,
disabled: false,
used: false,
};
if (!isTransform) {
this.baseMoveSlots.push(newMove);
this.moveSlots.push(newMove);
}
}
}
return oldAbility.id;
},
getItem() {
const item = this.battle.dex.items.getByID(this.item);
if (item.exists) return item;
let bmmItem = this.battle.dex.abilities.getByID(this.item) as Ability | Move;
if (!bmmItem.exists) bmmItem = this.battle.dex.moves.getByID(this.item);
return {
id: this.item,
name: bmmItem.name || this.name,
effectType: "Item",
toString() {
return bmmItem.name || this.id;
},
} as Item;
},
hasItem(item) {
if (this.ignoringItem()) return false;
if (Array.isArray(item)) return item.some(i => this.hasItem(i));
const itemId = this.battle.toID(item);
return this.item === itemId || !!this.volatiles['item:' + itemId];
},
takeItem(source) {
if (!this.item) return false;
if (!source) source = this;
if (this.battle.gen <= 4) {
if (source.itemKnockedOff) return false;
if (this.battle.toID(this.ability) === 'multitype' || (this.m.scrambled.abilities as { thing: string }[])
.findIndex(e => this.battle.toID(e.thing) === 'multitype') >= 0) {
return false;
}
if (this.battle.toID(source.ability) === 'multitype' || (source.m.scrambled.abilities as { thing: string }[])
.findIndex(e => this.battle.toID(e.thing) === 'multitype') >= 0) {
return false;
}
}
const item = this.getItem();
if (this.battle.runEvent('TakeItem', this, source, null, item)) {
this.item = '';
let wrongSlot = (this.m.scrambled.abilities as { inSlot: string }[]).findIndex(e => e.inSlot === 'Item');
if (wrongSlot >= 0) {
const dexAbil = this.battle.dex.abilities.get(this.m.scrambled.abilities[wrongSlot].thing);
if (dexAbil.flags['failskillswap']) return false;
this.removeVolatile('ability:' + this.battle.toID(this.m.scrambled.abilities[wrongSlot].thing));
this.m.scrambled.abilities.splice(wrongSlot, 1);
} else if ((this.m.scrambled.moves as { inSlot: string }[]).findIndex(e => e.inSlot === 'Item') >= 0) {
wrongSlot = (this.m.scrambled.moves as { inSlot: string }[]).findIndex(e => e.inSlot === 'Item');
let indexOfMove = this.baseMoveSlots.findIndex(m => this.battle.toID(this.m.scrambled.moves[wrongSlot].thing) === m.id);
if (indexOfMove >= 0) this.baseMoveSlots.splice(indexOfMove, 1);
if (item.id !== 'mimic') {
indexOfMove = this.moveSlots.findIndex(m => this.battle.toID(this.m.scrambled.moves[wrongSlot].thing) === m.id);
}
if (indexOfMove >= 0) this.moveSlots.splice(indexOfMove, 1);
this.m.scrambled.moves.splice(wrongSlot, 1);
}
const oldItemState = this.itemState;
this.battle.clearEffectState(this.itemState);
this.pendingStaleness = undefined;
this.battle.singleEvent('End', item, oldItemState, this);
this.battle.runEvent('AfterTakeItem', this, null, null, item);
return item;
}
return false;
},
setItem(item, source, effect) {
const allThings = new Set([
...(this.m.scrambled.abilities as { thing: string }[]).map(e => e.thing),
...(this.m.scrambled.items as { thing: string }[]).map(e => e.thing),
...(this.m.scrambled.moves as { thing: string }[]).map(e => e.thing),
this.ability, ...this.moveSlots.map(e => e.move), this.item,
].map(this.battle.toID));
let isBMMItem = false;
let isOldBMMItem = false;
if (!this.hp || !this.isActive) return false;
if (typeof item === 'string') {
if (!item.length || this.battle.dex.items.get(item).exists) {
item = this.battle.dex.items.get(item);
} else {
const itemString = item;
let newData = this.battle.dex.abilities.get(itemString) as Ability | Move;
if (!newData.exists) {
newData = this.battle.dex.moves.get(itemString);
} else {
if ((newData as Ability).flags['failskillswap']) return false;
}
item = {
id: newData.id || itemString,
name: newData.name || itemString,
effectType: "Item",
toString() {
return newData.name || itemString;
},
} as Item;
}
}
if (item.name.length && !this.battle.dex.items.get(item).exists) isBMMItem = true;
if (allThings.has(item.id)) return false;
const effectid = this.battle.effect ? this.battle.effect.id : '';
if (RESTORATIVE_BERRIES.has('leppaberry' as ID)) {
const inflicted = ['trick', 'switcheroo'].includes(effectid);
const external = inflicted && source && !source.isAlly(this);
this.pendingStaleness = external ? 'external' : 'internal';
} else {
this.pendingStaleness = undefined;
}
const oldItem = this.getItem();
if (!this.battle.dex.items.get(oldItem).exists) isOldBMMItem = true;
const oldItemState = this.itemState;
this.item = item.id;
this.itemState = this.battle.initEffectState({ id: item.id, target: this });
if (oldItem.exists) this.battle.singleEvent('End', oldItem, oldItemState, this);
if (isOldBMMItem) {
const isAbil = (this.m.scrambled.abilities as { inSlot: string }[]).findIndex(e => e.inSlot === 'Item');
if (isAbil >= 0) {
this.removeVolatile('ability:' + this.battle.toID(this.m.scrambled.items[isAbil].thing));
this.m.scrambled.abilities.splice(isAbil, 1);
} else if ((this.m.scrambled.moves as { inSlot: string }[]).findIndex(e => e.inSlot === 'Item') >= 0) {
const isMove = (this.m.scrambled.moves as { inSlot: string }[]).findIndex(e => e.inSlot === 'Item');
let indexOfMove = this.baseMoveSlots.findIndex(m => this.battle.toID(this.m.scrambled.moves[isMove].thing) === m.id);
if (indexOfMove >= 0) this.baseMoveSlots.splice(indexOfMove, 1);
if (oldItem.id !== 'mimic') {
indexOfMove = this.moveSlots.findIndex(m => this.battle.toID(this.m.scrambled.moves[isMove].thing) === m.id);
}
if (indexOfMove >= 0) this.moveSlots.splice(indexOfMove, 1);
this.m.scrambled.moves.splice(isMove, 1);
}
}
if (item.id) {
this.battle.singleEvent('Start', item, this.itemState, this, source, effect);
}
if (isBMMItem) {
if (this.battle.dex.abilities.get(item.id).exists) {
this.m.scrambled.abilities.push({ thing: item.id, inSlot: 'Item' });
const abileffect = 'ability:' + this.battle.toID(item.id);
this.addVolatile(abileffect);
this.volatiles[abileffect].inSlot = 'Item';
} else {
this.m.scrambled.moves.push({ thing: item.id, inSlot: 'Item' });
const move = Dex.moves.get(item.id);
const newMove = {
move: move.name,
id: move.id,
pp: move.noPPBoosts ? move.pp : move.pp * 8 / 5,
maxpp: move.noPPBoosts ? move.pp : move.pp * 8 / 5,
target: move.target,
disabled: false,
used: false,
};
this.baseMoveSlots.push(newMove);
this.moveSlots.push(newMove);
}
}
return true;
},
eatItem(force, source, sourceEffect) {
const item = sourceEffect?.effectType === 'Item' ? sourceEffect :
this.battle.effect.effectType === 'Item' ? this.battle.effect : this.getItem();
if (!item) return false;
if ((!this.hp && this.battle.toID(item.name) !== 'jabocaberry' && this.battle.toID(item.name) !== 'rowapberry') ||
!this.isActive) return false;
if (!sourceEffect && this.battle.effect) sourceEffect = this.battle.effect;
if (!source && this.battle.event?.target) source = this.battle.event.target;
// if (sourceEffect?.effectType === 'Item' && this.item !== sourceEffect.id && source === this) {
// // if an item is telling us to eat it but we aren't holding it, we probably shouldn't eat what we are holding
// return false;
// }
if (
this.battle.runEvent('UseItem', this, null, null, Dex.items.get(item.name)) &&
(force || this.battle.runEvent('TryEatItem', this, null, null, Dex.items.get(item.name)))
) {
this.battle.add('-enditem', this, Dex.items.get(item.name), '[eat]');
this.battle.singleEvent('Eat', Dex.items.get(item.name), this.itemState, this, source, sourceEffect);
this.battle.runEvent('EatItem', this, source, sourceEffect, Dex.items.get(item.name));
if (RESTORATIVE_BERRIES.has(item.id)) {
switch (this.pendingStaleness) {
case 'internal':
if (this.staleness !== 'external') this.staleness = 'internal';
break;
case 'external':
this.staleness = 'external';
break;
}
this.pendingStaleness = undefined;
}
const isBMM = this.volatiles[item.id]?.inSlot;
if (isBMM) {
const dexItem = this.battle.dex.items.get(item.name);
this.removeVolatile(item.id);
const itemIndex = (this.m.scrambled.items as { thing: string, inSlot: string }[]).findIndex(e =>
this.battle.toID(e.thing) === dexItem.id && e.inSlot === isBMM);
if (itemIndex >= 0) this.m.scrambled.items.splice(itemIndex, 1);
if (isBMM === 'Ability') this.setAbility('No Ability');
} else {
this.lastItem = this.item;
this.item = '';
}
this.battle.clearEffectState(this.itemState);
this.usedItemThisTurn = true;
this.ateBerry = true;
this.battle.runEvent('AfterUseItem', this, null, null, Dex.items.get(item.name));
return true;
}
return false;
},
useItem(source, sourceEffect) {
const item = sourceEffect?.effectType === 'Item' ? sourceEffect :
this.battle.effect.effectType === 'Item' ? this.battle.effect : this.getItem();
if ((!this.hp && !item.isGem) || !this.isActive) return false;
if (!item) return false;
if (!sourceEffect && this.battle.effect) sourceEffect = this.battle.effect;
if (!source && this.battle.event?.target) source = this.battle.event.target;
// const item = this.getItem();
// if (sourceEffect?.effectType === 'Item' && this.item !== sourceEffect.id && source === this) {
// // if an item is telling us to eat it but we aren't holding it, we probably shouldn't eat what we are holding
// return false;
// }
if (this.battle.runEvent('UseItem', this, null, null, Dex.items.get(item.name))) {
switch (item.id) {
case 'redcard':
this.battle.add('-enditem', this, Dex.items.get(item.name), `[of] ${source}`);
break;
default:
if (item.isGem) {
this.battle.add('-enditem', this, Dex.items.get(item.name), '[from] gem');
} else {
this.battle.add('-enditem', this, Dex.items.get(item.name));
}
break;
}
if (item.boosts) {
this.battle.boost(item.boosts, this, source, Dex.items.get(item.name));
}
this.battle.singleEvent('Use', Dex.items.get(item.name), this.itemState, this, source, sourceEffect);
const isBMM = this.volatiles[item.id]?.inSlot;
if (isBMM) {
const dexItem = this.battle.dex.items.get(item.name);
this.removeVolatile(item.id);
const itemIndex = (this.m.scrambled.items as { thing: string, inSlot: string }[]).findIndex(e =>
this.battle.toID(e.thing) === dexItem.id && e.inSlot === isBMM);
if (itemIndex >= 0) this.m.scrambled.items.splice(itemIndex, 1);
if (isBMM === 'Ability') this.setAbility('No Ability');
} else {
this.lastItem = this.item;
this.item = '';
}
this.battle.clearEffectState(this.itemState);
this.usedItemThisTurn = true;
this.battle.runEvent('AfterUseItem', this, null, null, item);
return true;
}
return false;
},
transformInto(pokemon, effect) {
const species = pokemon.species;
if (
pokemon.fainted || this.illusion || pokemon.illusion || (pokemon.volatiles['substitute'] && this.battle.gen >= 5) ||
(pokemon.transformed && this.battle.gen >= 2) || (this.transformed && this.battle.gen >= 5) ||
species.name === 'Eternatus-Eternamax' ||
(['Ogerpon', 'Terapagos'].includes(species.baseSpecies) && (this.terastallized || pokemon.terastallized)) ||
this.terastallized === 'Stellar'
) {
return false;
}
if (this.battle.dex.currentMod === 'gen1stadium' && (
species.name === 'Ditto' ||
(this.species.name === 'Ditto' && pokemon.moves.includes('transform'))
)) {
return false;
}
if (!this.setSpecies(species, effect, true)) return false;
this.transformed = true;
this.weighthg = pokemon.weighthg;
const types = pokemon.getTypes(true, true);
this.setType(pokemon.volatiles['roost'] ? pokemon.volatiles['roost'].typeWas : types, true);
this.addedType = pokemon.addedType;
this.knownType = this.isAlly(pokemon) && pokemon.knownType;
this.apparentType = pokemon.apparentType;
let statName: StatIDExceptHP;
for (statName in this.storedStats) {
this.storedStats[statName] = pokemon.storedStats[statName];
if (this.modifiedStats) this.modifiedStats[statName] = pokemon.modifiedStats![statName]; // Gen 1: Copy modified stats.
}
this.moveSlots = [];
this.hpType = (this.battle.gen >= 5 ? this.hpType : pokemon.hpType);
this.hpPower = (this.battle.gen >= 5 ? this.hpPower : pokemon.hpPower);
this.timesAttacked = pokemon.timesAttacked;
for (const moveSlot of pokemon.moveSlots) {
let moveName = moveSlot.move;
if (moveSlot.id === 'hiddenpower') {
moveName = 'Hidden Power ' + this.hpType;
}
this.moveSlots.push({
move: moveName,
id: moveSlot.id,
pp: moveSlot.maxpp === 1 ? 1 : 5,
maxpp: this.battle.gen >= 5 ? (moveSlot.maxpp === 1 ? 1 : 5) : moveSlot.maxpp,
target: moveSlot.target,
disabled: false,
used: false,
virtual: true,
});
}
let boostName: BoostID;
for (boostName in pokemon.boosts) {
this.boosts[boostName] = pokemon.boosts[boostName];
}
if (this.battle.gen >= 6) {
// we need to remove all of the overlapping crit volatiles before adding any of them
const volatilesToCopy = ['dragoncheer', 'focusenergy', 'gmaxchistrike', 'laserfocus'];
for (const volatile of volatilesToCopy) this.removeVolatile(volatile);
for (const volatile of volatilesToCopy) {
if (pokemon.volatiles[volatile]) {
this.addVolatile(volatile);
if (volatile === 'gmaxchistrike') this.volatiles[volatile].layers = pokemon.volatiles[volatile].layers;
if (volatile === 'dragoncheer') this.volatiles[volatile].hasDragonType = pokemon.volatiles[volatile].hasDragonType;
}
}
}
if (effect) {
this.battle.add('-transform', this, pokemon, '[from] ' + effect.fullname);
} else {
this.battle.add('-transform', this, pokemon);
}
if (this.terastallized) {
this.knownType = true;
this.apparentType = this.terastallized;
}
if (this.battle.gen > 2) this.setAbility(pokemon.ability, this, null, true, true);
// Change formes based on held items (for Transform)
// Only ever relevant in Generation 4 since Generation 3 didn't have item-based forme changes
if (this.battle.gen === 4) {
if (this.species.num === 487) {
// Giratina formes
if (this.species.name === 'Giratina' && this.item === 'griseousorb') {
this.formeChange('Giratina-Origin');
} else if (this.species.name === 'Giratina-Origin' && this.item !== 'griseousorb') {
this.formeChange('Giratina');
}
}
if (this.species.num === 493) {
// Arceus formes
const item = this.getItem();
const targetForme = (item?.onPlate ? 'Arceus-' + item.onPlate : 'Arceus');
if (this.species.name !== targetForme) {
this.formeChange(targetForme);
}
}
}
// Pokemon transformed into Ogerpon cannot Terastallize
// restoring their ability to tera after they untransform is handled ELSEWHERE
if (['Ogerpon', 'Terapagos'].includes(this.species.baseSpecies) && this.canTerastallize) this.canTerastallize = false;
for (const volatile in this.volatiles) {
if (this.volatiles[volatile].inSlot && this.volatiles[volatile].inSlot === 'Move') {
this.removeVolatile(volatile);
}
}
for (const volatile in pokemon.volatiles) {
if (pokemon.volatiles[volatile].inSlot && pokemon.volatiles[volatile].inSlot === 'Move') {
this.addVolatile(volatile);
this.volatiles[volatile].inSlot = 'Move';
}
}
return true;
},
},
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.abilities.get(x.replace('ability:', '')).suppressWeather
)))) {
return true;
}
}
return false;
},
},
};

View File

@ -953,4 +953,41 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
},
shortDesc: "This Pokemon can poison a Pokemon regardless of its typing and hit them with Poison moves.",
},
jellobody: {
onTryHit(pokemon, target, move) {
if (move.selfSwitch) {
this.add('-immune', pokemon, '[from] ability: Jello Body');
this.heal(target.baseMaxhp / 2);
return null;
}
},
onModifyMove(move, source, target) {
move.drain = [1, 2];
},
flags: { breakable: 1 },
name: "Jello Body",
rating: 5,
num: -122,
shortDesc: "Immune to pivot moves, heals 50% HP when hit by one. All moves drain 50%.",
},
nibblenibble: {
onPrepareHit(source, target, move) {
if (move.category === 'Status' || move.multihit || move.flags['noparentalbond'] || move.flags['charge'] ||
move.flags['futuremove'] || move.spreadHit || move.isZ || move.isMax || !move.flags['bite']) return;
move.multihit = 2;
move.multihitType = 'parentalbond';
},
// Damage modifier implemented in BattleActions#modifyDamage()
onSourceModifySecondaries(secondaries, target, source, move) {
if (move.multihitType === 'parentalbond' && move.id === 'secretpower' && move.hit < 2) {
// hack to prevent accidentally suppressing King's Rock/Razor Fang
return secondaries.filter(effect => effect.volatileStatus === 'flinch');
}
},
flags: {},
name: "Nibble Nibble",
rating: 5,
num: -123,
shortDesc: "Parental Bond but for Bite moves.",
},
};

View File

@ -13,12 +13,10 @@ export const Items: import('../../../sim/dex-items').ModdedItemDataTable = {
masquerainite: {
name: "Masquerainite",
spritenum: 1,
megaStone: "Masquerain-Mega",
megaEvolves: "Masquerain",
megaStone: { "Masquerain": "Masquerain-Mega" },
itemUser: ["Masquerain"],
onTakeItem(item, source) {
if (item.megaEvolves === source.baseSpecies.baseSpecies) return false;
return true;
return !item.megaStone?.[source.baseSpecies.baseSpecies];
},
num: -1,
gen: 9,
@ -59,12 +57,10 @@ export const Items: import('../../../sim/dex-items').ModdedItemDataTable = {
typhlosionite: {
name: "Typhlosionite",
spritenum: 1,
megaStone: "Typhlosion-Mega",
megaEvolves: "Typhlosion",
megaStone: { "Typhlosion": "Typhlosion-Mega" },
itemUser: ["Typhlosion"],
onTakeItem(item, source) {
if (item.megaEvolves === source.baseSpecies.baseSpecies) return false;
return true;
return !item.megaStone?.[source.baseSpecies.baseSpecies];
},
num: -2,
gen: 9,
@ -127,14 +123,28 @@ export const Items: import('../../../sim/dex-items').ModdedItemDataTable = {
},
onDamagePriority: -40,
onDamage(damage, target, source, effect) {
const chance = Math.max(Math.floor(target.hp / target.maxhp), 10);
const chance = Math.max(Math.floor(100 - (target.maxhp - target.hp)), 10);
if (this.randomChance(chance, 100) && damage >= target.hp && effect && effect.effectType === 'Move') {
this.add("-activate", target, "item: Focus Band");
return target.hp - 1;
} else {
return damage;
}
},
num: 230,
gen: 2,
desc: "Chance to survive attack equal to percentage of remaining HP, minimum 10%.",
},
raticite: {
name: "Raticite",
spritenum: 1,
megaStone: { "Raticate": "Raticate-Mega" },
itemUser: ["Raticate"],
onTakeItem(item, source) {
return !item.megaStone?.[source.baseSpecies.baseSpecies];
},
num: -3,
gen: 9,
desc: "If held by a Raticate, this item allows it to Mega Evolve in battle.",
},
};

View File

@ -1311,10 +1311,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
this.add('-fail', source, 'move: Crowverload');
return this.NOT_FAIL;
}
if (source.hp <= source.maxhp / 4) {
this.add('-fail', source, 'move: Substitute', '[weak]');
return this.NOT_FAIL;
}
},
onAfterMove(source, target, move) {
this.actions.useMove('substitute', source, { });
@ -1532,16 +1528,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
return false;
}
},
onTryHeal(damage, target, source, effect) {
if (effect && (effect.id === 'zpower' || (effect as Move).isZ)) return damage;
if (source && target !== source && target.hp !== target.maxhp && effect.name === "Pollen Puff") {
this.attrLastMove('[still]');
// FIXME: Wrong error message, correct one not supported yet
this.add('cant', source, 'move: Electric Terrain', effect);
return null;
}
return false;
},
onFieldResidualOrder: 27,
onFieldResidualSubOrder: 7,
onFieldEnd() {
@ -1635,6 +1621,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
target: "normal",
type: "Normal",
contestType: "Cute",
shortDesc: "Present but better.",
},
sinisterarrows: {
num: -1016,
@ -1712,9 +1699,54 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
target: "normal",
type: "Ghost",
contestType: "Clever",
shortDesc: "Hits for 4 turns, even if user switches out.",
},
mortalspin: {
inherit: true,
category: "Special",
},
lastbreakfast: {
num: -1020,
accuracy: 100,
basePower: 80,
category: "Physical",
name: "Last Breakfast",
pp: 15,
priority: 0,
flags: { protect: 1, mirror: 1, metronome: 1, contact: 1, bite: 1 },
onHit(target, source, move) {
const numberBerries = 0 + 1 * Number(source.side.totalFainted);
for (let i = 0; i < numberBerries; i++) {
const possibleBerries = ['aguavberry', 'apicotberry', 'enigmaberry', 'figyberry', 'ganlonberry', 'iapapaberry',
'keeberry', 'lansatberry', 'leppaberry', 'liechiberry', 'lumberry', 'magoberry',
'marangaberry', 'micleberry',
'oranberry', 'petayaberry', 'salacberry', 'sitrusberry', 'starfberry', 'wikiberry',
'aspearberry', 'cheriberry', 'chestoberry', 'lumberry', 'pechaberry', 'rawstberry', 'persimberry'];
const chosenBerry = this.sample(possibleBerries);
const berry = this.dex.items.get(chosenBerry);
if (source.hp && berry.isBerry) {
if (this.singleEvent('Eat', berry, null, source, source, move)) {
this.runEvent('EatItem', source, source, move, berry);
}
if (berry.onEat) source.ateBerry = true;
}
}
},
onTryMove() {
this.attrLastMove('[still]');
},
onPrepareHit(target, source) {
this.add('-anim', source, 'Curse', target);
this.add('-anim', source, 'Bug Bite', target);
},
secondary: null,
target: "normal",
type: "Ghost",
contestType: "Cute",
shortDesc: "Eats X random berries, where X is fainted teammates.",
},
superfang: {
inherit: true,
flags: { contact: 1, protect: 1, mirror: 1, metronome: 1, bite: 1 },
},
};

View File

@ -482,10 +482,33 @@ export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable
ogerponcornerstone: {
inherit: true,
abilities: { 0: "Solid Rock" },
types: ["Psychic", "Normal"],
},
glimmora: {
inherit: true,
abilities: { 0: "Corrosion" },
},
wobbuffet: {
inherit: true,
abilities: { 0: "Jello Body" },
},
raticate: {
inherit: true,
abilities: { 0: "Hustle" },
baseStats: { hp: 90, atk: 81, def: 60, spa: 50, spd: 70, spe: 97 },
},
raticatemega: {
num: -977,
name: "Raticate-Mega",
baseSpecies: "Raticate",
forme: "Mega",
types: ["Normal", "Ghost"],
genderRatio: { M: 0.5, F: 0.5 },
baseStats: { hp: 90, atk: 105, def: 60, spa: 50, spd: 70, spe: 173 },
abilities: { 0: "Nibble Nibble" },
heightm: 0.7,
weightkg: 5,
color: "Black",
eggGroups: ["Field"],
requiredItem: "Raticite",
},
};

View File

@ -294,5 +294,11 @@ export const Scripts: ModdedBattleScriptsData = {
this.modData('Learnsets', 'glimmora').learnset.icebeam = ['9L1'];
this.modData('Learnsets', 'glimmora').learnset.malignantchain = ['9L1'];
this.modData('Learnsets', 'wobbuffet').learnset.nightshade = ['9L1'];
this.modData('Learnsets', 'wobbuffet').learnset.guillotine = ['9L1'];
this.modData('Learnsets', 'wobbuffet').learnset.shedtail = ['9L1'];
this.modData('Learnsets', 'raticate').learnset.lastbreakfast = ['9L1'];
},
};

View File

@ -51,7 +51,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "NFE",
},
pidgeot: {
tier: "ZU",
tier: "PU",
},
rattata: {
tier: "LC",
@ -90,7 +90,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "NFE",
},
nidoqueen: {
tier: "PU",
tier: "ZU",
},
nidoranm: {
tier: "LC",
@ -117,7 +117,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "LC",
},
wigglytuff: {
tier: "PU",
tier: "ZU",
},
zubat: {
tier: "LC",
@ -132,7 +132,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "NFE",
},
vileplume: {
tier: "PU",
tier: "ZU",
},
paras: {
tier: "LC",
@ -168,7 +168,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "LC",
},
primeape: {
tier: "ZU",
tier: "PU",
},
growlithe: {
tier: "LC",
@ -189,7 +189,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "PU",
},
kadabra: {
tier: "UU",
tier: "NU",
},
alakazam: {
tier: "OU",
@ -201,7 +201,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "NFE",
},
machamp: {
tier: "PU",
tier: "ZU",
},
bellsprout: {
tier: "LC",
@ -216,7 +216,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "ZU",
},
tentacruel: {
tier: "UU",
tier: "NU",
},
geodude: {
tier: "LC",
@ -225,13 +225,13 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "PU",
},
golem: {
tier: "UU",
tier: "NU",
},
ponyta: {
tier: "LC",
},
rapidash: {
tier: "PUBL",
tier: "UU",
},
slowpoke: {
tier: "ZU",
@ -258,7 +258,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "LC",
},
dewgong: {
tier: "UU",
tier: "NU",
},
grimer: {
tier: "LC",
@ -294,13 +294,13 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "LC",
},
kingler: {
tier: "PU",
tier: "ZU",
},
voltorb: {
tier: "LC",
},
electrode: {
tier: "UU",
tier: "NU",
},
exeggcute: {
tier: "PU",
@ -339,7 +339,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "OU",
},
tangela: {
tier: "UU",
tier: "NU",
},
kangaskhan: {
tier: "UU",
@ -366,7 +366,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "NU",
},
scyther: {
tier: "ZU",
tier: "PU",
},
jynx: {
tier: "OU",
@ -375,10 +375,10 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "UU",
},
magmar: {
tier: "ZU",
tier: "PU",
},
pinsir: {
tier: "PU",
tier: "ZU",
},
tauros: {
tier: "OU",
@ -399,7 +399,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "LC",
},
vaporeon: {
tier: "UU",
tier: "NU",
},
jolteon: {
tier: "OU",
@ -414,7 +414,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "ZU",
},
omastar: {
tier: "UU",
tier: "NU",
},
kabuto: {
tier: "LC",
@ -435,7 +435,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "OU",
},
moltres: {
tier: "NU",
tier: "UU",
},
dratini: {
tier: "LC",

View File

@ -458,6 +458,22 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
target: "self",
type: "Psychic",
},
metronome: {
inherit: true,
onHit(pokemon) {
const moves = this.dex.moves.all().filter(move => (
(!move.isNonstandard || move.isNonstandard === 'Unobtainable') && move.flags['metronome']
));
let randomMove = '';
if (moves.length) {
moves.sort((a, b) => a.num - b.num);
randomMove = this.sample(moves).id;
}
if (!randomMove) return false;
pokemon.side.lastSelectedMove = this.toID(randomMove);
this.actions.useMove(randomMove, pokemon);
},
},
mimic: {
inherit: true,
flags: { protect: 1, bypasssub: 1, metronome: 1 },

View File

@ -25,6 +25,25 @@ export const Scripts: ModdedBattleScriptsData = {
// BattlePokemon scripts.
pokemon: {
inherit: true,
// In gen 1, a Pokémon can have two instances of the same move using Mimic
// we need to make sure to deduct PP from a move that has PP left
deductPP(move, amount, target) {
move = this.battle.dex.moves.get(move);
// first loop: get the first instance with PP left
// second loop: get the first instance, even if it has no PP left
for (let i = 0; i < 2; i++) {
for (const ppData of this.moveSlots) {
if (ppData.id !== move.id) continue;
ppData.used = true;
if (!ppData.pp && i === 0) continue;
if (!amount) amount = 1;
ppData.pp -= amount;
return amount;
}
}
return 0;
},
getStat(statName, unmodified) {
// @ts-expect-error type checking prevents 'hp' from being passed, but we're paranoid
if (statName === 'hp') throw new Error("Please read `maxhp` directly");

View File

@ -12,7 +12,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "LC",
},
charmeleon: {
tier: "ZU",
tier: "ZUBL",
},
charizard: {
tier: "UUBL",
@ -57,7 +57,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "LC",
},
raticate: {
tier: "NU",
tier: "PU",
},
spearow: {
tier: "LC",
@ -69,7 +69,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "LC",
},
arbok: {
tier: "NU",
tier: "PU",
},
pichu: {
tier: "LC",
@ -267,7 +267,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "UU",
},
farfetchd: {
tier: "NU",
tier: "PU",
},
doduo: {
tier: "ZU",
@ -345,10 +345,10 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "NU",
},
hitmonchan: {
tier: "PUBL",
tier: "PU",
},
hitmontop: {
tier: "PU",
tier: "NU",
},
lickitung: {
tier: "NU",
@ -540,7 +540,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "LC",
},
furret: {
tier: "PUBL",
tier: "PU",
},
hoothoot: {
tier: "LC",
@ -558,7 +558,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "LC",
},
ariados: {
tier: "ZU",
tier: "ZUBL",
},
chinchou: {
tier: "NU",
@ -591,7 +591,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "LC",
},
azumarill: {
tier: "NU",
tier: "PU",
},
sudowoodo: {
tier: "NU",
@ -645,7 +645,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "OU",
},
dunsparce: {
tier: "NU",
tier: "PU",
},
gligar: {
tier: "UU",
@ -705,7 +705,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "OU",
},
houndour: {
tier: "NU",
tier: "PU",
},
houndoom: {
tier: "UUBL",

View File

@ -573,6 +573,15 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
},
pursuit: {
inherit: true,
beforeTurnCallback(pokemon, target) {
if (pokemon.isAlly(target)) return;
target.addVolatile('pursuit');
const data = target.volatiles['pursuit'];
if (!data.sources) {
data.sources = [];
}
data.sources.push(pokemon);
},
onModifyMove() {},
condition: {
duration: 1,

View File

@ -63,7 +63,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "LC",
},
fearow: {
tier: "UU",
tier: "RUBL",
},
ekans: {
tier: "LC",
@ -312,7 +312,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "ZU",
},
hypno: {
tier: "UU",
tier: "RU",
},
krabby: {
tier: "LC",
@ -930,7 +930,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "LC",
},
manectric: {
tier: "UU",
tier: "RU",
},
plusle: {
tier: "NU",

View File

@ -138,8 +138,8 @@ export const Items: import('../../../sim/dex-items').ModdedItemDataTable = {
inherit: true,
onModifyMove(move) {
const affectedByKingsRock = [
'aerialace', 'aeroblast', 'aircutter', 'armthrust', 'barrage', 'beatup', 'bide', 'bind', 'blastburn', 'bonerush', 'bonemerang', 'bounce', 'brickbreak', 'bulletseed', 'clamp', 'cometpunch', 'crabhammer', 'crosschop', 'cut', 'dig', 'dive', 'doublekick', 'doubleslap', 'doubleedge', 'dragonbreath', 'dragonclaw', 'dragonrage', 'drillpeck', 'earthquake', 'eggbomb', 'endeavor', 'eruption', 'explosion', 'extremespeed', 'falseswipe', 'feintattack', 'firespin', 'flail', 'fly', 'frenzyplant', 'frustration', 'furyattack', 'furycutter', 'furyswipes', 'gust', 'hiddenpower', 'highjumpkick', 'hornattack', 'hydrocannon', 'hydropump', 'hyperbeam', 'iceball', 'iciclespear', 'jumpkick', 'karatechop', 'leafblade', 'lowkick', 'machpunch', 'magicalleaf', 'magnitude', 'megakick', 'megapunch', 'megahorn', 'meteormash', 'mudshot', 'muddywater', 'nightshade', 'outrage', 'overheat', 'payday', 'peck', 'petaldance', 'pinmissile', 'poisontail', 'pound', 'psychoboost', 'psywave', 'quickattack', 'rage', 'rapidspin', 'razorleaf', 'razorwind', 'return', 'revenge', 'reversal', 'rockblast', 'rockthrow', 'rollingkick', 'rollout', 'sandtomb', 'scratch', 'seismictoss', 'selfdestruct', 'shadowpunch', 'shockwave', 'signalbeam', 'silverwind', 'skullbash', 'skyattack', 'skyuppercut', 'slam', 'slash', 'snore', 'solarbeam', 'sonicboom', 'spikecannon', 'spitup', 'steelwing', 'strength', 'struggle', 'submission', 'surf', 'swift', 'tackle', 'takedown', 'thrash', 'tickle', 'triplekick', 'twister', 'uproar', 'visegrip', 'vinewhip', 'vitalthrow', 'volttackle', 'watergun', 'waterpulse', 'waterfall', 'weatherball', 'whirlpool', 'wingattack', 'wrap',
];
'aerialace', 'aeroblast', 'aircutter', 'armthrust', 'barrage', 'beatup', 'bide', 'bind', 'blastburn', 'bonerush', 'bonemerang', 'bounce', 'brickbreak', 'bulletseed', 'clamp', 'cometpunch', 'crabhammer', 'crosschop', 'cut', 'dig', 'dive', 'doublekick', 'doubleslap', 'doubleedge', 'dragonbreath', 'dragonclaw', 'dragonrage', 'drillpeck', 'earthquake', 'eggbomb', 'endeavor', 'eruption', 'explosion', 'extremespeed', 'falseswipe', 'feintattack', 'firespin', 'flail', 'fly', 'frenzyplant', 'frustration', 'furyattack', 'furycutter', 'furyswipes', 'gust', 'hiddenpower', 'highjumpkick', 'hornattack', 'hydrocannon', 'hydropump', 'hyperbeam', 'iceball', 'iciclespear', 'jumpkick', 'karatechop', 'leafblade', 'lowkick', 'machpunch', 'magicalleaf', 'magnitude', 'megakick', 'megapunch', 'megahorn', 'meteormash', 'mudshot', 'muddywater', 'nightshade', 'outrage', 'overheat', 'payday', 'peck', 'petaldance', 'pinmissile', 'poisontail', 'pound', 'psychoboost', 'psywave', 'quickattack', 'rage', 'rapidspin', 'razorleaf', 'razorwind', 'return', 'revenge', 'reversal', 'rockblast', 'rockthrow', 'rollingkick', 'rollout', 'sandtomb', 'scratch', 'seismictoss', 'selfdestruct', 'shadowpunch', 'shockwave', 'signalbeam', 'silverwind', 'skullbash', 'skyattack', 'skyuppercut', 'slam', 'slash', 'snore', 'solarbeam', 'sonicboom', 'spikecannon', 'spitup', 'steelwing', 'strength', 'struggle', 'submission', 'surf', 'swift', 'tackle', 'takedown', 'thrash', 'triplekick', 'twister', 'uproar', 'visegrip', 'vinewhip', 'vitalthrow', 'volttackle', 'watergun', 'waterpulse', 'waterfall', 'weatherball', 'whirlpool', 'wingattack', 'wrap',
]; // Tickle also has the move flag, but can never flinch because King's Rock requires damage to trigger
if (affectedByKingsRock.includes(move.id)) {
if (!move.secondaries) move.secondaries = [];
move.secondaries.push({

View File

@ -578,6 +578,20 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
inherit: true,
basePower: 70,
},
pursuit: {
inherit: true,
beforeTurnCallback(pokemon, target) {
if (['frz', 'slp'].includes(pokemon.status) ||
(pokemon.hasAbility('truant') && pokemon.truantTurn)) return;
if (pokemon.isAlly(target)) return;
target.addVolatile('pursuit');
const data = target.volatiles['pursuit'];
if (!data.sources) {
data.sources = [];
}
data.sources.push(pokemon);
},
},
recover: {
inherit: true,
pp: 20,

View File

@ -4356,6 +4356,7 @@ export const Learnsets: import('../../../sim/dex-species').ModdedLearnsetDataTab
toxic: ["3M"],
uproar: ["3E"],
waterpulse: ["3M"],
wish: ["3E"],
},
},
delcatty: {
@ -4813,6 +4814,7 @@ export const Learnsets: import('../../../sim/dex-species').ModdedLearnsetDataTab
thunderbolt: ["3M"],
thunderwave: ["3L4"],
toxic: ["3M"],
wish: ["3E"],
},
},
minun: {
@ -4846,6 +4848,7 @@ export const Learnsets: import('../../../sim/dex-species').ModdedLearnsetDataTab
thunderbolt: ["3M"],
thunderwave: ["3L4"],
toxic: ["3M"],
wish: ["3E"],
},
},
volbeat: {
@ -5462,6 +5465,7 @@ export const Learnsets: import('../../../sim/dex-species').ModdedLearnsetDataTab
trick: ["3E"],
uproar: ["3L5"],
waterpulse: ["3M"],
wish: ["3E"],
},
},
trapinch: {

View File

@ -1087,9 +1087,8 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
flags: { noassist: 1, failcopycat: 1, nosleeptalk: 1, failmimic: 1 },
onHit(pokemon) {
const moves = this.dex.moves.all().filter(move => (
(![2, 4].includes(this.gen) || !pokemon.moves.includes(move.id)) &&
move.flags['metronome'] && !pokemon.moves.includes(move.id) &&
(!move.isNonstandard || move.isNonstandard === 'Unobtainable') &&
move.flags['metronome'] &&
!(this.field.pseudoWeather['gravity'] && move.flags['gravity']) &&
!(pokemon.volatiles['healblock'] && move.flags['heal'])
));
@ -1332,6 +1331,18 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
},
pursuit: {
inherit: true,
beforeTurnCallback(pokemon) {
if (['frz', 'slp'].includes(pokemon.status) ||
(pokemon.hasAbility('truant') && pokemon.volatiles['truant'])) return;
for (const target of pokemon.foes()) {
target.addVolatile('pursuit');
const data = target.volatiles['pursuit'];
if (!data.sources) {
data.sources = [];
}
data.sources.push(pokemon);
}
},
condition: {
duration: 1,
onBeforeSwitchOut(pokemon) {
@ -1354,7 +1365,12 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}
}
}
this.actions.runMove('pursuit', source, source.getLocOf(pokemon));
const move = this.dex.getActiveMove('pursuit');
source.deductPP(move.id);
source.moveUsed(move, pokemon.position);
if (this.actions.useMove(move, source, { target: pokemon }) && source.getItem().isChoice) {
source.addVolatile('choicelock');
}
}
},
},
@ -1538,19 +1554,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
this.add('-activate', source, 'move: Mimic', move.name);
},
},
skillswap: {
inherit: true,
onHit(target, source) {
const targetAbility = target.ability;
const sourceAbility = source.ability;
if (targetAbility === sourceAbility || source.hasItem('griseousorb') || target.hasItem('griseousorb')) {
return false;
}
this.add('-activate', source, 'move: Skill Swap');
source.setAbility(targetAbility);
target.setAbility(sourceAbility);
},
},
sleeptalk: {
inherit: true,
onTryHit(pokemon) {

View File

@ -55,10 +55,6 @@ export const Scripts: ModdedBattleScriptsData = {
// Weather
baseDamage = this.battle.runEvent('WeatherModifyDamage', pokemon, target, move, baseDamage);
if (this.battle.gen === 3 && move.category === 'Physical' && !Math.floor(baseDamage)) {
baseDamage = 1;
}
baseDamage += 2;
const isCrit = target.getMoveHitData(move).crit;

View File

@ -794,19 +794,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
inherit: true,
flags: { protect: 1, reflectable: 1, mirror: 1, sound: 1, metronome: 1 },
},
skillswap: {
inherit: true,
onHit(target, source) {
const targetAbility = target.ability;
const sourceAbility = source.ability;
if (targetAbility === sourceAbility) {
return false;
}
this.add('-activate', source, 'move: Skill Swap', this.dex.abilities.get(targetAbility), this.dex.abilities.get(sourceAbility), `[of] ${target}`);
source.setAbility(targetAbility);
target.setAbility(sourceAbility);
},
},
skullbash: {
inherit: true,
basePower: 100,

View File

@ -1678,7 +1678,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
doublesTier: "DUber",
},
jirachi: {
tier: "OU",
tier: "(OU)",
doublesTier: "DUber",
},
deoxys: {

View File

@ -0,0 +1,369 @@
export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTable = {
merciless: {
shortDesc: "This Pokemon's attacks are critical hits if the target is statused.",
onModifyCritRatio(critRatio, source, target) {
if (target?.status) return 5;
},
name: "Merciless",
rating: 1.5,
num: 196,
gen: 6,
},
pocketdimension: {
shortDesc: "This Pokemon switches out after using a status move.",
onModifyMove(move, pokemon) {
if (move.category === 'Status') {
move.selfSwitch = true;
this.add('-ability', pokemon, 'Pocket Dimension');
this.add('-message', `${pokemon.name} will switch out if this moves lands!`);
}
},
name: "Pocket Dimension",
rating: 4.5,
},
grassysurge: {
inherit: true,
gen: 6,
},
mistysurge: {
inherit: true,
gen: 6,
},
neutralizinggas: {
inherit: true,
// Ability suppression cancelled in scripts.ts
// new Ability suppression implemented in scripts.ts
onSwitchIn(pokemon) {},
onEnd(source) {},
onStart(pokemon) {
this.add('-ability', pokemon, 'Neutralizing Gas');
},
// onModifyPriority implemented in relevant abilities
onFoeBeforeMovePriority: 13,
onFoeBeforeMove(attacker, defender, move) {
attacker.addVolatile('neutralizinggas');
},
condition: {
onAfterMove(pokemon) {
pokemon.removeVolatile('neutralizinggas');
},
},
flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, notransform: 1 },
desc: "While this Pokemon is active, opposing Pokemon's moves and their effects ignore its own Ability. Does not affect the As One, Battle Bond, Comatose, Disguise, Gulp Missile, Ice Face, Multitype, Power Construct, RKS System, Schooling, Shields Down, Stance Change, or Zen Mode Abilities.",
shortDesc: "While this Pokemon is active, opposing Pokemon's Ability has no effect when it uses moves.",
gen: 6,
},
nostalgiatrip: {
shortDesc: "This Pokemon's moves have the damage categories they would have in Gen 3. Fairy-type moves are Special.",
onStart(pokemon) {
this.add('-ability', pokemon, 'Nostalgia Trip');
this.add('-message', `This Pokemon is experiencing a nostalgia trip!`);
},
onModifyMovePriority: 8,
onModifyMove(move, pokemon) {
if (move.category === "Status") return;
if (['Fire', 'Water', 'Grass', 'Electric', 'Dark', 'Psychic', 'Dragon', 'Fairy', 'Ice'].includes(move.type)) {
move.category = "Special";
} else {
move.category = "Physical";
}
},
name: "Nostalgia Trip",
rating: 4,
gen: 6,
},
weatherreport: {
onBeforeMovePriority: 0.5,
onBeforeMove(target, source, move) {
if (move.type === 'Fire') {
this.field.setWeather('sunnyday');
} else if (move.type === 'Water') {
this.field.setWeather('raindance');
}
},
name: "Weather Report",
shortDesc: "Before using a Water or Fire-type move, this Pokemon sets Rain Dance or Sunny Day respectively.",
rating: 4,
gen: 6,
},
armortail: {
inherit: true,
gen: 6,
},
brainpower: {
onModifySpAPriority: 5,
onModifySpA(spa) {
return this.chainModify(2);
},
name: "Brain Power",
shortDesc: "This Pokemon's Special Attack is doubled.",
rating: 5,
},
neuroforce: {
inherit: true,
gen: 6,
},
bugzapper: {
onTryHit(target, source, move) {
if (target !== source && move.type === 'Bug') {
if (!source.addVolatile('trapped', target, move, 'trapper')) {
this.add('-immune', target, '[from] ability: Bug Zapper');
}
return null;
}
},
name: "Bug Zapper",
shortDesc: "This Pokemon is immune to Bug-type moves and traps the foe if hit by one.",
rating: 5,
},
exoskeleton: {
onSourceModifyDamage(damage, source, target, move) {
if (move.category === 'Physical') {
return this.chainModify(0.5);
}
},
name: "Exoskeleton",
shortDesc: "This Pokemon receives 1/2 damage from physical attacks; Hazard immunity.",
rating: 4,
},
icescales: {
inherit: true,
onModifyAtkPriority: 5,
onModifyAtk(atk, attacker, defender, move) {
if (move.type === 'Ice') {
this.debug('Ice Scales boost');
return this.chainModify(1.5);
}
},
onModifySpAPriority: 5,
onModifySpA(atk, attacker, defender, move) {
if (move.type === 'Ice') {
this.debug('Ice Scales boost');
return this.chainModify(1.5);
}
},
onImmunity(type, pokemon) {
if (type === 'hail') return false;
},
shortDesc: "This Pokemon receives 1/2 damage from special attacks. Ice moves have 1.5x power. Hail immunity.",
gen: 6,
},
eartheater: {
inherit: true,
onDamage(damage, target, source, effect) {
if (effect && (effect.id === 'stealthrock' || effect.id === 'spikes')) {
this.heal(damage);
return false;
}
},
shortDesc: "Heals 1/4 of its max HP when hit by Ground; Ground immunity. Healed by Spikes and Stealth Rock.",
gen: 6,
},
toxicchain: {
inherit: true,
gen: 6,
},
shellejection: {
onModifyMovePriority: -1,
onModifyMove(move, attacker) {
if (move.category === 'Special') {
attacker.addVolatile('shellejection');
this.add('-ability', attacker, 'Shell Ejection');
this.add('-message', `${attacker.name} is getting ready to leave the battlefield!`);
this.add('-message', `${attacker.name} can no longer use status moves!`);
}
},
condition: {
duration: 2,
onDisableMove(pokemon) {
for (const moveSlot of pokemon.moveSlots) {
const move = this.dex.moves.get(moveSlot.id);
if (move.category === 'Status' && move.id !== 'mefirst') {
pokemon.disableMove(moveSlot.id);
}
}
},
onSwitchOut(pokemon) {
pokemon.heal(pokemon.baseMaxhp / 3);
},
onEnd(pokemon) {
this.add('-ability', pokemon, 'Shell Ejection');
this.add('-message', `${pokemon.name} ejected itself from its shell!`);
pokemon.heal(pokemon.baseMaxhp / 3);
pokemon.switchFlag = true;
},
},
name: "Shell Ejection",
rating: 3.5,
gen: 6,
shortDesc: "On using Special move: switching heals 1/3, can't use status, switches out at end of next turn.",
},
sharpness: {
inherit: true,
gen: 6,
},
dauntlessshield: {
onStart(pokemon) {
this.boost({ def: 1 }, pokemon);
pokemon.addVolatile('dauntlessshield');
},
onResidualOrder: 6,
onResidual(pokemon) {
if (pokemon.positiveBoosts()) {
this.heal(pokemon.baseMaxhp / 16);
this.add('-message', `${pokemon.name}'s shield gives it strength!`);
}
},
name: "Dauntless Shield",
rating: 5,
num: 235,
shortDesc: "+1 Defense on switch-in. Heals 1/16 of max HP if it has a positive boost.",
gen: 6,
},
confidence: {
onSourceAfterFaint(length, target, source, effect) {
if (effect && effect.effectType === 'Move') {
this.boost({ spa: length }, source);
}
},
name: "Confidence",
rating: 3,
shortDesc: "This Pokemon's Sp. Atk is raised by 1 stage if it attacks and KOes another Pokemon.",
gen: 6,
},
electricsurge: {
inherit: true,
gen: 6,
},
goodasgold: {
inherit: true,
gen: 6,
},
opportunist: {
inherit: true,
onUpdate(pokemon) {
let activate = false;
const boosts: SparseBoostsTable = {};
let i: BoostID;
for (i in pokemon.boosts) {
if (pokemon.boosts[i] < 0) {
activate = true;
boosts[i] = 0;
}
}
if (this.effectState.herb) return;
if (activate) {
pokemon.setBoost(boosts);
this.effectState.herb = true;
this.add('-ability', pokemon, 'Opportunist');
this.add('-clearnegativeboost', pokemon, '[silent]');
}
},
onSwitchIn(pokemon) {
delete this.effectState.herb;
},
shortDesc: "Copies foe's stat gains as they happen. Resets negative stat changes once per switch-in.",
gen: 6,
},
intoxicate: {
onModifyTypePriority: -1,
onModifyType(move, pokemon) {
const noModifyType = [
'judgment', 'multiattack', 'naturalgift', 'revelationdance', 'technoblast', 'terrainpulse', 'weatherball',
];
if (move.type === 'Normal' && !noModifyType.includes(move.id) &&
!(move.isZ && move.category !== 'Status') && !(move.name === 'Tera Blast' && pokemon.terastallized)) {
move.type = 'Poison';
move.typeChangerBoosted = this.effect;
}
},
onBasePowerPriority: 23,
onBasePower(basePower, pokemon, target, move) {
if (move.typeChangerBoosted) return this.chainModify([5325, 4096]);
},
name: "Intoxicate",
rating: 4,
shortDesc: "This Pokemon's Normal-type moves become Poison-type and have 1.3x power.",
},
dragonsgale: {
onStart(source) {
this.field.setWeather('deltastream');
},
onAnySetWeather(target, source, weather) {
const strongWeathers = ['desolateland', 'primordialsea', 'deltastream'];
if (this.field.getWeather().id === 'deltastream' && !strongWeathers.includes(weather.id)) return false;
},
onEnd(pokemon) {
if (this.field.weatherState.source !== pokemon) return;
for (const target of this.getAllActive()) {
if (target === pokemon) continue;
if (target.hasAbility('dragonsgale')) {
this.field.weatherState.source = target;
return;
}
}
this.field.clearWeather();
},
onDamage(damage, target, source, effect) {
if (effect && (effect.id === 'stealthrock' || effect.id === 'spikes')) {
return damage / 2;
}
},
flags: {},
name: "Dragon's Gale",
shortDesc: "On switch-in, sets Delta Stream. User takes halved damage from hazards.",
rating: 5,
},
parentalbond: {
onPrepareHit(source, target, move) {
if (move.category === 'Status' || move.selfdestruct || move.multihit) return;
if ([
'endeavor', 'seismictoss', 'psywave', 'nightshade', 'sonicboom', 'dragonrage',
'superfang', 'naturesmadness', 'bide', 'counter', 'mirrorcoat', 'metalburst',
].includes(move.id)) return;
if (!move.spreadHit && !move.isZ && !move.isMax) {
move.multihit = 2;
move.multihitType = 'parentalbond';
}
},
onSourceModifySecondaries(secondaries, target, source, move) {
if (move.multihitType === 'parentalbond' && move.id === 'secretpower' && move.hit < 2) {
// hack to prevent accidentally suppressing King's Rock/Razor Fang
return secondaries.filter(effect => effect.volatileStatus === 'flinch');
}
},
name: "Parental Bond",
rating: 4.5,
shortDesc: "This Pokemon's damaging moves hit twice. The second hit has its damage quartered.",
num: 184,
},
// for ngas
galewings: {
// for ngas
inherit: true,
onModifyPriority(priority, pokemon, target, move) {
for (const poke of this.getAllActive()) {
if (poke.hasAbility('neutralizinggas') && poke.side.id !== pokemon.side.id && !poke.abilityState.ending) {
return;
}
}
if (move && move.type === 'Flying') return priority + 1;
},
},
prankster: {
// for ngas
inherit: true,
onModifyPriority(priority, pokemon, target, move) {
for (const poke of this.getAllActive()) {
if (poke.hasAbility('neutralizinggas') && poke.side.id !== pokemon.side.id && !poke.abilityState.ending) {
return;
}
}
if (move?.category === 'Status') {
move.pranksterBoosted = true;
return priority + 1;
}
},
},
};

View File

@ -0,0 +1,26 @@
export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormatsDataTable = {
blaziken: {
tier: "OU",
},
blazikenmega: {
tier: "OU",
},
gengarmega: {
tier: "OU",
},
kangaskhanmega: {
tier: "OU",
},
lucariomega: {
tier: "OU",
},
mawilemega: {
tier: "OU",
},
sableyemega: {
tier: "OU",
},
salamencemega: {
tier: "OU",
},
};

View File

@ -0,0 +1,12 @@
export const Items: import('../../../sim/dex-items').ModdedItemDataTable = {
meteorite: {
name: "Meteorite",
spritenum: 615,
megaStone: { "Rayquaza": "Rayquaza-Mega" },
itemUser: ["Rayquaza"],
onTakeItem(item, source) {
return !item.megaStone?.[source.baseSpecies.baseSpecies];
},
desc: "If held by a Rayquaza, this item allows it to Mega Evolve in battle.",
},
};

View File

@ -0,0 +1,77 @@
export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
stealthrock: {
inherit: true,
condition: {
// this is a side condition
onSideStart(side) {
this.add('-sidestart', side, 'move: Stealth Rock');
},
onSwitchIn(pokemon) {
if (pokemon.hasItem('heavydutyboots') || pokemon.hasAbility('exoskeleton')) return;
const typeMod = this.clampIntRange(pokemon.runEffectiveness(this.dex.getActiveMove('stealthrock')), -6, 6);
this.damage(pokemon.maxhp * (2 ** typeMod) / 8);
},
},
},
toxicspikes: {
inherit: true,
condition: {
// this is a side condition
onSideStart(side) {
this.add('-sidestart', side, 'move: Toxic Spikes');
this.effectState.layers = 1;
},
onSideRestart(side) {
if (this.effectState.layers >= 2) return false;
this.add('-sidestart', side, 'move: Toxic Spikes');
this.effectState.layers++;
},
onSwitchIn(pokemon) {
if (!pokemon.isGrounded()) return;
if (pokemon.hasType('Poison')) {
this.add('-sideend', pokemon.side, 'move: Toxic Spikes', `[of] ${pokemon}`);
pokemon.side.removeSideCondition('toxicspikes');
} else if (pokemon.hasType('Steel') || pokemon.hasItem('heavydutyboots') || pokemon.hasAbility('exoskeleton')) {
// do nothing
} else if (this.effectState.layers >= 2) {
pokemon.trySetStatus('tox', pokemon.side.foe.active[0]);
} else {
pokemon.trySetStatus('psn', pokemon.side.foe.active[0]);
}
},
},
},
spikes: {
inherit: true,
condition: {
// this is a side condition
onSideStart(side) {
this.add('-sidestart', side, 'Spikes');
this.effectState.layers = 1;
},
onSideRestart(side) {
if (this.effectState.layers >= 3) return false;
this.add('-sidestart', side, 'Spikes');
this.effectState.layers++;
},
onSwitchIn(pokemon) {
if (!pokemon.isGrounded() || pokemon.hasItem('heavydutyboots') || pokemon.hasAbility('exoskeleton')) return;
const damageAmounts = [0, 3, 4, 6]; // 1/8, 1/6, 1/4
this.damage(damageAmounts[this.effectState.layers] * pokemon.maxhp / 24);
},
},
},
stickyweb: {
inherit: true,
condition: {
onSideStart(side) {
this.add('-sidestart', side, 'move: Sticky Web');
},
onSwitchIn(pokemon) {
if (!pokemon.isGrounded() || pokemon.hasItem('heavydutyboots') || pokemon.hasAbility('exoskeleton')) return;
this.add('-activate', pokemon, 'move: Sticky Web');
this.boost({ spe: -1 }, pokemon, pokemon.side.foe.active[0], this.dex.getActiveMove('stickyweb'));
},
},
},
};

View File

@ -0,0 +1,249 @@
export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable = {
audinomega: {
inherit: true,
types: ["Normal", "Electric"],
baseStats: { hp: 103, atk: 60, def: 120, spa: 110, spd: 97, spe: 55 },
abilities: { 0: "Regenerator" },
},
houndoommega: {
inherit: true,
types: ["Dark", "Fire"],
baseStats: { hp: 75, atk: 90, def: 90, spa: 140, spd: 90, spe: 115 },
abilities: { 0: "Merciless" },
},
lucariomega: {
inherit: true,
types: ["Fighting", "Steel"],
baseStats: { hp: 70, atk: 125, def: 70, spa: 140, spd: 94, spe: 126 },
abilities: { 0: "Lightning Rod" },
},
banettemega: {
inherit: true,
types: ["Ghost", "Steel"],
baseStats: { hp: 64, atk: 149, def: 75, spa: 83, spd: 83, spe: 101 },
abilities: { 0: "Pocket Dimension" },
},
glaliemega: {
inherit: true,
types: ["Ice", "Steel"],
baseStats: { hp: 80, atk: 160, def: 70, spa: 95, spd: 70, spe: 105 },
abilities: { 0: "Refrigerate" },
},
venusaurmega: {
inherit: true,
types: ["Grass", "Poison"],
baseStats: { hp: 80, atk: 82, def: 123, spa: 120, spd: 120, spe: 100 },
abilities: { 0: "Grassy Surge" },
},
blastoisemega: {
inherit: true,
types: ["Water", "Fairy"],
baseStats: { hp: 79, atk: 83, def: 130, spa: 135, spd: 105, spe: 98 },
abilities: { 0: "Misty Surge" },
},
charizardmegay: {
inherit: true,
types: ["Fire", "Flying"],
baseStats: { hp: 78, atk: 94, def: 93, spa: 159, spd: 110, spe: 100 },
abilities: { 0: "Dragon's Gale" },
},
alakazammega: {
inherit: true,
types: ["Psychic", "Ice"],
baseStats: { hp: 55, atk: 50, def: 75, spa: 155, spd: 125, spe: 140 },
abilities: { 0: "Magic Guard" },
},
pinsirmega: {
inherit: true,
types: ["Bug", "Ice"],
baseStats: { hp: 65, atk: 150, def: 110, spa: 80, spd: 85, spe: 110 },
abilities: { 0: "Mountaineer" },
},
gengarmega: {
inherit: true,
types: ["Ghost", "Poison"],
baseStats: { hp: 60, atk: 65, def: 105, spa: 155, spd: 105, spe: 110 },
abilities: { 0: "Neutralizing Gas" },
},
aerodactylmega: {
inherit: true,
types: ["Rock", "Flying"],
baseStats: { hp: 80, atk: 140, def: 65, spa: 85, spd: 100, spe: 145 },
abilities: { 0: "Nostalgia Trip" },
},
steelixmega: {
inherit: true,
types: ["Steel", "Ground"],
baseStats: { hp: 75, atk: 135, def: 210, spa: 55, spd: 105, spe: 30 },
abilities: { 0: "Flash Fire" },
weightkg: 999.9,
},
altariamega: {
inherit: true,
types: ["Dragon", "Fairy"],
baseStats: { hp: 75, atk: 90, def: 90, spa: 140, spd: 115, spe: 80 },
abilities: { 0: "Weather Report" },
},
sceptilemega: {
inherit: true,
types: ["Grass", "Dragon"],
baseStats: { hp: 70, atk: 95, def: 79, spa: 145, spd: 99, spe: 142 },
abilities: { 0: "Armor Tail" },
},
swampertmega: {
inherit: true,
types: ["Water", "Poison"],
baseStats: { hp: 100, atk: 145, def: 110, spa: 85, spd: 110, spe: 85 },
abilities: { 0: "Toxic Chain" },
},
manectricmega: {
inherit: true,
types: ["Electric"],
baseStats: { hp: 70, atk: 75, def: 80, spa: 135, spd: 85, spe: 130 },
abilities: { 0: "Bug Zapper" },
},
absolmega: {
inherit: true,
types: ["Dark", "Fairy"],
baseStats: { hp: 65, atk: 130, def: 60, spa: 135, spd: 60, spe: 115 },
abilities: { 0: "Neuroforce" },
},
medichammega: {
inherit: true,
types: ["Fighting", "Psychic"],
baseStats: { hp: 60, atk: 60, def: 100, spa: 90, spd: 100, spe: 100 },
abilities: { 0: "Brain Power" },
},
sableyemega: {
inherit: true,
types: ["Dark", "Ghost"],
baseStats: { hp: 50, atk: 95, def: 115, spa: 85, spd: 115, spe: 20 },
},
beedrillmega: {
inherit: true,
types: ["Bug", "Rock"],
baseStats: { hp: 65, atk: 140, def: 85, spa: 45, spd: 85, spe: 75 },
abilities: { 0: "Exoskeleton" },
},
mawilemega: {
inherit: true,
types: ["Steel", "Fairy"],
baseStats: { hp: 50, atk: 90, def: 125, spa: 70, spd: 95, spe: 50 },
abilities: { 0: "Huge Power" },
},
abomasnowmega: {
inherit: true,
types: ["Grass"],
abilities: { 0: "Ice Scales" },
},
cameruptmega: {
inherit: true,
types: ["Fire", "Ground"],
baseStats: { hp: 70, atk: 80, def: 140, spa: 135, spd: 115, spe: 20 },
abilities: { 0: "Earth Eater" },
},
slowbromega: {
inherit: true,
types: ["Water", "Psychic"],
baseStats: { hp: 95, atk: 75, def: 150, spa: 120, spd: 120, spe: 30 },
abilities: { 0: "Shell Ejection" },
},
gallademega: {
inherit: true,
types: ["Psychic", "Fighting"],
baseStats: { hp: 68, atk: 150, def: 100, spa: 75, spd: 127, spe: 98 },
abilities: { 0: "Sharpness" },
},
ampharosmega: {
inherit: true,
types: ["Electric", "Dragon"],
baseStats: { hp: 90, atk: 95, def: 95, spa: 165, spd: 110, spe: 55 },
abilities: { 0: "Mega Launcher" },
},
gyaradosmega: {
inherit: true,
types: ["Water", "Flying"],
baseStats: { hp: 95, atk: 130, def: 109, spa: 85, spd: 130, spe: 91 },
abilities: { 0: "Aerilate" },
},
heracrossmega: {
inherit: true,
types: ["Bug", "Fighting"],
baseStats: { hp: 80, atk: 150, def: 150, spa: 40, spd: 110, spe: 70 },
abilities: { 0: "Iron Barbs" },
},
sharpedomega: {
inherit: true,
types: ["Water", "Electric"],
baseStats: { hp: 70, atk: 130, def: 55, spa: 145, spd: 55, spe: 105 },
abilities: { 0: "No Guard" },
},
gardevoirmega: {
inherit: true,
types: ["Psychic", "Fairy"],
baseStats: { hp: 68, atk: 65, def: 100, spa: 150, spd: 127, spe: 108 },
},
aggronmega: {
inherit: true,
types: ["Steel"],
baseStats: { hp: 70, atk: 145, def: 185, spa: 85, spd: 85, spe: 60 },
abilities: { 0: "Dauntless Shield" },
},
kangaskhanmega: {
inherit: true,
types: ["Normal", "Ground"],
baseStats: { hp: 105, atk: 125, def: 105, spa: 50, spd: 105, spe: 100 },
},
salamencemega: {
inherit: true,
types: ["Dragon", "Flying"],
baseStats: { hp: 95, atk: 135, def: 105, spa: 155, spd: 105, spe: 105 },
abilities: { 0: "Confidence" },
},
garchompmega: {
inherit: true,
types: ["Dragon", "Ground"],
baseStats: { hp: 108, atk: 150, def: 115, spa: 140, spd: 85, spe: 102 },
abilities: { 0: "Water Absorb" },
},
tyranitarmega: {
inherit: true,
types: ["Rock", "Electric"],
baseStats: { hp: 100, atk: 144, def: 120, spa: 110, spd: 144, spe: 82 },
abilities: { 0: "Electric Surge" },
},
latiasmega: {
inherit: true,
abilities: { 0: "Trace" },
},
latiosmega: {
inherit: true,
baseStats: { hp: 80, atk: 140, def: 100, spa: 150, spd: 120, spe: 110 },
abilities: { 0: "Opportunist" },
},
dianciemega: {
inherit: true,
abilities: { 0: "Good As Gold" },
},
blazikenmega: {
inherit: true,
baseStats: { hp: 80, atk: 150, def: 80, spa: 120, spd: 90, spe: 110 },
abilities: { 0: "Regenerator" },
},
mewtwomegax: {
inherit: true,
types: ["Psychic", "Poison"],
baseStats: { hp: 106, atk: 140, def: 130, spa: 154, spd: 120, spe: 130 },
abilities: { 0: "Intoxicate" },
},
mewtwomegay: {
inherit: true,
types: ["Psychic", "Water"],
baseStats: { hp: 106, atk: 120, def: 110, spa: 194, spd: 130, spe: 120 },
abilities: { 0: "Levitate" },
},
rayquazamega: {
inherit: true,
requiredItem: "Meteorite",
},
};

View File

@ -1,69 +1,33 @@
export const Rulesets: import('../../../sim/dex-formats').ModdedFormatDataTable = {
statusmod: {
effectType: 'Rule',
name: 'Status Mod',
desc: "Displays Dragonblight as a volatile",
onSwitchIn(pokemon) {
if (pokemon.status === 'dragonblight') {
this.add('-start', pokemon, 'dragonblight', '[silent]');
}
},
onSetStatus(status, target, source, effect) {
if (target.status === 'dragonblight') {
this.add('-start', target, 'dragonblight', '[silent]');
}
},
/* onCureStatus(pokemon, source, effect) {
const cured = effect?.status || pokemon.statusState?.prevStatus;
if (cured === 'dragonblight') {
this.add('-end', pokemon, 'dragonblight', '[silent]');
}
}, */
},
megadatamod: {
effectType: 'Rule',
name: 'Mega Data Mod',
desc: 'Gives data on stats, Ability and types when a Pokémon Mega Evolves or undergoes Ultra Burst.',
onSwitchIn(pokemon) {
if (pokemon.species.forme.startsWith('Mega') || pokemon.species.forme.startsWith('Ultra')) {
this.add('-start', pokemon, 'typechange', pokemon.getTypes(true).join('/'), '[silent]');
}
},
onAfterMega(pokemon) {
this.add('-start', pokemon, 'typechange', pokemon.getTypes(true).join('/'), '[silent]');
const species = pokemon.species;
let buf = `<span class="col pokemonnamecol" style="white-space: nowrap">${species.name}</span> `;
buf += `<span class="col typecol">`;
buf += `<img src="https://${Config.routes.client}/sprites/types/${species.types[0]}.png" alt="${species.types[0]}" height="14" width="32">`;
if (species.types[1]) {
buf += `<img src="https://${Config.routes.client}/sprites/types/${species.types[1]}.png" alt="${species.types[1]}" height="14" width="32">`;
}
buf += `</span> `;
buf += `<span style="float: left ; min-height: 26px"><span class="col abilitycol">${species.abilities[0]}</span><span class="col abilitycol"></span></span>`;
const stats = [];
let stat: StatID;
for (stat in species.baseStats) {
const statNames: { [k in StatID]: string } = { hp: "HP", atk: "Atk", def: "Def", spa: "SpA", spd: "SpD", spe: "Spe" };
stats.push(`<span class="col statcol"><em>${statNames[stat]}</em><br>${species.baseStats[stat]}</span>`);
}
buf += `<span style="float: left ; min-height: 26px">${stats.join(' ')}</span>`;
buf += `</span>`;
this.add(`raw|<ul class="utilichart"><li class="result">${buf}</li><li style="clear: both"></li></ul>`);
},
},
spriteviewer: {
effectType: 'ValidatorRule',
name: 'Sprite Viewer',
desc: "Displays a fakemon's sprite in chat when it is switched in for the first time",
onBegin() {
this.add('rule', 'Sprite Viewer: Displays sprites in chat');
},
onSwitchIn(pokemon) {
if (!this.effectState[pokemon.species.id]) {
this.add('-message', `${pokemon.species.name}'s Sprite:`);
this.add(`raw|<img src="https://raw.githubusercontent.com/scoopapa/DH2/refs/heads/main/data/mods/monsterhunter/sprites/front/${pokemon.species.id}.png" height="96" width="96">`);
this.effectState[pokemon.species.id] = true;
}
},
},
};
export const Rulesets: import('../../../sim/dex-formats').ModdedFormatDataTable = {
megadatamod: {
effectType: 'Rule',
name: 'Mega Data Mod',
desc: 'Gives data on stats, Ability and types when a Pokémon Mega Evolves or undergoes Ultra Burst.',
onSwitchIn(pokemon) {
if (pokemon.species.forme.startsWith('Mega') || pokemon.species.forme.startsWith('Ultra')) {
this.add('-start', pokemon, 'typechange', pokemon.getTypes(true).join('/'), '[silent]');
}
},
onAfterMega(pokemon) {
this.add('-start', pokemon, 'typechange', pokemon.getTypes(true).join('/'), '[silent]');
const species = pokemon.species;
let buf = `<span class="col pokemonnamecol" style="white-space: nowrap">${species.name}</span> `;
buf += `<span class="col typecol">`;
buf += `<img src="https://${Config.routes.client}/sprites/types/${species.types[0]}.png" alt="${species.types[0]}" height="14" width="32">`;
if (species.types[1]) {
buf += `<img src="https://${Config.routes.client}/sprites/types/${species.types[1]}.png" alt="${species.types[1]}" height="14" width="32">`;
}
buf += `</span> `;
buf += `<span style="float: left ; min-height: 26px"><span class="col abilitycol">${species.abilities[0]}</span><span class="col abilitycol"></span></span>`;
const stats = [];
let stat: StatID;
for (stat in species.baseStats) {
const statNames: { [k in StatID]: string } = { hp: "HP", atk: "Atk", def: "Def", spa: "SpA", spd: "SpD", spe: "Spe" };
stats.push(`<span class="col statcol"><em>${statNames[stat]}</em><br>${species.baseStats[stat]}</span>`);
}
buf += `<span style="float: left ; min-height: 26px">${stats.join(' ')}</span>`;
buf += `</span>`;
this.add(`raw|<ul class="utilichart"><li class="result">${buf}</li><li style="clear: both"></li></ul>`);
},
},
};

View File

@ -0,0 +1,237 @@
export const Scripts: ModdedBattleScriptsData = {
gen: 6,
inherit: 'gen6',
actions: {
// for parental bond
modifyDamage(
baseDamage: number, pokemon: Pokemon, target: Pokemon, move: ActiveMove, suppressMessages = false
) {
const tr = this.battle.trunc;
if (!move.type) move.type = '???';
const type = move.type;
baseDamage += 2;
if (move.spreadHit) {
// multi-target modifier (doubles only)
const spreadModifier = this.battle.gameType === 'freeforall' ? 0.5 : 0.75;
this.battle.debug(`Spread modifier: ${spreadModifier}`);
baseDamage = this.battle.modify(baseDamage, spreadModifier);
} else if (move.multihitType === 'parentalbond' && move.hit > 1) {
// Parental Bond modifier
const bondModifier = 0.25;
this.battle.debug(`Parental Bond modifier: ${bondModifier}`);
baseDamage = this.battle.modify(baseDamage, bondModifier);
}
baseDamage = this.battle.runEvent('WeatherModifyDamage', pokemon, target, move, baseDamage);
const isCrit = target.getMoveHitData(move).crit;
if (isCrit) {
baseDamage = tr(baseDamage * (move.critModifier || (this.battle.gen >= 6 ? 1.5 : 2)));
}
baseDamage = this.battle.randomizer(baseDamage);
if (type !== '???') {
let stab: number | [number, number] = 1;
const isSTAB = move.forceSTAB || pokemon.hasType(type) || pokemon.getTypes(false, true).includes(type);
if (isSTAB) {
stab = 1.5;
}
if (pokemon.terastallized === 'Stellar') {
if (!pokemon.stellarBoostedTypes.includes(type) || move.stellarBoosted) {
stab = isSTAB ? 2 : [4915, 4096];
move.stellarBoosted = true;
if (pokemon.species.name !== 'Terapagos-Stellar') {
pokemon.stellarBoostedTypes.push(type);
}
}
} else {
if (pokemon.terastallized === type && pokemon.getTypes(false, true).includes(type)) {
stab = 2;
}
stab = this.battle.runEvent('ModifySTAB', pokemon, target, move, stab);
}
baseDamage = this.battle.modify(baseDamage, stab);
}
let typeMod = target.runEffectiveness(move);
typeMod = this.battle.clampIntRange(typeMod, -6, 6);
target.getMoveHitData(move).typeMod = typeMod;
if (typeMod > 0) {
if (!suppressMessages) this.battle.add('-supereffective', target);
for (let i = 0; i < typeMod; i++) {
baseDamage *= 2;
}
}
if (typeMod < 0) {
if (!suppressMessages) this.battle.add('-resisted', target);
for (let i = 0; i > typeMod; i--) {
baseDamage = tr(baseDamage / 2);
}
}
if (isCrit && !suppressMessages) this.battle.add('-crit', target);
if (pokemon.status === 'brn' && move.category === 'Physical' && !pokemon.hasAbility('guts')) {
if (this.battle.gen < 6 || move.id !== 'facade') {
baseDamage = this.battle.modify(baseDamage, 0.5);
}
}
// Generation 5, but nothing later, sets damage to 1 before the final damage modifiers
if (this.battle.gen === 5 && !baseDamage) baseDamage = 1;
// Final modifier. Modifiers that modify damage after min damage check, such as Life Orb.
baseDamage = this.battle.runEvent('ModifyDamage', pokemon, target, move, baseDamage);
if (move.isZOrMaxPowered && target.getMoveHitData(move).zBrokeProtect) {
baseDamage = this.battle.modify(baseDamage, 0.25);
this.battle.add('-zbroken', target);
}
// Generation 6-7 moves the check for minimum 1 damage after the final modifier...
if (this.battle.gen !== 5 && !baseDamage) return 1;
// ...but 16-bit truncation happens even later, and can truncate to 0
return tr(baseDamage, 16);
},
},
pokemon: {
// for neutralizing gas
ignoringAbility() {
if (this.battle.gen >= 5 && !this.isActive) return true;
if (this.getAbility().flags['notransform'] && this.transformed) return true;
if (this.getAbility().flags['cantsuppress']) return false;
if (this.volatiles['gastroacid']) return true;
if (this.ability === ('neutralizinggas' as ID)) return false;
if (this.volatiles['neutralizinggas']) return true;
return false;
},
},
init() {
this.modData("Learnsets", "lucario").learnset.meteormash = ["6L1"];
this.modData("Learnsets", "lucario").learnset.machpunch = ["6L1"];
this.modData("Learnsets", "houndoom").learnset.toxicspikes = ["6L1"];
this.modData("Learnsets", "houndoom").learnset.venoshock = ["6L1"];
this.modData("Learnsets", "houndoom").learnset.hex = ["6L1"];
this.modData("Learnsets", "audino").learnset.discharge = ["6L1"];
this.modData("Learnsets", "audino").learnset.voltswitch = ["6L1"];
this.modData("Learnsets", "audino").learnset.chargebeam = ["6L1"];
this.modData("Learnsets", "audino").learnset.charge = ["6L1"];
this.modData("Learnsets", "audino").learnset.zapcannon = ["6L1"];
this.modData("Learnsets", "glalie").learnset.thunderfang = ["6L1"];
this.modData("Learnsets", "glalie").learnset.partingshot = ["6L1"];
this.modData("Learnsets", "glalie").learnset.boomburst = ["6L1"];
this.modData("Learnsets", "banette").learnset.ironhead = ["6L1"];
this.modData("Learnsets", "banette").learnset.metalsound = ["6L1"];
this.modData("Learnsets", "banette").learnset.powder = ["6L1"];
this.modData("Learnsets", "banette").learnset.stealthrock = ["6L1"];
this.modData("Learnsets", "banette").learnset.defog = ["6L1"];
this.modData("Learnsets", "venusaur").learnset.psychic = ["6L1"];
this.modData("Learnsets", "venusaur").learnset.calmmind = ["6L1"];
this.modData("Learnsets", "blastoise").learnset.moonblast = ["6L1"];
this.modData("Learnsets", "blastoise").learnset.mistyterrain = ["6L1"];
this.modData("Learnsets", "blastoise").learnset.taunt = ["6L1"];
this.modData("Learnsets", "blastoise").learnset.drainingkiss = ["6L1"];
this.modData("Learnsets", "blastoise").learnset.dazzlinggleam = ["6L1"];
this.modData("Learnsets", "charizard").learnset.calmmind = ["6L1"];
this.modData("Learnsets", "charizard").learnset.hurricane = ["6L1"];
this.modData("Learnsets", "charizard").learnset.lavaplume = ["6L1"];
this.modData("Learnsets", "gengar").learnset.reflecttype = ["6L1"];
this.modData("Learnsets", "gengar").learnset.calmmind = ["6L1"];
this.modData("Learnsets", "alakazam").learnset.blizzard = ["6L1"];
this.modData("Learnsets", "alakazam").learnset.flashcannon = ["6L1"];
this.modData("Learnsets", "alakazam").learnset.icebeam = ["6L1"];
this.modData("Learnsets", "alakazam").learnset.hail = ["6L1"];
this.modData("Learnsets", "pinsir").learnset.hail = ["6L1"];
this.modData("Learnsets", "pinsir").learnset.megahorn = ["6L1"];
this.modData("Learnsets", "pinsir").learnset.uturn = ["6L1"];
this.modData("Learnsets", "pinsir").learnset.iceshard = ["6L1"];
this.modData("Learnsets", "pinsir").learnset.iciclecrash = ["6L1"];
this.modData("Learnsets", "pinsir").learnset.icebeam = ["6L1"];
this.modData("Learnsets", "pinsir").learnset.blizzard = ["6L1"];
this.modData("Learnsets", "pinsir").learnset.roost = ["6L1"];
this.modData("Learnsets", "pinsir").learnset.iciclespear = ["6L1"];
this.modData("Learnsets", "aerodactyl").learnset.powergem = ["6L1"];
this.modData("Learnsets", "aerodactyl").learnset.shadowball = ["6L1"];
this.modData("Learnsets", "aerodactyl").learnset.hurricane = ["6L1"];
this.modData("Learnsets", "steelix").learnset.heatcrash = ["6L1"];
this.modData("Learnsets", "steelix").learnset.rapidspin = ["6L1"];
this.modData("Learnsets", "steelix").learnset.smackdown = ["6L1"];
this.modData("Learnsets", "altaria").learnset.scald = ["6L1"];
this.modData("Learnsets", "altaria").learnset.hydropump = ["6L1"];
this.modData("Learnsets", "altaria").learnset.thunder = ["6L1"];
this.modData("Learnsets", "sceptile").learnset.calmmind = ["6L1"];
this.modData("Learnsets", "sceptile").learnset.sludgewave = ["6L1"];
this.modData("Learnsets", "swampert").learnset.sludgebomb = ["6L1"];
this.modData("Learnsets", "swampert").learnset.bulkup = ["6L1"];
this.modData("Learnsets", "swampert").learnset.toxicspikes = ["6L1"];
this.modData("Learnsets", "swampert").learnset.aquajet = ["6L1"];
this.modData("Learnsets", "swampert").learnset.gunkshot = ["6L1"];
this.modData("Learnsets", "swampert").learnset.poisonjab = ["6L1"];
this.modData("Learnsets", "pidgeot").learnset.focusblast = ["6L1"];
this.modData("Learnsets", "absol").learnset.closecombat = ["6L1"];
this.modData("Learnsets", "absol").learnset.moonblast = ["6L1"];
this.modData("Learnsets", "absol").learnset.moonlight = ["6L1"];
this.modData("Learnsets", "medicham").learnset.aurasphere = ["6L1"];
this.modData("Learnsets", "medicham").learnset.thunderbolt = ["6L1"];
this.modData("Learnsets", "medicham").learnset.closecombat = ["6L1"];
this.modData("Learnsets", "medicham").learnset.gunkshot = ["6L1"];
this.modData("Learnsets", "medicham").learnset.healingwish = ["6L1"];
this.modData("Learnsets", "beedrill").learnset.earthquake = ["6L1"];
this.modData("Learnsets", "beedrill").learnset.stoneedge = ["6L1"];
this.modData("Learnsets", "beedrill").learnset.rockslide = ["6L1"];
this.modData("Learnsets", "beedrill").learnset.smackdown = ["6L1"];
this.modData("Learnsets", "beedrill").learnset.stealthrock = ["6L1"];
this.modData("Learnsets", "beedrill").learnset.diamondstorm = ["6L1"];
this.modData("Learnsets", "mawile").learnset.firepunch = ["6L1"];
this.modData("Learnsets", "mawile").learnset.rockslide = ["6L1"];
this.modData("Learnsets", "mawile").learnset.slackoff = ["6L1"];
this.modData("Learnsets", "camerupt").learnset.morningsun = ["6L1"];
this.modData("Learnsets", "abomasnow").learnset.spikyshield = ["6L1"];
this.modData("Learnsets", "abomasnow").learnset.earthpower = ["6L1"];
this.modData("Learnsets", "abomasnow").learnset.hornleech = ["6L1"];
this.modData("Learnsets", "gallade").learnset.sacredsword = ["6L1"];
this.modData("Learnsets", "gallade").learnset.machpunch = ["6L1"];
this.modData('Moves', 'aerialace').flags.slicing = 1;
this.modData('Moves', 'aircutter').flags.slicing = 1;
this.modData('Moves', 'airslash').flags.slicing = 1;
this.modData('Moves', 'behemothblade').flags.slicing = 1;
this.modData('Moves', 'crosspoison').flags.slicing = 1;
this.modData('Moves', 'cut').flags.slicing = 1;
this.modData('Moves', 'furycutter').flags.slicing = 1;
this.modData('Moves', 'nightslash').flags.slicing = 1;
this.modData('Moves', 'psychocut').flags.slicing = 1;
this.modData('Moves', 'razorleaf').flags.slicing = 1;
this.modData('Moves', 'razorshell').flags.slicing = 1;
this.modData('Moves', 'sacredsword').flags.slicing = 1;
this.modData('Moves', 'slash').flags.slicing = 1;
this.modData('Moves', 'solarblade').flags.slicing = 1;
this.modData('Moves', 'xscissor').flags.slicing = 1;
this.modData("Learnsets", "ampharos").learnset.waterpulse = ["6L1"];
this.modData("Learnsets", "ampharos").learnset.aurasphere = ["6L1"];
this.modData("Learnsets", "ampharos").learnset.darkpulse = ["6L1"];
this.modData("Learnsets", "ampharos").learnset.defog = ["6L1"];
this.modData("Learnsets", "ampharos").learnset.slackoff = ["6L1"];
this.modData("Learnsets", "heracross").learnset.healorder = ["6L1"];
this.modData("Learnsets", "heracross").learnset.circlethrow = ["6L1"];
this.modData("Learnsets", "heracross").learnset.spikes = ["6L1"];
this.modData("Learnsets", "heracross").learnset.icepunch = ["6L1"];
this.modData("Learnsets", "sharpedo").learnset.thunder = ["6L1"];
this.modData("Learnsets", "gardevoir").learnset.rapidspin = ["6L1"];
this.modData("Learnsets", "gardevoir").learnset.mysticalfire = ["6L1"];
this.modData("Learnsets", "aggron").learnset.voltswitch = ["6L1"];
this.modData("Learnsets", "kangaskhan").learnset.milkdrink = ["6L1"];
this.modData("Learnsets", "salamence").learnset.hurricane = ["6L1"];
this.modData("Learnsets", "salamence").learnset.airslash = ["6L1"];
this.modData("Learnsets", "salamence").learnset.ironhead = ["6L1"];
this.modData("Learnsets", "tyranitar").learnset.wildcharge = ["6L1"];
this.modData("Learnsets", "tyranitar").learnset.waterfall = ["6L1"];
this.modData("Learnsets", "diancie").learnset.spikyshield = ["6L1"];
this.modData("Learnsets", "blaziken").learnset.uturn = ["6L1"];
this.modData("Learnsets", "blaziken").learnset.spikes = ["6L1"];
this.modData("Learnsets", "blaziken").learnset.roost = ["6L1"];
this.modData("Learnsets", "blaziken").learnset.closecombat = ["6L1"];
this.modData("Learnsets", "mewtwo").learnset.extremespeed = ["6L1"];
this.modData("Learnsets", "mewtwo").learnset.sludgewave = ["6L1"];
this.modData("Learnsets", "mewtwo").learnset.swordsdance = ["6L1"];
this.modData("Learnsets", "mewtwo").learnset.uturn = ["6L1"];
this.modData("Learnsets", "mewtwo").learnset.closecombat = ["6L1"];
this.modData("Learnsets", "mewtwo").learnset.drainpunch = ["6L1"];
this.modData("Learnsets", "mewtwo").learnset.machpunch = ["6L1"];
this.modData("Learnsets", "mewtwo").learnset.scald = ["6L1"];
this.modData("Learnsets", "mewtwo").learnset.surf = ["6L1"];
this.modData("Learnsets", "mewtwo").learnset.hydropump = ["6L1"];
this.modData("Learnsets", "rayquaza").learnset.coil = ["6L1"];
this.modData("Learnsets", "rayquaza").learnset.defog = ["6L1"];
},
};

View File

@ -0,0 +1,46 @@
export const Items: import('../../../sim/dex-items').ModdedItemDataTable = {
blueorb: {
inherit: true,
onSwitchIn(pokemon) {
if (pokemon.isActive && !pokemon.species.isPrimal && !pokemon.transformed) {
// @ts-expect-error modded
const species: Species = this.actions.getMixedSpecies(pokemon.m.originalSpecies, 'Kyogre-Primal', pokemon);
if (pokemon.m.originalSpecies === 'Kyogre') {
pokemon.formeChange(species, this.effect, true);
} else {
pokemon.formeChange(species, this.effect, true);
pokemon.baseSpecies = species;
this.add('-start', pokemon, 'Blue Orb', '[silent]');
}
}
},
onTakeItem: false,
},
redorb: {
inherit: true,
onSwitchIn(pokemon) {
if (pokemon.isActive && !pokemon.species.isPrimal && !pokemon.transformed) {
// @ts-expect-error modded
const species: Species = this.actions.getMixedSpecies(pokemon.m.originalSpecies, 'Groudon-Primal', pokemon);
if (pokemon.m.originalSpecies === 'Groudon') {
pokemon.formeChange(species, this.effect, true);
} else {
pokemon.formeChange(species, this.effect, true);
pokemon.baseSpecies = species;
this.add('-start', pokemon, 'Red Orb', '[silent]');
const apparentSpecies = pokemon.illusion ? pokemon.illusion.species.name : pokemon.m.originalSpecies;
const oSpecies = this.dex.species.get(apparentSpecies);
if (pokemon.illusion) {
const types = oSpecies.types;
if (types.length > 1 || types[types.length - 1] !== 'Fire') {
this.add('-start', pokemon, 'typechange', (types[0] !== 'Fire' ? types[0] + '/' : '') + 'Fire', '[silent]');
}
} else if (oSpecies.types.length !== pokemon.species.types.length || oSpecies.types[1] !== pokemon.species.types[1]) {
this.add('-start', pokemon, 'typechange', pokemon.species.types.join('/'), '[silent]');
}
}
}
},
onTakeItem: false,
},
};

View File

@ -0,0 +1,117 @@
export const Scripts: ModdedBattleScriptsData = {
gen: 6,
inherit: 'gen6',
init() {
for (const i in this.data.Items) {
if (!this.data.Items[i].megaStone) continue;
this.modData('Items', i).onTakeItem = false;
}
},
actions: {
canMegaEvo(pokemon) {
if (pokemon.species.isMega || pokemon.species.isPrimal) return null;
const item = pokemon.getItem();
if (item.megaStone) {
const values = Object.values(item.megaStone);
if (values.includes(pokemon.name)) return null;
return values[0];
} else if (pokemon.baseMoves.includes('dragonascent')) {
return 'Rayquaza-Mega';
} else {
return null;
}
},
runMegaEvo(pokemon) {
if (pokemon.species.isMega || pokemon.species.isPrimal) return false;
const species: Species = (this as any).getMixedSpecies(pokemon.m.originalSpecies, pokemon.canMegaEvo, pokemon);
// Do we have a proper sprite for it? Code for when megas actually exist
if (this.dex.species.get(pokemon.canMegaEvo as any).baseSpecies === pokemon.m.originalSpecies) {
pokemon.formeChange(species, pokemon.getItem(), true);
} else {
const oSpecies = this.dex.species.get(pokemon.m.originalSpecies);
const oMegaSpecies = this.dex.species.get((species as any).originalSpecies);
pokemon.formeChange(species, pokemon.getItem(), true);
this.battle.add('-start', pokemon, oMegaSpecies.requiredItem, '[silent]');
if (oSpecies.types.join('/') !== pokemon.species.types.join('/')) {
this.battle.add('-start', pokemon, 'typechange', pokemon.species.types.join('/'), '[silent]');
}
}
pokemon.canMegaEvo = false;
return true;
},
getMixedSpecies(originalForme, formeChange, pokemon) {
const originalSpecies = this.dex.species.get(originalForme);
const formeChangeSpecies = this.dex.species.get(formeChange);
if (originalSpecies.baseSpecies === formeChangeSpecies.baseSpecies) {
return formeChangeSpecies;
}
const deltas = (this as any).getFormeChangeDeltas(formeChangeSpecies, pokemon);
const species = (this as any).mutateOriginalSpecies(originalSpecies, deltas);
return species;
},
getFormeChangeDeltas(formeChangeSpecies, pokemon) {
// Should be fine as long as Necrozma-U doesn't get added or Game Freak makes me sad with some convoluted forme change
const baseSpecies = this.dex.species.get(formeChangeSpecies.isMega ?
formeChangeSpecies.battleOnly as string : formeChangeSpecies.baseSpecies);
const deltas: {
ability: string,
baseStats: SparseStatsTable,
weighthg: number,
heightm: number,
originalSpecies: string,
requiredItem: string | undefined,
type?: string,
formeType?: string,
isMega?: boolean,
} = {
ability: formeChangeSpecies.abilities['0'],
baseStats: {},
weighthg: formeChangeSpecies.weighthg - baseSpecies.weighthg,
heightm: ((formeChangeSpecies.heightm * 10) - (baseSpecies.heightm * 10)) / 10,
originalSpecies: formeChangeSpecies.name,
requiredItem: formeChangeSpecies.requiredItem,
};
let statId: StatID;
for (statId in formeChangeSpecies.baseStats) {
deltas.baseStats[statId] = formeChangeSpecies.baseStats[statId] - baseSpecies.baseStats[statId];
}
let formeType: string | null = null;
if (formeChangeSpecies.types.length > baseSpecies.types.length) {
deltas.type = formeChangeSpecies.types[1];
} else if (formeChangeSpecies.types.length < baseSpecies.types.length) {
deltas.type = baseSpecies.types[0];
} else if (formeChangeSpecies.types[1] !== baseSpecies.types[1]) {
deltas.type = formeChangeSpecies.types[1];
}
if (formeChangeSpecies.isMega && !formeType) formeType = 'Mega';
if (formeChangeSpecies.isPrimal) formeType = 'Primal';
if (formeType) deltas.formeType = formeType;
return deltas;
},
mutateOriginalSpecies(speciesOrForme, deltas) {
if (!deltas) throw new TypeError("Must specify deltas!");
const species = this.dex.deepClone(this.dex.species.get(speciesOrForme));
species.abilities = { '0': deltas.ability };
if (species.types[0] === deltas.type) {
species.types = [deltas.type];
} else if (deltas.type) {
species.types = [species.types[0], deltas.type];
}
const baseStats = species.baseStats;
for (const statName in baseStats) {
baseStats[statName] = this.battle.clampIntRange(baseStats[statName] + deltas.baseStats[statName], 1, 255);
}
species.weighthg = Math.max(1, species.weighthg + deltas.weighthg);
species.heightm = Math.max(0.1, ((species.heightm * 10) + (deltas.heightm * 10)) / 10);
species.originalSpecies = deltas.originalSpecies;
species.requiredItem = deltas.requiredItem;
if (deltas.formeType === 'Mega' || deltas.isMega) species.isMega = true;
if (deltas.formeType === 'Primal') species.isPrimal = true;
return species;
},
},
};

View File

@ -592,7 +592,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
doublesTier: "NFE",
},
tangrowth: {
tier: "OU",
tier: "(OU)",
doublesTier: "(DUU)",
},
kangaskhan: {

View File

@ -41,8 +41,11 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
inherit: true,
desc: "A random move that was introduced in gen 1 is selected for use, other than Counter, Mimic, Mirror Move, Struggle, or Transform.",
shortDesc: "Picks a random move from gen 1.",
onHit(target, source, effect) {
const moves = this.dex.moves.all().filter(move => move.gen === 1 && move.flags['metronome']);
onHit(target) {
const moves = this.dex.moves.all().filter(move => (
(!move.isNonstandard || move.isNonstandard === 'Unobtainable') &&
move.flags['metronome'] && move.gen === 1
));
let randomMove = '';
if (moves.length) {
moves.sort((a, b) => a.num - b.num);

View File

@ -0,0 +1,46 @@
export const Items: import('../../../sim/dex-items').ModdedItemDataTable = {
blueorb: {
inherit: true,
onSwitchIn(pokemon) {
if (pokemon.isActive && !pokemon.species.isPrimal && !pokemon.transformed) {
// @ts-expect-error modded
const species: Species = this.actions.getMixedSpecies(pokemon.m.originalSpecies, 'Kyogre-Primal', pokemon);
if (pokemon.m.originalSpecies === 'Kyogre') {
pokemon.formeChange(species, this.effect, true);
} else {
pokemon.formeChange(species, this.effect, true);
pokemon.baseSpecies = species;
this.add('-start', pokemon, 'Blue Orb', '[silent]');
}
}
},
onTakeItem: false,
},
redorb: {
inherit: true,
onSwitchIn(pokemon) {
if (pokemon.isActive && !pokemon.species.isPrimal && !pokemon.transformed) {
// @ts-expect-error modded
const species: Species = this.actions.getMixedSpecies(pokemon.m.originalSpecies, 'Groudon-Primal', pokemon);
if (pokemon.m.originalSpecies === 'Groudon') {
pokemon.formeChange(species, this.effect, true);
} else {
pokemon.formeChange(species, this.effect, true);
pokemon.baseSpecies = species;
this.add('-start', pokemon, 'Red Orb', '[silent]');
const apparentSpecies = pokemon.illusion ? pokemon.illusion.species.name : pokemon.m.originalSpecies;
const oSpecies = this.dex.species.get(apparentSpecies);
if (pokemon.illusion) {
const types = oSpecies.types;
if (types.length > 1 || types[types.length - 1] !== 'Fire') {
this.add('-start', pokemon, 'typechange', (types[0] !== 'Fire' ? types[0] + '/' : '') + 'Fire', '[silent]');
}
} else if (oSpecies.types.length !== pokemon.species.types.length || oSpecies.types[1] !== pokemon.species.types[1]) {
this.add('-start', pokemon, 'typechange', pokemon.species.types.join('/'), '[silent]');
}
}
}
},
onTakeItem: false,
},
};

View File

@ -0,0 +1,121 @@
export const Scripts: ModdedBattleScriptsData = {
gen: 7,
inherit: 'gen7',
init() {
for (const i in this.data.Items) {
if (!this.data.Items[i].megaStone) continue;
this.modData('Items', i).onTakeItem = false;
}
},
actions: {
canMegaEvo(pokemon) {
if (pokemon.species.isMega || pokemon.species.isPrimal) return null;
const item = pokemon.getItem();
if (item.megaStone) {
const values = Object.values(item.megaStone);
if (values.includes(pokemon.name)) return null;
return values[0];
} else if (pokemon.baseMoves.includes('dragonascent')) {
return 'Rayquaza-Mega';
} else {
return null;
}
},
runMegaEvo(pokemon) {
if (pokemon.species.isMega || pokemon.species.isPrimal) return false;
const isUltraBurst = !pokemon.canMegaEvo;
const species: Species = (this as any).getMixedSpecies(pokemon.m.originalSpecies,
pokemon.canMegaEvo || pokemon.canUltraBurst, pokemon);
// Do we have a proper sprite for it? Code for when megas actually exist
if (isUltraBurst || this.dex.species.get(pokemon.canMegaEvo as any).baseSpecies === pokemon.m.originalSpecies) {
pokemon.formeChange(species, pokemon.getItem(), true);
} else {
const oSpecies = this.dex.species.get(pokemon.m.originalSpecies);
const oMegaSpecies = this.dex.species.get((species as any).originalSpecies);
pokemon.formeChange(species, pokemon.getItem(), true);
this.battle.add('-start', pokemon, oMegaSpecies.requiredItem, '[silent]');
if (oSpecies.types.join('/') !== pokemon.species.types.join('/')) {
this.battle.add('-start', pokemon, 'typechange', pokemon.species.types.join('/'), '[silent]');
}
}
pokemon.canMegaEvo = false;
if (isUltraBurst) pokemon.canUltraBurst = null;
return true;
},
getMixedSpecies(originalForme, formeChange, pokemon) {
const originalSpecies = this.dex.species.get(originalForme);
const formeChangeSpecies = this.dex.species.get(formeChange);
if (originalSpecies.baseSpecies === formeChangeSpecies.baseSpecies) {
return formeChangeSpecies;
}
const deltas = (this as any).getFormeChangeDeltas(formeChangeSpecies, pokemon);
const species = (this as any).mutateOriginalSpecies(originalSpecies, deltas);
return species;
},
getFormeChangeDeltas(formeChangeSpecies, pokemon) {
// Should be fine as long as Necrozma-U doesn't get added or Game Freak makes me sad with some convoluted forme change
const baseSpecies = this.dex.species.get(formeChangeSpecies.isMega ?
formeChangeSpecies.battleOnly as string : formeChangeSpecies.baseSpecies);
const deltas: {
ability: string,
baseStats: SparseStatsTable,
weighthg: number,
heightm: number,
originalSpecies: string,
requiredItem: string | undefined,
type?: string,
formeType?: string,
isMega?: boolean,
} = {
ability: formeChangeSpecies.abilities['0'],
baseStats: {},
weighthg: formeChangeSpecies.weighthg - baseSpecies.weighthg,
heightm: ((formeChangeSpecies.heightm * 10) - (baseSpecies.heightm * 10)) / 10,
originalSpecies: formeChangeSpecies.name,
requiredItem: formeChangeSpecies.requiredItem,
};
let statId: StatID;
for (statId in formeChangeSpecies.baseStats) {
deltas.baseStats[statId] = formeChangeSpecies.baseStats[statId] - baseSpecies.baseStats[statId];
}
let formeType: string | null = null;
if (formeChangeSpecies.types.length > baseSpecies.types.length) {
deltas.type = formeChangeSpecies.types[1];
} else if (formeChangeSpecies.types.length < baseSpecies.types.length) {
deltas.type = baseSpecies.types[0];
} else if (formeChangeSpecies.types[1] !== baseSpecies.types[1]) {
deltas.type = formeChangeSpecies.types[1];
}
if (formeChangeSpecies.isMega && !formeType) formeType = 'Mega';
if (formeChangeSpecies.isPrimal) formeType = 'Primal';
if (formeType) deltas.formeType = formeType;
return deltas;
},
mutateOriginalSpecies(speciesOrForme, deltas) {
if (!deltas) throw new TypeError("Must specify deltas!");
const species = this.dex.deepClone(this.dex.species.get(speciesOrForme));
species.abilities = { '0': deltas.ability };
if (species.types[0] === deltas.type) {
species.types = [deltas.type];
} else if (deltas.type) {
species.types = [species.types[0], deltas.type];
}
const baseStats = species.baseStats;
for (const statName in baseStats) {
baseStats[statName] = this.battle.clampIntRange(baseStats[statName] + deltas.baseStats[statName], 1, 255);
}
species.weighthg = Math.max(1, species.weighthg + deltas.weighthg);
species.heightm = Math.max(0.1, ((species.heightm * 10) + (deltas.heightm * 10)) / 10);
species.originalSpecies = deltas.originalSpecies;
species.requiredItem = deltas.requiredItem;
if (deltas.formeType === 'Mega' || deltas.isMega) species.isMega = true;
if (deltas.formeType === 'Primal') species.isPrimal = true;
return species;
},
},
};

View File

@ -2922,7 +2922,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
isNonstandard: "Past",
},
victini: {
tier: "OU",
tier: "(OU)",
doublesTier: "DUU",
natDexTier: "OU",
},

View File

@ -92,10 +92,10 @@ export const Rulesets: import('../../../sim/dex-formats').ModdedFormatDataTable
if (["Zacian", "Zamazenta"].includes(species.baseSpecies) && this.toID(set.item).startsWith('rusted')) {
species = this.dex.species.get(set.species + "-Crowned");
}
if (set.item && this.dex.items.get(set.item).megaStone) {
if (set.item) {
const item = this.dex.items.get(set.item);
if (item.megaEvolves === species.baseSpecies) {
species = this.dex.species.get(Array.isArray(item.megaStone) ? item.megaStone[0] : item.megaStone);
if (item.megaStone?.[species.baseSpecies]) {
species = this.dex.species.get(item.megaStone[species.baseSpecies]);
}
}
if (
@ -123,8 +123,8 @@ export const Rulesets: import('../../../sim/dex-formats').ModdedFormatDataTable
}
if (set.item) {
const item = this.dex.items.get(set.item);
if (item.megaEvolves === set.species) {
godSpecies = this.dex.species.get(Array.isArray(item.megaStone) ? item.megaStone[0] : item.megaStone);
if (item.megaStone?.[set.species]) {
godSpecies = this.dex.species.get(item.megaStone[set.species]);
}
if (["Zacian", "Zamazenta"].includes(godSpecies.baseSpecies) && item.id.startsWith('rusted')) {
godSpecies = this.dex.species.get(set.species + "-Crowned");

View File

@ -1,14 +0,0 @@
export const Items: import('../../../sim/dex-items').ModdedItemDataTable = {
leppaberry: {
inherit: true,
onUpdate(pokemon) {
if (!pokemon.hp) return;
const moveSlot = pokemon.getMoveData(pokemon.m.lastMoveAbsolute);
if (moveSlot?.pp === 0) {
pokemon.addVolatile('leppaberry');
pokemon.volatiles['leppaberry'].moveSlot = moveSlot;
pokemon.eatItem();
}
},
},
};

View File

@ -0,0 +1,115 @@
export const Scripts: ModdedBattleScriptsData = {
gen: 8,
inherit: 'gen8',
init() {
for (const i in this.data.Items) {
const item = this.data.Items[i];
if (!item.megaStone || item.isNonstandard !== 'Past') continue;
this.modData('Items', i).onTakeItem = false;
this.modData('Items', i).isNonstandard = null;
if (item.megaStone) {
for (const megaEvo of Object.values(item.megaStone)) {
this.modData('FormatsData', this.toID(megaEvo)).isNonstandard = null;
}
}
}
},
actions: {
canMegaEvo(pokemon) {
if (pokemon.species.isMega) return null;
const item = pokemon.getItem();
if (!item.megaStone) return null;
return Object.values(item.megaStone)[0];
},
runMegaEvo(pokemon) {
if (pokemon.species.isMega) return false;
const species: Species = (this as any).getMixedSpecies(pokemon.m.originalSpecies, pokemon.canMegaEvo, pokemon);
/* Do we have a proper sprite for it? Code for when megas actually exist
if (this.dex.species.get(pokemon.canMegaEvo!).baseSpecies === pokemon.m.originalSpecies) {
pokemon.formeChange(species, pokemon.getItem(), true);
} else { */
const oSpecies = this.dex.species.get(pokemon.m.originalSpecies);
const oMegaSpecies = this.dex.species.get((species as any).originalSpecies);
pokemon.formeChange(species, pokemon.getItem(), true);
this.battle.add('-start', pokemon, oMegaSpecies.requiredItem, '[silent]');
if (oSpecies.types.join('/') !== pokemon.species.types.join('/')) {
this.battle.add('-start', pokemon, 'typechange', pokemon.species.types.join('/'), '[silent]');
}
// }
pokemon.canMegaEvo = false;
return true;
},
getMixedSpecies(originalForme, formeChange, pokemon) {
const originalSpecies = this.dex.species.get(originalForme);
const formeChangeSpecies = this.dex.species.get(formeChange);
const deltas = (this as any).getFormeChangeDeltas(formeChangeSpecies, pokemon);
const species = (this as any).mutateOriginalSpecies(originalSpecies, deltas);
return species;
},
getFormeChangeDeltas(formeChangeSpecies, pokemon) {
// Should be fine as long as Necrozma-U doesn't get added or Game Freak makes me sad with some convoluted forme change
let baseSpecies = this.dex.species.get(formeChangeSpecies.isMega ?
formeChangeSpecies.battleOnly as string : formeChangeSpecies.baseSpecies);
if (formeChangeSpecies.name === 'Zygarde-Mega') {
baseSpecies = this.dex.species.get('Zygarde-Complete');
}
const deltas: {
ability: string,
baseStats: SparseStatsTable,
weighthg: number,
heightm: number,
originalSpecies: string,
requiredItem: string | undefined,
type?: string,
formeType?: string,
isMega?: boolean,
} = {
ability: formeChangeSpecies.abilities['0'],
baseStats: {},
weighthg: formeChangeSpecies.weighthg - baseSpecies.weighthg,
heightm: ((formeChangeSpecies.heightm * 10) - (baseSpecies.heightm * 10)) / 10,
originalSpecies: formeChangeSpecies.name,
requiredItem: formeChangeSpecies.requiredItem,
};
let statId: StatID;
for (statId in formeChangeSpecies.baseStats) {
deltas.baseStats[statId] = formeChangeSpecies.baseStats[statId] - baseSpecies.baseStats[statId];
}
if (formeChangeSpecies.types.length > baseSpecies.types.length) {
deltas.type = formeChangeSpecies.types[1];
} else if (formeChangeSpecies.types.length < baseSpecies.types.length) {
deltas.type = 'mono';
} else if (formeChangeSpecies.types[1] !== baseSpecies.types[1]) {
deltas.type = formeChangeSpecies.types[1];
}
deltas.isMega = true;
return deltas;
},
mutateOriginalSpecies(speciesOrForme, deltas) {
if (!deltas) throw new TypeError("Must specify deltas!");
const species = this.dex.deepClone(this.dex.species.get(speciesOrForme));
species.abilities = { '0': deltas.ability };
if (species.types[0] === deltas.type) {
species.types = [deltas.type];
} else if (deltas.type === 'mono') {
species.types = [species.types[0]];
} else if (deltas.type) {
species.types = [species.types[0], deltas.type];
}
const baseStats = species.baseStats;
for (const statName in baseStats) {
baseStats[statName] = this.battle.clampIntRange(baseStats[statName] + deltas.baseStats[statName], 1, 255);
}
species.weighthg = Math.max(1, species.weighthg + deltas.weighthg);
species.heightm = Math.max(0.1, ((species.heightm * 10) + (deltas.heightm * 10)) / 10);
species.originalSpecies = deltas.originalSpecies;
species.requiredItem = deltas.requiredItem;
if (deltas.isMega) species.isMega = true;
return species;
},
},
};

View File

@ -879,7 +879,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
isNonstandard: null,
},
sceptilemega: {
isNonstandard: "Unobtainable",
isNonstandard: null,
},
torchic: {
isNonstandard: null,
@ -891,7 +891,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
isNonstandard: null,
},
blazikenmega: {
isNonstandard: "Unobtainable",
isNonstandard: null,
},
mudkip: {
isNonstandard: null,
@ -903,7 +903,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
isNonstandard: null,
},
swampertmega: {
isNonstandard: "Unobtainable",
isNonstandard: null,
},
poochyena: {
isNonstandard: "Past",
@ -2260,13 +2260,13 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
isNonstandard: null,
},
sliggoohisui: {
isNonstandard: "Unobtainable",
isNonstandard: null,
},
goodra: {
isNonstandard: null,
},
goodrahisui: {
isNonstandard: "Unobtainable",
isNonstandard: null,
},
klefki: {
isNonstandard: null,
@ -2308,7 +2308,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
isNonstandard: null,
},
avalugghisui: {
isNonstandard: "Unobtainable",
isNonstandard: null,
},
noibat: {
isNonstandard: null,
@ -2569,6 +2569,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
isNonstandard: null,
},
magearnaoriginal: {
isNonstandard: "Unobtainable",
},
magearnamega: {
isNonstandard: null,
@ -3179,7 +3180,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
isNonstandard: null,
},
baxcaliburmega: {
isNonstandard: "Unobtainable",
isNonstandard: null,
},
gimmighoul: {
isNonstandard: null,

View File

@ -78,10 +78,10 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "UU",
},
raichumegax: {
tier: "OU",
tier: "UU",
},
raichumegay: {
tier: "OU",
tier: "UU",
},
clefairy: {
tier: "NFE",
@ -90,7 +90,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "OU",
},
clefablemega: {
tier: "(OU)",
tier: "OU",
},
igglybuff: {
tier: "LC",
@ -99,7 +99,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "NFE",
},
wigglytuff: {
tier: "OU",
tier: "UU",
},
zubat: {
tier: "LC",
@ -108,7 +108,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "NFE",
},
crobat: {
tier: "OU",
tier: "UU",
},
meowth: {
tier: "LC",
@ -120,13 +120,13 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "LC",
},
persian: {
tier: "OU",
tier: "UU",
},
persianalola: {
tier: "OU",
tier: "UU",
},
perrserker: {
tier: "OU",
tier: "UU",
},
mankey: {
tier: "LC",
@ -135,7 +135,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "NFE",
},
annihilape: {
tier: "OU",
tier: "Uber",
},
abra: {
tier: "LC",
@ -186,13 +186,13 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "UU",
},
farfetchd: {
tier: "OU",
tier: "UU",
},
farfetchdgalar: {
tier: "LC",
},
sirfetchd: {
tier: "OU",
tier: "UU",
},
gastly: {
tier: "LC",
@ -201,7 +201,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "NFE",
},
gengar: {
tier: "OU",
tier: "UU",
},
gengarmega: {
tier: "Uber",
@ -213,10 +213,10 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "LC",
},
marowak: {
tier: "OU",
tier: "UU",
},
marowakalola: {
tier: "OU",
tier: "UU",
},
kangaskhan: {
tier: "UU",
@ -237,13 +237,13 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "LC",
},
mrmime: {
tier: "OU",
tier: "UU",
},
mrmimegalar: {
tier: "NFE",
},
mrrime: {
tier: "OU",
tier: "UU",
},
scyther: {
tier: "LC",
@ -261,7 +261,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "NFE",
},
porygonz: {
tier: "OU",
tier: "UU",
},
magikarp: {
tier: "LC",
@ -276,7 +276,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "LC",
},
vaporeon: {
tier: "OU",
tier: "UU",
},
jolteon: {
tier: "UU",
@ -300,7 +300,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "OU",
},
dragonitemega: {
tier: "OU",
tier: "(OU)",
},
mewtwo: {
tier: "Uber",
@ -363,7 +363,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "UU",
},
umbreon: {
tier: "OU",
tier: "UU",
},
slowking: {
tier: "UU",
@ -378,13 +378,13 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "UU",
},
qwilfish: {
tier: "OU",
tier: "UU",
},
qwilfishhisui: {
tier: "LC",
},
overqwil: {
tier: "OU",
tier: "UU",
},
scizor: {
tier: "OU",
@ -405,7 +405,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "OU",
},
skarmorymega: {
tier: "OU",
tier: "(OU)",
},
houndour: {
tier: "LC",
@ -435,10 +435,10 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "NFE",
},
sceptile: {
tier: "OU",
tier: "UU",
},
sceptilemega: {
tier: "OU",
tier: "UU",
},
torchic: {
tier: "LC",
@ -459,10 +459,10 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "NFE",
},
swampert: {
tier: "OU",
tier: "UU",
},
swampertmega: {
tier: "OU",
tier: "UU",
},
ralts: {
tier: "LC",
@ -525,7 +525,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "LC",
},
swalot: {
tier: "OU",
tier: "UU",
},
carvanha: {
tier: "LC",
@ -549,7 +549,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "LC",
},
grumpig: {
tier: "OU",
tier: "UU",
},
swablu: {
tier: "LC",
@ -561,19 +561,19 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "UU",
},
zangoose: {
tier: "OU",
tier: "UU",
},
seviper: {
tier: "OU",
tier: "UU",
},
feebas: {
tier: "LC",
},
milotic: {
tier: "OU",
tier: "UU",
},
kecleon: {
tier: "OU",
tier: "UU",
},
shuppet: {
tier: "LC",
@ -588,10 +588,10 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "LC",
},
chimecho: {
tier: "OU",
tier: "UU",
},
chimechomega: {
tier: "OU",
tier: "UU",
},
absol: {
tier: "UU",
@ -636,16 +636,16 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "Uber",
},
latias: {
tier: "OU",
tier: "UU",
},
latiasmega: {
tier: "OU",
tier: "UU",
},
latios: {
tier: "OU",
},
latiosmega: {
tier: "OU",
tier: "(OU)",
},
kyogre: {
tier: "Uber",
@ -672,10 +672,10 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "NFE",
},
staraptor: {
tier: "OU",
tier: "UU",
},
staraptormega: {
tier: "OU",
tier: "UU",
},
budew: {
tier: "LC",
@ -717,7 +717,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "Uber",
},
lucariomegaz: {
tier: "OU",
tier: "UU",
},
hippopotas: {
tier: "LC",
@ -753,34 +753,34 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "UU",
},
rotom: {
tier: "OU",
tier: "UU",
},
rotomheat: {
tier: "OU",
tier: "UU",
},
rotomwash: {
tier: "OU",
},
rotomfrost: {
tier: "OU",
tier: "UU",
},
rotomfan: {
tier: "OU",
tier: "UU",
},
rotommow: {
tier: "OU",
tier: "UU",
},
heatran: {
tier: "OU",
},
heatranmega: {
tier: "OU",
tier: "(OU)",
},
darkrai: {
tier: "OU",
},
darkraimega: {
tier: "OU",
tier: "(OU)",
},
tepig: {
tier: "LC",
@ -804,7 +804,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "LC",
},
liepard: {
tier: "OU",
tier: "UU",
},
pansage: {
tier: "LC",
@ -828,7 +828,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "LC",
},
musharna: {
tier: "OU",
tier: "UU",
},
drilbur: {
tier: "LC",
@ -846,10 +846,10 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "UU",
},
throh: {
tier: "OU",
tier: "UU",
},
sawk: {
tier: "OU",
tier: "UU",
},
venipede: {
tier: "LC",
@ -888,10 +888,10 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "LC",
},
cofagrigus: {
tier: "OU",
tier: "UU",
},
runerigus: {
tier: "OU",
tier: "UU",
},
trubbish: {
tier: "LC",
@ -915,7 +915,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "LC",
},
amoonguss: {
tier: "OU",
tier: "UU",
},
tynamo: {
tier: "LC",
@ -927,7 +927,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "UU",
},
eelektrossmega: {
tier: "OU",
tier: "UU",
},
litwick: {
tier: "LC",
@ -942,7 +942,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "UU",
},
cryogonal: {
tier: "OU",
tier: "UU",
},
stunfisk: {
tier: "UU",
@ -954,19 +954,19 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "LC",
},
golurk: {
tier: "OU",
tier: "UU",
},
golurkmega: {
tier: "OU",
tier: "UU",
},
cobalion: {
tier: "OU",
tier: "UU",
},
terrakion: {
tier: "OU",
tier: "UU",
},
virizion: {
tier: "OU",
tier: "UU",
},
keldeo: {
tier: "OU",
@ -974,7 +974,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
keldeoresolute: {
},
meloetta: {
tier: "OU",
tier: "UU",
},
meloettapirouette: {
},
@ -996,10 +996,10 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "NFE",
},
chesnaught: {
tier: "OU",
tier: "UU",
},
chesnaughtmega: {
tier: "(OU)",
tier: "OU",
},
fennekin: {
tier: "LC",
@ -1011,7 +1011,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "UU",
},
delphoxmega: {
tier: "OU",
tier: "UU",
},
froakie: {
tier: "LC",
@ -1026,7 +1026,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "OU",
},
greninjamega: {
tier: "OU",
tier: "(OU)",
},
bunnelby: {
tier: "LC",
@ -1041,7 +1041,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "NFE",
},
talonflame: {
tier: "OU",
tier: "UU",
},
scatterbug: {
tier: "LC",
@ -1077,7 +1077,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "UU",
},
floettemega: {
tier: "OU",
tier: "UU",
},
florges: {
tier: "UU",
@ -1101,16 +1101,16 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "LC",
},
meowstic: {
tier: "OU",
tier: "UU",
},
meowsticf: {
tier: "OU",
tier: "UU",
},
meowsticmmega: {
tier: "OU",
tier: "UU",
},
meowsticfmega: {
tier: "OU",
tier: "UU",
},
honedge: {
tier: "LC",
@ -1119,7 +1119,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "NFE",
},
aegislash: {
tier: "OU",
tier: "UU",
},
aegislashblade: {
},
@ -1214,7 +1214,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "UU",
},
goodrahisui: {
tier: "OU",
tier: "UU",
},
klefki: {
tier: "UU",
@ -1247,7 +1247,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "UU",
},
gourgeistsuper: {
tier: "OU",
tier: "UU",
},
bergmite: {
tier: "LC",
@ -1274,7 +1274,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "Uber",
},
zygarde10: {
tier: "OU",
tier: "UU",
},
zygardecomplete: {
tier: "Uber",
@ -1301,25 +1301,25 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "LC",
},
crabominable: {
tier: "OU",
tier: "UU",
},
crabominablemega: {
tier: "OU",
tier: "UU",
},
wimpod: {
tier: "LC",
},
golisopod: {
tier: "OU",
tier: "UU",
},
golisopodmega: {
tier: "OU",
tier: "UU",
},
sandygast: {
tier: "LC",
},
palossand: {
tier: "OU",
tier: "UU",
},
drampa: {
tier: "UU",
@ -1328,7 +1328,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "UU",
},
mimikyu: {
tier: "OU",
tier: "UU",
},
magearna: {
tier: "OU",
@ -1349,10 +1349,10 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "OU",
},
zeraoramega: {
tier: "OU",
tier: "(OU)",
},
meltan: {
tier: "OU",
tier: "UU",
},
melmetal: {
tier: "OU",
@ -1370,13 +1370,13 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "LC",
},
thievul: {
tier: "OU",
tier: "UU",
},
toxel: {
tier: "LC",
},
toxtricity: {
tier: "OU",
tier: "UU",
},
toxtricitylowkey: {
},
@ -1384,7 +1384,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "LC",
},
grapploct: {
tier: "OU",
tier: "UU",
},
falinks: {
tier: "UU",
@ -1393,27 +1393,27 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "UU",
},
indeedee: {
tier: "OU",
tier: "UU",
},
indeedeef: {
tier: "OU",
tier: "UU",
},
morpeko: {
tier: "OU",
tier: "UU",
},
morpekohangry: {
},
kleavor: {
tier: "OU",
tier: "UU",
},
fidough: {
tier: "LC",
},
dachsbun: {
tier: "OU",
tier: "UU",
},
squawkabilly: {
tier: "OU",
tier: "UU",
},
squawkabillyblue: {
},
@ -1428,13 +1428,13 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "NFE",
},
garganacl: {
tier: "OU",
tier: "UU",
},
charcadet: {
tier: "LC",
},
armarouge: {
tier: "OU",
tier: "UU",
},
ceruledge: {
tier: "OU",
@ -1443,22 +1443,22 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "LC",
},
mabosstiff: {
tier: "OU",
tier: "UU",
},
shroodle: {
tier: "LC",
},
grafaiai: {
tier: "OU",
tier: "UU",
},
capsakid: {
tier: "LC",
},
scovillain: {
tier: "OU",
tier: "UU",
},
scovillainmega: {
tier: "OU",
tier: "UU",
},
tinkatink: {
tier: "LC",
@ -1467,10 +1467,10 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "NFE",
},
tinkaton: {
tier: "OU",
tier: "UU",
},
cyclizar: {
tier: "OU",
tier: "UU",
},
glimmet: {
tier: "LC",
@ -1479,37 +1479,37 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "OU",
},
glimmoramega: {
tier: "OU",
tier: "(OU)",
},
greavard: {
tier: "LC",
},
houndstone: {
tier: "OU",
tier: "UU",
},
flamigo: {
tier: "OU",
tier: "UU",
},
dondozo: {
tier: "OU",
tier: "UU",
},
tatsugiri: {
tier: "OU",
tier: "UU",
},
tatsugiridroopy: {
tier: "OU",
tier: "UU",
},
tatsugiristretchy: {
tier: "OU",
tier: "UU",
},
tatsugiricurlymega: {
tier: "OU",
tier: "UU",
},
tatsugiridroopymega: {
tier: "OU",
tier: "UU",
},
tatsugiristretchymega: {
tier: "OU",
tier: "UU",
},
frigibax: {
tier: "LC",
@ -1521,7 +1521,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "OU",
},
baxcaliburmega: {
tier: "OU",
tier: "(OU)",
},
gimmighoul: {
tier: "LC",

View File

@ -2,15 +2,15 @@ export const Items: import('../../../sim/dex-items').ModdedItemDataTable = {
slowbronite: {
inherit: true,
onTakeItem(item, source) {
if (item.megaEvolves === source.baseSpecies.name || item.megaStone === source.baseSpecies.name) return false;
return true;
return !item.megaStone || (!item.megaStone[source.baseSpecies.name] &&
!Object.values(item.megaStone).includes(source.baseSpecies.name));
},
},
greninjite: {
inherit: true,
onTakeItem(item, source) {
if (item.megaEvolves === source.baseSpecies.name || item.megaStone === source.baseSpecies.name) return false;
return true;
return !item.megaStone || (!item.megaStone[source.baseSpecies.name] &&
!Object.values(item.megaStone).includes(source.baseSpecies.name));
},
},
zygardite: {

View File

@ -68392,6 +68392,7 @@ export const Learnsets: import('../../../sim/dex-species').ModdedLearnsetDataTab
trailblaze: ["9M"],
upperhand: ["9M"],
uturn: ["9M", "7M"],
vacuumwave: ["9M"],
waterfall: ["9M", "7M"],
watergun: ["9M"],
waterpledge: ["9M", "7T"],

View File

@ -1,7 +1,7 @@
export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable = {
clefablemega: {
inherit: true,
abilities: { 0: "Serene Grace" },
abilities: { 0: "Prankster" },
},
victreebelmega: {
inherit: true,
@ -22,7 +22,7 @@ export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable
},
dragonitemega: {
inherit: true,
abilities: { 0: "Soul-Heart" },
abilities: { 0: "Sheer Force" },
},
meganiummega: {
inherit: true,
@ -78,7 +78,7 @@ export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable
},
heatranmega: {
inherit: true,
abilities: { 0: "Earth Eater" },
abilities: { 0: "Filter" },
},
darkraimega: {
inherit: true,
@ -90,7 +90,7 @@ export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable
},
excadrillmega: {
inherit: true,
abilities: { 0: "Mold Breaker" },
abilities: { 0: "Sand Rush" },
},
golurkmega: {
inherit: true,
@ -118,7 +118,7 @@ export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable
},
chesnaughtmega: {
inherit: true,
abilities: { 0: "Bulletproof" },
abilities: { 0: "Grassy Surge" },
},
delphoxmega: {
inherit: true,
@ -170,11 +170,11 @@ export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable
},
golisopodmega: {
inherit: true,
abilities: { 0: "Regenerator" },
abilities: { 0: "Heatproof" },
},
drampamega: {
inherit: true,
abilities: { 0: "Drizzle" },
abilities: { 0: "Adaptability" },
},
magearnamega: {
inherit: true,
@ -198,7 +198,7 @@ export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable
},
glimmoramega: {
inherit: true,
abilities: { 0: "Rocky Payload" },
abilities: { 0: "Levitate" },
},
tatsugiricurlymega: {
inherit: true,

View File

@ -57,23 +57,8 @@ export const Scripts: ModdedBattleScriptsData = {
pokemon.baseMoves.includes(this.battle.toID(altForme.requiredMove)) && !item.zMove) {
return altForme.name;
}
if (Array.isArray(item.megaEvolves)) {
if (!Array.isArray(item.megaStone)) {
throw new Error(`${item.name}#megaEvolves and ${item.name}#megaStone type mismatch`);
}
if (item.megaEvolves.length !== item.megaStone.length) {
throw new Error(`${item.name}#megaEvolves and ${item.name}#megaStone length mismatch`);
}
const index = item.megaEvolves.indexOf(species.name);
if (index < 0) return null;
return item.megaStone[index];
} else {
if (item.megaEvolves === species.name) {
if (Array.isArray(item.megaStone)) throw new Error(`${item.name}#megaEvolves and ${item.name}#megaStone type mismatch`);
return item.megaStone;
}
}
return null;
if (!item.megaStone) return null;
return item.megaStone[species.name];
},
runMegaEvo(pokemon) {
const speciesid = pokemon.canMegaEvo || pokemon.canUltraBurst;

View File

@ -3,6 +3,64 @@ import { changeSet, getName, enemyStaff } from './scripts';
import type { ModdedConditionData } from "../../../sim/dex-conditions";
export const Conditions: { [id: IDEntry]: ModdedConditionData & { innateName?: string } } = {
zacian: {
inherit: true,
onBattleStart(pokemon) {
if (pokemon.item !== 'rustedsword') return;
const rawSpecies = this.dex.species.get('Zacian-Crowned');
const species = pokemon.setSpecies(rawSpecies);
if (!species) return;
pokemon.baseSpecies = rawSpecies;
pokemon.details = pokemon.getUpdatedDetails();
// pokemon.setAbility(species.abilities['0'], null, null, true);
// pokemon.baseAbility = pokemon.ability;
const ironHeadIndex = pokemon.baseMoves.indexOf('ironhead');
if (ironHeadIndex >= 0) {
const move = this.dex.moves.get('behemothblade');
pokemon.baseMoveSlots[ironHeadIndex] = {
move: move.name,
id: move.id,
pp: move.noPPBoosts ? move.pp : move.pp * 8 / 5,
maxpp: move.noPPBoosts ? move.pp : move.pp * 8 / 5,
target: move.target,
disabled: false,
disabledSource: '',
used: false,
};
pokemon.moveSlots = pokemon.baseMoveSlots.slice();
}
},
},
zamazenta: {
inherit: true,
onBattleStart(pokemon) {
if (pokemon.item !== 'rustedshield') return;
const rawSpecies = this.dex.species.get('Zamazenta-Crowned');
const species = pokemon.setSpecies(rawSpecies);
if (!species) return;
pokemon.baseSpecies = rawSpecies;
pokemon.details = pokemon.getUpdatedDetails();
// pokemon.setAbility(species.abilities['0'], null, null, true);
// pokemon.baseAbility = pokemon.ability;
const ironHeadIndex = pokemon.baseMoves.indexOf('ironhead');
if (ironHeadIndex >= 0) {
const move = this.dex.moves.get('behemothbash');
pokemon.baseMoveSlots[ironHeadIndex] = {
move: move.name,
id: move.id,
pp: move.noPPBoosts ? move.pp : move.pp * 8 / 5,
maxpp: move.noPPBoosts ? move.pp : move.pp * 8 / 5,
target: move.target,
disabled: false,
disabledSource: '',
used: false,
};
pokemon.moveSlots = pokemon.baseMoveSlots.slice();
}
},
},
/*
// Example:
userid: {

View File

@ -14,11 +14,9 @@ export const Items: import('../../../sim/dex-items').ModdedItemDataTable = {
name: "Flygonite",
spritenum: 111,
itemUser: ["Flygon"],
megaEvolves: "Flygon",
megaStone: "Trapinch",
megaStone: { "Flygon": "Trapinch" },
onTakeItem(item, source) {
if (item.megaEvolves === source.baseSpecies.baseSpecies) return false;
return true;
return !item.megaStone?.[source.baseSpecies.baseSpecies];
},
desc: "If held by a Flygon, this item allows it to Mega Evolve in battle.",
},
@ -36,7 +34,7 @@ export const Items: import('../../../sim/dex-items').ModdedItemDataTable = {
gardevoirite: {
inherit: true,
itemUser: ["Ralts"],
megaEvolves: "Ralts",
megaStone: { "Ralts": "Gardevoir-Mega" },
desc: "If held by a Ralts, this item allows it to Mega Evolve in battle.",
},
// Peary

View File

@ -374,40 +374,8 @@ export const Scripts: ModdedBattleScriptsData = {
this.add('start');
// Change Zacian/Zamazenta into their Crowned formes
for (const pokemon of this.getAllPokemon()) {
let rawSpecies: Species | null = null;
if (pokemon.species.id === 'zacian' && pokemon.item === 'rustedsword') {
rawSpecies = this.dex.species.get('Zacian-Crowned');
} else if (pokemon.species.id === 'zamazenta' && pokemon.item === 'rustedshield') {
rawSpecies = this.dex.species.get('Zamazenta-Crowned');
}
if (!rawSpecies) continue;
const species = pokemon.setSpecies(rawSpecies);
if (!species) continue;
pokemon.baseSpecies = rawSpecies;
pokemon.details = pokemon.getUpdatedDetails();
// pokemon.setAbility(species.abilities['0'], null, null, true);
// pokemon.baseAbility = pokemon.ability;
const behemothMove: { [k: string]: string } = {
'Zacian-Crowned': 'behemothblade', 'Zamazenta-Crowned': 'behemothbash',
};
const ironHead = pokemon.baseMoves.indexOf('ironhead');
if (ironHead >= 0) {
const move = this.dex.moves.get(behemothMove[rawSpecies.name]);
pokemon.baseMoveSlots[ironHead] = {
move: move.name,
id: move.id,
pp: move.noPPBoosts ? move.pp : move.pp * 8 / 5,
maxpp: move.noPPBoosts ? move.pp : move.pp * 8 / 5,
target: move.target,
disabled: false,
disabledSource: '',
used: false,
};
pokemon.moveSlots = pokemon.baseMoveSlots.slice();
}
this.singleEvent('BattleStart', this.dex.conditions.getByID(pokemon.species.id), pokemon.speciesState, pokemon);
}
this.format.onBattleStart?.call(this);
@ -429,9 +397,6 @@ export const Scripts: ModdedBattleScriptsData = {
}
}
}
for (const pokemon of this.getAllPokemon()) {
this.singleEvent('Start', this.dex.conditions.getByID(pokemon.species.id), pokemon.speciesState, pokemon);
}
this.midTurn = true;
break;
}
@ -963,26 +928,11 @@ export const Scripts: ModdedBattleScriptsData = {
pokemon.baseMoves.includes(this.battle.toID(altForme.requiredMove)) && !item.zMove) {
return altForme.name;
}
if (!item.megaStone) return null;
// a hacked-in Megazard X can mega evolve into Megazard Y, but not into Megazard X
if (Array.isArray(item.megaEvolves)) {
if (!Array.isArray(item.megaStone)) {
throw new Error(`${item.name}#megaEvolves and ${item.name}#megaStone type mismatch`);
}
if (item.megaEvolves.length !== item.megaStone.length) {
throw new Error(`${item.name}#megaEvolves and ${item.name}#megaStone length mismatch`);
}
// FIXME: Change to species.name when champions comes
const index = item.megaEvolves.indexOf(species.baseSpecies);
if (index < 0) return null;
return item.megaStone[index];
// FIXME: Change to species.name when champions comes
} else {
if (item.megaEvolves === species.baseSpecies) {
if (Array.isArray(item.megaStone)) throw new Error(`${item.name}#megaEvolves and ${item.name}#megaStone type mismatch`);
return item.megaStone;
}
}
return null;
// FIXME: Change to species.name when champions comes
const megaEvolution = item.megaStone[species.baseSpecies];
return megaEvolution && megaEvolution !== species.name ? megaEvolution : null;
},
// 1 Z per pokemon

View File

@ -21,7 +21,7 @@ export const Conditions: import('../../../sim/dex-conditions').ModdedConditionDa
frz: {
inherit: true,
onBeforeMove(pokemon, target, move) {
if (move.flags['defrost']) return;
if (move.flags['defrost'] && !(move.id === 'burnup' && !pokemon.hasType('Fire'))) return;
if (this.effectState.durationRolled !== this.turn && this.randomChance(1, 5)) {
pokemon.cureStatus();
return;
@ -46,17 +46,14 @@ export const Conditions: import('../../../sim/dex-conditions').ModdedConditionDa
}
}
this.add('-activate', pokemon, 'confusion');
if (!this.randomChance(1, 3)) {
if (!this.randomChance(33, 100)) {
return;
}
this.activeTarget = pokemon;
const damage = this.actions.getDamage(pokemon, pokemon, 40);
const damage = this.actions.getConfusionDamage(pokemon, 40);
if (typeof damage !== 'number') throw new Error("Confusion damage not dealt");
this.damage(damage, pokemon, pokemon, {
id: 'confused' as ID,
effectType: 'Move',
type: '???',
} as unknown as ActiveMove);
const activeMove = { id: this.toID('confused'), effectType: 'Move', type: '???' };
this.damage(damage, pokemon, pokemon, activeMove as ActiveMove);
return false;
},
},

View File

@ -1,35 +1,38 @@
export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
pursuit: {
inherit: true,
beforeTurnCallback(pokemon, target) {
beforeTurnCallback(pokemon) {
// @ts-expect-error modded
const linkedMoves: [string, string] = pokemon.getLinkedMoves();
if (linkedMoves.length) {
if (linkedMoves[0] !== 'pursuit' && linkedMoves[1] === 'pursuit') return;
}
target.side.addSideCondition('pursuit', pokemon);
if (!target.side.sideConditions['pursuit'].sources) {
target.side.sideConditions['pursuit'].sources = [];
for (const target of pokemon.foes()) {
target.addVolatile('pursuit');
const data = target.volatiles['pursuit'];
if (!data.sources) {
data.sources = [];
}
data.sources.push(pokemon);
}
target.side.sideConditions['pursuit'].sources.push(pokemon);
},
},
mefirst: {
inherit: true,
onTryHit(target, pokemon) {
const action = this.queue.willMove(target);
if (action) {
// Mod-specific: Me First copies the first move in the link
// @ts-expect-error modded
const move = this.dex.getActiveMove(action.linked?.[0] || action.move);
if (move.category !== 'Status' && !move.flags['failmefirst']) {
pokemon.addVolatile('mefirst');
this.actions.useMove(move, pokemon, { target });
return null;
}
}
return false;
if (!action) return false;
// Mod-specific: Me First copies the first move in the link
// @ts-expect-error modded
const move = this.dex.getActiveMove(action.linked?.[0] || action.move.id);
if (action.zmove || move.isZ || move.isMax) return false;
if (target.volatiles['mustrecharge']) return false;
if (move.category === 'Status' || move.flags['failmefirst']) return false;
pokemon.addVolatile('mefirst');
this.actions.useMove(move, pokemon, { target });
return null;
},
},
@ -38,7 +41,9 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
inherit: true,
onTry(source, target) {
const action = this.queue.willMove(target);
if (!action || action.choice !== 'move') {
if (!action || action.choice !== 'move' ||
// @ts-expect-error modded
(!action.linked && action.move.category === 'Status' && action.move.id !== 'mefirst')) {
this.attrLastMove('[still]');
this.add('-fail', source);
return null;
@ -51,13 +56,67 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
return null;
}
// @ts-expect-error modded
if (!action.linked) {
if (action.move.category === 'Status' && action.move.id !== 'mefirst') {
this.attrLastMove('[still]');
this.add('-fail', source);
return null;
if (action.linked) {
// @ts-expect-error modded
for (const linkedMove of action.linked) {
if (linkedMove.category !== 'Status' || linkedMove.id === 'mefirst') return;
}
} else {
this.attrLastMove('[still]');
this.add('-fail', source);
return null;
}
},
},
thunderclap: {
inherit: true,
onTry(source, target) {
const action = this.queue.willMove(target);
if (!action || action.choice !== 'move' ||
// @ts-expect-error modded
(!action.linked && action.move.category === 'Status' && action.move.id !== 'mefirst')) {
this.attrLastMove('[still]');
this.add('-fail', source);
return null;
}
if (target.volatiles.mustrecharge && target.volatiles.mustrecharge.duration! < 2) {
// Duration may not be lower than 2 if Sucker Punch is used as a low-priority move
// i.e. if Sucker Punch is linked with a negative priority move
this.attrLastMove('[still]');
this.add('-fail', source);
return null;
}
// @ts-expect-error modded
if (action.linked) {
// @ts-expect-error modded
for (const linkedMove of action.linked) {
if (linkedMove.category !== 'Status' || linkedMove.id === 'mefirst') return;
}
this.attrLastMove('[still]');
this.add('-fail', source);
return null;
}
},
},
upperhand: {
inherit: true,
onTry(source, target) {
const action = this.queue.willMove(target);
if (!action || action.choice !== 'move' || action.move.priority < 0.1 ||
// @ts-expect-error modded
(!action.linked && action.move.category === 'Status' && action.move.id !== 'mefirst')) {
this.attrLastMove('[still]');
this.add('-fail', source);
return null;
}
if (target.volatiles.mustrecharge && target.volatiles.mustrecharge.duration! < 2) {
// Duration may not be lower than 2 if Sucker Punch is used as a low-priority move
// i.e. if Sucker Punch is linked with a negative priority move
this.attrLastMove('[still]');
this.add('-fail', source);
return null;
}
// @ts-expect-error modded
if (action.linked) {
// @ts-expect-error modded
for (const linkedMove of action.linked) {
if (linkedMove.category !== 'Status' || linkedMove.id === 'mefirst') return;
@ -73,13 +132,11 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
sketch: {
inherit: true,
onHit(target, source) {
const disallowedMoves = ['chatter', 'sketch', 'struggle'];
const lastMove: Move = target.m.lastMoveAbsolute;
if (source.transformed || !lastMove || disallowedMoves.includes(lastMove.id) ||
source.moves.includes(lastMove.id) || lastMove.isZ) return false;
const move = target.m.lastMoveAbsolute;
if (source.transformed || !move || source.moves.includes(move.id)) return false;
if (move.flags['nosketch'] || move.isZ || move.isMax) return false;
const sketchIndex = source.moves.indexOf('sketch');
if (sketchIndex < 0) return false;
const move = this.dex.moves.get(lastMove);
const sketchedMove = {
move: move.name,
id: move.id,
@ -97,12 +154,14 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
mimic: {
inherit: true,
onHit(target, source) {
const lastMove: Move = target.m.lastMoveAbsolute;
if (source.transformed || !lastMove || lastMove.flags['failmimic'] ||
source.moves.includes(lastMove.id) || lastMove.isZ) return false;
const move = target.m.lastMoveAbsolute;
if (source.transformed || !move || move.flags['failmimic'] || source.moves.includes(move.id)) {
return false;
}
if (move.isZ || move.isMax) return false;
const mimicIndex = source.moves.indexOf('mimic');
if (mimicIndex < 0) return false;
const move = this.dex.moves.get(lastMove);
source.moveSlots[mimicIndex] = {
move: move.name,
id: move.id,
@ -121,25 +180,30 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
instruct: {
inherit: true,
onHit(target, source) {
const lastMove: Move | ActiveMove | null = target.m.lastMoveAbsolute;
const lastMove = target.m.lastMoveAbsolute;
if (!lastMove || target.volatiles['dynamax']) return false;
const moveIndex = target.moves.indexOf(lastMove.id);
const moveSlot = target.getMoveData(lastMove.id);
if (
lastMove.flags['failinstruct'] || lastMove.isZ || lastMove.isMax ||
lastMove.flags['charge'] || lastMove.flags['recharge'] ||
target.volatiles['beakblast'] || target.volatiles['focuspunch'] || target.volatiles['shelltrap'] ||
(target.moveSlots[moveIndex] && target.moveSlots[moveIndex].pp <= 0)
(moveSlot && moveSlot.pp <= 0)
) {
return false;
}
this.add('-singleturn', target, 'move: Instruct', `[of] ${source}`);
this.actions.runMove(lastMove.id, target, target.lastMoveTargetLoc!);
this.queue.prioritizeAction(this.queue.resolveAction({
choice: 'move',
pokemon: target,
moveid: lastMove.id,
targetLoc: target.lastMoveTargetLoc!,
})[0] as MoveAction);
},
},
mirrormove: {
inherit: true,
onTryHit(target, pokemon) {
const move: Move | ActiveMove | null = target.m.lastMoveAbsolute;
const move = target.m.lastMoveAbsolute;
if (!move?.flags['mirror'] || move.isZ || move.isMax) {
return false;
}
@ -155,15 +219,16 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
duration: 5,
noCopy: true, // doesn't get copied by Baton Pass
onStart(pokemon, source, effect) {
const lastMove: Move | ActiveMove | null = pokemon.m.lastMoveAbsolute;
// The target hasn't taken its turn, or Cursed Body activated and the move was not used through Dancer or Instruct
if (
this.queue.willMove(pokemon) ||
(pokemon === this.activePokemon && this.activeMove && !this.activeMove.isExternal)
) {
this.effectState.duration!--;
}
const lastMove = pokemon.m.lastMoveAbsolute;
if (!lastMove) {
this.debug('pokemon hasn\'t moved yet');
this.debug(`Pokemon hasn't moved yet`);
return false;
}
for (const moveSlot of pokemon.moveSlots) {
@ -171,18 +236,15 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
if (!moveSlot.pp) {
this.debug('Move out of PP');
return false;
} else {
if (effect.id === 'cursedbody') {
this.add('-start', pokemon, 'Disable', moveSlot.move, '[from] ability: Cursed Body', `[of] ${source}`);
} else {
this.add('-start', pokemon, 'Disable', moveSlot.move);
}
this.effectState.move = lastMove.id;
return;
}
}
}
return false;
if (effect.effectType === 'Ability') {
this.add('-start', pokemon, 'Disable', lastMove.name, '[from] ability: ' + effect.name, `[of] ${source}`);
} else {
this.add('-start', pokemon, 'Disable', lastMove.name);
}
this.effectState.move = lastMove.id;
},
onResidualOrder: 14,
onEnd(pokemon) {
@ -190,7 +252,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
},
onBeforeMovePriority: 7,
onBeforeMove(attacker, defender, move) {
if (!move.isZ && move.id === this.effectState.move) {
if (!(move.isZ && move.isZOrMaxPowered) && move.id === this.effectState.move) {
this.add('cant', attacker, 'Disable', move);
return false;
}
@ -210,28 +272,26 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
duration: 3,
noCopy: true, // doesn't get copied by Z-Baton Pass
onStart(target) {
let lastMove: Move | ActiveMove | null = target.m.lastMoveAbsolute;
if (!lastMove || target.volatiles['dynamax']) return false;
if ((lastMove as ActiveMove).isZOrMaxPowered) lastMove = this.dex.moves.get(lastMove.baseMove);
let move: Move | ActiveMove | null = target.m.lastMoveAbsolute;
if (!move || target.volatiles['dynamax']) return false;
// Encore only works on Max Moves if the base move is not itself a Max Move
if (move.isMax && move.baseMove) move = this.dex.moves.get(move.baseMove);
// @ts-expect-error modded
const linkedMoves: [string, string] = target.getLinkedMoves(true);
const moveIndex = target.moves.indexOf(lastMove.id);
if (linkedMoves.includes(lastMove.id) && this.dex.moves.get((linkedMoves[0])).flags['failencore'] &&
this.dex.moves.get((linkedMoves[1])).flags['failencore']) {
const moveSlot = target.getMoveData(move.id);
if (linkedMoves.includes(move.id) && linkedMoves.every(m => !!this.dex.moves.get(m).flags['failencore'])) {
// both moves cannot be encored
delete target.volatiles['encore'];
return false;
}
if (lastMove.isZ || lastMove.flags['failencore'] ||
(target.moveSlots[moveIndex] && target.moveSlots[moveIndex].pp <= 0)) {
if (move.isZ || move.isMax || move.flags['failencore'] || !moveSlot || moveSlot.pp <= 0) {
// it failed
delete target.volatiles['encore'];
return false;
}
this.effectState.turnsActivated = {};
this.effectState.move = lastMove.id;
this.effectState.timesActivated = {};
this.effectState.move = move.id;
this.add('-start', target, 'Encore');
if (linkedMoves.includes(lastMove.id)) {
if (linkedMoves.includes(move.id)) {
this.effectState.move = linkedMoves;
}
if (!this.queue.willMove(target)) {
@ -239,51 +299,50 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}
},
onOverrideAction(pokemon, target, move) {
if (!this.effectState.turnsActivated[this.turn]) {
if (!this.effectState.timesActivated[this.turn]) {
// Initialize Encore effect for this turn
this.effectState.turnsActivated[this.turn] = 0;
} else if (
this.effectState.turnsActivated[this.turn] >= (Array.isArray(this.effectState.move) ?
this.effectState.move.length : 1)) {
this.effectState.timesActivated[this.turn] = 0;
} else if (this.effectState.timesActivated[this.turn] >= (Array.isArray(this.effectState.move) ?
this.effectState.move.length : 1)) {
// Finish Encore effect for this turn
return;
}
this.effectState.turnsActivated[this.turn]++;
this.effectState.timesActivated[this.turn]++;
if (!Array.isArray(this.effectState.move)) {
this.queue.cancelAction(pokemon);
if (move.id !== this.effectState.move) return this.effectState.move;
return;
}
} else {
// Locked into a link
switch (this.effectState.turnsActivated[this.turn]) {
case 1: {
if (this.effectState.move[0] !== move.id) return this.effectState.move[0];
return;
}
case 2:
if (this.effectState.move[1] !== move.id) return this.effectState.move[1];
return;
switch (this.effectState.timesActivated[this.turn]) {
case 1: {
if (this.effectState.move[0] !== move.id) return this.effectState.move[0];
return;
}
case 2:
if (this.effectState.move[1] !== move.id) return this.effectState.move[1];
return;
}
}
},
onResidualOrder: 13,
onResidual(target) {
// early termination if you run out of PP
const lastMove = target.m.lastMoveAbsolute;
const index = target.moves.indexOf(lastMove.id);
if (index === -1) return; // no last move
const moveSlot = target.getMoveData(lastMove);
if (!moveSlot) {
target.removeVolatile('encore');
return; // no last move
}
// @ts-expect-error modded
if (target.hasLinkedMove(lastMove.id)) {
// TODO: Check instead whether the last executed move was linked
if (target.moveSlots[0].pp <= 0 || target.moveSlots[1].pp <= 0) {
delete target.volatiles.encore;
this.add('-end', target, 'Encore');
target.removeVolatile('encore');
}
} else {
if (target.moveSlots[index].pp <= 0) {
delete target.volatiles.encore;
this.add('-end', target, 'Encore');
if (moveSlot.pp <= 0) {
target.removeVolatile('encore');
}
}
},
@ -313,22 +372,25 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
inherit: true,
condition: {
noCopy: true,
onStart(pokemon) {
onStart(pokemon, source, effect) {
if (pokemon.volatiles['dynamax']) {
delete pokemon.volatiles['torment'];
return false;
}
if (effect?.id === 'gmaxmeltdown') this.effectState.duration = 3;
this.add('-start', pokemon, 'Torment');
},
onEnd(pokemon) {
this.add('-end', pokemon, 'Torment');
},
onDisableMove(pokemon) {
const lastMove = pokemon.lastMove;
const lastMove = pokemon.m.lastMoveAbsolute;
if (!lastMove || lastMove.id === 'struggle') return;
if (Array.isArray(lastMove)) {
for (const move of lastMove) {
// @ts-expect-error
if (pokemon.hasLinkedMove(lastMove.id)) {
// @ts-expect-error
for (const move of pokemon.getLinkedMoves()) {
pokemon.disableMove(move.id);
}
} else {
@ -347,12 +409,13 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
},
onFaint(target, source, effect) {
if (!source || source.fainted || !effect) return;
const lastMove: Move | ActiveMove | null = source.m.lastMoveAbsolute;
if (effect.effectType === 'Move' && !effect.flags['futuremove'] && lastMove) {
let move = source.m.lastMoveAbsolute;
if (effect.effectType === 'Move' && !effect.flags['futuremove'] && move) {
if (move.isMax && move.baseMove) move = this.dex.moves.get(move.baseMove);
for (const moveSlot of source.moveSlots) {
if (moveSlot.id === lastMove.id) {
if (moveSlot.id === move.id) {
moveSlot.pp = 0;
this.add('-activate', source, 'move: Grudge', this.dex.moves.get(lastMove.id).name);
this.add('-activate', source, 'move: Grudge', move.name);
}
}
}
@ -368,11 +431,13 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
spite: {
inherit: true,
onHit(target) {
const lastMove: Move | ActiveMove | null = target.m.lastMoveAbsolute;
if (!lastMove || lastMove.isZ || lastMove.isMax) return false;
const ppDeducted = target.deductPP(lastMove.id, 4);
let move: Move | ActiveMove | null = target.m.lastMoveAbsolute;
if (!move || move.isZ) return false;
if (move.isMax && move.baseMove) move = this.dex.moves.get(move.baseMove);
const ppDeducted = target.deductPP(move.id, 4);
if (!ppDeducted) return false;
this.add("-activate", target, 'move: Spite', lastMove.name, ppDeducted);
this.add("-activate", target, 'move: Spite', move.name, ppDeducted);
},
},
@ -407,7 +472,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
this.add('-singlemove', pokemon, 'Destiny Bond');
},
onFaint(target, source, effect) {
if (!source || !effect || target.side === source.side) return;
if (!source || !effect || target.isAlly(source)) return;
if (effect.effectType === 'Move' && !effect.flags['futuremove']) {
if (source.volatiles['dynamax']) {
this.add('-hint', "Dynamaxed Pokémon are immune to Destiny Bond.");

View File

@ -1,6 +1,5 @@
export const Scripts: ModdedBattleScriptsData = {
inherit: 'gen8',
gen: 8,
gen: 9,
getActionSpeed(action) {
if (action.choice === 'move') {
let move = action.move;
@ -70,40 +69,8 @@ export const Scripts: ModdedBattleScriptsData = {
this.add('start');
// Change Zacian/Zamazenta into their Crowned formes
for (const pokemon of this.getAllPokemon()) {
let rawSpecies: Species | null = null;
if (pokemon.species.id === 'zacian' && pokemon.item === 'rustedsword') {
rawSpecies = this.dex.species.get('Zacian-Crowned');
} else if (pokemon.species.id === 'zamazenta' && pokemon.item === 'rustedshield') {
rawSpecies = this.dex.species.get('Zamazenta-Crowned');
}
if (!rawSpecies) continue;
const species = pokemon.setSpecies(rawSpecies);
if (!species) continue;
pokemon.baseSpecies = rawSpecies;
pokemon.details = pokemon.getUpdatedDetails();
// pokemon.setAbility(species.abilities['0'], null, null, true);
// pokemon.baseAbility = pokemon.ability;
const behemothMove: { [k: string]: string } = {
'Zacian-Crowned': 'behemothblade', 'Zamazenta-Crowned': 'behemothbash',
};
const ironHead = pokemon.baseMoves.indexOf('ironhead');
if (ironHead >= 0) {
const move = this.dex.moves.get(behemothMove[rawSpecies.name]);
pokemon.baseMoveSlots[ironHead] = {
move: move.name,
id: move.id,
pp: move.noPPBoosts ? move.pp : move.pp * 8 / 5,
maxpp: move.noPPBoosts ? move.pp : move.pp * 8 / 5,
target: move.target,
disabled: false,
disabledSource: '',
used: false,
};
pokemon.moveSlots = pokemon.baseMoveSlots.slice();
}
this.singleEvent('BattleStart', this.dex.conditions.getByID(pokemon.species.id), pokemon.speciesState, pokemon);
}
this.format.onBattleStart?.call(this);
@ -125,9 +92,6 @@ export const Scripts: ModdedBattleScriptsData = {
}
}
}
for (const pokemon of this.getAllPokemon()) {
this.singleEvent('Start', this.dex.conditions.getByID(pokemon.species.id), pokemon.speciesState, pokemon);
}
this.midTurn = true;
break;
}
@ -141,8 +105,9 @@ export const Scripts: ModdedBattleScriptsData = {
// @ts-expect-error modded
const linkedMoves: ActiveMove[] = action.linked;
for (let i = linkedMoves.length - 1; i >= 0; i--) {
const validTarget = this.validTargetLoc(action.targetLoc, action.pokemon, linkedMoves[i].target);
const targetLoc = validTarget ? action.targetLoc : 0;
const isValidTarget = this.validTargetLoc(action.targetLoc, action.pokemon, linkedMoves[i].target);
const targetLoc = isValidTarget ? action.targetLoc :
action.pokemon.getLocOf(this.getRandomTarget(action.pokemon, linkedMoves[i])!);
const pseudoAction: Action = {
choice: 'move', priority: action.priority, speed: action.speed, pokemon: action.pokemon,
targetLoc, moveid: linkedMoves[i].id, move: linkedMoves[i], mega: action.mega,
@ -367,15 +332,12 @@ export const Scripts: ModdedBattleScriptsData = {
// THIS IS PURELY A SANITY CHECK
// DO NOT TAKE ADVANTAGE OF THIS TO PREVENT A POKEMON FROM MOVING;
// USE this.queue.cancelMove INSTEAD
this.debug(`${pokemon.id} INCONSISTENT STATE, ALREADY MOVED: ${pokemon.moveThisTurn}`);
this.clearActiveMove(true);
this.battle.debug(`${pokemon.id} INCONSISTENT STATE, ALREADY MOVED: ${pokemon.moveThisTurn}`);
this.battle.clearActiveMove(true);
return;
} */
} */
const willTryMove = this.battle.runEvent('BeforeMove', pokemon, target, move);
if (!willTryMove) {
if (pokemon.volatiles['twoturnmove']?.move === move.id) {
pokemon.removeVolatile('twoturnmove');
}
this.battle.runEvent('MoveAborted', pokemon, target, move);
this.battle.clearActiveMove(true);
// The event 'BeforeMove' could have returned false or null
@ -384,6 +346,12 @@ export const Scripts: ModdedBattleScriptsData = {
pokemon.moveThisTurnResult = willTryMove;
return;
}
// Used exclusively for a hint later
if (move.flags['cantusetwice'] && pokemon.m.lastMoveAbsolute?.id === move.id) {
pokemon.addVolatile(move.id);
}
if (move.beforeMoveCallback) {
if (move.beforeMoveCallback.call(this.battle, pokemon, target, move)) {
this.battle.clearActiveMove(true);
@ -399,10 +367,6 @@ export const Scripts: ModdedBattleScriptsData = {
if (!lockedMove) {
if (!pokemon.deductPP(baseMove, null, target) && (move.id !== 'struggle')) {
this.battle.add('cant', pokemon, 'nopp', move);
const gameConsole = [
null, 'Game Boy', 'Game Boy Color', 'Game Boy Advance', 'DS', 'DS', '3DS', '3DS',
][this.battle.gen] || 'Switch';
this.battle.hint(`This is not a bug, this is really how it works on the ${gameConsole}; try it yourself if you don't believe us.`);
this.battle.clearActiveMove(true);
pokemon.moveThisTurnResult = false;
return;
@ -420,14 +384,25 @@ export const Scripts: ModdedBattleScriptsData = {
this.battle.add('-zpower', pokemon);
pokemon.side.zMoveUsed = true;
}
const oldActiveMove = move;
const moveDidSomething = this.useMove(baseMove, pokemon, { target, sourceEffect, zMove, maxMove });
this.battle.lastSuccessfulMoveThisTurn = moveDidSomething ? this.battle.activeMove && this.battle.activeMove.id : null;
if (this.battle.activeMove) move = this.battle.activeMove;
this.battle.singleEvent('AfterMove', move, null, pokemon, target, move);
this.battle.runEvent('AfterMove', pokemon, target, move);
if (move.flags['cantusetwice'] && pokemon.removeVolatile(move.id)) {
this.battle.add('-hint', `Some effects can force a Pokemon to use ${move.name} again in a row.`);
}
this.battle.faintMessages();
this.battle.checkWin();
if (this.battle.gen <= 4) {
// In gen 4, the outermost move is considered the last move for Copycat
this.battle.activeMove = oldActiveMove;
}
},
},
queue: {
@ -445,13 +420,16 @@ export const Scripts: ModdedBattleScriptsData = {
instaswitch: 3,
beforeTurn: 4,
beforeTurnMove: 5,
revivalblessing: 6,
runUnnerve: 100,
runSwitch: 101,
// runPrimal: 102, (deprecated)
switch: 103,
megaEvo: 104,
megaEvoX: 104,
megaEvoY: 104,
runDynamax: 105,
terastallize: 106,
priorityChargeMove: 107,
shift: 200,
// default is 200 (for moves)
@ -480,12 +458,37 @@ export const Scripts: ModdedBattleScriptsData = {
pokemon: action.pokemon,
}));
}
if (action.megax && !action.pokemon.isSkyDropped()) {
actions.unshift(...this.resolveAction({
choice: 'megaEvoX',
pokemon: action.pokemon,
}));
}
if (action.megay && !action.pokemon.isSkyDropped()) {
actions.unshift(...this.resolveAction({
choice: 'megaEvoY',
pokemon: action.pokemon,
}));
}
if (action.terastallize && !action.pokemon.terastallized) {
actions.unshift(...this.resolveAction({
choice: 'terastallize',
pokemon: action.pokemon,
}));
}
if (action.maxMove && !action.pokemon.volatiles['dynamax']) {
actions.unshift(...this.resolveAction({
choice: 'runDynamax',
pokemon: action.pokemon,
}));
}
if (!action.maxMove && !action.zmove && action.move.priorityChargeCallback) {
actions.unshift(...this.resolveAction({
choice: 'priorityChargeMove',
pokemon: action.pokemon,
move: action.move,
}));
}
action.fractionalPriority = this.battle.runEvent('FractionalPriority', action.pokemon, null, action.move, 0);
const linkedMoves: [string, string] = action.pokemon.getLinkedMoves();
if (

View File

@ -6,9 +6,11 @@ export const Scripts: ModdedBattleScriptsData = {
if (!item.megaStone && !item.onDrive && !(item.onPlate && !item.zMove) && !item.onMemory) continue;
this.modData('Items', i).onTakeItem = false;
if (item.isNonstandard === "Past" || item.isNonstandard === "Future") this.modData('Items', i).isNonstandard = null;
/* if (item.megaStone) {
this.modData('FormatsData', this.toID(item.megaStone)).isNonstandard = null;
} */
if (item.megaStone) {
for (const megaEvo of Object.values(item.megaStone)) {
this.modData('FormatsData', this.toID(megaEvo)).isNonstandard = null;
}
}
}
},
start() {
@ -385,12 +387,8 @@ export const Scripts: ModdedBattleScriptsData = {
if (pokemon.species.isMega) return null;
const item = pokemon.getItem();
if (item.megaStone) {
if (item.megaStone.includes(pokemon.baseSpecies.name)) return null;
return Array.isArray(item.megaStone) ? item.megaStone[0] : item.megaStone;
} else {
return null;
}
if (!item.megaStone) return null;
return Object.values(item.megaStone)[0];
},
runMegaEvo(pokemon) {
if (pokemon.species.isMega) return false;

View File

@ -193,40 +193,8 @@ export const Scripts: ModdedBattleScriptsData = {
this.add('start');
// Change Zacian/Zamazenta into their Crowned formes
for (const pokemon of this.getAllPokemon()) {
let rawSpecies: Species | null = null;
if (pokemon.species.id === 'zacian' && pokemon.item === 'rustedsword') {
rawSpecies = this.dex.species.get('Zacian-Crowned');
} else if (pokemon.species.id === 'zamazenta' && pokemon.item === 'rustedshield') {
rawSpecies = this.dex.species.get('Zamazenta-Crowned');
}
if (!rawSpecies) continue;
const species = pokemon.setSpecies(rawSpecies);
if (!species) continue;
pokemon.baseSpecies = rawSpecies;
pokemon.details = pokemon.getUpdatedDetails();
pokemon.setAbility(species.abilities['0'], null, null, true);
pokemon.baseAbility = pokemon.ability;
const behemothMove: { [k: string]: string } = {
'Zacian-Crowned': 'behemothblade', 'Zamazenta-Crowned': 'behemothbash',
};
const ironHead = pokemon.baseMoves.indexOf('ironhead');
if (ironHead >= 0) {
const move = this.dex.moves.get(behemothMove[rawSpecies.name]);
pokemon.baseMoveSlots[ironHead] = {
move: move.name,
id: move.id,
pp: move.noPPBoosts ? move.pp : move.pp * 8 / 5,
maxpp: move.noPPBoosts ? move.pp : move.pp * 8 / 5,
target: move.target,
disabled: false,
disabledSource: '',
used: false,
};
pokemon.moveSlots = pokemon.baseMoveSlots.slice();
}
this.singleEvent('BattleStart', this.dex.conditions.getByID(pokemon.species.id), pokemon.speciesState, pokemon);
}
this.format.onBattleStart?.call(this);
@ -248,9 +216,6 @@ export const Scripts: ModdedBattleScriptsData = {
}
}
}
for (const pokemon of this.getAllPokemon()) {
this.singleEvent('Start', this.dex.conditions.getByID(pokemon.species.id), pokemon.speciesState, pokemon);
}
this.midTurn = true;
break;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,370 +0,0 @@
export const Conditions: import('../../../sim/dex-conditions').ModdedConditionDataTable = {
frz: {
onStart(target, source, sourceEffect) {
this.add('-message', `${target.name} was Frostbitten! Special Attack halved! (Stat Change not visible)`);
if (sourceEffect && sourceEffect.id === 'frostorb') {
this.add('-status', target, 'frz', '[from] item: Frost Orb');
} else if (sourceEffect && sourceEffect.effectType === 'Ability') {
this.add('-status', target, 'frz', '[from] ability: ' + sourceEffect.name, `[of] ${source}`);
} else {
this.add('-status', target, 'frz');
}
},
onResidualOrder: 10,
onResidual(pokemon) {
this.damage(pokemon.baseMaxhp / 16);
},
onModifySpA(spa, pokemon) {
return this.chainModify(0.5);
},
},
slp: {
name: 'slp',
effectType: 'Status',
onStart(target, source, sourceEffect) {
this.add('-message', `${target.name} is Drowsy! Damage taken is 1.2x; can't use same attack twice! Multi-Hits strike once!`);
if (sourceEffect && sourceEffect.effectType === 'Ability') {
this.add('-status', target, 'slp', '[from] ability: ' + sourceEffect.name, `[of] ${source}`);
} else if (sourceEffect && sourceEffect.effectType === 'Move') {
this.add('-status', target, 'slp', '[from] move: ' + sourceEffect.name);
} else {
this.add('-status', target, 'slp');
}
if (target.removeVolatile('nightmare')) {
this.add('-end', target, 'Nightmare', '[silent]');
}
},
onSourceModifyDamage(damage, source, target, move) {
return this.chainModify(1.2);
},
onModifyMove(move, pokemon) {
if (move.multihit) delete move.multihit;
},
onDisableMove(pokemon) {
if (pokemon.lastMove && pokemon.lastMove.id !== 'struggle') {
pokemon.disableMove(pokemon.lastMove.id);
}
},
},
par: {
inherit: true,
onStart(target, source, sourceEffect) {
this.add('-message', `${target.name} is Paralyzed! Speed halved; will be fully paralyzed every 3 turns!`);
if (sourceEffect && sourceEffect.effectType === 'Ability') {
this.add('-status', target, 'par', '[from] ability: ' + sourceEffect.name, `[of] ${source}`);
} else {
this.add('-status', target, 'par');
}
},
onResidual(pokemon) {
if (this.effectState.static === undefined) this.effectState.static = 0;
this.effectState.static++;
if (this.effectState.static >= 3) {
this.add('-message', `${pokemon.name} has too much static!`);
} else {
this.add('-message', `${pokemon.name} is building static!`);
}
},
onSwitchOut(pokemon) {
this.effectState.static = 0;
},
onSwitchIn(pokemon) {
this.effectState.static = 0;
},
onBeforeMove(pokemon) {
if (this.effectState.static >= 3) {
this.add('cant', pokemon, 'par');
this.effectState.static = 0;
return false;
}
},
},
warmed: {
name: 'Warmed',
onStart(pokemon) {
this.add('-start', pokemon, 'Warmed');
},
onModifySpAPriority: 5,
onModifySpA(spa, pokemon) {
return this.chainModify([5461, 4096]);
},
onModifyAtkPriority: 5,
onModifyAtk(atk, pokemon) {
return this.chainModify([5461, 4096]);
},
onEnd(pokemon) {
this.add('-end', pokemon, 'Warmed');
},
},
cooled: {
name: 'Cooled',
onStart(pokemon) {
this.add('-start', pokemon, 'Cooled');
},
onModifyDefPriority: 5,
onModifyDef(def, pokemon) {
return this.chainModify([5325, 4096]);
},
onModifySpDPriority: 5,
onModifySpD(spd, pokemon) {
return this.chainModify([5325, 4096]);
},
onEnd(pokemon) {
this.add('-end', pokemon, 'Cooled');
},
},
blastblight: {
name: 'Blastblight',
onStart(pokemon) {
this.add('-start', pokemon, 'Blasted');
this.add('-message', `${pokemon.name} has Blastblight! Next hit will incur chip damage!`);
},
onDamagingHit(damage, target, source, move) {
this.damage(target.baseMaxhp / 6, target, source);
target.removeVolatile('blastblight');
},
onEnd(pokemon) {
this.add('-end', pokemon, 'Blasted');
},
},
bubbleblight: {
name: 'Bubbleblight',
duration: 4,
onStart(pokemon) {
this.add('-start', pokemon, 'Bubbled');
this.add('-message', `${pokemon.name} has Bubbleblight! +1 Speed, -1 Accuracy!`);
this.boost({ spe: 1, accuracy: -1 }, pokemon);
},
onEnd(pokemon) {
this.boost({ spe: -1, accuracy: 1 }, pokemon);
this.add('-end', pokemon, 'Bubbled');
},
},
defensedown: {
name: 'Defense Down',
duration: 4,
onStart(pokemon) {
this.add('-start', pokemon, 'Defense Down');
this.add('-message', `${pokemon.name} is afflicted with Defense Down! Defenses reduced by half for 3 turns!`);
},
onModifyDef(def, pokemon) {
return this.chainModify(0.5);
},
onModifySpD(spd, pokemon) {
return this.chainModify(0.5);
},
onEnd(pokemon) {
this.add('-end', pokemon, 'Defense Down');
},
},
stench: {
name: 'Stench',
duration: 4,
onStart(pokemon) {
this.add('-start', pokemon, 'Stench');
this.add('-message', `${pokemon.name} is afflicted with Stench! Held item disabled!`);
this.singleEvent('End', pokemon.getItem(), pokemon.itemState, pokemon);
// Item suppression implemented in Pokemon.ignoringItem() within sim/pokemon.js
},
onDisableMove(pokemon) {
for (const moveSlot of pokemon.moveSlots) {
const move = this.dex.moves.get(moveSlot.id);
if (move.category === 'Status' && move.id !== 'mefirst') {
pokemon.disableMove(moveSlot.id);
}
}
},
onBeforeMovePriority: 5,
onBeforeMove(attacker, defender, move) {
if (!move.isZ && !move.isMax && move.category === 'Status' && move.id !== 'mefirst') {
this.add('cant', attacker, 'move: Taunt', move);
return false;
}
},
onEnd(pokemon) {
this.add('-end', pokemon, 'Stench');
},
},
fatigue: {
name: 'Fatigue',
duration: 5,
onStart(pokemon, source) {
this.add('-start', pokemon, 'Fatigue');
this.add('-message', `${pokemon.name} is Fatigued! Moves use more PP!`);
},
onDeductPP(pokemon) {
return 1;
},
onEnd(pokemon) {
this.add('-end', pokemon, 'Fatigue');
},
},
bleeding: {
name: 'Bleeding',
onStart(pokemon) {
this.add('-start', pokemon, 'Bleeding');
this.add('-message', `${pokemon.name} is afflicted with Bleeding! Will take damage when attacking!`);
},
onAfterMoveSecondarySelf(source, target, move) {
if (source && source !== target && move && move.category !== 'Status' && !source.forceSwitchFlag) {
this.damage(source.baseMaxhp / 10, source, source);
}
},
onEnd(pokemon) {
this.add('-end', pokemon, 'Bleeding');
},
},
snowman: {
name: 'Snowman',
onStart(pokemon) {
this.add('-start', pokemon, 'Snowman');
this.add('-message', `${pokemon.name} is a Snowman! Unable to move.`);
},
onBeforeMovePriority: 10,
onBeforeMove(pokemon, target, move) {
if (move.flags['defrost']) return;
if (this.randomChance(1, 5)) {
pokemon.cureStatus();
return;
}
this.add('cant', pokemon, 'snowman');
return false;
},
onModifyMove(move, pokemon) {
if (move.flags['defrost']) {
this.add('-curestatus', pokemon, 'snowman', `[from] move: ${move}`);
pokemon.clearStatus();
}
},
onAfterMoveSecondary(target, source, move) {
if (move.thawsTarget) {
target.cureStatus();
}
},
onDamagingHit(damage, target, source, move) {
if (move.type === 'Fire' && move.category !== 'Status') {
target.cureStatus();
}
},
onEnd(pokemon) {
this.add('-end', pokemon, 'Snowman');
},
},
rusted: {
name: 'Rusted',
duration: 4,
onStart(pokemon) {
if (pokemon.hasType('Steel')) {
this.add('-start', pokemon, 'Rusted');
this.add('-message', `${pokemon.name}'s steel defenses have rusted away!`);
} else {
pokemon.removeVolatile('rusted');
}
},
onEffectiveness(typeMod, target, type, move) {
if (!target) return;
if (target.hasType('Steel') && target.volatiles['rusted']) {
if (typeMod < 0) {
return 0;
}
if (typeMod === 0 && this.dex.getImmunity(type, target)) {
return 1;
}
}
},
onEnd(pokemon) {
this.add('-end', pokemon, 'Rusted');
this.add('-message', `${pokemon.name}'s steel defenses are restored!`);
},
},
dragonblight: {
name: 'Dragonblight',
effectType: 'Status',
onStart(pokemon) {
if (pokemon.hasType('Fairy')) {
this.add('-immune', pokemon, '[from] status: Dragonblight');
return false;
}
this.add('-start', pokemon, 'Dragonblight');
this.add('-message', `${pokemon.name} is afflicted with Dragonblight! STAB disabled!`);
},
onResidualOrder: 10,
onResidual(pokemon) {
this.damage(pokemon.baseMaxhp / 16);
},
onModifySTAB(stab, source, target, move) {
return 1;
},
onEnd(pokemon) {
this.add('-end', pokemon, 'Dragonblight');
this.add('-message', `${pokemon.name} overcame Dragonblight!`);
},
},
/* Weather */
dustdevil: {
name: 'Dust Devil',
effectType: 'Weather',
duration: 0,
// This should be applied directly to the stat before any of the other modifiers are chained
// So we give it increased priority.
onModifySpDPriority: 10,
onModifySpD(spd, pokemon) {
if (pokemon.hasType('Rock') && this.field.isWeather('dustdevil')) {
return this.modify(spd, 1.5);
}
},
onModifyMove(move, attacker) {
if (move.type === 'Rock') {
move.accuracy = true;
}
},
onFieldStart(field, source, effect) {
this.add('-weather', 'Dust Devil', '[from] ability: ' + effect.name, `[of] ${source}`);
},
onFieldResidualOrder: 1,
onFieldResidual() {
this.add('-weather', 'Dust Devil', '[upkeep]');
this.eachEvent('Weather');
},
onWeather(target) {
if (this.field.weatherState.source !== target) this.damage(target.baseMaxhp / 16);
},
onFieldEnd() {
this.add('-weather', 'none');
},
},
absolutezero: {
name: 'Absolute Zero',
effectType: 'Weather',
duration: 0,
onModifyDefPriority: 10,
onModifyDef(def, pokemon) {
if (pokemon.hasType('Ice') && this.field.isWeather('absolutezero')) {
return this.modify(def, 1.5);
}
},
onModifySpe(spe, pokemon) {
if (this.field.weatherState.source !== pokemon) return this.chainModify(0.75);
},
onFieldStart(field, source, effect) {
this.add('-weather', 'Absolute Zero', '[from] ability: ' + effect.name, `[of] ${source}`);
},
onFieldResidualOrder: 1,
onFieldResidual() {
this.add('-weather', 'Absolute Zero', '[upkeep]');
this.eachEvent('Weather');
},
onWeather(target) {
if (this.field.weatherState.source !== target) this.damage(target.baseMaxhp / 16);
},
onFieldEnd() {
this.add('-weather', 'none');
},
},
snow: {
inherit: true,
onImmunity(type) {
if (type === 'brn') return false;
},
},
};

View File

@ -1,785 +0,0 @@
export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormatsDataTable = {
agnaktor: {
tier: "UU",
},
agnaktorex: {
tier: "OU",
},
ahtalka: {
tier: "OU",
},
akantor: {
tier: "UU",
},
aknosom: {
tier: "RU",
},
alatreon: {
tier: "OU",
},
almudron: {
tier: "UU",
},
magmadron: {
tier: "OU",
},
amatsu: {
tier: "OU",
},
anjanath: {
tier: "UU",
},
fuljanath: {
tier: "UU",
},
arzuros: {
tier: "RU",
},
astalos: {
tier: "UU",
},
banbaro: {
tier: "RU",
},
barioth: {
tier: "UU",
},
barroth: {
tier: "RU",
},
basarios: {
tier: "RU",
},
bazelgeuse: {
tier: "UU",
},
beotodus: {
tier: "RU",
},
bishaten: {
tier: "UU",
},
orangaten: {
tier: "UU",
},
blangonga: {
tier: "RU",
},
brachydios: {
tier: "OU",
},
bulldrome: {
tier: "RU",
},
ceadeus: {
tier: "OU",
},
cephadrome: {
tier: "RU",
},
chameleos: {
tier: "OU",
},
congalala: {
tier: "RU",
},
dahrenmohran: {
tier: "OU",
},
daimyohermitaur: {
tier: "UU",
},
dalamadur: {
tier: "OU",
},
deviljho: {
tier: "UU",
},
diablos: {
tier: "OU",
},
diremiralis: {
tier: "OU",
},
dodogama: {
tier: "RU",
},
duramboros: {
tier: "UU",
},
eruzerion: {
tier: "OU",
},
espinas: {
tier: "OU",
},
flaminas: {
tier: "OU",
},
fatalis: {
tier: "OU",
},
gaismagorm: {
tier: "OU",
},
gammoth: {
tier: "OU",
},
garangolm: {
tier: "UU",
},
gendrome: {
tier: "RU",
},
giadrome: {
tier: "RU",
},
gigginox: {
tier: "RU",
},
glavenus: {
tier: "OU",
},
gobul: {
tier: "RU",
},
gogmazios: {
tier: "OU",
},
goremagala: {
tier: "UU",
},
chaoticgore: {
tier: "OU",
},
gossharag: {
tier: "OU",
},
gravios: {
tier: "UU",
},
greatbaggi: {
tier: "RU",
},
greatgirros: {
tier: "RU",
},
greatizuchi: {
tier: "UU",
},
greatjaggi: {
tier: "RU",
},
greatjagras: {
tier: "RU",
},
greatmaccao: {
tier: "RU",
},
greatwroggi: {
tier: "RU",
},
gureadomosu: {
tier: "OU",
},
gypceros: {
tier: "UU",
},
harudomerugu: {
tier: "OU",
},
hypnocatrice: {
tier: "RU",
},
ibushi: {
tier: "UU",
},
iodrome: {
tier: "RU",
},
jhenmohran: {
tier: "OU",
},
jyuratodus: {
tier: "OU",
},
kechawacha: {
tier: "RU",
},
khezu: {
tier: "RU",
},
kingshakalaka: {
tier: "RU",
},
kirin: {
tier: "OU",
},
kuluyaku: {
tier: "UU",
},
kulvetaroth: {
tier: "OU",
},
kushaladaora: {
tier: "OU",
},
rushaladaora: {
tier: "OU",
},
lagiacrus: {
tier: "UU",
},
ivogiacrus: {
tier: "UU",
},
lagombi: {
tier: "RU",
},
laoshanlung: {
tier: "OU",
},
lavasioth: {
tier: "RU",
},
legiana: {
tier: "UU",
},
lunagaron: {
tier: "UU",
},
lunastra: {
tier: "UU",
},
magnamalo: {
tier: "OU",
},
malfestio: {
tier: "UU",
},
malzeno: {
tier: "OU",
},
mizutsune: {
tier: "UU",
},
vizutsune: {
tier: "OU",
},
monoblos: {
tier: "UU",
},
najarala: {
tier: "UU",
},
nakarkos: {
tier: "OU",
},
namielle: {
tier: "OU",
},
nargacuga: {
tier: "OU",
},
lucacuga: {
tier: "OU",
},
narwa: {
tier: "OU",
},
nergigante: {
tier: "OU",
},
nefgarmat: {
tier: "OU",
},
nerscylla: {
tier: "RU",
},
nibelsnarf: {
tier: "RU",
},
odogaron: {
tier: "UU",
},
paolumu: {
tier: "UU",
},
plesioth: {
tier: "UU",
},
pukeipukei: {
tier: "UU",
},
qurupeco: {
tier: "RU",
},
radobaan: {
tier: "UU",
},
rajang: {
tier: "OU",
},
raknakadaki: {
tier: "UU",
},
pyrekadaki: {
tier: "UU",
},
rathalos: {
tier: "UU",
},
rathian: {
tier: "OU",
},
royalludroth: {
tier: "RU",
},
safijiiva: {
tier: "OU",
},
seltas: {
tier: "RU",
},
seltasqueen: {
tier: "UU",
},
seregios: {
tier: "OU",
},
shagarumagala: {
tier: "OU",
},
shantien: {
tier: "OU",
},
sharaishvalda: {
tier: "OU",
},
shengaoren: {
tier: "OU",
},
shogunceanataur: {
tier: "UU",
},
somnacanth: {
tier: "RU",
},
auroracanth: {
tier: "OU",
},
spiribird: {
tier: "RU",
},
spiribirdred: {
tier: "RU",
},
spiribirdyellow: {
tier: "RU",
},
spiribirdorange: {
tier: "RU",
},
teostra: {
tier: "OU",
},
tetranadon: {
tier: "UU",
},
tetsucabra: {
tier: "RU",
},
tigrex: {
tier: "OU",
},
tobikadachi: {
tier: "RU",
},
tzitziyaku: {
tier: "UU",
},
ukanlos: {
tier: "OU",
},
uragaan: {
tier: "UU",
},
vaalhazak: {
tier: "UU",
},
valstrax: {
tier: "OU",
},
glowstrax: {
tier: "OU",
},
velkhana: {
tier: "OU",
},
velocidrome: {
tier: "RU",
},
vespoidqueen: {
tier: "RU",
},
volvidon: {
tier: "RU",
},
xenojiiva: {
tier: "OU",
},
yamatsukami: {
tier: "OU",
},
yiangaruga: {
tier: "UU",
},
yiankutku: {
tier: "UU",
},
bluekutku: {
tier: "OU",
},
zamtrios: {
tier: "UU",
},
zamtriosiced: {
tier: "UU",
},
zamtriospuffed: {
tier: "UU",
},
zinogre: {
tier: "UU",
},
zorahmagdaros: {
tier: "OU",
},
lalabarina: {
tier: "UU",
},
balahara: {
tier: "UU",
},
doshaguma: {
tier: "UU",
},
rompopolo: {
tier: "UU",
},
palico: {
tier: "RU",
},
palamute: {
tier: "RU",
},
disufiroa: {
tier: "UU",
},
disufiroasol: {
tier: "UU",
},
reydau: {
tier: "OU",
},
hirabami: {
tier: "RU",
},
nuudra: {
tier: "UU",
},
nightlumu: {
tier: "UU",
},
acidinus: {
tier: "OU",
},
molgrex: {
tier: "UU",
},
blackblos: {
tier: "UU",
},
sandrioth: {
tier: "OU",
},
uthduna: {
tier: "OU",
},
blackveilhazak: {
tier: "OU",
},
silvalos: {
tier: "OU",
},
goldthian: {
tier: "OU",
},
pinkthian: {
tier: "UU",
},
goldeus: {
tier: "OU",
},
azurelos: {
tier: "UU",
},
stygiogre: {
tier: "UU",
},
jindahaad: {
tier: "OU",
},
zohshia: {
tier: "OU",
},
zohshiaencased: {
tier: "OU",
},
greencuga: {
tier: "OU",
},
allmothernarwa: {
tier: "OU",
},
nightcloakmalfestio: {
tier: "OU",
},
boltreaverastalos: {
tier: "OU",
},
massacrediablos: {
tier: "OU",
},
primozeno: {
tier: "OU",
},
arkveld: {
tier: "OU",
},
chatacabra: {
tier: "RU",
},
quematrice: {
tier: "RU",
},
pokaradon: {
tier: "RU",
},
inagami: {
tier: "OU",
},
shroudcylla: {
tier: "RU",
},
estrellian: {
tier: "OU",
},
estrellianarmored: {
tier: "OU",
},
estrellianwinged: {
tier: "OU",
},
doomtrellian: {
tier: "OU",
},
doomtrelliancharged: {
tier: "OU",
},
arbitrellian: {
tier: "OU",
},
arbitrelliancharged: {
tier: "OU",
},
olturalarval: {
tier: "OU",
},
oltura: {
tier: "OU",
},
duremudira: {
tier: "OU",
},
akuravashimu: {
tier: "UU",
},
ebogaron: {
tier: "UU",
},
purpleludroth: {
tier: "RU",
},
ahtalneset: {
tier: "OU",
},
xuwu: {
tier: "OU",
},
oroshirin: {
tier: "OU",
},
terrataur: {
tier: "UU",
},
coralpukei: {
tier: "UU",
},
rustramboros: {
tier: "UU",
},
ajarakan: {
tier: "UU",
},
emgalala: {
tier: "RU",
},
tartaronis: {
tier: "OU",
},
inferonis: {
tier: "OU",
},
hallowedmohran: {
tier: "OU",
},
unknown: {
tier: "OU",
},
yamakurai: {
tier: "OU",
},
balenox: {
tier: "RU",
},
odibatorasu: {
tier: "OU",
},
landgiacrus: {
tier: "OU",
},
ashshanlung: {
tier: "OU",
},
blackvios: {
tier: "UU",
},
crysarios: {
tier: "RU",
},
glanaktor: {
tier: "UU",
},
greensioth: {
tier: "UU",
},
zinogrehowling: {
tier: "UU",
},
palepinas: {
tier: "OU",
},
redzu: {
tier: "RU",
},
basariossandstone: {
tier: "UU",
},
shahmadur: {
tier: "OU",
},
deviljhostarving: {
tier: "OU",
},
whiteblos: {
tier: "UU",
},
hellbladeglavenus: {
tier: "OU",
},
crystalbearduragaan: {
tier: "OU",
},
stonefistdaimyo: {
tier: "OU",
},
emperorkirin: {
tier: "OU",
},
frostfangbarioth: {
tier: "OU",
},
redhelmarzuros: {
tier: "OU",
},
harudomeruguz: {
tier: "OU",
},
scornedmagnamalo: {
tier: "OU",
},
seethingbazelgeuse: {
tier: "OU",
},
snowbaronlagombi: {
tier: "OU",
},
soulseermizutsune: {
tier: "OU",
},
furiousrajang: {
tier: "OU",
},
dreadqueenrathian: {
tier: "OU",
},
dreadkingrathalos: {
tier: "OU",
},
thunderlordzinogre: {
tier: "OU",
},
ragingbrachydios: {
tier: "OU",
},
abyssallagiacrus: {
tier: "OU",
},
crimsonfatalis: {
tier: "OU",
},
whitefatalis: {
tier: "OU",
},
savagedeviljho: {
tier: "OU",
},
plesiothz: {
tier: "OU",
},
risenchameleos: {
tier: "OU",
},
risenteostra: {
tier: "OU",
},
risenkushala: {
tier: "OU",
},
risenshagaru: {
tier: "OU",
},
inagamiz: {
tier: "OU",
},
deadeyegaruga: {
tier: "OU",
},
elderfrostgammoth: {
tier: "OU",
},
grimclawtigrex: {
tier: "OU",
},
};

View File

@ -1,483 +0,0 @@
export const Items: import('../../../sim/dex-items').ModdedItemDataTable = {
boosterenergy: {
inherit: true,
desc: "Activates abilities with Protosynthesis or Quark Drive effects. Single use.",
onUpdate(pokemon) {
if (!this.effectState.started || pokemon.transformed || this.queue.peek(true)?.choice === 'runSwitch') return;
if (!this.field.isWeather('sunnyday')) {
for (const proto of ['protopyre', 'protoneuron', 'prototoxin', 'protolithos', 'protoavian',
'protorefraction', 'protosynthesis']) {
if (pokemon.hasAbility(proto)) {
if (!pokemon.volatiles[proto] /* && !this.field.isWeather('sunnyday') */ && pokemon.useItem()) {
pokemon.addVolatile(proto);
}
return;
}
}
}
if (!this.field.isTerrain('electricterrain')) {
for (const quark of ['quarkdrive', 'jellyfilleddrive', 'winddrive', 'heavydrive', 'jadedrive', 'airdrive',
'magicdrive', 'phantomdrive', 'toxicdrive']) {
if (pokemon.hasAbility(quark)) {
if (!pokemon.volatiles[quark] && pokemon.useItem()) {
pokemon.addVolatile(quark);
}
return;
}
}
}
},
},
frostorb: {
name: "Frost Orb",
gen: 9,
num: 1000,
desc: "At the end of each turn, tries to freeze the holder.",
shortDesc: "At the end of each turn, tries to freeze the holder.",
fling: {
basePower: 30,
status: 'frz',
},
onResidualOrder: 26,
onResidualSubOrder: 2,
onResidual(pokemon) {
pokemon.trySetStatus('frz', pokemon);
},
},
arzurite: {
name: "Arzurite",
gen: 9,
shortDesc: "If held by Arzuros, allows it to transform into Redhelm. (Mega-Evolution)",
megaStone: "Redhelm Arzuros",
megaEvolves: "Arzuros",
itemUser: ["Arzuros", "Redhelm Arzuros"],
onTakeItem(item, source) {
if (item.megaEvolves === source.baseSpecies.baseSpecies) return false;
return true;
},
spritenum: 585,
},
astalite: {
name: "Astalite",
gen: 9,
shortDesc: "If held by Asatalos, allows it to transform into Boltreaver. (Mega-Evolution)",
megaStone: "Boltreaver Astalos",
megaEvolves: "Astalos",
itemUser: ["Astalos", "Boltreaver Astalos"],
onTakeItem(item, source) {
if (item.megaEvolves === source.baseSpecies.baseSpecies) return false;
return true;
},
spritenum: 613,
},
bazelnite: {
name: "Bazelnite",
gen: 9,
shortDesc: "If held by Bazelgeuse, allows it to transform into Seething. (Mega-Evolution)",
megaStone: "Seething Bazelgeuse",
megaEvolves: "Bazelgeuse",
itemUser: ["Bazelgeuse", "Seething Bazelgeuse"],
onTakeItem(item, source) {
if (item.megaEvolves === source.baseSpecies.baseSpecies) return false;
return true;
},
spritenum: 591,
},
bariothite: {
name: "Bariothite",
gen: 9,
shortDesc: "If held by Barioth, allows it to transform into Frostfang. (Mega-Evolution)",
megaStone: "Frostfang Barioth",
megaEvolves: "Barioth",
itemUser: ["Barioth", "Frostfang Barioth"],
onTakeItem(item, source) {
if (item.megaEvolves === source.baseSpecies.baseSpecies) return false;
return true;
},
spritenum: 685,
},
brachylite: {
name: "Brachylite",
gen: 9,
shortDesc: "If held by Brachydios, allows it to transform into Raging. (Mega-Evolution)",
megaStone: "Raging Brachydios",
megaEvolves: "Brachydios",
itemUser: ["Brachydios", "Raging Brachydios"],
onTakeItem(item, source) {
if (item.megaEvolves === source.baseSpecies.baseSpecies) return false;
return true;
},
spritenum: 613,
},
devilite: {
name: "Devilite",
gen: 9,
shortDesc: "If held by Deviljho, allows it to transform into Savage. (Mega-Evolution)",
megaStone: "Savage Deviljho",
megaEvolves: "Deviljho",
itemUser: ["Deviljho", "Savage Deviljho"],
onTakeItem(item, source) {
if (item.megaEvolves === source.baseSpecies.baseSpecies) return false;
return true;
},
spritenum: 584,
},
diablite: {
name: "Diablite",
gen: 9,
shortDesc: "If held by Diablos, allows it to transform into Massacre. (Mega-Evolution)",
megaStone: "Massacre Diablos",
megaEvolves: "Diablos",
itemUser: ["Diablos", "Massacre Diablos"],
onTakeItem(item, source) {
if (item.megaEvolves === source.baseSpecies.baseSpecies) return false;
return true;
},
spritenum: 589,
},
gammothite: {
name: "Gammothite",
gen: 9,
shortDesc: "If held by Gammoth, allows her to transform into Elderfrost. (Mega-Evolution)",
megaStone: "Elderfrost Gammoth",
megaEvolves: "Gammoth",
itemUser: ["Gammoth", "Elderfrost Gammoth"],
onTakeItem(item, source) {
if (item.megaEvolves === source.baseSpecies.baseSpecies) return false;
return true;
},
spritenum: 623,
},
garugite: {
name: "Garugite",
gen: 9,
shortDesc: "If held by Yian Garuga, allows it to transform into Deadeye. (Mega-Evolution)",
megaStone: "Deadeye Garuga",
megaEvolves: "Yian Garuga",
itemUser: ["Yian Garuga", "Deadeye Garuga"],
onTakeItem(item, source) {
if (item.megaEvolves === source.baseSpecies.baseSpecies) return false;
return true;
},
spritenum: 577,
},
harudomerite: {
name: "Harudomerite",
gen: 9,
shortDesc: "If held by Harudomerugu, allows it to enter it's Zenith Form. (Mega-Evolution)",
megaStone: "Harudomerugu-Z",
megaEvolves: "Harudomerugu",
itemUser: ["Harudomerugu", "Harudomerugu-Z"],
onTakeItem(item, source) {
if (item.megaEvolves === source.baseSpecies.baseSpecies) return false;
return true;
},
spritenum: 578,
},
inagamite: {
name: "Inagamite",
gen: 9,
shortDesc: "If held by Inagami, allows it to enter it's Zenith Form. (Mega-Evolution)",
megaStone: "Inagami-Z",
megaEvolves: "Inagami",
itemUser: ["Inagami", "Inagami-Z"],
onTakeItem(item, source) {
if (item.megaEvolves === source.baseSpecies.baseSpecies) return false;
return true;
},
spritenum: 613,
},
lagialite: {
name: "Lagialite",
gen: 9,
shortDesc: "If held by Lagiacrus, allows it to transform into Abyssal. (Mega-Evolution)",
megaStone: "Abyssal Lagiacrus",
megaEvolves: "Lagiacrus",
itemUser: ["Lagiacrus", "Abyssal Lagiacrus"],
onTakeItem(item, source) {
if (item.megaEvolves === source.baseSpecies.baseSpecies) return false;
return true;
},
spritenum: 585,
},
lagombite: {
name: "Lagombite",
gen: 9,
shortDesc: "If held by Lagombi, allows it to transform into Snowbaron. (Mega-Evolution)",
megaStone: "Snowbaron Lagombi",
megaEvolves: "Lagombi",
itemUser: ["Lagombi", "Snowbaron Lagombi"],
onTakeItem(item, source) {
if (item.megaEvolves === source.baseSpecies.baseSpecies) return false;
return true;
},
spritenum: 583,
},
magnamalite: {
name: "Magnamalite",
gen: 9,
shortDesc: "If held by Magnamalo, allows it to transform into Scorned. (Mega-Evolution)",
megaStone: "Scorned Magnamalo",
megaEvolves: "Magnamalo",
itemUser: ["Magnamalo", "Scorned Magnamalo"],
onTakeItem(item, source) {
if (item.megaEvolves === source.baseSpecies.baseSpecies) return false;
return true;
},
spritenum: 614,
},
malfestite: {
name: "Malfestite",
gen: 9,
shortDesc: "If held by Malfestio, allows it to transform into Nightcloak. (Mega-Evolution)",
megaStone: "Nightcloak Malfestio",
megaEvolves: "Malfestio",
itemUser: ["Malfestio", "Nightcloak Malfestio"],
onTakeItem(item, source) {
if (item.megaEvolves === source.baseSpecies.baseSpecies) return false;
return true;
},
spritenum: 577,
},
mizutsunite: {
name: "Mizutsunite",
gen: 9,
shortDesc: "If held by Mizutsune, allows it to transform into Soulseer. (Mega-Evolution)",
megaStone: "Soulseer Mizutsune",
megaEvolves: "Mizutsune",
itemUser: ["Mizutsune", "Soulseer Mizutsune"],
onTakeItem(item, source) {
if (item.megaEvolves === source.baseSpecies.baseSpecies) return false;
return true;
},
spritenum: 624,
},
narwanite: {
name: "Narwanite",
gen: 9,
shortDesc: "If held by Narwa, allows it to transform into Allmother. (Mega-Evolution)",
megaStone: "Allmother Narwa",
megaEvolves: "Narwa",
itemUser: ["Narwa", "Allmother Narwa"],
onTakeItem(item, source) {
if (item.megaEvolves === source.baseSpecies.baseSpecies) return false;
return true;
},
spritenum: 596,
},
plesite: {
name: "Plesite",
gen: 9,
shortDesc: "If held by Plesioth, allows it to enter it's Zenith Form. (Mega-Evolution)",
megaStone: "Plesioth-Z",
megaEvolves: "Plesioth",
itemUser: ["Plesioth", "Plesioth-Z"],
onTakeItem(item, source) {
if (item.megaEvolves === source.baseSpecies.baseSpecies) return false;
return true;
},
spritenum: 621,
},
rajanite: {
name: "Rajanite",
gen: 9,
shortDesc: "If held by Rajang, allows it to transform into Furious. (Mega-Evolution)",
megaStone: "Furious Rajang",
megaEvolves: "Rajang",
itemUser: ["Rajang", "Furious Rajang"],
onTakeItem(item, source) {
if (item.megaEvolves === source.baseSpecies.baseSpecies) return false;
return true;
},
spritenum: 602,
},
rathalosite: {
name: "Rathalosite",
gen: 9,
shortDesc: "If held by Rathalos, allows it to transform into Dreadking. (Mega-Evolution)",
megaStone: "Dreadking Rathalos",
megaEvolves: "Rathalos",
itemUser: ["Rathalos", "Dreadking Rathalos"],
onTakeItem(item, source) {
if (item.megaEvolves === source.baseSpecies.baseSpecies) return false;
return true;
},
spritenum: 586,
},
rathianite: {
name: "Rathianite",
gen: 9,
shortDesc: "If held by Rathian, allows it to transform into Dreadqueen. (Mega-Evolution)",
megaStone: "Dreadqueen Rathian",
megaEvolves: "Rathian",
itemUser: ["Rathian", "Dreadqueen Rathian"],
onTakeItem(item, source) {
if (item.megaEvolves === source.baseSpecies.baseSpecies) return false;
return true;
},
spritenum: 607,
},
risenitec: {
name: "Risenite-C",
gen: 9,
shortDesc: "If held by Chameleos, allows it to enter it's Risen Form. (Mega-Evolution)",
megaStone: "Risen Chameleos",
megaEvolves: "Chameleos",
itemUser: ["Chameleos", "Risen Chameleos"],
onTakeItem(item, source) {
if (item.megaEvolves === source.baseSpecies.baseSpecies) return false;
return true;
},
spritenum: 590,
},
risenitek: {
name: "Risenite-K",
gen: 9,
shortDesc: "If held by Kushala, allows it to enter it's Risen Form. (Mega-Evolution)",
megaStone: "Risen Kushala",
megaEvolves: "Kushala Daora",
itemUser: ["Kushala Daora", "Risen Kushala"],
onTakeItem(item, source) {
if (item.megaEvolves === source.baseSpecies.baseSpecies) return false;
return true;
},
spritenum: 590,
},
risenitet: {
name: "Risenite-T",
gen: 9,
shortDesc: "If held by Teostra, allows it to enter it's Risen Form. (Mega-Evolution)",
megaStone: "Risen Teostra",
megaEvolves: "Teostra",
itemUser: ["Teostra", "Risen Teostra"],
onTakeItem(item, source) {
if (item.megaEvolves === source.baseSpecies.baseSpecies) return false;
return true;
},
spritenum: 590,
},
risenites: {
name: "Risenite-S",
gen: 9,
shortDesc: "If held by Shagaru Magala, allows it to enter it's Risen Form. (Mega-Evolution)",
megaStone: "Risen Shagaru",
megaEvolves: "Shagaru Magala",
itemUser: ["Shagaru Magala", "Risen Shagaru"],
onTakeItem(item, source) {
if (item.megaEvolves === source.baseSpecies.baseSpecies) return false;
return true;
},
spritenum: 590,
},
tigrexite: {
name: "Tigrexite",
gen: 9,
shortDesc: "If held by Tigrex, allows it to transform into Grimclaw. (Mega-Evolution)",
megaStone: "Grimclaw Tigrex",
megaEvolves: "Tigrex",
itemUser: ["Tigrex", "Grimclaw Tigrex"],
onTakeItem(item, source) {
if (item.megaEvolves === source.baseSpecies.baseSpecies) return false;
return true;
},
spritenum: 619,
},
zinogrite: {
name: "Zinogrite",
gen: 9,
shortDesc: "If held by Zinogre, allows it to transform into Thunderlord. (Mega-Evolution)",
megaStone: "Thunderlord Zinogre",
megaEvolves: "Zinogre",
itemUser: ["Zinogre", "Thunderlord Zinogre"],
onTakeItem(item, source) {
if (item.megaEvolves === source.baseSpecies.baseSpecies) return false;
return true;
},
spritenum: 590,
},
kirinite: {
name: "Kirinite",
gen: 9,
shortDesc: "If held by Kirin, allows it to transform into Emperor. (Mega-Evolution)",
megaStone: "Emperor Kirin",
megaEvolves: "Kirin",
itemUser: ["Kirin", "Emperor Kirin"],
onTakeItem(item, source) {
if (item.megaEvolves === source.baseSpecies.baseSpecies) return false;
return true;
},
spritenum: 602,
},
uragaanite: {
name: "Uragaanite",
gen: 9,
shortDesc: "If held by Uragaan, allows it to transform into Crystalbeard. (Mega-Evolution)",
megaStone: "Crystalbeard Uragaan",
megaEvolves: "Uragaan",
itemUser: ["Uragaan", "Crystalbeard Uragaan"],
onTakeItem(item, source) {
if (item.megaEvolves === source.baseSpecies.baseSpecies) return false;
return true;
},
spritenum: 663,
},
daimyite: {
name: "Daimyite",
gen: 9,
shortDesc: "If held by Daimyo Hermitaur, allows it to transform into Stonefist. (Mega-Evolution)",
megaStone: "Stonefist Daimyo",
megaEvolves: "Daimyo Hermitaur",
itemUser: ["Daimyo Hermitaur", "Stonefist Daimyo"],
onTakeItem(item, source) {
if (item.megaEvolves === source.baseSpecies.baseSpecies) return false;
return true;
},
spritenum: 612,
},
glavenite: {
name: "Glavenite",
gen: 9,
shortDesc: "If held by Glavenus, allows it to transform into Hellblade. (Mega-Evolution)",
megaStone: "Hellblade Glavenus",
megaEvolves: "Glavenus",
itemUser: ["Glavenus", "Hellblade Glavenus"],
onTakeItem(item, source) {
if (item.megaEvolves === source.baseSpecies.baseSpecies) return false;
return true;
},
spritenum: 586,
},
/*
Fatalis Orbs
*/
crimsongem: {
name: "Crimson Gem",
gen: 9,
shortDesc: "If held by Fatalis, triggers its Crimson Form in battle. (Primal Reversion)",
itemUser: ["Fatalis", "Crimson-Fatalis"],
onSwitchIn(pokemon) {
if (pokemon.isActive && pokemon.baseSpecies.name === 'Fatalis' && !pokemon.transformed) {
pokemon.formeChange('Crimson-Fatalis', this.effect, true);
}
},
onTakeItem(item, source) {
if (source.baseSpecies.baseSpecies === 'Fatalis') return false;
return true;
},
},
whitegem: {
name: "White Gem",
gen: 9,
shortDesc: "If held by Fatalis, triggers its Crimson Form in battle. (Primal Reversion)",
itemUser: ["Fatalis", "White-Fatalis"],
onSwitchIn(pokemon) {
if (pokemon.isActive && pokemon.baseSpecies.name === 'Fatalis' && !pokemon.transformed) {
pokemon.formeChange('White-Fatalis', this.effect, true);
}
},
onTakeItem(item, source) {
if (source.baseSpecies.baseSpecies === 'Fatalis') return false;
return true;
},
},
};

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,14 +0,0 @@
export const Scripts: ModdedBattleScriptsData = {
gen: 9,
pokemon: {
ignoringItem() {
return !!(
this.itemState.knockedOff || // Gen 3-4
(this.battle.gen >= 5 && !this.isActive) ||
(!this.getItem().ignoreKlutz && this.hasAbility('klutz')) ||
this.volatiles['embargo'] || this.battle.field.pseudoWeather['magicroom'] ||
this.volatiles['stench']
);
},
},
};

View File

@ -3480,7 +3480,7 @@ export const Moves: import('../sim/dex-moves').MoveDataTable = {
flags: { protect: 1, reflectable: 1, mirror: 1, metronome: 1, nosketch: 1 },
status: 'slp',
onTry(source, target, move) {
if (source.species.name === 'Darkrai' || move.hasBounced) {
if (source.species.baseSpecies === 'Darkrai' || move.hasBounced) {
return;
}
this.add('-fail', source, 'move: Dark Void');
@ -14914,10 +14914,9 @@ export const Moves: import('../sim/dex-moves').MoveDataTable = {
priority: 0,
flags: { contact: 1, protect: 1, mirror: 1, metronome: 1 },
beforeTurnCallback(pokemon) {
for (const side of this.sides) {
if (side.hasAlly(pokemon)) continue;
side.addSideCondition('pursuit', pokemon);
const data = side.getSideConditionData('pursuit');
for (const target of pokemon.foes()) {
target.addVolatile('pursuit');
const data = target.volatiles['pursuit'];
if (!data.sources) {
data.sources = [];
}
@ -14927,9 +14926,6 @@ export const Moves: import('../sim/dex-moves').MoveDataTable = {
onModifyMove(move, source, target) {
if (target?.beingCalledBack || target?.switchFlag) move.accuracy = true;
},
onTryHit(target, pokemon) {
target.side.removeSideCondition('pursuit');
},
condition: {
duration: 1,
onBeforeSwitchOut(pokemon) {
@ -17213,35 +17209,8 @@ export const Moves: import('../sim/dex-moves').MoveDataTable = {
pp: 10,
priority: 0,
flags: { protect: 1, mirror: 1, bypasssub: 1, allyanim: 1, metronome: 1 },
onTryHit(target, source) {
const targetAbility = target.getAbility();
const sourceAbility = source.getAbility();
if (sourceAbility.flags['failskillswap'] || targetAbility.flags['failskillswap'] || target.volatiles['dynamax']) {
return false;
}
const sourceCanBeSet = this.runEvent('SetAbility', source, source, this.effect, targetAbility);
if (!sourceCanBeSet) return sourceCanBeSet;
const targetCanBeSet = this.runEvent('SetAbility', target, source, this.effect, sourceAbility);
if (!targetCanBeSet) return targetCanBeSet;
},
onHit(target, source, move) {
const targetAbility = target.getAbility();
const sourceAbility = source.getAbility();
if (target.isAlly(source)) {
this.add('-activate', source, 'move: Skill Swap', '', '', `[of] ${target}`);
} else {
this.add('-activate', source, 'move: Skill Swap', targetAbility, sourceAbility, `[of] ${target}`);
}
this.singleEvent('End', sourceAbility, source.abilityState, source);
this.singleEvent('End', targetAbility, target.abilityState, target);
source.ability = targetAbility.id;
target.ability = sourceAbility.id;
source.abilityState = this.initEffectState({ id: this.toID(source.ability), target: source });
target.abilityState = this.initEffectState({ id: this.toID(target.ability), target });
source.volatileStaleness = undefined;
if (!target.isAlly(source)) target.volatileStaleness = 'external';
this.singleEvent('Start', targetAbility, source.abilityState, source);
this.singleEvent('Start', sourceAbility, target.abilityState, target);
return this.skillSwap(source, target);
},
secondary: null,
target: "normal",

View File

@ -12034,7 +12034,7 @@ export const Pokedex: import('../sim/dex-species').SpeciesDataTable = {
types: ["Grass", "Fighting"],
genderRatio: { M: 0.875, F: 0.125 },
baseStats: { hp: 88, atk: 137, def: 172, spa: 74, spd: 115, spe: 44 },
abilities: { 0: "Overgrow", H: "Bulletproof" },
abilities: { 0: "Bulletproof" },
heightm: 1.6,
weightkg: 90,
color: "Green",
@ -12094,7 +12094,7 @@ export const Pokedex: import('../sim/dex-species').SpeciesDataTable = {
types: ["Fire", "Psychic"],
genderRatio: { M: 0.875, F: 0.125 },
baseStats: { hp: 75, atk: 69, def: 72, spa: 159, spd: 125, spe: 134 },
abilities: { 0: "Blaze", H: "Magician" },
abilities: { 0: "Levitate" },
heightm: 1.5,
weightkg: 39,
color: "Red",
@ -12186,7 +12186,7 @@ export const Pokedex: import('../sim/dex-species').SpeciesDataTable = {
types: ["Water", "Dark"],
genderRatio: { M: 0.875, F: 0.125 },
baseStats: { hp: 72, atk: 125, def: 77, spa: 133, spd: 81, spe: 142 },
abilities: { 0: "Torrent", H: "Protean" },
abilities: { 0: "Protean" },
heightm: 1.5,
weightkg: 40,
color: "Blue",

View File

@ -926,7 +926,7 @@
]
},
"swanna": {
"level": 84,
"level": 82,
"sets": [
{
"role": "Fast Attacker",
@ -937,7 +937,7 @@
]
},
"typhlosionmega": {
"level": 84,
"level": 82,
"sets": [
{
"role": "Fast Attacker",
@ -954,7 +954,7 @@
]
},
"terapagos": {
"level": 84,
"level": 82,
"sets": [
{
"role": "Bulky Setup",
@ -982,7 +982,7 @@
]
},
"genesectburn": {
"level": 84,
"level": 82,
"sets": [
{
"role": "Wallbreaker",
@ -1004,7 +1004,7 @@
]
},
"genesectdouse": {
"level": 84,
"level": 82,
"sets": [
{
"role": "Wallbreaker",
@ -1015,7 +1015,7 @@
]
},
"genesectshock": {
"level": 84,
"level": 80,
"sets": [
{
"role": "Wallbreaker",
@ -1162,5 +1162,27 @@
"teraTypes": ["Grass"]
}
]
},
"wobbuffet": {
"level": 84,
"sets": [
{
"role": "Bulky Support",
"movepool": ["Counter", "Mirror Coat", "Shed Tail", "Encore", "Guillotine", "Night Shade"],
"abilities": ["Jello Body"],
"teraTypes": ["Dark", "Steel"]
}
]
},
"raticatemega": {
"level": 84,
"sets": [
{
"role": "Fast Attacker",
"movepool": ["Super Fang", "Hyper Fang", "Last Breakfast", "U-turn"],
"abilities": ["Hustle"],
"teraTypes": ["Normal"]
}
]
}
}

View File

@ -236,6 +236,8 @@ export class RandomChatBatsTeams extends RandomTeams {
if (species.id === 'feraligatrmega') this.incompatibleMoves(moves, movePool, 'thunderfang', 'poisonfang');
if (species.id === 'salazzle') this.incompatibleMoves(moves, movePool, 'malignantchain', 'venoshock');
if (species.id === 'glimmora') this.incompatibleMoves(moves, movePool, 'powergem', 'meteorbeam');
if (species.id === 'wobbuffet') this.incompatibleMoves(moves, movePool, 'shedtail', 'encore');
if (species.id === 'wobbuffet') this.incompatibleMoves(moves, movePool, 'nightshade', 'guillotine');
}
override randomMoveset(
@ -724,6 +726,7 @@ export class RandomChatBatsTeams extends RandomTeams {
if (species.id === 'ogerponcornerstone') return 'Cornerstone Mask';
if (species.id === 'glimmora' && moves.has('meteorbeam')) return 'Power Herb';
if (species.id === 'glimmora') return 'Air Balloon';
if (species.id === 'wobbuffet') return 'Covert Cloak';
}
override randomSet(
@ -897,7 +900,7 @@ export class RandomChatBatsTeams extends RandomTeams {
let leadsRemaining = this.format.gameType === 'doubles' ? 2 : 1;
while (baseSpeciesPool.length && pokemon.length < this.maxTeamSize) {
const baseSpecies = this.sampleNoReplace(baseSpeciesPool);
if (hasMega && (baseSpecies === "Typhlosion" || baseSpecies === "Altaria")) continue;
if (hasMega && (baseSpecies === "Typhlosion" || baseSpecies === "Altaria" || baseSpecies === "Raticate")) continue;
const currentSpeciesPool: Species[] = [];
// Check if the base species has a mega forme available
// let canMega = false;
@ -1008,7 +1011,7 @@ export class RandomChatBatsTeams extends RandomTeams {
// if (potd?.exists && (pokemon.length === 1 || this.maxTeamSize === 1)) species = potd;
// testing code
// if (pokemon.length === 0 || this.maxTeamSize === 1) species = this.dex.species.get('Feraligatr-Mega');
// if (pokemon.length === 0 || this.maxTeamSize === 1) species = this.dex.species.get('Raticate-Mega');
let set: RandomTeamsTypes.RandomSet;

View File

@ -1,14 +1,14 @@
{
"bulbasaur": {
"level": 89,
"level": 91,
"moves": ["bodyslam", "razorleaf", "sleeppowder", "swordsdance"]
},
"ivysaur": {
"level": 80,
"level": 82,
"moves": ["bodyslam", "razorleaf", "sleeppowder", "swordsdance"]
},
"venusaur": {
"level": 74,
"level": 73,
"moves": ["bodyslam", "razorleaf", "sleeppowder"],
"exclusiveMoves": ["hyperbeam", "swordsdance", "swordsdance"]
},
@ -58,7 +58,7 @@
"exclusiveMoves": ["agility", "agility", "megadrain"]
},
"pidgey": {
"level": 93,
"level": 95,
"moves": ["agility", "agility", "quickattack", "quickattack", "skyattack"],
"essentialMoves": ["doubleedge"],
"exclusiveMoves": ["mirrormove", "sandattack", "substitute"],
@ -164,7 +164,7 @@
"exclusiveMoves": ["blizzard", "counter", "hyperbeam", "hyperbeam", "psychic", "sing", "sing"]
},
"vulpix": {
"level": 88,
"level": 89,
"moves": ["bodyslam", "confuseray", "fireblast"],
"exclusiveMoves": ["flamethrower", "flamethrower", "quickattack", "reflect", "substitute", "substitute"]
},
@ -199,7 +199,7 @@
"exclusiveMoves": ["stunspore", "stunspore", "swordsdance"]
},
"gloom": {
"level": 82,
"level": 83,
"moves": ["doubleedge", "megadrain", "sleeppowder"],
"exclusiveMoves": ["stunspore", "stunspore", "swordsdance"]
},
@ -245,7 +245,7 @@
"persian": {
"level": 73,
"moves": ["bodyslam", "bubblebeam", "slash"],
"exclusiveMoves": ["hyperbeam", "thunderbolt"]
"exclusiveMoves": ["hyperbeam", "thunderbolt", "thunderbolt", "thunderbolt"]
},
"psyduck": {
"level": 89,
@ -269,7 +269,7 @@
"exclusiveMoves": ["counter", "lowkick", "hyperbeam", "hyperbeam"]
},
"growlithe": {
"level": 89,
"level": 91,
"moves": ["agility", "bodyslam", "fireblast"],
"exclusiveMoves": ["flamethrower", "reflect"]
},
@ -308,12 +308,12 @@
"exclusiveMoves": ["counter", "reflect", "reflect", "seismictoss", "seismictoss"]
},
"machop": {
"level": 89,
"level": 92,
"moves": ["bodyslam", "earthquake", "submission"],
"exclusiveMoves": ["counter", "rockslide", "rockslide"]
},
"machoke": {
"level": 81,
"level": 84,
"moves": ["bodyslam", "earthquake", "submission"],
"exclusiveMoves": ["counter", "rockslide", "rockslide"]
},
@ -369,13 +369,13 @@
"moves": ["agility", "bodyslam", "fireblast", "hyperbeam"]
},
"slowpoke": {
"level": 84,
"level": 83,
"moves": ["blizzard", "psychic", "surf"],
"essentialMoves": ["amnesia", "thunderwave"],
"comboMoves": ["amnesia", "rest", "surf", "thunderwave"]
},
"slowbro": {
"level": 68,
"level": 69,
"moves": ["blizzard", "psychic", "surf"],
"essentialMoves": ["amnesia", "thunderwave"],
"comboMoves": ["amnesia", "rest", "surf", "thunderwave"]
@ -523,7 +523,7 @@
"moves": ["bodyslam", "earthquake", "rockslide", "substitute"]
},
"rhydon": {
"level": 68,
"level": 71,
"moves": ["bodyslam", "earthquake", "rockslide", "substitute"]
},
"chansey": {
@ -574,7 +574,8 @@
},
"mrmime": {
"level": 75,
"moves": ["psychic", "seismictoss", "thunderbolt", "thunderwave"]
"moves": ["psychic", "thunderbolt", "thunderwave"],
"exclusiveMoves": ["counter", "seismictoss", "seismictoss"]
},
"scyther": {
"level": 75,
@ -608,7 +609,8 @@
},
"gyarados": {
"level": 74,
"moves": ["blizzard", "bodyslam", "bodyslam", "hyperbeam", "thunderbolt"],
"moves": ["blizzard", "hyperbeam", "thunderbolt"],
"essentialMoves": ["bodyslam"],
"exclusiveMoves": ["hydropump", "surf", "surf"]
},
"lapras": {
@ -658,8 +660,7 @@
},
"kabuto": {
"level": 88,
"moves": ["blizzard", "bodyslam", "slash"],
"exclusiveMoves": ["hydropump", "surf", "surf"]
"moves": ["blizzard", "bodyslam", "slash", "surf"]
},
"kabutops": {
"level": 75,
@ -693,7 +694,7 @@
"exclusiveMoves": ["doubleedge", "doubleedge", "doubleedge", "reflect"]
},
"dratini": {
"level": 89,
"level": 91,
"moves": ["bodyslam", "hyperbeam", "thunderbolt", "thunderbolt"],
"essentialMoves": ["blizzard", "thunderwave"]
},
@ -704,8 +705,8 @@
},
"dragonite": {
"level": 74,
"moves": ["bodyslam", "hyperbeam", "thunderbolt", "thunderwave", "thunderwave"],
"essentialMoves": ["blizzard"]
"moves": ["bodyslam", "hyperbeam", "thunderbolt"],
"essentialMoves": ["blizzard", "thunderwave"]
},
"mewtwo": {
"level": 60,

View File

@ -103,6 +103,7 @@
]
},
"pikachu": {
"level": 73,
"sets": [
{
"role": "Fast Attacker",
@ -449,7 +450,7 @@
"sets": [
{
"role": "Fast Attacker",
"movepool": ["explosion", "icebeam", "rapidspin", "spikes", "surf", "toxic"]
"movepool": ["explosion", "icebeam", "spikes", "surf"]
},
{
"role": "Generalist",
@ -1359,11 +1360,7 @@
"sets": [
{
"role": "Generalist",
"movepool": ["haze", "hydropump", "rest", "sleeptalk", "sludgebomb", "spikes"]
},
{
"role": "Bulky Setup",
"movepool": ["curse", "hiddenpowerground", "hydropump", "sludgebomb", "spikes"]
"movepool": ["curse", "haze", "hydropump", "sludgebomb", "spikes"]
}
]
},

View File

@ -473,6 +473,7 @@ export class RandomGen2Teams extends RandomGen3Teams {
return {
name: species.baseSpecies,
species: forme,
speciesId: species.id,
level,
moves: shuffledMoves,
ability: 'No Ability',
@ -485,6 +486,33 @@ export class RandomGen2Teams extends RandomGen3Teams {
gender: species.gender ? species.gender : 'M',
};
}
/**
* Checks if the new species is compatible with the other mons currently on the team.
*/
override getPokemonCompatibility(
species: Species,
pokemon: RandomTeamsTypes.RandomSet[],
): boolean {
const spikesSetters = ['cloyster', 'delibird', 'qwilfish', 'forretress', 'smeargle'];
const incompatibilityList = [
// These combinations are prevented to avoid double spikes.
[spikesSetters, spikesSetters],
];
for (const pair of incompatibilityList) {
const monsArrayA = (Array.isArray(pair[0])) ? pair[0] : [pair[0]];
const monsArrayB = (Array.isArray(pair[1])) ? pair[1] : [pair[1]];
if (monsArrayB.includes(species.id)) {
if (pokemon.some(m => monsArrayA.includes(m.speciesId!))) return false;
}
if (monsArrayA.includes(species.id)) {
if (pokemon.some(m => monsArrayB.includes(m.speciesId!))) return false;
}
}
return true;
}
}
export default RandomGen2Teams;

View File

@ -188,9 +188,14 @@
"level": 82,
"sets": [
{
"role": "Wallbreaker",
"role": "Fast Attacker",
"movepool": ["earthquake", "fireblast", "icebeam", "shadowball", "sludgebomb", "substitute", "thunderbolt"],
"abilities": ["Poison Point"]
},
{
"role": "Wallbreaker",
"movepool": ["earthquake", "fireblast", "icebeam", "rockslide", "shadowball", "sludgebomb"],
"abilities": ["Poison Point"]
}
]
},
@ -198,9 +203,14 @@
"level": 82,
"sets": [
{
"role": "Wallbreaker",
"role": "Fast Attacker",
"movepool": ["earthquake", "fireblast", "icebeam", "megahorn", "shadowball", "sludgebomb", "substitute", "thunderbolt"],
"abilities": ["Poison Point"]
},
{
"role": "Wallbreaker",
"movepool": ["earthquake", "fireblast", "icebeam", "megahorn", "rockslide", "shadowball", "sludgebomb"],
"abilities": ["Poison Point"]
}
]
},
@ -342,7 +352,7 @@
]
},
"arcanine": {
"level": 79,
"level": 78,
"sets": [
{
"role": "Bulky Support",
@ -387,7 +397,7 @@
"sets": [
{
"role": "Setup Sweeper",
"movepool": ["calmmind", "encore", "firepunch", "icepunch", "psychic", "recover", "substitute", "thunderpunch"],
"movepool": ["calmmind", "encore", "firepunch", "hiddenpowerdark", "psychic", "recover", "substitute", "thunderpunch"],
"abilities": ["Synchronize"],
"preferredTypes": ["Fire"]
}
@ -474,7 +484,7 @@
},
{
"role": "Setup Sweeper",
"movepool": ["calmmind", "psychic", "rest", "surf"],
"movepool": ["calmmind", "psychic", "surf", "thunderwave"],
"abilities": ["Own Tempo"]
},
{
@ -510,7 +520,7 @@
]
},
"dodrio": {
"level": 77,
"level": 78,
"sets": [
{
"role": "Wallbreaker",
@ -544,13 +554,13 @@
"sets": [
{
"role": "Wallbreaker",
"movepool": ["explosion", "fireblast", "hiddenpowerground", "rest", "sludgebomb", "toxic"],
"movepool": ["explosion", "fireblast", "hiddenpowerground", "sludgebomb", "toxic"],
"abilities": ["Sticky Hold"],
"preferredTypes": ["Ground"]
},
{
"role": "Setup Sweeper",
"movepool": ["curse", "hiddenpowerground", "rest", "sludgebomb"],
"movepool": ["curse", "explosion", "hiddenpowerground", "sludgebomb"],
"abilities": ["Sticky Hold"]
}
]
@ -608,6 +618,11 @@
"role": "Setup Sweeper",
"movepool": ["doubleedge", "hiddenpowerghost", "hiddenpowerground", "surf", "swordsdance"],
"abilities": ["Hyper Cutter"]
},
{
"role": "Bulky Setup",
"movepool": ["doubleedge", "hiddenpowerghost", "mudshot", "swordsdance"],
"abilities": ["Hyper Cutter"]
}
]
},
@ -806,7 +821,7 @@
"sets": [
{
"role": "Setup Sweeper",
"movepool": ["calmmind", "hiddenpowerfire", "icebeam", "lovelykiss", "psychic", "substitute"],
"movepool": ["calmmind", "icebeam", "lovelykiss", "psychic", "substitute"],
"abilities": ["Oblivious"]
}
]
@ -1063,7 +1078,7 @@
"sets": [
{
"role": "Setup Sweeper",
"movepool": ["doubleedge", "dragondance", "earthquake", "healbell", "hiddenpowerflying", "rest", "substitute"],
"movepool": ["doubleedge", "dragondance", "earthquake", "healbell", "hiddenpowerflying", "substitute"],
"abilities": ["Inner Focus"],
"preferredTypes": ["Ground"]
},
@ -1176,7 +1191,7 @@
]
},
"noctowl": {
"level": 92,
"level": 93,
"sets": [
{
"role": "Staller",
@ -1479,7 +1494,7 @@
},
{
"role": "Setup Sweeper",
"movepool": ["calmmind", "psychic", "rest", "surf"],
"movepool": ["calmmind", "psychic", "surf", "thunderwave"],
"abilities": ["Own Tempo"]
},
{
@ -1544,7 +1559,7 @@
},
{
"role": "Wallbreaker",
"movepool": ["doubleedge", "earthquake", "protect", "psychic", "return", "shadowball", "thunderbolt", "thunderwave", "toxic", "wish"],
"movepool": ["doubleedge", "earthquake", "protect", "psychic", "return", "thunderwave", "toxic", "wish"],
"abilities": ["Early Bird"]
}
]
@ -1564,7 +1579,7 @@
"sets": [
{
"role": "Bulky Setup",
"movepool": ["bodyslam", "curse", "earthquake", "rest", "shadowball"],
"movepool": ["bodyslam", "curse", "earthquake", "rest", "shadowball", "sleeptalk"],
"abilities": ["Serene Grace"]
},
{
@ -1753,7 +1768,7 @@
"sets": [
{
"role": "Bulky Attacker",
"movepool": ["calmmind", "icebeam", "recover", "surf", "toxic"],
"movepool": ["calmmind", "explosion", "icebeam", "recover", "surf", "toxic"],
"abilities": ["Natural Cure"]
}
]
@ -2482,11 +2497,6 @@
"role": "Bulky Support",
"movepool": ["encore", "moonlight", "seismictoss", "thunderwave", "toxic"],
"abilities": ["Oblivious"]
},
{
"role": "Generalist",
"movepool": ["batonpass", "encore", "seismictoss", "substitute", "thunderwave", "toxic"],
"abilities": ["Oblivious"]
}
]
},
@ -2561,7 +2571,7 @@
"sets": [
{
"role": "Bulky Attacker",
"movepool": ["explosion", "fireblast", "flamethrower", "hiddenpowergrass", "rest", "toxic"],
"movepool": ["explosion", "fireblast", "flamethrower", "hiddenpowergrass", "toxic"],
"abilities": ["White Smoke"]
}
]
@ -2571,7 +2581,7 @@
"sets": [
{
"role": "Setup Sweeper",
"movepool": ["calmmind", "firepunch", "psychic", "substitute", "thunderpunch"],
"movepool": ["calmmind", "firepunch", "hiddenpowerdark", "psychic", "substitute"],
"abilities": ["Thick Fat"],
"preferredTypes": ["Fire"]
}
@ -2602,18 +2612,18 @@
},
{
"role": "Staller",
"movepool": ["dragonclaw", "earthquake", "fireblast", "protect", "toxic"],
"movepool": ["dragonclaw", "earthquake", "fireblast", "protect", "rockslide", "toxic"],
"abilities": ["Levitate"]
},
{
"role": "Bulky Attacker",
"role": "Staller",
"movepool": ["dragonclaw", "earthquake", "fireblast", "rockslide", "substitute", "toxic"],
"abilities": ["Levitate"]
}
]
},
"cacturne": {
"level": 95,
"level": 96,
"sets": [
{
"role": "Staller",
@ -2690,7 +2700,7 @@
},
{
"role": "Wallbreaker",
"movepool": ["earthquake", "explosion", "overheat", "rockslide", "shadowball"],
"movepool": ["earthquake", "explosion", "rockslide", "shadowball"],
"abilities": ["Levitate"],
"preferredTypes": ["Ground"]
}
@ -2781,7 +2791,7 @@
]
},
"kecleon": {
"level": 91,
"level": 92,
"sets": [
{
"role": "Wallbreaker",
@ -3024,7 +3034,7 @@
]
},
"latios": {
"level": 67,
"level": 66,
"sets": [
{
"role": "Bulky Setup",
@ -3053,7 +3063,12 @@
"sets": [
{
"role": "Wallbreaker",
"movepool": ["earthquake", "hiddenpowerbug", "overheat", "rockslide", "substitute", "swordsdance", "thunderwave"],
"movepool": ["earthquake", "overheat", "rockslide", "thunderwave"],
"abilities": ["Drought"]
},
{
"role": "Setup Sweeper",
"movepool": ["earthquake", "hiddenpowerbug", "rockslide", "substitute", "swordsdance", "thunderwave"],
"abilities": ["Drought"],
"preferredTypes": ["Rock"]
}
@ -3086,9 +3101,8 @@
},
{
"role": "Setup Sweeper",
"movepool": ["calmmind", "firepunch", "icepunch", "psychic", "substitute", "thunderbolt"],
"abilities": ["Serene Grace"],
"preferredTypes": ["Fire"]
"movepool": ["calmmind", "firepunch", "icepunch", "psychic", "thunderbolt"],
"abilities": ["Serene Grace"]
}
]
},
@ -3097,7 +3111,7 @@
"sets": [
{
"role": "Fast Attacker",
"movepool": ["extremespeed", "firepunch", "icebeam", "psychoboost", "shadowball", "superpower"],
"movepool": ["extremespeed", "icebeam", "psychoboost", "shadowball", "superpower"],
"abilities": ["Pressure"],
"preferredTypes": ["Fighting", "Ghost"]
}
@ -3108,7 +3122,7 @@
"sets": [
{
"role": "Fast Attacker",
"movepool": ["extremespeed", "firepunch", "icebeam", "psychoboost", "shadowball", "superpower"],
"movepool": ["extremespeed", "icebeam", "psychoboost", "shadowball", "superpower"],
"abilities": ["Pressure"],
"preferredTypes": ["Fighting", "Ghost"]
}

View File

@ -467,16 +467,10 @@ export class RandomGen3Teams extends RandomGen4Teams {
if (species.id === 'marowak') return 'Thick Club';
if (species.id === 'pikachu') return 'Light Ball';
if (species.id === 'shedinja') return 'Lum Berry';
if (species.id === 'shuckle') return 'Leftovers';
if (species.id === 'unown') return counter.get('Physical') ? 'Choice Band' : 'Twisted Spoon';
if (species.id === 'deoxys' || species.id === 'deoxysattack') return 'White Herb';
if (moves.has('trick')) return 'Choice Band';
if (
moves.has('rest') && !moves.has('sleeptalk') &&
// Altaria wants Chesto Berry on Dragon Dance + Rest
(moves.has('dragondance') || !['Early Bird', 'Natural Cure', 'Shed Skin'].includes(ability))
) return 'Chesto Berry';
// Medium priority items
if (counter.get('Physical') >= 4) return 'Choice Band';
@ -624,6 +618,7 @@ export class RandomGen3Teams extends RandomGen4Teams {
return {
name: species.baseSpecies,
species: forme,
speciesId: species.id,
gender: species.gender,
shiny: this.randomChance(1, 1024),
level,
@ -636,6 +631,35 @@ export class RandomGen3Teams extends RandomGen4Teams {
};
}
/**
* Checks if the new species is compatible with the other mons currently on the team.
*/
override getPokemonCompatibility(
species: Species,
pokemon: RandomTeamsTypes.RandomSet[],
): boolean {
const incompatibilityList = [
// These Pokemon are incompatible because the presence of one actively harms the other.
// Prevent Shedinja + Tyranitar
['shedinja', 'tyranitar'],
// Prevent Reversal/Flail users + Tyranitar
[['dodrio', 'raticate', 'primeape', 'hitmonlee', 'furret', 'yanma', 'heracross', 'blaziken', 'medicham'], 'tyranitar'],
];
for (const pair of incompatibilityList) {
const monsArrayA = (Array.isArray(pair[0])) ? pair[0] : [pair[0]];
const monsArrayB = (Array.isArray(pair[1])) ? pair[1] : [pair[1]];
if (monsArrayB.includes(species.id)) {
if (pokemon.some(m => monsArrayA.includes(m.speciesId!))) return false;
}
if (monsArrayA.includes(species.id)) {
if (pokemon.some(m => monsArrayB.includes(m.speciesId!))) return false;
}
}
return true;
}
override randomTeam() {
this.enforceNoDirectCustomBanlistChanges();
@ -665,9 +689,6 @@ export class RandomGen3Teams extends RandomGen4Teams {
// Limit to one of each species (Species Clause)
if (baseFormes[species.baseSpecies]) continue;
// Prevent Shedinja from generating after Tyranitar
if (species.name === 'Shedinja' && teamDetails.sand) continue;
// Limit to one Wobbuffet per battle (not just per team)
if (species.name === 'Wobbuffet' && this.battleHasWobbuffet) continue;
// Limit to one Ditto per battle in Gen 2
@ -713,6 +734,9 @@ export class RandomGen3Teams extends RandomGen4Teams {
if (!this.adjustLevel && (this.getLevel(species) === 100) && numMaxLevelPokemon >= limitFactor) {
continue;
}
// Check compatibility with team
if (!this.getPokemonCompatibility(species, pokemon)) continue;
}
// Okay, the set passes, add it to our team

View File

@ -137,7 +137,7 @@
]
},
"sandslash": {
"level": 89,
"level": 88,
"sets": [
{
"role": "Spinner",
@ -173,7 +173,7 @@
]
},
"clefable": {
"level": 84,
"level": 83,
"sets": [
{
"role": "Bulky Support",
@ -234,7 +234,7 @@
]
},
"parasect": {
"level": 98,
"level": 99,
"sets": [
{
"role": "Bulky Support",
@ -382,7 +382,8 @@
{
"role": "Bulky Support",
"movepool": ["haze", "hydropump", "icebeam", "rapidspin", "sludgebomb", "surf", "toxicspikes"],
"abilities": ["Clear Body", "Liquid Ooze"]
"abilities": ["Clear Body", "Liquid Ooze"],
"preferredTypes": ["Poison"]
}
]
},
@ -487,6 +488,11 @@
"role": "Bulky Support",
"movepool": ["explosion", "iceshard", "rapidspin", "rockblast", "spikes", "surf", "toxicspikes"],
"abilities": ["Shell Armor", "Skill Link"]
},
{
"role": "Bulky Support",
"movepool": ["explosion", "icebeam", "iceshard", "rapidspin", "spikes", "surf", "toxicspikes"],
"abilities": ["Shell Armor"]
}
]
},
@ -596,7 +602,7 @@
},
{
"role": "Bulky Attacker",
"movepool": ["bulkup", "closecombat", "drainpunch", "icepunch", "machpunch", "stoneedge"],
"movepool": ["bulkup", "closecombat", "icepunch", "machpunch", "stoneedge"],
"abilities": ["Iron Fist"]
}
]
@ -812,10 +818,9 @@
"abilities": ["Swift Swim"]
},
{
"role": "Bulky Support",
"movepool": ["earthpower", "icebeam", "spikes", "stealthrock", "surf", "toxicspikes"],
"abilities": ["Shell Armor", "Swift Swim"],
"preferredTypes": ["Ice"]
"role": "Bulky Attacker",
"movepool": ["icebeam", "spikes", "stealthrock", "surf", "toxicspikes"],
"abilities": ["Shell Armor", "Swift Swim"]
}
]
},
@ -851,7 +856,7 @@
]
},
"snorlax": {
"level": 77,
"level": 78,
"sets": [
{
"role": "Bulky Attacker",
@ -872,7 +877,7 @@
]
},
"articuno": {
"level": 81,
"level": 82,
"sets": [
{
"role": "Staller",
@ -897,7 +902,7 @@
]
},
"moltres": {
"level": 81,
"level": 82,
"sets": [
{
"role": "Bulky Attacker",
@ -927,7 +932,7 @@
"sets": [
{
"role": "Setup Sweeper",
"movepool": ["aurasphere", "calmmind", "fireblast", "psychic", "recover", "shadowball"],
"movepool": ["aurasphere", "calmmind", "fireblast", "psychic", "recover", "signalbeam"],
"abilities": ["Pressure"]
}
]
@ -1159,6 +1164,11 @@
"role": "Wallbreaker",
"movepool": ["earthpower", "hiddenpowerfire", "hiddenpowerice", "hiddenpowerrock", "leafstorm", "sludgebomb"],
"abilities": ["Chlorophyll"]
},
{
"role": "Setup Sweeper",
"movepool": ["earthpower", "hiddenpowerfire", "solarbeam", "sunnyday"],
"abilities": ["Chlorophyll"]
}
]
},
@ -1171,7 +1181,6 @@
"abilities": ["Water Absorb"]
},
{
"role": "Bulky Attacker",
"movepool": ["earthquake", "recover", "toxic", "waterfall"],
"abilities": ["Water Absorb"]
@ -1236,7 +1245,7 @@
]
},
"wobbuffet": {
"level": 86,
"level": 87,
"sets": [
{
"role": "Bulky Support",
@ -1299,9 +1308,14 @@
"granbull": {
"level": 88,
"sets": [
{
"role": "Bulky Support",
"movepool": ["earthquake", "healbell", "return", "thunderwave"],
"abilities": ["Intimidate"]
},
{
"role": "Bulky Attacker",
"movepool": ["closecombat", "crunch", "healbell", "return", "thunderwave"],
"movepool": ["closecombat", "crunch", "return", "thunderwave"],
"abilities": ["Intimidate"]
}
]
@ -1311,7 +1325,7 @@
"sets": [
{
"role": "Fast Support",
"movepool": ["destinybond", "explosion", "spikes", "thunderwave", "toxicspikes", "waterfall"],
"movepool": ["destinybond", "explosion", "poisonjab", "spikes", "thunderwave", "toxicspikes", "waterfall"],
"abilities": ["Poison Point", "Swift Swim"]
}
]
@ -1342,7 +1356,7 @@
]
},
"heracross": {
"level": 80,
"level": 79,
"sets": [
{
"role": "Wallbreaker",
@ -1352,7 +1366,8 @@
{
"role": "Fast Attacker",
"movepool": ["closecombat", "earthquake", "megahorn", "nightslash", "stoneedge", "swordsdance"],
"abilities": ["Guts"]
"abilities": ["Guts"],
"preferredTypes": ["Rock"]
}
]
},
@ -1475,16 +1490,10 @@
"level": 84,
"sets": [
{
"role": "Spinner",
"role": "Bulky Support",
"movepool": ["earthquake", "iceshard", "rapidspin", "stealthrock", "stoneedge", "toxic"],
"abilities": ["Sturdy"],
"preferredTypes": ["Rock"]
},
{
"role": "Bulky Attacker",
"movepool": ["earthquake", "gunkshot", "iceshard", "stealthrock", "stoneedge"],
"abilities": ["Sturdy"],
"preferredTypes": ["Rock"]
}
]
},
@ -1503,7 +1512,7 @@
"sets": [
{
"role": "Wallbreaker",
"movepool": ["earthquake", "hypnosis", "megahorn", "return", "suckerpunch", "thunderbolt"],
"movepool": ["doubleedge", "earthquake", "hypnosis", "megahorn", "return", "suckerpunch", "thunderbolt", "thunderwave"],
"abilities": ["Intimidate"],
"preferredTypes": ["Ground"]
}
@ -1631,7 +1640,7 @@
]
},
"hooh": {
"level": 72,
"level": 73,
"sets": [
{
"role": "Bulky Attacker",
@ -1680,13 +1689,13 @@
"level": 84,
"sets": [
{
"role": "Fast Attacker",
"movepool": ["agility", "fireblast", "stoneedge", "superpower", "thunderpunch", "vacuumwave"],
"role": "Wallbreaker",
"movepool": ["agility", "earthquake", "fireblast", "stoneedge", "superpower", "vacuumwave"],
"abilities": ["Blaze"]
},
{
"role": "Wallbreaker",
"movepool": ["flareblitz", "stoneedge", "superpower", "swordsdance", "thunderpunch"],
"role": "Fast Attacker",
"movepool": ["earthquake", "flareblitz", "stoneedge", "superpower", "swordsdance"],
"abilities": ["Blaze"]
}
]
@ -2114,9 +2123,14 @@
"sets": [
{
"role": "Fast Attacker",
"movepool": ["hiddenpowergrass", "hydropump", "icebeam", "selfdestruct", "waterspout"],
"movepool": ["hydropump", "icebeam", "selfdestruct", "waterspout"],
"abilities": ["Water Veil"],
"preferredTypes": ["Ice"]
},
{
"role": "Bulky Attacker",
"movepool": ["icebeam", "selfdestruct", "surf", "toxic"],
"abilities": ["Water Veil"]
}
]
},
@ -2136,7 +2150,7 @@
]
},
"torkoal": {
"level": 88,
"level": 87,
"sets": [
{
"role": "Bulky Support",
@ -2355,7 +2369,7 @@
]
},
"kecleon": {
"level": 91,
"level": 92,
"sets": [
{
"role": "Bulky Support",
@ -2370,7 +2384,7 @@
{
"role": "Wallbreaker",
"movepool": ["hiddenpowerfighting", "shadowclaw", "shadowsneak", "thunderwave", "willowisp"],
"abilities": ["Frisk", "Insomnia"]
"abilities": ["Insomnia"]
}
]
},
@ -2525,7 +2539,7 @@
"sets": [
{
"role": "Bulky Attacker",
"movepool": ["earthquake", "explosion", "rest", "stealthrock", "stoneedge", "thunderwave", "toxic"],
"movepool": ["earthquake", "explosion", "stealthrock", "stoneedge", "thunderwave", "toxic"],
"abilities": ["Clear Body"]
},
{
@ -2654,7 +2668,7 @@
]
},
"jirachi": {
"level": 75,
"level": 74,
"sets": [
{
"role": "Bulky Support",
@ -2685,7 +2699,7 @@
]
},
"deoxysattack": {
"level": 72,
"level": 71,
"sets": [
{
"role": "Wallbreaker",
@ -2710,7 +2724,7 @@
]
},
"deoxysspeed": {
"level": 79,
"level": 80,
"sets": [
{
"role": "Fast Support",
@ -2930,7 +2944,7 @@
]
},
"floatzel": {
"level": 84,
"level": 83,
"sets": [
{
"role": "Fast Attacker",
@ -2946,7 +2960,7 @@
]
},
"cherrim": {
"level": 96,
"level": 95,
"sets": [
{
"role": "Staller",
@ -3013,9 +3027,14 @@
"movepool": ["destinybond", "hiddenpowerfighting", "painsplit", "shadowball", "substitute", "taunt", "willowisp"],
"abilities": ["Levitate"]
},
{
"role": "Setup Sweeper",
"movepool": ["hiddenpowerfighting", "nastyplot", "shadowball", "substitute", "thunderbolt"],
"abilities": ["Levitate"]
},
{
"role": "Wallbreaker",
"movepool": ["hiddenpowerfighting", "nastyplot", "shadowball", "thunderbolt", "trick"],
"movepool": ["hiddenpowerfighting", "shadowball", "thunderbolt", "trick"],
"abilities": ["Levitate"]
}
]
@ -3127,7 +3146,7 @@
]
},
"hippowdon": {
"level": 80,
"level": 79,
"sets": [
{
"role": "Bulky Support",
@ -3496,7 +3515,7 @@
]
},
"rotomfan": {
"level": 79,
"level": 78,
"sets": [
{
"role": "Bulky Attacker",
@ -3616,7 +3635,7 @@
]
},
"regigigas": {
"level": 82,
"level": 83,
"sets": [
{
"role": "Staller",
@ -3686,7 +3705,7 @@
]
},
"darkrai": {
"level": 69,
"level": 68,
"sets": [
{
"role": "Setup Sweeper",

View File

@ -210,22 +210,11 @@ export class RandomGen4Teams extends RandomGen5Teams {
for (const pair of incompatiblePairs) this.incompatibleMoves(moves, movePool, pair[0], pair[1]);
const statusInflictingMoves = ['stunspore', 'thunderwave', 'toxic', 'willowisp', 'yawn'];
const statusInflictingMoves = ['hypnosis', 'stunspore', 'thunderwave', 'toxic', 'willowisp', 'yawn'];
if (role !== 'Staller') {
this.incompatibleMoves(moves, movePool, statusInflictingMoves, statusInflictingMoves);
}
// Cull filler moves for otherwise fixed set Stealth Rock users
if (!teamDetails.stealthRock) {
if (species.id === 'registeel' && role === 'Staller') {
if (movePool.includes('thunderwave')) this.fastPop(movePool, movePool.indexOf('thunderwave'));
if (moves.size + movePool.length <= this.maxMoveCount) return;
}
if (species.id === 'wormadamtrash' && role === 'Staller') {
if (movePool.includes('suckerpunch')) this.fastPop(movePool, movePool.indexOf('suckerpunch'));
if (moves.size + movePool.length <= this.maxMoveCount) return;
}
}
if (species.id === 'bastiodon') {
// Enforces Toxic too, for good measure.
this.incompatibleMoves(moves, movePool, ['metalburst', 'protect', 'roar'], ['metalburst', 'protect']);
@ -777,6 +766,7 @@ export class RandomGen4Teams extends RandomGen5Teams {
return {
name: species.baseSpecies,
species: forme,
speciesId: species.id,
gender: species.gender,
shiny: this.randomChance(1, 1024),
level,
@ -788,6 +778,35 @@ export class RandomGen4Teams extends RandomGen5Teams {
role,
};
}
/**
* Checks if the new species is compatible with the other mons currently on the team.
*/
override getPokemonCompatibility(
species: Species,
pokemon: RandomTeamsTypes.RandomSet[],
): boolean {
const incompatibilityList = [
// These Pokemon are incompatible because the presence of one actively harms the other.
// Prevent Dry Skin + sun setting ability
[['parasect', 'toxicroak'], 'groudon'],
// Prevent Shedinja + sand/hail setting ability
['shedinja', ['tyranitar', 'hippowdon', 'abomasnow']],
];
for (const pair of incompatibilityList) {
const monsArrayA = (Array.isArray(pair[0])) ? pair[0] : [pair[0]];
const monsArrayB = (Array.isArray(pair[1])) ? pair[1] : [pair[1]];
if (monsArrayB.includes(species.id)) {
if (pokemon.some(m => monsArrayA.includes(m.speciesId!))) return false;
}
if (monsArrayA.includes(species.id)) {
if (pokemon.some(m => monsArrayB.includes(m.speciesId!))) return false;
}
}
return true;
}
}
export default RandomGen4Teams;

View File

@ -1,6 +1,6 @@
{
"venusaur": {
"level": 84,
"level": 83,
"sets": [
{
"role": "Staller",
@ -321,9 +321,15 @@
"golduck": {
"level": 88,
"sets": [
{
"role": "Bulky Setup",
"movepool": ["calmmind", "encore", "focusblast", "icebeam", "scald", "substitute"],
"abilities": ["Cloud Nine", "Swift Swim"],
"preferredTypes": ["Ice"]
},
{
"role": "Fast Attacker",
"movepool": ["calmmind", "encore", "focusblast", "hydropump", "icebeam", "scald"],
"movepool": ["calmmind", "encore", "focusblast", "hydropump", "icebeam"],
"abilities": ["Cloud Nine", "Swift Swim"],
"preferredTypes": ["Ice"]
}
@ -418,7 +424,8 @@
{
"role": "Bulky Support",
"movepool": ["haze", "icebeam", "rapidspin", "scald", "sludgebomb", "toxicspikes"],
"abilities": ["Clear Body", "Liquid Ooze"]
"abilities": ["Clear Body", "Liquid Ooze"],
"preferredTypes": ["Poison"]
}
]
},
@ -451,20 +458,15 @@
"level": 83,
"sets": [
{
"role": "Bulky Support",
"role": "Bulky Attacker",
"movepool": ["fireblast", "icebeam", "psyshock", "scald", "slackoff", "thunderwave", "toxic"],
"abilities": ["Regenerator"]
"abilities": ["Regenerator"],
"preferredTypes": ["Psychic"]
},
{
"role": "Staller",
"movepool": ["calmmind", "psyshock", "scald", "slackoff"],
"abilities": ["Regenerator"]
},
{
"role": "Wallbreaker",
"movepool": ["fireblast", "icebeam", "psyshock", "surf", "trick", "trickroom"],
"abilities": ["Regenerator"],
"preferredTypes": ["Psychic"]
}
]
},
@ -515,7 +517,7 @@
]
},
"cloyster": {
"level": 78,
"level": 79,
"sets": [
{
"role": "Setup Sweeper",
@ -529,7 +531,7 @@
"sets": [
{
"role": "Fast Attacker",
"movepool": ["focusblast", "painsplit", "shadowball", "sludgewave", "substitute", "trick", "willowisp"],
"movepool": ["destinybond", "focusblast", "painsplit", "shadowball", "sludgewave", "substitute", "trick", "willowisp"],
"abilities": ["Levitate"],
"preferredTypes": ["Fighting"]
}
@ -644,7 +646,7 @@
]
},
"rhydon": {
"level": 83,
"level": 82,
"sets": [
{
"role": "Bulky Attacker",
@ -913,7 +915,7 @@
]
},
"articuno": {
"level": 84,
"level": 83,
"sets": [
{
"role": "Staller",
@ -983,7 +985,7 @@
"sets": [
{
"role": "Fast Attacker",
"movepool": ["aurasphere", "calmmind", "fireblast", "psystrike", "recover", "shadowball"],
"movepool": ["aurasphere", "calmmind", "fireblast", "psystrike", "recover", "signalbeam"],
"abilities": ["Unnerve"]
}
]
@ -1189,7 +1191,7 @@
]
},
"jumpluff": {
"level": 82,
"level": 81,
"sets": [
{
"role": "Fast Support",
@ -1267,13 +1269,8 @@
"level": 83,
"sets": [
{
"role": "Bulky Support",
"role": "Bulky Attacker",
"movepool": ["fireblast", "icebeam", "psyshock", "scald", "slackoff", "thunderwave", "toxic"],
"abilities": ["Regenerator"]
},
{
"role": "Wallbreaker",
"movepool": ["fireblast", "icebeam", "psyshock", "surf", "trick", "trickroom"],
"abilities": ["Regenerator"],
"preferredTypes": ["Psychic"]
}
@ -1310,7 +1307,7 @@
]
},
"forretress": {
"level": 78,
"level": 79,
"sets": [
{
"role": "Bulky Support",
@ -1373,9 +1370,14 @@
"granbull": {
"level": 90,
"sets": [
{
"role": "Bulky Support",
"movepool": ["earthquake", "healbell", "return", "thunderwave"],
"abilities": ["Intimidate"]
},
{
"role": "Bulky Attacker",
"movepool": ["closecombat", "crunch", "healbell", "return", "thunderwave"],
"movepool": ["closecombat", "crunch", "return", "thunderwave"],
"abilities": ["Intimidate"]
}
]
@ -1385,7 +1387,7 @@
"sets": [
{
"role": "Fast Support",
"movepool": ["destinybond", "spikes", "taunt", "thunderwave", "toxicspikes", "waterfall"],
"movepool": ["destinybond", "poisonjab", "spikes", "taunt", "thunderwave", "toxicspikes", "waterfall"],
"abilities": ["Intimidate"]
}
]
@ -1432,7 +1434,7 @@
]
},
"ursaring": {
"level": 85,
"level": 84,
"sets": [
{
"role": "Wallbreaker",
@ -1467,7 +1469,7 @@
]
},
"octillery": {
"level": 91,
"level": 92,
"sets": [
{
"role": "Bulky Attacker",
@ -1545,16 +1547,10 @@
"level": 82,
"sets": [
{
"role": "Spinner",
"role": "Bulky Support",
"movepool": ["earthquake", "iceshard", "rapidspin", "stealthrock", "stoneedge", "toxic"],
"abilities": ["Sturdy"],
"preferredTypes": ["Rock"]
},
{
"role": "Bulky Attacker",
"movepool": ["earthquake", "gunkshot", "iceshard", "stealthrock", "stoneedge"],
"abilities": ["Sturdy"],
"preferredTypes": ["Rock"]
}
]
},
@ -1573,7 +1569,7 @@
"sets": [
{
"role": "Wallbreaker",
"movepool": ["doubleedge", "earthquake", "hypnosis", "jumpkick", "megahorn", "suckerpunch", "thunderwave"],
"movepool": ["doubleedge", "earthquake", "hypnosis", "jumpkick", "megahorn", "return", "suckerpunch", "thunderwave"],
"abilities": ["Intimidate"],
"preferredTypes": ["Ground"]
}
@ -1711,7 +1707,7 @@
]
},
"celebi": {
"level": 81,
"level": 80,
"sets": [
{
"role": "Fast Attacker",
@ -2187,7 +2183,7 @@
]
},
"grumpig": {
"level": 92,
"level": 91,
"sets": [
{
"role": "Bulky Attacker",
@ -2388,7 +2384,7 @@
]
},
"castform": {
"level": 97,
"level": 98,
"sets": [
{
"role": "Bulky Attacker",
@ -2398,7 +2394,7 @@
]
},
"kecleon": {
"level": 94,
"level": 95,
"sets": [
{
"role": "Bulky Support",
@ -2413,7 +2409,7 @@
{
"role": "Wallbreaker",
"movepool": ["hiddenpowerfighting", "shadowclaw", "shadowsneak", "thunderwave", "willowisp"],
"abilities": ["Cursed Body", "Frisk", "Insomnia"]
"abilities": ["Insomnia"]
}
]
},
@ -2542,7 +2538,7 @@
]
},
"salamence": {
"level": 75,
"level": 74,
"sets": [
{
"role": "Setup Sweeper",
@ -2702,7 +2698,7 @@
]
},
"jirachi": {
"level": 75,
"level": 74,
"sets": [
{
"role": "Bulky Support",
@ -2777,7 +2773,7 @@
]
},
"infernape": {
"level": 79,
"level": 78,
"sets": [
{
"role": "Wallbreaker",
@ -2848,7 +2844,7 @@
]
},
"luxray": {
"level": 89,
"level": 88,
"sets": [
{
"role": "Wallbreaker",
@ -2934,7 +2930,7 @@
]
},
"wormadamtrash": {
"level": 88,
"level": 87,
"sets": [
{
"role": "Staller",
@ -3059,9 +3055,14 @@
"abilities": ["Levitate"]
},
{
"role": "Wallbreaker",
"movepool": ["hiddenpowerfighting", "nastyplot", "shadowball", "thunderbolt", "trick"],
"role": "Setup Sweeper",
"movepool": ["hiddenpowerfighting", "nastyplot", "shadowball", "substitute", "thunderbolt"],
"abilities": ["Levitate"]
},
{
"role": "Wallbreaker",
"movepool": ["hiddenpowerfighting", "shadowball", "thunderbolt", "trick"],
"abilities": ["Levitate"]
}
]
},
@ -3268,7 +3269,7 @@
{
"role": "Fast Attacker",
"movepool": ["flashcannon", "hiddenpowerfire", "hiddenpowerground", "hiddenpowerice", "thunderbolt", "voltswitch"],
"abilities": ["Magnet Pull"]
"abilities": ["Analytic", "Magnet Pull"]
},
{
"role": "Staller",
@ -3308,12 +3309,12 @@
"sets": [
{
"role": "Bulky Attacker",
"movepool": ["earthquake", "hiddenpowerfire", "leafstorm", "leechseed", "morningsun", "powerwhip", "rockslide", "sleeppowder"],
"movepool": ["earthquake", "gigadrain", "hiddenpowerfire", "leafstorm", "leechseed", "morningsun", "rockslide", "sleeppowder"],
"abilities": ["Regenerator"]
},
{
"role": "Bulky Support",
"movepool": ["earthquake", "hiddenpowerfire", "leafstorm", "powerwhip", "rockslide", "sleeppowder"],
"movepool": ["earthquake", "gigadrain", "hiddenpowerfire", "leafstorm", "rockslide", "sleeppowder"],
"abilities": ["Regenerator"]
}
]
@ -3426,12 +3427,7 @@
"sets": [
{
"role": "Wallbreaker",
"movepool": ["earthquake", "iceshard", "iciclecrash", "stealthrock"],
"abilities": ["Thick Fat"]
},
{
"role": "Fast Attacker",
"movepool": ["earthquake", "iceshard", "iciclecrash", "stoneedge", "superpower"],
"movepool": ["earthquake", "iceshard", "iciclecrash", "stealthrock", "stoneedge", "superpower"],
"abilities": ["Thick Fat"]
}
]
@ -3513,7 +3509,7 @@
]
},
"rotomwash": {
"level": 79,
"level": 80,
"sets": [
{
"role": "Bulky Attacker",
@ -3563,7 +3559,7 @@
]
},
"mesprit": {
"level": 82,
"level": 83,
"sets": [
{
"role": "Fast Attacker",
@ -3662,7 +3658,7 @@
]
},
"giratinaorigin": {
"level": 73,
"level": 72,
"sets": [
{
"role": "Fast Attacker",
@ -3976,7 +3972,7 @@
]
},
"serperior": {
"level": 85,
"level": 86,
"sets": [
{
"role": "Fast Attacker",
@ -4014,14 +4010,19 @@
"level": 86,
"sets": [
{
"role": "Fast Attacker",
"role": "Wallbreaker",
"movepool": ["aquajet", "grassknot", "hydropump", "icebeam", "megahorn", "superpower"],
"abilities": ["Torrent"]
},
{
"role": "Wallbreaker",
"role": "Setup Sweeper",
"movepool": ["aquajet", "megahorn", "superpower", "swordsdance", "waterfall"],
"abilities": ["Torrent"]
},
{
"role": "Fast Attacker",
"movepool": ["grassknot", "hydropump", "icebeam", "scald"],
"abilities": ["Torrent"]
}
]
},
@ -4274,7 +4275,7 @@
},
{
"role": "Staller",
"movepool": ["hurricane", "leechseed", "protect", "substitute"],
"movepool": ["encore", "hurricane", "leechseed", "substitute"],
"abilities": ["Prankster"]
}
]
@ -4353,12 +4354,12 @@
"level": 82,
"sets": [
{
"role": "Setup Sweeper",
"movepool": ["crunch", "dragondance", "highjumpkick", "stoneedge", "zenheadbutt"],
"abilities": ["Intimidate", "Moxie"]
"role": "Bulky Setup",
"movepool": ["crunch", "dragondance", "drainpunch", "stoneedge", "zenheadbutt"],
"abilities": ["Intimidate"]
},
{
"role": "Bulky Setup",
"role": "Bulky Attacker",
"movepool": ["bulkup", "crunch", "drainpunch", "rest"],
"abilities": ["Shed Skin"]
}
@ -4422,7 +4423,7 @@
]
},
"garbodor": {
"level": 89,
"level": 90,
"sets": [
{
"role": "Bulky Attacker",
@ -4466,7 +4467,7 @@
"sets": [
{
"role": "Bulky Setup",
"movepool": ["calmmind", "focusblast", "psychic", "psyshock", "recover", "signalbeam"],
"movepool": ["calmmind", "focusblast", "psychic", "psyshock", "recover"],
"abilities": ["Magic Guard"]
}
]
@ -4568,9 +4569,13 @@
"sets": [
{
"role": "Wallbreaker",
"movepool": ["bugbuzz", "gigadrain", "hiddenpowerice", "thunder", "voltswitch"],
"abilities": ["Compound Eyes"],
"preferredTypes": ["Bug"]
"movepool": ["bugbuzz", "hiddenpowerice", "thunder", "voltswitch"],
"abilities": ["Compound Eyes"]
},
{
"role": "Wallbreaker",
"movepool": ["bugbuzz", "gigadrain", "thunder", "voltswitch"],
"abilities": ["Compound Eyes"]
}
]
},
@ -4616,7 +4621,7 @@
]
},
"beheeyem": {
"level": 90,
"level": 89,
"sets": [
{
"role": "Wallbreaker",
@ -4626,7 +4631,7 @@
]
},
"chandelure": {
"level": 80,
"level": 79,
"sets": [
{
"role": "Fast Attacker",
@ -4930,7 +4935,7 @@
]
},
"zekrom": {
"level": 75,
"level": 74,
"sets": [
{
"role": "Bulky Attacker",
@ -4945,7 +4950,7 @@
]
},
"landorus": {
"level": 75,
"level": 74,
"sets": [
{
"role": "Wallbreaker",
@ -4956,7 +4961,8 @@
{
"role": "Setup Sweeper",
"movepool": ["calmmind", "earthpower", "focusblast", "psychic", "rockpolish", "sludgewave"],
"abilities": ["Sheer Force"]
"abilities": ["Sheer Force"],
"preferredTypes": ["Poison"]
}
]
},

View File

@ -236,15 +236,8 @@ export class RandomGen5Teams extends RandomGen6Teams {
if (abilities.includes('Guts')) this.incompatibleMoves(moves, movePool, 'protect', 'swordsdance');
// Cull filler moves for otherwise fixed set Stealth Rock users
if (!teamDetails.stealthRock) {
if (species.id === 'registeel' && role === 'Staller') {
if (movePool.includes('thunderwave')) this.fastPop(movePool, movePool.indexOf('thunderwave'));
if (moves.size + movePool.length <= this.maxMoveCount) return;
}
if (species.baseSpecies === 'Wormadam' && role === 'Staller') {
if (movePool.includes('suckerpunch')) this.fastPop(movePool, movePool.indexOf('suckerpunch'));
if (moves.size + movePool.length <= this.maxMoveCount) return;
}
if (species.id === 'mamoswine') {
this.incompatibleMoves(moves, movePool, ['stealthrock', 'stoneedge'], ['stoneedge', 'superpower']);
}
}
@ -837,6 +830,7 @@ export class RandomGen5Teams extends RandomGen6Teams {
return {
name: species.baseSpecies,
species: forme,
speciesId: species.id,
gender: species.gender,
shiny: this.randomChance(1, 1024),
level,
@ -849,6 +843,39 @@ export class RandomGen5Teams extends RandomGen6Teams {
};
}
/**
* Checks if the new species is compatible with the other mons currently on the team.
*/
override getPokemonCompatibility(
species: Species,
pokemon: RandomTeamsTypes.RandomSet[],
): boolean {
const incompatibilityList = [
// These Pokemon with support roles are considered too similar to each other.
['blissey', 'chansey'],
['illumise', 'volbeat'],
// These Pokemon are incompatible because the presence of one actively harms the other.
// Prevent Dry Skin + sun setting ability
[['parasect', 'jynx', 'toxicroak'], ['ninetales', 'groudon']],
// Prevent Shedinja + sand/hail setting ability
['shedinja', ['tyranitar', 'hippowdon', 'abomasnow']],
];
for (const pair of incompatibilityList) {
const monsArrayA = (Array.isArray(pair[0])) ? pair[0] : [pair[0]];
const monsArrayB = (Array.isArray(pair[1])) ? pair[1] : [pair[1]];
if (monsArrayB.includes(species.id)) {
if (pokemon.some(m => monsArrayA.includes(m.speciesId!))) return false;
}
if (monsArrayA.includes(species.id)) {
if (pokemon.some(m => monsArrayB.includes(m.speciesId!))) return false;
}
}
return true;
}
override randomTeam() {
this.enforceNoDirectCustomBanlistChanges();
@ -881,9 +908,6 @@ export class RandomGen5Teams extends RandomGen6Teams {
// Illusion shouldn't be in the last slot
if (species.name === 'Zoroark' && pokemon.length >= (this.maxTeamSize - 1)) continue;
// Prevent Shedinja from generating after Sandstorm/Hail setters
if (species.name === 'Shedinja' && (teamDetails.sand || teamDetails.hail)) continue;
// Dynamically scale limits for different team sizes. The default and minimum value is 1.
const limitFactor = Math.round(this.maxTeamSize / 6) || 1;
@ -931,6 +955,9 @@ export class RandomGen5Teams extends RandomGen6Teams {
if (!this.adjustLevel && (this.getLevel(species) === 100) && numMaxLevelPokemon >= limitFactor) {
continue;
}
// Check compatibility with team
if (!this.getPokemonCompatibility(species, pokemon)) continue;
}
const set = this.randomSet(species, teamDetails, pokemon.length === 0);

View File

@ -15,7 +15,7 @@
]
},
"venusaurmega": {
"level": 78,
"level": 77,
"sets": [
{
"role": "Bulky Attacker",
@ -31,6 +31,11 @@
"role": "Bulky Attacker",
"movepool": ["airslash", "earthquake", "fireblast", "roost", "willowisp"],
"abilities": ["Blaze", "Solar Power"]
},
{
"role": "Setup Sweeper",
"movepool": ["acrobatics", "earthquake", "flareblitz", "swordsdance"],
"abilities": ["Blaze"]
}
]
},
@ -105,7 +110,7 @@
]
},
"beedrillmega": {
"level": 78,
"level": 77,
"sets": [
{
"role": "Fast Attacker",
@ -212,7 +217,7 @@
"sets": [
{
"role": "Wallbreaker",
"movepool": ["earthpower", "fireblast", "icebeam", "sludgewave", "stealthrock", "toxicspikes"],
"movepool": ["earthpower", "fireblast", "icebeam", "poisonjab", "sludgewave", "stealthrock", "toxicspikes"],
"abilities": ["Sheer Force"],
"preferredTypes": ["Ice"]
}
@ -223,7 +228,7 @@
"sets": [
{
"role": "Wallbreaker",
"movepool": ["earthpower", "fireblast", "icebeam", "sludgewave", "substitute", "superpower"],
"movepool": ["earthpower", "fireblast", "icebeam", "poisonjab", "sludgewave", "substitute"],
"abilities": ["Sheer Force"],
"preferredTypes": ["Ice"]
}
@ -339,9 +344,15 @@
"golduck": {
"level": 90,
"sets": [
{
"role": "Bulky Setup",
"movepool": ["calmmind", "encore", "focusblast", "icebeam", "scald", "substitute"],
"abilities": ["Cloud Nine", "Swift Swim"],
"preferredTypes": ["Ice"]
},
{
"role": "Fast Attacker",
"movepool": ["calmmind", "encore", "focusblast", "hydropump", "icebeam", "scald"],
"movepool": ["calmmind", "encore", "focusblast", "hydropump", "icebeam"],
"abilities": ["Cloud Nine", "Swift Swim"],
"preferredTypes": ["Ice"]
}
@ -490,14 +501,10 @@
"level": 82,
"sets": [
{
"role": "Bulky Support",
"movepool": ["fireblast", "icebeam", "psyshock", "scald", "slackoff", "thunderwave", "toxic"],
"abilities": ["Regenerator"]
},
{
"role": "AV Pivot",
"movepool": ["fireblast", "futuresight", "icebeam", "psyshock", "scald"],
"abilities": ["Regenerator"]
"role": "Bulky Attacker",
"movepool": ["calmmind", "fireblast", "icebeam", "psyshock", "scald", "slackoff", "thunderwave", "toxic"],
"abilities": ["Regenerator"],
"preferredTypes": ["Psychic"]
}
]
},
@ -785,9 +792,14 @@
"sets": [
{
"role": "Fast Attacker",
"movepool": ["dazzlinggleam", "encore", "focusblast", "healingwish", "nastyplot", "psychic", "psyshock", "shadowball"],
"movepool": ["dazzlinggleam", "encore", "focusblast", "healingwish", "psychic", "psyshock", "shadowball", "thunderbolt"],
"abilities": ["Filter"],
"preferredTypes": ["Psychic"]
"preferredTypes": ["Fighting"]
},
{
"role": "Setup Sweeper",
"movepool": ["dazzlinggleam", "encore", "focusblast", "nastyplot", "psychic", "psyshock"],
"abilities": ["Filter"]
}
]
},
@ -822,7 +834,7 @@
]
},
"pinsir": {
"level": 84,
"level": 85,
"sets": [
{
"role": "Fast Attacker",
@ -859,7 +871,7 @@
]
},
"gyarados": {
"level": 77,
"level": 78,
"sets": [
{
"role": "Setup Sweeper",
@ -1056,7 +1068,7 @@
"sets": [
{
"role": "Fast Attacker",
"movepool": ["aurasphere", "calmmind", "fireblast", "psystrike", "recover", "shadowball"],
"movepool": ["aurasphere", "calmmind", "fireblast", "psystrike", "recover", "signalbeam"],
"abilities": ["Unnerve"]
}
]
@ -1076,7 +1088,7 @@
"sets": [
{
"role": "Setup Sweeper",
"movepool": ["aurasphere", "calmmind", "fireblast", "psystrike", "recover", "shadowball"],
"movepool": ["aurasphere", "calmmind", "fireblast", "psystrike", "recover", "signalbeam"],
"abilities": ["Unnerve"]
}
]
@ -1176,7 +1188,7 @@
]
},
"crobat": {
"level": 81,
"level": 80,
"sets": [
{
"role": "Bulky Attacker",
@ -1366,14 +1378,10 @@
"level": 86,
"sets": [
{
"role": "Bulky Support",
"movepool": ["fireblast", "icebeam", "nastyplot", "psyshock", "scald", "slackoff", "thunderwave", "toxic"],
"abilities": ["Regenerator"]
},
{
"role": "AV Pivot",
"movepool": ["dragontail", "fireblast", "futuresight", "icebeam", "psyshock", "scald"],
"abilities": ["Regenerator"]
"role": "Bulky Attacker",
"movepool": ["dragontail", "fireblast", "icebeam", "nastyplot", "psyshock", "scald", "slackoff", "thunderwave", "toxic"],
"abilities": ["Regenerator"],
"preferredTypes": ["Psychic"]
}
]
},
@ -1388,7 +1396,7 @@
]
},
"wobbuffet": {
"level": 92,
"level": 93,
"sets": [
{
"role": "Bulky Support",
@ -1494,13 +1502,13 @@
"sets": [
{
"role": "Fast Support",
"movepool": ["destinybond", "spikes", "taunt", "thunderwave", "toxicspikes", "waterfall"],
"movepool": ["destinybond", "poisonjab", "spikes", "taunt", "thunderwave", "toxicspikes", "waterfall"],
"abilities": ["Intimidate"]
}
]
},
"scizor": {
"level": 79,
"level": 78,
"sets": [
{
"role": "Setup Sweeper",
@ -1611,12 +1619,14 @@
{
"role": "Wallbreaker",
"movepool": ["energyball", "fireblast", "gunkshot", "hydropump", "icebeam", "scald"],
"abilities": ["Sniper"]
"abilities": ["Sniper"],
"preferredTypes": ["Poison"]
},
{
"role": "Bulky Attacker",
"movepool": ["energyball", "fireblast", "gunkshot", "icebeam", "scald", "thunderwave"],
"abilities": ["Sniper"]
"abilities": ["Sniper"],
"preferredTypes": ["Poison"]
}
]
},
@ -1661,7 +1671,7 @@
]
},
"houndoom": {
"level": 85,
"level": 84,
"sets": [
{
"role": "Fast Attacker",
@ -1720,7 +1730,7 @@
"sets": [
{
"role": "Wallbreaker",
"movepool": ["doubleedge", "earthquake", "jumpkick", "megahorn", "suckerpunch", "thunderwave"],
"movepool": ["doubleedge", "earthquake", "jumpkick", "megahorn", "return", "suckerpunch", "thunderwave"],
"abilities": ["Intimidate"],
"preferredTypes": ["Ground"]
}
@ -1848,7 +1858,7 @@
]
},
"lugia": {
"level": 72,
"level": 71,
"sets": [
{
"role": "Staller",
@ -2257,8 +2267,13 @@
"level": 86,
"sets": [
{
"role": "Wallbreaker",
"movepool": ["aquatail", "earthquake", "headsmash", "heavyslam", "rockpolish", "stealthrock"],
"role": "Setup Sweeper",
"movepool": ["earthquake", "headsmash", "heavyslam", "rockpolish"],
"abilities": ["Rock Head"]
},
{
"role": "Bulky Attacker",
"movepool": ["aquatail", "earthquake", "headsmash", "heavyslam", "stealthrock"],
"abilities": ["Rock Head"],
"preferredTypes": ["Ground"]
}
@ -2506,6 +2521,11 @@
"role": "Bulky Setup",
"movepool": ["dragondance", "earthquake", "outrage", "roost"],
"abilities": ["Natural Cure"]
},
{
"role": "Bulky Support",
"movepool": ["dracometeor", "earthquake", "fireblast", "healbell", "roost", "toxic"],
"abilities": ["Natural Cure"]
}
]
},
@ -2516,11 +2536,6 @@
"role": "Setup Sweeper",
"movepool": ["dragondance", "earthquake", "return", "roost"],
"abilities": ["Natural Cure"]
},
{
"role": "Bulky Support",
"movepool": ["earthquake", "fireblast", "healbell", "return", "roost"],
"abilities": ["Natural Cure"]
}
]
},
@ -3112,11 +3127,6 @@
"role": "Bulky Support",
"movepool": ["knockoff", "recover", "seismictoss", "spikes", "stealthrock", "taunt", "toxic"],
"abilities": ["Pressure"]
},
{
"role": "Bulky Setup",
"movepool": ["focusblast", "nastyplot", "psychic", "psyshock", "recover", "signalbeam"],
"abilities": ["Pressure"]
}
]
},
@ -3267,12 +3277,7 @@
"sets": [
{
"role": "Bulky Support",
"movepool": ["metalburst", "roar", "rockblast", "stealthrock", "toxic"],
"abilities": ["Sturdy"]
},
{
"role": "Staller",
"movepool": ["metalburst", "protect", "roar", "rockblast", "stealthrock", "toxic"],
"movepool": ["metalburst", "protect", "roar", "rockslide", "stealthrock", "toxic"],
"abilities": ["Sturdy"]
}
]
@ -3683,7 +3688,7 @@
{
"role": "Fast Attacker",
"movepool": ["flashcannon", "hiddenpowerground", "thunderbolt", "voltswitch"],
"abilities": ["Magnet Pull"]
"abilities": ["Analytic", "Magnet Pull"]
},
{
"role": "Staller",
@ -3734,12 +3739,12 @@
"sets": [
{
"role": "Bulky Attacker",
"movepool": ["earthquake", "knockoff", "leafstorm", "leechseed", "morningsun", "powerwhip", "rockslide", "sleeppowder", "sludgebomb"],
"movepool": ["earthquake", "gigadrain", "knockoff", "leafstorm", "leechseed", "morningsun", "rockslide", "sleeppowder", "sludgebomb"],
"abilities": ["Regenerator"]
},
{
"role": "AV Pivot",
"movepool": ["earthquake", "gigadrain", "knockoff", "powerwhip", "rockslide", "sludgebomb"],
"movepool": ["earthquake", "gigadrain", "knockoff", "leafstorm", "rockslide", "sludgebomb"],
"abilities": ["Regenerator"]
}
]
@ -3806,7 +3811,7 @@
"sets": [
{
"role": "Setup Sweeper",
"movepool": ["doubleedge", "knockoff", "leafblade", "swordsdance", "synthesis", "xscissor"],
"movepool": ["doubleedge", "knockoff", "leafblade", "substitute", "swordsdance", "synthesis"],
"abilities": ["Chlorophyll"],
"preferredTypes": ["Dark"]
}
@ -3990,7 +3995,7 @@
"level": 86,
"sets": [
{
"role": "Fast Support",
"role": "Bulky Attacker",
"movepool": ["hiddenpowerice", "leafstorm", "thunderbolt", "trick", "voltswitch", "willowisp"],
"abilities": ["Levitate"]
}
@ -4079,9 +4084,13 @@
"sets": [
{
"role": "Bulky Attacker",
"movepool": ["drainpunch", "knockoff", "return", "substitute", "thunderwave"],
"abilities": ["Slow Start"],
"preferredTypes": ["Dark"]
"movepool": ["drainpunch", "knockoff", "return", "thunderwave"],
"abilities": ["Slow Start"]
},
{
"role": "Bulky Support",
"movepool": ["knockoff", "return", "substitute", "thunderwave"],
"abilities": ["Slow Start"]
}
]
},
@ -4472,9 +4481,14 @@
"abilities": ["Torrent"]
},
{
"role": "Fast Attacker",
"role": "Setup Sweeper",
"movepool": ["aquajet", "knockoff", "megahorn", "superpower", "swordsdance", "waterfall"],
"abilities": ["Torrent"]
},
{
"role": "Fast Attacker",
"movepool": ["grassknot", "hydropump", "icebeam", "scald"],
"abilities": ["Torrent"]
}
]
},
@ -4718,7 +4732,7 @@
]
},
"scolipede": {
"level": 80,
"level": 79,
"sets": [
{
"role": "Fast Support",
@ -4773,7 +4787,7 @@
]
},
"krookodile": {
"level": 79,
"level": 78,
"sets": [
{
"role": "Fast Attacker",
@ -4822,9 +4836,9 @@
"level": 83,
"sets": [
{
"role": "Setup Sweeper",
"movepool": ["dragondance", "highjumpkick", "ironhead", "knockoff"],
"abilities": ["Intimidate", "Moxie"]
"role": "Bulky Attacker",
"movepool": ["dragondance", "drainpunch", "ironhead", "knockoff"],
"abilities": ["Intimidate"]
},
{
"role": "Bulky Setup",
@ -4937,7 +4951,7 @@
"sets": [
{
"role": "Bulky Setup",
"movepool": ["calmmind", "focusblast", "psychic", "psyshock", "recover", "signalbeam"],
"movepool": ["calmmind", "focusblast", "psychic", "psyshock", "recover"],
"abilities": ["Magic Guard"]
}
]
@ -5045,7 +5059,7 @@
"sets": [
{
"role": "Wallbreaker",
"movepool": ["bugbuzz", "gigadrain", "stickyweb", "thunder", "voltswitch"],
"movepool": ["bugbuzz", "energyball", "stickyweb", "thunder", "voltswitch"],
"abilities": ["Compound Eyes"],
"preferredTypes": ["Bug"]
}
@ -5186,7 +5200,7 @@
]
},
"druddigon": {
"level": 85,
"level": 86,
"sets": [
{
"role": "Wallbreaker",
@ -5293,7 +5307,7 @@
},
{
"role": "Bulky Attacker",
"movepool": ["darkpulse", "dracometeor", "fireblast", "roost", "uturn"],
"movepool": ["darkpulse", "dracometeor", "fireblast", "roost", "toxic", "uturn"],
"abilities": ["Levitate"]
},
{
@ -5685,7 +5699,7 @@
]
},
"pangoro": {
"level": 85,
"level": 84,
"sets": [
{
"role": "Wallbreaker",
@ -5883,11 +5897,6 @@
"sylveon": {
"level": 84,
"sets": [
{
"role": "Bulky Attacker",
"movepool": ["calmmind", "hiddenpowerground", "hypervoice", "protect", "psyshock", "wish"],
"abilities": ["Pixilate"]
},
{
"role": "Bulky Setup",
"movepool": ["calmmind", "hypervoice", "protect", "wish"],
@ -6001,7 +6010,7 @@
]
},
"gourgeistsuper": {
"level": 88,
"level": 87,
"sets": [
{
"role": "Bulky Support",

View File

@ -97,7 +97,7 @@ export class RandomGen6Teams extends RandomGen7Teams {
Normal: movePool => movePool.includes('boomburst'),
Poison: (movePool, moves, abilities, types, counter) => !counter.get('Poison'),
Psychic: (movePool, moves, abilities, types, counter) => (
!counter.get('Psychic') && (types.has('Fighting') || movePool.includes('calmmind'))
!counter.get('Psychic') && (types.has('Fighting') || types.has('Fairy') || movePool.includes('calmmind'))
),
Rock: (movePool, moves, abilities, types, counter, species) => (!counter.get('Rock') && species.baseStats.atk >= 80),
Steel: (movePool, moves, abilities, types, counter, species) => (!counter.get('Steel') && species.baseStats.atk >= 100),
@ -227,7 +227,7 @@ export class RandomGen6Teams extends RandomGen7Teams {
['hornleech', 'woodhammer'],
[['gigadrain', 'leafstorm'], ['leafstorm', 'petaldance', 'powerwhip']],
['wildcharge', 'thunderbolt'],
['gunkshot', 'poisonjab'],
[['gunkshot', 'sludgewave'], 'poisonjab'],
[['drainpunch', 'focusblast'], ['closecombat', 'highjumpkick', 'superpower']],
['stoneedge', 'headsmash'],
['dracometeor', 'dragonpulse'],
@ -250,6 +250,8 @@ export class RandomGen6Teams extends RandomGen7Teams {
['switcheroo', 'suckerpunch'],
// Jirachi
['bodyslam', 'healingwish'],
// Bastiodon
[['roar', 'protect'], ['metalburst', 'protect']],
];
for (const pair of incompatiblePairs) this.incompatibleMoves(moves, movePool, pair[0], pair[1]);
@ -258,7 +260,7 @@ export class RandomGen6Teams extends RandomGen7Teams {
this.incompatibleMoves(moves, movePool, 'knockoff', ['pursuit', 'suckerpunch']);
}
const statusInflictingMoves = ['thunderwave', 'toxic', 'willowisp', 'yawn'];
const statusInflictingMoves = ["nuzzle", 'thunderwave', 'toxic', 'willowisp', 'yawn'];
if (!abilities.includes('Prankster') && role !== 'Staller') {
this.incompatibleMoves(moves, movePool, statusInflictingMoves, statusInflictingMoves);
}
@ -732,12 +734,6 @@ export class RandomGen6Teams extends RandomGen7Teams {
)
) return 'Rocky Helmet';
if (['kingsshield', 'protect', 'spikyshield', 'substitute'].some(m => moves.has(m))) return 'Leftovers';
if (
this.dex.getEffectiveness('Ground', species) >= 2 &&
ability !== 'Levitate'
) {
return 'Air Balloon';
}
if (
(role === 'Fast Support' || moves.has('stickyweb')) && isLead && defensiveStatTotal < 255 &&
!counter.get('recovery') && (counter.get('hazards') || counter.get('setup')) &&
@ -887,6 +883,7 @@ export class RandomGen6Teams extends RandomGen7Teams {
return {
name: species.baseSpecies,
species: forme,
speciesId: species.id,
gender: species.gender || (this.random(2) ? 'F' : 'M'),
shiny: this.randomChance(1, 1024),
level,

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
import RandomGen6Teams from '../gen6/teams';
export class RandomMRTeams extends RandomGen6Teams {
override randomSets: { [species: string]: RandomTeamsTypes.RandomSpeciesData } = require('./sets.json');
}
export default RandomMRTeams;

View File

@ -33,6 +33,11 @@
"abilities": ["Blaze", "Solar Power"],
"preferredTypes": ["Normal"]
},
{
"role": "Setup Sweeper",
"movepool": ["acrobatics", "earthquake", "flareblitz", "swordsdance"],
"abilities": ["Blaze"]
},
{
"role": "Bulky Attacker",
"movepool": ["airslash", "earthquake", "fireblast", "roost", "willowisp"],
@ -283,7 +288,7 @@
"sets": [
{
"role": "Wallbreaker",
"movepool": ["earthpower", "fireblast", "icebeam", "sludgewave", "stealthrock", "toxicspikes"],
"movepool": ["earthpower", "fireblast", "icebeam", "poisonjab", "sludgewave", "stealthrock", "toxicspikes"],
"abilities": ["Sheer Force"],
"preferredTypes": ["Ice"]
}
@ -294,7 +299,7 @@
"sets": [
{
"role": "Wallbreaker",
"movepool": ["earthpower", "fireblast", "icebeam", "sludgewave", "substitute", "superpower"],
"movepool": ["earthpower", "fireblast", "icebeam", "poisonjab", "sludgewave", "substitute", "throatchop"],
"abilities": ["Sheer Force"],
"preferredTypes": ["Ice"]
}
@ -453,10 +458,16 @@
"level": 93,
"sets": [
{
"role": "Fast Attacker",
"movepool": ["calmmind", "encore", "focusblast", "hydropump", "icebeam", "scald"],
"role": "Bulky Setup",
"movepool": ["calmmind", "encore", "focusblast", "icebeam", "scald", "substitute"],
"abilities": ["Cloud Nine", "Swift Swim"],
"preferredTypes": ["Ice"]
},
{
"role": "Fast Attacker",
"movepool": ["calmmind", "encore", "focusblast", "hydropump", "icebeam"],
"abilities": ["Cloud Nine", "Swift Swim"],
"preferredTypes": ["Ice"]
}
]
},
@ -631,14 +642,10 @@
"level": 85,
"sets": [
{
"role": "Bulky Support",
"movepool": ["fireblast", "icebeam", "psyshock", "scald", "slackoff", "thunderwave", "toxic"],
"abilities": ["Regenerator"]
},
{
"role": "AV Pivot",
"movepool": ["fireblast", "futuresight", "icebeam", "psyshock", "scald"],
"abilities": ["Regenerator"]
"role": "Bulky Attacker",
"movepool": ["calmmind", "fireblast", "icebeam", "psyshock", "scald", "slackoff", "thunderwave", "toxic"],
"abilities": ["Regenerator"],
"preferredTypes": ["Psychic"]
}
]
},
@ -882,7 +889,7 @@
]
},
"rhydon": {
"level": 86,
"level": 85,
"sets": [
{
"role": "Bulky Attacker",
@ -933,7 +940,7 @@
]
},
"seaking": {
"level": 94,
"level": 95,
"sets": [
{
"role": "Fast Attacker",
@ -969,9 +976,14 @@
"sets": [
{
"role": "Fast Attacker",
"movepool": ["dazzlinggleam", "encore", "focusblast", "healingwish", "nastyplot", "psychic", "psyshock", "shadowball"],
"movepool": ["dazzlinggleam", "encore", "focusblast", "healingwish", "psychic", "psyshock", "shadowball", "thunderbolt"],
"abilities": ["Filter"],
"preferredTypes": ["Psychic"]
"preferredTypes": ["Fighting"]
},
{
"role": "Setup Sweeper",
"movepool": ["dazzlinggleam", "encore", "focusblast", "nastyplot", "psychic", "psyshock"],
"abilities": ["Filter"]
}
]
},
@ -1269,7 +1281,7 @@
"sets": [
{
"role": "Fast Attacker",
"movepool": ["aurasphere", "calmmind", "fireblast", "psystrike", "recover", "shadowball"],
"movepool": ["aurasphere", "calmmind", "fireblast", "psystrike", "recover", "signalbeam"],
"abilities": ["Unnerve"]
}
]
@ -1289,7 +1301,7 @@
"sets": [
{
"role": "Setup Sweeper",
"movepool": ["aurasphere", "calmmind", "fireblast", "psystrike", "recover", "shadowball"],
"movepool": ["aurasphere", "calmmind", "fireblast", "psystrike", "recover", "signalbeam"],
"abilities": ["Unnerve"]
}
]
@ -1437,7 +1449,7 @@
]
},
"ampharosmega": {
"level": 84,
"level": 85,
"sets": [
{
"role": "Bulky Attacker",
@ -1549,7 +1561,7 @@
]
},
"espeon": {
"level": 84,
"level": 83,
"sets": [
{
"role": "Fast Attacker",
@ -1578,14 +1590,10 @@
"level": 89,
"sets": [
{
"role": "Bulky Support",
"movepool": ["fireblast", "icebeam", "nastyplot", "psyshock", "scald", "slackoff", "thunderwave", "toxic"],
"abilities": ["Regenerator"]
},
{
"role": "AV Pivot",
"movepool": ["dragontail", "fireblast", "futuresight", "icebeam", "psyshock", "scald"],
"abilities": ["Regenerator"]
"role": "Bulky Attacker",
"movepool": ["dragontail", "fireblast", "icebeam", "nastyplot", "psyshock", "scald", "slackoff", "thunderwave", "toxic"],
"abilities": ["Regenerator"],
"preferredTypes": ["Psychic"]
}
]
},
@ -1686,7 +1694,7 @@
]
},
"steelixmega": {
"level": 81,
"level": 80,
"sets": [
{
"role": "Bulky Support",
@ -1710,7 +1718,7 @@
"sets": [
{
"role": "Fast Support",
"movepool": ["destinybond", "spikes", "taunt", "thunderwave", "toxicspikes", "waterfall"],
"movepool": ["destinybond", "poisonjab", "spikes", "taunt", "thunderwave", "toxicspikes", "waterfall"],
"abilities": ["Intimidate"]
}
]
@ -1764,10 +1772,15 @@
"level": 82,
"sets": [
{
"role": "Wallbreaker",
"role": "Setup Sweeper",
"movepool": ["closecombat", "facade", "knockoff", "swordsdance"],
"abilities": ["Guts"]
},
{
"role": "Wallbreaker",
"movepool": ["closecombat", "facade", "knockoff", "megahorn"],
"abilities": ["Guts"]
},
{
"role": "Fast Attacker",
"movepool": ["closecombat", "knockoff", "megahorn", "stoneedge"],
@ -1863,7 +1876,7 @@
]
},
"skarmory": {
"level": 76,
"level": 75,
"sets": [
{
"role": "Bulky Support",
@ -1888,7 +1901,7 @@
]
},
"houndoommega": {
"level": 81,
"level": 80,
"sets": [
{
"role": "Setup Sweeper",
@ -1937,7 +1950,7 @@
"sets": [
{
"role": "Wallbreaker",
"movepool": ["doubleedge", "earthquake", "jumpkick", "megahorn", "suckerpunch", "throatchop", "thunderwave"],
"movepool": ["doubleedge", "earthquake", "jumpkick", "megahorn", "return", "suckerpunch", "throatchop", "thunderwave"],
"abilities": ["Intimidate"],
"preferredTypes": ["Ground"]
}
@ -2454,7 +2467,7 @@
]
},
"sableyemega": {
"level": 87,
"level": 86,
"sets": [
{
"role": "Bulky Setup",
@ -2487,8 +2500,13 @@
"level": 87,
"sets": [
{
"role": "Wallbreaker",
"movepool": ["aquatail", "earthquake", "headsmash", "heavyslam", "rockpolish", "stealthrock"],
"role": "Setup Sweeper",
"movepool": ["earthquake", "headsmash", "heavyslam", "rockpolish"],
"abilities": ["Rock Head"]
},
{
"role": "Bulky Attacker",
"movepool": ["aquatail", "earthquake", "headsmash", "heavyslam", "stealthrock"],
"abilities": ["Rock Head"],
"preferredTypes": ["Ground"]
}
@ -2562,7 +2580,7 @@
]
},
"minun": {
"level": 94,
"level": 95,
"sets": [
{
"role": "Bulky Setup",
@ -2731,7 +2749,7 @@
]
},
"cacturne": {
"level": 92,
"level": 93,
"sets": [
{
"role": "Wallbreaker",
@ -2748,6 +2766,11 @@
"altaria": {
"level": 92,
"sets": [
{
"role": "Bulky Setup",
"movepool": ["dragondance", "earthquake", "outrage", "roost"],
"abilities": ["Natural Cure"]
},
{
"role": "Bulky Support",
"movepool": ["defog", "dracometeor", "earthquake", "fireblast", "healbell", "roost", "toxic"],
@ -3042,7 +3065,7 @@
]
},
"gorebyss": {
"level": 84,
"level": 85,
"sets": [
{
"role": "Setup Sweeper",
@ -3368,7 +3391,7 @@
]
},
"deoxysattack": {
"level": 73,
"level": 72,
"sets": [
{
"role": "Wallbreaker",
@ -3389,11 +3412,6 @@
"role": "Bulky Support",
"movepool": ["knockoff", "recover", "seismictoss", "spikes", "stealthrock", "taunt", "toxic"],
"abilities": ["Pressure"]
},
{
"role": "Bulky Setup",
"movepool": ["focusblast", "nastyplot", "psychic", "psyshock", "recover", "signalbeam"],
"abilities": ["Pressure"]
}
]
},
@ -3436,12 +3454,6 @@
"movepool": ["closecombat", "grassknot", "machpunch", "overheat", "stealthrock"],
"abilities": ["Blaze", "Iron Fist"]
},
{
"role": "Z-Move user",
"movepool": ["fireblast", "focusblast", "grassknot", "nastyplot", "vacuumwave"],
"abilities": ["Blaze"],
"preferredTypes": ["Fighting"]
},
{
"role": "Fast Support",
"movepool": ["closecombat", "flareblitz", "machpunch", "stoneedge", "swordsdance", "uturn"],
@ -3546,12 +3558,7 @@
"sets": [
{
"role": "Bulky Support",
"movepool": ["metalburst", "roar", "rockblast", "stealthrock", "toxic"],
"abilities": ["Sturdy"]
},
{
"role": "Staller",
"movepool": ["metalburst", "protect", "roar", "rockblast", "stealthrock", "toxic"],
"movepool": ["metalburst", "protect", "roar", "rockslide", "stealthrock", "toxic"],
"abilities": ["Sturdy"]
}
]
@ -3749,7 +3756,7 @@
]
},
"honchkrow": {
"level": 84,
"level": 83,
"sets": [
{
"role": "Wallbreaker",
@ -3992,7 +3999,7 @@
{
"role": "Fast Attacker",
"movepool": ["flashcannon", "hiddenpowerground", "thunderbolt", "voltswitch"],
"abilities": ["Magnet Pull"]
"abilities": ["Analytic", "Magnet Pull"]
},
{
"role": "Staller",
@ -4043,12 +4050,12 @@
"sets": [
{
"role": "Bulky Attacker",
"movepool": ["earthquake", "knockoff", "leafstorm", "leechseed", "morningsun", "powerwhip", "rockslide", "sleeppowder", "sludgebomb"],
"movepool": ["earthquake", "gigadrain", "knockoff", "leafstorm", "leechseed", "morningsun", "rockslide", "sleeppowder", "sludgebomb"],
"abilities": ["Regenerator"]
},
{
"role": "AV Pivot",
"movepool": ["earthquake", "gigadrain", "knockoff", "powerwhip", "rockslide", "sludgebomb"],
"movepool": ["earthquake", "gigadrain", "knockoff", "leafstorm", "rockslide", "sludgebomb"],
"abilities": ["Regenerator"]
}
]
@ -4115,7 +4122,7 @@
"sets": [
{
"role": "Setup Sweeper",
"movepool": ["doubleedge", "knockoff", "leafblade", "swordsdance", "synthesis", "xscissor"],
"movepool": ["doubleedge", "knockoff", "leafblade", "substitute", "swordsdance", "synthesis"],
"abilities": ["Chlorophyll"],
"preferredTypes": ["Dark"]
}
@ -4317,7 +4324,7 @@
"level": 86,
"sets": [
{
"role": "Fast Support",
"role": "Bulky Attacker",
"movepool": ["defog", "hiddenpowerice", "leafstorm", "thunderbolt", "trick", "voltswitch", "willowisp"],
"abilities": ["Levitate"]
}
@ -4406,9 +4413,13 @@
"sets": [
{
"role": "Bulky Attacker",
"movepool": ["drainpunch", "knockoff", "return", "substitute", "thunderwave"],
"abilities": ["Slow Start"],
"preferredTypes": ["Dark"]
"movepool": ["drainpunch", "knockoff", "return", "thunderwave"],
"abilities": ["Slow Start"]
},
{
"role": "Bulky Support",
"movepool": ["knockoff", "return", "substitute", "thunderwave"],
"abilities": ["Slow Start"]
}
]
},
@ -4834,9 +4845,14 @@
"abilities": ["Torrent"]
},
{
"role": "Fast Attacker",
"role": "Setup Sweeper",
"movepool": ["aquajet", "knockoff", "liquidation", "megahorn", "sacredsword", "swordsdance"],
"abilities": ["Torrent"]
},
{
"role": "Fast Attacker",
"movepool": ["grassknot", "hydropump", "icebeam", "scald"],
"abilities": ["Torrent"]
}
]
},
@ -4970,7 +4986,7 @@
]
},
"swoobat": {
"level": 87,
"level": 88,
"sets": [
{
"role": "Bulky Attacker",
@ -5067,6 +5083,11 @@
"movepool": ["bulkup", "facade", "knockoff", "stormthrow"],
"abilities": ["Guts"]
},
{
"role": "Wallbreaker",
"movepool": ["facade", "knockoff", "stormthrow", "superpower"],
"abilities": ["Guts"]
},
{
"role": "Bulky Support",
"movepool": ["bulkup", "circlethrow", "knockoff", "rest", "sleeptalk"],
@ -5200,9 +5221,9 @@
"level": 84,
"sets": [
{
"role": "Setup Sweeper",
"movepool": ["dragondance", "highjumpkick", "ironhead", "knockoff"],
"abilities": ["Intimidate", "Moxie"]
"role": "Bulky Attacker",
"movepool": ["dragondance", "drainpunch", "ironhead", "knockoff"],
"abilities": ["Intimidate"]
},
{
"role": "Bulky Setup",
@ -5315,7 +5336,7 @@
"sets": [
{
"role": "Bulky Setup",
"movepool": ["calmmind", "focusblast", "psychic", "psyshock", "recover", "signalbeam"],
"movepool": ["calmmind", "focusblast", "psychic", "psyshock", "recover"],
"abilities": ["Magic Guard"]
}
]
@ -5429,7 +5450,7 @@
"sets": [
{
"role": "Wallbreaker",
"movepool": ["bugbuzz", "gigadrain", "stickyweb", "thunder", "voltswitch"],
"movepool": ["bugbuzz", "energyball", "stickyweb", "thunder", "voltswitch"],
"abilities": ["Compound Eyes"],
"preferredTypes": ["Bug"]
}
@ -5551,7 +5572,7 @@
]
},
"stunfisk": {
"level": 89,
"level": 88,
"sets": [
{
"role": "Bulky Attacker",
@ -5694,7 +5715,7 @@
},
{
"role": "Bulky Attacker",
"movepool": ["darkpulse", "defog", "dracometeor", "fireblast", "roost", "uturn"],
"movepool": ["darkpulse", "defog", "dracometeor", "fireblast", "roost", "toxic", "uturn"],
"abilities": ["Levitate"]
},
{
@ -5802,7 +5823,7 @@
]
},
"thundurus": {
"level": 82,
"level": 81,
"sets": [
{
"role": "Setup Sweeper",
@ -5933,7 +5954,7 @@
]
},
"kyuremwhite": {
"level": 76,
"level": 75,
"sets": [
{
"role": "Fast Attacker",
@ -6051,7 +6072,7 @@
]
},
"diggersby": {
"level": 83,
"level": 82,
"sets": [
{
"role": "Setup Sweeper",
@ -6348,11 +6369,6 @@
"sylveon": {
"level": 85,
"sets": [
{
"role": "Bulky Attacker",
"movepool": ["calmmind", "hiddenpowerground", "hypervoice", "protect", "psyshock", "wish"],
"abilities": ["Pixilate"]
},
{
"role": "Bulky Setup",
"movepool": ["calmmind", "hypervoice", "protect", "wish"],
@ -6436,7 +6452,7 @@
]
},
"gourgeistsmall": {
"level": 90,
"level": 91,
"sets": [
{
"role": "Bulky Support",
@ -6446,7 +6462,7 @@
]
},
"gourgeistlarge": {
"level": 90,
"level": 91,
"sets": [
{
"role": "Bulky Support",
@ -6650,6 +6666,11 @@
"role": "Bulky Attacker",
"movepool": ["hydropump", "moonblast", "psychic", "scald"],
"abilities": ["Torrent"]
},
{
"role": "Bulky Support",
"movepool": ["moonblast", "rest", "scald", "sleeptalk"],
"abilities": ["Torrent"]
}
]
},
@ -6818,7 +6839,7 @@
"sets": [
{
"role": "AV Pivot",
"movepool": ["earthquake", "hiddenpowergrass", "hydropump", "icebeam", "scald", "uturn"],
"movepool": ["earthquake", "hydropump", "icebeam", "scald", "uturn"],
"abilities": ["Schooling"],
"preferredTypes": ["Ice"]
},
@ -6944,7 +6965,7 @@
]
},
"comfey": {
"level": 88,
"level": 87,
"sets": [
{
"role": "Bulky Support",
@ -7405,7 +7426,12 @@
"sets": [
{
"role": "Bulky Attacker",
"movepool": ["bulkup", "hornleech", "megahorn", "stoneedge", "superpower", "woodhammer"],
"movepool": ["hornleech", "megahorn", "stoneedge", "superpower", "woodhammer"],
"abilities": ["Grassy Surge"]
},
{
"role": "Bulky Setup",
"movepool": ["hornleech", "stoneedge", "superpower", "swordsdance", "woodhammer"],
"abilities": ["Grassy Surge"]
}
]
@ -7417,6 +7443,11 @@
"role": "Bulky Setup",
"movepool": ["calmmind", "hydropump", "icebeam", "moonblast", "surf", "taunt"],
"abilities": ["Misty Surge"]
},
{
"role": "Bulky Support",
"movepool": ["defog", "hydropump", "knockoff", "moonblast", "naturesmadness", "surf", "taunt"],
"abilities": ["Misty Surge"]
}
]
},
@ -7453,16 +7484,16 @@
},
{
"role": "Z-Move user",
"movepool": ["calmmind", "moonblast", "moongeistbeam", "psyshock", "roost"],
"movepool": ["calmmind", "moongeistbeam", "psyshock", "roost"],
"abilities": ["Shadow Shield"]
}
]
},
"nihilego": {
"level": 80,
"level": 79,
"sets": [
{
"role": "Fast Support",
"role": "Bulky Attacker",
"movepool": ["grassknot", "hiddenpowerfire", "hiddenpowerground", "powergem", "sludgewave", "stealthrock", "thunderbolt", "toxicspikes"],
"abilities": ["Beast Boost"],
"preferredTypes": ["Rock"]
@ -7548,7 +7579,7 @@
]
},
"guzzlord": {
"level": 87,
"level": 86,
"sets": [
{
"role": "AV Pivot",
@ -7615,9 +7646,10 @@
"level": 77,
"sets": [
{
"role": "Bulky Attacker",
"role": "Z-Move user",
"movepool": ["calmmind", "flashcannon", "fleurcannon", "shiftgear"],
"abilities": ["Soul-Heart"]
"abilities": ["Soul-Heart"],
"preferredTypes": ["Fairy"]
},
{
"role": "Bulky Support",
@ -7625,10 +7657,9 @@
"abilities": ["Soul-Heart"]
},
{
"role": "Z-Move user",
"role": "Bulky Setup",
"movepool": ["aurasphere", "fleurcannon", "ironhead", "shiftgear"],
"abilities": ["Soul-Heart"],
"preferredTypes": ["Fairy", "Steel"]
"abilities": ["Soul-Heart"]
}
]
},

View File

@ -135,7 +135,7 @@ export class RandomGen7Teams extends RandomGen8Teams {
Poison: (movePool, moves, abilities, types, counter) => !counter.get('Poison'),
Psychic: (movePool, moves, abilities, types, counter) => (
!counter.get('Psychic') && (
types.has('Fighting') || movePool.includes('psychicfangs') || movePool.includes('calmmind')
types.has('Fighting') || types.has('Fairy') || movePool.includes('psychicfangs') || movePool.includes('calmmind')
)
),
Rock: (movePool, moves, abilities, types, counter, species) => (!counter.get('Rock') && species.baseStats.atk >= 80),
@ -345,7 +345,7 @@ export class RandomGen7Teams extends RandomGen8Teams {
['hornleech', 'woodhammer'],
[['gigadrain', 'leafstorm'], ['energyball', 'leafstorm', 'petaldance', 'powerwhip']],
['wildcharge', 'thunderbolt'],
['gunkshot', 'poisonjab'],
[['gunkshot', 'sludgewave'], 'poisonjab'],
[['drainpunch', 'focusblast'], ['closecombat', 'highjumpkick', 'superpower']],
['dracometeor', 'dragonpulse'],
['dragonclaw', 'outrage'],
@ -367,6 +367,8 @@ export class RandomGen7Teams extends RandomGen8Teams {
['switcheroo', 'suckerpunch'],
// Jirachi
['bodyslam', 'healingwish'],
// Bastiodon
[['roar', 'protect'], ['metalburst', 'protect']],
];
for (const pair of incompatiblePairs) this.incompatibleMoves(moves, movePool, pair[0], pair[1]);
@ -375,7 +377,7 @@ export class RandomGen7Teams extends RandomGen8Teams {
this.incompatibleMoves(moves, movePool, 'knockoff', ['pursuit', 'suckerpunch']);
}
const statusInflictingMoves = ['thunderwave', 'toxic', 'willowisp', 'yawn'];
const statusInflictingMoves = ["nuzzle", 'thunderwave', 'toxic', 'willowisp', 'yawn'];
if (!abilities.includes('Prankster') && role !== 'Staller') {
this.incompatibleMoves(moves, movePool, statusInflictingMoves, statusInflictingMoves);
}
@ -933,7 +935,7 @@ export class RandomGen7Teams extends RandomGen8Teams {
if (ability === 'Sturdy' && moves.has('explosion') && !counter.get('speedsetup')) return 'Custap Berry';
if (types.includes('Normal') && moves.has('fakeout') && !!counter.get('Normal')) return 'Silk Scarf';
if (species.id === 'latias' || species.id === 'latios') return 'Soul Dew';
if (role === 'Bulky Setup' && !!counter.get('speedsetup') && !moves.has('swordsdance')) {
if (role === 'Bulky Setup' && (!!counter.get('speedsetup') || moves.has('shiftgear')) && !moves.has('swordsdance')) {
return 'Weakness Policy';
}
if (species.id === 'palkia') return 'Lustrous Orb';
@ -955,12 +957,6 @@ export class RandomGen7Teams extends RandomGen8Teams {
)
) return 'Rocky Helmet';
if (['kingsshield', 'protect', 'spikyshield', 'substitute'].some(m => moves.has(m))) return 'Leftovers';
if (
this.dex.getEffectiveness('Ground', species) >= 2 &&
ability !== 'Levitate' && species.id !== 'golemalola'
) {
return 'Air Balloon';
}
if (
(role === 'Fast Support' || moves.has('stickyweb')) && isLead && defensiveStatTotal < 255 &&
!counter.get('recovery') && (counter.get('hazards') || counter.get('setup')) &&
@ -1176,6 +1172,7 @@ export class RandomGen7Teams extends RandomGen8Teams {
return {
name: species.baseSpecies,
species: forme,
speciesId: species.id,
gender: species.baseSpecies === 'Greninja' ? 'M' : (species.gender || (this.random(2) ? 'F' : 'M')),
shiny: this.randomChance(1, 1024),
level,
@ -1188,6 +1185,60 @@ export class RandomGen7Teams extends RandomGen8Teams {
};
}
/**
* Checks if the new species is compatible with the other mons currently on the team.
*/
getPokemonCompatibility(
species: Species,
pokemon: RandomTeamsTypes.RandomSet[],
): boolean {
const webSetters = [
'ariados', 'shuckle', 'smeargle', 'masquerain', 'kricketune', 'leavanny', 'galvantula', 'ribombee', 'araquanid',
];
// Some pokes are setters in gen 7 but not gen 6
const gen6ScreenSetters = ['meowstic', 'carbink'];
const screenSetters = (this.gen === 7) ? [...gen6ScreenSetters, 'electrode', 'ninetalesalola'] : gen6ScreenSetters;
const gen6SunSetters = ['charizardmegay', 'ninetales', 'groudon'];
const sunSetters = (this.gen === 7) ? [...gen6SunSetters, 'torkoal'] : gen6SunSetters;
const gen6SandSetters = ['tyranitar', 'tyranitarmega', 'hippowdon'];
const sandSetters = (this.gen === 7) ? [...gen6SandSetters, 'gigalith'] : gen6SandSetters;
const gen6HailSetters = ['abomasnow', 'abomasnowmega', 'aurorus'];
const hailSetters = (this.gen === 7) ? [...gen6HailSetters, 'vanilluxe', 'ninetalesalola'] : gen6HailSetters;
const incompatibilityList = [
// These Pokemon with support roles are considered too similar to each other.
['blissey', 'chansey'],
['illumise', 'volbeat'],
// These combinations are prevented to avoid double webs or screens.
[webSetters, webSetters],
[screenSetters, screenSetters],
// These Pokemon are incompatible because the presence of one actively harms the other.
// Prevent Dry Skin + sun setting ability
['parasect', 'jynx', 'toxicroak', 'heliolisk', sunSetters],
// Prevent Shedinja + sand/hail setting ability
['shedinja', [...sandSetters, ...hailSetters]],
];
for (const pair of incompatibilityList) {
const monsArrayA = (Array.isArray(pair[0])) ? pair[0] : [pair[0]];
const monsArrayB = (Array.isArray(pair[1])) ? pair[1] : [pair[1]];
if (monsArrayB.includes(species.id)) {
if (pokemon.some(m => monsArrayA.includes(m.speciesId!))) return false;
}
if (monsArrayA.includes(species.id)) {
if (pokemon.some(m => monsArrayB.includes(m.speciesId!))) return false;
}
}
return true;
}
override randomTeam() {
this.enforceNoDirectCustomBanlistChanges();
@ -1304,6 +1355,9 @@ export class RandomGen7Teams extends RandomGen8Teams {
if (!this.adjustLevel && (this.getLevel(species) === 100) && numMaxLevelPokemon >= limitFactor) {
continue;
}
// Check compatibility with team
if (!this.getPokemonCompatibility(species, pokemon)) continue;
}
// Limit three of any type combination in Monotype
@ -1607,8 +1661,7 @@ export class RandomGen7Teams extends RandomGen8Teams {
if (isMonotype) {
// Prevents Mega Evolutions from breaking the type limits
if (itemData.megaStone) {
const megaSpecies = this.dex.species.get(Array.isArray(itemData.megaStone) ?
itemData.megaStone[0] : itemData.megaStone);
const megaSpecies = this.dex.species.get(Object.values(itemData.megaStone)[0]);
if (types.length > megaSpecies.types.length) types = [species.types[0]];
// Only check the second type because a Mega Evolution should always share the first type with its base forme.
if (megaSpecies.types[1] && types[1] && megaSpecies.types[1] !== types[1]) {

View File

@ -118,7 +118,7 @@
"doublesMoves": ["dazzlinggleam", "healpulse", "helpinghand", "hypervoice", "thunderwave"]
},
"vileplume": {
"level": 84,
"level": 83,
"moves": ["aromatherapy", "gigadrain", "sleeppowder", "sludgebomb", "strengthsap"],
"doublesLevel": 88,
"doublesMoves": ["aromatherapy", "energyball", "pollenpuff", "sleeppowder", "sludgebomb", "strengthsap"]
@ -178,7 +178,7 @@
"doublesMoves": ["bulletpunch", "closecombat", "facade", "knockoff", "protect"]
},
"tentacruel": {
"level": 82,
"level": 81,
"moves": ["haze", "knockoff", "rapidspin", "scald", "sludgebomb", "toxicspikes"],
"doublesLevel": 87,
"doublesMoves": ["acidspray", "icywind", "knockoff", "muddywater", "rapidspin", "sludgebomb"]
@ -190,7 +190,7 @@
"doublesMoves": ["flareblitz", "highhorsepower", "morningsun", "protect", "swordsdance", "wildcharge"]
},
"rapidashgalar": {
"level": 83,
"level": 84,
"moves": ["highhorsepower", "morningsun", "playrough", "swordsdance", "zenheadbutt"],
"doublesLevel": 88,
"doublesMoves": ["highhorsepower", "playrough", "protect", "swordsdance", "zenheadbutt"]
@ -323,7 +323,7 @@
"moves": ["focusblast", "freezedry", "nastyplot", "psychic", "rapidspin"]
},
"scyther": {
"level": 82,
"level": 81,
"moves": ["brickbreak", "dualwingbeat", "knockoff", "roost", "swordsdance", "uturn"],
"doublesLevel": 84,
"doublesMoves": ["brickbreak", "bugbite", "dualwingbeat", "uturn"]
@ -418,13 +418,13 @@
},
"articunogalar": {
"level": 81,
"moves": ["airslash", "calmmind", "freezingglare", "recover"],
"moves": ["calmmind", "freezingglare", "hurricane", "recover"],
"doublesLevel": 81,
"doublesMoves": ["calmmind", "freezingglare", "hurricane", "recover", "tailwind"],
"noDynamaxMoves": ["calmmind", "freezingglare", "hurricane", "recover"]
},
"zapdos": {
"level": 78,
"level": 79,
"moves": ["defog", "discharge", "heatwave", "hurricane", "roost", "uturn"],
"doublesLevel": 79,
"doublesMoves": ["heatwave", "hurricane", "roost", "tailwind", "thunderbolt", "voltswitch"]
@ -457,8 +457,8 @@
"noDynamaxMoves": ["dragondance", "dualwingbeat", "earthquake", "outrage", "roost"]
},
"mewtwo": {
"level": 70,
"moves": ["fireblast", "nastyplot", "psystrike", "recover", "shadowball"],
"level": 71,
"moves": ["aurasphere", "fireblast", "nastyplot", "psystrike", "recover"],
"doublesLevel": 74,
"doublesMoves": ["aurasphere", "icebeam", "nastyplot", "psystrike", "recover"]
},
@ -495,7 +495,7 @@
"doublesMoves": ["airslash", "heatwave", "lightscreen", "psychic", "reflect", "roost", "tailwind"]
},
"bellossom": {
"level": 82,
"level": 83,
"moves": ["gigadrain", "moonblast", "quiverdance", "sleeppowder", "strengthsap"],
"doublesLevel": 86,
"doublesMoves": ["energyball", "moonblast", "quiverdance", "sleeppowder", "strengthsap"]
@ -507,7 +507,7 @@
"doublesMoves": ["aquajet", "knockoff", "liquidation", "playrough", "protect"]
},
"sudowoodo": {
"level": 89,
"level": 90,
"moves": ["earthquake", "headsmash", "stealthrock", "suckerpunch", "woodhammer"],
"doublesLevel": 90,
"doublesMoves": ["bodypress", "firepunch", "headsmash", "protect", "suckerpunch", "woodhammer"]
@ -569,7 +569,7 @@
"noDynamaxMoves": ["curse", "earthquake", "headsmash", "heavyslam", "stealthrock", "toxic"]
},
"qwilfish": {
"level": 87,
"level": 86,
"moves": ["destinybond", "spikes", "taunt", "thunderwave", "toxicspikes", "waterfall"],
"doublesLevel": 88,
"doublesMoves": ["liquidation", "poisonjab", "protect", "taunt", "thunderwave", "toxicspikes"]
@ -641,7 +641,7 @@
"doublesMoves": ["icebeam", "recover", "thunderbolt", "toxic", "triattack", "trickroom"]
},
"hitmontop": {
"level": 86,
"level": 87,
"moves": ["closecombat", "earthquake", "rapidspin", "suckerpunch", "toxic", "tripleaxel"],
"doublesLevel": 88,
"doublesMoves": ["closecombat", "coaching", "fakeout", "helpinghand", "rapidspin", "suckerpunch", "tripleaxel"]
@ -708,7 +708,7 @@
"doublesMoves": ["breakingswipe", "energyball", "focusblast", "leafstorm"]
},
"blaziken": {
"level": 74,
"level": 75,
"moves": ["closecombat", "flareblitz", "knockoff", "stoneedge", "swordsdance"],
"doublesLevel": 78,
"doublesMoves": ["closecombat", "flareblitz", "knockoff", "protect", "swordsdance"]
@ -800,7 +800,7 @@
"doublesMoves": ["closecombat", "crunch", "flipturn", "icebeam", "protect", "waterfall"]
},
"wailord": {
"level": 91,
"level": 92,
"moves": ["hydropump", "hypervoice", "icebeam", "waterspout"],
"doublesLevel": 88,
"doublesMoves": ["hydropump", "heavyslam", "icebeam", "waterspout"]
@ -1065,7 +1065,7 @@
"doublesMoves": ["auroraveil", "blizzard", "iceshard", "protect", "woodhammer"]
},
"weavile": {
"level": 79,
"level": 78,
"moves": ["iceshard", "knockoff", "lowkick", "swordsdance", "tripleaxel"],
"doublesLevel": 84,
"doublesMoves": ["fakeout", "iceshard", "knockoff", "lowkick", "tripleaxel"]
@ -1119,7 +1119,7 @@
"doublesMoves": ["doubleedge", "knockoff", "leafblade", "protect", "swordsdance"]
},
"glaceon": {
"level": 91,
"level": 90,
"moves": ["freezedry", "protect", "toxic", "wish"],
"doublesLevel": 88,
"doublesMoves": ["blizzard", "freezedry", "helpinghand", "protect", "shadowball", "wish"]
@ -1186,7 +1186,7 @@
"doublesMoves": ["airslash", "nastyplot", "protect", "thunderbolt"]
},
"rotommow": {
"level": 84,
"level": 85,
"moves": ["leafstorm", "nastyplot", "thunderbolt", "trick", "voltswitch", "willowisp"],
"doublesLevel": 88,
"doublesMoves": ["electroweb", "leafstorm", "protect", "thunderbolt", "voltswitch", "willowisp"]
@ -1259,7 +1259,7 @@
"doublesMoves": ["boltstrike", "glaciate", "protect", "uturn", "vcreate", "zenheadbutt"]
},
"stoutland": {
"level": 87,
"level": 88,
"moves": ["crunch", "facade", "playrough", "superpower", "wildcharge"],
"doublesLevel": 90,
"doublesMoves": ["facade", "helpinghand", "superpower", "thunderwave"]
@ -1366,7 +1366,7 @@
"doublesMoves": ["closecombat", "highhorsepower", "knockoff", "protect", "rockslide", "taunt"]
},
"darmanitan": {
"level": 79,
"level": 78,
"moves": ["earthquake", "flareblitz", "rockslide", "superpower", "uturn"],
"doublesLevel": 82,
"doublesMoves": ["earthquake", "flareblitz", "protect", "rockslide", "superpower", "uturn"]
@ -1502,7 +1502,7 @@
"doublesMoves": ["geargrind", "protect", "shiftgear", "wildcharge"]
},
"beheeyem": {
"level": 89,
"level": 90,
"moves": ["darkpulse", "psychic", "thunderbolt", "trick", "trickroom"],
"doublesLevel": 88,
"doublesMoves": ["protect", "psychic", "shadowball", "thunderbolt", "trickroom"]
@ -1532,7 +1532,7 @@
"doublesMoves": ["freezedry", "haze", "icebeam", "icywind", "rapidspin", "recover", "toxic"]
},
"accelgor": {
"level": 91,
"level": 90,
"moves": ["bugbuzz", "energyball", "focusblast", "sludgebomb", "spikes", "toxicspikes", "yawn"],
"doublesLevel": 88,
"doublesMoves": ["acidspray", "bugbuzz", "encore", "energyball", "focusblast"],
@ -1599,7 +1599,7 @@
"doublesMoves": ["firelash", "gigadrain", "incinerate", "protect", "suckerpunch", "superpower"]
},
"durant": {
"level": 78,
"level": 77,
"moves": ["firstimpression", "honeclaws", "ironhead", "rockslide", "superpower"],
"doublesLevel": 82,
"doublesMoves": ["firstimpression", "ironhead", "protect", "stompingtantrum", "superpower", "xscissor"]
@ -1636,7 +1636,7 @@
"noDynamaxMoves": ["closecombat", "leafblade", "stoneedge", "swordsdance"]
},
"tornadus": {
"level": 81,
"level": 80,
"moves": ["defog", "grassknot", "heatwave", "hurricane", "nastyplot"],
"doublesLevel": 80,
"doublesMoves": ["heatwave", "hurricane", "nastyplot", "superpower", "tailwind", "taunt"]
@ -1725,7 +1725,7 @@
"doublesMoves": ["bodyslam", "highhorsepower", "knockoff", "quickattack", "swordsdance", "uturn"]
},
"talonflame": {
"level": 81,
"level": 80,
"moves": ["bravebird", "defog", "flareblitz", "roost", "swordsdance", "uturn"],
"doublesLevel": 86,
"doublesMoves": ["bravebird", "defog", "incinerate", "overheat", "tailwind", "uturn", "willowisp"]
@ -1771,7 +1771,7 @@
"doublesMoves": ["healpulse", "moonblast", "protect", "trickroom", "wish"]
},
"slurpuff": {
"level": 79,
"level": 80,
"moves": ["bellydrum", "drainpunch", "facade", "playrough"],
"doublesLevel": 86,
"doublesMoves": ["faketears", "flamethrower", "helpinghand", "playrough", "stickyweb"]
@ -1820,7 +1820,7 @@
},
"sylveon": {
"level": 83,
"moves": ["calmmind", "hypervoice", "mysticalfire", "protect", "psyshock", "shadowball", "wish"],
"moves": ["calmmind", "hypervoice", "mysticalfire", "protect", "psyshock", "wish"],
"doublesLevel": 80,
"doublesMoves": ["calmmind", "hypervoice", "mysticalfire", "protect", "psyshock"]
},
@ -1903,7 +1903,7 @@
"doublesMoves": ["dazzlinggleam", "focusblast", "geomancy", "moonblast", "thunderbolt"]
},
"yveltal": {
"level": 68,
"level": 67,
"moves": ["defog", "heatwave", "knockoff", "oblivionwing", "roost", "suckerpunch", "taunt"],
"doublesLevel": 71,
"doublesMoves": ["darkpulse", "heatwave", "knockoff", "oblivionwing", "roost", "suckerpunch", "tailwind"]
@ -2149,7 +2149,7 @@
},
"silvallyice": {
"level": 83,
"moves": ["flamecharge", "multiattack", "psychicfangs", "swordsdance"],
"moves": ["flamecharge", "multiattack", "rockslide", "swordsdance"],
"doublesLevel": 88,
"doublesMoves": ["flamethrower", "multiattack", "partingshot", "tailwind", "thunderbolt"]
},
@ -2161,7 +2161,7 @@
},
"silvallypsychic": {
"level": 83,
"moves": ["crunch", "multiattack", "swordsdance", "uturn"],
"moves": ["flamecharge", "multiattack", "swordsdance", "xscissor"],
"doublesLevel": 88,
"doublesMoves": ["flamethrower", "multiattack", "partingshot", "tailwind", "xscissor"]
},
@ -2214,13 +2214,13 @@
"doublesMoves": ["anchorshot", "knockoff", "powerwhip", "protect"]
},
"kommoo": {
"level": 81,
"level": 80,
"moves": ["clangingscales", "clangoroussoul", "closecombat", "poisonjab", "stealthrock"],
"doublesLevel": 80,
"doublesMoves": ["bodypress", "dracometeor", "irondefense", "protect"]
},
"tapukoko": {
"level": 76,
"level": 77,
"moves": ["calmmind", "dazzlinggleam", "grassknot", "substitute", "thunderbolt", "voltswitch"],
"doublesLevel": 80,
"doublesMoves": ["bravebird", "dazzlinggleam", "grassknot", "taunt", "thunderbolt", "uturn"]
@ -2269,13 +2269,13 @@
"noDynamaxMoves": ["bulkup", "closecombat", "darkestlariat", "leechlife", "poisonjab", "roost", "stoneedge"]
},
"pheromosa": {
"level": 74,
"level": 73,
"moves": ["closecombat", "icebeam", "poisonjab", "throatchop", "uturn"],
"doublesLevel": 78,
"doublesMoves": ["closecombat", "icebeam", "poisonjab", "protect", "throatchop", "uturn"]
},
"xurkitree": {
"level": 76,
"level": 77,
"moves": ["dazzlinggleam", "energyball", "hypnosis", "thunderbolt", "voltswitch"],
"doublesLevel": 79,
"doublesMoves": ["dazzlinggleam", "energyball", "thunderbolt", "voltswitch"]
@ -2288,7 +2288,7 @@
"noDynamaxMoves": ["airslash", "earthquake", "fireblast", "heavyslam", "leechseed", "protect"]
},
"kartana": {
"level": 72,
"level": 73,
"moves": ["knockoff", "leafblade", "sacredsword", "smartstrike", "swordsdance"],
"doublesLevel": 78,
"doublesMoves": ["knockoff", "leafblade", "sacredsword", "smartstrike", "swordsdance"]
@ -2456,17 +2456,17 @@
"doublesMoves": ["acrobatics", "dragondance", "dragonrush", "gravapple", "protect"]
},
"appletun": {
"level": 91,
"level": 92,
"moves": ["appleacid", "dragonpulse", "leechseed", "recover"],
"doublesLevel": 90,
"doublesMoves": ["appleacid", "dragonpulse", "leechseed", "protect", "recover"]
},
"appletungmax": {
"level": 91,
"level": 92,
"moves": ["appleacid", "dracometeor", "leechseed", "recover"]
},
"sandaconda": {
"level": 83,
"level": 84,
"moves": ["coil", "earthquake", "glare", "rest", "stealthrock", "stoneedge"]
},
"sandacondagmax": {
@ -2565,7 +2565,7 @@
"noDynamaxMoves": ["bravebird", "closecombat", "firstimpression", "knockoff", "poisonjab", "swordsdance"]
},
"mrrime": {
"level": 87,
"level": 88,
"moves": ["focusblast", "freezedry", "psychic", "rapidspin", "slackoff", "trick"],
"doublesLevel": 88,
"doublesMoves": ["fakeout", "focusblast", "freezedry", "icywind", "protect", "psychic", "rapidspin"]
@ -2613,7 +2613,7 @@
"doublesMoves": ["bellydrum", "iciclecrash", "liquidation", "protect"]
},
"indeedee": {
"level": 85,
"level": 84,
"moves": ["calmmind", "expandingforce", "hypervoice", "mysticalfire", "trick"],
"doublesLevel": 80,
"doublesMoves": ["encore", "expandingforce", "hypervoice", "mysticalfire", "protect", "trick"]
@ -2625,7 +2625,7 @@
"doublesMoves": ["expandingforce", "followme", "healpulse", "helpinghand", "protect"]
},
"morpeko": {
"level": 86,
"level": 85,
"moves": ["aurawheel", "foulplay", "partingshot", "protect", "psychicfangs", "rapidspin"],
"doublesLevel": 88,
"doublesMoves": ["aurawheel", "fakeout", "partingshot", "protect", "rapidspin", "superfang"]
@ -2690,7 +2690,7 @@
"doublesMoves": ["behemothblade", "closecombat", "playrough", "protect", "psychicfangs", "swordsdance"]
},
"zamazenta": {
"level": 70,
"level": 69,
"moves": ["closecombat", "crunch", "psychicfangs", "wildcharge"],
"doublesLevel": 74,
"doublesMoves": ["closecombat", "crunch", "playrough", "protect", "psychicfangs"]

View File

@ -1526,7 +1526,7 @@ export class RandomGen8Teams {
case 'Cloud Nine':
return (!isNoDynamax || species.id !== 'golduck');
case 'Competitive':
return (counter.get('Special') < 2 || (moves.has('rest') && moves.has('sleeptalk')));
return species.id === 'boltund';
case 'Compound Eyes': case 'No Guard':
return !counter.get('inaccurate');
case 'Cursed Body':

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -757,7 +757,7 @@
"item": ["Choice Specs"],
"ability": ["Infiltrator"],
"evs": {"spa": 252, "spd": 4, "spe": 252},
"nature": ["Timid", "Modest"],
"nature": ["Timid"],
"teraType": ["Dragon", "Ghost"],
"moves": [["Draco Meteor"], ["Shadow Ball"], ["Flamethrower"], ["U-turn"]]
}, {

View File

@ -60,13 +60,13 @@
"teraTypes": ["Dark", "Ground"]
},
{
"role": "Setup Sweeper",
"role": "Bulky Setup",
"movepool": ["Coil", "Earthquake", "Gunk Shot", "Trailblaze"],
"abilities": ["Intimidate"],
"teraTypes": ["Grass", "Ground"]
},
{
"role": "Fast Bulky Setup",
"role": "Bulky Attacker",
"movepool": ["Coil", "Earthquake", "Gunk Shot", "Sucker Punch"],
"abilities": ["Intimidate"],
"teraTypes": ["Dark", "Ground"]
@ -77,7 +77,7 @@
"level": 93,
"sets": [
{
"role": "Fast Attacker",
"role": "AV Pivot",
"movepool": ["Fake Out", "Knock Off", "Play Rough", "Surf", "Volt Switch", "Volt Tackle"],
"abilities": ["Lightning Rod"],
"teraTypes": ["Water"]
@ -185,7 +185,7 @@
},
{
"role": "Fast Attacker",
"movepool": ["Aurora Veil", "Blizzard", "Freeze-Dry", "Moonblast", "Nasty Plot"],
"movepool": ["Aurora Veil", "Blizzard", "Freeze-Dry", "Moonblast"],
"abilities": ["Snow Warning"],
"teraTypes": ["Steel", "Water"]
}
@ -296,7 +296,7 @@
"level": 90,
"sets": [
{
"role": "Fast Bulky Setup",
"role": "Bulky Setup",
"movepool": ["Encore", "Grass Knot", "Hydro Pump", "Ice Beam", "Nasty Plot"],
"abilities": ["Cloud Nine", "Swift Swim"],
"teraTypes": ["Water"]
@ -643,7 +643,7 @@
},
{
"role": "Bulky Setup",
"movepool": ["Calm Mind", "Giga Drain", "Psychic", "Psyshock", "Substitute"],
"movepool": ["Calm Mind", "Giga Drain", "Psychic", "Psyshock", "Sleep Powder", "Substitute"],
"abilities": ["Harvest"],
"teraTypes": ["Steel"]
}
@ -694,8 +694,8 @@
"sets": [
{
"role": "Setup Sweeper",
"movepool": ["Close Combat", "Drain Punch", "Ice Punch", "Knock Off", "Mach Punch", "Rapid Spin", "Swords Dance"],
"abilities": ["Inner Focus", "Iron Fist"],
"movepool": ["Drain Punch", "Ice Punch", "Knock Off", "Mach Punch", "Rapid Spin", "Swords Dance"],
"abilities": ["Iron Fist"],
"teraTypes": ["Dark", "Fighting"]
},
{
@ -703,6 +703,12 @@
"movepool": ["Bulk Up", "Drain Punch", "Knock Off", "Poison Jab", "Rapid Spin"],
"abilities": ["Iron Fist"],
"teraTypes": ["Dark", "Poison", "Steel"]
},
{
"role": "Bulky Support",
"movepool": ["Drain Punch", "Encore", "Knock Off", "Poison Jab", "Rapid Spin", "Taunt"],
"abilities": ["Iron Fist"],
"teraTypes": ["Steel"]
}
]
},
@ -1417,6 +1423,12 @@
"movepool": ["Body Press", "Iron Head", "Rapid Spin", "Spikes", "Stealth Rock"],
"abilities": ["Sturdy"],
"teraTypes": ["Fighting", "Water"]
},
{
"role": "Bulky Support",
"movepool": ["Iron Head", "Rapid Spin", "Spikes", "Stealth Rock", "Thunder Wave"],
"abilities": ["Sturdy"],
"teraTypes": ["Water"]
}
]
},
@ -2124,7 +2136,7 @@
"sets": [
{
"role": "Bulky Attacker",
"movepool": ["Clear Smog", "Earthquake", "Encore", "Ice Beam", "Knock Off", "Pain Split", "Sludge Bomb", "Toxic Spikes"],
"movepool": ["Clear Smog", "Earthquake", "Encore", "Ice Beam", "Knock Off", "Pain Split", "Sludge Bomb", "Thunder Wave", "Toxic Spikes"],
"abilities": ["Liquid Ooze"],
"teraTypes": ["Dark"]
},
@ -2259,7 +2271,7 @@
"teraTypes": ["Dark", "Fire", "Grass", "Ground", "Poison"]
},
{
"role": "Setup Sweeper",
"role": "Bulky Setup",
"movepool": ["Earthquake", "Gunk Shot", "Swords Dance", "Trailblaze"],
"abilities": ["Infiltrator"],
"teraTypes": ["Grass", "Ground"]
@ -2367,7 +2379,7 @@
"sets": [
{
"role": "Fast Support",
"movepool": ["Disable", "Earthquake", "Freeze-Dry", "Spikes", "Taunt"],
"movepool": ["Earthquake", "Freeze-Dry", "Spikes", "Taunt"],
"abilities": ["Inner Focus"],
"teraTypes": ["Ghost", "Ground", "Water"]
}
@ -2376,6 +2388,12 @@
"luvdisc": {
"level": 100,
"sets": [
{
"role": "Fast Support",
"movepool": ["Endeavor", "Flip Turn", "Substitute", "Surf"],
"abilities": ["Swift Swim"],
"teraTypes": ["Ghost", "Ground"]
},
{
"role": "Fast Support",
"movepool": ["Endeavor", "Substitute", "Surf", "Whirlpool"],
@ -2694,7 +2712,7 @@
"sets": [
{
"role": "Fast Support",
"movepool": ["Knock Off", "Pounce", "Sticky Web", "Swords Dance", "Taunt"],
"movepool": ["Knock Off", "Pounce", "Sticky Web", "Taunt"],
"abilities": ["Technician"],
"teraTypes": ["Ghost"]
}
@ -3044,14 +3062,14 @@
{
"role": "Fast Attacker",
"movepool": ["Body Press", "Flash Cannon", "Thunderbolt", "Volt Switch"],
"abilities": ["Magnet Pull"],
"teraTypes": ["Electric", "Fighting", "Flying", "Water"]
"abilities": ["Analytic", "Magnet Pull"],
"teraTypes": ["Electric", "Fighting", "Flying"]
},
{
"role": "AV Pivot",
"movepool": ["Body Press", "Discharge", "Flash Cannon", "Mirror Coat", "Thunderbolt", "Volt Switch"],
"abilities": ["Analytic", "Magnet Pull"],
"teraTypes": ["Flying", "Water"]
"teraTypes": ["Flying"]
},
{
"role": "Bulky Setup",
@ -3220,7 +3238,7 @@
]
},
"probopass": {
"level": 92,
"level": 91,
"sets": [
{
"role": "Bulky Setup",
@ -3282,7 +3300,13 @@
"role": "Bulky Attacker",
"movepool": ["Hydro Pump", "Nasty Plot", "Pain Split", "Thunderbolt", "Trick", "Volt Switch", "Will-O-Wisp"],
"abilities": ["Levitate"],
"teraTypes": ["Electric", "Water"]
"teraTypes": ["Electric", "Steel"]
},
{
"role": "Bulky Support",
"movepool": ["Discharge", "Hydro Pump", "Pain Split", "Volt Switch", "Will-O-Wisp"],
"abilities": ["Levitate"],
"teraTypes": ["Electric", "Steel"]
}
]
},
@ -3293,7 +3317,13 @@
"role": "Bulky Attacker",
"movepool": ["Nasty Plot", "Overheat", "Pain Split", "Thunderbolt", "Volt Switch", "Will-O-Wisp"],
"abilities": ["Levitate"],
"teraTypes": ["Electric", "Fire"]
"teraTypes": ["Electric", "Fire", "Steel"]
},
{
"role": "Bulky Support",
"movepool": ["Discharge", "Overheat", "Pain Split", "Volt Switch", "Will-O-Wisp"],
"abilities": ["Levitate"],
"teraTypes": ["Electric", "Steel"]
}
]
},
@ -3313,7 +3343,7 @@
"sets": [
{
"role": "Bulky Attacker",
"movepool": ["Air Slash", "Nasty Plot", "Thunderbolt", "Volt Switch", "Will-O-Wisp"],
"movepool": ["Air Slash", "Nasty Plot", "Thunder Wave", "Thunderbolt", "Volt Switch", "Will-O-Wisp"],
"abilities": ["Levitate"],
"teraTypes": ["Electric", "Steel"]
}
@ -3375,9 +3405,9 @@
},
{
"role": "Fast Attacker",
"movepool": ["Dazzling Gleam", "Fire Blast", "Nasty Plot", "Psychic", "Psyshock", "Thunderbolt", "Trick", "U-turn"],
"movepool": ["Dazzling Gleam", "Fire Blast", "Nasty Plot", "Psychic", "Psyshock", "U-turn"],
"abilities": ["Levitate"],
"teraTypes": ["Electric", "Fairy", "Fire", "Psychic"]
"teraTypes": ["Fairy", "Fire", "Psychic"]
}
]
},
@ -3734,21 +3764,15 @@
"level": 69,
"sets": [
{
"role": "Bulky Support",
"movepool": ["Focus Blast", "Judgment", "Recover", "Will-O-Wisp"],
"role": "Bulky Attacker",
"movepool": ["Calm Mind", "Focus Blast", "Judgment", "Recover", "Will-O-Wisp"],
"abilities": ["Multitype"],
"teraTypes": ["Fighting", "Normal"]
},
{
"role": "Bulky Setup",
"movepool": ["Calm Mind", "Focus Blast", "Judgment", "Recover"],
"abilities": ["Multitype"],
"teraTypes": ["Fighting", "Ghost", "Normal"]
"teraTypes": ["Dark", "Fighting"]
}
]
},
"arceusgrass": {
"level": 72,
"level": 73,
"sets": [
{
"role": "Setup Sweeper",
@ -3788,7 +3812,7 @@
]
},
"arceusice": {
"level": 72,
"level": 73,
"sets": [
{
"role": "Bulky Setup",
@ -3904,7 +3928,7 @@
"teraTypes": ["Fire"]
},
{
"role": "Setup Sweeper",
"role": "Bulky Setup",
"movepool": ["Bulk Up", "Drain Punch", "Flare Blitz", "Trailblaze"],
"abilities": ["Reckless"],
"teraTypes": ["Fighting", "Grass"]
@ -3994,13 +4018,13 @@
"sets": [
{
"role": "Fast Support",
"movepool": ["Knock Off", "Leaf Blade", "Lunge", "Sticky Web", "Swords Dance"],
"movepool": ["Knock Off", "Leaf Blade", "Lunge", "Sticky Web"],
"abilities": ["Chlorophyll", "Swarm"],
"teraTypes": ["Ghost", "Rock"]
},
{
"role": "Fast Attacker",
"movepool": ["Bullet Seed", "Knock Off", "Sticky Web", "Swords Dance", "Triple Axel"],
"movepool": ["Bullet Seed", "Knock Off", "Sticky Web", "Triple Axel"],
"abilities": ["Chlorophyll"],
"teraTypes": ["Ghost", "Rock"]
}
@ -4019,7 +4043,7 @@
"role": "Bulky Support",
"movepool": ["Encore", "Leech Seed", "Moonblast", "Substitute"],
"abilities": ["Prankster"],
"teraTypes": ["Steel"]
"teraTypes": ["Poison", "Steel"]
}
]
},
@ -4095,9 +4119,15 @@
"sets": [
{
"role": "Fast Attacker",
"movepool": ["Bulk Up", "Earthquake", "Gunk Shot", "Knock Off", "Stealth Rock", "Stone Edge"],
"movepool": ["Earthquake", "Gunk Shot", "Knock Off", "Stealth Rock", "Stone Edge"],
"abilities": ["Intimidate"],
"teraTypes": ["Ground", "Poison"]
},
{
"role": "Bulky Setup",
"movepool": ["Bulk Up", "Earthquake", "Gunk Shot", "Knock Off"],
"abilities": ["Intimidate"],
"teraTypes": ["Poison"]
}
]
},
@ -4110,12 +4140,6 @@
"abilities": ["Shed Skin"],
"teraTypes": ["Poison"]
},
{
"role": "Setup Sweeper",
"movepool": ["Close Combat", "Dragon Dance", "Knock Off", "Poison Jab"],
"abilities": ["Intimidate"],
"teraTypes": ["Poison"]
},
{
"role": "Bulky Attacker",
"movepool": ["Dragon Dance", "Drain Punch", "Knock Off", "Poison Jab"],
@ -4202,7 +4226,7 @@
"sets": [
{
"role": "Bulky Support",
"movepool": ["Brave Bird", "Defog", "Hydro Pump", "Knock Off", "Roost"],
"movepool": ["Brave Bird", "Defog", "Flip Turn", "Hydro Pump", "Knock Off", "Roost"],
"abilities": ["Hydration"],
"teraTypes": ["Ground"]
}
@ -4249,13 +4273,13 @@
"role": "Bulky Support",
"movepool": ["Flip Turn", "Protect", "Scald", "Wish"],
"abilities": ["Regenerator"],
"teraTypes": ["Steel"]
"teraTypes": ["Poison", "Steel"]
},
{
"role": "Fast Support",
"movepool": ["Flip Turn", "Protect", "Scald", "Wish"],
"abilities": ["Regenerator"],
"teraTypes": ["Steel"]
"teraTypes": ["Poison", "Steel"]
}
]
},
@ -4264,7 +4288,7 @@
"sets": [
{
"role": "Fast Support",
"movepool": ["Bug Buzz", "Giga Drain", "Sticky Web", "Thunder", "Volt Switch"],
"movepool": ["Bug Buzz", "Energy Ball", "Sticky Web", "Thunder", "Volt Switch"],
"abilities": ["Compound Eyes"],
"teraTypes": ["Electric"]
}
@ -4490,7 +4514,7 @@
},
{
"role": "Bulky Support",
"movepool": ["Body Press", "Iron Defense", "Iron Head", "Stealth Rock", "Stone Edge", "Thunder Wave", "Volt Switch"],
"movepool": ["Body Press", "Iron Defense", "Iron Head", "Stealth Rock", "Thunder Wave", "Volt Switch"],
"abilities": ["Justified"],
"teraTypes": ["Ghost", "Water"]
}
@ -4795,7 +4819,7 @@
{
"role": "Tera Blast user",
"movepool": ["Brave Bird", "Flare Blitz", "Swords Dance", "Tera Blast"],
"abilities": ["Flame Body"],
"abilities": ["Flame Body", "Gale Wings"],
"teraTypes": ["Ground"]
}
]
@ -5011,7 +5035,7 @@
"sets": [
{
"role": "Wallbreaker",
"movepool": ["Drain Punch", "Horn Leech", "Poltergeist", "Rest", "Trick Room", "Will-O-Wisp", "Wood Hammer"],
"movepool": ["Drain Punch", "Horn Leech", "Poltergeist", "Rest", "Will-O-Wisp", "Wood Hammer"],
"abilities": ["Natural Cure"],
"teraTypes": ["Fighting"]
},
@ -5325,7 +5349,7 @@
"sets": [
{
"role": "Fast Attacker",
"movepool": ["Close Combat", "Knock Off", "Stealth Rock", "Stone Edge", "Sucker Punch", "Swords Dance"],
"movepool": ["Close Combat", "Knock Off", "Play Rough", "Stealth Rock", "Stone Edge", "Sucker Punch", "Swords Dance"],
"abilities": ["No Guard"],
"teraTypes": ["Fighting"]
}
@ -5502,12 +5526,6 @@
"komala": {
"level": 89,
"sets": [
{
"role": "Fast Attacker",
"movepool": ["Double-Edge", "Earthquake", "Knock Off", "Superpower", "U-turn", "Wood Hammer"],
"abilities": ["Comatose"],
"teraTypes": ["Fighting", "Grass", "Ground"]
},
{
"role": "Bulky Support",
"movepool": ["Body Slam", "Earthquake", "Knock Off", "Rapid Spin", "U-turn"],
@ -5521,9 +5539,9 @@
"sets": [
{
"role": "Setup Sweeper",
"movepool": ["Drain Punch", "Play Rough", "Shadow Sneak", "Swords Dance", "Wood Hammer"],
"movepool": ["Drain Punch", "Play Rough", "Shadow Sneak", "Swords Dance"],
"abilities": ["Disguise"],
"teraTypes": ["Fairy", "Fighting", "Grass"]
"teraTypes": ["Fairy", "Fighting"]
},
{
"role": "Fast Bulky Setup",
@ -5549,7 +5567,7 @@
"sets": [
{
"role": "Fast Bulky Setup",
"movepool": ["Boomburst", "Clanging Scales", "Clangorous Soul", "Close Combat", "Iron Head"],
"movepool": ["Boomburst", "Clanging Scales", "Clangorous Soul", "Close Combat", "Drain Punch", "Iron Head"],
"abilities": ["Soundproof"],
"teraTypes": ["Normal", "Steel"]
},
@ -5604,6 +5622,12 @@
"abilities": ["Prism Armor"],
"teraTypes": ["Dark", "Ground", "Steel"]
},
{
"role": "Bulky Setup",
"movepool": ["Dragon Dance", "Earthquake", "Knock Off", "Photon Geyser"],
"abilities": ["Prism Armor"],
"teraTypes": ["Dark", "Ground", "Steel"]
},
{
"role": "Bulky Setup",
"movepool": ["Calm Mind", "Earth Power", "Heat Wave", "Moonlight", "Photon Geyser"],
@ -5622,7 +5646,7 @@
"teraTypes": ["Ground", "Steel", "Water"]
},
{
"role": "Setup Sweeper",
"role": "Bulky Setup",
"movepool": ["Dragon Dance", "Earthquake", "Photon Geyser", "Sunsteel Strike"],
"abilities": ["Prism Armor"],
"teraTypes": ["Ground", "Steel", "Water"]
@ -5659,7 +5683,7 @@
"role": "Bulky Setup",
"movepool": ["Calm Mind", "Flash Cannon", "Fleur Cannon", "Shift Gear"],
"abilities": ["Soul-Heart"],
"teraTypes": ["Fairy", "Flying", "Steel", "Water"]
"teraTypes": ["Fairy", "Flying", "Water"]
},
{
"role": "Tera Blast user",
@ -5697,9 +5721,9 @@
},
{
"role": "Fast Support",
"movepool": ["Court Change", "High Jump Kick", "Pyro Ball", "Sucker Punch"],
"movepool": ["Court Change", "Pyro Ball", "U-turn", "Will-O-Wisp"],
"abilities": ["Libero"],
"teraTypes": ["Fighting", "Fire"]
"teraTypes": ["Grass"]
},
{
"role": "Fast Attacker",
@ -6449,16 +6473,22 @@
"level": 79,
"sets": [
{
"role": "Fast Support",
"movepool": ["Aqua Step", "Close Combat", "Knock Off", "Rapid Spin", "Roost", "Triple Axel", "U-turn"],
"role": "Wallbreaker",
"movepool": ["Aqua Step", "Close Combat", "Knock Off", "Triple Axel", "U-turn"],
"abilities": ["Moxie"],
"teraTypes": ["Fighting", "Water"]
},
{
"role": "Setup Sweeper",
"movepool": ["Aqua Step", "Close Combat", "Encore", "Knock Off", "Roost", "Swords Dance", "Triple Axel"],
"movepool": ["Aqua Step", "Close Combat", "Encore", "Knock Off", "Swords Dance", "Triple Axel"],
"abilities": ["Moxie"],
"teraTypes": ["Fighting", "Water"]
"teraTypes": ["Fighting", "Steel", "Water"]
},
{
"role": "Bulky Attacker",
"movepool": ["Aqua Step", "Close Combat", "Rapid Spin", "Roost", "Swords Dance"],
"abilities": ["Moxie"],
"teraTypes": ["Steel"]
}
]
},
@ -6557,7 +6587,7 @@
"sets": [
{
"role": "Bulky Support",
"movepool": ["Body Press", "Play Rough", "Protect", "Stomping Tantrum", "Wish"],
"movepool": ["Body Press", "Play Rough", "Protect", "Wish", "Yawn"],
"abilities": ["Well-Baked Body"],
"teraTypes": ["Steel"]
}
@ -6831,7 +6861,7 @@
"teraTypes": ["Water"]
},
{
"role": "Setup Sweeper",
"role": "Bulky Setup",
"movepool": ["Gigaton Hammer", "Knock Off", "Play Rough", "Protect", "Swords Dance"],
"abilities": ["Mold Breaker"],
"teraTypes": ["Steel"]
@ -7049,12 +7079,6 @@
"movepool": ["Body Slam", "Protect", "Psychic Noise", "Wish"],
"abilities": ["Sap Sipper"],
"teraTypes": ["Fairy", "Ground", "Water"]
},
{
"role": "Bulky Attacker",
"movepool": ["Future Sight", "Hyper Voice", "Protect", "Wish"],
"abilities": ["Sap Sipper"],
"teraTypes": ["Fairy", "Ground", "Water"]
}
]
},
@ -7120,7 +7144,7 @@
"sets": [
{
"role": "Bulky Attacker",
"movepool": ["Close Combat", "Seed Bomb", "Spore", "Sucker Punch"],
"movepool": ["Close Combat", "Crunch", "Spore", "Sucker Punch"],
"abilities": ["Protosynthesis"],
"teraTypes": ["Fighting", "Poison"]
},
@ -7280,7 +7304,7 @@
]
},
"ironjugulis": {
"level": 78,
"level": 77,
"sets": [
{
"role": "Wallbreaker",
@ -7314,11 +7338,11 @@
]
},
"ironbundle": {
"level": 77,
"level": 78,
"sets": [
{
"role": "Fast Attacker",
"movepool": ["Encore", "Flip Turn", "Freeze-Dry", "Hydro Pump", "Ice Beam", "Substitute"],
"movepool": ["Encore", "Flip Turn", "Freeze-Dry", "Hydro Pump", "Ice Beam"],
"abilities": ["Quark Drive"],
"teraTypes": ["Ice", "Water"]
}
@ -7426,7 +7450,7 @@
},
{
"role": "Setup Sweeper",
"movepool": ["Ice Shard", "Icicle Crash", "Sacred Sword", "Sucker Punch", "Swords Dance", "Throat Chop"],
"movepool": ["Icicle Crash", "Sacred Sword", "Sucker Punch", "Swords Dance", "Throat Chop"],
"abilities": ["Sword of Ruin"],
"teraTypes": ["Dark", "Fighting", "Ice"]
}
@ -7481,8 +7505,8 @@
"level": 65,
"sets": [
{
"role": "Fast Bulky Setup",
"movepool": ["Calm Mind", "Draco Meteor", "Electro Drift", "Substitute"],
"role": "Setup Sweeper",
"movepool": ["Calm Mind", "Draco Meteor", "Dragon Pulse", "Electro Drift"],
"abilities": ["Hadron Engine"],
"teraTypes": ["Electric"]
},

View File

@ -37,6 +37,7 @@ interface BattleFactorySet {
evs?: Partial<StatsTable>;
ivs?: Partial<StatsTable>;
shiny?: boolean;
level?: number;
}
interface BSSFactorySet {
species: string;
@ -103,7 +104,7 @@ const SPEED_CONTROL = [
];
// Moves that shouldn't be the only STAB moves:
const NO_STAB = [
'accelerock', 'aquajet', 'bounce', 'breakingswipe', 'bulletpunch', 'chatter', 'chloroblast', 'clearsmog', 'covet',
'acidspray', 'accelerock', 'aquajet', 'bounce', 'breakingswipe', 'bulletpunch', 'chatter', 'chloroblast', 'clearsmog', 'covet',
'dragontail', 'doomdesire', 'electroweb', 'eruption', 'explosion', 'fakeout', 'feint', 'flamecharge', 'flipturn', 'futuresight',
'grassyglide', 'iceshard', 'icywind', 'incinerate', 'infestation', 'machpunch', 'meteorbeam', 'mortalspin', 'nuzzle', 'pluck', 'pursuit',
'quickattack', 'rapidspin', 'reversal', 'selfdestruct', 'shadowsneak', 'skydrop', 'snarl', 'strugglebug', 'suckerpunch', 'trailblaze',
@ -145,7 +146,7 @@ const DOUBLES_NO_LEAD_POKEMON = [
];
const DEFENSIVE_TERA_BLAST_USERS = [
'alcremie', 'bellossom', 'comfey', 'fezandipiti', 'florges', 'raikou',
'alcremie', 'bellossom', 'comfey', 'fezandipiti', 'florges',
];
function sereneGraceBenefits(move: Move) {
@ -245,7 +246,9 @@ export class RandomTeams {
!counter.get('Steel') &&
(isDoubles || species.baseStats.atk >= 90 || movePool.includes('gigatonhammer') || movePool.includes('makeitrain'))
),
Water: (movePool, moves, abilities, types, counter) => (!counter.get('Water') && !types.includes('Ground')),
Water: (movePool, moves, abilities, types, counter, species, teamDetails, isLead, isDoubles) => (
!counter.get('Water') && (!types.includes('Ground') || isDoubles)
),
};
this.poolsCacheKey = undefined;
this.cachedPool = undefined;
@ -500,7 +503,7 @@ export class RandomTeams {
// Team-based move culls
if (teamDetails.screens) {
if (movePool.includes('auroraveil')) this.fastPop(movePool, movePool.indexOf('auroraveil'));
if (movePool.includes('auroraveil') && !isDoubles) this.fastPop(movePool, movePool.indexOf('auroraveil'));
if (movePool.length >= this.maxMoveCount + 2) {
if (movePool.includes('reflect')) this.fastPop(movePool, movePool.indexOf('reflect'));
if (movePool.includes('lightscreen')) this.fastPop(movePool, movePool.indexOf('lightscreen'));
@ -567,7 +570,6 @@ export class RandomTeams {
[SETUP, HAZARDS],
[SETUP, ['defog', 'nuzzle', 'toxic', 'yawn', 'haze']],
[PHYSICAL_SETUP, PHYSICAL_SETUP],
[SPECIAL_SETUP, 'thunderwave'],
['substitute', PIVOT_MOVES],
[SPEED_SETUP, ['aquajet', 'rest', 'trickroom']],
['curse', ['irondefense', 'rapidspin']],
@ -834,11 +836,6 @@ export class RandomTeams {
counter = this.addMove('tailwind', moves, types, abilities, teamDetails, species, isLead, isDoubles,
movePool, teraType, role);
}
// Enforce Thunder Wave on Prankster users as well
if (movePool.includes('thunderwave') && abilities.includes('Prankster')) {
counter = this.addMove('thunderwave', moves, types, abilities, teamDetails, species, isLead, isDoubles,
movePool, teraType, role);
}
}
// Enforce STAB priority
@ -1104,7 +1101,6 @@ export class RandomTeams {
// Hard-code abilities here
if (species.id === 'drifblim') return moves.has('defog') ? 'Aftermath' : 'Unburden';
if (abilities.includes('Flash Fire') && this.dex.getEffectiveness('Fire', teraType) >= 1) return 'Flash Fire';
if (species.id === 'hitmonchan' && counter.get('ironfist')) return 'Iron Fist';
if ((species.id === 'thundurus' || species.id === 'tornadus') && !counter.get('Physical')) return 'Prankster';
if (species.id === 'swampert' && (counter.get('Water') || moves.has('flipturn'))) return 'Torrent';
if (species.id === 'toucannon' && counter.get('skilllink')) return 'Skill Link';
@ -1163,19 +1159,19 @@ export class RandomTeams {
}
return this.sample(species.requiredItems);
}
if (role === 'AV Pivot') return 'Assault Vest';
if (species.id === 'pikachu') return 'Light Ball';
if (role === 'AV Pivot') return 'Assault Vest';
if (species.id === 'regieleki') return 'Magnet';
if (types.includes('Normal') && moves.has('doubleedge') && moves.has('fakeout')) return 'Silk Scarf';
if (
species.id === 'froslass' || moves.has('populationbomb') ||
(ability === 'Hustle' && counter.get('setup') && !isDoubles && this.randomChance(1, 2))
) return 'Wide Lens';
if (species.id === 'smeargle' && !isDoubles) return 'Focus Sash';
if (species.id === 'smeargle') return 'Focus Sash';
if (moves.has('clangoroussoul') || (species.id === 'toxtricity' && moves.has('shiftgear'))) return 'Throat Spray';
if (
(species.baseSpecies === 'Magearna' && role === 'Tera Blast user') ||
species.id === 'necrozmaduskmane' || (species.id === 'calyrexice' && isDoubles)
((species.id === 'calyrexice' || species.id === 'necrozmaduskmane') && isDoubles)
) return 'Weakness Policy';
if (['dragonenergy', 'lastrespects', 'waterspout'].some(m => moves.has(m))) return 'Choice Scarf';
if (
@ -1291,9 +1287,14 @@ export class RandomTeams {
(role === 'Bulky Protect' && counter.get('setup')) ||
['irondefense', 'coil', 'acidarmor', 'wish'].some(m => moves.has(m)) ||
(counter.get('recovery') && !moves.has('strengthsap') && !counter.get('speedcontrol') && !offensiveRole) ||
(PROTECT_MOVES.some(m => moves.has(m)) && moves.has('leechseed')) ||
species.id === 'regigigas'
) return 'Leftovers';
if (species.id === 'sylveon') return 'Pixie Plate';
if (moves.has('hypervoice') && !types.includes('Normal')) return 'Throat Spray';
if (
role === 'Doubles Fast Attacker' && !counter.get('recoil') &&
species.baseStats.hp + species.baseStats.def + species.baseStats.spd <= 230
) return 'Focus Sash';
if (
(offensiveRole || (role === 'Tera Blast user' && (species.baseStats.spe >= 80 || moves.has('trickroom')))) &&
!moves.has('fakeout') &&
@ -1306,7 +1307,7 @@ export class RandomTeams {
) ? 'Booster Energy' : 'Life Orb';
}
if (isLead && (species.id === 'glimmora' ||
(['Doubles Fast Attacker', 'Doubles Wallbreaker', 'Offensive Protect'].includes(role) &&
(['Doubles Wallbreaker', 'Offensive Protect'].includes(role) &&
species.baseStats.hp + species.baseStats.def + species.baseStats.spd <= 230))
) return 'Focus Sash';
if (
@ -1329,17 +1330,17 @@ export class RandomTeams {
teraType: string,
role: RandomTeamsTypes.Role,
): string {
const lifeOrbReqs = ['flamecharge', 'nuzzle', 'rapidspin', 'trailblaze'].every(m => !moves.has(m));
const lifeOrbReqs = ['flamecharge', 'nuzzle', 'rapidspin'].every(m => !moves.has(m));
if (
species.id !== 'jirachi' && (counter.get('Physical') >= moves.size) &&
['dragontail', 'fakeout', 'firstimpression', 'flamecharge', 'rapidspin'].every(m => !moves.has(m))
['dragontail', 'fakeout', 'firstimpression', 'flamecharge', 'rapidspin', 'trailblaze'].every(m => !moves.has(m))
) {
const scarfReqs = (
role !== 'Wallbreaker' &&
(species.baseStats.atk >= 100 || ability === 'Huge Power' || ability === 'Pure Power') &&
species.baseStats.spe >= 60 && species.baseStats.spe <= 108 &&
ability !== 'Speed Boost' && !counter.get('priority') && !moves.has('aquastep')
ability !== 'Speed Boost' && !counter.get('priority')
);
return (scarfReqs && this.randomChance(1, 2)) ? 'Choice Scarf' : 'Choice Band';
}
@ -1355,7 +1356,7 @@ export class RandomTeams {
);
return (scarfReqs && this.randomChance(1, 2)) ? 'Choice Scarf' : 'Choice Specs';
}
if (counter.get('speedsetup') && role === 'Bulky Setup') return 'Weakness Policy';
if (counter.get('speedsetup') && !counter.get('physicalsetup') && role === 'Bulky Setup') return 'Weakness Policy';
if (
!counter.get('Status') &&
!['Fast Attacker', 'Wallbreaker', 'Tera Blast user'].includes(role)
@ -1378,6 +1379,7 @@ export class RandomTeams {
) return 'Heavy-Duty Boots';
// Low Priority
if (moves.has('dragondance') && role === 'Bulky Setup') return 'Weakness Policy';
if (
ability === 'Rough Skin' || (
ability === 'Regenerator' && (role === 'Bulky Support' || role === 'Bulky Attacker') &&
@ -1587,6 +1589,7 @@ export class RandomTeams {
return {
name: species.baseSpecies,
species: forme,
speciesId: species.id,
gender: species.baseSpecies === 'Greninja' ? 'M' : (species.gender || (this.random(2) ? 'F' : 'M')),
shiny: this.randomChance(1, 1024),
level,
@ -1635,6 +1638,79 @@ export class RandomTeams {
return [pokemonPool, baseSpeciesPool];
}
/**
* Checks if the new species is compatible with the other mons currently on the team.
*/
getPokemonCompatibility(
species: Species,
pokemon: RandomTeamsTypes.RandomSet[],
isDoubles = false
): boolean {
const webSetters = [
'ariados', 'smeargle', 'masquerain', 'kricketune', 'leavanny', 'galvantula', 'vikavolt', 'ribombee', 'araquanid', 'spidops',
];
const screenSetters = ['meowstic', 'grimmsnarl', 'ninetalesalola', 'abomasnow'];
const doublesWebSetters = ['ariados', 'kricketune', 'leavanny', 'galvantula', 'vikavolt', 'araquanid', 'spidops'];
const doublesScreenSetters = ['meowstic', 'klefki', 'grimmsnarl', 'ninetalesalola', 'abomasnow'];
const sunSetters = ['ninetales', 'torkoal', 'groudon', 'koraidon'];
const rainSetters = ['politoed', 'pelipper', 'kyogre'];
const sandSetters = ['tyranitar', 'hippowdon'];
const snowSetters = ['ninetalesalola', 'abomasnow'];
const incompatiblePokemon = [
// These Pokemon with support roles are considered too similar to each other.
['blissey', 'chansey'],
['illumise', 'volbeat'],
// These combinations are prevented to avoid double webs or screens.
[webSetters, webSetters],
[screenSetters, screenSetters],
// These Pokemon are incompatible because the presence of one actively harms the other.
// Prevent Dry Skin + sun setting ability
['toxicroak', sunSetters],
];
const doublesIncompatiblePokemon = [
// These Pokemon with support roles are considered too similar to each other.
['illumise', 'volbeat'],
[['minun', 'plusle', 'pachirisu', 'raichu'], ['minun', 'plusle', 'pachirisu', 'raichu']],
// These combinations are prevented to avoid double webs or screens.
[doublesWebSetters, doublesWebSetters],
[doublesScreenSetters, doublesScreenSetters],
// These Pokemon are incompatible because the presence of one actively harms the other.
// Prevent Dry Skin + sun setting ability
['toxicroak', sunSetters],
// Prevent conflicting weather abilities from generating together
[sunSetters, [...rainSetters, ...sandSetters, ...snowSetters]],
[rainSetters, [...sandSetters, ...snowSetters]],
[sandSetters, snowSetters],
// Prevent conflicting terrain abilities from generating together
[['pincurchin', 'miraidon'], ['indeedee', 'indeedeef', 'rillaboom']],
['rillaboom', ['indeedee', 'indeedeef']],
];
const incompatibilityList = isDoubles ? doublesIncompatiblePokemon : incompatiblePokemon;
for (const pair of incompatibilityList) {
const monsArrayA = (Array.isArray(pair[0])) ? pair[0] : [pair[0]];
const monsArrayB = (Array.isArray(pair[1])) ? pair[1] : [pair[1]];
if (monsArrayB.includes(species.id)) {
if (pokemon.some(m => monsArrayA.includes(m.speciesId!))) return false;
}
if (monsArrayA.includes(species.id)) {
if (pokemon.some(m => monsArrayB.includes(m.speciesId!))) return false;
}
}
return true;
}
randomSets: { [species: string]: RandomTeamsTypes.RandomSpeciesData } = require('./sets.json');
randomDoublesSets: { [species: string]: RandomTeamsTypes.RandomSpeciesData } = require('./doubles-sets.json');
@ -1742,6 +1818,9 @@ export class RandomTeams {
if (!this.adjustLevel && (this.getLevel(species, isDoubles) === 100) && numMaxLevelPokemon >= limitFactor) {
continue;
}
// Check compatibility with team
if (!this.getPokemonCompatibility(species, pokemon, isDoubles)) continue;
}
// Limit three of any type combination in Monotype
@ -3004,6 +3083,257 @@ export class RandomTeams {
};
});
}
random1v1FactorySets: { [species: string]: BattleFactorySpecies } = require('./1v1-factory-sets.json');
random1v1FactorySet(
species: Species, teamData: RandomTeamsTypes.FactoryTeamDetails
): RandomTeamsTypes.RandomFactorySet | null {
const setList = this.random1v1FactorySets[species.name].sets;
const movesLimited: { [k: string]: string } = {};
const abilitiesLimited: { [k: string]: string } = {};
// Build a pool of eligible sets, given the team partners
// Also keep track of moves and items limited to one per team
const effectivePool: {
set: BattleFactorySet, moves?: string[], item?: string,
}[] = [];
for (const set of setList) {
let reject = false;
// reject disallowed items, specifically a second of any given choice item
const allowedItems: string[] = [];
let ogItem = set.item;
if (!Array.isArray(ogItem)) ogItem = [ogItem];
for (const itemString of ogItem) {
const itemId = toID(itemString);
if (teamData.has[itemId]) continue;
teamData.has[itemId] = 1;
allowedItems.push(itemString);
}
if (!allowedItems.length) continue;
const item = this.sample(allowedItems);
const abilityId = toID(this.sample(set.ability));
if (abilitiesLimited[abilityId] && teamData.has[abilitiesLimited[abilityId]]) continue;
const moves: string[] = [];
for (const move of set.moves) {
const allowedMoves: string[] = [];
for (const m of move) {
const moveId = toID(m);
if (movesLimited[moveId] && teamData.has[movesLimited[moveId]]) continue;
allowedMoves.push(m);
}
if (!allowedMoves.length) {
reject = true;
break;
}
moves.push(this.sample(allowedMoves));
}
if (reject) continue;
effectivePool.push({ set, moves, item });
}
if (!effectivePool.length) {
if (!teamData.forceResult) return null;
for (const set of setList) {
effectivePool.push({ set });
}
}
// Sets have individual weight, choose one with weighted random selection
let setData = this.sample(effectivePool); // Init with unweighted random set as fallback
const total = effectivePool.reduce((a, b) => a + b.set.weight, 0);
const setRand = this.random(total);
let cur = 0;
for (const set of effectivePool) {
cur += set.set.weight;
if (cur > setRand) {
setData = set; // Bingo!
break;
}
}
const moves = [];
for (const [i, moveSlot] of setData.set.moves.entries()) {
moves.push(setData.moves ? setData.moves[i] : this.sample(moveSlot));
}
const item = setData.item || this.sampleIfArray(setData.set.item);
return {
name: species.baseSpecies,
species: (typeof species.battleOnly === 'string') ? species.battleOnly : species.name,
gender: setData.set.gender || species.gender || this.sample(['M', 'F']),
item,
ability: this.sampleIfArray(setData.set.ability),
shiny: setData.set.shiny || this.randomChance(1, 1024),
level: this.adjustLevel || setData.set.level || 100,
happiness: 255,
evs: { hp: 0, atk: 0, def: 0, spa: 0, spd: 0, spe: 0, ...setData.set.evs },
ivs: { hp: 31, atk: 31, def: 31, spa: 31, spd: 31, spe: 31, ...setData.set.ivs },
nature: this.sampleIfArray(setData.set.nature) || "Serious",
moves,
};
}
random1v1FactoryTeam(side: PlayerOptions, depth = 0): RandomTeamsTypes.RandomFactorySet[] {
this.enforceNoDirectCustomBanlistChanges();
const forceResult = depth >= 12;
const pokemon = [];
const pokemonPool = Object.keys(this.random1v1FactorySets);
const teamData: TeamData = {
typeCount: {},
typeComboCount: {},
baseFormes: {},
has: {},
forceResult,
weaknesses: {},
resistances: {},
};
const movesLimited: { [k: string]: string } = {};
const abilitiesLimited: { [k: string]: string } = {};
const limitFactor = Math.ceil(this.maxTeamSize / 3);
/**
* Weighted random shuffle
* Uses the fact that for two uniform variables x1 and x2, x1^(1/w1) is larger than x2^(1/w2)
* with probability equal to w1/(w1+w2), which is what we want. See e.g. here https://arxiv.org/pdf/1012.0256.pdf,
* original paper is behind a paywall.
*/
const shuffledSpecies = [];
for (const speciesName of pokemonPool) {
const sortObject = {
speciesName,
score: this.prng.random() ** (1 / this.random1v1FactorySets[speciesName].weight),
};
shuffledSpecies.push(sortObject);
}
shuffledSpecies.sort((a, b) => a.score - b.score);
while (shuffledSpecies.length && pokemon.length < this.maxTeamSize) {
// repeated popping from weighted shuffle is equivalent to repeated weighted sampling without replacement
const species = this.dex.species.get(shuffledSpecies.pop()!.speciesName);
if (!species.exists) continue;
if (this.forceMonotype && !species.types.includes(this.forceMonotype)) continue;
// Limit to one of each species (Species Clause)
if (teamData.baseFormes[species.baseSpecies]) continue;
// Limit 1 of any type (most of the time)
const types = species.types;
let skip = false;
if (!this.forceMonotype) {
for (const type of types) {
if (teamData.typeCount[type] >= limitFactor && this.randomChance(4, 5)) {
skip = true;
break;
}
}
}
if (skip) continue;
if (!teamData.forceResult && !this.forceMonotype) {
// Limit 2 of any weakness
for (const typeName of this.dex.types.names()) {
// it's weak to the type
if (this.dex.getEffectiveness(typeName, species) > 0 && this.dex.getImmunity(typeName, types)) {
if (teamData.weaknesses[typeName] >= limitFactor) {
skip = true;
break;
}
}
}
}
if (skip) continue;
const set = this.random1v1FactorySet(species, teamData);
if (!set) continue;
teamData.has[toID(set.item)] = 1;
const atkEVs = set.evs['atk'];
const spaEVs = set.evs['spa'];
const physMoveCount = set.moves.map(x => this.dex.moves.get(x).category).filter(x => x === 'Physical').length;
const specMoveCount = set.moves.map(x => this.dex.moves.get(x).category).filter(x => x === 'Special').length;
const atkBoostingMoves = set.moves.map(x => this.dex.moves.get(x))
.filter(x => (x.target === 'self' && x.boosts?.atk) || (x.id === 'curse' && !species.types.includes('Ghost'))).length;
const spaBoostingMoves = set.moves.map(x => this.dex.moves.get(x))
.filter(x => (x.target === 'self' && x.boosts?.spa) || x.id === 'takeheart').length;
if (teamData.has['physical'] && (atkEVs || physMoveCount >= 2 || atkBoostingMoves)) continue;
if (teamData.has['special'] && (spaEVs || specMoveCount >= 2 || spaBoostingMoves)) continue;
if (!teamData.has['physical']) teamData.has['physical'] = 0;
if (!teamData.has['special']) teamData.has['special'] = 0;
if (atkEVs || physMoveCount >= 2 || atkBoostingMoves) teamData.has['physical']++;
if (spaEVs || specMoveCount >= 2 || spaBoostingMoves) teamData.has['special']++;
// Limit 1 of any type combination
let typeCombo = types.slice().sort().join();
if (set.ability === "Drought" || set.ability === "Drizzle") {
// Drought and Drizzle don't count towards the type combo limit
typeCombo = set.ability;
}
if (!this.forceMonotype && teamData.typeComboCount[typeCombo] >= limitFactor) continue;
// Okay, the set passes, add it to our team
pokemon.push(set);
// Now that our Pokemon has passed all checks, we can update team data:
for (const type of types) {
if (type in teamData.typeCount) {
teamData.typeCount[type]++;
} else {
teamData.typeCount[type] = 1;
}
}
if (typeCombo in teamData.typeComboCount) {
teamData.typeComboCount[typeCombo]++;
} else {
teamData.typeComboCount[typeCombo] = 1;
}
teamData.baseFormes[species.baseSpecies] = 1;
teamData.has[toID(set.item)] = 1;
for (const move of set.moves) {
const moveId = toID(move);
if (movesLimited[moveId]) {
teamData.has[movesLimited[moveId]] = 1;
}
}
const ability = this.dex.abilities.get(set.ability);
if (abilitiesLimited[ability.id]) {
teamData.has[abilitiesLimited[ability.id]] = 1;
}
for (const typeName of this.dex.types.names()) {
const typeMod = this.dex.getEffectiveness(typeName, types);
if (typeMod > 0) {
teamData.weaknesses[typeName] = (teamData.weaknesses[typeName] || 0) + 1;
}
}
}
if (!teamData.forceResult && pokemon.length < this.maxTeamSize) return this.random1v1FactoryTeam(side, ++depth);
// Quality control we cannot afford for monotype
if (!teamData.forceResult && !this.forceMonotype) {
for (const type in teamData.weaknesses) {
if (teamData.weaknesses[type] >= limitFactor) return this.random1v1FactoryTeam(side, ++depth);
}
}
return pokemon;
}
}
export default RandomTeams;

View File

@ -1101,7 +1101,7 @@
"level": 5,
"sets": [
{
"role": "Setup Sweeper",
"role": "Bulky Setup",
"movepool": ["Dual Wingbeat", "Earthquake", "Knock Off", "Swords Dance"],
"abilities": ["Immunity"],
"teraTypes": ["Steel", "Water"]
@ -1970,7 +1970,7 @@
"level": 6,
"sets": [
{
"role": "Setup Sweeper",
"role": "Bulky Setup",
"movepool": ["Iron Head", "Night Slash", "Sucker Punch", "Swords Dance"],
"abilities": ["Defiant"],
"teraTypes": ["Dark", "Fairy", "Steel"]
@ -2599,7 +2599,7 @@
]
},
"skiddo": {
"level": 7,
"level": 6,
"sets": [
{
"role": "Bulky Setup",

View File

@ -4782,7 +4782,7 @@
"teraTypes": ["Fairy"]
},
{
"role": "Fast Attacker",
"role": "Wallbreaker",
"movepool": ["Alluring Voice", "Dark Pulse", "Protect", "Psychic", "Thunderbolt"],
"abilities": ["Competitive"],
"teraTypes": ["Dark", "Electric", "Fairy"]

Some files were not shown because too many files have changed in this diff Show More