Merge branch 'master' into gigatonhammer-tests

This commit is contained in:
André Bastos Dias 2026-01-10 12:06:15 +00:00 committed by GitHub
commit da4669be14
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
94 changed files with 14278 additions and 28103 deletions

File diff suppressed because it is too large Load Diff

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] Tier Shift",
lcotm: "[Gen 9] Bio Mech Mons",
ommotm: "[Gen 9] NatDex Camove Chaos",
ommspotlight: "[Gen 9] NatDex Camove Chaos",
// mega evos --- 1st ordered alphabetically by species, 2nd by alias
megasnow: "Abomasnow-Mega",

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",
},
@ -560,7 +560,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
tentacruel: {
tier: "NU",
doublesTier: "(DUU)",
natDexTier: "RU",
natDexTier: "UU",
},
geodude: {
tier: "LC",
@ -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",
},
@ -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",
@ -5281,7 +5283,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
},
enamorus: {
tier: "OU",
doublesTier: "(DUU)",
doublesTier: "DUU",
natDexTier: "RUBL",
},
enamorustherian: {
@ -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",
},
@ -5646,7 +5648,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
ironmoth: {
tier: "OU",
doublesTier: "(DUU)",
natDexTier: "UU",
natDexTier: "UUBL",
},
ironhands: {
tier: "UUBL",

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"},
],

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.id), this.item,
].map(this.battle.toID));
let isBMMAbil = false;
let isOldBMMAbil = false;
if (!this.hp) return false;
if (!this.battle.dex.abilities.get(ability).exists) isBMMAbil = true;
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 (!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.id), this.item,
].map(this.battle.toID));
let isBMMItem = false;
let isOldBMMItem = false;
if (!this.hp || !this.isActive) return false;
if (!this.battle.dex.items.get(item).exists) isBMMItem = true;
if (typeof item === 'string') {
if (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 (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

@ -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,

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

@ -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

@ -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

@ -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

@ -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

@ -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",
@ -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",
@ -753,22 +753,22 @@ 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",
@ -780,7 +780,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
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,12 +974,12 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
keldeoresolute: {
},
meloetta: {
tier: "OU",
tier: "UU",
},
meloettapirouette: {
},
genesect: {
tier: "OU",
tier: "Uber",
},
genesectdouse: {
},
@ -996,10 +996,10 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "NFE",
},
chesnaught: {
tier: "OU",
tier: "UU",
},
chesnaughtmega: {
tier: "(OU)",
tier: "UU",
},
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",
@ -1077,7 +1077,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "UU",
},
floettemega: {
tier: "OU",
tier: "UU",
},
florges: {
tier: "UU",
@ -1107,10 +1107,10 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "OU",
},
meowsticmmega: {
tier: "OU",
tier: "(OU)",
},
meowsticfmega: {
tier: "OU",
tier: "(OU)",
},
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,16 +1301,16 @@ 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",
@ -1319,7 +1319,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
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",
@ -1337,10 +1337,10 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
tier: "OU",
},
magearnamega: {
tier: "OU",
tier: "Uber",
},
magearnaoriginalmega: {
tier: "OU",
tier: "Uber",
},
marshadow: {
tier: "Uber",
@ -1352,7 +1352,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
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,11 +1,11 @@
export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable = {
clefablemega: {
inherit: true,
abilities: { 0: "Serene Grace" },
abilities: { 0: "Prankster" },
},
victreebelmega: {
inherit: true,
abilities: { 0: "Toxic Debris" },
abilities: { 0: "Triage" },
},
raichumegax: {
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,
@ -70,7 +70,7 @@ export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable
},
garchompmegaz: {
inherit: true,
abilities: { 0: "Neuroforce" },
abilities: { 0: "Rough Skin" },
},
lucariomegaz: {
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,
@ -186,7 +186,7 @@ export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable
},
zeraoramega: {
inherit: true,
abilities: { 0: "Iron Fist" },
abilities: { 0: "Volt Absorb" },
},
falinksmega: {
inherit: true,
@ -198,7 +198,7 @@ export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable
},
glimmoramega: {
inherit: true,
abilities: { 0: "Toxic Chain" },
abilities: { 0: "Levitate" },
},
tatsugiricurlymega: {
inherit: true,

View File

@ -10,7 +10,8 @@ export const Scripts: ModdedBattleScriptsData = {
'softsand', 'spelltag', 'twistedspoon', 'weaknesspolicy', 'whiteherb', 'wiseglasses', 'bottlecap', 'goldbottlecap', 'dawnstone',
'duskstone', 'firestone', 'galaricacuff', 'galaricawreath', 'icestone', 'leafstone', 'moonstone', 'sachet', 'shinystone',
'sunstone', 'thunderstone', 'waterstone', 'whippeddream', 'bignugget', 'redorb', 'blueorb', 'leek', 'thickclub', 'upgrade',
'dubiousdisc', 'prismscale', 'maliciousarmor', 'auspiciousarmor',
'dubiousdisc', 'prismscale', 'maliciousarmor', 'auspiciousarmor', 'poweranklet', 'powerband', 'powerbelt', 'powerbracer',
'powerlens', 'powerweight', 'bignugget', 'bottlecap', 'goldbottlecap', 'prismscale', 'sachet', 'whippeddream',
];
const legalBerries = [
'aspearberry', 'babiriberry', 'chartiberry', 'cheriberry', 'chestoberry', 'chilanberry', 'chopleberry', 'cobaberry', 'colburberry',
@ -19,12 +20,21 @@ export const Scripts: ModdedBattleScriptsData = {
'sitrusberry', 'tamatoberry', 'tangaberry', 'wacanberry', 'yacheberry',
];
const votedLegalitems = [
'heavydutyboots', 'choiceband', 'choicescarf', 'choicespecs',
'heavydutyboots', 'choiceband', 'choicescarf', 'choicespecs', 'airballoon', 'loadeddice', 'mentalherb', 'powerherb', 'mirrorherb',
'aguavberry', 'apicotberry', 'custapberry', 'enigmaberry', 'figyberry', 'ganlonberry', 'iapapaberry', 'jabocaberry', 'keeberry',
'lansatberry', 'leppaberry', 'liechiberry', 'magoberry', 'marangaberry', 'micleberry', 'petayaberry', 'rowapberry', 'salacberry',
'starfberry', 'wikiberry', 'abilityshield', 'blunderpolicy', 'blacksludge', 'lightclay', 'brightpowder', 'adrenalineorb', 'absorbbulb',
'clearamulet', 'covertcloak', 'damprock', 'heatrock', 'icyrock', 'smoothrock', 'electricseed', 'mistyseed', 'psychicseed', 'grassyseed',
'flameorb', 'toxicorb', 'gripclaw', 'laggingtail', 'metronome', 'protectivepads', 'punchingglove', 'razorclaw', 'razorfang', 'roomservice',
'safetygoggles', 'shellbell', 'shedshell', 'stickybarb', 'terrainextender', 'throatspray', 'utilityumbrella', 'zoomlens', 'bindingband',
'destinyknot', 'floatstone', 'ironball', 'machobrace', 'ringtarget', 'redcard', 'ejectpack', 'ejectbutton', 'souldew', 'cellbattery',
'luminousmoss', 'oddincense', 'roseincense', 'seaincense', 'waveincense', 'snowball',
];
for (const i in this.data.Items) {
if (this.data.Items[i].isNonstandard === 'CAP' || this.data.Items[i].isNonstandard === 'Custom') continue;
if ([...legalItems, ...votedLegalitems, ...legalBerries].includes(i) ||
this.data.Items[i].megaStone || this.data.Items[i].onDrive) {
this.data.Items[i].megaStone || this.data.Items[i].onDrive ||
(this.data.Items[i].onPlate && !this.data.Items[i].zMove)) {
this.modData('Items', i).isNonstandard = null;
} else {
this.modData('Items', i).isNonstandard = 'Past';
@ -47,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

@ -14,11 +14,9 @@ export const Items: import('../../../sim/dex-items').ModdedItemDataTable = {
name: "Flygonite",
spritenum: 111,
itemUser: ["Flygon"],
megaEvolves: "Flygon",
megaStone: "Trapinch",
megaStone: { "Trapinch": "Flygon" },
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

@ -963,26 +963,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

@ -5,10 +5,12 @@ export const Scripts: ModdedBattleScriptsData = {
const item = this.data.Items[i];
if (!item.megaStone && !item.onDrive && !(item.onPlate && !item.zMove) && !item.onMemory) continue;
this.modData('Items', i).onTakeItem = false;
if (item.isNonstandard === "Past") this.modData('Items', i).isNonstandard = null;
/* if (item.megaStone) {
this.modData('FormatsData', this.toID(item.megaStone)).isNonstandard = null;
} */
if (item.isNonstandard === "Past" || item.isNonstandard === "Future") 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;
}
}
}
},
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;
@ -405,7 +403,7 @@ export const Scripts: ModdedBattleScriptsData = {
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.length !== pokemon.species.types.length || oSpecies.types[1] !== pokemon.species.types[1]) {
if (oSpecies.types.join('/') !== pokemon.species.types.join('/')) {
this.battle.add('-start', pokemon, 'typechange', pokemon.species.types.join('/'), '[silent]');
}
// }
@ -466,7 +464,12 @@ export const Scripts: ModdedBattleScriptsData = {
return species;
},
getFormeChangeDeltas(formeChangeSpecies, pokemon) {
const baseSpecies = this.dex.species.get(formeChangeSpecies.baseSpecies);
// 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,
@ -476,6 +479,7 @@ export const Scripts: ModdedBattleScriptsData = {
requiredItem: string | undefined,
type?: string,
formeType?: string,
isMega?: boolean,
} = {
ability: formeChangeSpecies.abilities['0'],
baseStats: {},
@ -491,15 +495,19 @@ export const Scripts: ModdedBattleScriptsData = {
let formeType: string | null = null;
if (['Arceus', 'Silvally'].includes(baseSpecies.name)) {
deltas.type = formeChangeSpecies.types[0];
formeType = 'Arceus';
formeType = 'Primary';
} else if (formeChangeSpecies.types.length > baseSpecies.types.length) {
deltas.type = formeChangeSpecies.types[1];
} else if (formeChangeSpecies.types.length < baseSpecies.types.length) {
deltas.type = this.battle.ruleTable.has('mixandmegaoldaggronite') ? 'mono' : baseSpecies.types[0];
} else if (formeChangeSpecies.types[1] !== baseSpecies.types[1]) {
deltas.type = formeChangeSpecies.types[1];
} else if (formeChangeSpecies.types[0] !== baseSpecies.types[0]) {
deltas.type = formeChangeSpecies.types[0];
formeType = 'Primary';
deltas.isMega = true;
}
if (formeChangeSpecies.isMega) formeType = 'Mega';
if (formeChangeSpecies.isMega && !formeType) formeType = 'Mega';
if (formeChangeSpecies.isPrimal) formeType = 'Primal';
if (formeChangeSpecies.name.endsWith('Crowned')) formeType = 'Crowned';
if (formeType) deltas.formeType = formeType;
@ -513,7 +521,7 @@ export const Scripts: ModdedBattleScriptsData = {
if (!deltas) throw new TypeError("Must specify deltas!");
const species = this.dex.deepClone(this.dex.species.get(speciesOrForme));
species.abilities = { '0': deltas.ability };
if (deltas.formeType === 'Arceus') {
if (deltas.formeType === 'Primary') {
const secondType = species.types[1];
species.types = [deltas.type];
if (secondType && secondType !== deltas.type) species.types.push(secondType);
@ -532,7 +540,7 @@ export const Scripts: ModdedBattleScriptsData = {
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') species.isMega = true;
if (deltas.formeType === 'Mega' || deltas.isMega) species.isMega = true;
if (deltas.formeType === 'Primal') species.isPrimal = true;
return species;
},

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,69 +0,0 @@
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;
}
},
},
};

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

@ -0,0 +1,135 @@
export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTable = {
mythicalpresence: {
name: "Mythical Presence",
shortDesc: "Lowers opposing Pokemon Special Attack by 1 stage when switching in.",
onStart(pokemon) {
let activated = false;
for (const target of pokemon.adjacentFoes()) {
if (!activated) {
this.add('-ability', pokemon, 'Mythical Presence', 'boost');
activated = true;
}
if (target.volatiles['substitute']) {
this.add('-immune', target);
} else {
this.boost({ spa: -1 }, target, pokemon, null, true);
}
}
},
},
powerconstruct: {
onResidualOrder: 27,
onResidual(pokemon) {
if (pokemon.baseSpecies.baseSpecies !== 'Flocura' || pokemon.transformed || !pokemon.hp) return;
if (pokemon.species.id === 'flocuranexus' || pokemon.hp > pokemon.maxhp / 2) return;
this.add('-activate', pokemon, 'ability: Power Construct');
pokemon.formeChange('Flocura-Nexus', this.effect, true);
pokemon.baseMaxhp = Math.floor(Math.floor(
2 * pokemon.species.baseStats['hp'] + pokemon.set.ivs['hp'] + Math.floor(pokemon.set.evs['hp'] / 4) + 100
) * pokemon.level / 100 + 10);
const newMaxHP = pokemon.volatiles['dynamax'] ? (2 * pokemon.baseMaxhp) : pokemon.baseMaxhp;
pokemon.hp = newMaxHP - (pokemon.maxhp - pokemon.hp);
pokemon.maxhp = newMaxHP;
this.add('-heal', pokemon, pokemon.getHealth, '[silent]');
},
flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1 },
name: "Power Construct",
rating: 5,
num: 211,
},
battlebond: {
shortDesc: "Change to a stronger forme after getting a KO.",
onSourceAfterFaint(length, target, source, effect) {
if (effect?.effectType !== 'Move') {
return;
}
if (source.species.id === 'soleron' && source.hp && !source.transformed && source.side.foe.pokemonLeft) {
this.add('-activate', source, 'ability: Battle Bond');
source.formeChange('Soleron-Awakened', this.effect, true);
}
},
onModifyMovePriority: -1,
flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1 },
name: "Battle Bond",
rating: 4,
num: 210,
},
crystalheart: {
shortDesc: "User becomes Crystal type. While Crystal type, 33% boost to Def and SpD",
onStart(pokemon) {
if (pokemon.hasType('Crystal')) return false;
if (!pokemon.addType('Crystal')) return false;
pokemon.setType(["Crystal"]);
this.add('-start', pokemon, 'typechange', 'Crystal', '[from] ability: Crystal Heart');
},
onModifyDefPriority: 6,
onModifyDef(def, pokemon) {
if (pokemon.hasType('Crystal')) return this.chainModify(1 + (1 / 3));
},
onModifySpDPriority: 6,
onModifySpD(spd, pokemon) {
if (pokemon.hasType('Crystal')) return this.chainModify(1 + (1 / 3));
},
name: "Crystal Heart",
},
wildheart: {
onStart(pokemon) {
if (pokemon.hasType('Feral')) return false;
if (!pokemon.addType('Feral')) return false;
pokemon.setType(["Feral"]);
this.add('-start', pokemon, 'typechange', "Feral", '[from] ability: Wild Heart');
},
onModifyAtkPriority: 6,
onModifyAtk(atk, pokemon) {
if (pokemon.hasType('Feral')) return this.chainModify(1 + (1 / 3));
},
onModifySpAPriority: 6,
onModifySpA(spa, pokemon) {
if (pokemon.hasType('Feral')) return this.chainModify(1 + (1 / 3));
},
name: "Wild Heart",
shortDesc: "User becomes Feral type. While Feral type, 33% boost to Atk and SpA",
},
schooling: {
onStart(pokemon) {
if (pokemon.baseSpecies.baseSpecies !== 'Jaegorm' || pokemon.transformed) return;
if (pokemon.hp > pokemon.maxhp / 4) {
if (pokemon.species.id === 'jaegorm') {
pokemon.formeChange('Jaegorm-Collective');
}
} else {
if (pokemon.species.id === 'jaegormcollective') {
pokemon.formeChange('Jaegorm');
}
}
},
onResidualOrder: 27,
onResidual(pokemon) {
if (
pokemon.baseSpecies.baseSpecies !== 'Jaegorm' || pokemon.transformed || !pokemon.hp
) return;
if (pokemon.hp > pokemon.maxhp / 4) {
if (pokemon.species.id === 'jaegorm') {
pokemon.formeChange('Jaegorm-Collective');
}
} else {
if (pokemon.species.id === 'jaegormcollective') {
pokemon.formeChange('Jaegorm');
}
}
},
flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1 },
name: "Schooling",
shortDesc: "If user is Jaegorm, changes to Collective Form if it has > 1/4 max HP, else Solo Form.",
rating: 3,
num: 208,
},
shellbunker: {
onDamage(damage, target, source, effect) {
if (effect.effectType !== 'Move' || !target.hurtThisTurn) return damage;
return damage / 2;
},
name: "Shell Bunker",
shortDesc: "After taking damage, Def and SpD are doubled for the rest of the turn.",
},
};

View File

@ -0,0 +1,67 @@
export const Conditions: import('../../../sim/dex-conditions').ModdedConditionDataTable = {
frz: {
name: 'frz',
/*
start: " [Pokemon] was chilled!",
alreadyStarted: " [POKEMON] is already chilled!",
end: " [POKEMON] warmed up!",
endFromItem: " [POKEMON]'s [ITEM] warmed it up!",
endFromMove: " [POKEMON]'s [MOVE] warmed it up!",
cant: "[POKEMON] is chilled!",
*/
effectType: 'Status',
onStart(target, source, sourceEffect) {
if (sourceEffect && sourceEffect.effectType === 'Ability') {
this.add('-status', target, 'frz', '[from] ability: ' + sourceEffect.name, `[of] ${source}`);
} else {
this.add('-status', target, 'frz');
}
},
onResidualOrder: 9,
onResidual(pokemon) {
this.damage(pokemon.baseMaxhp / 16);
},
onModifySpA(spa, pokemon) {
return this.chainModify(0.5);
},
},
slp: {
name: 'slp',
effectType: 'Status',
onStart(target, source, sourceEffect) {
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');
}
// 1-3 turns
this.effectState.startTime = 3;
const sleepMoves = ["sleeppowder", "spore", "grasswhistle", "darkvoid", "hypnosis"];
if (sourceEffect && sourceEffect.effectType === 'Move') {
if (sleepMoves.includes(sourceEffect.id)) this.effectState.startTime = 2;
}
this.effectState.time = this.effectState.startTime;
},
onBeforeMovePriority: 10,
onBeforeMove(pokemon, target, move) {
if (pokemon.hasAbility('earlybird')) {
pokemon.statusState.time--;
}
pokemon.statusState.time--;
if (pokemon.statusState.time <= 0) {
pokemon.cureStatus();
return;
}
this.add('cant', pokemon, 'slp');
if (move.sleepUsable) {
return;
}
return false;
},
onModifySpe(spe, pokemon) {
return this.chainModify(0.5);
},
},
};

View File

@ -0,0 +1,218 @@
export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormatsDataTable = {
arbrella: {
tier: "OU",
doublesTier: "DOU",
},
krachiten: {
tier: "OU",
doublesTier: "DOU",
},
scalaron: {
tier: "OU",
doublesTier: "DOU",
},
rantler: {
tier: "OU",
doublesTier: "DOU",
},
woolora: {
tier: "OU",
doublesTier: "DOU",
},
albatrygon: {
tier: "OU",
doublesTier: "DOU",
},
orchile: {
tier: "OU",
doublesTier: "DOU",
},
embuck: {
tier: "OU",
doublesTier: "DOU",
},
cindoe: {
tier: "OU",
doublesTier: "DOU",
},
cobracotta: {
tier: "OU",
doublesTier: "DOU",
},
minillow: {
tier: "OU",
doublesTier: "DOU",
},
crossont: {
tier: "OU",
doublesTier: "DOU",
},
torgeist: {
tier: "OU",
doublesTier: "DOU",
},
platypad: {
tier: "OU",
doublesTier: "DOU",
},
lumoth: {
tier: "OU",
doublesTier: "DOU",
},
aurorowl: {
tier: "OU",
doublesTier: "DOU",
},
carapex: {
tier: "OU",
doublesTier: "DOU",
},
dojodo: {
tier: "OU",
doublesTier: "DOU",
},
nunopod: {
tier: "OU",
doublesTier: "DOU",
},
zeploom: {
tier: "OU",
doublesTier: "DOU",
},
sturgard: {
tier: "OU",
doublesTier: "DOU",
},
brawnkey: {
tier: "OU",
doublesTier: "DOU",
},
salamalix: {
tier: "OU",
doublesTier: "DOU",
},
cinnastar: {
tier: "OU",
doublesTier: "DOU",
},
muabboa: {
tier: "OU",
doublesTier: "DOU",
},
harzodia: {
tier: "OU",
doublesTier: "DOU",
},
cyllindrake: {
tier: "OU",
doublesTier: "DOU",
},
kodokai: {
tier: "OU",
doublesTier: "DOU",
},
electangle: {
tier: "OU",
doublesTier: "DOU",
},
dolphena: {
tier: "OU",
doublesTier: "DOU",
},
soleron: {
tier: "OU",
doublesTier: "DOU",
},
jaegorm: {
tier: "OU",
doublesTier: "DOU",
},
elemadillo: {
tier: "OU",
doublesTier: "DOU",
},
axolacred: {
tier: "OU",
doublesTier: "DOU",
},
roscenti: {
tier: "OU",
doublesTier: "DOU",
},
blunderbusk: {
tier: "OU",
doublesTier: "DOU",
},
barracoth: {
tier: "OU",
doublesTier: "DOU",
},
jamborai: {
tier: "OU",
doublesTier: "DOU",
},
dracoil: {
tier: "OU",
doublesTier: "DOU",
},
celespirit: {
tier: "OU",
doublesTier: "DOU",
},
noxtrice: {
tier: "OU",
doublesTier: "DOU",
},
avastar: {
tier: "OU",
doublesTier: "DOU",
},
faerenheit: {
tier: "OU",
doublesTier: "DOU",
},
cellsius: {
tier: "OU",
doublesTier: "DOU",
},
kelven: {
tier: "OU",
doublesTier: "DOU",
},
salaos: {
tier: "OU",
doublesTier: "DOU",
},
morndos: {
tier: "OU",
doublesTier: "DOU",
},
pythos: {
tier: "OU",
doublesTier: "DOU",
},
corundell: {
tier: "OU",
doublesTier: "DOU",
},
quadringo: {
tier: "OU",
doublesTier: "DOU",
},
saphor: {
tier: "OU",
doublesTier: "DOU",
},
fenreil: {
tier: "OU",
doublesTier: "DOU",
},
efflor: {
tier: "OU",
doublesTier: "DOU",
},
flocura: {
tier: "OU",
doublesTier: "DOU",
},
};

View File

@ -0,0 +1,88 @@
export const Items: import('../../../sim/dex-items').ModdedItemDataTable = {
crystalorb: {
name: "Crystal Orb",
num: 1001,
desc: "The holder's secondary type is replaced with Crystal. 20% boost to Crystal attacks.",
onBeforeSwitchIn(pokemon) {
if (this.effectState.usedSuperType && this.effectState.superTypeUser !== pokemon.fullname) return false;
if (pokemon.hasType('Crystal')) return false;
if (!pokemon.addType('Crystal')) return false;
pokemon.setType([pokemon.types[0], "Crystal"]);
this.effectState.usedSuperType = true;
this.effectState.superTypeUser = "first_switch";
},
onStart(pokemon) {
if (this.effectState.usedSuperType && this.effectState.superTypeUser === "first_switch") {
this.add('-message', pokemon.name + " is a Crystal type!");
this.effectState.superTypeUser = pokemon.fullname;
}
if (this.effectState.usedSuperType && this.effectState.superTypeUser === pokemon.fullname) {
this.add('-start', pokemon, 'typechange', pokemon.getTypes(true).join('/'), '[silent]');
}
},
onUpdate(pokemon) {
if (
this.effectState.usedSuperType && this.effectState.superTypeUser === pokemon.fullname && !pokemon.hasType('Crystal')
) {
pokemon.setType([pokemon.types[0], "Crystal"]);
this.add('-start', pokemon, 'typechange', pokemon.getTypes(true).join('/'), '[silent]');
}
},
onTakeItem(item, pokemon, source) {
if (source?.hasType("Crystal")) {
return false;
}
return true;
},
onBasePowerPriority: 15,
onBasePower(basePower, user, target, move) {
if (move && move.type === 'Crystal') {
return this.chainModify([0x1333, 0x1000]);
}
},
gen: 9,
},
feralorb: {
name: "Feral Orb",
num: 1002,
desc: "The holder's secondary type is replaced with Feral. 20% boost to Feral attacks.",
onBeforeSwitchIn(pokemon) {
if (this.effectState.usedSuperType && this.effectState.superTypeUser !== pokemon.fullname) return false;
if (pokemon.hasType('Feral')) return false;
if (!pokemon.addType('Feral')) return false;
pokemon.setType([pokemon.types[0], "Feral"]);
this.effectState.usedSuperType = true;
this.effectState.superTypeUser = "first_switch";
},
onStart(pokemon) {
if (this.effectState.usedSuperType && this.effectState.superTypeUser === "first_switch") {
this.add('-message', pokemon.name + " is a Feral type!");
this.effectState.superTypeUser = pokemon.fullname;
}
if (this.effectState.usedSuperType && this.effectState.superTypeUser === pokemon.fullname) {
this.add('-start', pokemon, 'typechange', pokemon.getTypes(true).join('/'), '[silent]');
}
},
onUpdate(pokemon) {
if (
this.effectState.usedSuperType && this.effectState.superTypeUser === pokemon.fullname && !pokemon.hasType('Feral')
) {
pokemon.setType([pokemon.types[0], "Feral"]);
this.add('-start', pokemon, 'typechange', pokemon.getTypes(true).join('/'), '[silent]');
}
},
onTakeItem(item, pokemon, source) {
if (source?.hasType("Feral")) {
return false;
}
return true;
},
onBasePowerPriority: 15,
onBasePower(basePower, user, target, move) {
if (move && move.type === 'Feral') {
return this.chainModify([0x1333, 0x1000]);
}
},
gen: 9,
},
};

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,551 @@
export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable = {
arbrella: {
num: 2001,
name: "Arbrella",
types: ["Grass", "Ground"],
baseStats: { hp: 80, atk: 115, def: 100, spa: 80, spd: 80, spe: 75 },
abilities: { 0: "Overgrow", H: "Tough Claws" },
weightkg: 211,
eggGroups: ["Undiscovered"],
},
krachiten: {
num: 2002,
name: "Krachiten",
types: ["Water", "Bug"],
baseStats: { hp: 90, atk: 120, def: 70, spa: 78, spd: 60, spe: 112 },
abilities: { 0: "Torrent", H: "Sniper" },
weightkg: 59,
eggGroups: ["Undiscovered"],
},
scalaron: {
num: 2003,
name: "Scalaron",
types: ["Fire", "Flying"],
baseStats: { hp: 90, atk: 70, def: 90, spa: 100, spd: 105, spe: 75 },
abilities: { 0: "Blaze", H: "Filter" },
weightkg: 70,
eggGroups: ["Undiscovered"],
},
rantler: {
num: 2004,
name: "Rantler",
types: ["Normal", "Ice"],
baseStats: { hp: 68, atk: 118, def: 94, spa: 43, spd: 79, spe: 73 },
abilities: { 0: "Intimidate", 1: "Slush Rush", H: "Tough Claws" },
weightkg: 67,
eggGroups: ["Undiscovered"],
},
woolora: {
num: 2005,
name: "Woolora",
types: ["Fairy"],
baseStats: { hp: 70, atk: 75, def: 70, spa: 95, spd: 115, spe: 70 },
abilities: { 0: "Fluffy", 1: "Rattled", H: "Pastel Veil" },
weightkg: 50.3,
eggGroups: ["Undiscovered"],
},
albatrygon: {
num: 2006,
name: "Albatrygon",
types: ["Flying"],
baseStats: { hp: 80, atk: 105, def: 70, spa: 65, spd: 60, spe: 95 },
abilities: { 0: "Prankster", 1: "Klutz", H: "Unburden" },
weightkg: 10.1,
eggGroups: ["Undiscovered"],
},
orchile: {
num: 2007,
name: "Orchile",
types: ["Grass", "Fairy"],
baseStats: { hp: 65, atk: 60, def: 75, spa: 110, spd: 121, spe: 64 },
abilities: { 0: "Sweet Veil", 1: "Aroma Veil", H: "Flower Veil" },
weightkg: 45,
eggGroups: ["Undiscovered"],
},
embuck: {
num: 2008,
name: "Embuck",
types: ["Fire", "Fighting"],
baseStats: { hp: 90, atk: 125, def: 80, spa: 83, spd: 65, spe: 82 },
abilities: { 0: "Intimidate", H: "Flash Fire" },
weightkg: 113,
eggGroups: ["Undiscovered"],
},
cindoe: {
num: 2009,
name: "Cindoe",
types: ["Fire", "Dark"],
baseStats: { hp: 80, atk: 74, def: 55, spa: 110, spd: 100, spe: 106 },
abilities: { 0: "Natural Cure", H: "Flash Fire" },
weightkg: 67,
eggGroups: ["Undiscovered"],
},
cobracotta: {
num: 2010,
name: "Cobracotta",
types: ["Grass", "Poison"],
baseStats: { hp: 80, atk: 90, def: 95, spa: 80, spd: 115, spe: 35 },
abilities: { 0: "Mold Breaker", 1: "Weak Armor", H: "Heatproof" },
weightkg: 68,
eggGroups: ["Undiscovered"],
},
minillow: {
num: 2011,
name: "Minillow",
types: ["Water", "Fairy"],
baseStats: { hp: 70, atk: 64, def: 75, spa: 90, spd: 95, spe: 81 },
abilities: { 0: "Swift Swim", 1: "Dazzling", H: "Adaptability" },
weightkg: 22,
eggGroups: ["Undiscovered"],
},
crossont: {
num: 2012,
name: "Crossont",
types: ["Bug", "Fighting"],
baseStats: { hp: 80, atk: 125, def: 100, spa: 60, spd: 80, spe: 80 },
abilities: { 0: "Sniper", 1: "Long Reach", H: "Gooey" },
weightkg: 121,
eggGroups: ["Undiscovered"],
},
torgeist: {
num: 2013,
name: "Torgeist",
types: ["Ghost", "Flying"],
baseStats: { hp: 55, atk: 65, def: 95, spa: 115, spd: 100, spe: 105 },
abilities: { 0: "Cursed Body", 1: "Clear Body", H: "Merciless" },
weightkg: 9.7,
eggGroups: ["Undiscovered"],
},
platypad: {
num: 2014,
name: "Platypad",
types: ["Grass", "Water"],
baseStats: { hp: 120, atk: 100, def: 80, spa: 100, spd: 80, spe: 40 },
abilities: { 0: "Thick Fat", 1: "Triage", H: "Flower Veil" },
weightkg: 89,
eggGroups: ["Undiscovered"],
},
lumoth: {
num: 2015,
name: "Lumoth",
types: ["Bug", "Ghost"],
baseStats: { hp: 60, atk: 55, def: 91, spa: 110, spd: 85, spe: 94 },
abilities: { 0: "Levitate" },
weightkg: 0.5,
eggGroups: ["Undiscovered"],
},
aurorowl: {
num: 2016,
name: "Aurorowl",
types: ["Ice", "Flying"],
baseStats: { hp: 70, atk: 70, def: 65, spa: 95, spd: 95, spe: 115 },
abilities: { 0: "Snow Cloak", H: "Technician" },
weightkg: 15,
eggGroups: ["Undiscovered"],
},
carapex: {
num: 2017,
name: "Carapex",
types: ["Bug", "Flying"],
baseStats: { hp: 75, atk: 105, def: 155, spa: 55, spd: 90, spe: 60 },
abilities: { 0: "Wind Rider", 1: "Mold Breaker", H: "Sturdy" },
weightkg: 135,
eggGroups: ["Undiscovered"],
},
dojodo: {
num: 2018,
name: "Dojodo",
types: ["Fighting"],
baseStats: { hp: 90, atk: 115, def: 80, spa: 65, spd: 100, spe: 80 },
abilities: { 0: "Iron Fist", 1: "Stamina", H: "Supreme Overlord" },
weightkg: 53,
eggGroups: ["Undiscovered"],
},
nunopod: {
num: 2019,
name: "Nunopod",
types: ["Ground", "Bug"],
baseStats: { hp: 80, atk: 110, def: 125, spa: 68, spd: 75, spe: 67 },
abilities: { 0: "Earth Eater", H: "Opportunist" },
weightkg: 68,
eggGroups: ["Undiscovered"],
},
zeploom: {
num: 2020,
name: "Zeploom",
types: ["Grass", "Ground"],
baseStats: { hp: 55, atk: 55, def: 145, spa: 65, spd: 150, spe: 45 },
abilities: { 0: "Wind Rider", H: "Levitate" },
weightkg: 5,
eggGroups: ["Undiscovered"],
},
brawnkey: {
num: 2021,
name: "Brawnkey",
types: ["Steel", "Fighting"],
baseStats: { hp: 95, atk: 105, def: 105, spa: 85, spd: 80, spe: 50 },
abilities: { 0: "Levitate" },
weightkg: 85,
eggGroups: ["Undiscovered"],
},
salamalix: {
num: 2022,
name: "Salamalix",
types: ["Rock", "Steel"],
baseStats: { hp: 70, atk: 120, def: 120, spa: 45, spd: 65, spe: 90 },
abilities: { 0: "No Guard", 1: "Mold Breaker", H: "Intimidate" },
weightkg: 85,
eggGroups: ["Undiscovered"],
},
cinnastar: {
num: 2023,
name: "Cinnastar",
types: ["Rock", "Poison"],
baseStats: { hp: 110, atk: 95, def: 80, spa: 95, spd: 80, spe: 80 },
abilities: { 0: "Liquid Ooze", H: "Regenerator" },
weightkg: 56,
eggGroups: ["Undiscovered"],
},
muabboa: {
num: 2024,
name: "MuabBoa",
types: ["Ground", "Fighting"],
baseStats: { hp: 65, atk: 100, def: 75, spa: 55, spd: 65, spe: 120 },
abilities: { 0: "Anticipation", 1: "Sand Rush", H: "Inner Focus" },
weightkg: 25,
eggGroups: ["Undiscovered"],
},
volvolpa: {
num: 2025,
name: "Volvolpa",
types: ["Electric", "Ice"],
baseStats: { hp: 76, atk: 97, def: 64, spa: 70, spd: 102, spe: 121 },
abilities: { 0: "Slush Rush", 1: "Volt Absorb", H: "Strong Jaw" },
weightkg: 27,
eggGroups: ["Undiscovered"],
},
harzodia: {
num: 2026,
name: "Harzodia",
types: ["Psychic"],
baseStats: { hp: 65, atk: 55, def: 75, spa: 125, spd: 75, spe: 95 },
abilities: { 0: "Prankster", 1: "Unburden", H: "Solar Power" },
weightkg: 35,
eggGroups: ["Undiscovered"],
},
cyllindrake: {
num: 2027,
name: "Cyllindrake",
types: ["Steel", "Dragon"],
baseStats: { hp: 70, atk: 85, def: 115, spa: 95, spd: 70, spe: 110 },
abilities: { 0: "Heavy Metal", 1: "Punk Rock", H: "Scrappy" },
weightkg: 180,
eggGroups: ["Undiscovered"],
},
kodokai: {
num: 2028,
name: "Kodokai",
types: ["Ghost", "Fire"],
baseStats: { hp: 110, atk: 65, def: 100, spa: 110, spd: 90, spe: 30 },
abilities: { 0: "White Smoke", H: "Aroma Veil" },
weightkg: 50,
eggGroups: ["Undiscovered"],
},
electangle: {
num: 2029,
name: "Electangle",
types: ["Steel", "Electric"],
baseStats: { hp: 120, atk: 90, def: 110, spa: 90, spd: 90, spe: 25 },
abilities: { 0: "Filter" },
weightkg: 190,
eggGroups: ["Undiscovered"],
},
dolphena: {
num: 2030,
name: "Dolphena",
types: ["Water", "Dragon"],
baseStats: { hp: 95, atk: 125, def: 80, spa: 84, spd: 75, spe: 81 },
abilities: { 0: "Anger Point", H: "Mythical Presence" },
weightkg: 271,
eggGroups: ["Undiscovered"],
},
elemadillo: {
num: 2035,
name: "Elemadillo",
types: ["Steel", "Electric"],
baseStats: { hp: 67, atk: 94, def: 73, spa: 103, spd: 64, spe: 129 },
abilities: { 0: "Weak Armor", 1: "Motor Drive", H: "Stalwart" },
weightkg: 58,
eggGroups: ["Undiscovered"],
},
axolacred: {
num: 2036,
name: "Axolacred",
types: ["Dragon"],
baseStats: { hp: 85, atk: 90, def: 85, spa: 95, spd: 95, spe: 65 },
abilities: { 0: "Magic Guard", H: "Purifying Salt" },
weightkg: 33,
eggGroups: ["Undiscovered"],
},
roscenti: {
num: 2037,
name: "Roscenti",
types: ["Bug", "Grass"],
baseStats: { hp: 80, atk: 115, def: 100, spa: 75, spd: 80, spe: 100 },
abilities: { 0: "Sheer Force", 1: "Chlorophyll", H: "Skill Link" },
eggGroups: ["Undiscovered"],
weightkg: 37,
},
blunderbusk: {
num: 2038,
name: "Blunderbusk",
types: ["Water"],
baseStats: { hp: 73, atk: 67, def: 124, spa: 128, spd: 89, spe: 24 },
abilities: { 0: "Mega Launcher", H: "Shell Bunker" },
weightkg: 86,
eggGroups: ["Undiscovered"],
},
barracoth: {
num: 2039,
name: "Barracoth",
types: ["Ice", "Water"],
baseStats: { hp: 140, atk: 115, def: 110, spa: 55, spd: 65, spe: 35 },
abilities: { 0: "Filter", 1: "Thick Fat", H: "Multiscale" },
weightkg: 356,
eggGroups: ["Undiscovered"],
},
jamborai: {
num: 2040,
name: "Jamborai",
types: ["Poison", "Psychic"],
baseStats: { hp: 75, atk: 55, def: 125, spa: 120, spd: 85, spe: 65 },
abilities: { 0: "Clear Body", 1: "Gooey", H: "Water Absorb" },
weightkg: 84,
eggGroups: ["Undiscovered"],
},
dracoil: {
num: 2041,
name: "Dracoil",
types: ["Dragon", "Flying"],
baseStats: { hp: 105, atk: 106, def: 85, spa: 96, spd: 60, spe: 78 },
abilities: { 0: "Mythical Presence", 1: "Gluttony", H: "Marvel Scale" },
weightkg: 428,
eggGroups: ["Undiscovered"],
},
celespirit: {
num: 2042,
name: "Celespirit",
types: ["Ghost"],
baseStats: { hp: 75, atk: 61, def: 73, spa: 117, spd: 135, spe: 69 },
abilities: { 0: "Levitate", H: "Power Spot" },
weightkg: 25.8,
eggGroups: ["Undiscovered"],
},
noxtrice: {
num: 2043,
name: "Noxtrice",
types: ["Poison", "Fire"],
baseStats: { hp: 65, atk: 118, def: 75, spa: 63, spd: 80, spe: 114 },
abilities: { 0: "Poison Touch", H: "Flash Fire" },
weightkg: 73.7,
eggGroups: ["Undiscovered"],
},
sturgard: {
num: 2055,
name: "Sturgard",
types: ["Water", "Ground"],
baseStats: { hp: 105, atk: 110, def: 105, spa: 65, spd: 70, spe: 70 },
abilities: { 0: "Rock Head", 1: "Battle Armor", H: "Mold Breaker" },
weightkg: 143,
eggGroups: ["Undiscovered"],
},
avastar: {
num: 2034,
name: "Avastar",
types: ["Psychic", "Steel"],
baseStats: { hp: 75, atk: 85, def: 110, spa: 115, spd: 100, spe: 60 },
abilities: { 0: "Stalwart", 1: "Heavy Metal", H: "Shell Bunker" },
weightkg: 999.9,
eggGroups: ["Undiscovered"],
},
faerenheit: {
num: 2044,
name: "Faerenheit",
types: ["Fire", "Fairy"],
baseStats: { hp: 71, atk: 83, def: 127, spa: 97, spd: 109, spe: 83 },
abilities: { 0: "Beast Boost" },
weightkg: 2.1,
eggGroups: ["Undiscovered"],
},
cellsius: {
num: 2045,
name: "Cellsius",
types: ["Water", "Fairy"],
baseStats: { hp: 71, atk: 83, def: 83, spa: 109, spd: 127, spe: 97 },
abilities: { 0: "Beast Boost" },
weightkg: 2.4,
eggGroups: ["Undiscovered"],
},
kelven: {
num: 2046,
name: "Kelven",
types: ["Ice", "Fairy"],
baseStats: { hp: 71, atk: 127, def: 109, spa: 83, spd: 83, spe: 97 },
abilities: { 0: "Beast Boost" },
weightkg: 2.8,
eggGroups: ["Undiscovered"],
},
salaos: {
num: 2047,
name: "Salaos",
types: ["Dark"],
baseStats: { hp: 75, atk: 85, def: 90, spa: 110, spd: 130, spe: 90 },
abilities: { 0: "Good as Gold" },
weightkg: 74,
eggGroups: ["Undiscovered"],
},
morndos: {
num: 2048,
name: "Morndos",
types: ["Dark", "Flying"],
baseStats: { hp: 110, atk: 90, def: 75, spa: 90, spd: 85, spe: 130 },
abilities: { 0: "Synchronize" },
weightkg: 56,
eggGroups: ["Undiscovered"],
},
pythos: {
num: 2049,
name: "Pythos",
types: ["Dark"],
baseStats: { hp: 90, atk: 110, def: 130, spa: 85, spd: 90, spe: 75 },
abilities: { 0: "Guts" },
weightkg: 178,
eggGroups: ["Undiscovered"],
},
corundell: {
num: 2050,
name: "Corundell",
types: ["Rock", "Electric"],
baseStats: { hp: 75, atk: 100, def: 130, spa: 105, spd: 80, spe: 110 },
abilities: { 0: "Lightning Rod", H: "Protosynthesis" },
weightkg: 137,
eggGroups: ["Undiscovered"],
},
quadringo: {
num: 2051,
name: "Quadringo",
types: ["Fairy", "Dragon"],
baseStats: { hp: 80, atk: 120, def: 95, spa: 100, spd: 120, spe: 85 },
abilities: { 0: "Hydration", 1: "Pastel Veil", H: "Inner Focus" },
weightkg: 156,
eggGroups: ["Undiscovered"],
},
saphor: {
num: 2052,
name: "Saphor",
types: ["Ground", "Normal"],
baseStats: { hp: 95, atk: 100, def: 105, spa: 100, spd: 105, spe: 95 },
abilities: { 0: "Thick Fat", 1: "Crystal Heart" },
weightkg: 638,
eggGroups: ["Undiscovered"],
},
fenreil: {
num: 2053,
name: "Fenreil",
types: ["Dark", "Normal"],
baseStats: { hp: 80, atk: 105, def: 97, spa: 105, spd: 97, spe: 116 },
abilities: { 0: "Natural Cure", 1: "Wild Heart" },
weightkg: 232,
eggGroups: ["Undiscovered"],
},
soleron: {
num: 2031,
name: "Soleron",
types: ["Electric", "Flying"],
baseStats: { hp: 70, atk: 75, def: 65, spa: 115, spd: 75, spe: 115 },
abilities: { 0: "Battle Bond" },
otherFormes: ["Soleron-Awakened"],
formeOrder: ["Soleron", "Soleron-Awakened"],
weightkg: 12,
eggGroups: ["Undiscovered"],
},
soleronawakened: {
num: 2031,
name: "Soleron-Awakened",
baseSpecies: "Soleron",
forme: "Awakened",
types: ["Electric", "Flying"],
baseStats: { hp: 70, atk: 105, def: 85, spa: 135, spd: 95, spe: 125 },
abilities: { 0: "Battle Bond" },
requiredAbility: "Battle Bond",
battleOnly: "Soleron",
weightkg: 24,
eggGroups: ["Undiscovered"],
},
efflor: {
num: 2032,
name: "Efflor",
types: ["Rock", "Grass"],
baseStats: { hp: 80, atk: 85, def: 110, spa: 105, spd: 110, spe: 25 },
abilities: { 0: "Solid Rock", 1: "Unaware", H: "Seed Sower" },
weightkg: 113,
eggGroups: ["Undiscovered"],
},
pictagon: {
num: 2055,
name: "Pictagon",
types: ["Dragon", "Ghost"],
baseStats: { hp: 105, atk: 105, def: 60, spa: 80, spd: 85, spe: 95 },
abilities: { 0: "Clear Body", 1: "Infiltrator", H: "No Guard" },
weightkg: 113,
eggGroups: ["Undiscovered"],
},
jaegorm: {
num: 2033,
name: "Jaegorm",
types: ["Bug", "Psychic"],
baseStats: { hp: 60, atk: 65, def: 40, spa: 130, spd: 40, spe: 130 },
abilities: { 0: "Schooling" },
otherFormes: ["Jaegorm-Collective"],
formeOrder: ["Jaegorm", "Jaegorm-Collective"],
weightkg: 10,
eggGroups: ["Undiscovered"],
},
jaegormcollective: {
num: 2033,
name: "Jaegorm-Collective",
baseSpecies: "Jaegorm",
forme: "Collective",
types: ["Bug", "Psychic"],
baseStats: { hp: 60, atk: 145, def: 130, spa: 100, spd: 130, spe: 80 },
abilities: { 0: "Schooling" },
requiredAbility: "Schooling",
battleOnly: "Jaegorm",
weightkg: 122,
eggGroups: ["Undiscovered"],
},
flocura: {
num: 2054,
name: "Flocura",
types: ["Grass", "Psychic"],
baseStats: { hp: 55, atk: 85, def: 55, spa: 107, spd: 180, spe: 118 },
abilities: { 0: "Levitate", H: "Power Construct" },
otherFormes: ["Flocura-Nexus"],
formeOrder: ["Flocura", "Flocura-Nexus"],
weightkg: 7.1,
eggGroups: ["Undiscovered"],
},
flocuranexus: {
num: 2054,
name: "Flocura-Nexus",
baseSpecies: "Flocura",
forme: "Nexus",
types: ["Grass", "Psychic"],
baseStats: { hp: 105, atk: 125, def: 105, spa: 137, spd: 180, spe: 48 },
abilities: { 0: "Levitate", H: "Power Construct" },
requiredAbility: "Power Construct",
battleOnly: "Flocura",
weightkg: 999,
eggGroups: ["Undiscovered"],
},
};

View File

@ -0,0 +1,38 @@
export const Rulesets: import('../../../sim/dex-formats').ModdedFormatDataTable = {
supertypemovesrule: {
effectType: 'Rule',
name: 'Super Type Moves Rule',
desc: 'Prevents pokemon from using Crystal or Feral moves unless they have a matching type.',
onBeforeMove(pokemon, target, move) {
move = {
...this.dex.moves.get(move),
hit: move.hit,
};
if (move.type === "Crystal" && !pokemon.hasType("Crystal")) return false;
if (move.type === "Feral" && !pokemon.hasType("Feral")) return false;
},
onDisableMove(pokemon) {
for (const moveSlot of pokemon.moveSlots) {
const move = this.dex.moves.get(moveSlot.id);
if ((move.type === "Crystal" && !pokemon.hasType("Crystal")) || (move.type === "Feral" && !pokemon.hasType("Feral"))) {
pokemon.disableMove(moveSlot.id, false);
}
}
},
},
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/scootopia/sprites/front/${pokemon.species.id}.png" height="96" width="96">`);
this.effectState[pokemon.species.id] = true;
}
},
},
};

View File

@ -0,0 +1,3 @@
export const Scripts: ModdedBattleScriptsData = {
gen: 9,
};

View File

@ -0,0 +1,530 @@
export const TypeChart: import('../../../sim/dex-data').ModdedTypeDataTable = {
bug: {
damageTaken: {
Bug: 0,
Dark: 0,
Dragon: 0,
Electric: 0,
Fairy: 0,
Fighting: 2,
Fire: 1,
Flying: 1,
Ghost: 0,
Grass: 2,
Ground: 2,
Ice: 0,
Normal: 0,
Poison: 0,
Psychic: 0,
Rock: 1,
Steel: 0,
Water: 0,
Crystal: 0,
Feral: 0,
},
HPivs: { atk: 30, def: 30, spd: 30 },
HPdvs: { atk: 13, def: 13 },
},
dark: {
damageTaken: {
prankster: 3,
Bug: 1,
Dark: 2,
Dragon: 0,
Electric: 0,
Fairy: 1,
Fighting: 1,
Fire: 0,
Flying: 0,
Ghost: 2,
Grass: 0,
Ground: 0,
Ice: 0,
Normal: 0,
Poison: 0,
Psychic: 3,
Rock: 0,
Steel: 0,
Water: 0,
Crystal: 1,
Feral: 0,
},
HPivs: {},
},
dragon: {
damageTaken: {
Bug: 0,
Dark: 0,
Dragon: 1,
Electric: 2,
Fairy: 1,
Fighting: 0,
Fire: 2,
Flying: 0,
Ghost: 0,
Grass: 2,
Ground: 0,
Ice: 1,
Normal: 0,
Poison: 0,
Psychic: 0,
Rock: 0,
Steel: 0,
Water: 2,
Crystal: 0,
Feral: 2,
},
HPivs: { atk: 30 },
HPdvs: { def: 14 },
},
electric: {
damageTaken: {
par: 3,
Bug: 0,
Dark: 0,
Dragon: 0,
Electric: 2,
Fairy: 0,
Fighting: 0,
Fire: 0,
Flying: 2,
Ghost: 0,
Grass: 0,
Ground: 1,
Ice: 0,
Normal: 0,
Poison: 0,
Psychic: 0,
Rock: 0,
Steel: 2,
Water: 0,
Crystal: 2,
Feral: 0,
},
HPivs: { spa: 30 },
HPdvs: { atk: 14 },
},
fairy: {
damageTaken: {
Bug: 2,
Dark: 2,
Dragon: 3,
Electric: 0,
Fairy: 0,
Fighting: 2,
Fire: 0,
Flying: 0,
Ghost: 0,
Grass: 0,
Ground: 0,
Ice: 0,
Normal: 0,
Poison: 1,
Psychic: 0,
Rock: 0,
Steel: 1,
Water: 0,
Crystal: 0,
Feral: 1,
},
},
fighting: {
damageTaken: {
Bug: 2,
Dark: 2,
Dragon: 0,
Electric: 0,
Fairy: 1,
Fighting: 0,
Fire: 0,
Flying: 1,
Ghost: 0,
Grass: 0,
Ground: 0,
Ice: 0,
Normal: 0,
Poison: 0,
Psychic: 1,
Rock: 2,
Steel: 0,
Water: 0,
Crystal: 2,
Feral: 0,
},
HPivs: { def: 30, spa: 30, spd: 30, spe: 30 },
HPdvs: { atk: 12, def: 12 },
},
fire: {
damageTaken: {
brn: 3,
Bug: 2,
Dark: 0,
Dragon: 0,
Electric: 0,
Fairy: 2,
Fighting: 0,
Fire: 2,
Flying: 0,
Ghost: 0,
Grass: 2,
Ground: 1,
Ice: 2,
Normal: 0,
Poison: 0,
Psychic: 0,
Rock: 1,
Steel: 2,
Water: 1,
Crystal: 1,
Feral: 2,
},
HPivs: { atk: 30, spa: 30, spe: 30 },
HPdvs: { atk: 14, def: 12 },
},
flying: {
damageTaken: {
Bug: 2,
Dark: 0,
Dragon: 0,
Electric: 1,
Fairy: 0,
Fighting: 2,
Fire: 0,
Flying: 0,
Ghost: 0,
Grass: 2,
Ground: 3,
Ice: 1,
Normal: 0,
Poison: 0,
Psychic: 0,
Rock: 1,
Steel: 0,
Water: 0,
Crystal: 0,
Feral: 1,
},
HPivs: { hp: 30, atk: 30, def: 30, spa: 30, spd: 30 },
HPdvs: { atk: 12, def: 13 },
},
ghost: {
damageTaken: {
trapped: 3,
Bug: 2,
Dark: 1,
Dragon: 0,
Electric: 0,
Fairy: 0,
Fighting: 3,
Fire: 0,
Flying: 0,
Ghost: 1,
Grass: 0,
Ground: 0,
Ice: 0,
Normal: 3,
Poison: 2,
Psychic: 0,
Rock: 0,
Steel: 0,
Water: 0,
Crystal: 1,
Feral: 2,
},
HPivs: { def: 30, spd: 30 },
HPdvs: { atk: 13, def: 14 },
},
grass: {
damageTaken: {
powder: 3,
Bug: 1,
Dark: 0,
Dragon: 0,
Electric: 2,
Fairy: 0,
Fighting: 0,
Fire: 1,
Flying: 1,
Ghost: 0,
Grass: 2,
Ground: 2,
Ice: 1,
Normal: 0,
Poison: 1,
Psychic: 0,
Rock: 0,
Steel: 0,
Water: 2,
Crystal: 0,
Feral: 1,
},
HPivs: { atk: 30, spa: 30 },
HPdvs: { atk: 14, def: 14 },
},
ground: {
damageTaken: {
sandstorm: 3,
Bug: 0,
Dark: 0,
Dragon: 0,
Electric: 3,
Fairy: 0,
Fighting: 0,
Fire: 0,
Flying: 0,
Ghost: 0,
Grass: 1,
Ground: 0,
Ice: 1,
Normal: 0,
Poison: 2,
Psychic: 0,
Rock: 2,
Steel: 0,
Water: 1,
Crystal: 0,
Feral: 0,
},
HPivs: { spa: 30, spd: 30 },
HPdvs: { atk: 12 },
},
ice: {
damageTaken: {
hail: 3,
frz: 3,
Bug: 0,
Dark: 0,
Dragon: 0,
Electric: 0,
Fairy: 0,
Fighting: 1,
Fire: 1,
Flying: 0,
Ghost: 0,
Grass: 0,
Ground: 0,
Ice: 2,
Normal: 0,
Poison: 0,
Psychic: 0,
Rock: 1,
Steel: 1,
Water: 0,
Crystal: 0,
Feral: 0,
},
HPivs: { atk: 30, def: 30 },
HPdvs: { def: 13 },
},
normal: {
damageTaken: {
Bug: 0,
Dark: 0,
Dragon: 0,
Electric: 0,
Fairy: 0,
Fighting: 1,
Fire: 0,
Flying: 0,
Ghost: 3,
Grass: 0,
Ground: 0,
Ice: 0,
Normal: 0,
Poison: 0,
Psychic: 0,
Rock: 0,
Steel: 0,
Water: 0,
Crystal: 0,
Feral: 1,
},
},
poison: {
damageTaken: {
psn: 3,
tox: 3,
Bug: 2,
Dark: 0,
Dragon: 0,
Electric: 0,
Fairy: 2,
Fighting: 2,
Fire: 0,
Flying: 0,
Ghost: 0,
Grass: 2,
Ground: 1,
Ice: 0,
Normal: 0,
Poison: 2,
Psychic: 1,
Rock: 0,
Steel: 0,
Water: 0,
Crystal: 0,
Feral: 2,
},
HPivs: { def: 30, spa: 30, spd: 30 },
HPdvs: { atk: 12, def: 14 },
},
psychic: {
damageTaken: {
Bug: 1,
Dark: 1,
Dragon: 0,
Electric: 0,
Fairy: 0,
Fighting: 2,
Fire: 0,
Flying: 0,
Ghost: 1,
Grass: 0,
Ground: 0,
Ice: 0,
Normal: 0,
Poison: 0,
Psychic: 2,
Rock: 0,
Steel: 0,
Water: 0,
Crystal: 0,
Feral: 0,
},
HPivs: { atk: 30, spe: 30 },
HPdvs: { def: 12 },
},
rock: {
damageTaken: {
sandstorm: 3,
Bug: 0,
Dark: 0,
Dragon: 0,
Electric: 0,
Fairy: 0,
Fighting: 1,
Fire: 2,
Flying: 2,
Ghost: 0,
Grass: 1,
Ground: 1,
Ice: 0,
Normal: 2,
Poison: 2,
Psychic: 0,
Rock: 0,
Steel: 1,
Water: 1,
Crystal: 0,
Feral: 0,
},
HPivs: { def: 30, spd: 30, spe: 30 },
HPdvs: { atk: 13, def: 12 },
},
steel: {
damageTaken: {
psn: 3,
tox: 3,
sandstorm: 3,
Bug: 2,
Dark: 0,
Dragon: 2,
Electric: 0,
Fairy: 2,
Fighting: 1,
Fire: 1,
Flying: 2,
Ghost: 0,
Grass: 2,
Ground: 1,
Ice: 2,
Normal: 2,
Poison: 3,
Psychic: 2,
Rock: 2,
Steel: 2,
Water: 0,
Crystal: 2,
Feral: 0,
},
HPivs: { spd: 30 },
HPdvs: { atk: 13 },
},
water: {
damageTaken: {
Bug: 0,
Dark: 0,
Dragon: 0,
Electric: 1,
Fairy: 0,
Fighting: 0,
Fire: 2,
Flying: 0,
Ghost: 0,
Grass: 1,
Ground: 0,
Ice: 2,
Normal: 0,
Poison: 0,
Psychic: 0,
Rock: 0,
Steel: 2,
Water: 2,
Crystal: 0,
Feral: 1,
},
HPivs: { atk: 30, def: 30, spa: 30 },
HPdvs: { atk: 14, def: 13 },
},
crystal: {
damageTaken: {
brn: 3,
sandstorm: 3,
Bug: 0,
Dark: 2,
Dragon: 0,
Electric: 1,
Fairy: 0,
Fighting: 1,
Fire: 2,
Flying: 0,
Ghost: 0,
Grass: 0,
Ground: 2,
Ice: 0,
Normal: 2,
Poison: 0,
Psychic: 0,
Rock: 2,
Steel: 1,
Water: 2,
Crystal: 2,
Feral: 2,
},
},
feral: {
damageTaken: {
slp: 3,
Bug: 0,
Dark: 0,
Dragon: 1,
Electric: 0,
Fairy: 2,
Fighting: 0,
Fire: 1,
Flying: 0,
Ghost: 2,
Grass: 0,
Ground: 0,
Ice: 2,
Normal: 0,
Poison: 1,
Psychic: 0,
Rock: 0,
Steel: 0,
Water: 0,
Crystal: 0,
Feral: 0,
},
},
};

View File

@ -12725,7 +12725,7 @@ export const Pokedex: import('../sim/dex-species').SpeciesDataTable = {
num: 678,
name: "Meowstic-M-Mega",
baseSpecies: "Meowstic",
forme: "Mega",
forme: "M-Mega",
types: ["Psychic"],
gender: "M",
baseStats: { hp: 74, atk: 48, def: 76, spa: 143, spd: 101, spe: 124 },
@ -12735,6 +12735,7 @@ export const Pokedex: import('../sim/dex-species').SpeciesDataTable = {
color: "Blue",
eggGroups: ["Field"],
requiredItem: "Meowsticite",
battleOnly: "Meowstic",
gen: 9,
},
meowsticfmega: {

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": {
@ -693,7 +693,7 @@
"exclusiveMoves": ["doubleedge", "doubleedge", "doubleedge", "reflect"]
},
"dratini": {
"level": 89,
"level": 91,
"moves": ["bodyslam", "hyperbeam", "thunderbolt", "thunderbolt"],
"essentialMoves": ["blizzard", "thunderwave"]
},

View File

@ -103,6 +103,7 @@
]
},
"pikachu": {
"level": 73,
"sets": [
{
"role": "Fast Attacker",

View File

@ -342,7 +342,7 @@
]
},
"arcanine": {
"level": 79,
"level": 78,
"sets": [
{
"role": "Bulky Support",
@ -510,7 +510,7 @@
]
},
"dodrio": {
"level": 77,
"level": 78,
"sets": [
{
"role": "Wallbreaker",
@ -806,7 +806,7 @@
"sets": [
{
"role": "Setup Sweeper",
"movepool": ["calmmind", "hiddenpowerfire", "icebeam", "lovelykiss", "psychic", "substitute"],
"movepool": ["calmmind", "icebeam", "lovelykiss", "psychic", "substitute"],
"abilities": ["Oblivious"]
}
]
@ -1176,7 +1176,7 @@
]
},
"noctowl": {
"level": 92,
"level": 93,
"sets": [
{
"role": "Staller",
@ -1753,7 +1753,7 @@
"sets": [
{
"role": "Bulky Attacker",
"movepool": ["calmmind", "icebeam", "recover", "surf", "toxic"],
"movepool": ["calmmind", "explosion", "icebeam", "recover", "surf", "toxic"],
"abilities": ["Natural Cure"]
}
]
@ -2613,7 +2613,7 @@
]
},
"cacturne": {
"level": 95,
"level": 96,
"sets": [
{
"role": "Staller",
@ -2690,7 +2690,7 @@
},
{
"role": "Wallbreaker",
"movepool": ["earthquake", "explosion", "overheat", "rockslide", "shadowball"],
"movepool": ["earthquake", "explosion", "rockslide", "shadowball"],
"abilities": ["Levitate"],
"preferredTypes": ["Ground"]
}
@ -2781,7 +2781,7 @@
]
},
"kecleon": {
"level": 91,
"level": 92,
"sets": [
{
"role": "Wallbreaker",
@ -3024,7 +3024,7 @@
]
},
"latios": {
"level": 67,
"level": 66,
"sets": [
{
"role": "Bulky Setup",

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"]
}
]
@ -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"]
}
]
},
@ -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"]
}
]
@ -2136,7 +2145,7 @@
]
},
"torkoal": {
"level": 88,
"level": 87,
"sets": [
{
"role": "Bulky Support",
@ -2355,7 +2364,7 @@
]
},
"kecleon": {
"level": 91,
"level": 92,
"sets": [
{
"role": "Bulky Support",
@ -2370,7 +2379,7 @@
{
"role": "Wallbreaker",
"movepool": ["hiddenpowerfighting", "shadowclaw", "shadowsneak", "thunderwave", "willowisp"],
"abilities": ["Frisk", "Insomnia"]
"abilities": ["Insomnia"]
}
]
},
@ -2525,7 +2534,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 +2663,7 @@
]
},
"jirachi": {
"level": 75,
"level": 74,
"sets": [
{
"role": "Bulky Support",
@ -2685,7 +2694,7 @@
]
},
"deoxysattack": {
"level": 72,
"level": 71,
"sets": [
{
"role": "Wallbreaker",
@ -2710,7 +2719,7 @@
]
},
"deoxysspeed": {
"level": 79,
"level": 80,
"sets": [
{
"role": "Fast Support",
@ -2930,7 +2939,7 @@
]
},
"floatzel": {
"level": 84,
"level": 83,
"sets": [
{
"role": "Fast Attacker",
@ -2946,7 +2955,7 @@
]
},
"cherrim": {
"level": 96,
"level": 95,
"sets": [
{
"role": "Staller",
@ -3127,7 +3136,7 @@
]
},
"hippowdon": {
"level": 80,
"level": 79,
"sets": [
{
"role": "Bulky Support",
@ -3496,7 +3505,7 @@
]
},
"rotomfan": {
"level": 79,
"level": 78,
"sets": [
{
"role": "Bulky Attacker",
@ -3616,7 +3625,7 @@
]
},
"regigigas": {
"level": 82,
"level": 83,
"sets": [
{
"role": "Staller",
@ -3686,7 +3695,7 @@
]
},
"darkrai": {
"level": 69,
"level": 68,
"sets": [
{
"role": "Setup Sweeper",

View File

@ -215,17 +215,6 @@ export class RandomGen4Teams extends RandomGen5Teams {
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']);

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"]
}
]
},
@ -515,7 +522,7 @@
]
},
"cloyster": {
"level": 78,
"level": 79,
"sets": [
{
"role": "Setup Sweeper",
@ -529,7 +536,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 +651,7 @@
]
},
"rhydon": {
"level": 83,
"level": 82,
"sets": [
{
"role": "Bulky Attacker",
@ -913,7 +920,7 @@
]
},
"articuno": {
"level": 84,
"level": 83,
"sets": [
{
"role": "Staller",
@ -983,7 +990,7 @@
"sets": [
{
"role": "Fast Attacker",
"movepool": ["aurasphere", "calmmind", "fireblast", "psystrike", "recover", "shadowball"],
"movepool": ["aurasphere", "calmmind", "fireblast", "psystrike", "recover", "signalbeam"],
"abilities": ["Unnerve"]
}
]
@ -1189,7 +1196,7 @@
]
},
"jumpluff": {
"level": 82,
"level": 81,
"sets": [
{
"role": "Fast Support",
@ -1310,7 +1317,7 @@
]
},
"forretress": {
"level": 78,
"level": 79,
"sets": [
{
"role": "Bulky Support",
@ -1373,9 +1380,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"]
}
]
@ -1432,7 +1444,7 @@
]
},
"ursaring": {
"level": 85,
"level": 84,
"sets": [
{
"role": "Wallbreaker",
@ -1467,7 +1479,7 @@
]
},
"octillery": {
"level": 91,
"level": 92,
"sets": [
{
"role": "Bulky Attacker",
@ -1545,16 +1557,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"]
}
]
},
@ -1711,7 +1717,7 @@
]
},
"celebi": {
"level": 81,
"level": 80,
"sets": [
{
"role": "Fast Attacker",
@ -2187,7 +2193,7 @@
]
},
"grumpig": {
"level": 92,
"level": 91,
"sets": [
{
"role": "Bulky Attacker",
@ -2388,7 +2394,7 @@
]
},
"castform": {
"level": 97,
"level": 98,
"sets": [
{
"role": "Bulky Attacker",
@ -2398,7 +2404,7 @@
]
},
"kecleon": {
"level": 94,
"level": 95,
"sets": [
{
"role": "Bulky Support",
@ -2413,7 +2419,7 @@
{
"role": "Wallbreaker",
"movepool": ["hiddenpowerfighting", "shadowclaw", "shadowsneak", "thunderwave", "willowisp"],
"abilities": ["Cursed Body", "Frisk", "Insomnia"]
"abilities": ["Insomnia"]
}
]
},
@ -2542,7 +2548,7 @@
]
},
"salamence": {
"level": 75,
"level": 74,
"sets": [
{
"role": "Setup Sweeper",
@ -2702,7 +2708,7 @@
]
},
"jirachi": {
"level": 75,
"level": 74,
"sets": [
{
"role": "Bulky Support",
@ -2777,7 +2783,7 @@
]
},
"infernape": {
"level": 79,
"level": 78,
"sets": [
{
"role": "Wallbreaker",
@ -2848,7 +2854,7 @@
]
},
"luxray": {
"level": 89,
"level": 88,
"sets": [
{
"role": "Wallbreaker",
@ -2934,7 +2940,7 @@
]
},
"wormadamtrash": {
"level": 88,
"level": 87,
"sets": [
{
"role": "Staller",
@ -3426,12 +3432,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 +3514,7 @@
]
},
"rotomwash": {
"level": 79,
"level": 80,
"sets": [
{
"role": "Bulky Attacker",
@ -3563,7 +3564,7 @@
]
},
"mesprit": {
"level": 82,
"level": 83,
"sets": [
{
"role": "Fast Attacker",
@ -3662,7 +3663,7 @@
]
},
"giratinaorigin": {
"level": 73,
"level": 72,
"sets": [
{
"role": "Fast Attacker",
@ -3976,7 +3977,7 @@
]
},
"serperior": {
"level": 85,
"level": 86,
"sets": [
{
"role": "Fast Attacker",
@ -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", "energyball", "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']);
}
}

View File

@ -15,7 +15,7 @@
]
},
"venusaurmega": {
"level": 78,
"level": 77,
"sets": [
{
"role": "Bulky Attacker",
@ -105,7 +105,7 @@
]
},
"beedrillmega": {
"level": 78,
"level": 77,
"sets": [
{
"role": "Fast Attacker",
@ -212,7 +212,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 +223,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 +339,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"]
}
@ -822,7 +828,7 @@
]
},
"pinsir": {
"level": 84,
"level": 85,
"sets": [
{
"role": "Fast Attacker",
@ -859,7 +865,7 @@
]
},
"gyarados": {
"level": 77,
"level": 78,
"sets": [
{
"role": "Setup Sweeper",
@ -1056,7 +1062,7 @@
"sets": [
{
"role": "Fast Attacker",
"movepool": ["aurasphere", "calmmind", "fireblast", "psystrike", "recover", "shadowball"],
"movepool": ["aurasphere", "calmmind", "fireblast", "psystrike", "recover", "signalbeam"],
"abilities": ["Unnerve"]
}
]
@ -1076,7 +1082,7 @@
"sets": [
{
"role": "Setup Sweeper",
"movepool": ["aurasphere", "calmmind", "fireblast", "psystrike", "recover", "shadowball"],
"movepool": ["aurasphere", "calmmind", "fireblast", "psystrike", "recover", "signalbeam"],
"abilities": ["Unnerve"]
}
]
@ -1176,7 +1182,7 @@
]
},
"crobat": {
"level": 81,
"level": 80,
"sets": [
{
"role": "Bulky Attacker",
@ -1388,7 +1394,7 @@
]
},
"wobbuffet": {
"level": 92,
"level": 93,
"sets": [
{
"role": "Bulky Support",
@ -1500,7 +1506,7 @@
]
},
"scizor": {
"level": 79,
"level": 78,
"sets": [
{
"role": "Setup Sweeper",
@ -1661,7 +1667,7 @@
]
},
"houndoom": {
"level": 85,
"level": 84,
"sets": [
{
"role": "Fast Attacker",
@ -1848,7 +1854,7 @@
]
},
"lugia": {
"level": 72,
"level": 71,
"sets": [
{
"role": "Staller",
@ -2506,6 +2512,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 +2527,6 @@
"role": "Setup Sweeper",
"movepool": ["dragondance", "earthquake", "return", "roost"],
"abilities": ["Natural Cure"]
},
{
"role": "Bulky Support",
"movepool": ["earthquake", "fireblast", "healbell", "return", "roost"],
"abilities": ["Natural Cure"]
}
]
},
@ -3806,7 +3812,7 @@
"sets": [
{
"role": "Setup Sweeper",
"movepool": ["doubleedge", "knockoff", "leafblade", "swordsdance", "synthesis", "xscissor"],
"movepool": ["doubleedge", "knockoff", "leafblade", "substitute", "swordsdance", "synthesis"],
"abilities": ["Chlorophyll"],
"preferredTypes": ["Dark"]
}
@ -4079,9 +4085,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"]
}
]
},
@ -4718,7 +4728,7 @@
]
},
"scolipede": {
"level": 80,
"level": 79,
"sets": [
{
"role": "Fast Support",
@ -4773,7 +4783,7 @@
]
},
"krookodile": {
"level": 79,
"level": 78,
"sets": [
{
"role": "Fast Attacker",
@ -4822,9 +4832,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 +4947,7 @@
"sets": [
{
"role": "Bulky Setup",
"movepool": ["calmmind", "focusblast", "psychic", "psyshock", "recover", "signalbeam"],
"movepool": ["calmmind", "focusblast", "psychic", "psyshock", "recover"],
"abilities": ["Magic Guard"]
}
]
@ -5045,7 +5055,7 @@
"sets": [
{
"role": "Wallbreaker",
"movepool": ["bugbuzz", "gigadrain", "stickyweb", "thunder", "voltswitch"],
"movepool": ["bugbuzz", "energyball", "stickyweb", "thunder", "voltswitch"],
"abilities": ["Compound Eyes"],
"preferredTypes": ["Bug"]
}
@ -5186,7 +5196,7 @@
]
},
"druddigon": {
"level": 85,
"level": 86,
"sets": [
{
"role": "Wallbreaker",
@ -5293,7 +5303,7 @@
},
{
"role": "Bulky Attacker",
"movepool": ["darkpulse", "dracometeor", "fireblast", "roost", "uturn"],
"movepool": ["darkpulse", "dracometeor", "fireblast", "roost", "toxic", "uturn"],
"abilities": ["Levitate"]
},
{
@ -5685,7 +5695,7 @@
]
},
"pangoro": {
"level": 85,
"level": 84,
"sets": [
{
"role": "Wallbreaker",
@ -6001,7 +6011,7 @@
]
},
"gourgeistsuper": {
"level": 88,
"level": 87,
"sets": [
{
"role": "Bulky Support",

View File

@ -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'],

View File

@ -283,7 +283,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 +294,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 +453,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"]
}
]
},
@ -882,7 +888,7 @@
]
},
"rhydon": {
"level": 86,
"level": 85,
"sets": [
{
"role": "Bulky Attacker",
@ -933,7 +939,7 @@
]
},
"seaking": {
"level": 94,
"level": 95,
"sets": [
{
"role": "Fast Attacker",
@ -1269,7 +1275,7 @@
"sets": [
{
"role": "Fast Attacker",
"movepool": ["aurasphere", "calmmind", "fireblast", "psystrike", "recover", "shadowball"],
"movepool": ["aurasphere", "calmmind", "fireblast", "psystrike", "recover", "signalbeam"],
"abilities": ["Unnerve"]
}
]
@ -1289,7 +1295,7 @@
"sets": [
{
"role": "Setup Sweeper",
"movepool": ["aurasphere", "calmmind", "fireblast", "psystrike", "recover", "shadowball"],
"movepool": ["aurasphere", "calmmind", "fireblast", "psystrike", "recover", "signalbeam"],
"abilities": ["Unnerve"]
}
]
@ -1437,7 +1443,7 @@
]
},
"ampharosmega": {
"level": 84,
"level": 85,
"sets": [
{
"role": "Bulky Attacker",
@ -1549,7 +1555,7 @@
]
},
"espeon": {
"level": 84,
"level": 83,
"sets": [
{
"role": "Fast Attacker",
@ -1686,7 +1692,7 @@
]
},
"steelixmega": {
"level": 81,
"level": 80,
"sets": [
{
"role": "Bulky Support",
@ -1863,7 +1869,7 @@
]
},
"skarmory": {
"level": 76,
"level": 75,
"sets": [
{
"role": "Bulky Support",
@ -1888,7 +1894,7 @@
]
},
"houndoommega": {
"level": 81,
"level": 80,
"sets": [
{
"role": "Setup Sweeper",
@ -2454,7 +2460,7 @@
]
},
"sableyemega": {
"level": 87,
"level": 86,
"sets": [
{
"role": "Bulky Setup",
@ -2562,7 +2568,7 @@
]
},
"minun": {
"level": 94,
"level": 95,
"sets": [
{
"role": "Bulky Setup",
@ -2731,7 +2737,7 @@
]
},
"cacturne": {
"level": 92,
"level": 93,
"sets": [
{
"role": "Wallbreaker",
@ -2748,6 +2754,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 +3053,7 @@
]
},
"gorebyss": {
"level": 84,
"level": 85,
"sets": [
{
"role": "Setup Sweeper",
@ -3368,7 +3379,7 @@
]
},
"deoxysattack": {
"level": 73,
"level": 72,
"sets": [
{
"role": "Wallbreaker",
@ -3749,7 +3760,7 @@
]
},
"honchkrow": {
"level": 84,
"level": 83,
"sets": [
{
"role": "Wallbreaker",
@ -4115,7 +4126,7 @@
"sets": [
{
"role": "Setup Sweeper",
"movepool": ["doubleedge", "knockoff", "leafblade", "swordsdance", "synthesis", "xscissor"],
"movepool": ["doubleedge", "knockoff", "leafblade", "substitute", "swordsdance", "synthesis"],
"abilities": ["Chlorophyll"],
"preferredTypes": ["Dark"]
}
@ -4406,9 +4417,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"]
}
]
},
@ -4970,7 +4985,7 @@
]
},
"swoobat": {
"level": 87,
"level": 88,
"sets": [
{
"role": "Bulky Attacker",
@ -5200,9 +5215,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 +5330,7 @@
"sets": [
{
"role": "Bulky Setup",
"movepool": ["calmmind", "focusblast", "psychic", "psyshock", "recover", "signalbeam"],
"movepool": ["calmmind", "focusblast", "psychic", "psyshock", "recover"],
"abilities": ["Magic Guard"]
}
]
@ -5429,7 +5444,7 @@
"sets": [
{
"role": "Wallbreaker",
"movepool": ["bugbuzz", "gigadrain", "stickyweb", "thunder", "voltswitch"],
"movepool": ["bugbuzz", "energyball", "stickyweb", "thunder", "voltswitch"],
"abilities": ["Compound Eyes"],
"preferredTypes": ["Bug"]
}
@ -5551,7 +5566,7 @@
]
},
"stunfisk": {
"level": 89,
"level": 88,
"sets": [
{
"role": "Bulky Attacker",
@ -5694,7 +5709,7 @@
},
{
"role": "Bulky Attacker",
"movepool": ["darkpulse", "defog", "dracometeor", "fireblast", "roost", "uturn"],
"movepool": ["darkpulse", "defog", "dracometeor", "fireblast", "roost", "toxic", "uturn"],
"abilities": ["Levitate"]
},
{
@ -5802,7 +5817,7 @@
]
},
"thundurus": {
"level": 82,
"level": 81,
"sets": [
{
"role": "Setup Sweeper",
@ -5933,7 +5948,7 @@
]
},
"kyuremwhite": {
"level": 76,
"level": 75,
"sets": [
{
"role": "Fast Attacker",
@ -6051,7 +6066,7 @@
]
},
"diggersby": {
"level": 83,
"level": 82,
"sets": [
{
"role": "Setup Sweeper",
@ -6436,7 +6451,7 @@
]
},
"gourgeistsmall": {
"level": 90,
"level": 91,
"sets": [
{
"role": "Bulky Support",
@ -6446,7 +6461,7 @@
]
},
"gourgeistlarge": {
"level": 90,
"level": 91,
"sets": [
{
"role": "Bulky Support",
@ -6944,7 +6959,7 @@
]
},
"comfey": {
"level": 88,
"level": 87,
"sets": [
{
"role": "Bulky Support",
@ -7459,7 +7474,7 @@
]
},
"nihilego": {
"level": 80,
"level": 79,
"sets": [
{
"role": "Fast Support",
@ -7548,7 +7563,7 @@
]
},
"guzzlord": {
"level": 87,
"level": 86,
"sets": [
{
"role": "AV Pivot",
@ -7615,9 +7630,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 +7641,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

@ -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'],
@ -933,7 +933,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';
@ -1607,8 +1607,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"]
@ -424,7 +424,7 @@
"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,7 +457,7 @@
"noDynamaxMoves": ["dragondance", "dualwingbeat", "earthquake", "outrage", "roost"]
},
"mewtwo": {
"level": 70,
"level": 71,
"moves": ["fireblast", "nastyplot", "psystrike", "recover", "shadowball"],
"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"]
@ -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"]
@ -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 (!counter.get('Special') || moves.has('rest') && moves.has('sleeptalk'));
case 'Compound Eyes': case 'No Guard':
return !counter.get('inaccurate');
case 'Cursed Body':

File diff suppressed because it is too large Load Diff

View File

@ -408,7 +408,7 @@
]
},
"slowbrogalar": {
"level": 86,
"level": 87,
"sets": [
{
"role": "Doubles Wallbreaker",
@ -586,7 +586,7 @@
]
},
"weezing": {
"level": 90,
"level": 91,
"sets": [
{
"role": "Doubles Support",
@ -1041,7 +1041,7 @@
"role": "Offensive Protect",
"movepool": ["Hurricane", "Hyper Voice", "Protect", "Tailwind"],
"abilities": ["Tinted Lens"],
"teraTypes": ["Flying"]
"teraTypes": ["Normal", "Steel"]
}
]
},
@ -1096,7 +1096,7 @@
]
},
"azumarill": {
"level": 82,
"level": 83,
"sets": [
{
"role": "Doubles Wallbreaker",
@ -1414,7 +1414,7 @@
]
},
"donphan": {
"level": 86,
"level": 87,
"sets": [
{
"role": "Doubles Support",
@ -1480,7 +1480,7 @@
"sets": [
{
"role": "Doubles Support",
"movepool": ["Heal Pulse", "Helping Hand", "Hyper Voice", "Protect", "Seismic Toss", "Soft-Boiled", "Thunder Wave"],
"movepool": ["Helping Hand", "Hyper Voice", "Life Dew", "Soft-Boiled", "Thunder Wave"],
"abilities": ["Healer"],
"teraTypes": ["Fairy", "Ghost", "Poison"]
}
@ -1538,13 +1538,13 @@
"role": "Doubles Bulky Setup",
"movepool": ["Dragon Dance", "High Horsepower", "Knock Off", "Protect", "Rock Slide", "Stone Edge"],
"abilities": ["Sand Stream"],
"teraTypes": ["Ghost", "Rock", "Steel"]
"teraTypes": ["Ghost", "Rock"]
},
{
"role": "Doubles Bulky Attacker",
"movepool": ["Fire Blast", "High Horsepower", "Icy Wind", "Knock Off", "Rock Slide", "Stone Edge"],
"abilities": ["Sand Stream"],
"teraTypes": ["Flying", "Ghost", "Steel"]
"teraTypes": ["Flying", "Ghost"]
}
]
},
@ -1682,7 +1682,7 @@
},
{
"role": "Doubles Wallbreaker",
"movepool": ["Dazzling Gleam", "Moonblast", "Mystical Fire", "Psychic", "Trick"],
"movepool": ["Dazzling Gleam", "Moonblast", "Mystical Fire", "Psychic"],
"abilities": ["Trace"],
"teraTypes": ["Fairy", "Fire", "Steel"]
}
@ -1847,7 +1847,7 @@
"role": "Doubles Support",
"movepool": ["Encore", "Struggle Bug", "Tailwind", "Thunder Wave"],
"abilities": ["Prankster"],
"teraTypes": ["Steel", "Water"]
"teraTypes": ["Steel", "Water"]
}
]
},
@ -2023,14 +2023,14 @@
"sets": [
{
"role": "Doubles Support",
"movepool": ["Energy Ball", "Helping Hand", "Hurricane", "Protect", "Tailwind", "Wide Guard"],
"movepool": ["Energy Ball", "Hurricane", "Protect", "Tailwind", "Wide Guard"],
"abilities": ["Harvest"],
"teraTypes": ["Steel"]
}
]
},
"chimecho": {
"level": 95,
"level": 94,
"sets": [
{
"role": "Doubles Support",
@ -2091,7 +2091,7 @@
]
},
"regirock": {
"level": 83,
"level": 82,
"sets": [
{
"role": "Doubles Bulky Setup",
@ -2575,7 +2575,7 @@
"sets": [
{
"role": "Doubles Support",
"movepool": ["Encore", "Helping Hand", "Hydro Pump", "Icy Wind", "Tailwind", "Tickle"],
"movepool": ["Encore", "Helping Hand", "Hydro Pump", "Icy Wind", "Tailwind"],
"abilities": ["Storm Drain"],
"teraTypes": ["Fire", "Ground"]
}
@ -2901,7 +2901,7 @@
]
},
"uxie": {
"level": 86,
"level": 85,
"sets": [
{
"role": "Doubles Support",
@ -3086,7 +3086,7 @@
"role": "Bulky Protect",
"movepool": ["Ice Beam", "Protect", "Scald", "Tail Glow"],
"abilities": ["Hydration"],
"teraTypes": ["Grass", "Steel", "Water"]
"teraTypes": ["Grass", "Steel"]
},
{
"role": "Doubles Bulky Setup",
@ -3486,13 +3486,7 @@
"sets": [
{
"role": "Doubles Bulky Attacker",
"movepool": ["Encore", "Moonblast", "Tailwind", "Taunt"],
"abilities": ["Prankster"],
"teraTypes": ["Fire", "Ghost", "Steel"]
},
{
"role": "Doubles Support",
"movepool": ["Encore", "Helping Hand", "Moonblast", "Tailwind"],
"movepool": ["Encore", "Helping Hand", "Moonblast", "Tailwind", "Taunt"],
"abilities": ["Prankster"],
"teraTypes": ["Fire", "Ghost", "Steel"]
}
@ -4298,7 +4292,7 @@
"sets": [
{
"role": "Choice Item user",
"movepool": ["Aura Sphere", "Dark Pulse", "Dragon Pulse", "Muddy Water", "U-turn"],
"movepool": ["Aura Sphere", "Dark Pulse", "Dragon Pulse", "Muddy Water"],
"abilities": ["Mega Launcher"],
"teraTypes": ["Dark", "Dragon", "Fighting"]
},
@ -4372,7 +4366,7 @@
]
},
"goodrahisui": {
"level": 82,
"level": 81,
"sets": [
{
"role": "Doubles Bulky Attacker",
@ -4411,7 +4405,7 @@
]
},
"avalugg": {
"level": 91,
"level": 92,
"sets": [
{
"role": "Bulky Protect",
@ -4615,7 +4609,7 @@
"teraTypes": ["Ground"]
},
{
"role": "Doubles Setup Sweeper",
"role": "Doubles Bulky Setup",
"movepool": ["Air Slash", "Protect", "Quiver Dance", "Revelation Dance"],
"abilities": ["Dancer"],
"teraTypes": ["Ground"]
@ -4632,7 +4626,7 @@
"teraTypes": ["Ground"]
},
{
"role": "Doubles Setup Sweeper",
"role": "Doubles Bulky Setup",
"movepool": ["Air Slash", "Protect", "Quiver Dance", "Revelation Dance"],
"abilities": ["Dancer"],
"teraTypes": ["Ground"]
@ -4649,7 +4643,7 @@
"teraTypes": ["Fighting", "Ground"]
},
{
"role": "Doubles Setup Sweeper",
"role": "Doubles Bulky Setup",
"movepool": ["Air Slash", "Protect", "Quiver Dance", "Revelation Dance"],
"abilities": ["Dancer"],
"teraTypes": ["Fighting", "Ground"]
@ -4666,7 +4660,7 @@
"teraTypes": ["Fighting", "Ground"]
},
{
"role": "Doubles Setup Sweeper",
"role": "Doubles Bulky Setup",
"movepool": ["Air Slash", "Protect", "Quiver Dance", "Revelation Dance"],
"abilities": ["Dancer"],
"teraTypes": ["Fighting", "Ground"]
@ -5183,8 +5177,8 @@
"teraTypes": ["Dragon", "Steel"]
},
{
"role": "Doubles Support",
"movepool": ["Glare", "High Horsepower", "Rest", "Stealth Rock", "Stone Edge"],
"role": "Doubles Bulky Attacker",
"movepool": ["Glare", "High Horsepower", "Rest", "Stone Edge"],
"abilities": ["Shed Skin"],
"teraTypes": ["Dragon", "Steel"]
}
@ -5206,7 +5200,7 @@
"sets": [
{
"role": "Doubles Wallbreaker",
"movepool": ["Close Combat", "Poison Jab", "Protect", "Psychic Fangs", "Waterfall"],
"movepool": ["Close Combat", "Flip Turn", "Poison Jab", "Protect", "Waterfall"],
"abilities": ["Propeller Tail"],
"teraTypes": ["Fighting"]
}
@ -5316,6 +5310,12 @@
"movepool": ["Alluring Voice", "Dazzling Gleam", "Decorate", "Encore", "Protect"],
"abilities": ["Aroma Veil"],
"teraTypes": ["Steel"]
},
{
"role": "Doubles Bulky Attacker",
"movepool": ["Alluring Voice", "Dazzling Gleam", "Decorate", "Helping Hand", "Protect"],
"abilities": ["Aroma Veil"],
"teraTypes": ["Steel"]
}
]
},
@ -5335,9 +5335,9 @@
"sets": [
{
"role": "Doubles Support",
"movepool": ["Electroweb", "Recover", "Thunderbolt", "Toxic Spikes"],
"movepool": ["Electroweb", "Recover", "Scald", "Thunderbolt"],
"abilities": ["Electric Surge"],
"teraTypes": ["Grass"]
"teraTypes": ["Grass", "Water"]
}
]
},
@ -5410,7 +5410,7 @@
]
},
"indeedeef": {
"level": 90,
"level": 91,
"sets": [
{
"role": "Doubles Support",
@ -5515,7 +5515,7 @@
"sets": [
{
"role": "Doubles Wallbreaker",
"movepool": ["Close Combat", "Coaching", "Crunch", "Howl", "Iron Head", "Psychic Fangs", "Stone Edge"],
"movepool": ["Close Combat", "Coaching", "Crunch", "Howl", "Stone Edge"],
"abilities": ["Dauntless Shield"],
"teraTypes": ["Dark", "Fighting", "Steel"]
},
@ -5673,7 +5673,7 @@
]
},
"calyrexshadow": {
"level": 62,
"level": 63,
"sets": [
{
"role": "Offensive Protect",
@ -5712,7 +5712,7 @@
]
},
"ursaluna": {
"level": 78,
"level": 77,
"sets": [
{
"role": "Doubles Wallbreaker",
@ -6121,7 +6121,7 @@
"role": "Doubles Support",
"movepool": ["Energy Ball", "Fire Blast", "Protect", "Rage Powder", "Will-O-Wisp"],
"abilities": ["Chlorophyll"],
"teraTypes": ["Fire", "Grass", "Steel"]
"teraTypes": ["Fire", "Steel"]
}
]
},
@ -6360,7 +6360,13 @@
"sets": [
{
"role": "Doubles Wallbreaker",
"movepool": ["Hyper Voice", "Nasty Plot", "Protect", "Psychic", "Trick Room"],
"movepool": ["Hyper Voice", "Protect", "Psychic", "Trick Room"],
"abilities": ["Armor Tail"],
"teraTypes": ["Fairy"]
},
{
"role": "Doubles Bulky Attacker",
"movepool": ["Hyper Voice", "Nasty Plot", "Psychic", "Trick Room"],
"abilities": ["Armor Tail"],
"teraTypes": ["Fairy"]
}
@ -6422,9 +6428,15 @@
"sets": [
{
"role": "Doubles Bulky Attacker",
"movepool": ["Close Combat", "Crunch", "Protect", "Rage Powder", "Seed Bomb", "Spore", "Sucker Punch"],
"movepool": ["Close Combat", "Crunch", "Protect", "Seed Bomb", "Spore", "Sucker Punch"],
"abilities": ["Protosynthesis"],
"teraTypes": ["Dark", "Poison"]
},
{
"role": "Doubles Support",
"movepool": ["Rage Powder", "Seed Bomb", "Spore", "Sucker Punch"],
"abilities": ["Protosynthesis"],
"teraTypes": ["Ghost", "Poison"]
}
]
},
@ -6669,7 +6681,13 @@
"sets": [
{
"role": "Bulky Protect",
"movepool": ["Knock Off", "Leech Seed", "Pollen Puff", "Protect", "Ruination"],
"movepool": ["Knock Off", "Leech Seed", "Pollen Puff", "Protect"],
"abilities": ["Tablets of Ruin"],
"teraTypes": ["Poison"]
},
{
"role": "Bulky Protect",
"movepool": ["Knock Off", "Leech Seed", "Protect", "Ruination"],
"abilities": ["Tablets of Ruin"],
"teraTypes": ["Poison"]
}
@ -6727,7 +6745,7 @@
]
},
"walkingwake": {
"level": 77,
"level": 78,
"sets": [
{
"role": "Doubles Wallbreaker",

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"]
@ -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"]
@ -694,7 +694,7 @@
"sets": [
{
"role": "Setup Sweeper",
"movepool": ["Close Combat", "Drain Punch", "Ice Punch", "Knock Off", "Mach Punch", "Rapid Spin", "Swords Dance"],
"movepool": ["Drain Punch", "Ice Punch", "Knock Off", "Mach Punch", "Rapid Spin", "Swords Dance"],
"abilities": ["Inner Focus", "Iron Fist"],
"teraTypes": ["Dark", "Fighting"]
},
@ -1417,6 +1417,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"]
}
]
},
@ -2259,7 +2265,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"]
@ -3044,7 +3050,7 @@
{
"role": "Fast Attacker",
"movepool": ["Body Press", "Flash Cannon", "Thunderbolt", "Volt Switch"],
"abilities": ["Magnet Pull"],
"abilities": ["Analytic", "Magnet Pull"],
"teraTypes": ["Electric", "Fighting", "Flying", "Water"]
},
{
@ -3179,7 +3185,7 @@
"sets": [
{
"role": "Wallbreaker",
"movepool": ["Earthquake", "Ice Shard", "Icicle Crash", "Knock Off", "Stealth Rock"],
"movepool": ["Earthquake", "Ice Shard", "Icicle Crash", "Knock Off", "Stealth Rock", "Trailblaze"],
"abilities": ["Thick Fat"],
"teraTypes": ["Ground", "Ice"]
}
@ -3220,7 +3226,7 @@
]
},
"probopass": {
"level": 92,
"level": 91,
"sets": [
{
"role": "Bulky Setup",
@ -3241,7 +3247,7 @@
},
{
"role": "Bulky Support",
"movepool": ["Earthquake", "Pain Split", "Poltergeist", "Shadow Sneak", "Will-O-Wisp"],
"movepool": ["Earthquake", "Pain Split", "Poltergeist", "Will-O-Wisp"],
"abilities": ["Frisk"],
"teraTypes": ["Dark", "Fairy"]
},
@ -3748,7 +3754,7 @@
]
},
"arceusgrass": {
"level": 72,
"level": 73,
"sets": [
{
"role": "Setup Sweeper",
@ -3788,7 +3794,7 @@
]
},
"arceusice": {
"level": 72,
"level": 73,
"sets": [
{
"role": "Bulky Setup",
@ -3904,7 +3910,7 @@
"teraTypes": ["Fire"]
},
{
"role": "Setup Sweeper",
"role": "Bulky Setup",
"movepool": ["Bulk Up", "Drain Punch", "Flare Blitz", "Trailblaze"],
"abilities": ["Reckless"],
"teraTypes": ["Fighting", "Grass"]
@ -4011,15 +4017,9 @@
"sets": [
{
"role": "Fast Support",
"movepool": ["Encore", "Giga Drain", "Moonblast", "Stun Spore", "U-turn"],
"movepool": ["Encore", "Giga Drain", "Leech Seed", "Moonblast", "Stun Spore", "Substitute", "U-turn"],
"abilities": ["Prankster"],
"teraTypes": ["Poison", "Steel"]
},
{
"role": "Bulky Support",
"movepool": ["Encore", "Leech Seed", "Moonblast", "Substitute"],
"abilities": ["Prankster"],
"teraTypes": ["Steel"]
}
]
},
@ -4095,9 +4095,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 +4116,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 +4202,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"]
}
@ -4264,7 +4264,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 +4490,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"]
}
@ -5325,7 +5325,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 +5502,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"],
@ -5604,6 +5598,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 +5622,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 +5659,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",
@ -6449,16 +6449,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"]
}
]
},
@ -6831,7 +6837,7 @@
"teraTypes": ["Water"]
},
{
"role": "Setup Sweeper",
"role": "Bulky Setup",
"movepool": ["Gigaton Hammer", "Knock Off", "Play Rough", "Protect", "Swords Dance"],
"abilities": ["Mold Breaker"],
"teraTypes": ["Steel"]
@ -7280,7 +7286,7 @@
]
},
"ironjugulis": {
"level": 78,
"level": 77,
"sets": [
{
"role": "Wallbreaker",
@ -7314,7 +7320,7 @@
]
},
"ironbundle": {
"level": 77,
"level": 78,
"sets": [
{
"role": "Fast Attacker",

View File

@ -37,6 +37,7 @@ interface BattleFactorySet {
evs?: Partial<StatsTable>;
ivs?: Partial<StatsTable>;
shiny?: boolean;
level?: number;
}
interface BSSFactorySet {
species: string;
@ -815,6 +816,12 @@ export class RandomTeams {
}
}
// Enforce Encore on Whimsicott
if (movePool.includes('encore') && species.id === 'whimsicott') {
counter = this.addMove('encore', moves, types, abilities, teamDetails, species, isLead, isDoubles,
movePool, teraType, role);
}
// Enforce moves in doubles
if (isDoubles) {
const doublesEnforcedMoves = ['mortalspin', 'spore'];
@ -1175,7 +1182,7 @@ export class RandomTeams {
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 (
@ -1329,17 +1336,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 +1362,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 +1385,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') &&
@ -3004,6 +3012,260 @@ 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 itemsLimited = ['choicespecs', 'choiceband', 'choicescarf'];
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 (itemsLimited.includes(itemId) && teamData.has[itemId]) continue;
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 resistanceAbilities: { [k: string]: string[] } = {
dryskin: ['Water'], waterabsorb: ['Water'], stormdrain: ['Water'],
flashfire: ['Fire'], heatproof: ['Fire'], waterbubble: ['Fire'], wellbakedbody: ['Fire'],
lightningrod: ['Electric'], motordrive: ['Electric'], voltabsorb: ['Electric'],
sapsipper: ['Grass'],
thickfat: ['Ice', 'Fire'],
eartheater: ['Ground'], levitate: ['Ground'],
};
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] >= 2 * limitFactor) {
skip = true;
break;
}
}
}
}
if (skip) continue;
const set = this.random1v1FactorySet(species, teamData);
if (!set) continue;
// 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);
// Track resistances because we will require it for triple weaknesses
if (
typeMod < 0 ||
resistanceAbilities[ability.id]?.includes(typeName) ||
!this.dex.getImmunity(typeName, types)
) {
// We don't care about the number of resistances, so just set to 1
teamData.resistances[typeName] = 1;
// Track weaknesses
} else 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) {
// We reject if our team is triple weak to any type without having a resist
if (teamData.resistances[type]) continue;
if (teamData.weaknesses[type] >= 2 * limitFactor) return this.random1v1FactoryTeam(side, ++depth);
}
}
return pokemon;
}
}
export default RandomTeams;

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"]

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,856 @@
{
"albatrygon": {
"level": 100,
"sets": [
{
"role": "Fast Support",
"movepool": ["Sticky Web", "Taunt", "Encore", "Brave Bird", "Memento", "Parting Shot"],
"abilities": ["Prankster"]
},
{
"role": "Setup Sweeper",
"movepool": ["Tidy Up", "Brave Bird", "Drill Peck", "Feral Rush", "Feral Bite", "Sacred Sword"],
"abilities": ["Prankster"]
}
]
},
"aurorowl": {
"level": 100,
"sets": [
{
"role": "Setup Sweeper",
"movepool": ["Frost Breath", "Air Cutter", "Focus Blast", "Nasty Plot"],
"abilities": ["Technician"]
}
]
},
"arbrella": {
"level": 100,
"sets": [
{
"role": "Wallbreaker",
"movepool": ["Earthquake", "Wood Hammer", "Swords Dance", "Synthesis", "Stone Edge", "Superpower"],
"abilities": ["Tough Claws"]
},
{
"role": "Choice Scarf",
"movepool": ["Earthquake", "Wood Hammer", "Stone Edge", "Superpower"],
"abilities": ["Tough Claws"]
}
]
},
"avastar": {
"level": 100,
"sets": [
{
"role": "Bulky Support",
"movepool": ["Thunder Wave", "Heavy Slam", "Psychic", "Recover", "Teleport"],
"abilities": ["Shell Bunker"]
},
{
"role": "Setup Sweeper",
"movepool": ["Calm Mind", "Psychic", "Flash Cannon", "Recover", "Thunderbolt"],
"abilities": ["Shell Bunker"]
}
]
},
"axolacred": {
"level": 100,
"sets": [
{
"role": "Bulky Support",
"movepool": ["Stealth Rock", "Dragon Tail", "Roost", "Core Enforcer", "Scald", "Defog", "Shed Tail"],
"abilities": ["Magic Guard"]
},
{
"role": "Bulky Attacker",
"movepool": ["Feral Rush", "Core Enforcer", "Flip Turn", "Recover"],
"abilities": ["Magic Guard"]
}
]
},
"barracoth": {
"level": 100,
"sets": [
{
"role": "Bulky Support",
"movepool": ["Sheer Cold", "Flip Turn", "Triple Axel", "Slack Off"],
"abilities": ["Multiscale", "Filter"]
}
]
},
"blunderbusk": {
"level": 100,
"sets": [
{
"role": "Bulky Attacker",
"movepool": ["Hydro Pump", "Aura Sphere", "Ice Beam", "Dark Pulse", "Dragon Pulse"],
"abilities": ["Mega Launcher"]
}
]
},
"brawnkey": {
"level": 100,
"sets": [
{
"role": "Bulky Support",
"movepool": ["Stealth Rock", "Drain Punch", "Iron Head", "Chilly Reception", "Spikes"],
"abilities": ["Levitate"]
},
{
"role": "Setup Sweeper",
"movepool": ["Iron Defense", "Body Press", "Iron Head", "Stealth Rock"],
"abilities": ["Levitate"]
},
{
"role": "Setup Sweeper",
"movepool": ["Bulk Up", "Drain Punch", "Iron Head", "Stealth Rock"],
"abilities": ["Levitate"]
}
]
},
"carapex": {
"level": 100,
"sets": [
{
"role": "Setup Sweeper",
"movepool": ["Tailwind", "Acrobatics", "Earthquake", "Stone Edge"],
"abilities": ["Wind Rider"]
},
{
"role": "Bulky Support",
"movepool": ["Stealth Rock", "Roost", "Body Press", "Knock Off", "Crystal Bash", "U-Turn"],
"abilities": ["Wind Rider"]
}
]
},
"celespirit": {
"level": 100,
"sets": [
{
"role": "Bulky Support",
"movepool": ["Sheer Cold", "Moonlight", "Hex", "Ice Beam", "Moonblast"],
"abilities": ["Levitate"]
},
{
"role": "Setup Sweeper",
"movepool": ["Calm Mind", "Crystal Burst", "Shadow Ball", "Moonlight"],
"abilities": ["Levitate"]
}
]
},
"cellsius": {
"level": 100,
"sets": [
{
"role": "Setup Sweeper",
"movepool": ["Calm Mind", "Hydro Pump", "Moonblast", "Ice Beam", "Psychic"],
"abilities": ["Beast Boost"]
},
{
"role": "Fast Attacker",
"movepool": ["Hydro Pump", "Moonblast", "Ice Beam", "Flip Turn", "Psychic"],
"abilities": ["Beast Boost"]
}
]
},
"cindoe": {
"level": 100,
"sets": [
{
"role": "Fast Support",
"movepool": ["Overheat", "Fiery Wrath", "Parting Shot", "Morning Sun"],
"abilities": ["Natural Cure"]
},
{
"role": "Setup Sweeper",
"movepool": ["Nasty Plot", "Fiery Wrath", "Fire Blast", "Morning Sun"],
"abilities": ["Natural Cure"]
},
{
"role": "Setup Sweeper",
"movepool": ["Nasty Plot", "Fiery Wrath", "Crystal Burst", "Morning Sun"],
"abilities": ["Natural Cure"]
}
]
},
"cinnastar": {
"level": 100,
"sets": [
{
"role": "AV Pivot",
"movepool": ["Sludge Bomb", "Earth Power", "Focus Blast", "Mortal Spin"],
"abilities": ["Regenerator"]
},
{
"role": "Bulky Support",
"movepool": ["Earth Power", "Mortal Spin", "Recover", "Stealth Rock", "Power Gem"],
"abilities": ["Regenerator"]
}
]
},
"cobracotta": {
"level": 100,
"sets": [
{
"role": "Bulky Support",
"movepool": ["Poison Fang", "Leech Seed", "Knock Off", "Synthesis", "Stealth Rock", "Power Whip"],
"abilities": ["Heatproof"]
}
]
},
"corundell": {
"level": 100,
"sets": [
{
"role": "Fast Attacker",
"movepool": ["Meteor Beam", "Power Gem", "Overheat", "Earth Power", "Volt Switch", "Energy Ball"],
"abilities": ["Lightning Rod"]
}
]
},
"crossont": {
"level": 100,
"sets": [
{
"role": "Bulky Support",
"movepool": ["Spikes", "Recover", "Knock Off", "Circle Throw"],
"abilities": ["Mold Breaker", "Sniper"]
},
{
"role": "Bulky Attacker",
"movepool": ["Crystal Cutter", "Close Combat", "Bulk Up", "Substitute"],
"abilities": ["Sniper"]
}
]
},
"cyllindrake": {
"level": 100,
"sets": [
{
"role": "Bulky Support",
"movepool": ["Body Press", "Rapid Spin", "Morning Sun", "Stealth Rock", "Boomburst"],
"abilities": ["Scrappy"]
},
{
"role": "Fast Support",
"movepool": ["Stealth Rock", "Rapid Spin", "Steel Beam", "Fire Blast"],
"abilities": ["Scrappy"]
},
{
"role": "Fast Attacker",
"movepool": ["Feral Shriek", "Flash Cannon", "Earth Power", "Feral Spray", "Rapid Spin"],
"abilities": ["Punk Rock"]
}
]
},
"dojodo": {
"level": 100,
"sets": [
{
"role": "Setup Sweeper",
"movepool": ["Bulk Up", "Drain Punch", "Jet Punch", "Knock Off", "Substitute"],
"abilities": ["Supreme Overlord"]
},
{
"role": "Setup Sweeper",
"movepool": ["Bulk Up", "Drain Punch", "Crystal Bash", "Jet Punch", "Crystal Healing"],
"abilities": ["Supreme Overlord"]
}
]
},
"dolphena": {
"level": 100,
"sets": [
{
"role": "Setup Sweeper",
"movepool": ["Coil", "Scale Shot", "Iron Tail", "Liquidation"],
"abilities": ["Mythical Presence"]
},
{
"role": "Setup Sweeper",
"movepool": ["Dragon Dance", "Scale Shot", "Liquidation", "Iron Head", "Substitute"],
"abilities": ["Mythical Presence"]
},
{
"role": "Setup Sweeper",
"movepool": ["Coil", "Scale Shot", "Iron Tail", "Liquidation"],
"abilities": ["Mythical Presence"]
},
{
"role": "Bulky Support",
"movepool": ["Defog", "Flip Turn", "Moonlight", "Dragon Tail"],
"abilities": ["Mythical Presence"]
}
]
},
"dracoil": {
"level": 100,
"sets": [
{
"role": "Bulky Support",
"movepool": ["Defog", "Roost", "U-Turn", "Hurricane", "Fire Blast", "Glare", "Draco Meteor", "Earthquake"],
"abilities": ["Mythical Presence"]
},
{
"role": "Setup Sweeper",
"movepool": ["Dragon Dance", "Acrobatics", "Substitute", "Earthquake"],
"abilities": ["Gluttony"]
},
{
"role": "Setup Sweeper",
"movepool": ["Dragon Dance", "Dragon Rush", "Coil", "Earthquake", "Dual Wingbeat"],
"abilities": ["Mythical Presence"]
},
{
"role": "Bulky Support",
"movepool": ["Feral Bite", "Dragon Tail", "Roost", "Glare", "Defog"],
"abilities": ["Mythical Presence"]
}
]
},
"efflor": {
"level": 100,
"sets": [
{
"role": "Bulky Support",
"movepool": ["Giga Drain", "Leech Seed", "Rapid Spin", "Stealth Rock", "Chilly Reception"],
"abilities": ["Seed Sower"]
},
{
"role": "Bulky Setup",
"movepool": ["Curse", "Stone Edge", "Body Press", "Synthesis"],
"abilities": ["Unaware"]
}
]
},
"electangle": {
"level": 100,
"sets": [
{
"role": "Bulky Support",
"movepool": ["Gyro Ball", "Stealth Rock", "Body Press", "Volt Switch", "Discharge"],
"abilities": ["Filter"]
}
]
},
"elemadillo": {
"level": 100,
"sets": [
{
"role": "Fast Attacker",
"movepool": ["Flash Cannon", "Thunderbolt", "Volt Switch", "Energy Ball"],
"abilities": ["Motor Drive", "Weak Armor"]
},
{
"role": "Fast Attacker",
"movepool": ["Feral Power", "Flash Cannon", "Earth Power", "Feral Resilience"],
"abilities": ["Motor Drive", "Weak Armor"]
}
]
},
"embuck": {
"level": 100,
"sets": [
{
"role": "Bulky Support",
"movepool": ["Blaze Kick", "Will-o-Wisp", "Morning Sun", "U-Turn", "Close Combat"],
"abilities": ["Intimidate"]
},
{
"role": "Bulky Support",
"movepool": ["Blaze Kick", "Crystal Bash", "Will-o-Wisp", "Morning Sun", "U-Turn"],
"abilities": ["Intimidate"]
},
{
"role": "Fast Attacker",
"movepool": ["Flare Blitz", "Wild Charge", "U-Turn", "Close Combat"],
"abilities": ["Intimidate"]
}
]
},
"faerenheit": {
"level": 100,
"sets": [
{
"role": "Bulky Setup",
"movepool": ["Calm Mind", "Lava Plume", "Moonblast", "Morning Sun"],
"abilities": ["Beast Boost"]
},
{
"role": "Bulky Setup",
"movepool": ["Calm Mind", "Lava Plume", "Crystal Cage", "Morning Sun"],
"abilities": ["Beast Boost"]
}
]
},
"fenreil": {
"level": 100,
"sets": [
{
"role": "Fast Attacker",
"movepool": ["Double Edge", "Knock Off", "Superpower", "U-Turn"],
"abilities": ["Natural Cure"]
},
{
"role": "Fast Attacker",
"movepool": ["Feral Bite", "Knock Off", "Iron Head", "Feral Shred"],
"abilities": ["Natural Cure"]
}
]
},
"flocura": {
"level": 100,
"sets": [
{
"role": "Fast Support",
"movepool": ["Stealth Rock", "Thunder Wave", "U-Turn", "Leaf Storm"],
"abilities": ["Power Construct"]
},
{
"role": "Setup Sweeper",
"movepool": ["Nasty Plot", "Giga Drain", "Psychic", "Earth Power"],
"abilities": ["Levitate"]
},
{
"role": "Setup Sweeper",
"movepool": ["Nasty Plot", "Giga Drain", "Feral Power", "Earth Power"],
"abilities": ["Levitate"]
},
{
"role": "Fast Attacker",
"movepool": ["Leaf Storm", "U-Turn", "Psychic", "Earth Power"],
"abilities": ["Levitate"]
},
{
"role": "Bulky Support",
"movepool": ["Leech Seed", "U-Turn", "Thunder Wave", "Psychic", "Giga Drain", "Stealth Rock"],
"abilities": ["Power Construct"]
}
]
},
"harzodia": {
"level": 100,
"sets": [
{
"role": "Bulky Support",
"movepool": ["Light Screen", "Reflect", "Teleport", "Thunder Wave", "Psychic"],
"abilities": ["Prankster"]
},
{
"role": "Setup Sweeper",
"movepool": ["Meteor Beam", "Psychic", "Shadow Ball", "Calm Mind", "Focus Blast"],
"abilities": ["Unburden"]
}
]
},
"jaegorm": {
"level": 100,
"sets": [
{
"role": "Fast Attacker",
"movepool": ["First Impression", "U-Turn", "Photon Ray", "Knock Off", "Superpower", "Earthquake"],
"abilities": ["Schooling"]
}
]
},
"jamborai": {
"level": 100,
"sets": [
{
"role": "Bulky Support",
"movepool": ["Mortal Spin", "Recover", "Pyschic", "Scald", "Teleport"],
"abilities": ["Water Absorb"]
},
{
"role": "Bulky Setup",
"movepool": ["Calm Mind", "Recover", "Pyschic", "Scald", "Sludge Bomb", "Stored Power"],
"abilities": ["Water Absorb"]
},
{
"role": "Bulky Support",
"movepool": ["Mortal Spin", "Recover", "Crystal Cage", "Crystal Healing", "Teleport"],
"abilities": ["Gooey"]
},
{
"role": "Bulky Setup",
"movepool": ["Crystal Fortification", "Recover", "Stored Power", "Crystal Beam"],
"abilities": ["Gooey"]
}
]
},
"kodokai": {
"level": 100,
"sets": [
{
"role": "Bulky Support",
"movepool": ["Crystal Cage", "Hex", "Will-o-Wisp", "Moonlight"],
"abilities": ["Aroma Veil"]
},
{
"role": "Bulky Support",
"movepool": ["Wish", "Hex", "Will-o-Wisp", "Moonlight"],
"abilities": ["Aroma Veil"]
}
]
},
"krachiten": {
"level": 100,
"sets": [
{
"role": "Fast Attacker",
"movepool": ["First Impression", "U-Turn", "Liquidation", "Rapid Spin"],
"abilities": ["Torrent"]
},
{
"role": "Fast Attacker",
"movepool": ["Crystal Cutter", "U-Turn", "Aqua Cutter", "Superpower", "Rapid Spin"],
"abilities": ["Sniper"]
}
]
},
"lumoth": {
"level": 100,
"sets": [
{
"role": "Setup Sweeper",
"movepool": ["Quiver Dance", "Hex", "Sleep Powder", "Bug Buzz"],
"abilities": ["Levitate"]
}
]
},
"minillow": {
"level": 100,
"sets": [
{
"role": "Setup Sweeper",
"movepool": ["Nasty Plot", "Agility", "Hydro Pump", "Moonblast", "Substitute"],
"abilities": ["Adaptability"]
}
]
},
"muabboa": {
"level": 100,
"sets": [
{
"role": "Fast Attacker",
"movepool": ["Earthquake", "U-Turn", "Close Combat", "Knock Off"],
"abilities": ["Inner Focus"]
},
{
"role": "Setup Sweeper",
"movepool": ["Swords Dance", "Earthquake", "Feral Rush", "Close Combat"],
"abilities": ["Inner Focus"]
}
]
},
"noxtrice": {
"level": 100,
"sets": [
{
"role": "Fast Support",
"movepool": ["Poison Jab", "Flare Blitz", "Roost", "U-Turn"],
"abilities": ["Poison Touch"]
},
{
"role": "Setup Sweeper",
"movepool": ["Gunk Shot", "Flare Blitz", "Earthquake", "Dragon Dance"],
"abilities": ["Poison Touch"]
},
{
"role": "Setup Sweeper",
"movepool": ["Gunk Shot", "Feral Rush", "Earthquake", "Dragon Dance"],
"abilities": ["Flash Fire"]
}
]
},
"nunopod": {
"level": 100,
"sets": [
{
"role": "Bulky Support",
"movepool": ["Earthquake", "Body Press", "Triple Axel", "Flip Turn", "Stealth Rock", "Rapid Spin", "Recover"],
"abilities": ["Opportunist"]
},
{
"role": "Bulky Support",
"movepool": ["Crystal Bash", "Body Press", "Earthquake", "Flip Turn", "Stealth Rock", "Rapid Spin", "Recover"],
"abilities": ["Opportunist"]
}
]
},
"orchile": {
"level": 100,
"sets": [
{
"role": "Bulky Support",
"movepool": ["Moonblast", "Earth Power", "Will-o-Wisp", "Strength Sap", "Spikes"],
"abilities": ["Flower Veil"]
},
{
"role": "Bulky Setup",
"movepool": ["Moonblast", "Earth Power", "Calm Mind", "Strength Sap"],
"abilities": ["Flower Veil"]
}
]
},
"platypad": {
"level": 100,
"sets": [
{
"role": "Bulky Support",
"movepool": ["Revival Blessing", "Wave Crash", "Flip Turn", "Synthesis"],
"abilities": ["Flower Veil"]
},
{
"role": "Bulky Setup",
"movepool": ["Feral Resilience", "Feral Breath", "Giga Drain", "Synthesis"],
"abilities": ["Triage"]
}
]
},
"pythos": {
"level": 100,
"sets": [
{
"role": "Bulky Setup",
"movepool": ["Coil", "Knock Off", "Iron Tail", "Sucker Punch", "Superpower", "Facade"],
"abilities": ["Guts"]
}
]
},
"quadringo": {
"level": 100,
"sets": [
{
"role": "Bulky Support",
"movepool": ["Defog", "Roost", "Dragon Tail", "Earthquake", "Moonblast"],
"abilities": ["Pastel Veil"]
},
{
"role": "Bulky Setup",
"movepool": ["Calm Mind", "Moonblast", "Mystical Fire", "Roost"],
"abilities": ["Pastel Veil"]
},
{
"role": "Fast Attacker",
"movepool": ["Moonblast", "Draco Meteor", "Mystical Fire", "Earthquake"],
"abilities": ["Pastel Veil"]
},
{
"role": "Fast Attacker",
"movepool": ["Feral Rush", "Earthquake", "Feral Shred", "Roost"],
"abilities": ["Pastel Veil"]
}
]
},
"rantler": {
"level": 100,
"sets": [
{
"role": "Fast Attacker",
"movepool": ["Double Edge", "Ice Spinner", "Superpower", "Earthquake"],
"abilities": ["Slush Rush"]
},
{
"role": "Setup Sweeper",
"movepool": ["Swords Dance", "Double Edge", "Ice Spinner", "Superpower", "Earthquake", "Quick Attack"],
"abilities": ["Slush Rush"]
},
{
"role": "Fast Attacker",
"movepool": ["Double Edge", "Ice Spinner", "Superpower", "Quick Attack", "Fake Out"],
"abilities": ["Tough Claws"]
}
]
},
"roscenti": {
"level": 100,
"sets": [
{
"role": "Fast Attacker",
"movepool": ["First Impression", "U-Turn", "Superpower", "Rock Blast", "Bullet Seed"],
"abilities": ["Skill Link"]
},
{
"role": "Fast Attacker",
"movepool": ["First Impression", "U-Turn", "Feral Rush", "Drill Run", "Iron Tail"],
"abilities": ["Sheer Force"]
},
{
"role": "Fast Attacker",
"movepool": ["First Impression", "U-Turn", "Crystal Tail", "Superpower", "Rock Slide"],
"abilities": ["Sheer Force"]
}
]
},
"salamalix": {
"level": 100,
"sets": [
{
"role": "Bulky Support",
"movepool": ["Stealth Rock", "Spikes", "Stone Edge", "Close Combat", "Iron Head"],
"abilities": ["Intimidate"]
},
{
"role": "Bulky Setup",
"movepool": ["Swords Dance", "Iron Head", "Close Combat", "Accelerock"],
"abilities": ["Intimidate"]
}
]
},
"salaos": {
"level": 100,
"sets": [
{
"role": "Bulky Support",
"movepool": ["Toxic", "Recover", "Fiery Wrath", "Scald", "Flamethrower", "Toxic Spikes"],
"abilities": ["Good as Gold"]
},
{
"role": "Bulky Support",
"movepool": ["Toxic", "Recover", "Crystal Cage", "Flamethrower", "Toxic Spikes"],
"abilities": ["Good as Gold"]
}
]
},
"saphor": {
"level": 100,
"sets": [
{
"role": "Bulky Support",
"movepool": ["Stealth Rock", "Earthquake", "Body Slam", "Slack Off", "Roar", "Heal Bell"],
"abilities": ["Thick Fat"]
},
{
"role": "Bulky Support",
"movepool": ["Stealth Rock", "Crystal Tail", "Crystal Shard", "Slack Off", "Roar", "Crystal Healing"],
"abilities": ["Thick Fat"]
},
{
"role": "Bulky Setup",
"movepool": ["Bulk Up", "Crystal Cutter", "Slack Off", "Body Press"],
"abilities": ["Thick Fat"]
},
{
"role": "Bulky Setup",
"movepool": ["Calm Mind", "Crystal Cage", "Slack Off", "Focus Blast"],
"abilities": ["Thick Fat"]
},
{
"role": "Fast Attacker",
"movepool": ["Headlong Rush", "Double Edge", "Heavy Slam", "Superpower", "Stone Edge"],
"abilities": ["Thick Fat"]
}
]
},
"scalaron": {
"level": 100,
"sets": [
{
"role": "Bulky Support",
"movepool": ["Flamethrower", "Hurricane", "Roost", "U-Turn", "Defog", "Toxic", "Will-o-Wisp"],
"abilities": ["Filter"]
},
{
"role": "Bulky Support",
"movepool": ["Flamethrower", "Crystal Cage", "Roost", "U-Turn", "Defog", "Will-o-Wisp", "Crystal Shard"],
"abilities": ["Filter"]
}
]
},
"soleron": {
"level": 100,
"sets": [
{
"role": "Fast Attacker",
"movepool": ["Thunderbolt", "Hurricane", "Heat Wave", "U-Turn", "Air Slash", "Volt Switch", "Roost"],
"abilities": ["Battle Bond"]
},
{
"role": "Fast Attacker",
"movepool": ["Thunderbolt", "Feral Power", "Feral Spray", "Volt Switch", "Roost"],
"abilities": ["Battle Bond"]
},
{
"role": "Fast Attacker",
"movepool": ["Thunderbolt", "Crystal Burst", "Heat Wave", "Volt Switch", "Hurricane"],
"abilities": ["Battle Bond"]
}
]
},
"torgeist": {
"level": 100,
"sets": [
{
"role": "Fast Attacker",
"movepool": ["Toxic Thread", "Hex", "Hurricane", "Heat Wave", "Pain Split", "Taunt"],
"abilities": ["Merciless"]
},
{
"role": "Fast Attacker",
"movepool": ["Toxic Thread", "Hex", "Feral Power", "Pain Split", "Taunt", "Nasty Plot"],
"abilities": ["Merciless"]
},
{
"role": "Setup Sweeper",
"movepool": ["Will-o-Wisp", "Hex", "Feral Power", "Nasty Plot"],
"abilities": ["Cursed Body"]
}
]
},
"woolora": {
"level": 100,
"sets": [
{
"role": "Bulky Setup",
"movepool": ["Calm Mind", "Cotton Guard", "Stored Power", "Draining Kiss"],
"abilities": ["Fluffy", "Pastel Veil"]
},
{
"role": "Bulky Setup",
"movepool": ["Calm Mind", "Moonlight", "Stored Power", "Moonblast"],
"abilities": ["Fluffy"]
}
]
},
"zeploom": {
"level": 100,
"sets": [
{
"role": "Bulky Support",
"movepool": ["Energy Siphon", "Synthesis", "Stealth Rock", "U-Turn", "Defog", "Toxic", "Earth Power"],
"abilities": ["Wind Rider"]
}
]
}
}

View File

@ -22,13 +22,14 @@ const SETUP = [
'acidarmor', 'agility', 'autotomize', 'bellydrum', 'bulkup', 'calmmind', 'clangoroussoul', 'coil', 'cosmicpower', 'curse', 'dragondance',
'filletaway', 'flamecharge', 'growth', 'honeclaws', 'howl', 'irondefense', 'meditate', 'nastyplot', 'noretreat', 'poweruppunch', 'quiverdance',
'rockpolish', 'shellsmash', 'shiftgear', 'swordsdance', 'tailglow', 'takeheart', 'tidyup', 'trailblaze', 'trickroom', 'workup', 'victorydance',
'feralresilience', 'feralspray', 'crystalfortification',
];
const SPEED_CONTROL = [
'electroweb', 'glare', 'icywind', 'lowsweep', 'quash', 'stringshot', 'tailwind', 'thunderwave', 'trickroom',
];
// Hazard-setting moves
const HAZARDS = [
'spikes', 'stealthrock', 'stickyweb', 'toxicspikes',
'spikes', 'stealthrock', 'stickyweb', 'toxicspikes', 'crystalshard',
];
// Protect and its variants
const PROTECT_MOVES = [
@ -68,7 +69,7 @@ const NO_LEAD_POKEMON = [
const DOUBLES_NO_LEAD_POKEMON = [
'Basculegion', 'Houndstone', 'Iron Bundle', 'Roaring Moon', 'Zacian', 'Zamazenta',
];
export class RandomMHSTeams extends RandomTeams {
export class RandomSCTeams extends RandomTeams {
override cullMovePool(
types: string[],
moves: Set<string>,
@ -264,6 +265,7 @@ export class RandomMHSTeams extends RandomTeams {
role: RandomTeamsTypes.Role,
): Set<string> {
const moves = new Set<string>();
if (this.getSuperType(moves)) types[1] = this.getSuperType(moves);
let counter = this.queryMoves(moves, species, teraType, abilities);
this.cullMovePool(types, moves, abilities, counter, movePool, teamDetails, species, isLead, isDoubles, teraType, role);
@ -605,6 +607,7 @@ export class RandomMHSTeams extends RandomTeams {
teraType: string,
role: RandomTeamsTypes.Role,
) {
if (this.getSuperType(moves)) return this.getSuperType(moves) + " Orb";
if (!isDoubles) {
if (role === 'Fast Bulky Setup' && (ability === 'Quark Drive' || ability === 'Protosynthesis')) {
return 'Booster Energy';
@ -621,7 +624,9 @@ export class RandomMHSTeams extends RandomTeams {
return this.sample(species.requiredItems);
}
if (role === 'AV Pivot') return 'Assault Vest';
// MHS hardcodes
// Super Type hardcodes
if (species.id === 'cyllindrake' && moves.has('shiftgear')) return 'Throat Spray';
if (species.id === 'albatrygon' && moves.has('acrobatics')) return 'Sitrus Berry';
if (species.id === 'yiankutku' && moves.has('facade') || species.id === 'bluekutku' && moves.has('facade')) {
return 'Frost Orb';
}
@ -684,6 +689,14 @@ export class RandomMHSTeams extends RandomTeams {
}
}
getSuperType(moves: Set<string> | string[]): string {
for (const move of moves) {
if (move.includes('crystal')) return "Crystal";
if (move.includes('feral')) return "Feral";
}
return "";
}
override randomSet(
s: string | Species,
teamDetails: RandomTeamsTypes.TeamDetails = {},
@ -695,7 +708,7 @@ export class RandomMHSTeams extends RandomTeams {
const sets = this.randomSets[species.id]["sets"];
const possibleSets: RandomTeamsTypes.RandomSetData[] = [];
const ruleTable = this.dex.formats.getRuleTable(this.format);
// const ruleTable = this.dex.formats.getRuleTable(this.format);
for (const set of sets) {
// Prevent Fast Bulky Setup on lead Paradox Pokemon, since it generates Booster Energy.
@ -705,7 +718,8 @@ export class RandomMHSTeams extends RandomTeams {
set.role === 'Fast Bulky Setup'
) continue;
// Prevent Tera Blast user if the team already has one, or if Terastallizion is prevented.
if ((teamDetails.teraBlast || ruleTable.has('terastalclause')) && set.role === 'Tera Blast user') {
// used here to limit team to 1 Super Types user
if (teamDetails.teraBlast && set.role === 'Tera Blast user') {
continue;
}
possibleSets.push(set);
@ -725,13 +739,17 @@ export class RandomMHSTeams extends RandomTeams {
const evs = { hp: 85, atk: 85, def: 85, spa: 85, spd: 85, spe: 85 };
const ivs = { hp: 31, atk: 31, def: 31, spa: 31, spd: 31, spe: 31 };
const types = species.types;
const types = [];
types[0] = species.types[0];
if (species.types[1]) types[1] = species.types[1];
const abilities = set.abilities!;
// Get moves
const moves = this.randomMoveset(types, abilities, teamDetails, species, isLead, isDoubles, movePool, teraType, role);
const counter = this.queryMoves(moves, species, teraType, abilities);
if (this.getSuperType(moves)) types[1] = this.getSuperType(moves);
// Get ability
ability = this.getAbility(types, moves, abilities, counter, teamDetails, species, isLead, isDoubles, teraType, role);
@ -817,7 +835,7 @@ export class RandomMHSTeams extends RandomTeams {
override randomSets: { [species: string]: RandomTeamsTypes.RandomSpeciesData } = require('./random-sets.json');
randomMHSTeam() {
randomSCTeam() {
this.enforceNoDirectCustomBanlistChanges();
const seed = this.prng.getSeed();
@ -836,6 +854,7 @@ export class RandomMHSTeams extends RandomTeams {
const baseFormes: { [k: string]: number } = {};
// const superTypeCount = 0;
const typeCount: { [k: string]: number } = {};
const typeComboCount: { [k: string]: number } = {};
const typeWeaknesses: { [k: string]: number } = {};
@ -888,14 +907,17 @@ export class RandomMHSTeams extends RandomTeams {
) {
if (pokemon.length + leadsRemaining === this.maxTeamSize) continue;
set = this.randomSet(species, teamDetails, false, isDoubles);
if (teamDetails.teraBlast && this.getSuperType(set.moves)) continue;
pokemon.push(set);
} else {
set = this.randomSet(species, teamDetails, true, isDoubles);
if (teamDetails.teraBlast && this.getSuperType(set.moves)) continue;
pokemon.unshift(set);
leadsRemaining--;
}
} else {
set = this.randomSet(species, teamDetails, false, isDoubles);
if (teamDetails.teraBlast && this.getSuperType(set.moves)) continue;
pokemon.push(set);
}
@ -919,6 +941,11 @@ export class RandomMHSTeams extends RandomTeams {
typeComboCount[typeCombo] = 1;
}
// Increment item counter
if (set.item === "Crystal Orb" || set.item === "Feral Orb") {
teamDetails.teraBlast = 1;
}
// Increment weakness counter
for (const typeName of this.dex.types.names()) {
// it's weak to the type
@ -971,4 +998,4 @@ export class RandomMHSTeams extends RandomTeams {
}
}
export default RandomMHSTeams;
export default RandomSCTeams;

View File

@ -1507,17 +1507,9 @@ export const Rulesets: import('../sim/dex-formats').FormatDataTable = {
typeTable = typeTable.filter(type => species.types.includes(type));
}
const item = this.dex.items.get(set.item);
if (item.megaStone) {
if (Array.isArray(item.megaStone)) {
const index = (item.megaEvolves as string[]).indexOf(species.name);
if (index >= 0) {
species = this.dex.species.get(item.megaStone[index]);
typeTable = typeTable.filter(type => species.types.includes(type));
}
} else {
species = this.dex.species.get(item.megaStone);
typeTable = typeTable.filter(type => species.types.includes(type));
}
if (item.megaStone?.[species.name]) {
species = this.dex.species.get(item.megaStone[species.name]);
typeTable = typeTable.filter(type => species.types.includes(type));
}
if (item.id === "ultranecroziumz" && species.baseSpecies === "Necrozma") {
species = this.dex.species.get("Necrozma-Ultra");
@ -1556,17 +1548,9 @@ export const Rulesets: import('../sim/dex-formats').FormatDataTable = {
}
color = species.color;
const item = this.dex.items.get(set.item);
if (item.megaStone) {
if (Array.isArray(item.megaStone)) {
const index = (item.megaEvolves as string[]).indexOf(species.name);
if (index >= 0) {
species = this.dex.species.get(item.megaStone[index]);
color = species.color;
}
} else {
species = this.dex.species.get(item.megaStone);
color = species.color;
}
if (item.megaStone?.[species.name]) {
species = this.dex.species.get(item.megaStone[species.name]);
color = species.color;
}
if (item.id === "ultranecroziumz" && species.baseSpecies === "Necrozma") {
species = this.dex.species.get("Necrozma-Ultra");
@ -2666,12 +2650,10 @@ export const Rulesets: import('../sim/dex-formats').FormatDataTable = {
) {
species = this.dex.species.get(`${species.baseSpecies}-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?.includes(species.name)) {
species = this.dex.species.get(Array.isArray(item.megaEvolves) ?
(item.megaStone as string[])[item.megaEvolves.indexOf(species.name)] :
item.megaStone as string);
if (item.megaStone?.[species.name]) {
species = this.dex.species.get(item.megaStone[species.name]);
}
}
if (this.ruleTable.isRestrictedSpecies(species) ||
@ -2693,10 +2675,8 @@ export const Rulesets: import('../sim/dex-formats').FormatDataTable = {
}
if (set.item) {
const item = this.dex.items.get(set.item);
if (item.megaEvolves?.includes(set.species)) {
godSpecies = this.dex.species.get(Array.isArray(item.megaEvolves) ?
(item.megaStone as string[])[item.megaEvolves.indexOf(set.species)] :
item.megaStone as string);
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

@ -1788,8 +1788,8 @@ export const commands: Chat.ChatCommands = {
`- <a href="https://www.smogon.com/forums/threads/3676132/">Beginner's Guide to Pok&eacute;mon Showdown</a><br />` +
`- <a href="https://www.smogon.com/dp/articles/intro_comp_pokemon">An introduction to competitive Pok&eacute;mon</a><br />` +
`- <a href="https://www.smogon.com/sm/articles/sm_tiers">What do 'OU', 'UU', etc mean?</a><br />` +
`- <a href="https://www.smogon.com/dex/ss/formats/">What are the rules for each format?</a><br />` +
`- <a href="https://www.smogon.com/ss/articles/clauses">What is 'Sleep Clause' and other clauses?</a><br />` +
`- <a href="https://www.smogon.com/dex/sv/formats/">What are the rules for each format?</a><br />` +
`- <a href="https://www.smogon.com/sv/articles/clauses">What is 'Sleep Clause' and other clauses?</a><br />` +
`- <a href="https://www.smogon.com/articles/getting-started">Next Steps for Competitive Battling</a>`
);
},

View File

@ -13,6 +13,7 @@ interface StoneDeltas {
weighthg: number;
heightm: number;
type?: string;
primaryTypeChange?: boolean;
}
type TierShiftTiers = 'UU' | 'RUBL' | 'RU' | 'NUBL' | 'NU' | 'PUBL' | 'PU' | 'ZUBL' | 'ZU' | 'NFE' | 'LC';
@ -28,14 +29,23 @@ function getMegaStone(stone: string, mod = 'gen9'): Item | null {
id: move.id,
name: move.name,
fullname: move.name,
megaEvolves: 'Rayquaza',
megaStone: 'Rayquaza-Mega',
megaStone: { 'Rayquaza': 'Rayquaza-Mega' },
exists: true,
// Adding extra values to appease typescript
gen: 6,
num: -1,
effectType: 'Item',
sourceEffect: '',
isBerry: false,
ignoreKlutz: false,
isGem: false,
isPokeball: false,
isPrimalOrb: false,
shortDesc: "",
desc: "",
isNonstandard: null,
noCopy: false,
affectsFainted: false,
} as Item;
} else {
return null;
@ -130,8 +140,8 @@ export const commands: Chat.ChatCommands = {
megaSpecies = dex.species.get(forcedForme);
baseSpecies = dex.species.get(forcedForme.split('-')[0]);
} else {
megaSpecies = dex.species.get(Array.isArray(stone.megaStone) ? stone.megaStone[0] : stone.megaStone);
baseSpecies = dex.species.get(Array.isArray(stone.megaEvolves) ? stone.megaEvolves[0] : stone.megaEvolves);
megaSpecies = dex.species.get(Object.values(stone.megaStone!)[0]);
baseSpecies = dex.species.get(Object.keys(stone.megaStone!)[0]);
}
break;
}
@ -153,10 +163,13 @@ export const commands: Chat.ChatCommands = {
deltas.type = dex.gen === 8 ? 'mono' : baseSpecies.types[0];
} else if (megaSpecies.types[1] !== baseSpecies.types[1]) {
deltas.type = megaSpecies.types[1];
} else if (megaSpecies.types[0] !== baseSpecies.types[0]) {
deltas.type = megaSpecies.types[0];
deltas.primaryTypeChange = true;
}
const mixedSpecies = Utils.deepClone(species);
mixedSpecies.abilities = Utils.deepClone(megaSpecies.abilities);
if (['Arceus', 'Silvally'].includes(baseSpecies.name)) {
if (['Arceus', 'Silvally'].includes(baseSpecies.name) || deltas.primaryTypeChange) {
const secondType = mixedSpecies.types[1];
mixedSpecies.types = [deltas.type];
if (secondType && secondType !== deltas.type) mixedSpecies.types.push(secondType);
@ -230,7 +243,7 @@ export const commands: Chat.ChatCommands = {
const stones = [];
if (!stone) {
const formeIdRegex = new RegExp(
`(?:mega[xy]?|primal|origin|crowned|epilogue|cornerstone|wellspring|hearthflame|douse|shock|chill|burn|${dex.types.all().map(x => x.id).filter(x => x !== 'normal').join('|')})$`
`(?:mega[xyz]?|primal|origin|crowned|epilogue|cornerstone|wellspring|hearthflame|douse|shock|chill|burn|${dex.types.all().map(x => x.id).filter(x => x !== 'normal').join('|')})$`
);
const species = dex.species.get(targetid.replace(formeIdRegex, ''));
if (!species.exists) throw new Chat.ErrorMessage(`Error: Mega Stone not found.`);
@ -278,8 +291,8 @@ export const commands: Chat.ChatCommands = {
megaSpecies = dex.species.get(forcedForme);
baseSpecies = dex.species.get(forcedForme.split('-')[0]);
} else {
megaSpecies = dex.species.get(Array.isArray(aStone.megaStone) ? aStone.megaStone[0] : aStone.megaStone);
baseSpecies = dex.species.get(Array.isArray(aStone.megaEvolves) ? aStone.megaEvolves[0] : aStone.megaEvolves);
megaSpecies = dex.species.get(Object.values(aStone.megaStone!)[0]);
baseSpecies = dex.species.get(Object.keys(aStone.megaStone!)[0]);
}
break;
}
@ -301,6 +314,8 @@ export const commands: Chat.ChatCommands = {
deltas.type = dex.gen === 8 ? 'mono' : megaSpecies.types[0];
} else if (megaSpecies.types[1] !== baseSpecies.types[1]) {
deltas.type = megaSpecies.types[1];
} else if (megaSpecies.types[0] !== baseSpecies.types[0]) {
deltas.type = megaSpecies.types[0];
}
const details = {
Gen: aStone.gen,

View File

@ -257,21 +257,21 @@ function getLetsGoMoves(species: string | Species) {
return data.moves.map(formatMove).sort().join(`, `);
}
function battleFactorySets(species: string | Species, tier: string | null, gen = 'gen9', isBSS = false) {
function battleFactorySets(species: string | Species, tier: string | null, gen = 'gen9', isBSS = false, is1v1 = false) {
species = Dex.species.get(species);
if (typeof species.battleOnly === 'string') {
species = Dex.species.get(species.battleOnly);
}
gen = toID(gen);
const genNum = parseInt(gen[3]);
if (isNaN(genNum) || genNum < 6 || (isBSS && genNum < 7)) return null;
if (isNaN(genNum) || genNum < 6 || (isBSS && genNum < 7) || (is1v1 && genNum < 9)) return null;
const statsFile = JSON.parse(
FS(`data/random-battles/gen${genNum}/${isBSS ? `bss-` : ``}factory-sets.json`).readIfExistsSync() ||
FS(`data/random-battles/gen${genNum}/${isBSS ? `bss-` : is1v1 ? `1v1-` : ``}factory-sets.json`).readIfExistsSync() ||
"{}"
);
if (!Object.keys(statsFile).length) return null;
let buf = ``;
if (!isBSS) {
if (!isBSS && !is1v1) {
if (!tier) throw new Chat.ErrorMessage(`Please provide a valid tier.`);
if (!(toID(tier) in TIERS)) throw new Chat.ErrorMessage(`That tier isn't supported.`);
if (!(TIERS[toID(tier)] in statsFile)) {
@ -330,19 +330,26 @@ function battleFactorySets(species: string | Species, tier: string | null, gen =
buf += `</ul></details>`;
}
} else {
const format = Dex.formats.get(`${gen}bssfactory`);
if (!(species.id in statsFile)) throw new Chat.ErrorMessage(`${species.name} doesn't have any sets in ${format.name}.`);
const setObj = statsFile[species.id];
const format = Dex.formats.get(`${gen}${is1v1 ? '1v1' : 'bss'}factory`);
if (!((is1v1 ? species.name : species.id) in statsFile))
throw new Chat.ErrorMessage(`${species.name} doesn't have any sets in ${format.name}.`);
const setObj = statsFile[is1v1 ? species.name : species.id];
if (genNum >= 9) {
buf += `Species rarity: ${setObj.weight} (higher is more common, max 10)<br />`;
buf += `Sets for ${species.name} in ${format.name}:<br />`;
for (const [i, set] of setObj.sets.entries()) {
buf += `<details class="details"><summary>Set ${i + 1} (${set.weight}%)</summary>`;
buf += `<ul style="list-style-type:none;padding-left:0;">`;
buf += `<li>${Dex.forFormat(format).species.get(set.species).name} @ ${set.item.map(formatItem).join(" / ")}</li>`;
buf += `<li>Ability: ${set.ability.map(formatAbility).join(" / ")}</li>`;
buf += `<li>Level: 50</li>`;
buf += `<li>Tera Type: ${set.teraType.map(formatType).join(' / ')}</li>`;
const item = !Array.isArray(set.item) ? [set.item] : set.item;
buf += `<li>${Dex.forFormat(format).species.get(set.species).name} @ ${item.map(formatItem).join(" / ")}</li>`;
const ability = !Array.isArray(set.ability) ? [set.ability] : set.ability;
buf += `<li>Ability: ${ability.map(formatAbility).join(" / ")}</li>`;
if (isBSS) {
buf += `<li>Level: 50</li>`;
} else if (set.level) {
buf += `<li>Level: ${set.level}</li>`;
}
if (!is1v1) buf += `<li>Tera Type: ${set.teraType.map(formatType).join(' / ')}</li>`;
if (set.evs) {
buf += `<li>EVs: `;
const evs: string[] = [];
@ -353,7 +360,8 @@ function battleFactorySets(species: string | Species, tier: string | null, gen =
}
buf += `${evs.join(" / ")}</li>`;
}
buf += `<li>${formatNature(set.nature)} Nature</li>`;
const nature = !Array.isArray(set.nature) ? [set.nature] : set.nature;
buf += `<li>${nature.map(formatNature).join(" / ")} Nature</li>`;
if (set.ivs) {
buf += `<li>IVs: `;
const ivs: string[] = [];
@ -603,10 +611,12 @@ export const commands: Chat.ChatCommands = {
`/randomdoublesbattle OR /randdubs [pokemon], [gen] - Same as above, but instead displays Random Doubles Battle moves.`,
],
'1v1factory': 'battlefactory',
bssfactory: 'battlefactory',
battlefactory(target, room, user, connection, cmd) {
if (!this.runBroadcast()) return;
const isBSS = cmd === 'bssfactory';
const is1v1 = cmd === '1v1factory';
if (isBSS) {
const args = target.split(',');
if (!args[0]) return this.parse(`/help battlefactory`);
@ -619,6 +629,15 @@ export const commands: Chat.ChatCommands = {
const bssSets = battleFactorySets(species, null, mod, true);
if (!bssSets) return this.parse(`/help battlefactory`);
return this.sendReplyBox(bssSets);
} else if (is1v1) {
if (!target) return this.parse(`/help battlefactory`);
const species = Dex.species.get(target);
if (!species.exists) {
throw new Chat.ErrorMessage(`Error: Pok\u00e9mon '${target.trim()}' not found.`);
}
const onevoneSets = battleFactorySets(species, null, 'gen9', false, true);
if (!onevoneSets) return this.parse(`/help battlefactory`);
return this.sendReplyBox(onevoneSets);
} else {
const args = target.split(',');
if (!args[0]) return this.parse(`/help battlefactory`);

View File

@ -373,7 +373,7 @@ class SSBSetsHTML extends Chat.JSX.Component<{ target: string }> {
<SSBInnateHTML name={setName} dex={dex} baseDex={baseDex} />
<SSBPokemonHTML species={set.species} dex={dex} baseDex={baseDex} />
{(!Array.isArray(set.item) && item.megaStone) && <SSBPokemonHTML
species={Array.isArray(item.megaStone) ? item.megaStone[0] : item.megaStone} dex={dex} baseDex={baseDex}
species={Object.values(item.megaStone)[0]} dex={dex} baseDex={baseDex}
/>}
{/* keys and Kennedy have an itemless forme change */}
{['Rayquaza'].includes(set.species) && <SSBPokemonHTML species={`${set.species}-Mega`} dex={dex} baseDex={baseDex} />}

View File

@ -134,7 +134,7 @@ export function getSpeciesName(set: PokemonSet, format: Format) {
} else if (species === "Groudon" && item.name === "Red Orb") {
return "Groudon-Primal";
} else if (item.megaStone) {
return Array.isArray(item.megaStone) ? item.megaStone[0] : item.megaStone;
return Object.values(item.megaStone)[0];
} else if (species === "Rayquaza" && moves.includes('Dragon Ascent') && !item.zMove && megaRayquazaPossible) {
return "Rayquaza-Mega";
} else if (species === "Poltchageist-Artisan") { // Babymons from here on out

View File

@ -2,6 +2,8 @@ import { FS, Utils } from '../../lib';
import { YouTube } from './youtube';
const MINUTE = 60 * 1000;
const DAY = 24 * 60 * MINUTE;
const WEEK = DAY * 7;
const PRENOM_BUMP_TIME = 2 * 60 * MINUTE;
const PRENOMS_FILE = 'config/chat-plugins/otd-prenoms.json';
@ -63,6 +65,7 @@ class OtdHandler {
removedNominations: Map<string, AnyObject>;
voting: boolean;
timer: NodeJS.Timeout | null;
autoStartTimer: NodeJS.Timeout | null;
keys: string[];
keyLabels: string[];
timeLabel: string;
@ -81,6 +84,7 @@ class OtdHandler {
this.voting = false;
this.timer = null;
this.autoStartTimer = null;
this.keys = settings.keys;
this.keyLabels = settings.keyLabels;
@ -105,6 +109,7 @@ class OtdHandler {
needsSave = true;
}
}
if (room.settings.autoStartOtd) handler.toggleAutoStartTimer(true);
if (needsSave) handler.save();
return handler;
}
@ -142,6 +147,22 @@ class OtdHandler {
}
}
toggleAutoStartTimer(on: boolean) {
if (on && !this.autoStartTimer) {
this.autoStartTimer = setInterval(() => {
if (this.voting) {
// in case the 20 min auto-end timer didnt end the nomm process due to 0 nomms
this.rollWinner();
}
this.startVote();
this.room.modlog({ action: `${this.id.toUpperCase()} START` });
}, this.timeLabel === 'week' ? WEEK : DAY);
} else if (!on && this.autoStartTimer) {
clearInterval(this.autoStartTimer);
this.autoStartTimer = null;
}
}
startVote() {
this.voting = true;
this.timer = setTimeout(() => this.rollWinner(), 20 * MINUTE);
@ -740,6 +761,35 @@ export const otdCommands: Chat.ChatCommands = {
`Requires: % @ # ~`,
],
toggleautostart(target, room, user) {
const otd = selectHandler(this.message);
room = this.requireRoom(otd.room.roomid);
this.checkCan('declare', null, room);
let logMessage = '';
const handler = selectHandler(this.message);
if (this.meansYes(target)) {
if (room.settings.autoStartOtd) {
throw new Chat.ErrorMessage(`This -OTD is already set to automatically start.`);
}
room.settings.autoStartOtd = true;
handler.toggleAutoStartTimer(true);
logMessage = 'start automatically';
} else {
if (!room.settings.autoStartOtd) {
throw new Chat.ErrorMessage(`This -OTD is not set to automatically start.`);
}
room.settings.autoStartOtd = false;
logMessage = 'not start automatically';
handler.toggleAutoStartTimer(false);
}
this.privateModAction(`${user.name} set the ${otd.name} nomination to ${logMessage}`);
this.modlog(`OTD TOGGLEAUTOSTART`, null, logMessage);
room.saveSettings();
},
toggleupdate(target, room, user) {
const otd = selectHandler(this.message);
room = this.requireRoom(otd.room.roomid);
@ -908,6 +958,7 @@ const otdHelp = [
`- /-otd set property: value[, property: value] - Set the winner, quote, song, link or image for the current Thing of the Day. Requires: % @ # ~`,
`- /-otd winners - Displays a list of previous things of the day.`,
`- /-otd toggleupdate [on|off] - Changes the Thing of the Day to display on nomination ([on] to update, [off] to turn off updates). Requires: # ~`,
`- /-otd toggleautostart [on|off] - Enables or disables automatic start for Thing of the Day ([on] enables autostart, [off] disables it). Requires: # ~`,
];
for (const otd in otdData) {
@ -929,6 +980,15 @@ for (const [k, v] of otds) {
commands[`${k}help`] = otdHelp;
}
const getKeyByRoomId = (id: string): string | undefined => {
for (const [key, handler] of otds.entries()) {
if (handler.room.roomid === id) {
return key;
}
}
return undefined;
};
export const handlers: Chat.Handlers = {
onRenameRoom(oldID, newID, room) {
for (const otd in otdData) {
@ -950,3 +1010,24 @@ export const punishmentfilter: Chat.PunishmentFilter = (user, punishment) => {
handler.removeNomination(user);
}
};
export const roomSettings: Chat.SettingsHandler[] = [
(room, user) => ({
label: `Autostart -OTD`,
permission: "editroom",
options: getKeyByRoomId(room.roomid) ? [
['off', !room.settings.autoStartOtd || `${getKeyByRoomId(room.roomid)} toggleautostart off`],
['on', room.settings.autoStartOtd || `${getKeyByRoomId(room.roomid)} toggleautostart on`],
] : [['disabled', true]],
}),
];
export const destroy = () => {
for (const [, v] of otds) {
if (v.autoStartTimer) {
clearInterval(v.autoStartTimer);
v.autoStartTimer = null;
v.room.modlog({ action: `${v.id.toUpperCase()} TIMER RESTART` });
}
}
};

View File

@ -220,7 +220,7 @@ export const pages: Chat.PageTable = {
const sorted: { [k: string]: number } = {};
for (const curUser of Users.users.values()) {
for (const term of nameList) {
if (curUser.id.includes(term)) {
if (curUser.id.includes(term) && !curUser.id.startsWith('guest')) {
if (!(term in sorted)) sorted[term] = 0;
sorted[term]++;
}

View File

@ -125,6 +125,8 @@ export interface RoomSettings {
minorActivityQueue?: MinorActivityData[];
repeats?: RepeatedPhrase[];
topics?: string[];
// auto start thing of the day
autoStartOtd?: boolean;
autoModchat?: {
rank: GroupSymbol,
time: number,

View File

@ -1871,21 +1871,15 @@ export class BattleActions {
pokemon.baseMoves.includes(toID(altForme.requiredMove)) && !item.zMove) {
return altForme.name;
}
if (!item.megaStone) return null;
// Temporary hardcode until generation shift
if ((species.baseSpecies === "Floette" || species.baseSpecies === "Zygarde") && item.megaEvolves === species.name) {
return item.megaStone as string;
if ((species.baseSpecies === "Floette" || species.baseSpecies === "Zygarde") && item.megaStone[species.name]) {
return item.megaStone[species.name];
}
// a hacked-in Megazard X can mega evolve into Megazard Y, but not into Megazard X
if (Array.isArray(item.megaStone)) {
// FIXME: Change to species.name when champions comes
const index = (item.megaEvolves as string[]).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 && item.megaStone !== species.name) {
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;
}
canUltraBurst(pokemon: Pokemon) {

View File

@ -3144,9 +3144,9 @@ export class Battle {
this.log[this.lastMoveLine] = parts.join('|');
}
debug(activity: string) {
debug(...activity: Part[]) {
if (this.debugMode) {
this.add('debug', activity);
this.add('debug', ...activity);
}
}

View File

@ -85,7 +85,7 @@ export class DexAbilities {
}
getByID(id: ID): Ability {
if (id === '') return EMPTY_ABILITY;
if (id === '' || id === 'constructor') return EMPTY_ABILITY;
let ability = this.abilityCache.get(id);
if (ability) return ability;

View File

@ -665,7 +665,7 @@ export class DexConditions {
}
getByID(id: ID): Condition {
if (id === '') return EMPTY_CONDITION;
if (id === '' || id === 'constructor') return EMPTY_CONDITION;
let condition = this.conditionCache.get(id);
if (condition) return condition;

View File

@ -172,7 +172,7 @@ export class DexNatures {
return this.getByID(toID(name));
}
getByID(id: ID): Nature {
if (id === '') return EMPTY_NATURE;
if (id === '' || id === 'constructor') return EMPTY_NATURE;
let nature = this.natureCache.get(id);
if (nature) return nature;
@ -293,7 +293,7 @@ export class DexTypes {
}
getByID(id: ID): TypeInfo {
if (id === '') return EMPTY_TYPE_INFO;
if (id === '' || id === 'constructor') return EMPTY_TYPE_INFO;
let type = this.typeCache.get(id);
if (type) return type;

View File

@ -43,17 +43,11 @@ export class Item extends BasicEffect implements Readonly<BasicEffect> {
*/
readonly onMemory?: string;
/**
* If this is a mega stone: The name (e.g. Charizard-Mega-X) of the
* forme this allows transformation into.
* If this is a mega stone: A pair (e.g. Charizard: Charizard-Mega-X) of the
* forme this allows transformation from and into.
* undefined, if not a mega stone.
*/
readonly megaStone?: string | string[];
/**
* If this is a mega stone: The name (e.g. Charizard) of the
* forme this allows transformation from.
* undefined, if not a mega stone.
*/
readonly megaEvolves?: string | string[];
readonly megaStone?: { [megaEvolves: string]: string };
/**
* If this is a Z crystal: true if the Z Crystal is generic
* (e.g. Firium Z). If species-specific, the name
@ -116,7 +110,6 @@ export class Item extends BasicEffect implements Readonly<BasicEffect> {
this.onDrive = data.onDrive || undefined;
this.onMemory = data.onMemory || undefined;
this.megaStone = data.megaStone || undefined;
this.megaEvolves = data.megaEvolves || undefined;
this.zMove = data.zMove || undefined;
this.zMoveType = data.zMoveType || undefined;
this.zMoveFrom = data.zMoveFrom || undefined;
@ -176,7 +169,7 @@ export class DexItems {
}
getByID(id: ID): Item {
if (id === '') return EMPTY_ITEM;
if (id === '' || id === 'constructor') return EMPTY_ITEM;
let item = this.itemCache.get(id);
if (item) return item;
if (this.dex.getAlias(id)) {

View File

@ -621,7 +621,7 @@ export class DexMoves {
}
getByID(id: ID): Move {
if (id === '') return EMPTY_MOVE;
if (id === '' || id === 'constructor') return EMPTY_MOVE;
let move = this.moveCache.get(id);
if (move) return move;
if (this.dex.getAlias(id)) {

View File

@ -436,7 +436,7 @@ export class DexSpecies {
}
getByID(id: ID): Species {
if (id === '') return EMPTY_SPECIES;
if (id === '' || id === 'constructor') return EMPTY_SPECIES;
let species: Mutable<Species> | undefined = this.speciesCache.get(id);
if (species) return species;

View File

@ -526,14 +526,8 @@ export class TeamValidator {
if (ruleTable.has('obtainableformes')) {
const canMegaEvo = dex.gen <= 7 || ruleTable.has('+pokemontag:past');
if (item.megaEvolves?.includes(species.name)) {
if (!item.megaStone) throw new Error(`Item ${item.name} has no base form for mega evolution`);
if (Array.isArray(item.megaEvolves)) {
const idx = item.megaEvolves.indexOf(species.name);
tierSpecies = dex.species.get(item.megaStone[idx]);
} else {
tierSpecies = dex.species.get(item.megaStone as string);
}
if (item.megaStone?.[species.name]) {
tierSpecies = dex.species.get(item.megaStone[species.name]);
} else if (item.id === 'redorb' && species.id === 'groudon') {
tierSpecies = dex.species.get('Groudon-Primal');
} else if (item.id === 'blueorb' && species.id === 'kyogre') {

View File

@ -137,8 +137,8 @@ export class ExhaustiveRunner {
const signatures = new Map();
for (const id of pools.items.possible) {
const item = dex.data.Items[id];
if (item.megaEvolves) {
const pokemon = toID(item.megaEvolves);
if (item.megaStone) {
const pokemon = toID(Object.keys(item.megaStone)[0]);
const combo = { item: id };
let combos = signatures.get(pokemon);
if (!combos) {

View File

@ -462,3 +462,74 @@ describe('[Gen 9] BSS Factory data should be valid (slow)', () => {
}
});
});
describe('[Gen 9] 1v1 Factory data should be valid (slow)', () => {
it(`gen9/1v1-factory-sets.json should contain valid sets`, function () {
this.timeout(0);
const setsJSON = require(`../../dist/data/random-battles/gen9/1v1-factory-sets.json`);
const mod = 'gen9';
for (const speciesName in setsJSON) {
const speciesData = setsJSON[speciesName];
for (const set of speciesData.sets) {
const species = Dex.species.get(set.species);
assert(species.exists, `invalid species "${set.species}" of ${speciesName}`);
assert.equal(species.name, set.species, `miscapitalized species "${set.species}" of ${speciesName}`);
assert(species.id.startsWith(toID(species.baseSpecies)), `non-matching species "${set.species}" of ${speciesName}`);
for (const itemName of [].concat(set.item)) {
if (!itemName) continue;
const item = Dex.items.get(itemName);
assert(item.exists, `invalid item "${itemName}" of ${speciesName}`);
assert.equal(item.name, itemName, `miscapitalized item "${itemName}" of ${speciesName}`);
}
for (const abilityName of [].concat(set.ability)) {
const ability = Dex.abilities.get(abilityName);
assert(ability.exists, `invalid ability "${abilityName}" of ${speciesName}`);
assert.equal(ability.name, abilityName, `miscapitalized ability "${abilityName}" of ${speciesName}`);
const allowedAbilities = new Set(Object.values((species.battleOnly && !species.requiredAbility) ? Dex.species.get(species.battleOnly).abilities : species.abilities));
if (species.unreleasedHidden) allowedAbilities.delete(species.abilities.H);
assert(allowedAbilities.has(abilityName), `${speciesName} can't have ${abilityName}`);
}
for (const natureName of [].concat(set.nature)) {
const nature = Dex.natures.get(natureName);
assert(nature.exists, `invalid nature "${natureName}" of ${speciesName}`);
assert.equal(nature.name, natureName, `miscapitalized nature "${natureName}" of ${speciesName}`);
}
for (const moveSpec of set.moves) {
for (const moveName of [].concat(moveSpec)) {
const move = Dex.moves.get(moveName);
assert(move.exists, `invalid move "${moveName}" of ${speciesName}`);
assert.equal(move.name, moveName, `miscapitalized move "${moveName}" ≠ "${move.name}" of ${speciesName}`);
assert(validateLearnset(move, set, '1v1', mod), `illegal move "${moveName}" of ${speciesName}`);
}
}
// Check that no moves appear more than once in a set
assert.equal(set.moves.flat(1).length, new Set(set.moves.flat(1)).size, `${speciesName} has repeat moves`);
if (speciesName === 'Carbink') continue;
assert(!!set.evs, `Set of ${speciesName} has no EVs specified`);
const keys = Object.keys(set.evs);
let totalEVs = 0;
for (const ev of keys) {
assert(Dex.stats.ids().includes(ev), `Invalid EV key (${ev}) on set of ${speciesName}`);
totalEVs += set.evs[ev];
assert.equal(set.evs[ev] % 4, 0, `EVs of ${ev} not divisible by 4 on ${speciesName}`);
}
const sortedKeys = Utils.sortBy([...keys], ev => Dex.stats.ids().indexOf(ev));
assert.deepEqual(keys, sortedKeys, `EVs out of order on set of ${speciesName}, possibly because one of them is for the wrong stat`);
assert(totalEVs <= 510, `more than 510 EVs on set of ${speciesName}`);
}
let totalWeight = 0;
for (const set of speciesData.sets) {
totalWeight += set.weight;
}
assert.equal(totalWeight, 100, `Total set weight for ${speciesName} is ${totalWeight < 100 ? 'less' : 'greater'} than 100%`);
}
});
});

View File

@ -113,7 +113,7 @@ describe('Dex data', () => {
assert.equal(entry.evoItem, item.exists && item.name, `Misspelled/nonexistent evo item "${entry.evoItem}" of ${entry.name}`);
}
const battleOnly = ['Mega', 'Mega-X', 'Mega-Y', 'Mega-Z', 'Primal'].includes(entry.forme) ? entry.baseSpecies : entry.battleOnly;
const battleOnly = (entry.forme || '').includes('Mega') || entry.forme === 'Primal' ? entry.baseSpecies : entry.battleOnly;
if (entry.requiredAbility) {
assert(entry.battleOnly, `Forme ${entry.name} with requiredAbility must have battleOnly`);
}
@ -132,12 +132,6 @@ describe('Dex data', () => {
const entry = Items[itemid];
assert.equal(toID(entry.name), itemid, `Mismatched Item key "${itemid}" of "${entry.name}"`);
assert.equal(typeof entry.num, 'number', `Item ${entry.name} should have a number`);
if (entry.megaStone) {
assert.equal(typeof entry.megaStone, typeof entry.megaEvolves, `Item ${entry.name} megaStone and megaEvolves should both be the same type`);
if (Array.isArray(entry.megaStone)) {
assert.equal(entry.megaStone.length, entry.megaEvolves.length, `Item ${entry.name} megaStone and megaEvolves arrays should be the same length`);
}
}
}
});
@ -407,11 +401,11 @@ describe('Dex data', () => {
// Shaymin (1) + Therian (4) + Hisui (16) + Basculin (1) + Basculegion (1)
formes['gen8legends'] = 1 + 1 + 2 + 1 + 5 + 3 + 17 + 1 + 4 + 16 + 1 + 1;
species['gen9legends'] = 232 + 132; // Lumiose Pokedex + Hyperspace Pokedex
// Mega (90) + Primal (2) + Rotom (5) + Keldeo (1) + Meloetta (1) + Genesect (4) + Vivillon (2) + Floette (1) +
// Meowstic (1) + Aegislash (1) + Pumpkaboo (3) + Gourgeist (3) + Zygarde (2) + Mimikyu (1) + Magearna (1) +
// Alola (4) + Toxtricity (1) + Indeedee (1) + Morpeko (1) + Galar (8) + Hisui (1) + Squawkabilly (3) +
// Mega (96) + Primal (2) + Rotom (5) + Keldeo (1) + Meloetta (1) + Genesect (4) + Vivillon (2) + Floette (1) +
// Meowstic (1) + Aegislash (1) + Pumpkaboo (3) + Gourgeist (3) + Zygarde (2) + Mimikyu (1) +
// Alola (4) + Toxtricity (1) + Indeedee (1) + Morpeko (1) + Galar (8) + Hisui (4) + Squawkabilly (3) +
// Tatsugiri (2) + Gimmighoul (1) + Hoopa (1)
formes['gen9legends'] = 92 + 2 + 5 + 1 + 1 + 4 + 2 + 1 + 1 + 1 + 3 + 3 + 2 + 1 + 1 + 4 + 1 + 1 + 1 + 8 + 1 + 3 + 2 + 1 + 1;
formes['gen9legends'] = 96 + 2 + 5 + 1 + 1 + 4 + 2 + 1 + 1 + 1 + 3 + 3 + 2 + 1 + 4 + 1 + 1 + 1 + 8 + 4 + 3 + 2 + 1 + 1;
for (const mod of ['gen7letsgo', 'gen8bdsp', 'gen8legends', 'gen9legends']) {
it(`${mod} should have ${species[mod]} species and ${formes[mod]} formes`, () => {

View File

@ -156,7 +156,7 @@ describe('Team Validator', () => {
const team = [
{ species: 'smeargle', ability: 'owntempo', moves: ['bellydrum', 'spore', 'sketch'], evs: { hp: 1 } },
];
assert.legalTeam(team, 'gen4ou');
assert.legalTeam(team, 'gen4anythinggoes');
});
it('should accept both ability types for Mega Evolutions', () => {

View File

@ -233,10 +233,10 @@ describe('Team Validator', () => {
))
.reduce((x, y) => x + y);
// Dex.species.all skips over cosmetic formes
const accepted = Dex.species.all().filter(species => !(
// ruleTable.isBannedSpecies blind spots
species.natDexTier === 'Illegal' || species.isNonstandard === 'CAP'
species.natDexTier === 'Illegal' || species.isNonstandard === 'CAP' ||
Dex.species.get(species.baseSpecies).cosmeticFormes?.includes(species.name)
) && !ruleTable.isBannedSpecies(species)).length;
assert.equal(accepted, allowed);

View File

@ -312,7 +312,8 @@ function skip(dex: ModdedDex, format: Format, pokemon: string, set: DeepPartial<
if (pokemon === 'Rayquaza-Mega') {
return format.id.includes('ubers') || !hasMove('Dragon Ascent');
} else {
return dex.items.get(set.item).megaStone !== pokemon;
const item = dex.items.get(set.item);
return !item.megaStone || !Object.values(item.megaStone).includes(pokemon);
}
}
if (pokemon === 'Necrozma-Ultra' && set.item !== 'Ultranecrozium Z') return true;